mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'rideroid-hardcode' into 'master'
Lat Hardcode See merge request KartKrew/Kart!1515
This commit is contained in:
commit
c72a2cf94a
29 changed files with 3101 additions and 10 deletions
|
|
@ -723,6 +723,50 @@ struct player_t
|
|||
|
||||
SINT8 glanceDir; // Direction the player is trying to look backwards in
|
||||
|
||||
//////////////
|
||||
// rideroid //
|
||||
//////////////
|
||||
boolean rideroid; // on rideroid y/n
|
||||
boolean rdnodepull; // being pulled by rideroid node. mo target is set to the node while this is true.
|
||||
INT32 rideroidangle; // angle the rideroid is going at. This doesn't change once we're on it. INT32 because the code was originally written in lua and fuckshit happens with angle_t.
|
||||
fixed_t rideroidspeed; // speed the rideroid is to be moving at.
|
||||
INT32 rideroidrollangle; // rollangle while turning
|
||||
fixed_t rdaddmomx; // some speed variables to smoothe things out without fighting with the regular momentum system.
|
||||
fixed_t rdaddmomy;
|
||||
fixed_t rdaddmomz;
|
||||
|
||||
////////////
|
||||
// bungee //
|
||||
////////////
|
||||
UINT8 bungee; // constants are defined with the object file for the bungee.
|
||||
|
||||
////////////////////
|
||||
// dead line zone //
|
||||
////////////////////
|
||||
// hovers
|
||||
tic_t lasthover; // used for the hover mobjs
|
||||
|
||||
// rockets
|
||||
tic_t dlzrocket; // counts up as we stay on a rocket.
|
||||
angle_t dlzrocketangle; // current travel angle with the rocket.
|
||||
INT32 dlzrocketanglev; // current vertical travel angle with the rocket. signed instead of angle_t.
|
||||
fixed_t dlzrocketspd; // current rocket travel speed.
|
||||
|
||||
// seasaws (variables are shared with other seasaw-like objects)
|
||||
boolean seasaw; // true if using a seasaw
|
||||
tic_t seasawcooldown; // cooldown to avoid triggering the same seasaw over and over
|
||||
fixed_t seasawdist; // distance from the center of the seasaw when latched.
|
||||
INT32 seasawangle; // angle from the center of the seasaw when latched.
|
||||
INT32 seasawangleadd; // used to spin the seasaw
|
||||
INT32 seasawmoreangle; // used for reverse sesaws in DLZ.
|
||||
boolean seasawdir; // flips or not seasaw rotation
|
||||
|
||||
// water palace turbines (or cnz barrels, or whatever the hell people use it for nowadays)
|
||||
tic_t turbine; // ticker (while true, we set the tracer to the turbine)
|
||||
INT32 turbineangle; // angle around the turbine. ...Made in INT32 to make it easier to translate from lua
|
||||
fixed_t turbineheight; // height around the turbine
|
||||
boolean turbinespd; // if true, we used a sneaker and get the altpath.
|
||||
|
||||
//
|
||||
|
||||
SINT8 lives;
|
||||
|
|
|
|||
|
|
@ -4684,6 +4684,20 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_CHECKPOINT_SPARK10",
|
||||
"S_CHECKPOINT_SPARK11",
|
||||
|
||||
"S_RIDEROID",
|
||||
"S_RIDEROID_ICON",
|
||||
|
||||
"S_EGGBALL",
|
||||
|
||||
"S_DLZHOVER",
|
||||
"S_DLZROCKET_L",
|
||||
"S_DLZROCKET_R",
|
||||
|
||||
"S_WPZFOUNTAIN",
|
||||
"S_WPZFOUNTAINANIM",
|
||||
"S_KURAGEN",
|
||||
"S_KURAGENBOMB",
|
||||
|
||||
"S_BALLSWITCH_BALL",
|
||||
"S_BALLSWITCH_BALL_ACTIVE",
|
||||
"S_BALLSWITCH_PAD",
|
||||
|
|
@ -5845,6 +5859,27 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
"MT_CHECKPOINT_END",
|
||||
"MT_SCRIPT_THING",
|
||||
|
||||
"MT_RIDEROID",
|
||||
"MT_RIDEROIDNODE",
|
||||
|
||||
"MT_LSZ_BUNGEE",
|
||||
"MT_LSZ_EGGBALLSPAWNER",
|
||||
"MT_LSZ_EGGBALL",
|
||||
|
||||
"MT_DLZ_HOVER",
|
||||
"MT_DLZ_ROCKET",
|
||||
"MT_DLZ_SEASAW_SPAWN",
|
||||
"MT_DLZ_SEASAW_HITBOX",
|
||||
"MT_DLZ_SEASAW_VISUAL",
|
||||
"MT_DLZ_RINGVACCUM",
|
||||
"MT_DLZ_SUCKEDRING",
|
||||
|
||||
"MT_WATERPALACETURBINE",
|
||||
"MT_WATERPALACEBUBBLE",
|
||||
"MT_WATERPALACEFOUNTAIN",
|
||||
"MT_KURAGEN",
|
||||
"MT_KURAGENBOMB",
|
||||
|
||||
"MT_BALLSWITCH_BALL",
|
||||
"MT_BALLSWITCH_PAD",
|
||||
};
|
||||
|
|
|
|||
499
src/info.c
499
src/info.c
|
|
@ -896,6 +896,26 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"CPT2", // Checkpoint Stick
|
||||
"CPT3", // Checkpoint Base
|
||||
|
||||
// rideroid (see info.h for detail)
|
||||
"RDRD",
|
||||
"RDRA",
|
||||
"RDRC",
|
||||
"RDRL",
|
||||
|
||||
// leaf storm egg ball.
|
||||
"LSZB",
|
||||
|
||||
// Dead Line Zone
|
||||
"DLZH",
|
||||
"DLZR",
|
||||
"DLZS",
|
||||
"DLZA",
|
||||
|
||||
// Water Palace Zone
|
||||
"WPWL", // turbine
|
||||
"WPZF", // fountain
|
||||
"WPZK", // klagen
|
||||
|
||||
"SA2S", // SA2-style Ball Switch
|
||||
|
||||
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
|
||||
|
|
@ -5435,6 +5455,25 @@ state_t states[NUMSTATES] =
|
|||
{SPR_SGNS, FF_ADD|FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_CHECKPOINT_SPARK11}, // S_CHECKPOINT_SPARK10
|
||||
{SPR_SGNS, FF_ADD|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_CHECKPOINT_SPARK1}, // S_CHECKPOINT_SPARK11
|
||||
|
||||
// Las Vegas
|
||||
{SPR_RDRD, 0, -1, {NULL}, 0, 0, S_RIDEROID}, // S_RIDEROID
|
||||
{SPR_RDRC, FF_ANIMATE|FF_FULLBRIGHT|FF_TRANS30, -1, {NULL}, 3, 2, S_RIDEROID_ICON}, // S_RIDEROID_ICON
|
||||
|
||||
// Leaf Storm
|
||||
{SPR_LSZB, 0, -1, {NULL}, 0, 0, S_EGGBALL}, // S_EGGBALL
|
||||
|
||||
// Dead Line
|
||||
{SPR_DLZH, 0, -1, {NULL}, 0, 0, S_DLZHOVER}, // S_DLZHOVER
|
||||
|
||||
{SPR_DLZR, 0, -1, {NULL}, 0, 0, S_DLZROCKET_L}, // S_DLZROCKET_L
|
||||
{SPR_DLZR, 1, -1, {NULL}, 0, 0, S_DLZROCKET_R}, // S_DLZROCKET_R
|
||||
|
||||
// Water Palace
|
||||
{SPR_WPZF, 0, -1, {NULL}, 0, 0, S_WPZFOUNTAIN}, // S_WPZFOUNTAIN
|
||||
{SPR_WPZF, 1|FF_ANIMATE, -1, {NULL}, 3, 2, S_WPZFOUNTAINANIM}, // S_WPZFOUNTAINANIM
|
||||
{SPR_WPZK, FF_ANIMATE, -1, {NULL}, 3, 12, S_KURAGEN}, // S_KURAGEN
|
||||
{SPR_WPZK, 4, -1, {NULL}, 0, 0, S_KURAGENBOMB}, // S_KURAGENBOMB
|
||||
|
||||
{SPR_SA2S, FF_SEMIBRIGHT|3, -1, {NULL}, 0, 0, S_NULL}, // S_BALLSWITCH_BALL
|
||||
{SPR_SA2S, FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM|4, -1, {NULL}, 1, 1, S_NULL}, // S_BALLSWITCH_BALL_ACTIVE
|
||||
{SPR_SA2S, FF_FLOORSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_BALLSWITCH_PAD
|
||||
|
|
@ -30458,6 +30497,465 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_RIDEROID
|
||||
-1, // doomednum
|
||||
S_RIDEROID, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
30*FRACUNIT, // radius
|
||||
40*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_RIDEROIDNODE
|
||||
3711, // doomednum
|
||||
S_RIDEROID_ICON, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
80*FRACUNIT, // radius
|
||||
80*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_NOCLIP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_LSZ_BUNGEE
|
||||
3440, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
127*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_SPECIAL, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_LSZ_EGGBALLSPAWNER
|
||||
3443, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8*FRACUNIT, // radius
|
||||
8*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_LSZ_EGGBALL
|
||||
-1, // doomednum
|
||||
S_EGGBALL, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
32*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
0, // display offset
|
||||
DMG_TUMBLE, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_PAIN, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DLZ_HOVER,
|
||||
3430, // doomednum
|
||||
S_DLZHOVER, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
100*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_SOLID, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DLZ_ROCKET,
|
||||
3431, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
100*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_SPECIAL, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DLZ_SEASAW_SPAWN,
|
||||
3432, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
32*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
0, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DLZ_SEASAW_HITBOX,
|
||||
-1, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8*FRACUNIT, // radius
|
||||
40*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DLZ_SEASAW_VISUAL,
|
||||
-1, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
40*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DLZ_RINGVACCUM,
|
||||
3433, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
96*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DLZ_SUCKEDRING,
|
||||
-1, // doomednum
|
||||
S_RING, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
32*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_WATERPALACETURBINE
|
||||
3400, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
32*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_NOBLOCKMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_WATERPALACEBUBBLE
|
||||
-1, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
32*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_WATERPALACEFOUNTAIN
|
||||
3401, // doomednum
|
||||
S_WPZFOUNTAIN, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
16*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_KURAGEN
|
||||
3402, // doomednum
|
||||
S_KURAGEN, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
64*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_KURAGENBOMB
|
||||
-1, // doomednum
|
||||
S_KURAGENBOMB, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
64*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
DMG_EXPLODE, // damage
|
||||
sfx_None, // activesound
|
||||
MF_PAIN, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BALLSWITCH_BALL
|
||||
5000, // doomednum
|
||||
S_BALLSWITCH_BALL, // spawnstate
|
||||
|
|
@ -30513,6 +31011,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
},
|
||||
};
|
||||
|
||||
|
||||
skincolor_t skincolors[MAXSKINCOLORS] = {
|
||||
{"Default", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false, UINT16_MAX}, // SKINCOLOR_NONE
|
||||
|
||||
|
|
|
|||
57
src/info.h
57
src/info.h
|
|
@ -1243,7 +1243,7 @@ typedef enum sprite
|
|||
SPR_ARK3,
|
||||
SPR_ARK4,
|
||||
SPR_ARK5,
|
||||
|
||||
|
||||
|
||||
SPR_BUMP, // Player/shell bump
|
||||
SPR_FLEN, // Shell hit graphics stuff
|
||||
|
|
@ -1452,6 +1452,22 @@ typedef enum sprite
|
|||
SPR_CPT2, // Checkpoint Stick
|
||||
SPR_CPT3, // Checkpoint Base
|
||||
|
||||
SPR_RDRD, // rideroid
|
||||
SPR_RDRA, // rideroid node sprites
|
||||
SPR_RDRC,
|
||||
SPR_RDRL,
|
||||
|
||||
SPR_LSZB, // eggman ball.
|
||||
|
||||
SPR_DLZH, // DLZ Hover
|
||||
SPR_DLZR, // DLZ Rocket
|
||||
SPR_DLZS, // DLZ Seasaw
|
||||
SPR_DLZA, // Helper arrows for rocket
|
||||
|
||||
SPR_WPWL, // turbine
|
||||
SPR_WPZF, // fountain
|
||||
SPR_WPZK, // klagen
|
||||
|
||||
SPR_SA2S, // SA2-style Ball Switch
|
||||
|
||||
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
|
||||
|
|
@ -5864,6 +5880,24 @@ typedef enum state
|
|||
S_CHECKPOINT_SPARK10,
|
||||
S_CHECKPOINT_SPARK11,
|
||||
|
||||
// rideroid
|
||||
S_RIDEROID,
|
||||
S_RIDEROID_ICON,
|
||||
|
||||
// leaf storm
|
||||
S_EGGBALL,
|
||||
|
||||
// dead line zone
|
||||
S_DLZHOVER,
|
||||
S_DLZROCKET_L,
|
||||
S_DLZROCKET_R,
|
||||
|
||||
// water palace zone
|
||||
S_WPZFOUNTAIN,
|
||||
S_WPZFOUNTAINANIM,
|
||||
S_KURAGEN,
|
||||
S_KURAGENBOMB,
|
||||
|
||||
S_BALLSWITCH_BALL,
|
||||
S_BALLSWITCH_BALL_ACTIVE,
|
||||
S_BALLSWITCH_PAD,
|
||||
|
|
@ -7044,6 +7078,27 @@ typedef enum mobj_type
|
|||
MT_CHECKPOINT_END,
|
||||
MT_SCRIPT_THING,
|
||||
|
||||
MT_RIDEROID,
|
||||
MT_RIDEROIDNODE,
|
||||
|
||||
MT_LSZ_BUNGEE,
|
||||
MT_LSZ_EGGBALLSPAWNER,
|
||||
MT_LSZ_EGGBALL,
|
||||
|
||||
MT_DLZ_HOVER,
|
||||
MT_DLZ_ROCKET,
|
||||
MT_DLZ_SEASAW_SPAWN,
|
||||
MT_DLZ_SEASAW_HITBOX,
|
||||
MT_DLZ_SEASAW_VISUAL,
|
||||
MT_DLZ_RINGVACCUM,
|
||||
MT_DLZ_SUCKEDRING,
|
||||
|
||||
MT_WATERPALACETURBINE,
|
||||
MT_WATERPALACEBUBBLE,
|
||||
MT_WATERPALACEFOUNTAIN,
|
||||
MT_KURAGEN,
|
||||
MT_KURAGENBOMB,
|
||||
|
||||
MT_BALLSWITCH_BALL,
|
||||
MT_BALLSWITCH_PAD,
|
||||
|
||||
|
|
|
|||
36
src/k_kart.c
36
src/k_kart.c
|
|
@ -57,6 +57,19 @@
|
|||
// comeback is Battle Mode's karma comeback, also bool
|
||||
// mapreset is set when enough players fill an empty server
|
||||
|
||||
// lat: used for when the player is in some weird state where it wouldn't be wise for it to be overwritten by another object that does similarly wacky shit.
|
||||
boolean K_isPlayerInSpecialState(player_t *p)
|
||||
{
|
||||
return (
|
||||
p->rideroid
|
||||
|| p->rdnodepull
|
||||
|| p->bungee
|
||||
|| p->dlzrocket
|
||||
|| p->seasaw
|
||||
|| p->turbine
|
||||
);
|
||||
}
|
||||
|
||||
boolean K_IsDuelItem(mobjtype_t type)
|
||||
{
|
||||
switch (type)
|
||||
|
|
@ -8305,7 +8318,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
player->incontrol = 0;
|
||||
player->incontrol++;
|
||||
}
|
||||
|
||||
|
||||
player->incontrol = min(player->incontrol, 5*TICRATE);
|
||||
player->incontrol = max(player->incontrol, -5*TICRATE);
|
||||
|
||||
|
|
@ -11898,7 +11911,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
K_KartDrift(player, onground);
|
||||
K_KartSpindash(player);
|
||||
|
||||
if (onground == false)
|
||||
if (onground == false
|
||||
&& !player->bungee // if this list of condition ever gets bigger, maybe this should become a function.
|
||||
)
|
||||
{
|
||||
K_AirFailsafe(player);
|
||||
}
|
||||
|
|
@ -11908,6 +11923,23 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
}
|
||||
|
||||
Obj_RingShooterInput(player);
|
||||
|
||||
if (player->bungee)
|
||||
Obj_playerBungeeThink(player);
|
||||
|
||||
if (player->dlzrocket)
|
||||
Obj_playerDLZRocket(player);
|
||||
|
||||
if (player->seasawcooldown && !player->seasaw)
|
||||
player->seasawcooldown--;
|
||||
|
||||
if (player->turbine)
|
||||
{
|
||||
if (player->mo->tracer && !P_MobjWasRemoved(player->mo->tracer))
|
||||
Obj_playerWPZTurbine(player);
|
||||
else
|
||||
player->turbine--; // acts as a cooldown
|
||||
}
|
||||
}
|
||||
|
||||
void K_CheckSpectateStatus(boolean considermapreset)
|
||||
|
|
|
|||
|
|
@ -229,6 +229,9 @@ UINT32 K_PointLimitForGametype(void);
|
|||
|
||||
boolean K_Cooperative(void);
|
||||
|
||||
// lat: used for when the player is in some weird state where it wouldn't be wise for it to be overwritten by another object that does similarly wacky shit.
|
||||
boolean K_isPlayerInSpecialState(player_t *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -233,12 +233,60 @@ boolean Obj_GetCheckpointRespawnPosition(const mobj_t *checkpoint, vector3_t *re
|
|||
angle_t Obj_GetCheckpointRespawnAngle(const mobj_t *checkpoint);
|
||||
void Obj_ActivateCheckpointInstantly(mobj_t* mobj);
|
||||
|
||||
/* Rideroid / Rideroid Node */
|
||||
void Obj_RideroidThink(mobj_t *mo);
|
||||
void Obj_RideroidNodeSpawn(mobj_t *mo);
|
||||
void Obj_RideroidNodeThink(mobj_t *mo);
|
||||
void Obj_getPlayerOffRideroid(mobj_t *mo); // used in p_map.c to get off of em when passing transfer lines.
|
||||
|
||||
/* LSZ Bungee */
|
||||
void Obj_BungeeSpecial(mobj_t *mo, player_t *p); // used when the player touches the bungee, to be used in p_inter.c
|
||||
void Obj_playerBungeeThink(player_t *p); // player interaction with the bungee. The bungee is to be stored in p->mo->tracer.
|
||||
|
||||
/* LSZ Balls */
|
||||
void Obj_EggBallSpawnerThink(mobj_t *mo);
|
||||
void Obj_EggBallThink(mobj_t *mo);
|
||||
|
||||
/* DLZ Rockets */
|
||||
void Obj_DLZRocketThink(mobj_t *mo);
|
||||
void Obj_DLZRocketSpecial(mobj_t *mo, player_t *p); // touch activation
|
||||
void Obj_playerDLZRocket(player_t *p); // player looping thinker
|
||||
void Obj_DLZRocketDismount(player_t *p); // used in p_map.c to get off the rocket when we cross transfer lines.
|
||||
|
||||
/* DLZ Seasaw */
|
||||
void Obj_DLZSeasawSpawn(mobj_t *mo);
|
||||
void Obj_DLZSeasawThink(mobj_t *mo);
|
||||
void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2);
|
||||
|
||||
/* DLZ Hover */
|
||||
void Obj_DLZHoverSpawn(mobj_t *mo);
|
||||
void Obj_DLZHoverCollide(mobj_t *mo, mobj_t *mo2);
|
||||
|
||||
/* DLZ Ring Vaccum */
|
||||
void Obj_DLZRingVaccumSpawn(mobj_t *mo);
|
||||
void Obj_DLZRingVaccumCollide(mobj_t *mo, mobj_t *mo2);
|
||||
void Obj_DLZSuckedRingThink(mobj_t *mo);
|
||||
|
||||
/* WPZ Turbine */
|
||||
void Obj_WPZTurbineSpawn(mobj_t *mo);
|
||||
void Obj_WPZTurbineThinker(mobj_t *mo);
|
||||
void Obj_playerWPZTurbine(player_t *p);
|
||||
void Obj_WPZBubbleThink(mobj_t *mo);
|
||||
|
||||
/* WPZ Fountains */
|
||||
void Obj_WPZFountainThink(mobj_t *mo);
|
||||
|
||||
/* WPZ Kuragens */
|
||||
void Obj_WPZKuragenThink(mobj_t *mo);
|
||||
void Obj_WPZKuragenBombThink(mobj_t *mo);
|
||||
|
||||
/* Ball Switch */
|
||||
void Obj_BallSwitchInit(mobj_t *mobj);
|
||||
void Obj_BallSwitchThink(mobj_t *mobj);
|
||||
void Obj_BallSwitchTouched(mobj_t *mobj, mobj_t *toucher);
|
||||
void Obj_BallSwitchDamaged(mobj_t *mobj, mobj_t *inflictor, mobj_t *source);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -465,6 +465,69 @@ static int player_get(lua_State *L)
|
|||
else if (fastcmp(field,"follower"))
|
||||
LUA_PushUserdata(L, plr->follower, META_MOBJ);
|
||||
//
|
||||
|
||||
// rideroids
|
||||
else if (fastcmp(field,"rideroid"))
|
||||
lua_pushboolean(L, plr->rideroid);
|
||||
else if (fastcmp(field,"rdnodepull"))
|
||||
lua_pushboolean(L, plr->rdnodepull);
|
||||
else if (fastcmp(field,"rideroidangle"))
|
||||
lua_pushinteger(L, plr->rideroidangle);
|
||||
else if (fastcmp(field,"rideroidspeed"))
|
||||
lua_pushinteger(L, plr->rideroidspeed);
|
||||
else if (fastcmp(field,"rideroidrollangle"))
|
||||
lua_pushinteger(L, plr->rideroidrollangle);
|
||||
else if (fastcmp(field,"rdaddmomx"))
|
||||
lua_pushinteger(L, plr->rdaddmomx);
|
||||
else if (fastcmp(field,"rdaddmomy"))
|
||||
lua_pushinteger(L, plr->rdaddmomy);
|
||||
else if (fastcmp(field,"rdaddmomz"))
|
||||
lua_pushinteger(L, plr->rdaddmomz);
|
||||
|
||||
// bungee
|
||||
else if (fastcmp(field,"bungee"))
|
||||
lua_pushinteger(L, plr->bungee);
|
||||
|
||||
// dlz hover
|
||||
else if (fastcmp(field,"lasthover"))
|
||||
lua_pushinteger(L, plr->lasthover);
|
||||
|
||||
// dlz rocket
|
||||
else if (fastcmp(field,"dlzrocket"))
|
||||
lua_pushinteger(L, plr->dlzrocket);
|
||||
else if (fastcmp(field,"dlzrocketangle"))
|
||||
lua_pushinteger(L, plr->dlzrocketangle);
|
||||
else if (fastcmp(field,"dlzrocketanglev"))
|
||||
lua_pushinteger(L, plr->dlzrocketanglev);
|
||||
else if (fastcmp(field,"dlzrocketspd"))
|
||||
lua_pushinteger(L, plr->dlzrocketspd);
|
||||
|
||||
// seasaws
|
||||
else if (fastcmp(field,"seasaw"))
|
||||
lua_pushboolean(L, plr->seasaw);
|
||||
else if (fastcmp(field,"seasawcooldown"))
|
||||
lua_pushinteger(L, plr->seasawcooldown);
|
||||
else if (fastcmp(field,"seasawdist"))
|
||||
lua_pushinteger(L, plr->seasawdist);
|
||||
else if (fastcmp(field,"seasawangle"))
|
||||
lua_pushinteger(L, plr->seasawangle);
|
||||
else if (fastcmp(field,"seasawangleadd"))
|
||||
lua_pushinteger(L, plr->seasawangleadd);
|
||||
else if (fastcmp(field,"seasawmoreangle"))
|
||||
lua_pushinteger(L, plr->seasawmoreangle);
|
||||
else if (fastcmp(field,"seasawdir"))
|
||||
lua_pushboolean(L, plr->seasawdir);
|
||||
|
||||
// turbine
|
||||
else if (fastcmp(field,"turbine"))
|
||||
lua_pushinteger(L, plr->turbine);
|
||||
else if (fastcmp(field,"turbineangle"))
|
||||
lua_pushinteger(L, plr->turbineangle);
|
||||
else if (fastcmp(field,"turbineheight"))
|
||||
lua_pushinteger(L, plr->turbineheight);
|
||||
else if (fastcmp(field,"turbinespd"))
|
||||
lua_pushinteger(L, plr->turbinespd);
|
||||
|
||||
else if (fastcmp(field,"charflags"))
|
||||
lua_pushinteger(L, plr->charflags);
|
||||
else if (fastcmp(field,"followitem"))
|
||||
|
|
@ -860,6 +923,70 @@ static int player_set(lua_State *L)
|
|||
plr->followerready = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"follower")) // it's probably best we don't allow the follower mobj to change.
|
||||
return NOSET;
|
||||
|
||||
// time to add to the endless elseif list!!!!
|
||||
// rideroids
|
||||
else if (fastcmp(field,"rideroid"))
|
||||
plr->rideroid = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"rdnodepull"))
|
||||
plr->rdnodepull = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"rideroidangle"))
|
||||
plr->rideroidangle = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"rideroidspeed"))
|
||||
plr->rideroidspeed = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"rideroidrollangle"))
|
||||
plr->rideroidrollangle = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"rdaddmomx"))
|
||||
plr->rdaddmomx = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"rdaddmomy"))
|
||||
plr->rdaddmomy = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"rdaddmomz"))
|
||||
plr->rdaddmomz = luaL_checkfixed(L, 3);
|
||||
|
||||
// bungee
|
||||
else if (fastcmp(field,"bungee"))
|
||||
plr->bungee = luaL_checkinteger(L, 3);
|
||||
|
||||
// dlz hover
|
||||
else if (fastcmp(field,"lasthover"))
|
||||
plr->lasthover = luaL_checkinteger(L, 3);
|
||||
|
||||
// dlz rocket
|
||||
else if (fastcmp(field,"dlzrocket"))
|
||||
plr->dlzrocket = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"dlzrocketangle"))
|
||||
plr->dlzrocketangle = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"dlzrocketanglev"))
|
||||
plr->dlzrocketanglev = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"dlzrocketspd"))
|
||||
plr->dlzrocketspd = luaL_checkfixed(L, 3);
|
||||
|
||||
// seasaws
|
||||
else if (fastcmp(field,"seasaw"))
|
||||
plr->seasaw = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"seasawcooldown"))
|
||||
plr->seasawcooldown = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"seasawdist"))
|
||||
plr->seasawdist = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"seasawangle"))
|
||||
plr->seasawangle = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"seasawangleadd"))
|
||||
plr->seasawangleadd = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"seasawmoreangle"))
|
||||
plr->seasawmoreangle = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"seasawdir"))
|
||||
plr->seasawdir = luaL_checkboolean(L, 3);
|
||||
|
||||
// turbines
|
||||
else if (fastcmp(field,"turbine"))
|
||||
plr->turbine = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"turbineangle"))
|
||||
plr->turbineangle = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"turbineheight"))
|
||||
plr->turbineheight = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"turbinespd"))
|
||||
plr->turbinespd = luaL_checkinteger(L, 3);
|
||||
|
||||
//
|
||||
else if (fastcmp(field,"charflags"))
|
||||
plr->charflags = (UINT32)luaL_checkinteger(L, 3);
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ typedef enum
|
|||
PR_SPARKLE, // Endsign and/or Emerald
|
||||
|
||||
PR_MOVINGTARGET, // Randomised moving targets
|
||||
PR_TRACKHAZARD, // Randomised track hazards
|
||||
|
||||
PR_BATTLEUFO, // Battle UFO spawning
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,14 @@ target_sources(SRB2SDL2 PRIVATE
|
|||
sneaker-panel.c
|
||||
emerald.c
|
||||
checkpoint.cpp
|
||||
rideroid.c
|
||||
bungee.c
|
||||
eggball.c
|
||||
dlzrocket.c
|
||||
dlzseasaw.c
|
||||
dlzothers.c
|
||||
wpzturbine.c
|
||||
wpzothers.c
|
||||
shadow.cpp
|
||||
ball-switch.cpp
|
||||
)
|
||||
|
|
|
|||
119
src/objects/bungee.c
Normal file
119
src/objects/bungee.c
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2022 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file bungee.c
|
||||
/// \brief Leaf Storm bungee interaction/behaviour code to be used in other files.
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../info.h"
|
||||
#include "../k_kart.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../m_random.h"
|
||||
#include "../p_local.h"
|
||||
#include "../r_main.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../g_game.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../k_waypoint.h"
|
||||
#include "../k_respawn.h"
|
||||
#include "../k_collide.h"
|
||||
|
||||
#define BUNGEE_NONE 0
|
||||
#define BUNGEE_LATCH 1
|
||||
#define BUNGEE_LAUNCH 2
|
||||
|
||||
// Touching the bungee, used in p_inter.c
|
||||
void Obj_BungeeSpecial(mobj_t *mo, player_t *p)
|
||||
{
|
||||
|
||||
mobj_t *latch;
|
||||
|
||||
if (P_IsObjectOnGround(p->mo) || p->springstars || K_isPlayerInSpecialState(p))
|
||||
return;
|
||||
|
||||
P_InstaThrust(p->mo, 0, 0);
|
||||
p->bungee = BUNGEE_LATCH;
|
||||
p->mo->flags |= MF_NOCLIPTHING; // prevent players from bumping if they latch onto the same bungee.
|
||||
p->pflags |= PF_NOFASTFALL; // didn't know this flag existed but it's very convenient!!
|
||||
|
||||
latch = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_THOK);
|
||||
P_SetMobjState(latch, S_INVISIBLE);
|
||||
latch->angle = mo->angle;
|
||||
|
||||
S_StartSound(mo, sfx_s3k5a);
|
||||
P_SetTarget(&p->mo->tracer, latch);
|
||||
}
|
||||
|
||||
// this is the thinker to call on the player when they get bungee'd.
|
||||
void Obj_playerBungeeThink(player_t *p)
|
||||
{
|
||||
|
||||
mobj_t *bungee = p->mo->tracer;
|
||||
UINT8 i;
|
||||
|
||||
// someone removed it
|
||||
if (!bungee || P_MobjWasRemoved(bungee))
|
||||
return;
|
||||
|
||||
bungee->tics = 4; // we set this to a low value so that it despawns if the player vanishes for some reason.
|
||||
|
||||
if (p->bungee == BUNGEE_LATCH)
|
||||
{
|
||||
// rr has super high gravity which gets in the way.
|
||||
p->mo->flags |= MF_NOGRAVITY;
|
||||
p->mo->momz = (p->mo->momz*9)/10;
|
||||
|
||||
if (abs(p->mo->momz) < 6*mapobjectscale)
|
||||
{
|
||||
p->bungee = BUNGEE_LAUNCH;
|
||||
p->mo->momz = P_MobjFlip(p->mo)*mapobjectscale;
|
||||
S_StartSound(p->mo, sfx_s3k81);
|
||||
}
|
||||
}
|
||||
else if (p->bungee == BUNGEE_LAUNCH)
|
||||
{
|
||||
p->mo->momz = (p->mo->momz*12)/10;
|
||||
|
||||
// if we go above/below (depending on our flip flags) the bungee, release us!
|
||||
if ((p->mo->eflags & MFE_VERTICALFLIP && p->mo->z < bungee->z)
|
||||
|| (!(p->mo->eflags & MFE_VERTICALFLIP) && p->mo->z > bungee->z ))
|
||||
{
|
||||
|
||||
p->mo->flags &= ~MF_NOGRAVITY;
|
||||
p->mo->flags &= ~MF_NOCLIPTHING;
|
||||
p->pflags &= ~PF_NOFASTFALL;
|
||||
p->bungee = BUNGEE_NONE;
|
||||
P_InstaThrust(p->mo, bungee->angle, p->mo->momz/8);
|
||||
p->mo->momz = (p->mo->momz*3)/4;
|
||||
|
||||
p->springstars = TICRATE; // these are used as a buffer not to latch to vines again.
|
||||
p->springcolor = SKINCOLOR_EMERALD;
|
||||
|
||||
P_RemoveMobj(bungee);
|
||||
P_SetTarget(&p->mo->tracer, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// basic visuals (but hey they work fine enough!)
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
fixed_t xpos = -(bungee->x - p->mo->x) /8 *i;
|
||||
fixed_t ypos = -(bungee->y - p->mo->y) /8 *i;
|
||||
fixed_t zpos = -(bungee->z - p->mo->z) /8 *i;
|
||||
|
||||
mobj_t *seg = P_SpawnMobj(bungee->x + xpos, bungee->y + ypos, bungee->z + zpos, MT_THOK);
|
||||
|
||||
P_SetScale(seg, mapobjectscale/3);
|
||||
seg->color = SKINCOLOR_EMERALD;
|
||||
seg->frame = 0;
|
||||
seg->fuse = 2;
|
||||
}
|
||||
}
|
||||
133
src/objects/dlzothers.c
Normal file
133
src/objects/dlzothers.c
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2022 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file dlzothers.c
|
||||
/// \brief Dead Line Zone other objects (Hover + Ring Vaccum), they're small enough that we can just lump em together instead of having 2 more small files...
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../info.h"
|
||||
#include "../k_kart.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../m_random.h"
|
||||
#include "../p_local.h"
|
||||
#include "../r_main.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../g_game.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../k_waypoint.h"
|
||||
#include "../k_respawn.h"
|
||||
#include "../k_collide.h"
|
||||
|
||||
// Hover:
|
||||
void Obj_DLZHoverSpawn(mobj_t *mo)
|
||||
{
|
||||
P_SetScale(mo, mapobjectscale*4);
|
||||
mo->destscale = mapobjectscale*4;
|
||||
}
|
||||
|
||||
// collision between MT_PLAYER and hover
|
||||
void Obj_DLZHoverCollide(mobj_t *mo, mobj_t *mo2)
|
||||
{
|
||||
player_t *p = mo->player;
|
||||
|
||||
if (!p || p->lasthover == leveltime)
|
||||
return;
|
||||
|
||||
if (abs(mo->z - mo2->z) < 512*mapobjectscale)
|
||||
{
|
||||
// momz adjust
|
||||
if (mo2->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (mo->momz > -16*mapobjectscale)
|
||||
{
|
||||
mo->momz -= 8*mapobjectscale;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo->momz < 16*mapobjectscale)
|
||||
{
|
||||
mo->momz += 8*mapobjectscale;
|
||||
}
|
||||
}
|
||||
|
||||
// speed adjust
|
||||
if (p->speed > K_GetKartSpeed(p, false, false))
|
||||
P_Thrust(mo, R_PointToAngle2(0, 0, -mo->momx, -mo->momy), mapobjectscale/16);
|
||||
|
||||
if (!S_SoundPlaying(mo, sfx_s3kc6s))
|
||||
S_StartSound(mo, sfx_s3kc6s);
|
||||
|
||||
p->lasthover = leveltime;
|
||||
}
|
||||
}
|
||||
|
||||
// Ring Vaccum:
|
||||
void Obj_DLZRingVaccumSpawn(mobj_t *mo)
|
||||
{
|
||||
P_SetScale(mo, mapobjectscale*4);
|
||||
mo->destscale = mapobjectscale*4;
|
||||
}
|
||||
|
||||
// collision between MT_FLINGRING and ring vaccum
|
||||
void Obj_DLZRingVaccumCollide(mobj_t *mo, mobj_t *mo2)
|
||||
{
|
||||
mobj_t *fake;
|
||||
|
||||
if (mo->z + mo->height < mo2->z)
|
||||
return;
|
||||
|
||||
if (mo->z > mo2->z + mo2->height)
|
||||
return;
|
||||
|
||||
if (!P_IsObjectOnGround(mo) || mo->momz)
|
||||
return;
|
||||
|
||||
fake = P_SpawnMobj(mo->x, mo->y, mo->z, MT_DLZ_SUCKEDRING);
|
||||
P_SetScale(fake, mo->scale);
|
||||
fake->scalespeed = mapobjectscale/64;
|
||||
fake->destscale = 1;
|
||||
|
||||
P_SetTarget(&fake->target, mo2);
|
||||
|
||||
fake->angle = R_PointToAngle2(mo2->x, mo2->y, fake->x, fake->y);
|
||||
fake->movefactor = R_PointToDist2(mo2->x, mo2->y, fake->x, fake->y);
|
||||
|
||||
P_RemoveMobj(mo);
|
||||
}
|
||||
|
||||
void Obj_DLZSuckedRingThink(mobj_t *mo)
|
||||
{
|
||||
mobj_t *t = mo->target;
|
||||
fixed_t x, y;
|
||||
|
||||
// commit die if the target disappears for some fucking reason
|
||||
if (!t || P_MobjWasRemoved(t))
|
||||
{
|
||||
P_RemoveMobj(mo);
|
||||
return;
|
||||
}
|
||||
|
||||
x = t->x + FixedMul(mo->movefactor, FINECOSINE(mo->angle>>ANGLETOFINESHIFT));
|
||||
y = t->y + FixedMul(mo->movefactor, FINESINE(mo->angle>>ANGLETOFINESHIFT));
|
||||
|
||||
P_MoveOrigin(mo, x, y, mo->z);
|
||||
|
||||
if (mo->cusval < 24)
|
||||
mo->cusval++;
|
||||
|
||||
mo->angle += mo->cusval*ANG1;
|
||||
|
||||
if (mo->cusval > 8 && mo->movefactor)
|
||||
mo->movefactor -= 1;
|
||||
|
||||
if (mo->scale < mapobjectscale/12)
|
||||
P_RemoveMobj(mo);
|
||||
}
|
||||
201
src/objects/dlzrocket.c
Normal file
201
src/objects/dlzrocket.c
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2022 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file dlzrocket.c
|
||||
/// \brief Dead Line Zone free flight rockets! They cool af doe.
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../info.h"
|
||||
#include "../k_kart.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../m_random.h"
|
||||
#include "../p_local.h"
|
||||
#include "../r_main.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../g_game.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../k_waypoint.h"
|
||||
#include "../k_respawn.h"
|
||||
#include "../k_collide.h"
|
||||
#include "../k_color.h"
|
||||
|
||||
#define DLZROCKETDIST 96
|
||||
#define DLZROCKETSPEED 80
|
||||
#define DLZROCKETTURNSPEED ((ANG1*3)/2)
|
||||
#define DLZROCKETVERTSPEED (ANG1)
|
||||
#define DLZROCKETMAXVERT (ANG1*60)
|
||||
|
||||
void Obj_DLZRocketThink(mobj_t *mo)
|
||||
{
|
||||
UINT8 i;
|
||||
angle_t an = mo->angle + ANGLE_90;
|
||||
|
||||
if (mo->extravalue1)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
fixed_t x = mo->x + FixedMul(mapobjectscale, DLZROCKETDIST*FINECOSINE(an>>ANGLETOFINESHIFT));
|
||||
fixed_t y = mo->y + FixedMul(mapobjectscale, DLZROCKETDIST*FINESINE(an>>ANGLETOFINESHIFT));
|
||||
|
||||
mobj_t *r = P_SpawnMobj(x, y, mo->z, MT_THOK);
|
||||
P_SetMobjState(r, i ? S_DLZROCKET_L : S_DLZROCKET_R);
|
||||
P_SetScale(r, (mapobjectscale*3)/2);
|
||||
r->destscale = (mapobjectscale*3)/2;
|
||||
r->angle = mo->spawnpoint->angle*ANG1;
|
||||
r->tics = -1;
|
||||
|
||||
an += ANGLE_180;
|
||||
}
|
||||
|
||||
mo->extravalue1 = 1;
|
||||
}
|
||||
|
||||
void Obj_DLZRocketDismount(player_t *p)
|
||||
{
|
||||
// we aren't mounted on one.
|
||||
if (!p->dlzrocket)
|
||||
return;
|
||||
|
||||
p->dlzrocket = 0;
|
||||
K_SpawnMineExplosion(p->mo, p->mo->color, 3);
|
||||
S_StartSound(p->mo, sfx_s3k4e);
|
||||
}
|
||||
|
||||
// touching the rocket, initialize player vars etc...
|
||||
void Obj_DLZRocketSpecial(mobj_t *mo, player_t *p)
|
||||
{
|
||||
if (K_isPlayerInSpecialState(p)) // already on one, don't bother resetting, duh.
|
||||
return;
|
||||
|
||||
p->mo->z = mo->z + 16*P_MobjFlip(p->mo)*mapobjectscale;
|
||||
P_SetPlayerAngle(p->mo->player, mo->angle);
|
||||
p->dlzrocket = true;
|
||||
p->dlzrocketangle = mo->angle;
|
||||
p->dlzrocketanglev = 0;
|
||||
p->dlzrocketspd = DLZROCKETSPEED;
|
||||
|
||||
p->spinouttimer = 0;
|
||||
p->wipeoutslow = 0;
|
||||
|
||||
S_StartSound(mo, sfx_s262);
|
||||
}
|
||||
|
||||
void Obj_playerDLZRocket(player_t *p)
|
||||
{
|
||||
|
||||
fixed_t maxspd = DLZROCKETSPEED;
|
||||
angle_t visangle;
|
||||
UINT8 i, j;
|
||||
|
||||
p->dlzrocket++;
|
||||
|
||||
// helper arrows at the start of the ride to tell players they can move freely
|
||||
if (p->dlzrocket < TICRATE*2
|
||||
&& leveltime%10 < 5)
|
||||
{
|
||||
mobj_t *arr = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_THOK);
|
||||
arr->sprite = SPR_DLZA;
|
||||
arr->frame = FF_FULLBRIGHT;
|
||||
P_SetScale(arr, 2*mapobjectscale);
|
||||
arr->tics = 2;
|
||||
}
|
||||
|
||||
// calc max speed
|
||||
if (p->ringboost)
|
||||
maxspd += 10;
|
||||
|
||||
if (p->startboost)
|
||||
maxspd += 30;
|
||||
|
||||
// set player speed
|
||||
if (p->dlzrocketspd < maxspd)
|
||||
p->dlzrocketspd++;
|
||||
else if (p->dlzrocketspd > maxspd)
|
||||
p->dlzrocket--;
|
||||
|
||||
// so long as PF_STASIS is applied, let the angle be overwritten freely.
|
||||
// this is used by seasaws but can be used for misc modding purposes too.
|
||||
if (p->pflags & PF_STASIS)
|
||||
p->dlzrocketangle = p->mo->angle;
|
||||
else
|
||||
{
|
||||
SINT8 turndir = 0;
|
||||
P_SetPlayerAngle(p->mo->player, p->dlzrocketangle);
|
||||
|
||||
if (p->cmd.turning > 0)
|
||||
turndir = 1;
|
||||
else if (p->cmd.turning < 0)
|
||||
turndir = -1;
|
||||
|
||||
p->dlzrocketangle += turndir*DLZROCKETTURNSPEED;
|
||||
|
||||
if (p->cmd.throwdir > 0)
|
||||
p->dlzrocketanglev = min(DLZROCKETMAXVERT, p->dlzrocketanglev + DLZROCKETVERTSPEED);
|
||||
else if (p->cmd.throwdir < 0)
|
||||
p->dlzrocketanglev = max(-DLZROCKETMAXVERT, p->dlzrocketanglev - DLZROCKETVERTSPEED);
|
||||
|
||||
}
|
||||
|
||||
// angle correction on ceilings (THIS CODE LOOKS AWFUL AND IT CAN PROBABLY BE DONE BETTER......)
|
||||
if ( (!(p->mo->eflags & MFE_VERTICALFLIP) && (p->mo->z+p->mo->height >= p->mo->ceilingz))
|
||||
|| (p->mo->eflags & MFE_VERTICALFLIP && p->mo->z <= p->mo->floorz))
|
||||
if ( (!(p->mo->eflags & MFE_VERTICALFLIP) && p->dlzrocketanglev > 0)
|
||||
|| (p->mo->eflags & MFE_VERTICALFLIP && p->dlzrocketanglev < 0))
|
||||
p->dlzrocketanglev = 0;
|
||||
|
||||
|
||||
if (!(p->pflags & PF_STASIS))
|
||||
{
|
||||
angle_t van = p->dlzrocketanglev /4;
|
||||
P_InstaThrust(p->mo, p->dlzrocketangle, FixedMul(mapobjectscale, p->dlzrocketspd*FINECOSINE(van>>ANGLETOFINESHIFT)));
|
||||
p->mo->momz = FixedMul(mapobjectscale, p->dlzrocketspd*FINESINE((angle_t)p->dlzrocketanglev>>ANGLETOFINESHIFT));
|
||||
}
|
||||
|
||||
if (leveltime%4 == 0)
|
||||
S_StartSound(p->mo, sfx_s1c8);
|
||||
|
||||
// finally, visuals.
|
||||
visangle = p->mo->angle + ANGLE_90;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
fixed_t x = p->mo->x + FixedMul(mapobjectscale, 56*FINECOSINE(visangle>>ANGLETOFINESHIFT));
|
||||
fixed_t y = p->mo->y + FixedMul(mapobjectscale, 56*FINESINE(visangle>>ANGLETOFINESHIFT));
|
||||
mobj_t *r = P_SpawnMobj(x, y, p->mo->z + 16*mapobjectscale, MT_THOK);
|
||||
r->fuse = 2;
|
||||
P_SetMobjState(r, i ? S_DLZROCKET_L : S_DLZROCKET_R);
|
||||
P_SetScale(r, (mapobjectscale*3)/2);
|
||||
r->angle = p->mo->angle;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
fixed_t xoffs = P_RandomRange(PR_EXPLOSION, -6, 6)*mapobjectscale;
|
||||
fixed_t yoffs = P_RandomRange(PR_EXPLOSION, -6, 6)*mapobjectscale;
|
||||
fixed_t soffs = P_RandomRange(PR_EXPLOSION, 0, 3);
|
||||
|
||||
mobj_t *expl = P_SpawnMobj(r->x + xoffs, r->y + yoffs, r->z + xoffs, MT_THOK);
|
||||
P_SetMobjState(expl, S_QUICKBOOM1+soffs);
|
||||
expl->color = p->mo->color;
|
||||
P_SetScale(expl, mapobjectscale);
|
||||
expl->destscale = 2*mapobjectscale;
|
||||
|
||||
if (p->startboost)
|
||||
expl->color = K_RainbowColor(leveltime);
|
||||
|
||||
|
||||
}
|
||||
visangle += ANGLE_180;
|
||||
}
|
||||
|
||||
if ((p->dlzrocket > 10 && (P_IsObjectOnGround(p->mo) || p->mo->eflags & MFE_JUSTBOUNCEDWALL))
|
||||
|| p->spinouttimer || p->wipeoutslow || p->tumbleHeight)
|
||||
Obj_DLZRocketDismount(p);
|
||||
}
|
||||
365
src/objects/dlzseasaw.c
Normal file
365
src/objects/dlzseasaw.c
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2022 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file dlzseasaw.c
|
||||
/// \brief Dead Line Zone seasaw. Amplifies momentum in a stylish way... and hellish as far as code is concerned, heh!
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../info.h"
|
||||
#include "../k_kart.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../m_random.h"
|
||||
#include "../p_local.h"
|
||||
#include "../r_main.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../g_game.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../k_waypoint.h"
|
||||
#include "../k_respawn.h"
|
||||
#include "../k_collide.h"
|
||||
|
||||
// updates the seasaw's visuals and hitboxes using the hnext/hprev list.
|
||||
static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme)
|
||||
{
|
||||
|
||||
mobj_t *ptr = mo;
|
||||
mobj_t *ptrp = mo;
|
||||
UINT8 i, j;
|
||||
angle_t visan = (angle_t)mo->extravalue1 + ANGLE_90;
|
||||
|
||||
if (mo->tracer && !P_MobjWasRemoved(mo->tracer))
|
||||
{
|
||||
mo->tracer->tics = 3;
|
||||
P_MoveOrigin(mo->tracer, mo->x, mo->y, mo->z);
|
||||
P_SetScale(mo->tracer, mo->scale);
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
mo->tracer->eflags |= MFE_VERTICALFLIP;
|
||||
mo->tracer->eflags |= MF2_OBJECTFLIP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
INT32 dist = 32; // visuals dist
|
||||
INT32 hdist = 16; // hitbox dist
|
||||
|
||||
// visuals
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
// get our mobj.
|
||||
if (ptr && !P_MobjWasRemoved(ptr) && ptr->hnext && !P_MobjWasRemoved(ptr->hnext))
|
||||
{
|
||||
fixed_t x = mo->x + FixedMul(mo->scale, dist*FINECOSINE(visan>>ANGLETOFINESHIFT));
|
||||
fixed_t y = mo->y + FixedMul(mo->scale, dist*FINESINE(visan>>ANGLETOFINESHIFT));
|
||||
ptr = ptr->hnext;
|
||||
|
||||
P_MoveOrigin(ptr, x, y, mo->z + 8*mapobjectscale*P_MobjFlip(mo));
|
||||
ptr->angle = visan;
|
||||
ptr->tics = 3;
|
||||
P_SetScale(ptr, mo->scale);
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
ptr->eflags |= MFE_VERTICALFLIP;
|
||||
ptr->flags2 |= MF2_OBJECTFLIP;
|
||||
}
|
||||
|
||||
if (ghostme && leveltime&1)
|
||||
{
|
||||
mobj_t *g = P_SpawnGhostMobj(ptr);
|
||||
g->colorized = true;
|
||||
g->color = mo->color;
|
||||
g->fuse = 3;
|
||||
}
|
||||
|
||||
dist += 55;
|
||||
}
|
||||
}
|
||||
|
||||
// hitboxes:
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
// get our mobj.
|
||||
if (ptrp && !P_MobjWasRemoved(ptrp) && ptrp->hprev && !P_MobjWasRemoved(ptrp->hprev))
|
||||
{
|
||||
|
||||
fixed_t x = mo->x + FixedMul(mo->scale, hdist*FINECOSINE(visan>>ANGLETOFINESHIFT));
|
||||
fixed_t y = mo->y + FixedMul(mo->scale, hdist*FINESINE(visan>>ANGLETOFINESHIFT));
|
||||
|
||||
ptrp = ptrp->hprev;
|
||||
|
||||
P_SetOrigin(ptrp, x, y, mo->z + 8*mapobjectscale*P_MobjFlip(mo)); // it's invisible so nobody cares about interpolating it.
|
||||
ptrp->angle = visan;
|
||||
ptrp->tics = 3;
|
||||
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
ptrp->eflags |= MFE_VERTICALFLIP;
|
||||
ptrp->flags2 |= MF2_OBJECTFLIP;
|
||||
}
|
||||
|
||||
hdist += 16;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
visan += ANGLE_180;
|
||||
}
|
||||
}
|
||||
|
||||
// sets up seasaw spawn objects to update each frame later
|
||||
void Obj_DLZSeasawSpawn(mobj_t *mo)
|
||||
{
|
||||
mobj_t *pole;
|
||||
mobj_t *ptr = mo;
|
||||
mobj_t *ptrp = mo;
|
||||
UINT8 i, j;
|
||||
|
||||
P_SetScale(mo, 2*mapobjectscale);
|
||||
mo->destscale = 2*mapobjectscale;
|
||||
|
||||
// setup vars
|
||||
mo->extravalue1 = (INT32)mo->angle;
|
||||
|
||||
// center pole:
|
||||
pole = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK);
|
||||
pole->tics = -1;
|
||||
pole->sprite = SPR_DLZS;
|
||||
pole->frame = 0;
|
||||
P_SetTarget(&pole->target, mo);
|
||||
P_SetTarget(&mo->tracer, pole);
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
pole->eflags |= MFE_VERTICALFLIP;
|
||||
|
||||
// spawn visuals / hitboxes.
|
||||
for (i = 0; i < 2; i++) // for each side...
|
||||
{
|
||||
for (j = 0; j < 2; j++) // spawn the 2 visual papersprites on each side.
|
||||
{
|
||||
// right now we don't care if the objects are positionned properly.
|
||||
|
||||
mobj_t *vis = P_SpawnMobj(mo->x, mo->y, mo->z + 8*mapobjectscale*P_MobjFlip(mo), MT_DLZ_SEASAW_VISUAL);
|
||||
vis->sprite = SPR_DLZS;
|
||||
vis->frame = (j+1)|FF_PAPERSPRITE;
|
||||
vis->tics = -1;
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
vis->eflags |= MFE_VERTICALFLIP;
|
||||
vis->flags2 |= MF2_OBJECTFLIP;
|
||||
}
|
||||
|
||||
P_SetTarget(&vis->target, mo);
|
||||
P_SetTarget(&ptr->hnext, vis); // save in an hnext list for updating later.
|
||||
ptr = vis;
|
||||
}
|
||||
|
||||
for (j = 0; j < 8; j++) // spawn the 8 hitboxes on each side.
|
||||
{
|
||||
// right now we don't care if the objects are positionned properly.
|
||||
|
||||
mobj_t *h = P_SpawnMobj(mo->x, mo->y, mo->z + 8*mapobjectscale*P_MobjFlip(mo), MT_DLZ_SEASAW_HITBOX);
|
||||
h->extravalue1 = i; // keep track of which side we're on.
|
||||
h->tics = -1;
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
h->eflags |= MFE_VERTICALFLIP;
|
||||
h->flags2 |= MF2_OBJECTFLIP;
|
||||
}
|
||||
|
||||
P_SetTarget(&h->target, mo);
|
||||
P_SetTarget(&ptrp->hprev, h); // save in an hprev list for updating later.
|
||||
ptrp = h;
|
||||
}
|
||||
}
|
||||
|
||||
// update after spawning the objects so that they appear in the right spot when the map loads.
|
||||
Obj_DLZSeasawUpdate(mo, false);
|
||||
}
|
||||
|
||||
static void Obj_DLZSeasawReset(mobj_t *mo)
|
||||
{
|
||||
mo->extravalue1 = (INT32)mo->angle;
|
||||
P_SetTarget(&mo->target, NULL);
|
||||
Obj_DLZSeasawUpdate(mo, false);
|
||||
}
|
||||
|
||||
// main seasaw thinker.
|
||||
void Obj_DLZSeasawThink(mobj_t *mo)
|
||||
{
|
||||
boolean ghost = false;
|
||||
SINT8 rot = 1;
|
||||
fixed_t px, py;
|
||||
|
||||
if (mo->target && !P_MobjWasRemoved(mo->target))
|
||||
{
|
||||
mobj_t *t = mo->target;
|
||||
player_t *p = t->player; // our target should always be a player, do NOT porceed if it isn't.
|
||||
|
||||
if (!p) // untarget this instantly.
|
||||
{
|
||||
Obj_DLZSeasawReset(mo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mo->extravalue2)
|
||||
rot = -1;
|
||||
|
||||
// first half of the animation...
|
||||
if (!p->seasawdir)
|
||||
{
|
||||
INT32 angleadd = ANG1*max(4, (mo->movefactor/3)/mapobjectscale) * rot;
|
||||
|
||||
if (p->seasawangleadd > 175)
|
||||
angleadd /= max(1, (p->seasawangleadd - 160)/8);
|
||||
|
||||
mo->extravalue1 += angleadd;
|
||||
p->seasawangle += angleadd;
|
||||
|
||||
p->seasawangleadd += max(4, (mo->movefactor/3)/mapobjectscale);
|
||||
P_SetPlayerAngle(p, (angle_t)(p->seasawangle + ANGLE_90*rot));
|
||||
//t->angle = p->seasawangle + ANGLE_90*rot;
|
||||
|
||||
p->seasawdist++;
|
||||
p->seasawdist = min(p->seasawdist, (160*mapobjectscale)/FRACUNIT);
|
||||
|
||||
if (abs((angleadd)/ANG1 ) < 2) // if we get to 1, invert the rotation!
|
||||
{
|
||||
p->seasawdir = true;
|
||||
p->seasawangleadd = 0; // reset, we're gonna do a full 360!
|
||||
p->seasawmoreangle = p->seasawangleadd - 170;
|
||||
S_StartSound(t, sfx_s3k88);
|
||||
S_StartSound(t, sfx_s3ka2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 angleadd = (mo->cvmem*2 +1)*(-rot);
|
||||
mo->cvmem++;
|
||||
|
||||
p->seasawangleadd += abs(angleadd)/2; // for some reason i need to do this and i'm actually not sure why.
|
||||
mo->extravalue1 += angleadd*ANG1;
|
||||
p->seasawangle += angleadd*ANG1;
|
||||
|
||||
P_SetPlayerAngle(p, (angle_t)(p->seasawangle - ANGLE_90*rot));
|
||||
ghost = true;
|
||||
|
||||
if (p->seasawangleadd >= 340 + p->seasawmoreangle)
|
||||
{
|
||||
// reset everything and send the player zooming
|
||||
Obj_DLZSeasawReset(mo);
|
||||
|
||||
P_SetPlayerAngle(p, mo->angle);
|
||||
P_MoveOrigin(t, t->x, t->y, t->z); // miscall that to set the position properly.
|
||||
P_InstaThrust(t, mo->angle, mo->movefactor*3); // send the player flying at triple the speed they came at us with.
|
||||
S_StartSound(t, sfx_cdfm62);
|
||||
|
||||
p->seasawangleadd = 0;
|
||||
p->seasawangle = 0;
|
||||
p->seasawmoreangle = 0;
|
||||
p->seasaw = false;
|
||||
|
||||
Obj_DLZSeasawUpdate(mo, true);
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
// update the player
|
||||
px = mo->x + p->seasawdist*FINECOSINE((angle_t)p->seasawangle>>ANGLETOFINESHIFT);
|
||||
py = mo->y + p->seasawdist*FINESINE((angle_t)p->seasawangle>>ANGLETOFINESHIFT);
|
||||
|
||||
P_MoveOrigin(t, px, py, mo->z + mapobjectscale*8);
|
||||
}
|
||||
else
|
||||
Obj_DLZSeasawReset(mo);
|
||||
|
||||
// finally, update the visuals.
|
||||
Obj_DLZSeasawUpdate(mo, ghost);
|
||||
}
|
||||
|
||||
// ported just for convenience of not needing to rewrite the code to account for UINT32 angles...
|
||||
// the precision loss hardly matters whatsoever.
|
||||
static INT32 angtoint(angle_t a)
|
||||
{
|
||||
return a/ANG1;
|
||||
}
|
||||
|
||||
// to use in mobjcollide and movemobjcollide just like the lua, woo.
|
||||
// mo is the player's mo, mo2 is the seasaw hitbox.
|
||||
void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2)
|
||||
{
|
||||
player_t *p = mo->player;
|
||||
INT32 momangle;
|
||||
boolean invert = false;
|
||||
|
||||
// cooldown / respawning
|
||||
if (p->seasawcooldown || p->respawn.timer)
|
||||
return;
|
||||
|
||||
// other wacko state that'd do very weird shit if we overwrote it.
|
||||
if (K_isPlayerInSpecialState(p))
|
||||
return;
|
||||
|
||||
// another player is already using the seasar
|
||||
if (mo2->target && !P_MobjWasRemoved(mo2->target) && mo2->target->target && !P_MobjWasRemoved(mo2->target->target))
|
||||
return;
|
||||
|
||||
// height checks
|
||||
if (mo->z + mo->height < mo2->z)
|
||||
return;
|
||||
|
||||
if (mo->z > mo2->z + mo2->height)
|
||||
return;
|
||||
|
||||
// too slow.
|
||||
if (p->speed < K_GetKartSpeed(p, false, false)/3)
|
||||
return;
|
||||
|
||||
|
||||
momangle = angtoint(R_PointToAngle2(0, 0, mo->momx, mo->momy));
|
||||
|
||||
//CONS_Printf("%d / %d -> %d\n", momangle, angtoint(mo2->target->angle), (abs(((momangle - angtoint(mo2->target->angle) +180) % 360) - 180)));
|
||||
|
||||
// this depends on the side we hit the thing from.
|
||||
if (abs(((momangle - angtoint(mo2->target->angle) +180) % 360) - 180) > 60)
|
||||
{
|
||||
mo2->target->angle += ANGLE_180;
|
||||
mo2->target->extravalue1 += ANGLE_180;
|
||||
invert = true;
|
||||
}
|
||||
|
||||
mo2->target->movefactor = p->speed; // keep the speed the player was going at.
|
||||
mo2->target->extravalue2 = mo2->extravalue1; // which side of the pole are we on?
|
||||
|
||||
// if inverted, then invert the value too.
|
||||
if (invert)
|
||||
mo2->target->extravalue2 = (!mo2->target->extravalue2) ? 1 : 0;
|
||||
|
||||
P_SetTarget(&mo2->target->target, mo);
|
||||
mo2->target->cvmem = 0;
|
||||
|
||||
// set player vars now:
|
||||
p->seasawdist = R_PointToDist2(mo->x, mo->y, mo2->target->x, mo2->target->y) /FRACUNIT; // distance from us to the center
|
||||
p->seasawangle = (INT32)R_PointToAngle2(mo2->target->x, mo2->target->y, mo->x, mo->y); // angle from the center to us
|
||||
p->seasawangleadd = 0;
|
||||
p->seasawdir = false;
|
||||
p->seasaw = true;
|
||||
p->pflags |= PF_STASIS;
|
||||
p->seasawcooldown = TICRATE/2;
|
||||
|
||||
S_StartSound(mo, sfx_s3k88);
|
||||
}
|
||||
136
src/objects/eggball.c
Normal file
136
src/objects/eggball.c
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2022 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file eggball.c
|
||||
/// \brief Leaf Storm giant Eggman Balls. And their spawner. Yes, that sounds horribly wrong. No, I'm not changing it.
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../info.h"
|
||||
#include "../k_kart.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../m_random.h"
|
||||
#include "../p_local.h"
|
||||
#include "../r_main.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../g_game.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../k_waypoint.h"
|
||||
#include "../k_respawn.h"
|
||||
#include "../k_collide.h"
|
||||
|
||||
#define BALLMINSPAWNTIME 3
|
||||
#define BALLMAXSPAWNTIME 5
|
||||
|
||||
// spawns balls every BALLMINSPAWNTIME to BALLMAXSPAWNTIME seconds.
|
||||
void Obj_EggBallSpawnerThink(mobj_t *mo)
|
||||
{
|
||||
if (!mo->extravalue1)
|
||||
{
|
||||
mobj_t *ball = P_SpawnMobj(mo->x, mo->y, mo->z, MT_LSZ_EGGBALL);
|
||||
if (P_MobjWasRemoved(ball) == false)
|
||||
{
|
||||
ball->angle = mo->angle;
|
||||
P_SetScale(ball, (ball->destscale = 6*mapobjectscale));
|
||||
}
|
||||
|
||||
mo->extravalue1 = P_RandomRange(PR_TRACKHAZARD, TICRATE*BALLMINSPAWNTIME, TICRATE*BALLMAXSPAWNTIME);
|
||||
}
|
||||
mo->extravalue1--;
|
||||
}
|
||||
|
||||
// ball thinker, it's mostly for particles and some bouncing n stuff to make em fancy.
|
||||
// vars:
|
||||
// threshold -> prevmomz
|
||||
// movedir -> prevz
|
||||
|
||||
void Obj_EggBallThink(mobj_t *mo)
|
||||
{
|
||||
const boolean onground = P_IsObjectOnGround(mo);
|
||||
|
||||
if (mo->eflags & MFE_JUSTHITFLOOR)
|
||||
{
|
||||
if (mo->extravalue1 && P_CheckDeathPitCollide(mo))
|
||||
{
|
||||
P_RemoveMobj(mo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mo->threshold && mo->threshold < -10*mapobjectscale)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
mo->momz = (fixed_t)(-mo->threshold)/8;
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
{
|
||||
angle_t an = ANG1;
|
||||
mobj_t *dust = P_SpawnMobj(mo->x, mo->y, mo->z, MT_DRIFTDUST);
|
||||
P_SetScale(dust, mapobjectscale*3);
|
||||
P_InstaThrust(dust, (360/16)*an*i, mapobjectscale*24); // the angle thing is to avoid a warning due to overflows.
|
||||
dust->momz = P_RandomRange(PR_DECORATION, 0, 7)*mapobjectscale;
|
||||
}
|
||||
|
||||
S_StartSound(mo, sfx_s3k59);
|
||||
|
||||
P_StartQuakeFromMobj(FRACUNIT*20, 6, 512 * mapobjectscale, mo);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!mo->extravalue1)
|
||||
{
|
||||
if (onground)
|
||||
{
|
||||
mo->extravalue1 = 1;
|
||||
mo->cusval = 24*mapobjectscale;
|
||||
mo->movedir = mo->z;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (onground && (mo->extravalue2 & 1))
|
||||
{
|
||||
fixed_t dx = mo->x + P_RandomRange(PR_DECORATION, -96, 96)*mapobjectscale - mo->momx*2;
|
||||
fixed_t dy = mo->y + P_RandomRange(PR_DECORATION, -96, 96)*mapobjectscale - mo->momy*2;
|
||||
fixed_t dz = mo->z;
|
||||
|
||||
mobj_t *dust = P_SpawnMobj(dx, dy, dz, MT_DRIFTDUST);
|
||||
P_SetScale(dust, mapobjectscale*3);
|
||||
dust->momz = P_RandomRange(PR_DECORATION, 0, 7)*mapobjectscale;
|
||||
dust->destscale = mapobjectscale*8;
|
||||
}
|
||||
|
||||
P_InstaThrust(mo, mo->angle, mo->cusval);
|
||||
mo->extravalue2 += 1;
|
||||
mo->frame = mo->extravalue2 % (24 * 2) / 2; // 24 is for frame Y.
|
||||
|
||||
// build up speed
|
||||
if (onground)
|
||||
{
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (mo->z > (fixed_t)mo->movedir)
|
||||
{
|
||||
mo->cusval += max(mapobjectscale/32, abs(mo->z - (fixed_t)mo->movedir)/16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo->z < (fixed_t)mo->movedir)
|
||||
{
|
||||
mo->cusval += max(mapobjectscale/32, abs(mo->z - (fixed_t)mo->movedir)/16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mo->movedir = mo->z;
|
||||
}
|
||||
mo->threshold = mo->momz;
|
||||
}
|
||||
577
src/objects/rideroid.c
Normal file
577
src/objects/rideroid.c
Normal file
|
|
@ -0,0 +1,577 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2022 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file rideroid.c
|
||||
/// \brief Rideroid / Rideroid Node object code. This also has the player behaviour code to be used in k_kart.
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../info.h"
|
||||
#include "../k_kart.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../m_random.h"
|
||||
#include "../p_local.h"
|
||||
#include "../r_main.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../g_game.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../k_waypoint.h"
|
||||
#include "../k_respawn.h"
|
||||
#include "../k_collide.h"
|
||||
#include "../k_color.h"
|
||||
|
||||
#define NODERADIUS 260
|
||||
#define NODEPULLOK 48
|
||||
#define NODEROTSPEED ANG1
|
||||
|
||||
#define RIDEROIDSPEED 80
|
||||
#define RIDEROIDMAXADD 8
|
||||
|
||||
|
||||
// static functions that only really get used here...
|
||||
static void plr_undoRespawn(player_t *p)
|
||||
{
|
||||
p->respawn.state = 0;
|
||||
p->respawn.timer = 0;
|
||||
}
|
||||
|
||||
static void plr_resetRideroidVars(player_t *p)
|
||||
{
|
||||
p->rdnodepull = false;
|
||||
p->rideroid = false;
|
||||
p->rideroidangle = 0;
|
||||
p->rideroidspeed = 0;
|
||||
p->rideroidrollangle = 0;
|
||||
|
||||
p->rdaddmomx = 0;
|
||||
p->rdaddmomy = 0;
|
||||
p->rdaddmomz = 0;
|
||||
|
||||
P_SetTarget(&p->mo->tracer, NULL);
|
||||
}
|
||||
|
||||
// kills the rideroid and removes it from the map.
|
||||
static void Obj_killRideroid(mobj_t *mo)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
mobj_t *t = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK);
|
||||
t->color = SKINCOLOR_TEAL;
|
||||
t->frame = FF_FULLBRIGHT;
|
||||
t->destscale = 1;
|
||||
t->momx = P_RandomRange(PR_EXPLOSION, -32, 32)*mapobjectscale;
|
||||
t->momy = P_RandomRange(PR_EXPLOSION, -32, 32)*mapobjectscale;
|
||||
t->momz = P_RandomRange(PR_EXPLOSION, -32, 32)*mapobjectscale;
|
||||
}
|
||||
P_RemoveMobj(mo);
|
||||
}
|
||||
|
||||
// makes the player get off of the rideroid.
|
||||
void Obj_getPlayerOffRideroid(mobj_t *mo)
|
||||
{
|
||||
mobj_t *pmo = mo->target;
|
||||
|
||||
if (pmo && !P_MobjWasRemoved(pmo))
|
||||
{
|
||||
player_t *p = pmo->player;
|
||||
|
||||
pmo->flags &= ~MF_NOGRAVITY;
|
||||
|
||||
if (p)
|
||||
plr_resetRideroidVars(p);
|
||||
|
||||
mo->fuse = TICRATE/2;
|
||||
mo->momx = mo->momx*2;
|
||||
mo->momy = mo->momy*2;
|
||||
mo->momz = 0;
|
||||
mo->target = NULL;
|
||||
|
||||
S_StartSound(mo, sfx_ridr4);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// this assumes mo->target and mo->target->player is valid.
|
||||
// if it's not, uuuh well too bad.
|
||||
static void Obj_explodeRideroid(mobj_t *mo)
|
||||
{
|
||||
mobj_t *pmo = mo->target;
|
||||
|
||||
Obj_getPlayerOffRideroid(mo);
|
||||
K_SpawnMineExplosion(pmo, pmo->color, 3);
|
||||
S_StartSound(pmo, sfx_s3k4e);
|
||||
Obj_killRideroid(mo);
|
||||
|
||||
// @TODO: quake.
|
||||
|
||||
}
|
||||
|
||||
// used to create a smooth trail.
|
||||
static fixed_t Obj_rideroidLerp(INT32 start, INT32 finish, INT32 percent)
|
||||
{
|
||||
return start + FixedMul(finish-start, FRACUNIT-percent);
|
||||
}
|
||||
|
||||
static void Obj_rideroidTrail(mobj_t *mo)
|
||||
{
|
||||
mobj_t *pmo = mo->target;
|
||||
player_t *p = NULL;
|
||||
|
||||
UINT8 i, j;
|
||||
|
||||
angle_t h_an = mo->angle + ANG1*90;
|
||||
|
||||
if (pmo && !P_MobjWasRemoved(pmo))
|
||||
{
|
||||
p = pmo->player; // used to make some graphics local to save on framerate
|
||||
mo->color = pmo->color;
|
||||
mo->colorized = pmo->colorized;
|
||||
}
|
||||
// from here, we will use the following:
|
||||
// extravalue1: prev x
|
||||
// extravalue2: prev y
|
||||
// cusval: prev z
|
||||
// cvmem: prev roll angle
|
||||
|
||||
for (j = 0; j < 9; j++)
|
||||
{
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
INT32 percent = FRACUNIT * (10-j)/10;
|
||||
angle_t roll = (angle_t)Obj_rideroidLerp((angle_t)mo->cvmem, mo->rollangle, percent);
|
||||
fixed_t x = (fixed_t)Obj_rideroidLerp((fixed_t)mo->extravalue1, mo->x, percent);
|
||||
fixed_t y = (fixed_t)Obj_rideroidLerp((fixed_t)mo->extravalue2, mo->y, percent);
|
||||
fixed_t z = (fixed_t)Obj_rideroidLerp((fixed_t)mo->cusval, mo->z, percent);
|
||||
|
||||
angle_t v_an = i ? (roll+ANG1*90) : (roll-ANG1*90);
|
||||
|
||||
fixed_t pos = FixedMul(mo->scale, FINESINE(v_an>>ANGLETOFINESHIFT)*60);
|
||||
fixed_t tx = x+FixedMul(FINECOSINE(h_an>>ANGLETOFINESHIFT), pos);
|
||||
fixed_t ty = y+FixedMul(FINESINE(h_an>>ANGLETOFINESHIFT), pos);
|
||||
fixed_t tz = z+FixedMul(FINECOSINE(v_an>>ANGLETOFINESHIFT)*60, mo->scale);
|
||||
|
||||
mobj_t *t = P_SpawnMobj(tx, ty, tz, MT_THOK);
|
||||
t->color = SKINCOLOR_TEAL;
|
||||
t->frame = FF_FULLBRIGHT|FF_TRANS50;
|
||||
// 120 is no magic number, the base scale speed is mapobjectscale/12
|
||||
P_SetScale(t, max(1, mapobjectscale*5/6 - ((10-j)*mapobjectscale/120)));
|
||||
t->destscale = 1;
|
||||
|
||||
if (p)
|
||||
{
|
||||
if (j)
|
||||
t->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(p));
|
||||
|
||||
if (p->startboost)
|
||||
t->color = K_RainbowColor(leveltime);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
mo->extravalue1 = (INT32)mo->x;
|
||||
mo->extravalue2 = (INT32)mo->y;
|
||||
mo->cusval = (INT32)mo->z;
|
||||
mo->cvmem = (INT32)mo->rollangle;
|
||||
}
|
||||
|
||||
|
||||
static void Obj_updateRideroidPos(mobj_t *mo)
|
||||
{
|
||||
mobj_t *pmo = mo->target;
|
||||
|
||||
fixed_t x = pmo->x + 2*FINECOSINE(pmo->angle>>ANGLETOFINESHIFT);
|
||||
fixed_t y = pmo->y + 2*FINESINE(pmo->angle>>ANGLETOFINESHIFT);
|
||||
|
||||
P_MoveOrigin(mo, x, y, pmo->z - 10*mapobjectscale);
|
||||
mo->momx = pmo->momx;
|
||||
mo->momy = pmo->momy;
|
||||
mo->momz = pmo->momz;
|
||||
|
||||
Obj_rideroidTrail(mo);
|
||||
}
|
||||
|
||||
// handles the rideroid and the player attached to it.
|
||||
void Obj_RideroidThink(mobj_t *mo)
|
||||
{
|
||||
player_t *p;
|
||||
mobj_t *pmo = mo->target;
|
||||
|
||||
fixed_t basemomx;
|
||||
fixed_t basemomy;
|
||||
fixed_t xthreshold;
|
||||
fixed_t ythreshold;
|
||||
|
||||
|
||||
// speed values...
|
||||
fixed_t maxspd = RIDEROIDSPEED*mapobjectscale;
|
||||
|
||||
if (!pmo || P_MobjWasRemoved(pmo))
|
||||
{
|
||||
if (!mo->fuse)
|
||||
{
|
||||
mo->fuse = TICRATE/2;
|
||||
}
|
||||
else if (mo->fuse == 1)
|
||||
{
|
||||
Obj_killRideroid(mo);
|
||||
}
|
||||
else
|
||||
{
|
||||
Obj_rideroidTrail(mo);
|
||||
mo->rollangle += ANG1*24;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// if we're here, our player should still exist which is kinda crazy!
|
||||
p = pmo->player;
|
||||
|
||||
// pulling towards the node, AKA towards where the rideroid is, which just so happens to be us right now.
|
||||
if (p->rdnodepull)
|
||||
{
|
||||
pmo->momx = (mo->x - pmo->x)/6;
|
||||
pmo->momy = (mo->y - pmo->y)/6;
|
||||
pmo->momz = (mo->z - pmo->z)/6;
|
||||
|
||||
//CONS_Printf("%d\n", R_PointToDist2(mo->x, mo->y, pmo->x, pmo->y)/FRACUNIT);
|
||||
|
||||
if (R_PointToDist2(mo->x, mo->y, pmo->x, pmo->y) < NODEPULLOK*mapobjectscale)
|
||||
{
|
||||
p->rideroid = true;
|
||||
p->rdnodepull = false;
|
||||
|
||||
S_StartSound(pmo, sfx_ridr2);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if we're here, we made it to the rideroid and we can use it, or something like that!
|
||||
|
||||
P_SetTarget(&p->mo->tracer, mo); // keep a reference of the rideroid in the player for convenience.
|
||||
|
||||
// calculate the maximum speed we can move at.
|
||||
// the values are a little arbitrary but they work for how little use these have.
|
||||
|
||||
if (p->ringboost)
|
||||
maxspd = (maxspd*12)/10; // Ring Boost: 120% max speed.
|
||||
|
||||
if (p->draftpower)
|
||||
{
|
||||
UINT8 draftperc = (p->draftpower*100 / FRACUNIT); // 0-100%
|
||||
maxspd += (draftperc/5) / 100;
|
||||
}
|
||||
|
||||
if (p->startboost)
|
||||
maxspd = (maxspd*15)/10; // 150% speed
|
||||
|
||||
// increase speed as we go unless we're turning harshly.
|
||||
if (p->rideroidspeed*mapobjectscale < maxspd)
|
||||
{
|
||||
if (abs(p->cmd.turning < 400))
|
||||
p->rideroidspeed += (p->ringboost ? 2 : 1); // acceleration is also higher with a ring boost.
|
||||
}
|
||||
else
|
||||
p->rideroidspeed -= 1;
|
||||
|
||||
|
||||
// sounds
|
||||
|
||||
mo->movecount++; // we use this as a timer for sounds and whatnot.
|
||||
|
||||
if (mo->movecount == 1 || !(mo->movecount%TICRATE))
|
||||
S_StartSound(mo, sfx_ridr3);
|
||||
|
||||
|
||||
// aaaaand the actual gameplay and shit... wooooo
|
||||
pmo->angle = mo->angle;
|
||||
pmo->flags |= MF_NOGRAVITY;
|
||||
|
||||
// do not let the player touch the ground
|
||||
// @TODO: check all 4 corners of the player and use P_GetZAt to account for slopes if pmo->standslope isn't NULL.
|
||||
// right now it's not important as LV doesn't mix rdr and slopes but if somehow i manage to pull through w this shit it'll need to be done
|
||||
if (pmo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
fixed_t minz = pmo->ceilingz - 2*mapobjectscale;
|
||||
if (pmo->z > minz)
|
||||
pmo->z = minz;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t minz = pmo->floorz + 2*mapobjectscale;
|
||||
if (pmo->z < minz)
|
||||
pmo->z = minz;
|
||||
}
|
||||
|
||||
|
||||
// if we hit a wall or get hit, get off of the rideroid.
|
||||
if (pmo->eflags & MFE_JUSTBOUNCEDWALL || P_PlayerInPain(p))
|
||||
{
|
||||
Obj_explodeRideroid(mo);
|
||||
return;
|
||||
}
|
||||
|
||||
// now actual movement:
|
||||
|
||||
// first, do the movement for this frame
|
||||
P_InstaThrust(pmo, (angle_t)p->rideroidangle, p->rideroidspeed*mapobjectscale);
|
||||
basemomx = p->mo->momx;
|
||||
basemomy = p->mo->momy;
|
||||
|
||||
pmo->momx += p->rdaddmomx;
|
||||
pmo->momy += p->rdaddmomy;
|
||||
pmo->momz += p->rdaddmomz;
|
||||
pmo->angle = (angle_t)p->rideroidangle;
|
||||
p->drawangle = (angle_t)p->rideroidangle;
|
||||
P_SetPlayerAngle(pmo->player, (angle_t)p->rideroidangle);
|
||||
pmo->rollangle = p->rideroidrollangle;
|
||||
mo->rollangle = p->rideroidrollangle;
|
||||
pmo->pitch = 0;
|
||||
|
||||
// update the rideroid object (me) to be below the target player
|
||||
Obj_updateRideroidPos(mo);
|
||||
|
||||
// turning left/right
|
||||
if (p->cmd.turning)
|
||||
{
|
||||
fixed_t savemomx = pmo->momx;
|
||||
fixed_t savemomy = pmo->momy;
|
||||
SINT8 dir = 0;
|
||||
INT32 a;
|
||||
|
||||
if (p->cmd.turning < -400)
|
||||
{
|
||||
a = (INT32)(mo->angle) - ANG1*90;
|
||||
P_Thrust(pmo, mo->angle - ANGLE_90, 2*mapobjectscale);
|
||||
p->rideroidrollangle -= ANG1*3;
|
||||
|
||||
if (p->rideroidrollangle < -ANG1*25)
|
||||
p->rideroidrollangle = -ANG1*25;
|
||||
|
||||
dir = 1;
|
||||
|
||||
}
|
||||
else if (p->cmd.turning > 400)
|
||||
{
|
||||
a = (INT32)(mo->angle) + ANG1*90;
|
||||
P_Thrust(pmo, mo->angle + ANGLE_90, 2*mapobjectscale);
|
||||
p->rideroidrollangle += ANG1*3;
|
||||
|
||||
if (p->rideroidrollangle > ANG1*25)
|
||||
p->rideroidrollangle = ANG1*25;
|
||||
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
if (dir != 0 && leveltime & 1 && p->rideroidspeed > RIDEROIDSPEED/2)
|
||||
{
|
||||
p->rideroidspeed -= 1;
|
||||
}
|
||||
|
||||
if (dir != 0)
|
||||
{
|
||||
|
||||
// save the added momentum
|
||||
p->rdaddmomx = pmo->momx - basemomx;
|
||||
p->rdaddmomy = pmo->momy - basemomy;
|
||||
|
||||
//CONS_Printf("AX1: %d, AY1: %d\n", p->rdaddmomx/mapobjectscale, p->rdaddmomy/mapobjectscale);
|
||||
|
||||
pmo->momx = basemomx;
|
||||
pmo->momy = basemomy;
|
||||
|
||||
/*CONS_Printf("CURR: %d, %d\n", pmo->momx/mapobjectscale, pmo->momy/mapobjectscale);
|
||||
CONS_Printf("BASE: %d, %d\n", basemomx/mapobjectscale, basemomy/mapobjectscale);
|
||||
CONS_Printf("ADD: %d, %d\n", p->rdaddmomx/mapobjectscale, p->rdaddmomy/mapobjectscale);*/
|
||||
|
||||
// find out how much addmomx and addmomy we can actually get.
|
||||
// we do this by misusing P_Thrust to calc our values then immediately cancelling it.
|
||||
basemomx = pmo->momx;
|
||||
basemomy = pmo->momy;
|
||||
|
||||
a = (INT32)(mo->angle) - dir*ANG1*90;
|
||||
P_Thrust(pmo, (angle_t)a, RIDEROIDMAXADD*3*mapobjectscale);
|
||||
|
||||
xthreshold = pmo->momx - basemomx;
|
||||
ythreshold = pmo->momy - basemomy;
|
||||
|
||||
//CONS_Printf("XT: %d (%d), YT: %d (%d)\n", xthreshold/mapobjectscale, abs(xthreshold/mapobjectscale), ythreshold/mapobjectscale, abs(ythreshold/mapobjectscale));
|
||||
|
||||
// clamp the momentums using the calculated thresholds.
|
||||
|
||||
// the fixedmul check checks if both numbers are of the same sign.
|
||||
if (abs(p->rdaddmomx) > abs(xthreshold))
|
||||
p->rdaddmomx = xthreshold;
|
||||
|
||||
if (abs(p->rdaddmomy) > abs(ythreshold))
|
||||
p->rdaddmomy = ythreshold;
|
||||
|
||||
//CONS_Printf("AX2: %d, AY2: %d\n", p->rdaddmomx/mapobjectscale, p->rdaddmomy/mapobjectscale);
|
||||
|
||||
// now cancel it.
|
||||
pmo->momx = savemomx;
|
||||
pmo->momy = savemomy;
|
||||
//CONS_Printf("NEWCURR: %d, %d\n", pmo->momx/mapobjectscale, pmo->momy/mapobjectscale);
|
||||
}
|
||||
}
|
||||
else // not turning
|
||||
{
|
||||
// for some reason doing *= 9/10 causes it to get set to 0 instantly? so it's done like this.
|
||||
p->rdaddmomx = (p->rdaddmomx*9)/10;
|
||||
p->rdaddmomy = (p->rdaddmomy*9)/10;
|
||||
p->rideroidrollangle /= 2;
|
||||
}
|
||||
|
||||
// and now, going up/down
|
||||
|
||||
if (p->cmd.throwdir > 0)
|
||||
{
|
||||
// if we were going the opposite direction, this helps us change our height very easily.
|
||||
if (p->rdaddmomz < 0)
|
||||
p->rdaddmomz /= 2;
|
||||
|
||||
p->rdaddmomz = min(RIDEROIDMAXADD*mapobjectscale/7, p->rdaddmomz + mapobjectscale/16);
|
||||
|
||||
if (p->rideroidspeed > RIDEROIDSPEED/2
|
||||
&& abs(p->cmd.turning) > 400
|
||||
&& leveltime & 1)
|
||||
p->rideroidspeed -= 1;
|
||||
|
||||
}
|
||||
else if (p->cmd.throwdir < 0)
|
||||
{
|
||||
// if we were going the opposite direction, this helps us change our height very easily.
|
||||
if (p->rdaddmomz > 0)
|
||||
p->rdaddmomz /= 2;
|
||||
|
||||
p->rdaddmomz = max(-RIDEROIDMAXADD*mapobjectscale/7, p->rdaddmomz - mapobjectscale/16);
|
||||
|
||||
if (p->rideroidspeed > RIDEROIDSPEED/2
|
||||
&& abs(p->cmd.turning) > 400
|
||||
&& leveltime & 1)
|
||||
p->rideroidspeed -= 1;
|
||||
}
|
||||
else
|
||||
p->rdaddmomz = (p->rdaddmomz*6)/10;
|
||||
|
||||
}
|
||||
|
||||
// transposed lua code.
|
||||
// the lua used to continuously P_SpawnMobj the letters which was fine for the intended use case in the original LV iteration.
|
||||
// however the LV remake spams a lot of these rideroid nodes close to each other which created a huge overhead whether or not they were being displayed.
|
||||
// so now it's more optimized and only spawns things once.
|
||||
|
||||
void Obj_RideroidNodeSpawn(mobj_t *mo)
|
||||
{
|
||||
|
||||
fixed_t radius = NODERADIUS*mapobjectscale; // radius for the text to rotate at.
|
||||
mobj_t *ptr = mo;
|
||||
UINT8 i;
|
||||
UINT8 j;
|
||||
|
||||
|
||||
// make it bigger.
|
||||
P_SetScale(mo, mo->scale*3);
|
||||
|
||||
// spawn the letter things.
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
|
||||
angle_t ang = mo->angle + (i)*180;
|
||||
fixed_t zpos = mo->z + 64*mapobjectscale + mapobjectscale*96*i;
|
||||
|
||||
ang *= ANG1; // this has to be done here or the warning prevents the compile, we don't care about overflowing here.
|
||||
|
||||
for (j = 0; j < 7; j++)
|
||||
{
|
||||
fixed_t xpos = mo->x + FixedMul(radius, FINECOSINE(ang>>ANGLETOFINESHIFT));
|
||||
fixed_t ypos = mo->y + FixedMul(radius, FINESINE(ang>>ANGLETOFINESHIFT));
|
||||
|
||||
mobj_t *let = P_SpawnMobj(xpos, ypos, zpos, MT_THOK);
|
||||
let->sprite = SPR_RDRL;
|
||||
let->frame = j|FF_FULLBRIGHT|FF_PAPERSPRITE;
|
||||
let->fuse = -1;
|
||||
let->tics = -1;
|
||||
let->angle = ang + ANG1*90;
|
||||
let->scale = 2*mapobjectscale;
|
||||
|
||||
// set letter in previous thing's hnext, this will let us loop em easily in the looping thinker.
|
||||
P_SetTarget(&ptr->hnext, let);
|
||||
|
||||
// set the ptr to the last letter spawned.
|
||||
ptr = let;
|
||||
|
||||
ang += ANG1*8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Obj_RideroidNodeThink(mobj_t *mo)
|
||||
{
|
||||
fixed_t radius = NODERADIUS*mapobjectscale; // radius for the text to rotate at.
|
||||
mobj_t *ptr = mo->hnext;
|
||||
mobj_t *pmo;
|
||||
UINT8 i;
|
||||
|
||||
mo->angle -= NODEROTSPEED; // continuously rotate.
|
||||
|
||||
while (ptr && !P_MobjWasRemoved(ptr))
|
||||
{
|
||||
// get the new position, move us here, and move on to the next object in line.
|
||||
angle_t newang = ptr->angle - NODEROTSPEED;
|
||||
fixed_t newxpos = mo->x + FixedMul(radius, FINECOSINE((newang - ANG1*90)>>ANGLETOFINESHIFT));
|
||||
fixed_t newypos = mo->y + FixedMul(radius, FINESINE((newang - ANG1*90)>>ANGLETOFINESHIFT));
|
||||
|
||||
P_MoveOrigin(ptr, newxpos, newypos, ptr->z);
|
||||
ptr->angle = newang;
|
||||
|
||||
ptr = ptr->hnext;
|
||||
}
|
||||
|
||||
// check for players coming near us.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator || players[i].rideroid ||
|
||||
players[i].rdnodepull || K_isPlayerInSpecialState(&players[i]) || P_PlayerInPain(&players[i]))
|
||||
continue;
|
||||
|
||||
pmo = players[i].mo;
|
||||
//CONS_Printf("rd: %d\n", players[i].rideroid);
|
||||
|
||||
if (R_PointToDist2(mo->x, mo->y, pmo->x, pmo->y) < NODERADIUS*mapobjectscale
|
||||
&& pmo->z + pmo->height >= mo->z
|
||||
&& pmo->z <= mo->z + 512*mapobjectscale)
|
||||
{
|
||||
|
||||
mobj_t *rd;
|
||||
|
||||
plr_undoRespawn(&players[i]);
|
||||
plr_resetRideroidVars(&players[i]);
|
||||
|
||||
players[i].rdnodepull = true;
|
||||
players[i].rideroidangle = mo->spawnpoint->angle*ANG1; // reminder that mo->angle changes, so we use the spawnpoint angle.
|
||||
players[i].rideroidspeed = RIDEROIDSPEED;
|
||||
|
||||
P_SetTarget(&pmo->tracer, mo);
|
||||
|
||||
// spawn the rideroid.
|
||||
rd = P_SpawnMobj(mo->x, mo->y, mo->z, MT_RIDEROID);
|
||||
rd->angle = players[i].rideroidangle;
|
||||
P_SetTarget(&rd->target, pmo);
|
||||
|
||||
S_StartSound(rd, sfx_ridr1);
|
||||
|
||||
//CONS_Printf("rd pull\n");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
104
src/objects/wpzothers.c
Normal file
104
src/objects/wpzothers.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2022 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file wpzturbine.c
|
||||
/// \brief Water Palace Zone turbines and associated bubble object. Yep, this is going to suck.
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../info.h"
|
||||
#include "../k_kart.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../m_random.h"
|
||||
#include "../p_local.h"
|
||||
#include "../r_main.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../g_game.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../k_waypoint.h"
|
||||
#include "../k_respawn.h"
|
||||
#include "../k_collide.h"
|
||||
|
||||
// foutains
|
||||
void Obj_WPZFountainThink(mobj_t *mo)
|
||||
{
|
||||
if (mo->state == &states[S_WPZFOUNTAIN]
|
||||
&& !(mo->eflags & MFE_UNDERWATER))
|
||||
P_SetMobjState(mo, S_WPZFOUNTAINANIM);
|
||||
|
||||
else if (mo->state == &states[S_WPZFOUNTAINANIM]
|
||||
&& mo->eflags & MFE_UNDERWATER)
|
||||
P_SetMobjState(mo, S_WPZFOUNTAIN);
|
||||
}
|
||||
|
||||
// kuragens
|
||||
void Obj_WPZKuragenThink(mobj_t *mo)
|
||||
{
|
||||
//(void)mo;
|
||||
boolean active = false;
|
||||
|
||||
// .....and i need to do this... because?
|
||||
if (!mo->cusval)
|
||||
{
|
||||
P_SetScale(mo, mapobjectscale*2);
|
||||
mo->destscale = mapobjectscale*2;
|
||||
mo->cusval = 1;
|
||||
}
|
||||
|
||||
if (!(mo->spawnpoint->options & 1 || mo->spawnpoint->thing_args[0])) // extra flag skips player checks, making it a decoration.
|
||||
{
|
||||
UINT8 i;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *p;
|
||||
mobj_t *pmo;
|
||||
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
|
||||
p = &players[i];
|
||||
pmo = p->mo;
|
||||
|
||||
if (R_PointToDist2(pmo->x, pmo->y, mo->x, mo->y) < mapobjectscale*6144)
|
||||
{
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (active && mo->extravalue1)
|
||||
{
|
||||
mo->extravalue1--;
|
||||
|
||||
if (!mo->extravalue1)
|
||||
{
|
||||
mobj_t *b = P_SpawnMobj(mo->x, mo->y, mo->z, MT_KURAGENBOMB);
|
||||
b->flags2 = mo->flags2 & MF2_OBJECTFLIP;
|
||||
P_SetScale(b, mapobjectscale*2);
|
||||
b->destscale = mapobjectscale*2;
|
||||
mo->extravalue1 = TICRATE*5;
|
||||
}
|
||||
}
|
||||
else
|
||||
mo->extravalue1 = TICRATE*5/2;
|
||||
}
|
||||
|
||||
// kuragen bomb
|
||||
void Obj_WPZKuragenBombThink(mobj_t *mo)
|
||||
{
|
||||
if (P_IsObjectOnGround(mo))
|
||||
{
|
||||
P_SetScale(mo, mapobjectscale/2);
|
||||
P_RadiusAttack(mo, mo, FRACUNIT*192, DMG_EXPLODE, false);
|
||||
A_MineExplode(mo);
|
||||
|
||||
P_RemoveMobj(mo);
|
||||
}
|
||||
}
|
||||
388
src/objects/wpzturbine.c
Normal file
388
src/objects/wpzturbine.c
Normal file
|
|
@ -0,0 +1,388 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2022 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file wpzturbine.c
|
||||
/// \brief Water Palace Zone turbines and associated bubble object. Yep, this is going to suck.
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../info.h"
|
||||
#include "../k_kart.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../m_random.h"
|
||||
#include "../p_local.h"
|
||||
#include "../r_main.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../g_game.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../k_waypoint.h"
|
||||
#include "../k_respawn.h"
|
||||
#include "../k_collide.h"
|
||||
|
||||
// distance to spawn the fan from the center:
|
||||
#define TURBINE_RADIUS 128
|
||||
|
||||
// default distance at which players activate the turbine:
|
||||
#define TURBINE_RANGE (2048*FRACUNIT)
|
||||
|
||||
// default distance at which players spin away from the turbine
|
||||
#define TURBINE_SPIN 1536
|
||||
|
||||
// spawns the hnext visual list for the turbine.
|
||||
// whether we use it or not will depend on its flags.
|
||||
void Obj_WPZTurbineSpawn(mobj_t *mo)
|
||||
{
|
||||
mobj_t *ptr = mo;
|
||||
UINT8 i;
|
||||
|
||||
// spawn the visuals regardless of flags, make em invisible.
|
||||
// we'll care about updating em if it's worth doing later.
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
mobj_t *vis = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK);
|
||||
P_SetMobjState(vis, S_INVISIBLE);
|
||||
vis->tics = 4; // if we don't use it just despawn it later.
|
||||
|
||||
P_SetTarget(&ptr->hnext, vis);
|
||||
ptr = vis;
|
||||
}
|
||||
}
|
||||
|
||||
// visually update the turbine's hnext visuals if need be.
|
||||
static void Obj_WPZTurbineUpdate(mobj_t *mo)
|
||||
{
|
||||
angle_t ang = (angle_t)mo->extravalue1;
|
||||
mapthing_t *mt = mo->spawnpoint;
|
||||
|
||||
if (!mt)
|
||||
return;
|
||||
|
||||
// fans
|
||||
if (!mt->thing_args[1])
|
||||
{
|
||||
UINT8 i;
|
||||
mobj_t *ptr = mo;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
|
||||
fixed_t x = mo->x + FixedMul(mapobjectscale, TURBINE_RADIUS*FINECOSINE(ang>>ANGLETOFINESHIFT));
|
||||
fixed_t y = mo->y + FixedMul(mapobjectscale, TURBINE_RADIUS*FINESINE(ang>>ANGLETOFINESHIFT));
|
||||
|
||||
// get the mobj
|
||||
if (ptr && !P_MobjWasRemoved(ptr) && ptr->hnext && !P_MobjWasRemoved(ptr->hnext))
|
||||
{
|
||||
ptr = ptr->hnext;
|
||||
P_MoveOrigin(ptr, x, y, mo->z);
|
||||
ptr->tics = 4;
|
||||
ptr->sprite = SPR_WPWL;
|
||||
ptr->frame = 1|FF_PAPERSPRITE;
|
||||
P_SetScale(ptr, mapobjectscale*4);
|
||||
ptr->destscale = mapobjectscale*4;
|
||||
ptr->angle = ang;
|
||||
}
|
||||
|
||||
ang += (360/8)*ANG1;
|
||||
}
|
||||
}
|
||||
|
||||
// bubbles if we're underwater
|
||||
if (mo->z < mo->watertop && leveltime%10 == 0)
|
||||
{
|
||||
|
||||
INT32 dradius = TURBINE_SPIN;
|
||||
INT32 bubbleradius;
|
||||
angle_t bubbleang;
|
||||
fixed_t bx, by, bz;
|
||||
mobj_t *bubble;
|
||||
|
||||
if (mt->thing_args[7])
|
||||
dradius = mt->thing_args[7];
|
||||
|
||||
bubbleradius = P_RandomRange(PR_BUBBLE, dradius/4, (dradius*3)/2);
|
||||
bubbleang = P_RandomRange(PR_BUBBLE, 0, 359)*ANG1;
|
||||
|
||||
bx = mo->x + FixedMul(mapobjectscale, bubbleradius*FINECOSINE(bubbleang>>ANGLETOFINESHIFT));
|
||||
by = mo->y + FixedMul(mapobjectscale, bubbleradius*FINECOSINE(bubbleang>>ANGLETOFINESHIFT));
|
||||
bz = R_PointInSubsector(bx, by)->sector->floorheight;
|
||||
|
||||
bubble = P_SpawnMobj(bx, by, bz, MT_WATERPALACEBUBBLE);
|
||||
bubble->fuse = TICRATE*10;
|
||||
bubble->angle = bubbleang;
|
||||
bubble->movecount = bubbleradius;
|
||||
P_SetTarget(&bubble->tracer, mo);
|
||||
}
|
||||
}
|
||||
|
||||
void Obj_WPZTurbineThinker(mobj_t *mo)
|
||||
{
|
||||
|
||||
UINT8 i;
|
||||
mapthing_t *mt = mo->spawnpoint;
|
||||
boolean opt1 = mt->thing_args[0] != 0;
|
||||
fixed_t baseheight = (mt->thing_args[2]) ? (mt->thing_args[2]*FRACUNIT) : (mo->z+mapobjectscale*1024);
|
||||
fixed_t sneakerheight = (mt->thing_args[3]) ? (mt->thing_args[3]*FRACUNIT) : (mo->z+mapobjectscale*1768);
|
||||
fixed_t range = (mt->thing_args[7]) ? (mt->thing_args[7]*FRACUNIT) : (FixedMul(mapobjectscale, TURBINE_RANGE));
|
||||
INT32 rotspeed = (mt->thing_args[5]) ? (mt->thing_args[5]*ANG1/10) : (ANG1*3); // not angle_t for negatives.
|
||||
tic_t turbinetime = (mt->thing_args[4]) ? (mt->thing_args[4]) : (TICRATE*3);
|
||||
SINT8 mult = (opt1) ? (-1) : (1);
|
||||
|
||||
mo->extravalue1 += rotspeed*mult;
|
||||
|
||||
// find players in range and take their phones.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *p;
|
||||
mobj_t *pmo;
|
||||
|
||||
if (!playeringame[i] || players[i].spectator || K_isPlayerInSpecialState(&players[i]))
|
||||
continue;
|
||||
|
||||
p = &players[i];
|
||||
pmo = p->mo;
|
||||
|
||||
if (R_PointToDist2(pmo->x, pmo->y, mo->x, mo->y) < range
|
||||
&& !p->turbine
|
||||
&& !p->respawn.timer)
|
||||
{
|
||||
P_SetTarget(&pmo->tracer, mo);
|
||||
p->turbine = turbinetime;
|
||||
|
||||
// to be fully honest i dont rememebr what i was on while writing this
|
||||
// but it originally went by mo instead of pmo for angle??? how did it ever *work* ?
|
||||
p->turbineangle = ANGLE_180 + R_PointToAngle2(0, 0, mo->momx, mo->momy);
|
||||
if (!p->speed)
|
||||
p->turbineangle = ANGLE_180 + mo->angle;
|
||||
|
||||
p->turbineangle += ANG1*45*mult;
|
||||
|
||||
p->turbineheight = baseheight;
|
||||
p->turbinespd = false;
|
||||
|
||||
if (FixedDiv(p->speed, K_GetKartSpeed(p, false, false)) > FRACUNIT*2 // 200% speed
|
||||
&& baseheight != sneakerheight)
|
||||
{
|
||||
p->turbineheight = sneakerheight;
|
||||
p->turbinespd = true;
|
||||
}
|
||||
|
||||
pmo->flags |= MF_NOCLIP;
|
||||
}
|
||||
}
|
||||
Obj_WPZTurbineUpdate(mo);
|
||||
}
|
||||
|
||||
// ported from my lua for convenience of not having to rewrite half the shit code.
|
||||
static INT32 angtoint(angle_t a)
|
||||
{
|
||||
return a/ANG1;
|
||||
}
|
||||
|
||||
// controls player while using a turbine.
|
||||
// i do not remember what i smoked before writing the lua version of this code.
|
||||
// it's a fucking mess what the fuck does half of this even DO
|
||||
void Obj_playerWPZTurbine(player_t *p)
|
||||
{
|
||||
mobj_t *pmo = p->mo;
|
||||
mobj_t *t = pmo->tracer;
|
||||
mapthing_t *mt;
|
||||
boolean opt1;
|
||||
fixed_t dist = FixedMul(mapobjectscale, TURBINE_SPIN)*FRACUNIT;
|
||||
INT32 speed = ANG1*3;
|
||||
boolean mode = false;
|
||||
boolean distreached;
|
||||
|
||||
fixed_t tx, ty, tz;
|
||||
fixed_t momz;
|
||||
|
||||
|
||||
if (!t || P_MobjWasRemoved(t))
|
||||
{
|
||||
p->turbine = false;
|
||||
P_SetTarget(&pmo->tracer, NULL);
|
||||
return; // wtf happened
|
||||
}
|
||||
|
||||
mt = t->spawnpoint;
|
||||
|
||||
opt1 = (mt->thing_args[0] != 0);
|
||||
|
||||
if (mt->thing_args[6])
|
||||
dist = mt->thing_args[6]*FRACUNIT;
|
||||
|
||||
if (mt->thing_args[5])
|
||||
speed = mt->thing_args[5]*ANG1/10;
|
||||
|
||||
if (mt->thing_args[9])
|
||||
mode = true;
|
||||
|
||||
distreached = R_PointToDist2(t->x, t->y, pmo->x, pmo->y) <= dist+32*mapobjectscale;
|
||||
|
||||
if (mode && !distreached)
|
||||
p->turbineangle = (INT32)R_PointToAngle2(t->x, t->y, pmo->x, pmo->y);
|
||||
|
||||
p->spinouttimer = TICRATE;
|
||||
pmo->pitch = 0;
|
||||
|
||||
// determine target x/y/z
|
||||
tx = t->x + (dist/FRACUNIT)*FINECOSINE((angle_t)(p->turbineangle)>>ANGLETOFINESHIFT);
|
||||
ty = t->y + (dist/FRACUNIT)*FINESINE((angle_t)(p->turbineangle)>>ANGLETOFINESHIFT);
|
||||
tz = p->turbineheight;
|
||||
|
||||
//CONS_Printf("%d %d\n", tx/FRACUNIT, ty/FRACUNIT);
|
||||
|
||||
if (mode)
|
||||
{
|
||||
if (distreached)
|
||||
{
|
||||
P_MoveOrigin(pmo, tx, ty, pmo->z);
|
||||
}
|
||||
else
|
||||
{
|
||||
pmo->momx = FixedMul(FINECOSINE((angle_t)(p->turbineangle)>>ANGLETOFINESHIFT), -(max(p->speed, mapobjectscale*32)));
|
||||
pmo->momy = FixedMul(FINESINE((angle_t)(p->turbineangle)>>ANGLETOFINESHIFT), -(max(p->speed, mapobjectscale*32)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pmo->momx = (tx - pmo->x)/24 * (p->turbinespd ? 2 : 1);
|
||||
pmo->momy = (ty - pmo->y)/24 * (p->turbinespd ? 2 : 1);
|
||||
}
|
||||
|
||||
momz = (tz - pmo->z)/128 * (p->turbinespd+1);
|
||||
|
||||
if (mt->thing_args[8])
|
||||
{
|
||||
momz = (mt->thing_args[8]*FRACUNIT) * ((tz < pmo->z) ? -1 : 1);
|
||||
|
||||
if (momz < 0)
|
||||
{
|
||||
if (pmo->z + momz < tz)
|
||||
{
|
||||
momz = pmo->z - tz;
|
||||
}
|
||||
}
|
||||
else if (momz > 0)
|
||||
{
|
||||
if (pmo->z + momz > tz)
|
||||
{
|
||||
momz = tz - pmo->z;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pmo->momz = momz;
|
||||
p->turbineangle += (speed * (p->turbinespd ? 2 : 1)) * (opt1 ? -1 : 1);
|
||||
P_SetPlayerAngle(p, (angle_t)p->turbineangle + ANGLE_90*(opt1 ? -1 : 1));
|
||||
|
||||
if (pmo->eflags & MFE_UNDERWATER)
|
||||
{
|
||||
fixed_t rx = pmo->x + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale;
|
||||
fixed_t ry = pmo->y + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale;
|
||||
fixed_t rz = pmo->z + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale;
|
||||
|
||||
mobj_t *bubl = P_SpawnMobj(rx, ry, rz, MT_THOK);
|
||||
P_SetScale(bubl, pmo->scale*2);
|
||||
bubl->scalespeed = pmo->scale/12;
|
||||
bubl->destscale = 1;
|
||||
bubl->sprite = SPR_BUBL;
|
||||
bubl->frame = 0;
|
||||
bubl->tics = TICRATE;
|
||||
}
|
||||
|
||||
|
||||
if (pmo->momz < mapobjectscale*6)
|
||||
{
|
||||
INT32 myang = angtoint(pmo->angle);
|
||||
angle_t exitangle = t->angle;
|
||||
INT32 targetangle = angtoint(exitangle);
|
||||
INT32 launchangle = myang-targetangle;
|
||||
|
||||
// WHAT WAS I SMOKING
|
||||
if ( (opt1 && launchangle > -60 && launchangle < -45)
|
||||
|| (!opt1 && launchangle > 45 && launchangle < 60))
|
||||
{
|
||||
|
||||
P_SetPlayerAngle(p, targetangle*ANG1);
|
||||
|
||||
if (mode)
|
||||
P_InstaThrust(pmo, targetangle*ANG1, 128*mapobjectscale);
|
||||
else
|
||||
{
|
||||
fixed_t spd = FixedHypot(pmo->momx, pmo->momy);
|
||||
P_InstaThrust(pmo, targetangle*ANG1, spd);
|
||||
}
|
||||
|
||||
P_SetTarget(&pmo->tracer, NULL);
|
||||
p->turbineheight = 0;
|
||||
p->turbineangle = 0;
|
||||
|
||||
if (p->turbinespd)
|
||||
pmo->momz = mapobjectscale*5 * (pmo->eflags & MFE_UNDERWATER ? 2 : 1);
|
||||
|
||||
if (pmo->eflags & MFE_UNDERWATER)
|
||||
{
|
||||
pmo->momz = mapobjectscale*5;
|
||||
pmo->momx = (pmo->momx*17)/10;
|
||||
pmo->momy = (pmo->momy*17)/10;
|
||||
}
|
||||
|
||||
p->spinouttimer = 0;
|
||||
pmo->flags &= ~MF_NOCLIP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bubbles that circle the turbine
|
||||
void Obj_WPZBubbleThink(mobj_t *mo)
|
||||
{
|
||||
angle_t ang = mo->angle - ANGLE_90;
|
||||
mobj_t *t = mo->tracer;
|
||||
fixed_t tx, ty;
|
||||
mapthing_t *mt;
|
||||
|
||||
// where
|
||||
// where did it go
|
||||
if (!t || P_MobjWasRemoved(t))
|
||||
{
|
||||
P_RemoveMobj(mo);
|
||||
return;
|
||||
}
|
||||
|
||||
mt = t->spawnpoint;
|
||||
if (!mt)
|
||||
return;
|
||||
|
||||
mo->momz = mapobjectscale*16;
|
||||
tx = t->x + FixedMul(mapobjectscale, mo->movecount*FINECOSINE(ang>>ANGLETOFINESHIFT));
|
||||
ty = t->y + FixedMul(mapobjectscale, mo->movecount*FINESINE(ang>>ANGLETOFINESHIFT));
|
||||
|
||||
mo->momx = (tx - mo->x)/24;
|
||||
mo->momy = (ty - mo->y)/24;
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
fixed_t rx = mo->x + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale;
|
||||
fixed_t ry = mo->y + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale;
|
||||
fixed_t rz = mo->z + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale;
|
||||
mobj_t *bubl = P_SpawnMobj(rx, ry, rz, MT_THOK);
|
||||
P_SetScale(bubl, mapobjectscale*4);
|
||||
bubl->destscale = 1;
|
||||
bubl->sprite = SPR_BUBL;
|
||||
bubl->frame = 0;
|
||||
bubl->tics = TICRATE;
|
||||
}
|
||||
|
||||
mo->angle += 3*ANG1 * (mt->thing_args[0] ? -1 : 1);
|
||||
|
||||
if (mo->z > mo->watertop || mo->z > mo->ceilingz)
|
||||
P_RemoveMobj(mo);
|
||||
}
|
||||
|
|
@ -785,6 +785,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
}
|
||||
|
||||
case MT_LSZ_BUNGEE:
|
||||
Obj_BungeeSpecial(special, player);
|
||||
return;
|
||||
|
||||
// CTF Flags
|
||||
case MT_REDFLAG:
|
||||
case MT_BLUEFLAG:
|
||||
|
|
@ -837,6 +841,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
Obj_DashRingTouch(special, player);
|
||||
return;
|
||||
|
||||
case MT_DLZ_ROCKET:
|
||||
Obj_DLZRocketSpecial(special, player);
|
||||
return;
|
||||
|
||||
case MT_BALLSWITCH_BALL:
|
||||
{
|
||||
Obj_BallSwitchTouched(special, toucher);
|
||||
|
|
|
|||
24
src/p_map.c
24
src/p_map.c
|
|
@ -742,6 +742,30 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
// SRB2kart 011617 - Colission[sic] code for kart items //
|
||||
|
||||
if (thing->type == MT_DLZ_SEASAW_HITBOX)
|
||||
{
|
||||
if (tm.thing->type == MT_PLAYER)
|
||||
Obj_DLZSeasawCollide(tm.thing, thing); // all checks are performed in there.
|
||||
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (thing->type == MT_DLZ_HOVER)
|
||||
{
|
||||
if (tm.thing->type == MT_PLAYER)
|
||||
Obj_DLZHoverCollide(tm.thing, thing);
|
||||
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (thing->type == MT_DLZ_RINGVACCUM)
|
||||
{
|
||||
if (tm.thing->type == MT_FLINGRING)
|
||||
Obj_DLZRingVaccumCollide(tm.thing, thing);
|
||||
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (tm.thing->type == MT_INSTAWHIP)
|
||||
{
|
||||
if (tm.thing->z > thing->z + thing->height)
|
||||
|
|
|
|||
93
src/p_mobj.c
93
src/p_mobj.c
|
|
@ -9703,11 +9703,86 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
case MT_RAINBOWDASHRING:
|
||||
Obj_RainbowDashRingThink(mobj);
|
||||
break;
|
||||
|
||||
case MT_RIDEROID:
|
||||
Obj_RideroidThink(mobj);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MT_RIDEROIDNODE:
|
||||
Obj_RideroidNodeThink(mobj);
|
||||
break;
|
||||
|
||||
case MT_LSZ_EGGBALLSPAWNER:
|
||||
Obj_EggBallSpawnerThink(mobj);
|
||||
break;
|
||||
|
||||
case MT_LSZ_EGGBALL:
|
||||
Obj_EggBallThink(mobj);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_DLZ_ROCKET:
|
||||
Obj_DLZRocketThink(mobj);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_DLZ_SEASAW_SPAWN:
|
||||
Obj_DLZSeasawThink(mobj);
|
||||
break;
|
||||
|
||||
case MT_DLZ_SUCKEDRING:
|
||||
Obj_DLZSuckedRingThink(mobj);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_WATERPALACETURBINE:
|
||||
Obj_WPZTurbineThinker(mobj);
|
||||
break;
|
||||
|
||||
case MT_WATERPALACEBUBBLE:
|
||||
Obj_WPZBubbleThink(mobj);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_WATERPALACEFOUNTAIN:
|
||||
Obj_WPZFountainThink(mobj);
|
||||
break;
|
||||
|
||||
case MT_KURAGEN:
|
||||
Obj_WPZKuragenThink(mobj);
|
||||
break;
|
||||
|
||||
case MT_KURAGENBOMB:
|
||||
Obj_WPZKuragenBombThink(mobj);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_BALLSWITCH_BALL:
|
||||
{
|
||||
Obj_BallSwitchThink(mobj);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// check mobj against possible water content, before movement code
|
||||
P_MobjCheckWater(mobj);
|
||||
|
|
@ -10611,6 +10686,9 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
|||
case MT_SNEAKERPANEL:
|
||||
thing->shadowscale = 0;
|
||||
break;
|
||||
case MT_KURAGEN:
|
||||
thing->shadowscale = FRACUNIT/4;
|
||||
break;
|
||||
default:
|
||||
if (thing->flags & (MF_ENEMY|MF_BOSS))
|
||||
thing->shadowscale = FRACUNIT;
|
||||
|
|
@ -11167,6 +11245,21 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
case MT_RAINBOWDASHRING:
|
||||
Obj_RainbowDashRingSpawn(mobj);
|
||||
break;
|
||||
case MT_RIDEROIDNODE:
|
||||
Obj_RideroidNodeSpawn(mobj);
|
||||
break;
|
||||
case MT_DLZ_SEASAW_SPAWN:
|
||||
Obj_DLZSeasawSpawn(mobj);
|
||||
break;
|
||||
case MT_DLZ_HOVER:
|
||||
Obj_DLZHoverSpawn(mobj);
|
||||
break;
|
||||
case MT_DLZ_RINGVACCUM:
|
||||
Obj_DLZRingVaccumSpawn(mobj);
|
||||
break;
|
||||
case MT_WATERPALACETURBINE:
|
||||
Obj_WPZTurbineSpawn(mobj);
|
||||
break;
|
||||
case MT_SNEAKERPANEL:
|
||||
Obj_SneakerPanelSpawn(mobj);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -555,6 +555,37 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
WRITEUINT8(save->p, players[i].ringboxaward);
|
||||
WRITEFIXED(save->p, players[i].outrun);
|
||||
|
||||
WRITEUINT8(save->p, players[i].rideroid);
|
||||
WRITEUINT8(save->p, players[i].rdnodepull);
|
||||
WRITEINT32(save->p, players[i].rideroidangle);
|
||||
WRITEFIXED(save->p, players[i].rideroidspeed);
|
||||
WRITEINT32(save->p, players[i].rideroidrollangle);
|
||||
WRITEFIXED(save->p, players[i].rdaddmomx);
|
||||
WRITEFIXED(save->p, players[i].rdaddmomy);
|
||||
WRITEFIXED(save->p, players[i].rdaddmomz);
|
||||
|
||||
WRITEUINT8(save->p, players[i].bungee);
|
||||
|
||||
WRITEUINT32(save->p, players[i].lasthover);
|
||||
|
||||
WRITEUINT32(save->p, players[i].dlzrocket);
|
||||
WRITEANGLE(save->p, players[i].dlzrocketangle);
|
||||
WRITEINT32(save->p, players[i].dlzrocketanglev);
|
||||
WRITEFIXED(save->p, players[i].dlzrocketspd);
|
||||
|
||||
WRITEUINT8(save->p, players[i].seasaw);
|
||||
WRITEUINT32(save->p, players[i].seasawcooldown);
|
||||
WRITEFIXED(save->p, players[i].seasawdist);
|
||||
WRITEINT32(save->p, players[i].seasawangle);
|
||||
WRITEINT32(save->p, players[i].seasawangleadd);
|
||||
WRITEINT32(save->p, players[i].seasawmoreangle);
|
||||
WRITEUINT8(save->p, players[i].seasawdir);
|
||||
|
||||
WRITEUINT32(save->p, players[i].turbine);
|
||||
WRITEINT32(save->p, players[i].turbineangle);
|
||||
WRITEFIXED(save->p, players[i].turbineheight);
|
||||
WRITEUINT8(save->p, players[i].turbinespd);
|
||||
|
||||
// respawnvars_t
|
||||
WRITEUINT8(save->p, players[i].respawn.state);
|
||||
WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].respawn.wp));
|
||||
|
|
@ -1034,6 +1065,37 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
players[i].ringboxaward = READUINT8(save->p);
|
||||
players[i].outrun = READFIXED(save->p);
|
||||
|
||||
players[i].rideroid = (boolean)READUINT8(save->p);
|
||||
players[i].rdnodepull = (boolean)READUINT8(save->p);
|
||||
players[i].rideroidangle = READINT32(save->p);
|
||||
players[i].rideroidspeed = READFIXED(save->p);
|
||||
players[i].rideroidrollangle = READINT32(save->p);
|
||||
players[i].rdaddmomx = READFIXED(save->p);
|
||||
players[i].rdaddmomy = READFIXED(save->p);
|
||||
players[i].rdaddmomz = READFIXED(save->p);
|
||||
|
||||
players[i].bungee = READUINT8(save->p);
|
||||
|
||||
players[i].lasthover = (tic_t)READUINT32(save->p);
|
||||
|
||||
players[i].dlzrocket = (tic_t)READUINT32(save->p);
|
||||
players[i].dlzrocketangle = READANGLE(save->p);
|
||||
players[i].dlzrocketanglev = READINT32(save->p);
|
||||
players[i].dlzrocketspd = READFIXED(save->p);
|
||||
|
||||
players[i].seasaw = (boolean)READUINT8(save->p);
|
||||
players[i].seasawcooldown = READUINT32(save->p);
|
||||
players[i].seasawdist = READFIXED(save->p);
|
||||
players[i].seasawangle = READINT32(save->p);
|
||||
players[i].seasawangleadd = READINT32(save->p);
|
||||
players[i].seasawmoreangle = READINT32(save->p);
|
||||
players[i].seasawdir = (boolean)READUINT8(save->p);
|
||||
|
||||
players[i].turbine = (tic_t)READUINT32(save->p);
|
||||
players[i].turbineangle = READINT32(save->p);
|
||||
players[i].turbineheight = READFIXED(save->p);
|
||||
players[i].turbinespd = (boolean)READUINT8(save->p);
|
||||
|
||||
// respawnvars_t
|
||||
players[i].respawn.state = READUINT8(save->p);
|
||||
players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save->p);
|
||||
|
|
|
|||
|
|
@ -7266,7 +7266,7 @@ static void P_ConvertBinaryThingTypes(void)
|
|||
case 3786: // MT_BATTLEUFO_SPAWNER
|
||||
mapthings[i].thing_args[0] = mapthings[i].angle;
|
||||
break;
|
||||
case 3400: // MT_WATERPALACETURBINE (TODO: not yet hardcoded)
|
||||
case 3400: // MT_WATERPALACETURBINE
|
||||
{
|
||||
mtag_t tag = (mtag_t)mapthings[i].angle;
|
||||
INT32 j = Tag_FindLineSpecial(2009, tag);
|
||||
|
|
@ -7315,8 +7315,8 @@ static void P_ConvertBinaryThingTypes(void)
|
|||
|
||||
break;
|
||||
}
|
||||
case 3441: // MT_DASHRING (TODO: not yet hardcoded)
|
||||
case 3442: // MT_RAINBOWDASHRING (TODO: not yet hardcoded)
|
||||
case 3441: // MT_DASHRING
|
||||
case 3442: // MT_RAINBOWDASHRING
|
||||
mapthings[i].thing_args[0] = mapthings[i].options & 13;
|
||||
mapthings[i].thing_args[1] = mapthings[i].extrainfo;
|
||||
break;
|
||||
|
|
|
|||
20
src/p_spec.c
20
src/p_spec.c
|
|
@ -46,6 +46,7 @@
|
|||
#include "console.h" // CON_LogMessage
|
||||
#include "k_respawn.h"
|
||||
#include "k_terrain.h"
|
||||
#include "k_objects.h"
|
||||
#include "acs/interface.h"
|
||||
#include "m_easing.h"
|
||||
|
||||
|
|
@ -1379,6 +1380,7 @@ boolean P_CanActivateSpecial(INT16 special)
|
|||
{
|
||||
case 2001: // Finish line
|
||||
case 2003: // Respawn line
|
||||
case 2005: // Dismount Flying Object (always true here so that conditions are only kept on execution)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -4450,6 +4452,18 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
|
|||
}
|
||||
break;
|
||||
|
||||
case 2005: // Dismount Flying object
|
||||
// the rideroid is a bit complex so it's the one controlling the player rather than the player controlling it.
|
||||
// so it is the object needing to be checked for rather than the player
|
||||
if (mo->player && mo->player->rideroid && mo->tracer
|
||||
&& !P_MobjWasRemoved(mo->tracer) && mo->tracer->type == MT_RIDEROID)
|
||||
Obj_getPlayerOffRideroid(mo->tracer);
|
||||
|
||||
// dlz rockets are simpler and are tied to the player hence why we check for the player here instead.
|
||||
if (mo->player && mo->player->dlzrocket)
|
||||
Obj_DLZRocketDismount(mo->player);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -9263,9 +9277,9 @@ void T_Pusher(pusher_t *p)
|
|||
if (thing->angle - angle > ANGLE_180)
|
||||
thing->player->drawangle = angle - (angle - thing->angle) / 8;
|
||||
else
|
||||
thing->player->drawangle = angle + (thing->angle - angle) / 8;
|
||||
thing->player->drawangle = angle + (thing->angle - angle) / 8;
|
||||
//P_SetPlayerAngle(thing->player, thing->angle);
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (p->exclusive)
|
||||
|
|
@ -9408,7 +9422,7 @@ void P_DoQuakeOffset(UINT8 view, mappoint_t *viewPos, mappoint_t *offset)
|
|||
viewPos->z - quake->epicenter->z
|
||||
) - distBuffer;
|
||||
|
||||
|
||||
|
||||
fixed_t distEase = FixedDiv(max(epidist, 0), quake->radius);
|
||||
distEase = min(distEase, FRACUNIT);
|
||||
ir = Easing_InCubic(distEase, ir, 0);
|
||||
|
|
|
|||
|
|
@ -3188,7 +3188,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
lookback = ( player->cmd.buttons & BT_LOOKBACK );
|
||||
|
||||
camspeed = cv_cam_speed[num].value;
|
||||
camstill = cv_cam_still[num].value;
|
||||
camstill = cv_cam_still[num].value || player->seasaw; // RR: seasaws lock the camera so that it isn't disorienting.
|
||||
camrotate = cv_cam_rotate[num].value;
|
||||
camdist = FixedMul(cv_cam_dist[num].value, cameraScale);
|
||||
camheight = FixedMul(cv_cam_height[num].value, cameraScale);
|
||||
|
|
|
|||
|
|
@ -419,6 +419,7 @@ boolean R_IsDebugLine(seg_t *line)
|
|||
{
|
||||
case 2001: // Ring Racers: Finish Line
|
||||
case 2003: // Ring Racers: Respawn Line
|
||||
case 2005: // Ring Racers: Dismount flying object Line
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ UINT8 R_DebugLineColor(const line_t *ld)
|
|||
|
||||
case 2003: // Ring Racers: Respawn Line
|
||||
return alt ? 0x23 : 0x00; // red, white
|
||||
|
||||
case 2005: // Ring Racers: Dismount flying object Line
|
||||
return alt ? 0x86 : 0x36; // blue, orange
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
|
|
|
|||
|
|
@ -1210,6 +1210,11 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
|
||||
{"rank", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rank slam
|
||||
|
||||
{"ridr1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boarding Rideroid"}, // Rideroid Activation
|
||||
{"ridr2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rideroid Diveroll
|
||||
{"ridr3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rideroid Loop
|
||||
{"ridr4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Leaving Rideroid
|
||||
|
||||
// Damage sounds
|
||||
{"dmga1", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
|
||||
{"dmga2", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
|
||||
|
|
|
|||
|
|
@ -1278,6 +1278,12 @@ typedef enum
|
|||
sfx_rainbr,
|
||||
|
||||
sfx_rank,
|
||||
|
||||
// rideroid
|
||||
sfx_ridr1,
|
||||
sfx_ridr2,
|
||||
sfx_ridr3,
|
||||
sfx_ridr4,
|
||||
|
||||
// Damage sounds
|
||||
sfx_dmga1,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue