Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update existing monsters after loading monster gfx #6845

Merged
merged 1 commit into from
Dec 1, 2023

Conversation

obligaron
Copy link
Contributor

Fixed a bug reported by @FitzRoyX on discord

It happens when entering a new level and monsters are visible.

@StephenCWills has a good description:

It's calling InitAllMonsterGFX() at the end of InitMonsters().
It means that all calls to InitMonster() are already complete, and have copied animation data from CMonster structs before the animations have even been loaded into CMonster structs.
It doesn't completely break the game because monsters change state when they are activated. But if a monster is visible from the stairs, it hasn't had a chance to change states before the first time it's drawn.

This PR fixes the issue by updating the animations after the new sprites are loaded.
This happens for all Monsters that don't have a sprite loaded yet.

Alternative fixes, could be

  • Change initialization order
    • First call AddMonsterType for all needed monsters
    • Second call InitAllMonsterGFX to load all sprites
    • Third call AddMonster/PlaceMonster to add monsters to the dungeon and assign sprites
    • Problem: We don't know upfront what monster types are needed, because they are present in the ".dun"-files. We would need to load the ".dun"-files a second time to check what types are needed. This would also change the current control flow.
  • Load sprites in AddMonsterType
    • Load the sprites when a monster type is loaded
    • Problem: this would basically revert the current sprite optimization logic, because we only know about one monstertype at this point and can't reuse sprites for different monsters
  • Combination of both
    • Load sprites for all (yet known) monsters after GetLevelMTypes (this is where most monsters types are added for normal levels)
    • After that load all monsters one at a time
    • Problem: Two ways to handle stuff and we need to know in AddMonsterType if we need to load the sprites now or this is done later (a parameter or a global/switch of some sort).

Thanks @StephenCWills for the up-front analysis

@AJenbo AJenbo merged commit e7ba810 into diasurgical:master Dec 1, 2023
23 checks passed
@obligaron obligaron deleted the monstersync branch December 2, 2023 07:42
@AJenbo
Copy link
Member

AJenbo commented Dec 2, 2023

It looks like it might still be an issue in some cases. I got this when re-visting the poison water areas after having to back track for potions (after killing the first goat):

image

Still this an improvement since previously the game would not even let you in to the area.

@AJenbo
Copy link
Member

AJenbo commented Dec 2, 2023

Same with Leorics tomb, I also noticed this errors when quest levels are loaded:


/home/ajenbo/code/diablo/devilutionX/Source/objects.cpp:3963:68: runtime error: index -1 out of bounds for type 'ObjectData [109]'
/home/ajenbo/code/diablo/devilutionX/Source/objects.cpp:3963:68: runtime error: index -1 out of bounds for type 'ObjectData [109]'
=================================================================
==465935==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55caed0daa1e at pc 0x55caedbac587 bp 0x7ffd7afabf30 sp 0x7ffd7afabf20
READ of size 1 at 0x55caed0daa1e thread T0
    #0 0x55caedbac586 in devilution::SetMapObjects(unsigned short const*, int, int) /home/ajenbo/code/diablo/devilutionX/Source/objects.cpp:3964
    #1 0x55caee3b7220 in devilution::LoadDungeonBase(char const*, devilution::PointOf<int>, int, int) /home/ajenbo/code/diablo/devilutionX/Source/levels/gendung.cpp:570
    #2 0x55caee2e7909 in devilution::LoadL1Dungeon(char const*, devilution::PointOf<int>) /home/ajenbo/code/diablo/devilutionX/Source/levels/drlg_l1.cpp:1326
    #3 0x55caee3c9883 in devilution::LoadSetMap() /home/ajenbo/code/diablo/devilutionX/Source/levels/setmaps.cpp:118
    #4 0x55caed598ed9 in devilution::LoadGameLevel(bool, devilution::lvl_entry) /home/ajenbo/code/diablo/devilutionX/Source/diablo.cpp:2927
    #5 0x55caed6196f3 in devilution::ShowProgress(devilution::interface_mode) /home/ajenbo/code/diablo/devilutionX/Source/interfac.cpp:400
    #6 0x55caed567f18 in GameEventHandler /home/ajenbo/code/diablo/devilutionX/Source/diablo.cpp:756
    #7 0x55caee0be2b2 in devilution::HandleMessage(SDL_Event const&, unsigned short) /home/ajenbo/code/diablo/devilutionX/Source/engine/events.cpp:184
    #8 0x55caed5687c3 in RunGameLoop /home/ajenbo/code/diablo/devilutionX/Source/diablo.cpp:834
    #9 0x55caed594609 in devilution::StartGame(bool, bool) /home/ajenbo/code/diablo/devilutionX/Source/diablo.cpp:2416
    #10 0x55caed8b1bd0 in InitMenu /home/ajenbo/code/diablo/devilutionX/Source/menu.cpp:59
    #11 0x55caed8b1c37 in InitSinglePlayerMenu /home/ajenbo/code/diablo/devilutionX/Source/menu.cpp:69
    #12 0x55caed8b2843 in devilution::mainmenu_loop() /home/ajenbo/code/diablo/devilutionX/Source/menu.cpp:161
    #13 0x55caed594870 in devilution::DiabloMain(int, char**) /home/ajenbo/code/diablo/devilutionX/Source/diablo.cpp:2490
    #14 0x55caed439d5d in main /home/ajenbo/code/diablo/devilutionX/Source/main.cpp:52
    #15 0x7f1a0be280cf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #16 0x7f1a0be28188 in __libc_start_main_impl ../csu/libc-start.c:360
    #17 0x55caed439c64 in _start (/home/ajenbo/code/diablo/devilutionX/build/devilutionx+0x332cc64) (BuildId: 36cadaa73bb1851e38dafb0aa8267154fde6e8c8)

@AJenbo
Copy link
Member

AJenbo commented Dec 2, 2023

Narrowed it down to 42e1b82 :)

@AJenbo
Copy link
Member

AJenbo commented Dec 2, 2023

Fix ready: #6847

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants