- Duke: scriptified the crane

This commit is contained in:
Christoph Oelckers 2022-11-13 18:55:32 +01:00
parent 660c546266
commit f23ddc28f0
18 changed files with 266 additions and 291 deletions

View file

@ -614,191 +614,6 @@ void movefx(void)
}
}
//---------------------------------------------------------------------------
//
//
//---------------------------------------------------------------------------
void movecrane(DDukeActor *actor, int crane)
{
const double CRANE_STEP = 16.;
auto sectp = actor->sector();
double xx;
auto& cpt = cranes[actor->temp_data[4]];
//actor->temp_data[0] = state
//actor->temp_data[1] = checking sector number
if(actor->vel.X != 0) getglobalz(actor);
if (actor->temp_data[0] == 0) //Waiting to check the sector
{
DukeSectIterator it(actor->temp_sect);
while (auto a2 = it.Next())
{
switch (a2->spr.statnum)
{
case STAT_ACTOR:
case STAT_ZOMBIEACTOR:
case STAT_STANDABLE:
case STAT_PLAYER:
actor->spr.angle = (cpt.pole - actor->spr.pos.XY()).Angle();
SetActor(a2, DVector3( cpt.pole.X, cpt.pole.Y, a2->spr.pos.Z ));
actor->temp_data[0]++;
return;
}
}
}
else if (actor->temp_data[0] == 1)
{
if (actor->vel.X < 11.5)
{
actor->spr.picnum = crane + 1;
actor->vel.X += 0.5;
}
//IFMOVING; // JBF 20040825: see my rant above about this
ssp(actor, CLIPMASK0);
if (actor->sector() == actor->temp_sect)
actor->temp_data[0]++;
}
else if (actor->temp_data[0] == 2 || actor->temp_data[0] == 7)
{
actor->spr.pos.Z += 6;
if (actor->temp_data[0] == 2)
{
if ((sectp->floorz - actor->spr.pos.Z) < 64)
if (actor->spr.picnum > crane) actor->spr.picnum--;
if ((sectp->floorz - actor->spr.pos.Z) < 20)
actor->temp_data[0]++;
}
if (actor->temp_data[0] == 7)
{
if ((sectp->floorz - actor->spr.pos.Z) < 64)
{
if (actor->spr.picnum > crane) actor->spr.picnum--;
else
{
if (actor->IsActiveCrane())
{
int p = findplayer(actor, &xx);
S_PlayActorSound(isRR() ? 390 : DUKE_GRUNT, ps[p].GetActor());
if (ps[p].on_crane == actor)
ps[p].on_crane = nullptr;
}
actor->temp_data[0]++;
actor->SetActiveCrane(false);
}
}
}
}
else if (actor->temp_data[0] == 3)
{
actor->spr.picnum++;
if (actor->spr.picnum == (crane + 2))
{
int p = checkcursectnums(actor->temp_sect);
if (p >= 0 && ps[p].on_ground)
{
actor->SetActiveCrane(true);
ps[p].on_crane = actor;
S_PlayActorSound(isRR() ? 390 : DUKE_GRUNT, ps[p].GetActor());
ps[p].angle.settarget(actor->spr.angle + DAngle180);
}
else
{
DukeSectIterator it(actor->temp_sect);
while (auto a2 = it.Next())
{
switch (a2->spr.statnum)
{
case 1:
case 6:
actor->SetOwner(a2);
break;
}
}
}
actor->temp_data[0]++;//Grabbed the sprite
actor->temp_data[2] = 0;
return;
}
}
else if (actor->temp_data[0] == 4) //Delay before going up
{
actor->temp_data[2]++;
if (actor->temp_data[2] > 10)
actor->temp_data[0]++;
}
else if (actor->temp_data[0] == 5 || actor->temp_data[0] == 8)
{
if (actor->temp_data[0] == 8 && actor->spr.picnum < (crane + 2))
if ((sectp->floorz - actor->spr.pos.Z) > 32)
actor->spr.picnum++;
if (actor->spr.pos.Z < cpt.pos.Z)
{
actor->temp_data[0]++;
actor->vel.X = 0;
}
else
actor->spr.pos.Z -= 6;
}
else if (actor->temp_data[0] == 6)
{
if (actor->vel.X < 12)
actor->vel.X += 0.5;
actor->spr.angle = (cpt.pos.XY() - actor->spr.pos.XY()).Angle();
ssp(actor, CLIPMASK0);
if (((actor->spr.pos.X - cpt.pos.X) * (actor->spr.pos.X - cpt.pos.X) + (actor->spr.pos.Y - cpt.pos.Y) * (actor->spr.pos.Y - cpt.pos.Y)) < (8 * 8))
actor->temp_data[0]++;
}
else if (actor->temp_data[0] == 9)
actor->temp_data[0] = 0;
if (cpt.poleactor)
SetActor(cpt.poleactor, actor->spr.pos.plusZ(-34));
auto Owner = actor->GetOwner();
if (Owner != nullptr || actor->IsActiveCrane())
{
int p = findplayer(actor, &xx);
int j = fi.ifhitbyweapon(actor);
if (j >= 0)
{
if (actor->IsActiveCrane())
if (ps[p].on_crane == actor)
ps[p].on_crane = nullptr;
actor->SetActiveCrane(false);
actor->spr.picnum = crane;
return;
}
if (Owner != nullptr)
{
SetActor(Owner, actor->spr.pos);
Owner->opos = actor->spr.pos;
actor->vel.Z = 0;
}
else if (actor->IsActiveCrane())
{
auto ang = ps[p].angle.ang;
ps[p].backupxyz();
ps[p].pos.XY() = actor->spr.pos.XY() - CRANE_STEP * ang.ToVector();
ps[p].pos.Z = actor->spr.pos.Z + 2;
SetActor(ps[p].GetActor(), ps[p].pos);
ps[p].setCursector(ps[p].GetActor()->sector());
}
}
}
//---------------------------------------------------------------------------
//
//

