mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-31 05:00:41 +00:00
- scriptified the pool balls.
This commit is contained in:
parent
1ef61c8588
commit
6d9a8bfaa5
19 changed files with 274 additions and 191 deletions
|
@ -632,7 +632,8 @@ struct DirectNativeDesc
|
|||
template<typename Ret, TP(1), TP(2), TP(3), TP(4), TP(5), TP(6), TP(7), TP(8), TP(9), TP(10), TP(11), TP(12)> DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)) : Ptr(reinterpret_cast<void*>(func)) { ValidateRet<Ret>(); 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<typename Ret, TP(1), TP(2), TP(3), TP(4), TP(5), TP(6), TP(7), TP(8), TP(9), TP(10), TP(11), TP(12), TP(13)> DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)) : Ptr(reinterpret_cast<void*>(func)) { ValidateRet<Ret>(); 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<typename Ret, TP(1), TP(2), TP(3), TP(4), TP(5), TP(6), TP(7), TP(8), TP(9), TP(10), TP(11), TP(12), TP(13), TP(14)> DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)) : Ptr(reinterpret_cast<void*>(func)) { ValidateRet<Ret>(); 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<typename Ret, TP(1), TP(2), TP(3), TP(4), TP(5), TP(6), TP(7), TP(8), TP(9), TP(10), TP(11), TP(12), TP(13), TP(14), TP(15)> DirectNativeDesc(Ret(*func)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)) : Ptr(reinterpret_cast<void*>(func)) { ValidateRet<Ret>(); 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<typename T> void ValidateType() { static_assert(native_is_valid<T>::value, "Argument type is not valid as a direct native parameter or return type"); }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -401,21 +401,8 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
|||
[[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;
|
||||
|
||||
|
|
|
@ -293,19 +293,8 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
|||
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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -44,6 +44,10 @@ spawnclasses
|
|||
625 = DukeCamera
|
||||
3190 = DukeRespawnmarker
|
||||
1267 = DukeRat
|
||||
902 = DukeQueball
|
||||
901 = DukeStripeBall
|
||||
903 = DukePoolPocket
|
||||
|
||||
|
||||
1272 = DukeTrash
|
||||
634 = DukeBolt1
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
138
wadsrc/static/zscript/games/duke/actors/queball.zs
Normal file
138
wadsrc/static/zscript/games/duke/actors/queball.zs
Normal file
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue