From 6d9a8bfaa5f39e7e1cf79dd76113b8b15cd90d66 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Nov 2022 23:36:39 +0100 Subject: [PATCH] - scriptified the pool balls. --- source/common/scripting/vm/vm.h | 3 +- source/core/vmexports.cpp | 51 ++++++- source/games/duke/src/actors.cpp | 95 ------------ source/games/duke/src/actors_d.cpp | 8 +- source/games/duke/src/actors_r.cpp | 4 - source/games/duke/src/funct.h | 1 - source/games/duke/src/sectors_d.cpp | 24 --- source/games/duke/src/sectors_r.cpp | 12 +- source/games/duke/src/spawn_d.cpp | 17 +-- source/games/duke/src/spawn_r.cpp | 15 +- source/games/duke/src/vmexports.cpp | 12 ++ .../static/filter/dukelike/engine/engine.def | 4 + wadsrc/static/filter/dukelike/sndinfo.txt | 1 + wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/coreactor.zs | 17 +-- .../zscript/games/duke/actors/queball.zs | 138 ++++++++++++++++++ wadsrc/static/zscript/games/duke/dukeactor.zs | 2 +- wadsrc/static/zscript/games/duke/dukegame.zs | 44 ++++++ wadsrc/static/zscript/razebase.zs | 16 ++ 19 files changed, 274 insertions(+), 191 deletions(-) create mode 100644 wadsrc/static/zscript/games/duke/actors/queball.zs diff --git a/source/common/scripting/vm/vm.h b/source/common/scripting/vm/vm.h index ef089eba5..4870f0048 100644 --- a/source/common/scripting/vm/vm.h +++ b/source/common/scripting/vm/vm.h @@ -632,7 +632,8 @@ struct DirectNativeDesc template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); } template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); VP(13); } template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); VP(13), VP(14); } - #undef TP + template DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)) : Ptr(reinterpret_cast(func)) { ValidateRet(); VP(1); VP(2); VP(3); VP(4); VP(5); VP(6); VP(7); VP(8); VP(9); VP(10); VP(11); VP(12); VP(13), VP(14), VP(15); } +#undef TP #undef VP template void ValidateType() { static_assert(native_is_valid::value, "Argument type is not valid as a direct native parameter or return type"); } diff --git a/source/core/vmexports.cpp b/source/core/vmexports.cpp index aae52b791..13031e979 100644 --- a/source/core/vmexports.cpp +++ b/source/core/vmexports.cpp @@ -54,6 +54,30 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Raze, updatesector, Raze_updatesector) ACTION_RETURN_POINTER(Raze_updatesector(x, y, s, dist)); } +DEFINE_ACTION_FUNCTION(_Raze, clipmove) +{ + PARAM_PROLOGUE; + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_FLOAT(z); + PARAM_POINTER_NOT_NULL(s, sectortype); + PARAM_FLOAT(mx); + PARAM_FLOAT(my); + PARAM_FLOAT(wdist); + PARAM_FLOAT(cdist); + PARAM_FLOAT(fdist); + PARAM_UINT(cliptype); + PARAM_POINTER_NOT_NULL(coll, CollisionBase); + PARAM_INT(cmtn); + DVector3 rpos(x, y, z); + clipmove(rpos, &s, DVector2(mx, my), wdist, cdist, fdist, cliptype, *coll, cmtn); + if (numret > 0) ret[0].SetPointer(s); + if (numret > 1) ret[1].SetVector(rpos); + return min(numret, 2); +} + + + DEFINE_ACTION_FUNCTION_NATIVE(_Raze, SoundEnabled, SoundEnabled) { ACTION_RETURN_INT(SoundEnabled()); @@ -795,6 +819,19 @@ DEFINE_ACTION_FUNCTION_NATIVE(DCoreActor, absangle, absangleDbl) // should this ACTION_RETURN_FLOAT(absangle(DAngle::fromDeg(a1), DAngle::fromDeg(a2)).Degrees()); } +static double Normalize180(double angle) +{ + return DAngle::fromDeg(angle).Normalized180().Degrees(); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DCoreActor, Normalize180, Normalize180) +{ + PARAM_PROLOGUE; + PARAM_ANGLE(angle); + ACTION_RETURN_FLOAT(angle.Normalized180().Degrees()); +} + + DEFINE_FIELD_X(Collision, CollisionBase, type) DEFINE_FIELD_X(Collision, CollisionBase, exbits) @@ -805,7 +842,7 @@ walltype* collision_getwall(CollisionBase* coll) else return nullptr; } -DEFINE_ACTION_FUNCTION_NATIVE(_Collision, hitwall, collision_getwall) +DEFINE_ACTION_FUNCTION_NATIVE(_CollisionData, hitwall, collision_getwall) { PARAM_SELF_STRUCT_PROLOGUE(CollisionBase); ACTION_RETURN_POINTER(collision_getwall(self)); @@ -817,7 +854,7 @@ sectortype* collision_getsector(CollisionBase* coll) else return nullptr; } -DEFINE_ACTION_FUNCTION_NATIVE(_Collision, hitsector, collision_getsector) +DEFINE_ACTION_FUNCTION_NATIVE(_CollisionData, hitsector, collision_getsector) { PARAM_SELF_STRUCT_PROLOGUE(CollisionBase); ACTION_RETURN_POINTER(collision_getsector(self)); @@ -829,7 +866,7 @@ DCoreActor* collision_getactor(CollisionBase* coll) else return nullptr; } -DEFINE_ACTION_FUNCTION_NATIVE(_Collision, hitactor, collision_getactor) +DEFINE_ACTION_FUNCTION_NATIVE(_CollisionData, hitactor, collision_getactor) { PARAM_SELF_STRUCT_PROLOGUE(CollisionBase); ACTION_RETURN_POINTER(collision_getactor(self)); @@ -843,7 +880,7 @@ void collision_setwall(CollisionBase* coll, walltype * w) coll->hitWall = w; } -DEFINE_ACTION_FUNCTION_NATIVE(_Collision, setwall, collision_setwall) +DEFINE_ACTION_FUNCTION_NATIVE(_CollisionData, setwall, collision_setwall) { PARAM_SELF_STRUCT_PROLOGUE(CollisionBase); PARAM_POINTER(p, walltype); @@ -857,7 +894,7 @@ void collision_setsector(CollisionBase* coll, sectortype* s) coll->hitSector = s; } -DEFINE_ACTION_FUNCTION_NATIVE(_Collision, setsector, collision_setsector) +DEFINE_ACTION_FUNCTION_NATIVE(_CollisionData, setsector, collision_setsector) { PARAM_SELF_STRUCT_PROLOGUE(CollisionBase); PARAM_POINTER(p, sectortype); @@ -871,7 +908,7 @@ void collision_setactor(CollisionBase* coll, DCoreActor* a) coll->hitActor = a; } -DEFINE_ACTION_FUNCTION_NATIVE(_Collision, setactor, collision_setactor) +DEFINE_ACTION_FUNCTION_NATIVE(_CollisionData, setactor, collision_setactor) { PARAM_SELF_STRUCT_PROLOGUE(CollisionBase); PARAM_POINTER(p, DCoreActor); @@ -885,7 +922,7 @@ void collision_setvoid(CollisionBase* coll) coll->hitActor = nullptr; } -DEFINE_ACTION_FUNCTION_NATIVE(_Collision, setvoid, collision_setvoid) +DEFINE_ACTION_FUNCTION_NATIVE(_CollisionData, setvoid, collision_setvoid) { PARAM_SELF_STRUCT_PROLOGUE(CollisionBase); collision_setvoid(self); diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 77b757e92..e16744ce0 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -681,101 +681,6 @@ void rpgexplode(DDukeActor *actor, int hit, const DVector3 &pos, int EXPLOSION2, // //--------------------------------------------------------------------------- -bool queball(DDukeActor *actor, int pocket, int queball, int stripeball) -{ - if(actor->vel.X != 0) - { - DukeStatIterator it(STAT_DEFAULT); - while (auto aa = it.Next()) - { - double dist = (aa->spr.pos.XY() - actor->spr.pos.XY()).Length(); - if (aa->spr.picnum == pocket && dist < 3.25) - { - actor->Destroy(); - return false; - } - } - - Collision coll; - auto sect = actor->sector(); - auto pos = actor->spr.pos; - auto move = actor->spr.Angles.Yaw.ToVector() * actor->vel.X * 0.5; - int j = clipmove(pos, §, move, 1.5, 4., 4., CLIPMASK1, coll); - actor->spr.pos = pos;; - actor->setsector(sect); - - if (j == kHitWall) - { - auto ang = coll.hitWall->delta().Angle(); - actor->spr.Angles.Yaw = ang * 2 - actor->spr.Angles.Yaw; - } - else if (j == kHitSprite) - { - fi.checkhitsprite(actor, coll.actor()); - } - - actor->vel.X -= 1/16.; - if(actor->vel.X < 0) actor->vel.X = 0; - if (actor->spr.picnum == stripeball) - { - actor->spr.cstat = CSTAT_SPRITE_BLOCK_ALL; - actor->spr.cstat |= (CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP) & ESpriteFlags::FromInt(int(actor->vel.X * 16.)); // special hack edition... - } - } - else - { - double x; - int p = findplayer(actor, &x); - - if (x < 99.75) - { - // if(actor->spr.pal == 12) - { - auto delta = absangle(ps[p].GetActor()->spr.Angles.Yaw, (actor->spr.pos.XY() - ps[p].GetActor()->spr.pos.XY()).Angle()); - if (delta < DAngle22_5 / 2 && PlayerInput(p, SB_OPEN)) - if (ps[p].toggle_key_flag == 1) - { - DukeStatIterator it(STAT_ACTOR); - DDukeActor *act2; - while ((act2 = it.Next())) - { - if (act2->spr.picnum == queball || act2->spr.picnum == stripeball) - { - delta = absangle(ps[p].GetActor()->spr.Angles.Yaw, (act2->spr.pos.XY() - ps[p].GetActor()->spr.pos.XY()).Angle()); - if (delta < DAngle22_5 / 2) - { - double l; - findplayer(act2, &l); - if (x > l) break; - } - } - } - if (act2 == nullptr) - { - if (actor->spr.pal == 12) - actor->vel.X = 10.25; - else actor->vel.X = 8.75; - actor->spr.Angles.Yaw = ps[p].GetActor()->spr.Angles.Yaw; - ps[p].toggle_key_flag = 2; - } - } - } - } - if (x < 32 && actor->sector() == ps[p].cursector) - { - actor->spr.Angles.Yaw = (actor->spr.pos.XY() - ps[p].GetActor()->spr.pos.XY()).Angle(); - actor->vel.X = 3; - } - } - return true; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - void forcesphere(DDukeActor* actor, int forcesphere) { auto sectp = actor->sector(); diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 8932dd8c5..fbd066ac3 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -2218,6 +2218,10 @@ void moveactors_d(void) DukeStatIterator it(STAT_ACTOR); while (auto act = it.Next()) { + if (act->spr.picnum == QUEBALL) + { + int a = 0; + } auto sectp = act->sector(); if (act->spr.scale.X == 0 || sectp == nullptr || actorflag(act, SFLAG2_DIENOW)) @@ -2305,10 +2309,6 @@ void moveactors_d(void) spawn(act, EXPLOSION2); ssp(act, CLIPMASK0); break; - case QUEBALL: - case STRIPEBALL: - if (!queball(act, POCKET, QUEBALL, STRIPEBALL)) continue; - break; case FORCESPHERE: forcesphere(act, FORCESPHERE); continue; diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index 9d738954e..4d22b16ca 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -2065,10 +2065,6 @@ void moveactors_r(void) break; } - case QUEBALL: - case STRIPEBALL: - if (!queball(act, POCKET, QUEBALL, STRIPEBALL)) continue; - break; case FORCESPHERE: forcesphere(act, FORCESPHERE); continue; diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index bd6ddd5c1..c98f30eb2 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -41,7 +41,6 @@ void bounce(DDukeActor* i); void rpgexplode(DDukeActor* i, int j, const DVector3& pos, int EXPLOSION2, int EXPLOSIONBOT2, int newextra, int playsound); void lotsofstuff(DDukeActor* s, int n, int spawntype); bool respawnmarker(DDukeActor* i, int yellow, int green); -bool queball(DDukeActor* i, int pocket, int queball, int stripeball); void forcesphere(DDukeActor* i, int forcesphere); void recon(DDukeActor* i, int explosion, int firelaser, int attacksnd, int painsnd, int roamsnd, int shift, int (*getspawn)(DDukeActor* i)); void ooz(DDukeActor* i); diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 5a5c568e2..813721835 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -1077,30 +1077,6 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) spawn(targ, SMALLSMOKE); targ->Destroy(); break; - case QUEBALL: - case STRIPEBALL: - if (proj->spr.picnum == QUEBALL || proj->spr.picnum == STRIPEBALL) - { - proj->vel.X = targ->vel.X * 0.75; - proj->spr.Angles.Yaw -= targ->spr.Angles.Yaw.Normalized180() * 2 + DAngle180; - targ->spr.Angles.Yaw = (targ->spr.pos.XY() - proj->spr.pos.XY()).Angle() - DAngle90; - if (S_CheckSoundPlaying(POOLBALLHIT) < 2) - S_PlayActorSound(POOLBALLHIT, targ); - } - else - { - if (krand() & 3) - { - targ->vel.X = 10.25; - targ->spr.Angles.Yaw = proj->spr.Angles.Yaw; - } - else - { - lotsofglass(targ, nullptr, 3); - targ->Destroy(); - } - } - break; case HANGLIGHT: case GENERICPOLE2: for (k = 0; k < 6; k++) diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 7cff6b015..dd9680ec7 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -1454,21 +1454,11 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj) S_PlayActorSound(355, targ); break; - case STRIPEBALL: - case QUEBALL: case BOWLINGPIN: case BOWLINGPIN + 1: case HENSTAND: case HENSTAND + 1: - if (proj->spr.picnum == QUEBALL || proj->spr.picnum == STRIPEBALL) - { - proj->vel.X = targ->vel.X * 0.75; - proj->spr.Angles.Yaw -= targ->spr.Angles.Yaw.Normalized180() * 2 + DAngle180; - targ->spr.Angles.Yaw = (targ->spr.pos.XY() - proj->spr.pos.XY()).Angle() - DAngle90; - if (S_CheckSoundPlaying(POOLBALLHIT) < 2) - S_PlayActorSound(POOLBALLHIT, targ); - } - else if (proj->spr.picnum == BOWLINGPIN || proj->spr.picnum == BOWLINGPIN + 1) + if (proj->spr.picnum == BOWLINGPIN || proj->spr.picnum == BOWLINGPIN + 1) { proj->vel.X *= 0.75; proj->spr.Angles.Yaw -= targ->spr.Angles.Yaw * 2 + randomAngle(11.25); diff --git a/source/games/duke/src/spawn_d.cpp b/source/games/duke/src/spawn_d.cpp index f959ca4fa..91ed4b8d4 100644 --- a/source/games/duke/src/spawn_d.cpp +++ b/source/games/duke/src/spawn_d.cpp @@ -401,21 +401,8 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* [[fallthrough]]; case BLOODYPOLE: - - case QUEBALL: - case STRIPEBALL: - - if (act->spr.picnum == QUEBALL || act->spr.picnum == STRIPEBALL) - { - act->spr.cstat = CSTAT_SPRITE_BLOCK_HITSCAN; - act->clipdist = 2; - } - else - { - act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL; - act->clipdist = 8; - } - + act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL; + act->clipdist = 8; ChangeActorStat(act, STAT_ZOMBIEACTOR); break; diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index d8f7b5592..b3eb076f0 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -293,19 +293,8 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* case TOUGHGAL: act->spr.yint = act->spr.hitag; act->spr.hitag = -1; - [[fallthrough]]; - case QUEBALL: - case STRIPEBALL: - if (act->spr.picnum == QUEBALL || act->spr.picnum == STRIPEBALL) - { - act->spr.cstat = CSTAT_SPRITE_BLOCK_HITSCAN; - act->clipdist = 2; - } - else - { - act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL; - act->clipdist = 8; - } + act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL; + act->clipdist = 8; ChangeActorStat(act, STAT_ZOMBIEACTOR); break; case BOWLINGBALL: diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index f05680a68..cb7e2d9e9 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -898,6 +898,18 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, centerview, dukeplayer_centerview) return 0; } +inline int DukePlayer_PlayerInput(player_struct* pl, int bit) +{ + return (!!((pl->sync.actions) & ESyncBits::FromInt(bit))); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, playerinput, DukePlayer_PlayerInput) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_struct); + PARAM_INT(bit); + ACTION_RETURN_INT(DukePlayer_PlayerInput(self, bit)); +} + void dukeplayer_settargetangle(player_struct* self, double a, int backup) { self->Angles.setYaw(DAngle::fromDeg(a), backup); diff --git a/wadsrc/static/filter/dukelike/engine/engine.def b/wadsrc/static/filter/dukelike/engine/engine.def index 5c63ee7b1..b376d9a7c 100644 --- a/wadsrc/static/filter/dukelike/engine/engine.def +++ b/wadsrc/static/filter/dukelike/engine/engine.def @@ -44,6 +44,10 @@ spawnclasses 625 = DukeCamera 3190 = DukeRespawnmarker 1267 = DukeRat + 902 = DukeQueball + 901 = DukeStripeBall + 903 = DukePoolPocket + 1272 = DukeTrash 634 = DukeBolt1 diff --git a/wadsrc/static/filter/dukelike/sndinfo.txt b/wadsrc/static/filter/dukelike/sndinfo.txt index 3a40c1bc2..51cb831a3 100644 --- a/wadsrc/static/filter/dukelike/sndinfo.txt +++ b/wadsrc/static/filter/dukelike/sndinfo.txt @@ -7,6 +7,7 @@ $conreserve INSERT_CLIP 5 $conreserve CHAINGUN_FIRE 6 $conreserve RPG_SHOOT 7 $conreserve POOLBALLHIT 8 +$limit POOLBALLHIT 2 $conreserve RPG_EXPLODE 9 $conreserve CAT_FIRE 10 $conreserve SHRINKER_FIRE 11 diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index db942bacb..87b6078ab 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -76,6 +76,7 @@ version "4.10" #include "zscript/games/duke/actors/viewscreen.zs" #include "zscript/games/duke/actors/canwithsomething.zs" #include "zscript/games/duke/actors/tongue.zs" +#include "zscript/games/duke/actors/queball.zs" #include "zscript/games/duke/actors/genericdestructible.zs" #include "zscript/games/duke/actors/redneckmisc.zs" diff --git a/wadsrc/static/zscript/coreactor.zs b/wadsrc/static/zscript/coreactor.zs index bfea62199..2d5723a49 100644 --- a/wadsrc/static/zscript/coreactor.zs +++ b/wadsrc/static/zscript/coreactor.zs @@ -22,7 +22,7 @@ const maptoworld = (1. / 16.); class CoreActor native { const REPEAT_SCALE = 1. / 64.; - native readonly sectortype sector; + native sectortype sector; // cannot be read-only, some code calls clipmove directly on this. native int16 cstat; //native int16 picnum; // access is disabled to allow later refactoring. @@ -70,6 +70,7 @@ class CoreActor native native clearscope static double deltaangle(double ang1, double ang2); native clearscope static double absangle(double ang1, double ang2); + native clearscope static double Normalize180(double ang); int randomFlip() { @@ -90,17 +91,3 @@ class CoreActor native } -// this only allows function getters to enable validation on the target. -struct Collision -{ - native int type; - native int exbits; - native walltype hitWall(); - native sectortype hitSector(); - native CoreActor hitActor(); - native void setSector(sectortype s); - native void setWall(walltype w); - native void setActor(CoreActor a); - native void setVoid(); - -} \ No newline at end of file diff --git a/wadsrc/static/zscript/games/duke/actors/queball.zs b/wadsrc/static/zscript/games/duke/actors/queball.zs new file mode 100644 index 000000000..3475e92a6 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/queball.zs @@ -0,0 +1,138 @@ +class DukePoolPocket : DukeActor +{ + // we only need this for checking, it's an empty sprite. +} + +class DukeQueball : DukeActor +{ + default + { + clipdist 2; + pic "QUEBALL"; + statnum STAT_ZOMBIEACTOR; + } + + override void Initialize() + { + self.cstat = CSTAT_SPRITE_BLOCK_HITSCAN; + } + + override void Tick() + { + if(self.vel.X != 0) + { + DukeStatIterator it; + for(let aa = it.First(STAT_DEFAULT); aa; aa = it.Next()) + { + double dist = (aa.pos.XY - self.pos.XY).Length(); + if (aa is 'DukePoolPocket' && dist < 3.25) + { + self.Destroy(); + return; + } + } + + CollisionData colli; + let move = self.angle.ToVector() * self.vel.X * 0.5; + [self.sector, self.pos] = Raze.clipmove(self.pos, self.sector, move, 1.5, 4., 4., CLIPMASK1, colli); + int j = colli.type; + + if (j == kHitWall) + { + let ang = colli.hitWall().delta().Angle(); + self.angle = ang * 2 - self.angle; + } + else if (j == kHitSprite) + { + self.checkhitsprite(DukeActor(colli.hitactor())); + } + + self.vel.X -= 1/16.; + if(self.vel.X < 0) self.vel.X = 0; + if (self is 'DukeStripeBall') + { + self.cstat = CSTAT_SPRITE_BLOCK_ALL; + self.cstat |= (CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP) & int(self.vel.X * 16.); // special hack edition... + } + } + else + { + double x; + DukePlayer p; + [p, x] = self.findplayer(); + + if (x < 99.75) + { + // if(self.pal == 12) + { + let delta = absangle(p.actor.angle, (self.pos.XY - p.actor.pos.XY).Angle()); + if (delta < 11.25 && p.PlayerInput(Duke.SB_OPEN)) + if (p.toggle_key_flag == 1) + { + DukeStatIterator it; + DukeActor act2; + for (act2 = it.First(STAT_ACTOR); act2; act2 = it.Next()) + { + if (act2 is 'DukeQueball') + { + delta = absangle(p.Actor.angle, (act2.pos.XY - p.Actor.pos.XY).Angle()); + if (delta < 11.25) + { + double l; + DukePlayer q; + [q, l] = act2.findplayer(); + if (x > l) break; + } + } + } + if (act2 == nullptr) + { + if (self.pal == 12) + self.vel.X = 10.25; + else self.vel.X = 8.75; + self.angle = p.Actor.angle; + p.toggle_key_flag = 2; + } + } + } + } + if (x < 32 && self.sector == p.cursector) + { + self.angle = (self.pos.XY - p.Actor.pos.XY).Angle(); + self.vel.X = 3; + } + } + } + + override void onHit(DukeActor hitter) + { + if (hitter is 'DukeQueball') + { + hitter.vel.X = self.vel.X * 0.75; + hitter.angle -= Normalize180(self.angle) * 2 + 180; + self.angle = (self.pos.XY - hitter.pos.XY).Angle() - 90; + self.PlayActorSound("POOLBALLHIT"); + } + else + { + if (random(0, 3)) + { + self.vel.X = 10.25; + self.angle = hitter.angle; + } + else + { + self.lotsofglass(3); + self.Destroy(); + } + } + } +} + +class DukeStripeball : DukeQueball +{ + default + { + pic "STRIPEBALL"; + } +} diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index a9f3eebba..74c090d6a 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -200,7 +200,7 @@ class DukeActor : CoreActor native native void lotsofstuff(Name type, int count); native double gutsoffset(); native int movesprite(Vector3 move, int clipmask); - native int movesprite_ex(Vector3 move, int clipmask, Collision coll); + native int movesprite_ex(Vector3 move, int clipmask, CollisionData coll); // temporary flag accessors - need to be eliminated once we can have true actor flags diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index 292d3b74c..3aed11145 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -90,6 +90,49 @@ struct Duke native SF_DTAG = 128, }; + enum ESyncBits + { + SB_FIRST_WEAPON_BIT = 1 << 0, + SB_ITEM_BIT_1 = 1 << 4, + SB_ITEM_BIT_2 = 1 << 5, + SB_ITEM_BIT_3 = 1 << 6, + SB_ITEM_BIT_4 = 1 << 7, + SB_ITEM_BIT_5 = 1 << 8, + SB_ITEM_BIT_6 = 1 << 9, + SB_ITEM_BIT_7 = 1 << 10, + + SB_INVPREV = 1 << 11, + SB_INVNEXT = 1 << 12, + SB_INVUSE = 1 << 13, + SB_CENTERVIEW = 1 << 14, + SB_TURNAROUND = 1 << 15, + SB_HOLSTER = 1 << 16, + SB_OPEN = 1 << 17, + + SB_AIMMODE = 1 << 18, + SB_QUICK_KICK = 1 << 19, + SB_ESCAPE = 1 << 20, + + SB_AIM_UP = 1 << 21, + SB_AIM_DOWN = 1 << 22, + SB_LOOK_LEFT = 1 << 23, + SB_LOOK_RIGHT = 1 << 24, + SB_LOOK_UP = 1 << 25, + SB_LOOK_DOWN = 1 << 26, + SB_RUN = 1 << 27, + SB_JUMP = 1 << 28, + SB_CROUCH = 1 << 29, + SB_FIRE = 1 << 30, + SB_ALTFIRE = 1u << 31, + + SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits + SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1), + + SB_BUTTON_MASK = SB_ALTFIRE|SB_FIRE|SB_CROUCH|SB_JUMP|SB_LOOK_UP|SB_LOOK_DOWN|SB_AIM_UP|SB_AIM_DOWN|SB_LOOK_LEFT|SB_LOOK_RIGHT, // all input from buttons (i.e. active while held) + SB_INTERFACE_MASK = (SB_INVPREV|SB_INVNEXT|SB_INVUSE|SB_CENTERVIEW|SB_TURNAROUND|SB_HOLSTER|SB_OPEN|SB_ESCAPE|SB_QUICK_KICK), // all input from CCMDs + SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS | SB_ITEMUSE_BITS | SB_INTERFACE_MASK), + SB_ALL = ~0u + }; native static void PlaySpecialMusic(int which); native static int PlaySound(Sound num, int channel = CHAN_AUTO, int flags = 0, float vol =0.8f); @@ -300,6 +343,7 @@ struct DukePlayer native native void quickkill(); native void addPitch(double p); native void centerView(); + native int playerinput(int bit); } diff --git a/wadsrc/static/zscript/razebase.zs b/wadsrc/static/zscript/razebase.zs index bff836bbf..355ea3616 100644 --- a/wadsrc/static/zscript/razebase.zs +++ b/wadsrc/static/zscript/razebase.zs @@ -137,6 +137,21 @@ struct SummaryInfo native native readonly bool endofgame; } +// this only allows function getters to enable validation on the target. +struct CollisionData +{ + int type; + int exbits; + voidptr hit; // do not access! + native walltype hitWall(); + native sectortype hitSector(); + native CoreActor hitActor(); + native void setSector(sectortype s); + native void setWall(walltype w); + native void setActor(CoreActor a); + native void setVoid(); + +} struct Raze { const kAngleMask = 0x7FF; @@ -156,6 +171,7 @@ struct Raze native static Sound FindSoundByResID(int id); native static sectortype updatesector(Vector2 pos, sectortype lastsect, double maxdist = 96); + native static sectortype, Vector3 clipmove(Vector3 pos, sectortype sect, Vector2 move, double walldist, double ceildist, double flordist, uint cliptype, CollisionData coll, int clipmoveboxtracenum = 3); // game check shortcuts