- scriptified touchplate

This commit is contained in:
Christoph Oelckers 2022-11-19 15:40:35 +01:00
parent 63a8c3148c
commit 046ba1ae0c
17 changed files with 187 additions and 110 deletions

View file

@ -13,3 +13,4 @@ xx(AltHud)
// internal Duke actor classes that need direct checking // internal Duke actor classes that need direct checking
xx(DukeMasterSwitch) xx(DukeMasterSwitch)
xx(DukeTouchplate)

View file

@ -673,89 +673,6 @@ void detonate(DDukeActor *actor, int explosion)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void movetouchplate(DDukeActor* actor, int plate)
{
auto sectp = actor->sector();
int p;
if (actor->temp_data[1] == 1 && actor->spr.hitag >= 0) //Move the sector floor
{
double X = sectp->floorz;
double add = sectp->extra * zmaptoworld;
if (actor->temp_data[3] == 1)
{
if (X >= actor->temp_pos.Z)
{
sectp->setfloorz(X);
actor->temp_data[1] = 0;
}
else
{
sectp->addfloorz(add);
p = checkcursectnums(actor->sector());
if (p >= 0) ps[p].pos.Z += add;
}
}
else
{
if (X <= actor->spr.pos.Z)
{
sectp->setfloorz(actor->spr.pos.Z);
actor->temp_data[1] = 0;
}
else
{
sectp->floorz -= add;
p = checkcursectnums(actor->sector());
if (p >= 0)
ps[p].pos.Z -= add;
}
}
return;
}
if (actor->temp_data[5] == 1) return;
p = checkcursectnums(actor->sector());
if (p >= 0 && (ps[p].on_ground || actor->spr.intangle == 512))
{
if (actor->temp_data[0] == 0 && !check_activator_motion(actor->spr.lotag))
{
actor->temp_data[0] = 1;
actor->temp_data[1] = 1;
actor->temp_data[3] = !actor->temp_data[3];
operatemasterswitches(actor->spr.lotag);
operateactivators(actor->spr.lotag, p);
if (actor->spr.hitag > 0)
{
actor->spr.hitag--;
if (actor->spr.hitag == 0) actor->temp_data[5] = 1;
}
}
}
else actor->temp_data[0] = 0;
if (actor->temp_data[1] == 1)
{
DukeStatIterator it(STAT_STANDABLE);
while (auto act2 = it.Next())
{
if (act2 != actor && act2->spr.picnum == plate && act2->spr.lotag == actor->spr.lotag)
{
act2->temp_data[1] = 1;
act2->temp_data[3] = actor->temp_data[3];
}
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void movecanwithsomething(DDukeActor* actor) void movecanwithsomething(DDukeActor* actor)
{ {
makeitfall(actor); makeitfall(actor);
@ -2429,7 +2346,7 @@ void handle_se30(DDukeActor *actor, int JIBS6)
else else
{ {
if (actor->vel.X == 0) if (actor->vel.X == 0)
operateactivators(actor->spr.hitag + (!actor->temp_data[3]), -1); operateactivators(actor->spr.hitag + (!actor->temp_data[3]), nullptr);
if (actor->vel.X < 16) if (actor->vel.X < 16)
actor->vel.X += 1; actor->vel.X += 1;
} }
@ -2444,7 +2361,7 @@ void handle_se30(DDukeActor *actor, int JIBS6)
else else
{ {
actor->vel.X = 0; actor->vel.X = 0;
operateactivators(actor->spr.hitag + (short)actor->temp_data[3], -1); operateactivators(actor->spr.hitag + (short)actor->temp_data[3], nullptr);
actor->SetOwner(nullptr); actor->SetOwner(nullptr);
actor->spr.angle += DAngle180; actor->spr.angle += DAngle180;
actor->temp_data[4] = 0; actor->temp_data[4] = 0;

View file

@ -849,11 +849,6 @@ void movestandables_d(void)
moveviewscreen(act); moveviewscreen(act);
} }
else if (picnum == TOUCHPLATE)
{
movetouchplate(act, TOUCHPLATE);
}
else if (isIn(picnum, CANWITHSOMETHING, CANWITHSOMETHING2, CANWITHSOMETHING3, CANWITHSOMETHING4)) else if (isIn(picnum, CANWITHSOMETHING, CANWITHSOMETHING2, CANWITHSOMETHING3, CANWITHSOMETHING4))
{ {
movecanwithsomething(act); movecanwithsomething(act);
@ -2417,7 +2412,7 @@ void moveactors_d(void)
if (k == 1) if (k == 1)
{ {
operateactivators(act->spr.lotag, -1); operateactivators(act->spr.lotag, nullptr);
fi.operateforcefields(act, act->spr.lotag); fi.operateforcefields(act, act->spr.lotag);
operatemasterswitches(act->spr.lotag); operatemasterswitches(act->spr.lotag);
} }

View file

@ -732,11 +732,6 @@ void movestandables_r(void)
continue; continue;
} }
else if (picnum == TOUCHPLATE)
{
movetouchplate(act, TOUCHPLATE);
}
else if (picnum == CANWITHSOMETHING) else if (picnum == CANWITHSOMETHING)
{ {
movecanwithsomething(act); movecanwithsomething(act);
@ -3581,7 +3576,7 @@ void fakebubbaspawn(DDukeActor *actor, int g_p)
break; break;
case 4: case 4:
spawn(actor, VIXEN); spawn(actor, VIXEN);
operateactivators(666, g_p); operateactivators(666, &ps[g_p]);
break; break;
} }
} }

View file

@ -32,7 +32,6 @@ void movefta();
void clearcameras(int i, player_struct* p); void clearcameras(int i, player_struct* p);
void RANDOMSCRAP(DDukeActor* i); void RANDOMSCRAP(DDukeActor* i);
void detonate(DDukeActor* i, int explosion); void detonate(DDukeActor* i, int explosion);
void movetouchplate(DDukeActor* i, int plate);
void movecanwithsomething(DDukeActor* i); void movecanwithsomething(DDukeActor* i);
void bounce(DDukeActor* i); void bounce(DDukeActor* i);
void movetongue(DDukeActor* i, int tongue, int jaw); void movetongue(DDukeActor* i, int tongue, int jaw);
@ -139,7 +138,7 @@ void allignwarpelevators(void);
bool isablockdoor(int tileNum); bool isablockdoor(int tileNum);
bool activatewarpelevators(DDukeActor* s, int w); bool activatewarpelevators(DDukeActor* s, int w);
int check_activator_motion(int lotag); int check_activator_motion(int lotag);
void operateactivators(int l, int w); void operateactivators(int l, player_struct* w);
void operateforcefields_common(DDukeActor* s, int low, const std::initializer_list<int>& tiles); void operateforcefields_common(DDukeActor* s, int low, const std::initializer_list<int>& tiles);
void operatemasterswitches(int lotag); void operatemasterswitches(int lotag);
void operatesectors(sectortype* s, DDukeActor* i); void operatesectors(sectortype* s, DDukeActor* i);

View file

@ -1615,7 +1615,7 @@ int ParseState::parse(void)
insptr++; insptr++;
break; break;
case concmd_mamatrigger: case concmd_mamatrigger:
operateactivators(667, g_p); operateactivators(667, &ps[g_p]);
insptr++; insptr++;
break; break;
case concmd_mamaspawn: case concmd_mamaspawn:

View file

@ -1099,7 +1099,7 @@ void operatesectors(sectortype* sptr, DDukeActor *actor)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void operateactivators(int low, int plnum) void operateactivators(int low, player_struct* plr)
{ {
int i, j, k; int i, j, k;
Cycler * p; Cycler * p;
@ -1132,11 +1132,11 @@ void operateactivators(int low, int plnum)
{ {
act->sector()->lotag ^= 16384; act->sector()->lotag ^= 16384;
if (plnum >= 0) if (plr)
{ {
if (act->sector()->lotag & 16384) if (act->sector()->lotag & 16384)
FTA(4, &ps[plnum]); FTA(4, plr);
else FTA(8, &ps[plnum]); else FTA(8, plr);
} }
} }
else else
@ -1204,7 +1204,6 @@ void operatemasterswitches(int low)
if (ismasterswitch(act2) && act2->spr.lotag == low && act2->spr.yint == 0) if (ismasterswitch(act2) && act2->spr.lotag == low && act2->spr.yint == 0)
{ {
act2->spr.yint = 1; act2->spr.yint = 1;
Printf("triggering %d\n", act2->time);
} }
} }
} }

View file

@ -578,7 +578,7 @@ bool checkhitswitch_d(int snum, walltype* wwal, DDukeActor *act)
} }
} }
operateactivators(lotag, snum); operateactivators(lotag, &ps[snum]);
fi.operateforcefields(ps[snum].GetActor(), lotag); fi.operateforcefields(ps[snum].GetActor(), lotag);
operatemasterswitches(lotag); operatemasterswitches(lotag);
@ -622,7 +622,7 @@ void activatebysector_d(sectortype* sect, DDukeActor* activator)
{ {
if (act->spr.picnum == ACTIVATOR) if (act->spr.picnum == ACTIVATOR)
{ {
operateactivators(act->spr.lotag, -1); operateactivators(act->spr.lotag, nullptr);
didit = 1; didit = 1;
// return; // return;
} }

View file

@ -771,7 +771,7 @@ bool checkhitswitch_r(int snum, walltype* wwal, DDukeActor* act)
{ {
if (ps[snum].SeaSick == 0) if (ps[snum].SeaSick == 0)
ps[snum].SeaSick = 350; ps[snum].SeaSick = 350;
operateactivators(668, snum); operateactivators(668, &ps[snum]);
operatemasterswitches(668); operatemasterswitches(668);
S_PlayActorSound(328, ps[snum].GetActor()); S_PlayActorSound(328, ps[snum].GetActor());
return 1; return 1;
@ -867,7 +867,7 @@ bool checkhitswitch_r(int snum, walltype* wwal, DDukeActor* act)
} }
} }
operateactivators(lotag, snum); operateactivators(lotag, &ps[snum]);
fi.operateforcefields(ps[snum].GetActor(), lotag); fi.operateforcefields(ps[snum].GetActor(), lotag);
operatemasterswitches(lotag); operatemasterswitches(lotag);
@ -909,7 +909,7 @@ void activatebysector_r(sectortype* sect, DDukeActor* activator)
{ {
if (act->spr.picnum == ACTIVATOR) if (act->spr.picnum == ACTIVATOR)
{ {
operateactivators(act->spr.lotag, -1); operateactivators(act->spr.lotag, nullptr);
// return; // return;
} }
} }

