ZDoom / gzdoom

GZDoom is a feature centric port for all Doom engine games, based on ZDoom, adding an OpenGL renderer and powerful scripting capabilities
http://zdoom.org
GNU General Public License v3.0
2.33k stars 526 forks source link

[BUG] Inventory Actor with Classes in Map <String, Class> when called crashes using map.Copy(...) after Level Transition #2599

Open Lemon-King opened 3 weeks ago

Lemon-King commented 3 weeks ago

GZDoom version

GZDoom g4.12.2

Which game are you running with GZDoom?

Other

What Operating System are you using?

Windows 11

Please describe your specific OS version

No response

Relevant hardware info

NVidia 3080, AMD CPU, 32 GB System Ram

Have you checked that no other similar issue already exists?

A clear and concise description of what the bug is.

If you have a map <string, class> within an inventory actor which is populated by copy from another map in another class. Changing level leads to a crash.

Steps to reproduce the behaviour.

Ref: Discord Conversation

class PlayerSheetStat {
    String name;
    Array<int> table;
    double value;

    double stat_compute(double min, double max) {
        double value = (max-min+1) * frandom[sheetstat](0.0, 1.0) + min;
        if (value > max) {
            return max;
        }
        value = ceil(value);
        return value;
    }

    void Roll() {
        self.value = self.stat_compute(self.table[0], self.table[1]);
    }

    void ProcessLevelIncrease(bool levelCap) {
        // stat uses a leveling table
        if (self.table.Size() >= 5) {
            int max = self.table[1];
            if (self.table[5]) {
                max = self.table[5];
            }
            if (levelCap) {
                self.value += clamp(self.table[0], self.table[4], max);
            } else {
                self.value += clamp(self.table[0], self.stat_compute(self.table[2], self.table[3]), max);
            }
        }
    }
}

It exists within this map: Map<String, PlayerSheetStat> stats; This is within a class called: PlayerSheetJSON Which is then accessed in another class called PlayerSheet PlayerSheet copies the mapped data from PlayerSheetJSON into its own local class variable using self.var.Copy(PlayerSheet.stat) as an example. Doing this leads to a crash on map change when accessing self.var. Now if I use self.var.Move(...) or self.var.Swap(...) it doesn't occur.

Within my commit you can see my solution for now using Move. Replacing those with Copy will cause the after map change.

Your configuration

No response

Provide a Log

E1M2 - The Dungeons

XGameTranslation.XClass: Load playersheets/hereticplayer.playersheet 7793 XGameTranslation.XClass.TrySwap Found: SilverShield 0 XGameTranslation.XClass.TrySwap Found: SilverShield 0 Game saved. (V:/Applications/GZDoom/Save/raven.hxdd/auto19.zds) Gained 42 Experience! Total Experience: 532 (675) Gained 42 Experience! Total Experience: 574 (675) Gained 98 Experience! Total Experience: 672 (675) Gained 38 Experience! Total Experience: 711 (675) VM execution aborted: string format failed. MapIterator::Next called from invalid iterator Called from Progression.AdvanceLevel at V:/Applications/GZDoom/data/_hxdd/:zscript/actors/hxdd/shared/inventory/progression.zs, line 888 Called from Progression.GiveExperience at V:/Applications/GZDoom/data/_hxdd/:zscript/actors/hxdd/shared/inventory/progression.zs, line 944 Called from Progression.AwardExperience at V:/Applications/GZDoom/data/_hxdd/:zscript/actors/hxdd/shared/inventory/progression.zs, line 1005 Called from PlayerSheetEventHandler.WorldThingDied at V:/Applications/GZDoom/data/_hxdd/:zscript/actors/hxdd/shared/inventory/progression.zs, line 49