- converted the masterswitch.

This commit is contained in:
Christoph Oelckers 2022-11-19 09:02:40 +01:00
parent b106fb693a
commit 5ae7011e41
18 changed files with 158 additions and 78 deletions

View file

@ -10,3 +10,6 @@ xx(MultiMenu)
xx(RazeStatusBar)
xx(zoomsize)
xx(AltHud)
// internal Duke actor classes that need direct checking
xx(DukeMasterSwitch)

View file

@ -673,59 +673,6 @@ void detonate(DDukeActor *actor, int explosion)
//
//---------------------------------------------------------------------------
void movemasterswitch(DDukeActor *actor)
{
if (actor->spr.yint == 1)
{
actor->spr.hitag--;
if (actor->spr.hitag <= 0)
{
operatesectors(actor->sector(), actor);
DukeSectIterator it(actor->sector());
while (auto effector = it.Next())
{
if (effector->spr.statnum == STAT_EFFECTOR)
{
switch (effector->spr.lotag)
{
case SE_2_EARTHQUAKE:
case SE_21_DROP_FLOOR:
case SE_31_FLOOR_RISE_FALL:
case SE_32_CEILING_RISE_FALL:
case SE_36_PROJ_SHOOTER:
effector->temp_data[0] = 1;
break;
case SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT:
effector->temp_data[4] = 1;
break;
}
}
else if (effector->spr.statnum == STAT_STANDABLE)
{
if (actorflag(effector, SFLAG2_BRIGHTEXPLODE)) // _SEENINE_ and _OOZFILTER_
{
effector->spr.shade = -31;
}
}
}
// we cannot delete this because it may be used as a sound source.
// This originally depended on undefined behavior as the deleted sprite was still used for the sound
// with no checking if it got reused in the mean time.
actor->spr.picnum = 0; // give it a picnum without any behavior attached, just in case
actor->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
actor->spr.cstat2 |= CSTAT2_SPRITE_NOFIND;
ChangeActorStat(actor, STAT_REMOVED);
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void movetrash(DDukeActor *actor)
{
if (actor->vel.X == 0) actor->vel.X = 1 / 16.;
@ -1530,7 +1477,7 @@ void reactor(DDukeActor* const actor, int REACTOR, int REACTOR2, int REACTORBURN
DukeStatIterator it(STAT_STANDABLE);
while (auto a2 = it.Next())
{
if (a2->spr.picnum == MASTERSWITCH)
if (ismasterswitch(a2))
if (a2->spr.hitag == actor->spr.hitag)
if (a2->spr.yint == 0)
a2->spr.yint = 1;

View file

@ -945,11 +945,6 @@ void movestandables_d(void)
continue;
}
else if (picnum == MASTERSWITCH)
{
movemasterswitch(act);
}
else if (picnum == VIEWSCREEN || picnum == VIEWSCREEN2)
{
moveviewscreen(act);

View file

@ -793,11 +793,6 @@ void movestandables_r(void)
continue;
}
else if (picnum == MASTERSWITCH)
{
movemasterswitch(act);
}
else if (picnum == TRASH)
{
movetrash(act);

View file

@ -32,7 +32,6 @@ void movefta();
void clearcameras(int i, player_struct* p);
void RANDOMSCRAP(DDukeActor* i);
void detonate(DDukeActor* i, int explosion);
void movemasterswitch(DDukeActor* i);
void movetrash(DDukeActor* i);
void movewaterdrip(DDukeActor* i, int drip);
void movedoorshock(DDukeActor* i);

View file

@ -11,6 +11,13 @@ inline int rnd(int X)
return ((krand() >> 8) >= (255 - (X)));
}
// internal controller classes can be directly checked for by type
inline int ismasterswitch(DDukeActor* actor)
{
// The STAT_REMOVED check here is important!
return actor->GetClass()->TypeName == NAME_DukeMasterSwitch && actor->spr.statnum != STAT_REMOVED;
}
inline int badguypic(int const tileNum)
{
return ((gs.actorinfo[tileNum].flags & (SFLAG_INTERNAL_BADGUY | SFLAG_BADGUY)) != 0);

View file

@ -50,7 +50,6 @@ void premapcontroller(DDukeActor* ac)
case ACTIVATOR:
case ACTIVATORLOCKED:
case LOCATORS:
case MASTERSWITCH:
case MUSICANDSFX:
case RESPAWN:
case SECTOREFFECTOR:
@ -965,6 +964,12 @@ static TArray<DDukeActor*> spawnactors(SpawnSpriteDef& sprites)
spawns.Pop();
continue;
}
if (i == 210)
{
int a = 0;
}
auto sprt = &sprites.sprites[i];
auto info = spawnMap.CheckKey(sprt->picnum);
auto actor = static_cast<DDukeActor*>(InsertActor(info? info->Class() : RUNTIME_CLASS(DDukeActor), sprt->sectp, sprt->statnum));

View file

@ -1201,7 +1201,7 @@ void operatemasterswitches(int low)
DukeStatIterator it(STAT_STANDABLE);
while (auto act2 = it.Next())
{
if (act2->spr.picnum == MASTERSWITCH && act2->spr.lotag == low && act2->spr.yint == 0)
if (ismasterswitch(act2) && act2->spr.lotag == low && act2->spr.yint == 0)
act2->spr.yint = 1;
}
}

View file

@ -1731,7 +1731,7 @@ void checksectors_d(int snum)
DukeSectIterator it(near.hitSector);
while (auto act = it.Next())
{
if (act->spr.picnum == ACTIVATOR || act->spr.picnum == MASTERSWITCH)
if (act->spr.picnum == ACTIVATOR || ismasterswitch(act))
return;
}
operatesectors(near.hitSector, p->GetActor());
@ -1743,7 +1743,7 @@ void checksectors_d(int snum)
DukeSectIterator it(p->GetActor()->sector());
while (auto act = it.Next())
{
if (act->spr.picnum == ACTIVATOR || act->spr.picnum == MASTERSWITCH) return;
if (act->spr.picnum == ACTIVATOR || ismasterswitch(act)) return;
}
operatesectors(p->GetActor()->sector(), p->GetActor());
}

View file

@ -2668,7 +2668,7 @@ void checksectors_r(int snum)
DukeSectIterator it(near.hitSector);
while (auto act = it.Next())
{
if (act->spr.picnum == ACTIVATOR || act->spr.picnum == MASTERSWITCH)
if (act->spr.picnum == ACTIVATOR || ismasterswitch(act))
return;
}
if (haskey(near.hitSector, snum))
@ -2689,7 +2689,7 @@ void checksectors_r(int snum)
DukeSectIterator it(p->GetActor()->sector());
while (auto act = it.Next())
{
if (act->spr.picnum == ACTIVATOR || act->spr.picnum == MASTERSWITCH)
if (act->spr.picnum == ACTIVATOR || ismasterswitch(act))
return;
}
if (haskey(near.hitSector, snum))

View file

@ -704,12 +704,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
case BOLT1 + 1:
case BOLT1 + 2:
case BOLT1 + 3:
act->temp_pos.X = act->spr.scale.X;
act->temp_pos.Y = act->spr.scale.Y;
[[fallthrough]];
case MASTERSWITCH:
if (act->spr.picnum == MASTERSWITCH)
act->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
act->temp_pos.XY() = act->spr.scale;
act->spr.yint = 0;
ChangeActorStat(act, STAT_STANDABLE);
break;

View file

@ -357,6 +357,19 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, checkhitdefault, DukeActor_checkhitdef
return 0;
}
void DukeActor_operatesectors(DDukeActor* origin, sectortype* sector)
{
operatesectors(sector, origin);
}
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, operatesectors, DukeActor_operatesectors)
{
PARAM_SELF_PROLOGUE(DDukeActor);
PARAM_POINTER(sec, sectortype);
operatesectors(sec, self);
return 0;
}
// temporary helpers to hide the fact that these flags are not part of the actor yet.
DEFINE_ACTION_FUNCTION(DDukeActor, actorflag1)
{

View file

@ -1,5 +1,7 @@
spawnclasses
{
8 = DukeMasterSwitch
1221 = DukeCranePole
1222 = DukeCrane
563 = DukeWaterFountain

View file

@ -1,5 +1,7 @@
spawnclasses
{
8 = DukeMasterSwitch
1298 = DukeCranePole
1299 = DukeCrane
1092 = DukeWaterFountain

View file

@ -50,6 +50,7 @@ version "4.10"
#include "zscript/games/duke/ui/screens.zs"
#include "zscript/games/duke/ui/cutscenes.zs"
#include "zscript/games/duke/ui/menu.zs"
#include "zscript/games/duke/actors/masterswitch.zs"
#include "zscript/games/duke/actors/crane.zs"
#include "zscript/games/duke/actors/waterfountain.zs"
#include "zscript/games/duke/actors/flammables.zs"

View file

@ -6,6 +6,7 @@ enum EClipMask
};
const MAXPLAYERS = 8;
const MAXSTATUS = 1024;
class CoreActor native
{
@ -54,4 +55,3 @@ class CoreActor native
native void setPosition(Vector3 pos);
native void setPositionZ(Vector3 pos);
}

View file

@ -0,0 +1,60 @@
class DukeMasterSwitch : DukeActor
{
default
{
statnum STAT_STANDABLE;
}
override void Initialize()
{
self.cstat = CSTAT_SPRITE_INVISIBLE;
self.yint = 0;
}
override void Tick()
{
if (self.yint == 1 && self.statnum == STAT_STANDABLE)
{
self.hitag--;
if (self.hitag <= 0)
{
self.operatesectors(self.sector);
DukeSectIterator it;
for (let effector = it.First(self.sector); effector; effector = it.Next())
{
if (effector.statnum == STAT_EFFECTOR)
{
// Todo: Once the effectors have been ported, do this with a virtual that can be overridden by custom effects.
switch (effector.lotag)
{
case SE_2_EARTHQUAKE:
case SE_21_DROP_FLOOR:
case SE_31_FLOOR_RISE_FALL:
case SE_32_CEILING_RISE_FALL:
case SE_36_PROJ_SHOOTER:
effector.temp_data[0] = 1;
break;
case SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT:
effector.temp_data[4] = 1;
break;
}
}
else //if (effector.statnum == STAT_STANDABLE) this check is not really needed.
{
if (effector.actorflag2(SFLAG2_BRIGHTEXPLODE)) // SEENINE and OOZFILTER
{
effector.shade = -31;
}
}
}
// we cannot delete this actor because it may be used as a sound source.
// This originally depended on undefined behavior as the deleted sprite was still used for the sound
// with no checking if it got reused in the mean time.
self.cstat |= CSTAT_SPRITE_INVISIBLE;
self.cstat2 |= CSTAT2_SPRITE_NOFIND;
self.ChangeStat(STAT_REMOVED);
}
}
}
}

View file

@ -1,3 +1,55 @@
// sector effector lotags. Preferably these should be eliminated once SE's get converted to classes. Until then we still need these.
enum EEffectorTypes
{
SE_0_ROTATING_SECTOR = 0,
SE_1_PIVOT = 1,
SE_2_EARTHQUAKE = 2,
SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT = 3,
SE_4_RANDOM_LIGHTS = 4,
SE_5_BOSS = 5,
SE_6_SUBWAY = 6,
SE_7_TELEPORT = 7,
SE_8_UP_OPEN_DOOR_LIGHTS = 8,
SE_9_DOWN_OPEN_DOOR_LIGHTS = 9,
SE_10_DOOR_AUTO_CLOSE = 10,
SE_11_SWINGING_DOOR = 11,
SE_12_LIGHT_SWITCH = 12,
SE_13_EXPLOSIVE = 13,
SE_14_SUBWAY_CAR = 14,
SE_15_SLIDING_DOOR = 15,
SE_16_REACTOR = 16,
SE_17_WARP_ELEVATOR = 17,
SE_18_INCREMENTAL_SECTOR_RISE_FALL = 18,
SE_19_EXPLOSION_LOWERS_CEILING = 19,
SE_20_STRETCH_BRIDGE = 20,
SE_21_DROP_FLOOR = 21,
SE_22_TEETH_DOOR = 22,
SE_23_ONE_WAY_TELEPORT = 23,
SE_24_CONVEYOR = 24,
SE_25_PISTON = 25,
SE_26 = 26,
SE_27_DEMO_CAM = 27,
SE_28_LIGHTNING = 28,
SE_29_WAVES = 29,
SE_30_TWO_WAY_TRAIN = 30,
SE_31_FLOOR_RISE_FALL = 31,
SE_32_CEILING_RISE_FALL = 32,
SE_33_QUAKE_DEBRIS = 33,
SE_34 = 34,
SE_35 = 35,
SE_36_PROJ_SHOOTER = 36,
SE_47_LIGHT_SWITCH = 47,
SE_48_LIGHT_SWITCH = 48,
SE_49_POINT_LIGHT = 49,
SE_50_SPOT_LIGHT = 50,
SE_128_GLASS_BREAKING = 128,
SE_130 = 130,
SE_131 = 131,
SE_156_CONVEYOR_NOSCROLL = 156,
};
class DukeActor : CoreActor native
{
enum EStatnums
@ -21,6 +73,9 @@ class DukeActor : CoreActor native
STAT_DESTRUCT = 100,
STAT_BOWLING = 105,
STAT_REMOVED = MAXSTATUS-2,
};
native void SetSpritesetImage(int index);
@ -78,6 +133,7 @@ class DukeActor : CoreActor native
native void makeitfall();
native void detonate(name type);
native void checkhitdefault(DukeActor proj);
native void operatesectors(sectortype sec);
virtual void BeginPlay() {}
virtual void Initialize() {}