- scriptified the pool balls.

This commit is contained in:
Christoph Oelckers 2022-11-27 23:36:39 +01:00
parent 1ef61c8588
commit 6d9a8bfaa5
19 changed files with 274 additions and 191 deletions

View file

@ -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"); }

View file

@ -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);

View file

@ -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, &sect, 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();

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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++)

View file

@ -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);

View file

@ -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;
}
ChangeActorStat(act, STAT_ZOMBIEACTOR);
break;

View file

@ -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;
}
ChangeActorStat(act, STAT_ZOMBIEACTOR);
break;
case BOWLINGBALL:

View file

@ -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);

View file

@ -44,6 +44,10 @@ spawnclasses
625 = DukeCamera
3190 = DukeRespawnmarker
1267 = DukeRat
902 = DukeQueball
901 = DukeStripeBall
903 = DukePoolPocket
1272 = DukeTrash
634 = DukeBolt1

View file

@ -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

View file

@ -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"

View file

@ -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();
}

View 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";
}
}

View file

@ -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

View file

@ -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);
}

View file

@ -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