From f23ddc28f06f57a84233e511366f1faee52cc95d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 13 Nov 2022 18:55:32 +0100 Subject: [PATCH] - Duke: scriptified the crane --- source/games/duke/src/actors.cpp | 185 ------------- source/games/duke/src/actors_d.cpp | 5 - source/games/duke/src/actors_r.cpp | 5 +- source/games/duke/src/funct.h | 1 - source/games/duke/src/game.cpp | 1 - source/games/duke/src/global.cpp | 1 - source/games/duke/src/global.h | 1 - source/games/duke/src/premap.cpp | 1 - source/games/duke/src/savegame.cpp | 16 -- source/games/duke/src/spawn.cpp | 47 +--- source/games/duke/src/spawn_d.cpp | 6 +- source/games/duke/src/spawn_r.cpp | 5 +- source/games/duke/src/types.h | 18 -- wadsrc/static/filter/duke/engine/engine.def | 4 +- .../static/filter/redneck/engine/engine.def | 4 +- wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/coreactor.zs | 2 +- .../static/zscript/games/duke/actors/crane.zs | 254 ++++++++++++++++++ 18 files changed, 266 insertions(+), 291 deletions(-) create mode 100644 wadsrc/static/zscript/games/duke/actors/crane.zs diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index b108dc3c5..a946a3cf7 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -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()); - } - } -} - //--------------------------------------------------------------------------- // // diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 53f6fa3a0..e150e8c18 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -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); diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index bd7fbeca4..6a4521d9b 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -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()); diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index b088e41d2..7b067b68c 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -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* actors); diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index 034f9241d..6fad5fc22 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -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); diff --git a/source/games/duke/src/global.cpp b/source/games/duke/src/global.cpp index f4d9f6f19..998f2e5eb 100644 --- a/source/games/duke/src/global.cpp +++ b/source/games/duke/src/global.cpp @@ -85,7 +85,6 @@ int playerswhenstarted; // why is this needed? int show_shareware; // display only. int rtsplaying; // RTS playback state TArray mspos; -TArray cranes; TArray animates; bool sound445done; // used in checksectors_r. This was local state inside a function, but this must be maintained globally and serialized diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index 2cf53c8b7..a62a28d1e 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -129,7 +129,6 @@ extern short ambientlotag[64]; extern short ambienthitag[64]; extern unsigned ambientfx; extern TArray mspos; -extern TArray cranes; extern int WindTime; extern DAngle WindDir; extern short fakebubba_spawn, mamaspawn_count, banjosound; diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index d22c32bd8..9f453c688 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -452,7 +452,6 @@ void resetprestat(int snum,int g) paused = 0; ud.cameraactor =nullptr; mspos.Clear(); - cranes.Clear(); camsprite =nullptr; earthquaketime = 0; diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index feb677a22..5c7c8909d 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -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) diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index 6a164f3ea..f5047e6e7 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -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)) diff --git a/source/games/duke/src/spawn_d.cpp b/source/games/duke/src/spawn_d.cpp index 4ae653a61..8272f2076 100644 --- a/source/games/duke/src/spawn_d.cpp +++ b/source/games/duke/src/spawn_d.cpp @@ -45,6 +45,8 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* { 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* ChangeActorStat(act, STAT_MISC); break; - case CRANE: - initcrane(actj, act, CRANEPOLE); - break; - case WATERDRIP: initwaterdrip(actj, act); break; diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index a2b629957..75dd97d8d 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -39,6 +39,8 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* { 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* 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; diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 5e820970f..9443201af 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -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 poleactor; -}; - struct player_struct { DVector3 vel; diff --git a/wadsrc/static/filter/duke/engine/engine.def b/wadsrc/static/filter/duke/engine/engine.def index 989f70e7a..84378fcd5 100644 --- a/wadsrc/static/filter/duke/engine/engine.def +++ b/wadsrc/static/filter/duke/engine/engine.def @@ -1,5 +1,5 @@ spawnclasses { - //1221 = DukeCranePole - //1222 = DukeCrane + 1221 = DukeCranePole + 1222 = DukeCrane } diff --git a/wadsrc/static/filter/redneck/engine/engine.def b/wadsrc/static/filter/redneck/engine/engine.def index c08b71397..3ced7d61a 100644 --- a/wadsrc/static/filter/redneck/engine/engine.def +++ b/wadsrc/static/filter/redneck/engine/engine.def @@ -1,5 +1,5 @@ spawnclasses { - //1298 = DukeCranePole - //1299 = DukeCrane + 1298 = DukeCranePole + 1299 = DukeCrane } diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 03bb8e730..245f1ef5a 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -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" diff --git a/wadsrc/static/zscript/coreactor.zs b/wadsrc/static/zscript/coreactor.zs index dd56af012..3fa4303ea 100644 --- a/wadsrc/static/zscript/coreactor.zs +++ b/wadsrc/static/zscript/coreactor.zs @@ -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; diff --git a/wadsrc/static/zscript/games/duke/actors/crane.zs b/wadsrc/static/zscript/games/duke/actors/crane.zs new file mode 100644 index 000000000..b4c37a0d4 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/crane.zs @@ -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"; + } +}