From 59bdebb20a36ab762303fd60a242e52a8d023c49 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 27 Oct 2019 13:06:26 +0200 Subject: [PATCH] - added generic level post-processing script class It was extracted from LevelCompatibility class, and native code was moved accordingly --- src/maploader/compatibility.cpp | 207 ------------------ src/maploader/maploader.cpp | 208 ++++++++++++++++++- src/maploader/maploader.h | 2 +- wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/level_compatibility.zs | 77 +------ wadsrc/static/zscript/level_postprocessor.zs | 82 ++++++++ 6 files changed, 292 insertions(+), 285 deletions(-) create mode 100644 wadsrc/static/zscript/level_postprocessor.zs diff --git a/src/maploader/compatibility.cpp b/src/maploader/compatibility.cpp index 5b23b51be..cabb2ade1 100644 --- a/src/maploader/compatibility.cpp +++ b/src/maploader/compatibility.cpp @@ -50,7 +50,6 @@ #include "w_wad.h" #include "textures.h" #include "g_levellocals.h" -#include "vm.h" #include "actor.h" #include "p_setup.h" #include "maploader/maploader.h" @@ -340,209 +339,3 @@ FName MapLoader::CheckCompatibility(MapData *map) } return FName(hash, true); // if this returns NAME_None it means there is no scripted compatibility handler. } - -//========================================================================== -// -// SetCompatibilityParams -// -//========================================================================== - -class DLevelCompatibility : public DObject -{ - DECLARE_ABSTRACT_CLASS(DLevelCompatibility, DObject) -public: - MapLoader *loader; - FLevelLocals *Level; -}; -IMPLEMENT_CLASS(DLevelCompatibility, true, false); - - -void MapLoader::SetCompatibilityParams(FName checksum) -{ - auto lc = Create(); - lc->loader = this; - lc->Level = Level; - for(auto cls : PClass::AllClasses) - { - if (cls->IsDescendantOf(RUNTIME_CLASS(DLevelCompatibility))) - { - PFunction *const func = dyn_cast(cls->FindSymbol("Apply", false)); - if (func == nullptr) - { - Printf("Missing 'Apply' method in class '%s', level compatibility object ignored\n", cls->TypeName.GetChars()); - continue; - } - - auto argTypes = func->Variants[0].Proto->ArgumentTypes; - if (argTypes.Size() != 3 || argTypes[1] != TypeName || argTypes[2] != TypeString) - { - Printf("Wrong signature of 'Apply' method in class '%s', level compatibility object ignored\n", cls->TypeName.GetChars()); - continue; - } - - VMValue param[] = { lc, checksum.GetIndex(), &Level->MapName }; - VMCall(func->Variants[0].Implementation, param, 3, nullptr, 0); - } - } -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, OffsetSectorPlane) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_INT(sector); - PARAM_INT(planeval); - PARAM_FLOAT(delta); - - if ((unsigned)sector < self->Level->sectors.Size()) - { - sector_t *sec = &self->Level->sectors[sector]; - secplane_t& plane = sector_t::floor == planeval? sec->floorplane : sec->ceilingplane; - plane.ChangeHeight(delta); - sec->ChangePlaneTexZ(planeval, delta); - } - return 0; -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, ClearSectorTags) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_INT(sector); - self->Level->tagManager.RemoveSectorTags(sector); - return 0; -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, AddSectorTag) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_INT(sector); - PARAM_INT(tag); - - if ((unsigned)sector < self->Level->sectors.Size()) - { - self->Level->tagManager.AddSectorTag(sector, tag); - } - return 0; -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, ClearLineIDs) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_INT(line); - self->Level->tagManager.RemoveLineIDs(line); - return 0; -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, AddLineID) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_INT(line); - PARAM_INT(tag); - - if ((unsigned)line < self->Level->lines.Size()) - { - self->Level->tagManager.AddLineID(line, tag); - } - return 0; -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetThingSkills) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_INT(thing); - PARAM_INT(skillmask); - - if ((unsigned)thing < self->loader->MapThingsConverted.Size()) - { - self->loader->MapThingsConverted[thing].SkillFilter = skillmask; - } - return 0; -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetThingXY) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_INT(thing); - PARAM_FLOAT(x); - PARAM_FLOAT(y); - - if ((unsigned)thing < self->loader->MapThingsConverted.Size()) - { - auto& pos = self->loader->MapThingsConverted[thing].pos; - pos.X = x; - pos.Y = y; - } - return 0; -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetThingZ) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_INT(thing); - PARAM_FLOAT(z); - - if ((unsigned)thing < self->loader->MapThingsConverted.Size()) - { - self->loader->MapThingsConverted[thing].pos.Z = z; - } - return 0; -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetThingFlags) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_INT(thing); - PARAM_INT(flags); - - if ((unsigned)thing < self->loader->MapThingsConverted.Size()) - { - self->loader->MapThingsConverted[thing].flags = flags; - } - return 0; -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetVertex) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_UINT(vertex); - PARAM_FLOAT(x); - PARAM_FLOAT(y); - - if (vertex < self->Level->vertexes.Size()) - { - self->Level->vertexes[vertex].p = DVector2(x, y); - } - self->loader->ForceNodeBuild = true; - return 0; -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetLineSectorRef) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_UINT(lineidx); - PARAM_UINT(sideidx); - PARAM_UINT(sectoridx); - - if ( sideidx < 2 - && lineidx < self->Level->lines.Size() - && sectoridx < self->Level->sectors.Size()) - { - line_t *line = &self->Level->lines[lineidx]; - side_t *side = line->sidedef[sideidx]; - side->sector = &self->Level->sectors[sectoridx]; - if (sideidx == 0) line->frontsector = side->sector; - else line->backsector = side->sector; - } - self->loader->ForceNodeBuild = true; - return 0; -} - -DEFINE_ACTION_FUNCTION(DLevelCompatibility, GetDefaultActor) -{ - PARAM_SELF_PROLOGUE(DLevelCompatibility); - PARAM_NAME(actorclass); - ACTION_RETURN_OBJECT(GetDefaultByName(actorclass)); -} - - -DEFINE_FIELD(DLevelCompatibility, Level); - diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index 368d38824..098f5f178 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -79,6 +79,7 @@ #include "swrenderer/r_swrenderer.h" #include "hwrenderer/data/flatvertices.h" #include "xlat/xlat.h" +#include "vm.h" enum { @@ -3053,7 +3054,7 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position) ParseTextMap(map, missingtex); } - SetCompatibilityParams(checksum); + PostProcessLevel(checksum); LoopSidedefs(true); @@ -3269,3 +3270,208 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position) if (!Level->IsReentering()) Level->FinalizePortals(); // finalize line portals after polyobjects have been initialized. This info is needed for properly flagging them. } + +//========================================================================== +// +// PostProcessLevel +// +//========================================================================== + +class DLevelPostProcessor : public DObject +{ + DECLARE_ABSTRACT_CLASS(DLevelPostProcessor, DObject) +public: + MapLoader *loader; + FLevelLocals *Level; +}; + +IMPLEMENT_CLASS(DLevelPostProcessor, true, false); + +void MapLoader::PostProcessLevel(FName checksum) +{ + auto lc = Create(); + lc->loader = this; + lc->Level = Level; + for(auto cls : PClass::AllClasses) + { + if (cls->IsDescendantOf(RUNTIME_CLASS(DLevelPostProcessor))) + { + PFunction *const func = dyn_cast(cls->FindSymbol("Apply", false)); + if (func == nullptr) + { + Printf("Missing 'Apply' method in class '%s', level compatibility object ignored\n", cls->TypeName.GetChars()); + continue; + } + + auto argTypes = func->Variants[0].Proto->ArgumentTypes; + if (argTypes.Size() != 3 || argTypes[1] != TypeName || argTypes[2] != TypeString) + { + Printf("Wrong signature of 'Apply' method in class '%s', level compatibility object ignored\n", cls->TypeName.GetChars()); + continue; + } + + VMValue param[] = { lc, checksum.GetIndex(), &Level->MapName }; + VMCall(func->Variants[0].Implementation, param, 3, nullptr, 0); + } + } +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, OffsetSectorPlane) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_INT(sector); + PARAM_INT(planeval); + PARAM_FLOAT(delta); + + if ((unsigned)sector < self->Level->sectors.Size()) + { + sector_t *sec = &self->Level->sectors[sector]; + secplane_t& plane = sector_t::floor == planeval? sec->floorplane : sec->ceilingplane; + plane.ChangeHeight(delta); + sec->ChangePlaneTexZ(planeval, delta); + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, ClearSectorTags) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_INT(sector); + self->Level->tagManager.RemoveSectorTags(sector); + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, AddSectorTag) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_INT(sector); + PARAM_INT(tag); + + if ((unsigned)sector < self->Level->sectors.Size()) + { + self->Level->tagManager.AddSectorTag(sector, tag); + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, ClearLineIDs) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_INT(line); + self->Level->tagManager.RemoveLineIDs(line); + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, AddLineID) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_INT(line); + PARAM_INT(tag); + + if ((unsigned)line < self->Level->lines.Size()) + { + self->Level->tagManager.AddLineID(line, tag); + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SetThingSkills) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_INT(thing); + PARAM_INT(skillmask); + + if ((unsigned)thing < self->loader->MapThingsConverted.Size()) + { + self->loader->MapThingsConverted[thing].SkillFilter = skillmask; + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SetThingXY) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_INT(thing); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + + if ((unsigned)thing < self->loader->MapThingsConverted.Size()) + { + auto& pos = self->loader->MapThingsConverted[thing].pos; + pos.X = x; + pos.Y = y; + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SetThingZ) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_INT(thing); + PARAM_FLOAT(z); + + if ((unsigned)thing < self->loader->MapThingsConverted.Size()) + { + self->loader->MapThingsConverted[thing].pos.Z = z; + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SetThingFlags) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_INT(thing); + PARAM_INT(flags); + + if ((unsigned)thing < self->loader->MapThingsConverted.Size()) + { + self->loader->MapThingsConverted[thing].flags = flags; + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SetVertex) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_UINT(vertex); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + + if (vertex < self->Level->vertexes.Size()) + { + self->Level->vertexes[vertex].p = DVector2(x, y); + } + self->loader->ForceNodeBuild = true; + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SetLineSectorRef) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_UINT(lineidx); + PARAM_UINT(sideidx); + PARAM_UINT(sectoridx); + + if ( sideidx < 2 + && lineidx < self->Level->lines.Size() + && sectoridx < self->Level->sectors.Size()) + { + line_t *line = &self->Level->lines[lineidx]; + side_t *side = line->sidedef[sideidx]; + side->sector = &self->Level->sectors[sectoridx]; + if (sideidx == 0) line->frontsector = side->sector; + else line->backsector = side->sector; + } + self->loader->ForceNodeBuild = true; + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelPostProcessor, GetDefaultActor) +{ + PARAM_SELF_PROLOGUE(DLevelPostProcessor); + PARAM_NAME(actorclass); + ACTION_RETURN_OBJECT(GetDefaultByName(actorclass)); +} + +DEFINE_FIELD(DLevelPostProcessor, Level); + diff --git a/src/maploader/maploader.h b/src/maploader/maploader.h index 67c78c36b..6932b8aa0 100644 --- a/src/maploader/maploader.h +++ b/src/maploader/maploader.h @@ -131,7 +131,7 @@ private: TArray KnownPolySides; FName CheckCompatibility(MapData *map); - void SetCompatibilityParams(FName checksum); + void PostProcessLevel(FName checksum); // Slopes void SlopeLineToPoint(int lineid, const DVector3 &pos, bool slopeCeil); diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index ccef58d1d..7981d9032 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -6,6 +6,7 @@ version "4.2" #include "zscript/constants.zs" #include "zscript/events.zs" #include "zscript/destructible.zs" +#include "zscript/level_postprocessor.zs" #include "zscript/level_compatibility.zs" #include "zscript/actors/actor.zs" diff --git a/wadsrc/static/zscript/level_compatibility.zs b/wadsrc/static/zscript/level_compatibility.zs index 3bc427ac8..507473e5c 100644 --- a/wadsrc/static/zscript/level_compatibility.zs +++ b/wadsrc/static/zscript/level_compatibility.zs @@ -1,8 +1,6 @@ -class LevelCompatibility native play +class LevelCompatibility : LevelPostProcessor { - native LevelLocals level; - protected void Apply(Name checksum, String mapname) { switch (checksum) @@ -1461,77 +1459,4 @@ class LevelCompatibility native play } } } - - protected native void ClearSectorTags(int sector); - protected native void AddSectorTag(int sector, int tag); - protected native void ClearLineIDs(int line); - protected native void AddLineID(int line, int tag); - protected native void OffsetSectorPlane(int sector, int plane, double offset); - protected native void SetThingSkills(int thing, int skills); - protected native void SetThingXY(int thing, double x, double y); - protected native void SetThingZ(int thing, double z); - protected native void SetThingFlags(int thing, int flags); - protected native void SetVertex(uint vertex, double x, double y); - protected native void SetLineSectorRef(uint line, uint side, uint sector); - protected native Actor GetDefaultActor(Name actorclass); - - protected void SetWallTexture(int line, int side, int texpart, String texture) - { - SetWallTextureID(line, side, texpart, TexMan.CheckForTexture(texture, TexMan.Type_Wall)); - } - - protected void SetWallTextureID(int line, int side, int texpart, TextureID texture) - { - level.Lines[line].sidedef[side].SetTexture(texpart, texture); - } - - protected void SetLineFlags(int line, int setflags, int clearflags = 0) - { - level.Lines[line].flags = (level.Lines[line].flags & ~clearflags) | setflags; - } - - protected void SetLineActivation(int line, int acttype) - { - level.Lines[line].activation = acttype; - } - - protected void ClearLineSpecial(int line) - { - level.Lines[line].special = 0; - } - - protected void SetLineSpecial(int line, int special, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0, int arg5 = 0) - { - level.Lines[line].special = special; - level.Lines[line].args[0] = arg1; - level.Lines[line].args[1] = arg2; - level.Lines[line].args[2] = arg3; - level.Lines[line].args[3] = arg4; - level.Lines[line].args[4] = arg5; - } - - protected void SetSectorSpecial(int sectornum, int special) - { - level.sectors[sectornum].special = special; - } - - protected void SetSectorTextureID(int sectornum, int plane, TextureID texture) - { - level.sectors[sectornum].SetTexture(plane, texture); - } - - protected void SetSectorTexture(int sectornum, int plane, String texture) - { - SetSectorTextureID(sectornum, plane, TexMan.CheckForTexture(texture, TexMan.Type_Flat)); - } - - protected void SetSectorLight(int sectornum, int newval) - { - level.sectors[sectornum].SetLightLevel(newval); - } - - protected void SetWallYScale(int line, int side, int texpart, double scale) - { - level.lines[line].sidedef[side].SetTextureYScale(texpart, scale); - } } diff --git a/wadsrc/static/zscript/level_postprocessor.zs b/wadsrc/static/zscript/level_postprocessor.zs new file mode 100644 index 000000000..e967f93f0 --- /dev/null +++ b/wadsrc/static/zscript/level_postprocessor.zs @@ -0,0 +1,82 @@ + +class LevelPostProcessor native play +{ + protected native LevelLocals level; + + protected void Apply(Name checksum, String mapname) + { + } + + protected native void ClearSectorTags(int sector); + protected native void AddSectorTag(int sector, int tag); + protected native void ClearLineIDs(int line); + protected native void AddLineID(int line, int tag); + protected native void OffsetSectorPlane(int sector, int plane, double offset); + protected native void SetThingSkills(int thing, int skills); + protected native void SetThingXY(int thing, double x, double y); + protected native void SetThingZ(int thing, double z); + protected native void SetThingFlags(int thing, int flags); + protected native void SetVertex(uint vertex, double x, double y); + protected native void SetLineSectorRef(uint line, uint side, uint sector); + protected native Actor GetDefaultActor(Name actorclass); + + protected void SetWallTexture(int line, int side, int texpart, String texture) + { + SetWallTextureID(line, side, texpart, TexMan.CheckForTexture(texture, TexMan.Type_Wall)); + } + + protected void SetWallTextureID(int line, int side, int texpart, TextureID texture) + { + level.Lines[line].sidedef[side].SetTexture(texpart, texture); + } + + protected void SetLineFlags(int line, int setflags, int clearflags = 0) + { + level.Lines[line].flags = (level.Lines[line].flags & ~clearflags) | setflags; + } + + protected void SetLineActivation(int line, int acttype) + { + level.Lines[line].activation = acttype; + } + + protected void ClearLineSpecial(int line) + { + level.Lines[line].special = 0; + } + + protected void SetLineSpecial(int line, int special, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0, int arg5 = 0) + { + level.Lines[line].special = special; + level.Lines[line].args[0] = arg1; + level.Lines[line].args[1] = arg2; + level.Lines[line].args[2] = arg3; + level.Lines[line].args[3] = arg4; + level.Lines[line].args[4] = arg5; + } + + protected void SetSectorSpecial(int sectornum, int special) + { + level.sectors[sectornum].special = special; + } + + protected void SetSectorTextureID(int sectornum, int plane, TextureID texture) + { + level.sectors[sectornum].SetTexture(plane, texture); + } + + protected void SetSectorTexture(int sectornum, int plane, String texture) + { + SetSectorTextureID(sectornum, plane, TexMan.CheckForTexture(texture, TexMan.Type_Flat)); + } + + protected void SetSectorLight(int sectornum, int newval) + { + level.sectors[sectornum].SetLightLevel(newval); + } + + protected void SetWallYScale(int line, int side, int texpart, double scale) + { + level.lines[line].sidedef[side].SetTextureYScale(texpart, scale); + } +}