View file

@ -1187,11 +1187,6 @@ void movestandables_d(void)
CallTick(act);
continue;
}
if (picnum >= CRANE && picnum <= CRANE +3)
{
movecrane(act, CRANE);
}
else if (picnum >= WATERFOUNTAIN && picnum <= WATERFOUNTAIN + 3)
{
movefountain(act, WATERFOUNTAIN);

View file

@ -825,10 +825,6 @@ void movestandables_r(void)
CallTick(act);
continue;
}
if (picnum >= CRANE && picnum <= CRANE +3)
{
movecrane(act, CRANE);
}
else if (picnum >= WATERFOUNTAIN && picnum <= WATERFOUNTAIN + 3)
{
@ -3900,6 +3896,7 @@ void destroyit(DDukeActor *actor)
destsect->lotag = srcsect->lotag;
destsect->hitag = srcsect->hitag;
destsect->extra = srcsect->extra;
destsect->dirty = EDirty::AllDirty;
}
}
it1.Reset(actor->sector());

View file

@ -196,7 +196,6 @@ void spawntransporter(DDukeActor* actj, DDukeActor* acti, bool beam);
int spawnbloodpoolpart1(DDukeActor* acti);
void initfootprint(DDukeActor* actj, DDukeActor* acti);
void initshell(DDukeActor* actj, DDukeActor* acti, bool isshell);
void initcrane(DDukeActor* actj, DDukeActor* acti, int CRANEPOLE);
void initwaterdrip(DDukeActor* actj, DDukeActor* acti);
int initreactor(DDukeActor* actj, DDukeActor* acti, bool isrecon);
void spawneffector(DDukeActor* actor, TArray<DDukeActor*>* actors);

View file

