- added generic level post-processing script class

It was extracted from LevelCompatibility class, and native code was moved accordingly
This commit is contained in:
alexey.lysiuk 2019-10-27 13:06:26 +02:00
commit 59bdebb20a
6 changed files with 292 additions and 285 deletions

View file

@ -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<DLevelCompatibility>();
lc->loader = this;
lc->Level = Level;
for(auto cls : PClass::AllClasses)
{
if (cls->IsDescendantOf(RUNTIME_CLASS(DLevelCompatibility)))
{
PFunction *const func = dyn_cast<PFunction>(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);