View file

@ -654,6 +654,21 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, setpos, dukeplayer_setpos)
return 0; return 0;
} }
void dukeplayer_addpos(player_struct* self, double x, double y, double z)
{
self->pos += { x, y, z };
}
DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, addpos, dukeplayer_addpos)
{
PARAM_SELF_STRUCT_PROLOGUE(player_struct);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
dukeplayer_addpos(self, x, y, z);
return 0;
}
void dukeplayer_settargetangle(player_struct* self, double a, int backup) void dukeplayer_settargetangle(player_struct* self, double a, int backup)
{ {
self->angle.settarget(DAngle::fromDeg(a), backup); self->angle.settarget(DAngle::fromDeg(a), backup);
@ -775,6 +790,30 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, SpawnActor, DukeLevel_SpawnActor)
ACTION_RETURN_POINTER(DukeLevel_SpawnActor(self, sect, x, y, z, static_cast<PClassActor*>(type), shade, scalex, scaley, angle, vel, zvel, owner, stat)); ACTION_RETURN_POINTER(DukeLevel_SpawnActor(self, sect, x, y, z, static_cast<PClassActor*>(type), shade, scalex, scaley, angle, vel, zvel, owner, stat));
} }
DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, check_activator_motion, check_activator_motion)
{
PARAM_PROLOGUE;
PARAM_INT(lotag);
ACTION_RETURN_INT(check_activator_motion(lotag));
}
DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, operatemasterswitches, operatemasterswitches)
{
PARAM_PROLOGUE;
PARAM_INT(lotag);
operatemasterswitches(lotag);
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, operateactivators, operateactivators)
{
PARAM_PROLOGUE;
PARAM_INT(lotag);
PARAM_POINTER(p, player_struct);
operateactivators(lotag, p);
return 0;
}
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, playerfriction); DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, playerfriction);
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, gravity); DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, gravity);
DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, respawnactortime); DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, respawnactortime);