@ -80,7 +80,6 @@ static void markgcroots()
GC::MarkArray(spriteq, countof(spriteq));
GC::Mark(currentCommentarySprite);
GC::Mark(ud.cameraactor);
for (auto& crn : cranes) GC::Mark(crn.poleactor);
for (auto& pl : ps)
{
GC::Mark(pl.actor);

View file

@ -85,7 +85,6 @@ int playerswhenstarted; // why is this needed?
int show_shareware; // display only.
int rtsplaying; // RTS playback state
TArray<DVector2> mspos;
TArray<CraneDef> cranes;
TArray<animate> animates;
bool sound445done; // used in checksectors_r. This was local state inside a function, but this must be maintained globally and serialized

View file

@ -129,7 +129,6 @@ extern short ambientlotag[64];
extern short ambienthitag[64];
extern unsigned ambientfx;
extern TArray<DVector2> mspos;
extern TArray<CraneDef> cranes;
extern int WindTime;
extern DAngle WindDir;
extern short fakebubba_spawn, mamaspawn_count, banjosound;

View file

@ -452,7 +452,6 @@ void resetprestat(int snum,int g)
paused = 0;
ud.cameraactor =nullptr;
mspos.Clear();
cranes.Clear();
camsprite =nullptr;
earthquaketime = 0;

View file

@ -47,21 +47,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, GameVarValue& w, G
void lava_serialize(FSerializer& arc);
void SerializeGameVars(FSerializer &arc);
FSerializer& Serialize(FSerializer& arc, const char* keyname, CraneDef& w, CraneDef* def)
{
if (arc.BeginObject(keyname))
{
arc("x", w.pos.X)
("y", w.pos.Y)
("z", w.pos.Z)
("polex", w.pole.X)
("poley", w.pole.Y)
("pole", w.poleactor)
.EndObject();
}
return arc;
}
FSerializer& Serialize(FSerializer& arc, const char* keyname, animwalltype& w, animwalltype* def)
{
if (arc.BeginObject(keyname))
@ -373,7 +358,6 @@ void GameInterface::SerializeGameState(FSerializer& arc)
("rtsplaying", rtsplaying)
//("tempwallptr", tempwallptr)
("cranes", cranes)
("sound445done", sound445done)
.Array("players", ps, ud.multimode)
("spriteqamount", spriteqamount)

View file

@ -111,6 +111,7 @@ DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, int s_pn, in
act->spsmooth = {};
return act;
}
DDukeActor* SpawnActor(sectortype* whatsectp, const DVector3& pos, int s_pn, int8_t s_shd, const DVector2& scale, DAngle s_ang, double s_vel, double s_zvel, DDukeActor* s_ow, int8_t s_stat)
@ -120,7 +121,6 @@ DDukeActor* SpawnActor(sectortype* whatsectp, const DVector3& pos, int s_pn, int
return actor;
}
//---------------------------------------------------------------------------
//
//
@ -452,51 +452,6 @@ void initshell(DDukeActor* actj, DDukeActor* act, bool isshell)
//
//---------------------------------------------------------------------------
void initcrane(DDukeActor* actj, DDukeActor* act, int CRANEPOLE)
{
auto sect = act->sector();
act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL | CSTAT_SPRITE_ONE_SIDE;
act->spr.picnum += 2;
act->spr.pos.Z = sect->ceilingz + 48;
act->temp_data[4] = cranes.Reserve(1);
auto& apt = cranes[act->temp_data[4]];
apt.pos = act->spr.pos;
apt.poleactor = nullptr;
DukeStatIterator it(STAT_DEFAULT);
while (auto actk = it.Next())
{
if (actk->spr.picnum == CRANEPOLE && act->spr.hitag == actk->spr.hitag)
{
apt.poleactor = actk;
act->temp_sect = actk->sector();
actk->spr.scale = DVector2(0.75, 2);
apt.pole = actk->spr.pos.XY();
actk->spr.pos = act->spr.pos;
actk->spr.shade = act->spr.shade;
SetActor(actk, actk->spr.pos);
break;
}
}
act->SetOwner(nullptr);
act->spr.extra = 8;
ChangeActorStat(act, STAT_STANDABLE);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void initwaterdrip(DDukeActor* actj, DDukeActor* actor)
{
if (actj && (actj->spr.statnum == 10 || actj->spr.statnum == 1))

View file

@ -45,6 +45,8 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
{
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
{
auto sset = act->spriteset();
if (sset.Size() > 0) act->spr.picnum = sset[0];
CallInitialize(act);
return act;
}
@ -683,10 +685,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
ChangeActorStat(act, STAT_MISC);
break;
case CRANE:
initcrane(actj, act, CRANEPOLE);
break;
case WATERDRIP:
initwaterdrip(actj, act);
break;

View file

@ -39,6 +39,8 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
{
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
{
auto sset = act->spriteset();
if (sset.Size() > 0) act->spr.picnum = sset[0];
CallInitialize(act);
return act;
}
@ -673,9 +675,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
act->spr.scale = DVector2(0.5, 0.5);
ChangeActorStat(act, STAT_MISC);
break;
case CRANE:
initcrane(actj, act, CRANEPOLE);
break;
case WATERDRIP:
initwaterdrip(actj, act);
break;

View file

@ -93,17 +93,6 @@ public:
hitOwnerActor = a;
}
inline bool IsActiveCrane()
{
return spr.intowner == -2;
}
inline void SetActiveCrane(bool yes)
{
ownerActor = nullptr;
spr.intowner = yes ? -2 : -1;
}
int PlayerIndex() const
{
// only valid for real players - just here to abstract yvel.
@ -185,13 +174,6 @@ struct player_orig
sectortype* os;
};
struct CraneDef
{
DVector3 pos;
DVector2 pole;
TObjPtr<DDukeActor*> poleactor;
};
struct player_struct
{
DVector3 vel;

View file

@ -1,5 +1,5 @@
spawnclasses
{
//1221 = DukeCranePole
//1222 = DukeCrane
1221 = DukeCranePole
1222 = DukeCrane
}

View file

@ -1,5 +1,5 @@
spawnclasses
{
//1298 = DukeCranePole
//1299 = DukeCrane
1298 = DukeCranePole
1299 = DukeCrane
}

View file

@ -50,6 +50,7 @@ version "4.9"
#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/crane.zs"
#include "zscript/games/blood/bloodgame.zs"
#include "zscript/games/blood/ui/menu.zs"

View file

@ -11,7 +11,7 @@ class CoreActor native
native int16 cstat;
//native int16 picnum; // access is disabled to allow later refactoring.
native readonly Vector3 pos;
native Vector3 pos;
native readonly int16 statnum;
native int16 intangle;
native int16 xint;

View file

@ -0,0 +1,254 @@
class DukeCrane : DukeActor
{
default
{
spriteset "CRANE", "CRANE1", "CRANE2";
statnum STAT_STANDABLE;
}
enum EPic
{
PIC_DEFAULT = 0,
PIC_OPEN = 1,
PIC_CLOSED = 2,
}
Vector3 cranepos;
Vector2 polepos;
DukeActor poleactor;
bool isactive;
const CRANE_STEP = 16.;
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
override void Initialize()
{
let sect = self.sector;
self.cstat |= CSTAT_SPRITE_BLOCK_ALL | CSTAT_SPRITE_ONE_SIDE;
self.setSpritePic(PIC_CLOSED);
self.pos.Z = sect.ceilingz + 48;
self.cranepos = self.pos;
self.poleactor = null;
DukeStatIterator it;
for (DukeActor poleactor = it.first(DukeActor.STAT_DEFAULT); poleactor; poleactor = it.next())
{
if (self.hitag == poleactor.hitag && poleactor is "DukeCranePole")
{
self.poleactor = poleactor;
self.temp_sect = poleactor.sector;
poleactor.scale = (0.75, 2);
self.polepos = poleactor.pos.XY;
poleactor.shade = self.shade;
poleactor.SetPosition(self.pos);
break;
}
}
self.ownerActor = null;
self.extra = 8;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
override void Tick()
{
let sectp = self.sector;
double xx;
//self.temp_data[0] = state
//self.temp_data[1] = checking sector number
if (self.vel.X != 0) self.getGlobalZ();
if (self.temp_data[0] == 0) //Waiting to check the sector
{
DukeSectIterator it;
for (DukeActor a2 = it.First(self.temp_sect); a2; a2 = it.Next())
{
switch (a2.statnum)
{
case STAT_ACTOR:
case STAT_ZOMBIEACTOR:
case STAT_STANDABLE:
case STAT_PLAYER:
self.angle = (self.polepos - self.pos.XY).Angle();
a2.SetPosition(( self.polepos, a2.pos.Z ));
self.temp_data[0]++;
return;
}
}
}
else if (self.temp_data[0] == 1)
{
if (self.vel.X < 11.5)
{
self.setSpritePic(PIC_OPEN);
self.vel.X += 0.5;
}
self.DoMove(CLIPMASK0);
if (self.sector == self.temp_sect)
self.temp_data[0]++;
}
else if (self.temp_data[0] == 2 || self.temp_data[0] == 7)
{
self.pos.Z += 6;
if (self.temp_data[0] == 2)
{
if ((sectp.floorz - self.pos.Z) < 64)
if (self.spritesetindex != PIC_DEFAULT) self.setSpritePic(self.spritesetindex - 1);
if ((sectp.floorz - self.pos.Z) < 20)
self.temp_data[0]++;
}
if (self.temp_data[0] == 7)
{
if ((sectp.floorz - self.pos.Z) < 64)
{
if (self.spritesetindex != PIC_DEFAULT) self.setSpritePic(self.spritesetindex - 1);
else
{
if (self.isactive)
{
let pp = findplayer();
// fixme: Sounds really need to be better abstracted...
pp.actor.PlayActorSound(Raze.isRR() ? RRSnd.YEHAA16 : DukeSnd.DUKE_GRUNT);
if (pp.on_crane == self)
pp.on_crane = null;
}
self.temp_data[0]++;
self.isactive = false;
self.ownerActor = null;
}
}
}
}
else if (self.temp_data[0] == 3)
{
self.setSpritePic(self.spritesetindex + 1);
if (self.spritesetindex == PIC_CLOSED)
{
let plr = Duke.checkcursectnums(self.temp_sect);
if (plr != null && plr.on_ground)
{
self.isactive = true;
self.ownerActor = null;
plr.on_crane = self;
// fixme: Sounds really need to be better abstracted...
plr.actor.PlayActorSound(Raze.isRR() ? RRSnd.YEHAA16 : DukeSnd.DUKE_GRUNT);
plr.settargetangle(self.angle + 180);
}
else
{
DukeSectIterator it;
for (DukeActor a2 = it.First(self.temp_sect); a2; a2 = it.Next())
{
switch (a2.statnum)
{
case 1:
case 6:
self.OwnerActor = a2;
break;
}
}
}
self.temp_data[0]++;//Grabbed the sprite
self.temp_data[2] = 0;
return;
}
}
else if (self.temp_data[0] == 4) //Delay before going up
{
self.temp_data[2]++;
if (self.temp_data[2] > 10)
self.temp_data[0]++;
}
else if (self.temp_data[0] == 5 || self.temp_data[0] == 8)
{
if (self.temp_data[0] == 8 && self.spritesetindex < PIC_CLOSED)
if ((sectp.floorz - self.pos.Z) > 32)
self.setSpritePic(self.spritesetindex + 1);
if (self.pos.Z < self.cranepos.Z)
{
self.temp_data[0]++;
self.vel.X = 0;
}
else
self.pos.Z -= 6;
}
else if (self.temp_data[0] == 6)
{
if (self.vel.X < 12)
self.vel.X += 0.5;
self.angle = (self.cranepos.XY - self.pos.XY).Angle();
self.DoMove(CLIPMASK0);
if ((self.pos.XY - self.cranepos.XY).LengthSquared() < 8 * 8)
self.temp_data[0]++;
}
else if (self.temp_data[0] == 9)
self.temp_data[0] = 0;
if (self.poleactor)
self.poleactor.SetPosition(self.pos.plusZ(-34));
let Owner = self.OwnerActor;
if (Owner != null || self.isactive)
{
let p = self.findplayer();
int j = self.ifhitbyweapon();
if (j >= 0)
{
if (self.isactive && p.on_crane == self)
p.on_crane = null;
self.isactive = false;
self.ownerActor = null;
self.setSpritePic(PIC_DEFAULT);
return;
}
if (Owner != null)
{
Owner.SetPosition(self.pos);
Owner.backuppos();
self.vel.Z = 0;
}
else if (self.isactive)
{
let ang = p.angle();
p.backupxyz();
p.pos.XY = self.pos.XY - CRANE_STEP * ang.ToVector();
p.pos.Z = self.pos.Z + 2;
p.actor.SetPosition(p.pos);
p.cursector = p.actor.sector;
}
}
}
}
class DukeCranePole : DukeActor
{
default
{
pic "CRANEPOLE";
}
}