View file

@ -1,6 +1,7 @@
spawnclasses spawnclasses
{ {
8 = DukeMasterSwitch 8 = DukeMasterSwitch
3 = DukeTouchplate
1221 = DukeCranePole 1221 = DukeCranePole
1222 = DukeCrane 1222 = DukeCrane

View file

@ -1,6 +1,7 @@
spawnclasses spawnclasses
{ {
8 = DukeMasterSwitch 8 = DukeMasterSwitch
3 = DukeTouchplate
1298 = DukeCranePole 1298 = DukeCranePole
1299 = DukeCrane 1299 = DukeCrane

View file

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

View file

@ -7,6 +7,8 @@ enum EClipMask
const MAXPLAYERS = 8; const MAXPLAYERS = 8;
const MAXSTATUS = 1024; const MAXSTATUS = 1024;
const zmaptoworld = (1. / 256.);
const maptoworld = (1. / 16.);
class CoreActor native class CoreActor native
{ {

View file

@ -0,0 +1,123 @@
class DukeTouchPlate : DukeActor
{
default
{
statnum STAT_STANDABLE;
}
private bool checkspawn()
{
if (!Raze.isWorldTour())
{
if (self.pal && ud.multimode > 1) return false;
}
else { // Twentieth Anniversary World Tour addition - needs to be guarded because some mods surely will run afoul of it
if ((self.pal == 1 && ud.multimode > 1) // Single-game Only
|| (self.pal == 2 && (ud.multimode == 1 || (ud.multimode > 1 && ud.coop != 1))) // Co-op Only
|| (self.pal == 3 && (ud.multimode == 1 || (ud.multimode > 1 && ud.coop == 1)))) // Dukematch Only
{
return false;
}
}
return true;
}
override void Initialize()
{
let sectp = self.sector;
self.temp_data[2] = sectp.floorz;
if (sectp.lotag != 1 && sectp.lotag != 2)
sectp.setfloorz(self.pos.Z);
if (!checkspawn())
{
self.Scale = (0, 0);
self.ChangeStat(STAT_MISC);
return;
}
self.cstat |= CSTAT_SPRITE_INVISIBLE;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
override void Tick()
{
let sectp = self.sector;
DukePlayer p;
if (self.temp_data[1] == 1 && self.hitag >= 0) //Move the sector floor
{
double Z = sectp.floorz;
double add = sectp.extra * zmaptoworld;
if (self.temp_data[3] == 1)
{
if (Z >= self.temp_pos.Z)
{
sectp.setfloorz(Z);
self.temp_data[1] = 0;
}
else
{
sectp.addfloorz(add);
p = Duke.checkcursectnums(sectp);
if (p != null) p.addpos((0, 0, add));
}
}
else
{
if (Z <= self.pos.Z)
{
sectp.setfloorz(self.pos.Z);
self.temp_data[1] = 0;
}
else
{
sectp.addfloorz(-add);
p = Duke.checkcursectnums(sectp);
if (p != null) p.addpos((0, 0, -add));
}
}
return;
}
if (self.temp_data[5] == 1) return;
p = Duke.checkcursectnums(sectp);
if (p != null && (p.on_ground || self.intangle == 512))
{
if (self.temp_data[0] == 0 && !dlevel.check_activator_motion(self.lotag))
{
self.temp_data[0] = 1;
self.temp_data[1] = 1;
self.temp_data[3] = !self.temp_data[3];
dlevel.operatemasterswitches(self.lotag);
dlevel.operateactivators(self.lotag, p);
if (self.hitag > 0)
{
self.hitag--;
if (self.hitag == 0) self.temp_data[5] = 1;
}
}
}
else self.temp_data[0] = 0;
if (self.temp_data[1] == 1)
{
DukeStatIterator it;
for(let act2 = it.first(STAT_STANDABLE); act2; act2 = it.Next())
{
if (act2 != self && act2 is 'DukeTouchPlate' && act2.lotag == self.lotag)
{
act2.temp_data[1] = 1;
act2.temp_data[3] = self.temp_data[3];
}
}
}
}
}

View file

@ -172,6 +172,9 @@ extend struct _
struct DukeLevel struct DukeLevel
{ {
native DukeActor SpawnActor(sectortype sect, Vector3 pos, class<DukeActor> type, int shade, Vector2 scale, double angle, double vel, double zvel, DukeActor owner, int stat = -1); native DukeActor SpawnActor(sectortype sect, Vector3 pos, class<DukeActor> type, int shade, Vector2 scale, double angle, double vel, double zvel, DukeActor owner, int stat = -1);
native static int check_activator_motion(int lotag);
native static void operatemasterswitches(int lotag);
native static void operateactivators(int lotag, DukePlayer p);
} }
struct DukeStatIterator struct DukeStatIterator

View file

@ -277,6 +277,7 @@ struct DukePlayer native
native void backuppos(); native void backuppos();
native void backupxyz(); native void backupxyz();
native void setpos(Vector3 pos); native void setpos(Vector3 pos);
native void addpos(Vector3 pos);
native void settargetangle(double angle, bool backup = false); native void settargetangle(double angle, bool backup = false);
native double angle(); native double angle();