Merge remote-tracking branch 'origin/master' into catholic-vfx

This commit is contained in:
AJ Martinez 2023-11-14 21:47:51 -07:00
commit d54d2f6d04
43 changed files with 689 additions and 324 deletions

View file

@ -906,6 +906,7 @@ void Dummymenuplayer_OnChange(void);
consvar_t cv_dummymenuplayer = MenuDummy("dummymenuplayer", "P1").onchange(Dummymenuplayer_OnChange).values({{0, "NOPE"}, {1, "P1"}, {2, "P2"}, {3, "P3"}, {4, "P4"}}); consvar_t cv_dummymenuplayer = MenuDummy("dummymenuplayer", "P1").onchange(Dummymenuplayer_OnChange).values({{0, "NOPE"}, {1, "P1"}, {2, "P2"}, {3, "P3"}, {4, "P4"}});
consvar_t cv_dummyprofileautoroulette = MenuDummy("dummyprofileautoroulette", "Off").on_off(); consvar_t cv_dummyprofileautoroulette = MenuDummy("dummyprofileautoroulette", "Off").on_off();
consvar_t cv_dummyprofilelitesteer = MenuDummy("dummyprofilelitesteer", "On").on_off();
consvar_t cv_dummyprofilekickstart = MenuDummy("dummyprofilekickstart", "Off").on_off(); consvar_t cv_dummyprofilekickstart = MenuDummy("dummyprofilekickstart", "Off").on_off();
consvar_t cv_dummyprofilename = MenuDummy("dummyprofilename", ""); consvar_t cv_dummyprofilename = MenuDummy("dummyprofilename", "");
consvar_t cv_dummyprofileplayername = MenuDummy("dummyprofileplayername", ""); consvar_t cv_dummyprofileplayername = MenuDummy("dummyprofileplayername", "");
@ -1012,6 +1013,13 @@ consvar_t cv_autoroulette[MAXSPLITSCREENPLAYERS] = {
Player("autoroulette4", "Off").on_off().onchange(weaponPrefChange4), Player("autoroulette4", "Off").on_off().onchange(weaponPrefChange4),
}; };
consvar_t cv_litesteer[MAXSPLITSCREENPLAYERS] = {
Player("litesteer", "On").on_off().onchange(weaponPrefChange),
Player("litesteer2", "On").on_off().onchange(weaponPrefChange2),
Player("litesteer3", "On").on_off().onchange(weaponPrefChange3),
Player("litesteer4", "On").on_off().onchange(weaponPrefChange4),
};
consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS] = { consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS] = {
Player("cam_dist", "190").floating_point(), Player("cam_dist", "190").floating_point(),
Player("cam2_dist", "190").floating_point(), Player("cam2_dist", "190").floating_point(),

View file

@ -5619,7 +5619,7 @@ static INT16 Consistancy(void)
if (TypeIsNetSynced(mo->type) == false) if (TypeIsNetSynced(mo->type) == false)
continue; continue;
if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY)) if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_ELEMENTAL | MF_FIRE | MF_ENEMY | MF_PAIN | MF_DONTPUNT))
{ {
ret -= mo->type; ret -= mo->type;
ret += mo->x; ret += mo->x;

View file

@ -1229,6 +1229,7 @@ enum {
WP_KICKSTARTACCEL = 1<<0, WP_KICKSTARTACCEL = 1<<0,
WP_SHRINKME = 1<<1, WP_SHRINKME = 1<<1,
WP_AUTOROULETTE = 1<<2, WP_AUTOROULETTE = 1<<2,
WP_LITESTEER = 1<<3,
}; };
void WeaponPref_Send(UINT8 ssplayer) void WeaponPref_Send(UINT8 ssplayer)
@ -1241,6 +1242,9 @@ void WeaponPref_Send(UINT8 ssplayer)
if (cv_autoroulette[ssplayer].value) if (cv_autoroulette[ssplayer].value)
prefs |= WP_AUTOROULETTE; prefs |= WP_AUTOROULETTE;
if (cv_litesteer[ssplayer].value)
prefs |= WP_LITESTEER;
if (cv_shrinkme[ssplayer].value) if (cv_shrinkme[ssplayer].value)
prefs |= WP_SHRINKME; prefs |= WP_SHRINKME;
@ -1259,6 +1263,9 @@ void WeaponPref_Save(UINT8 **cp, INT32 playernum)
if (player->pflags & PF_AUTOROULETTE) if (player->pflags & PF_AUTOROULETTE)
prefs |= WP_AUTOROULETTE; prefs |= WP_AUTOROULETTE;
if (player->pflags & PF_LITESTEER)
prefs |= WP_LITESTEER;
if (player->pflags & PF_SHRINKME) if (player->pflags & PF_SHRINKME)
prefs |= WP_SHRINKME; prefs |= WP_SHRINKME;

View file

@ -64,6 +64,14 @@ typedef enum
PST_REBORN PST_REBORN
} playerstate_t; } playerstate_t;
typedef enum
{
IF_USERINGS = 1, // Have to be not holding the item button to change from using rings to using items (or vice versa) - prevents weirdness
IF_ITEMOUT = 1<<1, // Are you holding an item out?
IF_EGGMANOUT = 1<<2, // Eggman mark held, separate from IF_ITEMOUT so it doesn't stop you from getting items
IF_HOLDREADY = 1<<3, // Hold button-style item is ready to activate
} itemflags_t;
// //
// Player internal flags // Player internal flags
// //
@ -95,11 +103,9 @@ typedef enum
PF_RINGLOCK = 1<<13, // Prevent picking up rings while SPB is locked on PF_RINGLOCK = 1<<13, // Prevent picking up rings while SPB is locked on
// The following four flags are mutually exclusive, although they can also all be off at the same time. If we ever run out of pflags, eventually turn them into a seperate five(+) mode UINT8..? PF_LITESTEER = 1<<14, // Hold Down to shallow turn (digital only)
PF_USERINGS = 1<<14, // Have to be not holding the item button to change from using rings to using items (or vice versa) - prevents weirdness
PF_ITEMOUT = 1<<15, // Are you holding an item out? //15-17 free, was previously itemflags stuff
PF_EGGMANOUT = 1<<16, // Eggman mark held, separate from PF_ITEMOUT so it doesn't stop you from getting items
PF_HOLDREADY = 1<<17, // Hold button-style item is ready to activate
PF_DRIFTINPUT = 1<<18, // Drifting! PF_DRIFTINPUT = 1<<18, // Drifting!
PF_GETSPARKS = 1<<19, // Can get sparks PF_GETSPARKS = 1<<19, // Can get sparks
@ -942,6 +948,8 @@ struct player_t
UINT8 ringboxdelay; // Delay until Ring Box auto-activates UINT8 ringboxdelay; // Delay until Ring Box auto-activates
UINT8 ringboxaward; // Where did we stop? UINT8 ringboxaward; // Where did we stop?
UINT8 itemflags; // holds IF_ flags (see itemflags_t)
fixed_t outrun; // Milky Way road effect fixed_t outrun; // Milky Way road effect
uint8_t public_key[PUBKEYLENGTH]; uint8_t public_key[PUBKEYLENGTH];

View file

@ -6014,13 +6014,13 @@ const char *const MOBJFLAG_LIST[] = {
"SLOPE", "SLOPE",
"MISSILE", "MISSILE",
"SPRING", "SPRING",
"MONITOR", "ELEMENTAL",
"NOTHINK", "NOTHINK",
"NOCLIPHEIGHT", "NOCLIPHEIGHT",
"ENEMY", "ENEMY",
"SCENERY", "SCENERY",
"PAIN", "PAIN",
"STICKY", "DONTPUNT",
"APPLYTERRAIN", "APPLYTERRAIN",
"NOCLIPTHING", "NOCLIPTHING",
"GRENADEBOUNCE", "GRENADEBOUNCE",
@ -6120,11 +6120,10 @@ const char *const PLAYERFLAG_LIST[] = {
"RINGLOCK", // Prevent picking up rings while SPB is locked on "RINGLOCK", // Prevent picking up rings while SPB is locked on
// The following four flags are mutually exclusive, although they can also all be off at the same time. If we ever run out of pflags, eventually turn them into a seperate five(+) mode UINT8..? "LITESTEER", // Shallow digital turn with DOWN
"USERINGS", // Have to be not holding the item button to change from using rings to using items (or vice versa) - prevents weirdness "\x01", // Free
"ITEMOUT", // Are you holding an item out? "\x01", // Free
"EGGMANOUT", // Eggman mark held, separate from PF_ITEMOUT so it doesn't stop you from getting items "\x01", // Free
"HOLDREADY", // Hold button-style item is ready to activate
"DRIFTINPUT", // Drifting! "DRIFTINPUT", // Drifting!
"GETSPARKS", // Can get sparks "GETSPARKS", // Can get sparks

View file

@ -380,7 +380,7 @@ class TiccmdBuilder
// ugly with the current abstractions, though, and there's a fortunate trick here: // ugly with the current abstractions, though, and there's a fortunate trick here:
// if you can input full strength turns on both axes, either you're using a fucking // if you can input full strength turns on both axes, either you're using a fucking
// square gate, or you're not on an analog device. // square gate, or you're not on an analog device.
if (joystickvector.yaxis >= JOYAXISRANGE && abs(cmd->turning) == KART_FULLTURN) // >= beacuse some analog devices can go past JOYAXISRANGE (?!) if (cv_litesteer[ssplayer - 1].value && joystickvector.yaxis >= JOYAXISRANGE && abs(cmd->turning) == KART_FULLTURN) // >= beacuse some analog devices can go past JOYAXISRANGE (?!)
cmd->turning /= 2; cmd->turning /= 2;
} }

View file

@ -127,6 +127,7 @@ demoghost *ghosts = NULL;
#define DEMO_SHRINKME 0x04 #define DEMO_SHRINKME 0x04
#define DEMO_BOT 0x08 #define DEMO_BOT 0x08
#define DEMO_AUTOROULETTE 0x10 #define DEMO_AUTOROULETTE 0x10
#define DEMO_LITESTEER 0x20
// For demos // For demos
#define ZT_FWD 0x0001 #define ZT_FWD 0x0001
@ -1329,7 +1330,7 @@ readghosttic:
z = READFIXED(g->p); z = READFIXED(g->p);
angle = READANGLE(g->p); angle = READANGLE(g->p);
if (!(mobjinfo[type].flags & MF_SHOOTABLE) if (!(mobjinfo[type].flags & MF_SHOOTABLE)
|| !(mobjinfo[type].flags & (MF_ENEMY|MF_MONITOR)) || !(mobjinfo[type].flags & MF_ENEMY)
|| health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad. || health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad.
continue; continue;
poof = P_SpawnMobj(x, y, z, MT_GHOST); poof = P_SpawnMobj(x, y, z, MT_GHOST);
@ -2480,6 +2481,8 @@ void G_BeginRecording(void)
i |= DEMO_KICKSTART; i |= DEMO_KICKSTART;
if (player->pflags & PF_AUTOROULETTE) if (player->pflags & PF_AUTOROULETTE)
i |= DEMO_AUTOROULETTE; i |= DEMO_AUTOROULETTE;
if (player->pflags & PF_LITESTEER)
i |= DEMO_LITESTEER;
if (player->pflags & PF_SHRINKME) if (player->pflags & PF_SHRINKME)
i |= DEMO_SHRINKME; i |= DEMO_SHRINKME;
if (player->bot == true) if (player->bot == true)
@ -3447,6 +3450,11 @@ void G_DoPlayDemo(const char *defdemoname)
else else
players[p].pflags &= ~PF_AUTOROULETTE; players[p].pflags &= ~PF_AUTOROULETTE;
if (flags & DEMO_LITESTEER)
players[p].pflags |= PF_LITESTEER;
else
players[p].pflags &= ~PF_LITESTEER;
if (flags & DEMO_SHRINKME) if (flags & DEMO_SHRINKME)
players[p].pflags |= PF_SHRINKME; players[p].pflags |= PF_SHRINKME;
else else

View file

@ -2127,7 +2127,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
totalring = players[player].totalring; totalring = players[player].totalring;
xtralife = players[player].xtralife; xtralife = players[player].xtralife;
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE|PF_AUTOROULETTE)); pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE|PF_AUTOROULETTE|PF_LITESTEER));
// SRB2kart // SRB2kart
memcpy(&itemRoulette, &players[player].itemRoulette, sizeof (itemRoulette)); memcpy(&itemRoulette, &players[player].itemRoulette, sizeof (itemRoulette));
@ -2145,7 +2145,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
{ {
rings = 0; rings = 0;
} }
else if (modeattacking & ATTACKING_SPB) else if (G_TimeAttackStart())
{ {
rings = 20; rings = 20;
} }
@ -2175,7 +2175,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
} }
else else
{ {
if (players[player].pflags & PF_ITEMOUT) if (players[player].itemflags & IF_ITEMOUT)
{ {
itemtype = 0; itemtype = 0;
itemamount = 0; itemamount = 0;

View file

@ -99,6 +99,7 @@ extern consvar_t cv_pauseifunfocused;
extern consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_autoroulette[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_autoroulette[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_litesteer[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_shrinkme[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_shrinkme[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_deadzone[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_deadzone[MAXSPLITSCREENPLAYERS];

View file

@ -4848,12 +4848,12 @@ state_t states[NUMSTATES] =
{SPR_FLEN, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_FLINGENERGY3}, // S_FLINGENERGY2, {SPR_FLEN, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_FLINGENERGY3}, // S_FLINGENERGY2,
{SPR_FLEN, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_NULL}, // S_FLINGENERGY3, {SPR_FLEN, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_NULL}, // S_FLINGENERGY3,
{SPR_CLAS, FF_FULLBRIGHT|FF_TRANS30, 2, {A_PlayActiveSound}, 0, 0, S_CLASH2}, // S_CLASH1 {SPR_CLAS, FF_FULLBRIGHT|FF_ADD, 2, {A_PlayActiveSound}, 0, 0, S_CLASH2}, // S_CLASH1
{SPR_CLAS, FF_FULLBRIGHT|FF_TRANS30|1, 2, {NULL}, 0, 0, S_CLASH3}, // S_CLASH2 {SPR_CLAS, FF_FULLBRIGHT|FF_ADD|1, 2, {NULL}, 0, 0, S_CLASH3}, // S_CLASH2
{SPR_CLAS, FF_FULLBRIGHT|FF_TRANS30|2, 2, {NULL}, 0, 0, S_CLASH4}, // S_CLASH3 {SPR_CLAS, FF_FULLBRIGHT|FF_ADD|2, 2, {NULL}, 0, 0, S_CLASH4}, // S_CLASH3
{SPR_CLAS, FF_FULLBRIGHT|FF_TRANS30|3, 2, {NULL}, 0, 0, S_CLASH5}, // S_CLASH4 {SPR_CLAS, FF_FULLBRIGHT|FF_ADD|3, 2, {NULL}, 0, 0, S_CLASH5}, // S_CLASH4
{SPR_CLAS, FF_FULLBRIGHT|FF_TRANS30|4, 2, {NULL}, 0, 0, S_CLASH6}, // S_CLASH5 {SPR_CLAS, FF_FULLBRIGHT|FF_ADD|4, 2, {NULL}, 0, 0, S_CLASH6}, // S_CLASH5
{SPR_CLAS, FF_FULLBRIGHT|FF_TRANS30|5, 2, {NULL}, 0, 0, S_NULL}, // S_CLASH6 {SPR_CLAS, FF_FULLBRIGHT|FF_ADD|5, 2, {NULL}, 0, 0, S_NULL}, // S_CLASH6
{SPR_PSHW, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FIREDITEM2}, // S_FIREDITEM1 {SPR_PSHW, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FIREDITEM2}, // S_FIREDITEM1
{SPR_PSHW, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_FIREDITEM3}, // S_FIREDITEM2 {SPR_PSHW, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_FIREDITEM3}, // S_FIREDITEM2
@ -5775,7 +5775,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
1000, // mass 1000, // mass
MT_THOK, // damage MT_THOK, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SOLID|MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
(statenum_t)MT_THOK // raisestate (statenum_t)MT_THOK // raisestate
}, },
@ -9581,7 +9581,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_RING_ICON, // damage MT_RING_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9608,7 +9608,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_PITY_ICON, // damage MT_PITY_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9635,7 +9635,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_ATTRACT_ICON,// damage MT_ATTRACT_ICON,// damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9662,7 +9662,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_FORCE_ICON, // damage MT_FORCE_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9689,7 +9689,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_ARMAGEDDON_ICON, // damage MT_ARMAGEDDON_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9716,7 +9716,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_WHIRLWIND_ICON, // damage MT_WHIRLWIND_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9743,7 +9743,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_ELEMENTAL_ICON, // damage MT_ELEMENTAL_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9770,7 +9770,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_SNEAKERS_ICON, // damage MT_SNEAKERS_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9797,7 +9797,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_INVULN_ICON, // damage MT_INVULN_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9824,7 +9824,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_1UP_ICON, // damage MT_1UP_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9851,7 +9851,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_EGGMAN_ICON, // damage MT_EGGMAN_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9878,7 +9878,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_MIXUP_ICON, // damage MT_MIXUP_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9905,7 +9905,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_UNKNOWN, // damage MT_UNKNOWN, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9932,7 +9932,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_GRAVITY_ICON, // damage MT_GRAVITY_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9959,7 +9959,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_RECYCLER_ICON, // damage MT_RECYCLER_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9986,7 +9986,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_SCORE1K_ICON, // damage MT_SCORE1K_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10013,7 +10013,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_SCORE10K_ICON, // damage MT_SCORE10K_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10040,7 +10040,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_FLAMEAURA_ICON, // damage MT_FLAMEAURA_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10067,7 +10067,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_BUBBLEWRAP_ICON, // damage MT_BUBBLEWRAP_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10094,7 +10094,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_THUNDERCOIN_ICON, // damage MT_THUNDERCOIN_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10121,7 +10121,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_PITY_ICON, // damage MT_PITY_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10148,7 +10148,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_ATTRACT_ICON,// damage MT_ATTRACT_ICON,// damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10175,7 +10175,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_FORCE_ICON, // damage MT_FORCE_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10202,7 +10202,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_ARMAGEDDON_ICON, // damage MT_ARMAGEDDON_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10229,7 +10229,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_WHIRLWIND_ICON, // damage MT_WHIRLWIND_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10256,7 +10256,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_ELEMENTAL_ICON, // damage MT_ELEMENTAL_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10283,7 +10283,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_SNEAKERS_ICON, // damage MT_SNEAKERS_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10310,7 +10310,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_INVULN_ICON, // damage MT_INVULN_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10337,7 +10337,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_EGGMAN_ICON, // damage MT_EGGMAN_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10364,7 +10364,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_GRAVITY_ICON, // damage MT_GRAVITY_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10391,7 +10391,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_FLAMEAURA_ICON, // damage MT_FLAMEAURA_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10418,7 +10418,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_BUBBLEWRAP_ICON, // damage MT_BUBBLEWRAP_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10445,7 +10445,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_THUNDERCOIN_ICON, // damage MT_THUNDERCOIN_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags MF_SOLID|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10472,7 +10472,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_RING_ICON, // damage MT_RING_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -10499,7 +10499,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
MT_RING_ICON, // damage MT_RING_ICON, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags MF_SOLID|MF_SHOOTABLE, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -14651,13 +14651,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
5*FRACUNIT, // speed 5*FRACUNIT, // speed
8*FRACUNIT, // radius 16*FRACUNIT, // radius
8*FRACUNIT, // height 32*FRACUNIT, // height
0, // display offset 0, // display offset
DMG_NORMAL, // mass DMG_NORMAL, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_NOGRAVITY|MF_MISSILE|MF_PAIN, // flags MF_NOGRAVITY|MF_MISSILE|MF_PAIN|MF_NOSQUISH|MF_NOHITLAGFORME|MF_ELEMENTAL, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -23144,7 +23144,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24197,7 +24197,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_peel, // activesound sfx_peel, // activesound
MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24224,7 +24224,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24278,7 +24278,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_s3k96, // activesound sfx_s3k96, // activesound
MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24305,7 +24305,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24332,7 +24332,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_s3kc0s, // activesound sfx_s3kc0s, // activesound
MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24359,7 +24359,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24413,7 +24413,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_s3k5c, // activesound sfx_s3k5c, // activesound
MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24440,7 +24440,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24548,7 +24548,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // mass 0, // mass
0, // damage 0, // damage
sfx_s3k5c, // activesound sfx_s3k5c, // activesound
MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24575,7 +24575,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_s3k96, // activesound sfx_s3k96, // activesound
MF_SPECIAL|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SPECIAL|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24602,7 +24602,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SPECIAL|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SPECIAL|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24656,7 +24656,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN, // flags MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24710,7 +24710,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_kc64, // activesound sfx_kc64, // activesound
MF_SOLID|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags MF_SOLID|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -24953,7 +24953,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_NOCLIPTHING|MF_DONTENCOREMAP, // flags MF_NOCLIPTHING|MF_DONTENCOREMAP|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -25250,7 +25250,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_s3k5c, // activesound sfx_s3k5c, // activesound
MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN, // flags MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -25277,7 +25277,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_None, // activesound sfx_None, // activesound
MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -25331,7 +25331,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass 100, // mass
1, // damage 1, // damage
sfx_s3k96, // activesound sfx_s3k96, // activesound
MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -25385,7 +25385,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // mass 0, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SPECIAL|MF_DONTENCOREMAP|MF_APPLYTERRAIN, // flags MF_SPECIAL|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -30709,7 +30709,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // mass 0, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_DONTPUNT, // flags
S_NULL // raisestate S_NULL // raisestate
}, },

View file

@ -440,7 +440,7 @@ static boolean K_BotRevealsGenericTrap(player_t *player, INT16 turnamt, boolean
--------------------------------------------------*/ --------------------------------------------------*/
static void K_BotItemGenericTrapShield(player_t *player, ticcmd_t *cmd, INT16 turnamt, boolean mine) static void K_BotItemGenericTrapShield(player_t *player, ticcmd_t *cmd, INT16 turnamt, boolean mine)
{ {
if (player->pflags & PF_ITEMOUT) if (player->itemflags & IF_ITEMOUT)
{ {
return; return;
} }
@ -465,7 +465,7 @@ static void K_BotItemGenericTrapShield(player_t *player, ticcmd_t *cmd, INT16 tu
--------------------------------------------------*/ --------------------------------------------------*/
static void K_BotItemGenericOrbitShield(player_t *player, ticcmd_t *cmd) static void K_BotItemGenericOrbitShield(player_t *player, ticcmd_t *cmd)
{ {
if (player->pflags & PF_ITEMOUT) if (player->itemflags & IF_ITEMOUT)
{ {
return; return;
} }
@ -811,7 +811,7 @@ static boolean K_BotRevealsEggbox(player_t *player)
--------------------------------------------------*/ --------------------------------------------------*/
static void K_BotItemEggmanShield(player_t *player, ticcmd_t *cmd) static void K_BotItemEggmanShield(player_t *player, ticcmd_t *cmd)
{ {
if (player->pflags & PF_EGGMANOUT) if (player->itemflags & IF_EGGMANOUT)
{ {
return; return;
} }
@ -1221,7 +1221,7 @@ static void K_BotItemBubble(player_t *player, ticcmd_t *cmd)
hold = true; hold = true;
} }
if (hold && (player->pflags & PF_HOLDREADY)) if (hold && (player->itemflags & IF_HOLDREADY))
{ {
cmd->buttons |= BT_ATTACK; cmd->buttons |= BT_ATTACK;
} }
@ -1245,7 +1245,7 @@ static void K_BotItemFlame(player_t *player, ticcmd_t *cmd)
{ {
player->botvars.itemconfirm--; player->botvars.itemconfirm--;
} }
else if (player->pflags & PF_HOLDREADY) else if (player->itemflags & IF_HOLDREADY)
{ {
INT32 flamemax = player->flamelength; INT32 flamemax = player->flamelength;
@ -1532,7 +1532,7 @@ static void K_BotItemRouletteMash(player_t *player, ticcmd_t *cmd)
--------------------------------------------------*/ --------------------------------------------------*/
void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
{ {
if (player->pflags & PF_USERINGS) if (player->itemflags & IF_USERINGS)
{ {
if (player->rings > 0) if (player->rings > 0)
{ {
@ -1567,7 +1567,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
{ {
K_BotItemEggmanExplosion(player, cmd); K_BotItemEggmanExplosion(player, cmd);
} }
else if (player->pflags & PF_EGGMANOUT) else if (player->itemflags & IF_EGGMANOUT)
{ {
K_BotItemEggman(player, cmd); K_BotItemEggman(player, cmd);
} }
@ -1604,7 +1604,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
K_BotItemSneaker(player, cmd); K_BotItemSneaker(player, cmd);
break; break;
case KITEM_BANANA: case KITEM_BANANA:
if (!(player->pflags & PF_ITEMOUT)) if (!(player->itemflags & IF_ITEMOUT))
{ {
K_BotItemGenericTrapShield(player, cmd, turnamt, false); K_BotItemGenericTrapShield(player, cmd, turnamt, false);
} }
@ -1617,7 +1617,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
K_BotItemEggmanShield(player, cmd); K_BotItemEggmanShield(player, cmd);
break; break;
case KITEM_ORBINAUT: case KITEM_ORBINAUT:
if (!(player->pflags & PF_ITEMOUT)) if (!(player->itemflags & IF_ITEMOUT))
{ {
K_BotItemGenericOrbitShield(player, cmd); K_BotItemGenericOrbitShield(player, cmd);
} }
@ -1627,7 +1627,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
} }
break; break;
case KITEM_JAWZ: case KITEM_JAWZ:
if (!(player->pflags & PF_ITEMOUT)) if (!(player->itemflags & IF_ITEMOUT))
{ {
K_BotItemGenericOrbitShield(player, cmd); K_BotItemGenericOrbitShield(player, cmd);
} }
@ -1637,7 +1637,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
} }
break; break;
case KITEM_MINE: case KITEM_MINE:
if (!(player->pflags & PF_ITEMOUT)) if (!(player->itemflags & IF_ITEMOUT))
{ {
K_BotItemGenericTrapShield(player, cmd, turnamt, true); K_BotItemGenericTrapShield(player, cmd, turnamt, true);
} }
@ -1654,7 +1654,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
K_BotItemBallhog(player, cmd); K_BotItemBallhog(player, cmd);
break; break;
case KITEM_DROPTARGET: case KITEM_DROPTARGET:
if (!(player->pflags & PF_ITEMOUT)) if (!(player->itemflags & IF_ITEMOUT))
{ {
K_BotItemGenericTrapShield(player, cmd, turnamt, false); K_BotItemGenericTrapShield(player, cmd, turnamt, false);
} }

View file

@ -577,8 +577,8 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
} }
// Has held item shield // Has held item shield
else if (K_PlayerAttackSteer(thing, side, 20, else if (K_PlayerAttackSteer(thing, side, 20,
(thing->player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)), (thing->player->itemflags & (IF_ITEMOUT|IF_EGGMANOUT)),
(g_nudgeSearch.botmo->player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)) (g_nudgeSearch.botmo->player->itemflags & (IF_ITEMOUT|IF_EGGMANOUT))
)) ))
{ {
break; break;

View file

@ -18,6 +18,7 @@
#include "k_podium.h" #include "k_podium.h"
#include "k_powerup.h" #include "k_powerup.h"
#include "k_hitlag.h" #include "k_hitlag.h"
#include "m_random.h"
angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2) angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2)
{ {
@ -190,7 +191,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
if (t1->target->hnext == t1) if (t1->target->hnext == t1)
{ {
P_SetTarget(&t1->target->hnext, NULL); P_SetTarget(&t1->target->hnext, NULL);
t1->target->player->pflags &= ~PF_EGGMANOUT; t1->target->player->itemflags &= ~IF_EGGMANOUT;
} }
} }
@ -1170,3 +1171,114 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
return false; return false;
} }
void K_PuntHazard(mobj_t *t1, mobj_t *t2)
{
// TODO: spawn a unique mobjtype other than MT_GHOST
mobj_t *img = P_SpawnGhostMobj(t1);
K_MakeObjectReappear(t1);
img->flags &= ~MF_NOGRAVITY;
img->renderflags = t1->renderflags & ~RF_DONTDRAW;
img->extravalue1 = 1;
img->extravalue2 = 2;
img->fuse = 2*TICRATE;
struct Vector
{
fixed_t x_, y_, z_;
fixed_t h_ = FixedHypot(x_, y_);
fixed_t speed_ = std::max(60 * mapobjectscale, FixedHypot(h_, z_) * 2);
explicit Vector(fixed_t x, fixed_t y, fixed_t z) : x_(x), y_(y), z_(z) {}
explicit Vector(const mobj_t* mo) :
Vector(std::max(
Vector(mo->x - mo->old_x, mo->y - mo->old_y, mo->z - mo->old_z),
Vector(mo->momx, mo->momy, mo->momz)
))
{
}
explicit Vector(const Vector&) = default;
bool operator<(const Vector& b) const { return speed_ < b.speed_; }
void invert()
{
x_ = -x_;
y_ = -y_;
z_ = -z_;
}
void thrust(mobj_t* mo) const
{
angle_t yaw = R_PointToAngle2(0, 0, h_, z_);
yaw = std::max(AbsAngle(yaw), static_cast<angle_t>(ANGLE_11hh)) + (yaw & ANGLE_180);
P_InstaThrust(mo, R_PointToAngle2(0, 0, x_, y_), FixedMul(speed_, FCOS(yaw)));
mo->momz = FixedMul(speed_, FSIN(yaw));
}
};
Vector h_vector(t1);
Vector p_vector(t2);
h_vector.invert();
std::max(h_vector, p_vector).thrust(img);
K_DoPowerClash(img, t2); // applies hitlag
P_SpawnMobj(t2->x/2 + t1->x/2, t2->y/2 + t1->y/2, t2->z/2 + t1->z/2, MT_ITEMCLASH);
}
boolean K_PuntCollide(mobj_t *t1, mobj_t *t2)
{
if (t1->flags & MF_DONTPUNT)
{
return false;
}
if (!t2->player)
{
return false;
}
if (!K_PlayerCanPunt(t2->player))
{
return false;
}
if (t1->flags & MF_ELEMENTAL)
{
K_MakeObjectReappear(t1);
// copied from MT_ITEMCAPSULE
UINT8 i;
INT16 spacing = (t1->radius >> 1) / t1->scale;
// dust effects
for (i = 0; i < 10; i++)
{
mobj_t *puff = P_SpawnMobjFromMobj(
t1,
P_RandomRange(PR_ITEM_DEBRIS, -spacing, spacing) * FRACUNIT,
P_RandomRange(PR_ITEM_DEBRIS, -spacing, spacing) * FRACUNIT,
P_RandomRange(PR_ITEM_DEBRIS, 0, 4*spacing) * FRACUNIT,
MT_SPINDASHDUST
);
puff->momz = puff->scale * P_MobjFlip(puff);
P_Thrust(puff, R_PointToAngle2(t2->x, t2->y, puff->x, puff->y), 3*puff->scale);
puff->momx += t2->momx / 2;
puff->momy += t2->momy / 2;
puff->momz += t2->momz / 2;
}
}
else
{
K_PuntHazard(t1, t2);
}
return true;
}

View file

@ -33,6 +33,9 @@ boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2);
boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2); boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2);
void K_PuntHazard(mobj_t *t1, mobj_t *t2);
boolean K_PuntCollide(mobj_t *t1, mobj_t *t2);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View file

@ -1453,7 +1453,7 @@ static void K_drawKartItem(void)
break; break;
} }
if ((stplyr->pflags & PF_ITEMOUT) && !(leveltime & 1)) if ((stplyr->itemflags & IF_ITEMOUT) && !(leveltime & 1))
localpatch[1] = kp_nodraw; localpatch[1] = kp_nodraw;
} }

View file

@ -6824,11 +6824,11 @@ void K_DropHnextList(player_t *player)
player->bananadrag = 0; player->bananadrag = 0;
if (player->pflags & PF_EGGMANOUT) if (player->itemflags & IF_EGGMANOUT)
{ {
player->pflags &= ~PF_EGGMANOUT; player->itemflags &= ~IF_EGGMANOUT;
} }
else if ((player->pflags & PF_ITEMOUT) else if ((player->itemflags & IF_ITEMOUT)
&& (dropall || (--player->itemamount <= 0))) && (dropall || (--player->itemamount <= 0)))
{ {
player->itemamount = 0; player->itemamount = 0;
@ -7221,11 +7221,11 @@ static void K_MoveHeldObjects(player_t *player)
{ {
player->bananadrag = 0; player->bananadrag = 0;
if (player->pflags & PF_EGGMANOUT) if (player->itemflags & IF_EGGMANOUT)
{ {
player->pflags &= ~PF_EGGMANOUT; player->itemflags &= ~IF_EGGMANOUT;
} }
else if (player->pflags & PF_ITEMOUT) else if (player->itemflags & IF_ITEMOUT)
{ {
player->itemamount = 0; player->itemamount = 0;
K_UnsetItemOut(player); K_UnsetItemOut(player);
@ -7240,11 +7240,11 @@ static void K_MoveHeldObjects(player_t *player)
P_SetTarget(&player->mo->hnext, NULL); P_SetTarget(&player->mo->hnext, NULL);
player->bananadrag = 0; player->bananadrag = 0;
if (player->pflags & PF_EGGMANOUT) if (player->itemflags & IF_EGGMANOUT)
{ {
player->pflags &= ~PF_EGGMANOUT; player->itemflags &= ~IF_EGGMANOUT;
} }
else if (player->pflags & PF_ITEMOUT) else if (player->itemflags & IF_ITEMOUT)
{ {
player->itemamount = 0; player->itemamount = 0;
K_UnsetItemOut(player); K_UnsetItemOut(player);
@ -8228,7 +8228,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
} }
if (player->itemtype == KITEM_NONE) if (player->itemtype == KITEM_NONE)
player->pflags &= ~PF_HOLDREADY; player->itemflags &= ~IF_HOLDREADY;
// DKR style camera for boosting // DKR style camera for boosting
if (player->karthud[khud_boostcam] != 0 || player->karthud[khud_destboostcam] != 0) if (player->karthud[khud_boostcam] != 0 || player->karthud[khud_destboostcam] != 0)
@ -8610,7 +8610,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
S_StopSoundByID(player->mo, sfx_wchrg2); S_StopSoundByID(player->mo, sfx_wchrg2);
} }
if (player->itemamount || player->respawn.state != RESPAWNST_NONE || player->pflags & (PF_ITEMOUT|PF_EGGMANOUT) || player->rocketsneakertimer || player->ringboxdelay) if (player->itemamount || player->respawn.state != RESPAWNST_NONE || player->itemflags & (IF_ITEMOUT|IF_EGGMANOUT) || player->rocketsneakertimer || player->ringboxdelay)
player->instaWhipCharge = 0; player->instaWhipCharge = 0;
if (player->tiregrease) if (player->tiregrease)
@ -8939,7 +8939,7 @@ void K_KartPlayerAfterThink(player_t *player)
K_MoveHeldObjects(player); K_MoveHeldObjects(player);
// Jawz reticule (seeking) // Jawz reticule (seeking)
if (player->itemtype == KITEM_JAWZ && (player->pflags & PF_ITEMOUT)) if (player->itemtype == KITEM_JAWZ && (player->itemflags & IF_ITEMOUT))
{ {
const INT32 lastTargID = player->lastjawztarget; const INT32 lastTargID = player->lastjawztarget;
mobj_t *lastTarg = NULL; mobj_t *lastTarg = NULL;
@ -10430,7 +10430,7 @@ void K_StripItems(player_t *player)
K_DropKitchenSink(player); K_DropKitchenSink(player);
player->itemtype = KITEM_NONE; player->itemtype = KITEM_NONE;
player->itemamount = 0; player->itemamount = 0;
player->pflags &= ~(PF_ITEMOUT|PF_EGGMANOUT); player->itemflags &= ~(IF_ITEMOUT|IF_EGGMANOUT);
if (player->itemRoulette.eggman == false) if (player->itemRoulette.eggman == false)
{ {
@ -11274,7 +11274,7 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz)
void K_SetItemOut(player_t *player) void K_SetItemOut(player_t *player)
{ {
player->pflags |= PF_ITEMOUT; player->itemflags |= IF_ITEMOUT;
if (player->mo->scale >= FixedMul(GROW_PHYSICS_SCALE, mapobjectscale)) if (player->mo->scale >= FixedMul(GROW_PHYSICS_SCALE, mapobjectscale))
{ {
@ -11292,7 +11292,7 @@ void K_SetItemOut(player_t *player)
void K_UnsetItemOut(player_t *player) void K_UnsetItemOut(player_t *player)
{ {
player->pflags &= ~PF_ITEMOUT; player->itemflags &= ~IF_ITEMOUT;
player->itemscale = ITEMSCALE_NORMAL; player->itemscale = ITEMSCALE_NORMAL;
player->bananadrag = 0; player->bananadrag = 0;
} }
@ -11304,7 +11304,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
{ {
ticcmd_t *cmd = &player->cmd; ticcmd_t *cmd = &player->cmd;
boolean ATTACK_IS_DOWN = ((cmd->buttons & BT_ATTACK) && !(player->oldcmd.buttons & BT_ATTACK) && (player->respawn.state == RESPAWNST_NONE)); boolean ATTACK_IS_DOWN = ((cmd->buttons & BT_ATTACK) && !(player->oldcmd.buttons & BT_ATTACK) && (player->respawn.state == RESPAWNST_NONE));
boolean HOLDING_ITEM = (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)); boolean HOLDING_ITEM = (player->itemflags & (IF_ITEMOUT|IF_EGGMANOUT));
boolean NO_HYUDORO = (player->stealingtimer == 0); boolean NO_HYUDORO = (player->stealingtimer == 0);
if (!player->exiting) if (!player->exiting)
@ -11330,9 +11330,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|| player->itemRoulette.active == true || player->itemRoulette.active == true
|| player->rocketsneakertimer || player->rocketsneakertimer
|| player->eggmanexplode)) || player->eggmanexplode))
player->pflags |= PF_USERINGS; player->itemflags |= IF_USERINGS;
else else
player->pflags &= ~PF_USERINGS; player->itemflags &= ~IF_USERINGS;
} }
if (player->ringboxdelay) if (player->ringboxdelay)
@ -11373,7 +11373,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->instaWhipCooldown = 0; player->instaWhipCooldown = 0;
} }
if (leveltime < starttime || player->pflags & (PF_ITEMOUT|PF_EGGMANOUT) || player->rocketsneakertimer || player->instaWhipCooldown) if (leveltime < starttime || player->itemflags & (IF_ITEMOUT|IF_EGGMANOUT) || player->rocketsneakertimer || player->instaWhipCooldown)
{ {
chargingwhip = false; chargingwhip = false;
player->instaWhipCharge = 0; player->instaWhipCharge = 0;
@ -11447,7 +11447,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
// First, the really specific, finicky items that function without the item being directly in your item slot. // First, the really specific, finicky items that function without the item being directly in your item slot.
{ {
// Ring boosting // Ring boosting
if (player->pflags & PF_USERINGS) if (player->itemflags & IF_USERINGS)
{ {
if ((cmd->buttons & BT_ATTACK) && !player->ringdelay && player->rings > 0) if ((cmd->buttons & BT_ATTACK) && !player->ringdelay && player->rings > 0)
{ {
@ -11471,13 +11471,13 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->eggmanexplode = 1; player->eggmanexplode = 1;
} }
// Eggman Monitor throwing // Eggman Monitor throwing
else if (player->pflags & PF_EGGMANOUT) else if (player->itemflags & IF_EGGMANOUT)
{ {
if (ATTACK_IS_DOWN) if (ATTACK_IS_DOWN)
{ {
K_ThrowKartItem(player, false, MT_EGGMANITEM, -1, 0, 0); K_ThrowKartItem(player, false, MT_EGGMANITEM, -1, 0, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->pflags &= ~PF_EGGMANOUT; player->itemflags &= ~IF_EGGMANOUT;
K_UpdateHnextList(player, true); K_UpdateHnextList(player, true);
} }
} }
@ -11581,7 +11581,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
prev = mo; prev = mo;
} }
} }
else if (ATTACK_IS_DOWN && (player->pflags & PF_ITEMOUT)) // Banana x3 thrown else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) // Banana x3 thrown
{ {
K_ThrowKartItem(player, false, MT_BANANA, -1, 0, 0); K_ThrowKartItem(player, false, MT_BANANA, -1, 0, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
@ -11594,7 +11594,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
{ {
mobj_t *mo; mobj_t *mo;
player->itemamount--; player->itemamount--;
player->pflags |= PF_EGGMANOUT; player->itemflags |= IF_EGGMANOUT;
S_StartSound(player->mo, sfx_s254); S_StartSound(player->mo, sfx_s254);
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EGGMANITEM_SHIELD); mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EGGMANITEM_SHIELD);
if (mo) if (mo)
@ -11644,7 +11644,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
prev = mo; prev = mo;
} }
} }
else if (ATTACK_IS_DOWN && (player->pflags & PF_ITEMOUT)) // Orbinaut x3 thrown else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) // Orbinaut x3 thrown
{ {
K_ThrowKartItem(player, true, MT_ORBINAUT, 1, 0, 0); K_ThrowKartItem(player, true, MT_ORBINAUT, 1, 0, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
@ -11685,7 +11685,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
prev = mo; prev = mo;
} }
} }
else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->pflags & PF_ITEMOUT)) // Jawz thrown else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->itemflags & IF_ITEMOUT)) // Jawz thrown
{ {
K_ThrowKartItem(player, true, MT_JAWZ, 1, 0, 0); K_ThrowKartItem(player, true, MT_JAWZ, 1, 0, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
@ -11711,12 +11711,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_SetTarget(&player->mo->hnext, mo); P_SetTarget(&player->mo->hnext, mo);
} }
} }
else if (ATTACK_IS_DOWN && (player->pflags & PF_ITEMOUT)) else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT))
{ {
K_ThrowKartItem(player, false, MT_SSMINE, 1, 1, 0); K_ThrowKartItem(player, false, MT_SSMINE, 1, 1, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->itemamount--; player->itemamount--;
player->pflags &= ~PF_ITEMOUT; player->itemflags &= ~IF_ITEMOUT;
K_UpdateHnextList(player, true); K_UpdateHnextList(player, true);
} }
break; break;
@ -11746,12 +11746,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_SetTarget(&player->mo->hnext, mo); P_SetTarget(&player->mo->hnext, mo);
} }
} }
else if (ATTACK_IS_DOWN && (player->pflags & PF_ITEMOUT)) else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT))
{ {
K_ThrowKartItem(player, (player->throwdir > 0), MT_DROPTARGET, -1, 0, 0); K_ThrowKartItem(player, (player->throwdir > 0), MT_DROPTARGET, -1, 0, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->itemamount--; player->itemamount--;
player->pflags &= ~PF_ITEMOUT; player->itemflags &= ~IF_ITEMOUT;
K_UpdateHnextList(player, true); K_UpdateHnextList(player, true);
} }
break; break;
@ -11771,7 +11771,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->ballhogcharge == 0) if (player->ballhogcharge == 0)
player->ballhogtap = false; player->ballhogtap = false;
boolean realcharge = (cmd->buttons & BT_ATTACK) && (player->pflags & PF_HOLDREADY) && (player->ballhogcharge < ballhogmax); boolean realcharge = (cmd->buttons & BT_ATTACK) && (player->itemflags & IF_HOLDREADY) && (player->ballhogcharge < ballhogmax);
if ((realcharge && !player->ballhogtap) || (player->ballhogtap && player->ballhogcharge < BALLHOGINCREMENT)) if ((realcharge && !player->ballhogtap) || (player->ballhogtap && player->ballhogcharge < BALLHOGINCREMENT))
{ {
player->ballhogcharge++; player->ballhogcharge++;
@ -11794,11 +11794,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
{ {
if (cmd->buttons & BT_ATTACK) if (cmd->buttons & BT_ATTACK)
{ {
player->pflags &= ~PF_HOLDREADY; player->itemflags &= ~IF_HOLDREADY;
} }
else else
{ {
player->pflags |= PF_HOLDREADY; player->itemflags |= IF_HOLDREADY;
} }
if (player->ballhogcharge > 0) if (player->ballhogcharge > 0)
@ -11834,7 +11834,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
} }
player->ballhogcharge = 0; player->ballhogcharge = 0;
player->pflags &= ~PF_HOLDREADY; player->itemflags &= ~IF_HOLDREADY;
} }
} }
} }
@ -11968,7 +11968,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (!HOLDING_ITEM && NO_HYUDORO) if (!HOLDING_ITEM && NO_HYUDORO)
{ {
if ((cmd->buttons & BT_ATTACK) && (player->pflags & PF_HOLDREADY)) if ((cmd->buttons & BT_ATTACK) && (player->itemflags & IF_HOLDREADY))
{ {
if (player->bubbleblowup == 0) if (player->bubbleblowup == 0)
S_StartSound(player->mo, sfx_s3k75); S_StartSound(player->mo, sfx_s3k75);
@ -11988,7 +11988,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->bubbleblowup = 0; player->bubbleblowup = 0;
player->bubblecool = 0; player->bubblecool = 0;
player->pflags &= ~PF_HOLDREADY; player->itemflags &= ~IF_HOLDREADY;
player->itemamount--; player->itemamount--;
} }
} }
@ -12001,9 +12001,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->bubbleblowup--; player->bubbleblowup--;
if (player->bubblecool) if (player->bubblecool)
player->pflags &= ~PF_HOLDREADY; player->itemflags &= ~IF_HOLDREADY;
else else
player->pflags |= PF_HOLDREADY; player->itemflags |= IF_HOLDREADY;
} }
} }
break; break;
@ -12027,7 +12027,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
flamemax = player->flamelength + TICRATE; // TICRATE leniency period, but we block most effects at flamelength 0 down below flamemax = player->flamelength + TICRATE; // TICRATE leniency period, but we block most effects at flamelength 0 down below
if ((cmd->buttons & BT_ATTACK) && (player->pflags & PF_HOLDREADY)) if ((cmd->buttons & BT_ATTACK) && (player->itemflags & IF_HOLDREADY))
{ {
const INT32 incr = (gametyperules & GTR_CLOSERPLAYERS) ? 4 : 2; const INT32 incr = (gametyperules & GTR_CLOSERPLAYERS) ? 4 : 2;
player->flamemeter += incr; player->flamemeter += incr;
@ -12069,13 +12069,13 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->flamemeter = 0; player->flamemeter = 0;
player->flamelength = 0; player->flamelength = 0;
player->pflags &= ~PF_HOLDREADY; player->itemflags &= ~IF_HOLDREADY;
player->itemamount--; player->itemamount--;
} }
} }
else else
{ {
player->pflags |= PF_HOLDREADY; player->itemflags |= IF_HOLDREADY;
if (!(gametyperules & GTR_CLOSERPLAYERS) || leveltime % 6 == 0) if (!(gametyperules & GTR_CLOSERPLAYERS) || leveltime % 6 == 0)
{ {
@ -12145,12 +12145,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_SetTarget(&player->mo->hnext, mo); P_SetTarget(&player->mo->hnext, mo);
} }
} }
else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->pflags & PF_ITEMOUT)) // Sink thrown else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->itemflags & IF_ITEMOUT)) // Sink thrown
{ {
K_ThrowKartItem(player, false, MT_SINK, 1, 2, 0); K_ThrowKartItem(player, false, MT_SINK, 1, 2, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->itemamount--; player->itemamount--;
player->pflags &= ~PF_ITEMOUT; player->itemflags &= ~IF_ITEMOUT;
K_UpdateHnextList(player, true); K_UpdateHnextList(player, true);
} }
break; break;
@ -12185,7 +12185,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
// No more! // No more!
if (!player->itemamount) if (!player->itemamount)
{ {
player->pflags &= ~PF_ITEMOUT; player->itemflags &= ~IF_ITEMOUT;
player->itemtype = KITEM_NONE; player->itemtype = KITEM_NONE;
} }
@ -12293,7 +12293,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->tumbleHeight = 30; // Base tumble bounce height player->tumbleHeight = 30; // Base tumble bounce height
player->trickpanel = TRICKSTATE_NONE; player->trickpanel = TRICKSTATE_NONE;
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
if (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)) if (player->itemflags & (IF_ITEMOUT|IF_EGGMANOUT))
{ {
//K_PopPlayerShield(player); // shield is just being yeeted, don't pop //K_PopPlayerShield(player); // shield is just being yeeted, don't pop
K_DropHnextList(player); K_DropHnextList(player);
@ -13053,4 +13053,40 @@ void K_SetTireGrease(player_t *player, tic_t tics)
player->tiregrease = tics; player->tiregrease = tics;
} }
// somewhat sensible check for HUD sounds in a post-bot-takeover world
boolean K_IsPlayingDisplayPlayer(player_t *player)
{
return P_IsDisplayPlayer(player) && (!player->exiting);
}
boolean K_PlayerCanPunt(player_t *player)
{
if (player->invincibilitytimer > 0)
{
return true;
}
if (player->flamedash > 0 && player->itemtype == KITEM_FLAMESHIELD)
{
return true;
}
if (player->growshrinktimer > 0)
{
return true;
}
if (player->tripwirePass >= TRIPWIRE_BLASTER && player->speed >= 2 * K_GetKartSpeed(player, false, false))
{
return true;
}
return false;
}
void K_MakeObjectReappear(mobj_t *mo)
{
(!P_MobjWasRemoved(mo->punt_ref) ? mo->punt_ref : mo)->reappear = leveltime + (30*TICRATE);
}
//} //}

View file

@ -245,6 +245,11 @@ boolean K_isPlayerInSpecialState(player_t *p);
void K_SetTireGrease(player_t *player, tic_t tics); void K_SetTireGrease(player_t *player, tic_t tics);
boolean K_IsPlayingDisplayPlayer(player_t *player);
boolean K_PlayerCanPunt(player_t *player);
void K_MakeObjectReappear(mobj_t *mo);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View file

@ -979,6 +979,7 @@ extern consvar_t cv_dummyprofilename;
extern consvar_t cv_dummyprofileplayername; extern consvar_t cv_dummyprofileplayername;
extern consvar_t cv_dummyprofilekickstart; extern consvar_t cv_dummyprofilekickstart;
extern consvar_t cv_dummyprofileautoroulette; extern consvar_t cv_dummyprofileautoroulette;
extern consvar_t cv_dummyprofilelitesteer;
extern consvar_t cv_dummyprofilerumble; extern consvar_t cv_dummyprofilerumble;
void M_ResetOptions(void); void M_ResetOptions(void);

View file

@ -141,7 +141,7 @@ void Obj_UpdateRingShooterFace(mobj_t *part);
/* Follower Audience */ /* Follower Audience */
void Obj_AudienceInit(mobj_t * mobj, mapthing_t *mthing, INT32 followerpick); void Obj_AudienceInit(mobj_t * mobj, mapthing_t *mthing, INT32 followerpick);
void Obj_AudienceThink(mobj_t * mobj, boolean focusonplayer); void Obj_AudienceThink(mobj_t * mobj, boolean focusonplayer, boolean checkdeathpit);
/* Random Item Boxes */ /* Random Item Boxes */
void Obj_RandomItemVisuals(mobj_t *mobj); void Obj_RandomItemVisuals(mobj_t *mobj);

View file

@ -72,6 +72,7 @@ profile_t* PR_MakeProfile(
new->followercolor = fcol; new->followercolor = fcol;
new->kickstartaccel = false; new->kickstartaccel = false;
new->autoroulette = false; new->autoroulette = false;
new->litesteer = true;
// Copy from gamecontrol directly as we'll be setting controls up directly in the profile. // Copy from gamecontrol directly as we'll be setting controls up directly in the profile.
memcpy(new->controls, controlarray, sizeof(new->controls)); memcpy(new->controls, controlarray, sizeof(new->controls));
@ -89,6 +90,7 @@ profile_t* PR_MakeProfileFromPlayer(const char *prname, const char *pname, const
// Player bound cvars: // Player bound cvars:
new->kickstartaccel = cv_kickstartaccel[pnum].value; new->kickstartaccel = cv_kickstartaccel[pnum].value;
new->autoroulette = cv_autoroulette[pnum].value; new->autoroulette = cv_autoroulette[pnum].value;
new->litesteer = cv_litesteer[pnum].value;
new->rumble = cv_rumble[pnum].value; new->rumble = cv_rumble[pnum].value;
return new; return new;
@ -276,6 +278,7 @@ void PR_SaveProfiles(void)
// Consvars. // Consvars.
WRITEUINT8(save.p, profilesList[i]->kickstartaccel); WRITEUINT8(save.p, profilesList[i]->kickstartaccel);
WRITEUINT8(save.p, profilesList[i]->autoroulette); WRITEUINT8(save.p, profilesList[i]->autoroulette);
WRITEUINT8(save.p, profilesList[i]->litesteer);
WRITEUINT8(save.p, profilesList[i]->rumble); WRITEUINT8(save.p, profilesList[i]->rumble);
// Controls. // Controls.
@ -425,6 +428,17 @@ void PR_LoadProfiles(void)
profilesList[i]->autoroulette = (boolean)READUINT8(save.p); profilesList[i]->autoroulette = (boolean)READUINT8(save.p);
} }
// 7->8, add litesteer
if (version < 8)
{
profilesList[i]->litesteer = true;
}
else
{
profilesList[i]->litesteer = (boolean)READUINT8(save.p);
}
if (version < 4) if (version < 4)
{ {
profilesList[i]->rumble = true; profilesList[i]->rumble = true;
@ -478,6 +492,7 @@ static void PR_ApplyProfile_Settings(profile_t *p, UINT8 playernum)
// toggles // toggles
CV_StealthSetValue(&cv_kickstartaccel[playernum], p->kickstartaccel); CV_StealthSetValue(&cv_kickstartaccel[playernum], p->kickstartaccel);
CV_StealthSetValue(&cv_autoroulette[playernum], p->autoroulette); CV_StealthSetValue(&cv_autoroulette[playernum], p->autoroulette);
CV_StealthSetValue(&cv_litesteer[playernum], p->litesteer);
// set controls... // set controls...
memcpy(&gamecontrol[playernum], p->controls, sizeof(gamecontroldefault)); memcpy(&gamecontrol[playernum], p->controls, sizeof(gamecontroldefault));

View file

@ -31,7 +31,7 @@ extern "C" {
#define SKINNAMESIZE 16 #define SKINNAMESIZE 16
#define PROFILENAMELEN 6 #define PROFILENAMELEN 6
#define PROFILEVER 7 #define PROFILEVER 8
#define MAXPROFILES 16 #define MAXPROFILES 16
#define PROFILESFILE "ringprofiles.prf" #define PROFILESFILE "ringprofiles.prf"
#define PROFILE_GUEST 0 #define PROFILE_GUEST 0
@ -75,6 +75,7 @@ struct profile_t
// @TODO: List all of those // @TODO: List all of those
boolean kickstartaccel; // cv_kickstartaccel boolean kickstartaccel; // cv_kickstartaccel
boolean autoroulette; // cv_autoroulette boolean autoroulette; // cv_autoroulette
boolean litesteer; // cv_litesteer
boolean rumble; // cv_rumble boolean rumble; // cv_rumble
// Finally, control data itself // Finally, control data itself

View file

@ -297,7 +297,7 @@ void K_DoIngameRespawn(player_t *player)
player->respawn.init = true; player->respawn.init = true;
player->respawn.fast = true; player->respawn.fast = true;
player->respawn.returnspeed = 0; player->respawn.returnspeed = 0;
player->laps = player->lastsafelap; player->laps = min(player->laps, player->lastsafelap);
player->respawn.airtimer = player->airtime; player->respawn.airtimer = player->airtime;
player->respawn.truedeath = !!(player->pflags & PF_FAULT); player->respawn.truedeath = !!(player->pflags & PF_FAULT);

View file

@ -1622,7 +1622,7 @@ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd)
// If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item. // If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item.
// I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think. // I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think.
// Finally, if you get past this check, now you can actually start calculating what item you get. // Finally, if you get past this check, now you can actually start calculating what item you get.
if (confirmItem == true && (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT|PF_USERINGS)) == 0) if (confirmItem == true && (player->itemflags & (IF_ITEMOUT|IF_EGGMANOUT|IF_USERINGS)) == 0)
{ {
if (roulette->eggman == true) if (roulette->eggman == true)
{ {
@ -1633,7 +1633,7 @@ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd)
//player->karthud[khud_itemblinkmode] = 1; //player->karthud[khud_itemblinkmode] = 1;
//player->karthud[khud_rouletteoffset] = K_GetRouletteOffset(roulette, FRACUNIT); //player->karthud[khud_rouletteoffset] = K_GetRouletteOffset(roulette, FRACUNIT);
if (P_IsDisplayPlayer(player)) if (K_IsPlayingDisplayPlayer(player))
{ {
S_StartSound(NULL, sfx_itrole); S_StartSound(NULL, sfx_itrole);
} }
@ -1680,7 +1680,7 @@ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd)
player->karthud[khud_itemblinkmode] = 0; player->karthud[khud_itemblinkmode] = 0;
player->karthud[khud_rouletteoffset] = K_GetRouletteOffset(roulette, FRACUNIT); player->karthud[khud_rouletteoffset] = K_GetRouletteOffset(roulette, FRACUNIT);
if (P_IsDisplayPlayer(player)) if (K_IsPlayingDisplayPlayer(player))
{ {
if (roulette->ringbox) if (roulette->ringbox)
{ {
@ -1714,7 +1714,7 @@ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd)
// This makes the roulette produce the random noises. // This makes the roulette produce the random noises.
roulette->sound = (roulette->sound + 1) % 8; roulette->sound = (roulette->sound + 1) % 8;
if (P_IsDisplayPlayer(player)) if (K_IsPlayingDisplayPlayer(player))
{ {
if (roulette->ringbox) if (roulette->ringbox)
S_StartSound(NULL, sfx_s240); S_StartSound(NULL, sfx_s240);

View file

@ -106,7 +106,9 @@ enum mobj_e {
mobj_tid, mobj_tid,
mobj_special, mobj_special,
mobj_args, mobj_args,
mobj_stringargs mobj_stringargs,
mobj_reappear,
mobj_punt_ref,
}; };
static const char *const mobj_opt[] = { static const char *const mobj_opt[] = {
@ -194,6 +196,8 @@ static const char *const mobj_opt[] = {
"special", "special",
"args", "args",
"stringargs", "stringargs",
"reappear",
"punt_ref",
NULL}; NULL};
#define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field])
@ -493,6 +497,17 @@ static int mobj_get(lua_State *L)
case mobj_stringargs: case mobj_stringargs:
LUA_PushUserdata(L, mo->thing_stringargs, META_THINGSTRINGARGS); LUA_PushUserdata(L, mo->thing_stringargs, META_THINGSTRINGARGS);
break; break;
case mobj_reappear:
lua_pushinteger(L, mo->reappear);
break;
case mobj_punt_ref:
if (mo->punt_ref && P_MobjWasRemoved(mo->punt_ref))
{ // don't put invalid mobj back into Lua.
P_SetTarget(&mo->punt_ref, NULL);
return 0;
}
LUA_PushUserdata(L, mo->punt_ref, META_MOBJ);
break;
default: // extra custom variables in Lua memory default: // extra custom variables in Lua memory
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1)); I_Assert(lua_istable(L, -1));
@ -883,6 +898,18 @@ static int mobj_set(lua_State *L)
return NOSET; return NOSET;
case mobj_stringargs: case mobj_stringargs:
return NOSET; return NOSET;
case mobj_reappear:
mo->reappear = luaL_checkinteger(L, 3);
break;
case mobj_punt_ref:
if (lua_isnil(L, 3))
P_SetTarget(&mo->punt_ref, NULL);
else
{
mobj_t *punt_ref = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
P_SetTarget(&mo->punt_ref, punt_ref);
}
break;
default: default:
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1)); I_Assert(lua_istable(L, -1));

View file

@ -263,6 +263,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->ringboxdelay); lua_pushinteger(L, plr->ringboxdelay);
else if (fastcmp(field,"ringboxaward")) else if (fastcmp(field,"ringboxaward"))
lua_pushinteger(L, plr->ringboxaward); lua_pushinteger(L, plr->ringboxaward);
else if (fastcmp(field,"itemflags"))
lua_pushinteger(L, plr->itemflags);
else if (fastcmp(field,"drift")) else if (fastcmp(field,"drift"))
lua_pushinteger(L, plr->drift); lua_pushinteger(L, plr->drift);
else if (fastcmp(field,"driftcharge")) else if (fastcmp(field,"driftcharge"))
@ -757,6 +759,8 @@ static int player_set(lua_State *L)
plr->ringboxdelay = luaL_checkinteger(L, 3); plr->ringboxdelay = luaL_checkinteger(L, 3);
else if (fastcmp(field,"ringboxaward")) else if (fastcmp(field,"ringboxaward"))
plr->ringboxaward = luaL_checkinteger(L, 3); plr->ringboxaward = luaL_checkinteger(L, 3);
else if (fastcmp(field,"itemflags"))
plr->itemflags = luaL_checkinteger(L, 3);
else if (fastcmp(field,"drift")) else if (fastcmp(field,"drift"))
plr->drift = luaL_checkinteger(L, 3); plr->drift = luaL_checkinteger(L, 3);
else if (fastcmp(field,"driftcharge")) else if (fastcmp(field,"driftcharge"))

View file

@ -89,6 +89,7 @@ static void M_StartEditProfile(INT32 c)
CV_StealthSet(&cv_dummyprofileplayername, optionsmenu.profile->playername); CV_StealthSet(&cv_dummyprofileplayername, optionsmenu.profile->playername);
CV_StealthSetValue(&cv_dummyprofilekickstart, optionsmenu.profile->kickstartaccel); CV_StealthSetValue(&cv_dummyprofilekickstart, optionsmenu.profile->kickstartaccel);
CV_StealthSetValue(&cv_dummyprofileautoroulette, optionsmenu.profile->autoroulette); CV_StealthSetValue(&cv_dummyprofileautoroulette, optionsmenu.profile->autoroulette);
CV_StealthSetValue(&cv_dummyprofilelitesteer, optionsmenu.profile->litesteer);
CV_StealthSetValue(&cv_dummyprofilerumble, optionsmenu.profile->rumble); CV_StealthSetValue(&cv_dummyprofilerumble, optionsmenu.profile->rumble);
} }
else else
@ -97,6 +98,7 @@ static void M_StartEditProfile(INT32 c)
CV_StealthSet(&cv_dummyprofileplayername, ""); CV_StealthSet(&cv_dummyprofileplayername, "");
CV_StealthSetValue(&cv_dummyprofilekickstart, 0); // off CV_StealthSetValue(&cv_dummyprofilekickstart, 0); // off
CV_StealthSetValue(&cv_dummyprofileautoroulette, 0); // off CV_StealthSetValue(&cv_dummyprofileautoroulette, 0); // off
CV_StealthSetValue(&cv_dummyprofilelitesteer, 1); // on
CV_StealthSetValue(&cv_dummyprofilerumble, 1); // on CV_StealthSetValue(&cv_dummyprofilerumble, 1); // on
} }

View file

@ -94,6 +94,9 @@ menuitem_t OPTIONS_ProfileControls[] = {
{IT_CONTROL | IT_CVAR, "AUTO ROULETTE", "Item roulette auto-stops on a random result.", {IT_CONTROL | IT_CVAR, "AUTO ROULETTE", "Item roulette auto-stops on a random result.",
NULL, {.cvar = &cv_dummyprofileautoroulette}, 0, 0}, NULL, {.cvar = &cv_dummyprofileautoroulette}, 0, 0},
{IT_CONTROL | IT_CVAR, "LITE STEER", "Hold DOWN on d-pad/keyboard for shallow turns.",
NULL, {.cvar = &cv_dummyprofilelitesteer}, 0, 0},
{IT_HEADER, "EXTRA", "", {IT_HEADER, "EXTRA", "",
NULL, {NULL}, 0, 0}, NULL, {NULL}, 0, 0},
@ -191,6 +194,7 @@ static void M_ProfileControlSaveResponse(INT32 choice)
// Save the profile // Save the profile
optionsmenu.profile->kickstartaccel = cv_dummyprofilekickstart.value; optionsmenu.profile->kickstartaccel = cv_dummyprofilekickstart.value;
optionsmenu.profile->autoroulette = cv_dummyprofileautoroulette.value; optionsmenu.profile->autoroulette = cv_dummyprofileautoroulette.value;
optionsmenu.profile->litesteer = cv_dummyprofilelitesteer.value;
optionsmenu.profile->rumble = cv_dummyprofilerumble.value; optionsmenu.profile->rumble = cv_dummyprofilerumble.value;
memcpy(&optionsmenu.profile->controls, optionsmenu.tempcontrols, sizeof(gamecontroldefault)); memcpy(&optionsmenu.profile->controls, optionsmenu.tempcontrols, sizeof(gamecontroldefault));
@ -201,6 +205,7 @@ static void M_ProfileControlSaveResponse(INT32 choice)
memcpy(&gamecontrol[belongsto], optionsmenu.tempcontrols, sizeof(gamecontroldefault)); memcpy(&gamecontrol[belongsto], optionsmenu.tempcontrols, sizeof(gamecontroldefault));
CV_SetValue(&cv_kickstartaccel[belongsto], cv_dummyprofilekickstart.value); CV_SetValue(&cv_kickstartaccel[belongsto], cv_dummyprofilekickstart.value);
CV_SetValue(&cv_autoroulette[belongsto], cv_dummyprofileautoroulette.value); CV_SetValue(&cv_autoroulette[belongsto], cv_dummyprofileautoroulette.value);
CV_SetValue(&cv_litesteer[belongsto], cv_dummyprofilelitesteer.value);
CV_SetValue(&cv_rumble[belongsto], cv_dummyprofilerumble.value); CV_SetValue(&cv_rumble[belongsto], cv_dummyprofilerumble.value);
} }

View file

@ -29,6 +29,7 @@ Obj_AudienceInit
mapthing_t *mthing, mapthing_t *mthing,
INT32 followerpick) INT32 followerpick)
{ {
const boolean ourchoiceofvisuals = (followerpick < 0 || followerpick > numfollowers);
INT16 *reflist = NULL; INT16 *reflist = NULL;
INT16 tempreflist[MAXHEADERFOLLOWERS]; INT16 tempreflist[MAXHEADERFOLLOWERS];
UINT8 numref = 0; UINT8 numref = 0;
@ -36,9 +37,9 @@ Obj_AudienceInit
audience_mainstate(mobj) = S_NULL; audience_mainstate(mobj) = S_NULL;
// Pick follower // Pick follower
if (mthing != NULL) if (ourchoiceofvisuals == true)
{ {
if (mthing->thing_stringargs[0] != NULL) if (mthing != NULL && mthing->thing_stringargs[0] != NULL)
{ {
// From mapthing // From mapthing
char *stringcopy = Z_StrDup(mthing->thing_stringargs[0]); char *stringcopy = Z_StrDup(mthing->thing_stringargs[0]);
@ -56,11 +57,23 @@ Obj_AudienceInit
*c = ' '; *c = ' ';
} }
if ((tempreflist[numref++] = K_FollowerAvailable(tok)) == -1) if ((tempreflist[numref] = K_FollowerAvailable(tok)) == -1)
{
CONS_Alert(CONS_WARNING, "Mapthing %s: Follower \"%s\" is invalid!\n", sizeu1(mthing-mapthings), tok); CONS_Alert(CONS_WARNING, "Mapthing %s: Follower \"%s\" is invalid!\n", sizeu1(mthing-mapthings), tok);
}
else
numref++;
tok = strtok(NULL, " ,"); tok = strtok(NULL, " ,");
} }
if (!numref)
{
// This is the one thing a user should definitely be told about.
CONS_Alert(CONS_WARNING, "Mapthing %s: Follower audience has no valid followers to pick from!\n", sizeu1(mthing-mapthings));
// DO NOT RETURN HERE
}
Z_Free(stringcopy); Z_Free(stringcopy);
reflist = tempreflist; reflist = tempreflist;
@ -81,8 +94,8 @@ Obj_AudienceInit
if (!numref || !reflist) if (!numref || !reflist)
{ {
// This is the one thing a user should definitely be told about. // Clean up after ourselves.
CONS_Alert(CONS_WARNING, "Mapthing %s: Follower audience has no valid followers to pick from!\n", sizeu1(mthing-mapthings)); P_RemoveMobj(mobj);
return; return;
} }
@ -137,11 +150,11 @@ Obj_AudienceInit
} }
// Handle colors // Handle colors
if (mthing != NULL) if (ourchoiceofvisuals == true)
{ {
UINT16 colorpick = SKINCOLOR_NONE; UINT16 colorpick = SKINCOLOR_NONE;
if (mthing->thing_stringargs[1] != NULL) if (mthing != NULL && mthing->thing_stringargs[1] != NULL)
{ {
if (!stricmp("Random", mthing->thing_stringargs[1])) if (!stricmp("Random", mthing->thing_stringargs[1]))
{ {
@ -189,8 +202,17 @@ Obj_AudienceInit
void void
Obj_AudienceThink Obj_AudienceThink
( mobj_t * mobj, ( mobj_t * mobj,
boolean focusonplayer) boolean focusonplayer,
boolean checkdeathpit)
{ {
boolean landed = false;
if (mobj->fuse && mobj->fuse < (TICRATE/2))
{
mobj->renderflags ^= RF_DONTDRAW;
return; // no jumping when you hit the floor, your gravity is weird
}
if (audience_mainstate(mobj) == S_NULL) if (audience_mainstate(mobj) == S_NULL)
{ {
// Uninitialised, don't do anything funny. // Uninitialised, don't do anything funny.
@ -315,15 +337,23 @@ Obj_AudienceThink
} }
else if (mobj->flags2 & MF2_OBJECTFLIP) else if (mobj->flags2 & MF2_OBJECTFLIP)
{ {
if (mobj->z + mobj->height >= mobj->ceilingz) landed = (mobj->z + mobj->height >= mobj->ceilingz);
{
mobj->momz = -audience_bobamp(mobj);
P_SetMobjState(mobj, audience_mainstate(mobj));
} }
} else
else if (mobj->z <= mobj->floorz)
{ {
mobj->momz = audience_bobamp(mobj); landed = (mobj->z <= mobj->floorz);
}
if (landed == true)
{
if (checkdeathpit && P_CheckDeathPitCollide(mobj))
{
P_RemoveMobj(mobj);
return;
}
mobj->momx = mobj->momy = 0;
mobj->momz = P_MobjFlip(mobj)*audience_bobamp(mobj);
P_SetMobjState(mobj, audience_mainstate(mobj)); P_SetMobjState(mobj, audience_mainstate(mobj));
} }
} }

View file

@ -765,7 +765,7 @@ mobj_t *Obj_SuperFlickyOwner(const mobj_t* mobj)
{ {
const Flicky* x = static_cast<const Flicky*>(mobj); const Flicky* x = static_cast<const Flicky*>(mobj);
return x->source(); return x->valid() ? x->source() : nullptr;
} }
boolean Obj_IsSuperFlickyWhippable(const mobj_t* mobj) boolean Obj_IsSuperFlickyWhippable(const mobj_t* mobj)

View file

@ -1017,7 +1017,6 @@ static mobj_t *SearchMarioNode(msecnode_t *node)
} }
// Ignore popped monitors, too. // Ignore popped monitors, too.
if (node->m_thing->health == 0 // this only really applies for monitors if (node->m_thing->health == 0 // this only really applies for monitors
|| (!(node->m_thing->flags & MF_MONITOR) && (mobjinfo[node->m_thing->type].flags & MF_MONITOR)) // gold monitor support
|| (node->m_thing->type == MT_RANDOMITEM)) || (node->m_thing->type == MT_RANDOMITEM))
continue; continue;
// Okay, we found something valid. // Okay, we found something valid.
@ -2344,7 +2343,6 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
fixed_t topheight = *rover->topheight; fixed_t topheight = *rover->topheight;
mariothink_t *block; mariothink_t *block;
mobj_t *thing; mobj_t *thing;
fixed_t oldx = 0, oldy = 0, oldz = 0;
I_Assert(puncher != NULL); I_Assert(puncher != NULL);
I_Assert(puncher->player != NULL); I_Assert(puncher->player != NULL);
@ -2362,7 +2360,6 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
S_StartSound(puncher, sfx_mario1); // "Thunk!" sound - puncher is "close enough". S_StartSound(puncher, sfx_mario1); // "Thunk!" sound - puncher is "close enough".
else // Found something! else // Found something!
{ {
const boolean itsamonitor = (thing->flags & MF_MONITOR) == MF_MONITOR;
// create and initialize new elevator thinker // create and initialize new elevator thinker
block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL); block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL);
@ -2383,13 +2380,6 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
R_CreateInterpolator_SectorPlane(&block->thinker, roversec, false); R_CreateInterpolator_SectorPlane(&block->thinker, roversec, false);
R_CreateInterpolator_SectorPlane(&block->thinker, roversec, true); R_CreateInterpolator_SectorPlane(&block->thinker, roversec, true);
if (itsamonitor)
{
oldx = thing->x;
oldy = thing->y;
oldz = thing->z;
}
P_UnsetThingPosition(thing); P_UnsetThingPosition(thing);
thing->x = thing->old_x = sector->soundorg.x; thing->x = thing->old_x = sector->soundorg.x;
thing->y = thing->old_y = sector->soundorg.y; thing->y = thing->old_y = sector->soundorg.y;
@ -2410,16 +2400,5 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
// "Powerup rise" sound // "Powerup rise" sound
S_StartSound(puncher, sfx_mario9); // Puncher is "close enough" S_StartSound(puncher, sfx_mario9); // Puncher is "close enough"
} }
if (itsamonitor && thing)
{
P_UnsetThingPosition(thing);
thing->x = thing->old_x = oldx;
thing->y = thing->old_y = oldy;
thing->z = thing->old_z = oldz;
thing->momx = 1;
thing->momy = 1;
P_SetThingPosition(thing);
}
} }
} }

View file

@ -43,6 +43,7 @@
#include "k_hitlag.h" #include "k_hitlag.h"
#include "acs/interface.h" #include "acs/interface.h"
#include "k_powerup.h" #include "k_powerup.h"
#include "k_collide.h"
// CTF player names // CTF player names
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : "" #define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
@ -153,7 +154,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
if (player->itemRoulette.active == true if (player->itemRoulette.active == true
|| player->ringboxdelay > 0 || player->ringboxdelay > 0
|| (weapon != 3 && player->itemamount) || (weapon != 3 && player->itemamount)
|| (player->pflags & PF_ITEMOUT)) || (player->itemflags & IF_ITEMOUT))
return false; return false;
if (weapon == 3 && K_GetShieldFromItem(player->itemtype) != KSHIELD_NONE) if (weapon == 3 && K_GetShieldFromItem(player->itemtype) != KSHIELD_NONE)
@ -1537,7 +1538,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->momx = target->momy = target->momz = 0; target->momx = target->momy = target->momz = 0;
// SRB2kart // SRB2kart
if (target->type != MT_PLAYER && !(target->flags & MF_MONITOR) if (target->type != MT_PLAYER
&& !(target->type == MT_ORBINAUT || target->type == MT_ORBINAUT_SHIELD && !(target->type == MT_ORBINAUT || target->type == MT_ORBINAUT_SHIELD
|| target->type == MT_JAWZ || target->type == MT_JAWZ_SHIELD || target->type == MT_JAWZ || target->type == MT_JAWZ_SHIELD
|| target->type == MT_BANANA || target->type == MT_BANANA_SHIELD || target->type == MT_BANANA || target->type == MT_BANANA_SHIELD
@ -1577,10 +1578,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
// I wish I knew a better way to do this // I wish I knew a better way to do this
if (target->target && target->target->player && target->target->player->mo) if (target->target && target->target->player && target->target->player->mo)
{ {
if ((target->target->player->pflags & PF_EGGMANOUT) && target->type == MT_EGGMANITEM_SHIELD) if ((target->target->player->itemflags & IF_EGGMANOUT) && target->type == MT_EGGMANITEM_SHIELD)
target->target->player->pflags &= ~PF_EGGMANOUT; target->target->player->itemflags &= ~IF_EGGMANOUT;
if (target->target->player->pflags & PF_ITEMOUT) if (target->target->player->itemflags & IF_ITEMOUT)
{ {
if ((target->type == MT_BANANA_SHIELD && target->target->player->itemtype == KITEM_BANANA) // trail items if ((target->type == MT_BANANA_SHIELD && target->target->player->itemtype == KITEM_BANANA) // trail items
|| (target->type == MT_SSMINE_SHIELD && target->target->player->itemtype == KITEM_MINE) || (target->type == MT_SSMINE_SHIELD && target->target->player->itemtype == KITEM_MINE)
@ -1608,7 +1609,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
} }
if (!target->target->player->itemamount) if (!target->target->player->itemamount)
target->target->player->pflags &= ~PF_ITEMOUT; target->target->player->itemflags &= ~IF_ITEMOUT;
if (target->target->hnext == target) if (target->target->hnext == target)
P_SetTarget(&target->target->hnext, NULL); P_SetTarget(&target->target->hnext, NULL);
@ -1630,7 +1631,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
// if killed by a player // if killed by a player
if (source && source->player) if (source && source->player)
{ {
if (target->flags & MF_MONITOR || target->type == MT_RANDOMITEM) if (target->type == MT_RANDOMITEM)
{ {
P_SetTarget(&target->target, source); P_SetTarget(&target->target, source);
@ -2103,6 +2104,67 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
cur = cur->hnext; cur = cur->hnext;
} }
// Spawn three Followers (if possible)
if (mapheaderinfo[gamemap-1]->numFollowers)
{
dir = FixedAngle(P_RandomKey(PR_RANDOMAUDIENCE, 360)*FRACUNIT);
const fixed_t launchmomentum = 7 * mapobjectscale;
const fixed_t jaggedness = 4;
angle_t launchangle;
UINT8 i;
for (i = 0; i < 6; i++, dir += ANG60)
{
cur = P_SpawnMobj(
target->x, target->y,
target->z + target->height/2,
MT_RANDOMAUDIENCE
);
// We check if you have some horrible Lua
if (P_MobjWasRemoved(cur))
break;
Obj_AudienceInit(cur, NULL, -1);
// We check again if the list is invalid
if (P_MobjWasRemoved(cur))
break;
cur->hitlag = target->hitlag;
cur->destscale /= 2;
P_SetScale(cur, cur->destscale/TICRATE);
cur->scalespeed = cur->destscale/TICRATE;
cur->z -= cur->height/2;
// flags are NOT from the target - just in case it's just been placed on the ceiling as a gimmick
cur->flags2 |= (source->flags2 & MF2_OBJECTFLIP);
cur->eflags |= (source->eflags & MFE_VERTICALFLIP);
launchangle = FixedAngle(
(
(
P_RandomRange(PR_RANDOMAUDIENCE, 12/jaggedness, 24/jaggedness) * jaggedness
) + (i & 1)*16
) * FRACUNIT
);
cur->momz = P_MobjFlip(target) // THIS one uses target!
* P_ReturnThrustY(cur, launchangle, launchmomentum);
cur->angle = dir;
P_InstaThrust(
cur, cur->angle,
P_ReturnThrustX(cur, launchangle, launchmomentum)
);
cur->fuse = (3*TICRATE)/2;
cur->flags |= MF_NOCLIPHEIGHT;
}
}
S_StartSound(target, sfx_mbs60); S_StartSound(target, sfx_mbs60);
P_AddBrokenPrison(target, inflictor, source); P_AddBrokenPrison(target, inflictor, source);
@ -2876,6 +2938,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
invincible = false; invincible = false;
} }
// TODO: doing this from P_DamageMobj limits punting to objects that damage the player.
// And it may be kind of yucky.
// But this is easier than accounting for every condition in PIT_CheckThing!
if (inflictor && K_PuntCollide(inflictor, target))
{
return false;
}
if (invincible && type != DMG_STUMBLE && type != DMG_WHUMBLE) if (invincible && type != DMG_STUMBLE && type != DMG_WHUMBLE)
{ {
const INT32 oldHitlag = target->hitlag; const INT32 oldHitlag = target->hitlag;

View file

@ -595,6 +595,8 @@ mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator);
void P_DeleteMobjStringArgs(mobj_t *mobj); void P_DeleteMobjStringArgs(mobj_t *mobj);
tic_t P_MobjIsReappearing(const mobj_t *mobj);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View file

@ -528,6 +528,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
static BlockItReturn_t PIT_CheckThing(mobj_t *thing) static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
{ {
fixed_t blockdist; fixed_t blockdist;
boolean damage = false;
if (tm.thing == NULL || P_MobjWasRemoved(tm.thing) == true) if (tm.thing == NULL || P_MobjWasRemoved(tm.thing) == true)
return BMIT_STOP; // func just popped our tm.thing, cannot continue. return BMIT_STOP; // func just popped our tm.thing, cannot continue.
@ -552,6 +553,10 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
if ((thing->flags & MF_NOCLIPTHING) || !(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE|MF_SPRING))) if ((thing->flags & MF_NOCLIPTHING) || !(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE|MF_SPRING)))
return BMIT_CONTINUE; return BMIT_CONTINUE;
// Thing is respawning
if (P_MobjIsReappearing(thing))
return BMIT_CONTINUE;
blockdist = thing->radius + tm.thing->radius; blockdist = thing->radius + tm.thing->radius;
if (abs(thing->x - tm.x) >= blockdist || abs(thing->y - tm.y) >= blockdist) if (abs(thing->x - tm.x) >= blockdist || abs(thing->y - tm.y) >= blockdist)
@ -684,10 +689,12 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
if (P_DamageMobj(tm.thing, thing, thing, 1, damagetype) && (damagetype = (thing->info->mass>>8))) if (P_DamageMobj(tm.thing, thing, thing, 1, damagetype) && (damagetype = (thing->info->mass>>8)))
S_StartSound(thing, damagetype); S_StartSound(thing, damagetype);
}
if (P_MobjWasRemoved(tm.thing) || P_MobjWasRemoved(thing)) if (P_MobjWasRemoved(tm.thing) || P_MobjWasRemoved(thing))
return BMIT_CONTINUE; return BMIT_CONTINUE;
damage = true;
}
} }
else if (tm.thing->flags & MF_PAIN && thing->player) else if (tm.thing->flags & MF_PAIN && thing->player)
{ // Painful thing splats player in the face { // Painful thing splats player in the face
@ -702,10 +709,12 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
if (P_DamageMobj(thing, tm.thing, tm.thing, 1, damagetype) && (damagetype = (tm.thing->info->mass>>8))) if (P_DamageMobj(thing, tm.thing, tm.thing, 1, damagetype) && (damagetype = (tm.thing->info->mass>>8)))
S_StartSound(tm.thing, damagetype); S_StartSound(tm.thing, damagetype);
}
if (P_MobjWasRemoved(tm.thing) || P_MobjWasRemoved(thing)) if (P_MobjWasRemoved(tm.thing) || P_MobjWasRemoved(thing))
return BMIT_CONTINUE; return BMIT_CONTINUE;
damage = true;
}
} }
// check for skulls slamming into things // check for skulls slamming into things
@ -1206,7 +1215,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
} }
// missiles can hit other things // missiles can hit other things
if (tm.thing->flags & MF_MISSILE) if ((tm.thing->flags & MF_MISSILE) && !damage) // if something was already damaged, don't run this
{ {
UINT8 damagetype = (tm.thing->info->mass ^ DMG_WOMBO); UINT8 damagetype = (tm.thing->info->mass ^ DMG_WOMBO);
@ -1616,7 +1625,10 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
if (tm.thing->z + tm.thing->height < thing->z) if (tm.thing->z + tm.thing->height < thing->z)
return BMIT_CONTINUE; // underneath return BMIT_CONTINUE; // underneath
if (!K_PuntCollide(thing, tm.thing))
{
K_KartSolidBounce(tm.thing, thing); K_KartSolidBounce(tm.thing, thing);
}
return BMIT_CONTINUE; return BMIT_CONTINUE;
} }
} }
@ -2331,7 +2343,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y, TryMoveResult_t *re
// Check things first, possibly picking things up. // Check things first, possibly picking things up.
// MF_NOCLIPTHING: used by camera to not be blocked by things // MF_NOCLIPTHING: used by camera to not be blocked by things
if (!(thing->flags & MF_NOCLIPTHING)) // Respawning things should also be intangible to other things
if (!(thing->flags & MF_NOCLIPTHING) && !P_MobjIsReappearing(thing))
{ {
for (bx = xl; bx <= xh; bx++) for (bx = xl; bx <= xh; bx++)
{ {
@ -4210,7 +4223,7 @@ static BlockItReturn_t PIT_RadiusAttack(mobj_t *thing)
if ((bombdamagetype & DMG_CANTHURTSELF) && bombsource && thing->type == bombsource->type) // ignore the type of guys who dropped the bomb (Jetty-Syn Bomber or Skim can bomb eachother, but not themselves.) if ((bombdamagetype & DMG_CANTHURTSELF) && bombsource && thing->type == bombsource->type) // ignore the type of guys who dropped the bomb (Jetty-Syn Bomber or Skim can bomb eachother, but not themselves.)
return BMIT_CONTINUE; return BMIT_CONTINUE;
if ((thing->flags & (MF_MONITOR|MF_SHOOTABLE)) != MF_SHOOTABLE) if ((thing->flags & MF_SHOOTABLE) != MF_SHOOTABLE)
return BMIT_CONTINUE; return BMIT_CONTINUE;
dx = abs(thing->x - bombspot->x); dx = abs(thing->x - bombspot->x);

View file

@ -1278,6 +1278,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
} }
break; break;
} }
case MT_RANDOMAUDIENCE:
if (mo->fuse)
gravityadd /= 10;
break;
default: default:
break; break;
} }
@ -1721,25 +1725,6 @@ void P_XYMovement(mobj_t *mo)
P_ExplodeMissile(mo); P_ExplodeMissile(mo);
return; return;
} }
else if (mo->flags & MF_STICKY)
{
S_StartSound(mo, mo->info->activesound);
mo->momx = mo->momy = mo->momz = 0; //Full stop!
mo->flags |= MF_NOGRAVITY; //Stay there!
mo->flags &= ~MF_STICKY; //Don't check again!
// Check for hit against sky here
if (P_CheckSkyHit(mo))
{
// Hack to prevent missiles exploding
// against the sky.
// Does not handle sky floors.
// Check frontsector as well.
P_RemoveMobj(mo);
return;
}
}
else else
{ {
boolean walltransferred = false; boolean walltransferred = false;
@ -5694,12 +5679,12 @@ static void P_FlameJetSceneryThink(mobj_t *mobj)
flame->angle = mobj->angle; flame->angle = mobj->angle;
if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side
flame->momz = mobj->fuse << (FRACBITS - 2); flame->momz = (mobj->fuse * mapobjectscale) / 4;
else else
flame->angle += FixedAngle(mobj->fuse<<FRACBITS); flame->angle += FixedAngle(mobj->fuse<<FRACBITS);
strength = 20*FRACUNIT; strength = 20*mapobjectscale;
strength -= ((20*FRACUNIT)/16)*mobj->movedir; strength -= ((20*mapobjectscale)/16)*mobj->movedir;
P_InstaThrust(flame, flame->angle, strength); P_InstaThrust(flame, flame->angle, strength);
S_StartSound(flame, sfx_fire); S_StartSound(flame, sfx_fire);
@ -5729,8 +5714,8 @@ static void P_VerticalFlameJetSceneryThink(mobj_t *mobj)
flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME);
strength = 20*FRACUNIT; strength = 20*mapobjectscale;
strength -= ((20*FRACUNIT)/16)*mobj->movedir; strength -= ((20*mapobjectscale)/16)*mobj->movedir;
// If deaf'd, the object spawns on the ceiling. // If deaf'd, the object spawns on the ceiling.
if (mobj->flags2 & MF2_AMBUSH) if (mobj->flags2 & MF2_AMBUSH)
@ -5744,7 +5729,7 @@ static void P_VerticalFlameJetSceneryThink(mobj_t *mobj)
P_SetMobjState(flame, S_FLAMEJETFLAME7); P_SetMobjState(flame, S_FLAMEJETFLAME7);
} }
P_InstaThrust(flame, mobj->angle, FixedDiv(mobj->fuse*FRACUNIT, 3*FRACUNIT)); P_InstaThrust(flame, mobj->angle, (mobj->fuse * mapobjectscale) / 3);
S_StartSound(flame, sfx_fire); S_StartSound(flame, sfx_fire);
} }
@ -6471,7 +6456,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
break; break;
} }
if (mobj->target->player->pflags & PF_ITEMOUT) if (mobj->target->player->itemflags & IF_ITEMOUT)
{ {
if (leveltime & 1) if (leveltime & 1)
mobj->tracer->renderflags &= ~RF_DONTDRAW; mobj->tracer->renderflags &= ~RF_DONTDRAW;
@ -7270,7 +7255,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->flags2 & MF2_STRONGBOX) if (mobj->flags2 & MF2_STRONGBOX)
{ {
Obj_AudienceThink(mobj, true); Obj_AudienceThink(mobj, true, false);
if (P_MobjWasRemoved(mobj)) if (P_MobjWasRemoved(mobj))
return false; return false;
} }
@ -10256,48 +10241,6 @@ static void K_MineExplodeThink(mobj_t *mobj)
} }
} }
static void P_MonitorFuseThink(mobj_t *mobj)
{
mobj_t *newmobj;
// Special case for ALL monitors.
// If a box's speed is nonzero, it's allowed to respawn as a WRM/SRM.
if (mobj->info->speed != 0 && (mobj->flags2 & (MF2_AMBUSH|MF2_STRONGBOX)))
{
mobjtype_t spawnchance[64];
INT32 numchoices = 0, i = 0;
// This define should make it a lot easier to organize and change monitor weights
#define SETMONITORCHANCES(type, strongboxamt, weakboxamt) \
for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) spawnchance[numchoices++] = type
// Type SRM WRM
SETMONITORCHANCES(MT_SNEAKERS_BOX, 0, 10); // Super Sneakers
SETMONITORCHANCES(MT_INVULN_BOX, 2, 0); // Invincibility
SETMONITORCHANCES(MT_WHIRLWIND_BOX, 3, 8); // Whirlwind Shield
SETMONITORCHANCES(MT_ELEMENTAL_BOX, 3, 8); // Elemental Shield
SETMONITORCHANCES(MT_ATTRACT_BOX, 2, 0); // Attraction Shield
SETMONITORCHANCES(MT_FORCE_BOX, 3, 3); // Force Shield
SETMONITORCHANCES(MT_ARMAGEDDON_BOX, 2, 0); // Armageddon Shield
SETMONITORCHANCES(MT_MIXUP_BOX, 0, 1); // Teleporters
SETMONITORCHANCES(MT_RECYCLER_BOX, 0, 1); // Recycler
SETMONITORCHANCES(MT_1UP_BOX, 1, 1); // 1-Up
// =======================================
// Total 16 32
#undef SETMONITORCHANCES
i = P_RandomKey(PR_UNDEFINED, numchoices); // Gotta love those random numbers!
newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]);
}
else
newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type);
// Transfer flags2 (ambush, strongbox, objectflip)
newmobj->flags2 = mobj->flags2;
P_RemoveMobj(mobj); // make sure they disappear
}
static boolean P_CanFlickerFuse(mobj_t *mobj) static boolean P_CanFlickerFuse(mobj_t *mobj)
{ {
switch (mobj->type) switch (mobj->type)
@ -10346,11 +10289,6 @@ static boolean P_FuseThink(mobj_t *mobj)
if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse)) || P_MobjWasRemoved(mobj)) if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse)) || P_MobjWasRemoved(mobj))
; ;
else if (mobj->info->flags & MF_MONITOR)
{
P_MonitorFuseThink(mobj);
return false;
}
else switch (mobj->type) else switch (mobj->type)
{ {
// gargoyle and snowman handled in P_PushableThinker, not here // gargoyle and snowman handled in P_PushableThinker, not here
@ -10495,6 +10433,8 @@ void P_MobjThinker(mobj_t *mobj)
P_SetTarget(&mobj->hprev, NULL); P_SetTarget(&mobj->hprev, NULL);
if (mobj->itnext && P_MobjWasRemoved(mobj->itnext)) if (mobj->itnext && P_MobjWasRemoved(mobj->itnext))
P_SetTarget(&mobj->itnext, NULL); P_SetTarget(&mobj->itnext, NULL);
if (mobj->punt_ref && P_MobjWasRemoved(mobj->punt_ref))
P_SetTarget(&mobj->punt_ref, NULL);
if (mobj->flags & MF_NOTHINK) if (mobj->flags & MF_NOTHINK)
return; return;
@ -10991,7 +10931,9 @@ void P_SceneryThinker(mobj_t *mobj)
if (mobj->type == MT_RANDOMAUDIENCE) if (mobj->type == MT_RANDOMAUDIENCE)
{ {
Obj_AudienceThink(mobj, !!(mobj->flags2 & MF2_AMBUSH)); Obj_AudienceThink(mobj, !!(mobj->flags2 & MF2_AMBUSH), !!(mobj->flags2 & MF2_DONTRESPAWN));
if (P_MobjWasRemoved(mobj))
return;
} }
} }
@ -11003,6 +10945,10 @@ fixed_t P_GetMobjDefaultScale(mobj_t *mobj)
{ {
switch(mobj->type) switch(mobj->type)
{ {
case MT_FLAMEJETFLAME:
return 3*FRACUNIT;
case MT_ITEMCLASH:
return 2*FRACUNIT;
case MT_SPECIALSTAGEARCH: case MT_SPECIALSTAGEARCH:
return 5*FRACUNIT; return 5*FRACUNIT;
case MT_SPECIALSTAGEBOMB: case MT_SPECIALSTAGEBOMB:
@ -11558,6 +11504,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->y + FINESINE((ang>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_DAYTONAPINETREE_SIDE); mobj->y + FINESINE((ang>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_DAYTONAPINETREE_SIDE);
side->angle = ang; side->angle = ang;
P_SetTarget(&side->target, mobj); P_SetTarget(&side->target, mobj);
P_SetTarget(&side->punt_ref, mobj);
side->threshold = i; side->threshold = i;
} }
break; break;
@ -12042,6 +11989,7 @@ void P_RemoveMobj(mobj_t *mobj)
} }
P_SetTarget(&mobj->itnext, NULL); P_SetTarget(&mobj->itnext, NULL);
P_SetTarget(&mobj->punt_ref, NULL);
P_RemoveThingTID(mobj); P_RemoveThingTID(mobj);
P_DeleteMobjStringArgs(mobj); P_DeleteMobjStringArgs(mobj);
@ -15617,3 +15565,9 @@ void P_DeleteMobjStringArgs(mobj_t *mobj)
mobj->script_stringargs[i] = NULL; mobj->script_stringargs[i] = NULL;
} }
} }
tic_t P_MobjIsReappearing(const mobj_t *mobj)
{
tic_t t = (!P_MobjWasRemoved(mobj->punt_ref) ? mobj->punt_ref : mobj)->reappear;
return t - min(leveltime, t);
}

View file

@ -137,8 +137,8 @@ typedef enum
MF_MISSILE = 1<<15, MF_MISSILE = 1<<15,
// Item is a spring. // Item is a spring.
MF_SPRING = 1<<16, MF_SPRING = 1<<16,
// Item box // Object is elemental. If it is punted, it will evaporate.
MF_MONITOR = 1<<17, MF_ELEMENTAL = 1<<17,
// Don't run the thinker for this object. // Don't run the thinker for this object.
MF_NOTHINK = 1<<18, MF_NOTHINK = 1<<18,
// Don't adjust z if below or above floorz/ceilingz // Don't adjust z if below or above floorz/ceilingz
@ -149,8 +149,8 @@ typedef enum
MF_SCENERY = 1<<21, MF_SCENERY = 1<<21,
// Painful (shit hurts). // Painful (shit hurts).
MF_PAIN = 1<<22, MF_PAIN = 1<<22,
// This mobj will stick to any surface or solid object it touches. // Object cannot be punted by invincible players. (Default CAN be punted, if it deals damage or is solid.)
MF_STICKY = 1<<23, MF_DONTPUNT = 1<<23,
// Object uses terrain effects. (Overlays, footsteps, etc) // Object uses terrain effects. (Overlays, footsteps, etc)
MF_APPLYTERRAIN = 1<<24, MF_APPLYTERRAIN = 1<<24,
// for chase camera, don't be blocked by things (partial clipping) // for chase camera, don't be blocked by things (partial clipping)
@ -437,6 +437,14 @@ struct mobj_t
boolean frozen; boolean frozen;
// Object was punted and is temporarily invisible and
// intangible. This is the leveltime that it will
// reappear.
tic_t reappear;
// If punt_ref, set punt_ref->reappear, treat as if this->reappear
mobj_t *punt_ref;
// WARNING: New fields must be added separately to savegame and Lua. // WARNING: New fields must be added separately to savegame and Lua.
}; };

View file

@ -571,6 +571,9 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT8(save->p, players[i].ringboxdelay); WRITEUINT8(save->p, players[i].ringboxdelay);
WRITEUINT8(save->p, players[i].ringboxaward); WRITEUINT8(save->p, players[i].ringboxaward);
WRITEUINT8(save->p, players[i].itemflags);
WRITEFIXED(save->p, players[i].outrun); WRITEFIXED(save->p, players[i].outrun);
WRITEUINT8(save->p, players[i].rideroid); WRITEUINT8(save->p, players[i].rideroid);
@ -1107,6 +1110,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].ringboxdelay = READUINT8(save->p); players[i].ringboxdelay = READUINT8(save->p);
players[i].ringboxaward = READUINT8(save->p); players[i].ringboxaward = READUINT8(save->p);
players[i].itemflags = READUINT8(save->p);
players[i].outrun = READFIXED(save->p); players[i].outrun = READFIXED(save->p);
players[i].rideroid = (boolean)READUINT8(save->p); players[i].rideroid = (boolean)READUINT8(save->p);
@ -2043,6 +2049,8 @@ static void ArchiveSectors(savebuffer_t *save)
WRITEUINT8(save->p, diff3); WRITEUINT8(save->p, diff3);
if (diff3 & SD_DIFF4) if (diff3 & SD_DIFF4)
WRITEUINT8(save->p, diff4); WRITEUINT8(save->p, diff4);
if (diff4 & SD_DIFF5)
WRITEUINT8(save->p, diff5);
if (diff & SD_FLOORHT) if (diff & SD_FLOORHT)
WRITEFIXED(save->p, ss->floorheight); WRITEFIXED(save->p, ss->floorheight);
if (diff & SD_CEILHT) if (diff & SD_CEILHT)
@ -2682,9 +2690,16 @@ typedef enum
MD2_FROZEN = 1<<28, MD2_FROZEN = 1<<28,
MD2_TERRAIN = 1<<29, MD2_TERRAIN = 1<<29,
MD2_WATERSKIP = 1<<30, MD2_WATERSKIP = 1<<30,
MD2_LIGHTLEVEL = (INT32)(1U<<31), MD2_MORE = (INT32)(1U<<31),
} mobj_diff2_t; } mobj_diff2_t;
typedef enum
{
MD3_LIGHTLEVEL = 1,
MD3_REAPPEAR = 1<<1,
MD3_PUNT_REF = 1<<2,
} mobj_diff3_t;
typedef enum typedef enum
{ {
tc_mobj, tc_mobj,
@ -2795,12 +2810,14 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
const mobj_t *mobj = (const mobj_t *)th; const mobj_t *mobj = (const mobj_t *)th;
UINT32 diff; UINT32 diff;
UINT32 diff2; UINT32 diff2;
UINT32 diff3;
size_t j; size_t j;
if (TypeIsNetSynced(mobj->type) == false) if (TypeIsNetSynced(mobj->type) == false)
return; return;
diff2 = 0; diff2 = 0;
diff3 = 0;
if (mobj->spawnpoint) if (mobj->spawnpoint)
{ {
@ -2982,8 +2999,6 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|| (slope->normal.z != FRACUNIT)) || (slope->normal.z != FRACUNIT))
diff2 |= MD2_FLOORSPRITESLOPE; diff2 |= MD2_FLOORSPRITESLOPE;
} }
if (mobj->lightlevel)
diff2 |= MD2_LIGHTLEVEL;
if (mobj->hitlag) if (mobj->hitlag)
diff2 |= MD2_HITLAG; diff2 |= MD2_HITLAG;
if (mobj->waterskip) if (mobj->waterskip)
@ -3001,6 +3016,16 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
if (mobj->terrain != NULL || mobj->terrainOverlay != NULL) if (mobj->terrain != NULL || mobj->terrainOverlay != NULL)
diff2 |= MD2_TERRAIN; diff2 |= MD2_TERRAIN;
if (mobj->lightlevel)
diff3 |= MD3_LIGHTLEVEL;
if (mobj->reappear)
diff3 |= MD3_REAPPEAR;
if (mobj->punt_ref)
diff3 |= MD3_PUNT_REF;
if (diff3 != 0)
diff2 |= MD2_MORE;
if (diff2 != 0) if (diff2 != 0)
diff |= MD_MORE; diff |= MD_MORE;
@ -3012,6 +3037,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
WRITEUINT32(save->p, diff); WRITEUINT32(save->p, diff);
if (diff & MD_MORE) if (diff & MD_MORE)
WRITEUINT32(save->p, diff2); WRITEUINT32(save->p, diff2);
if (diff2 & MD2_MORE)
WRITEUINT32(save->p, diff3);
WRITEFIXED(save->p, mobj->z); // Force this so 3dfloor problems don't arise. WRITEFIXED(save->p, mobj->z); // Force this so 3dfloor problems don't arise.
WRITEFIXED(save->p, mobj->floorz); WRITEFIXED(save->p, mobj->floorz);
@ -3249,10 +3276,6 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
WRITEFIXED(save->p, slope->normal.y); WRITEFIXED(save->p, slope->normal.y);
WRITEFIXED(save->p, slope->normal.z); WRITEFIXED(save->p, slope->normal.z);
} }
if (diff2 & MD2_LIGHTLEVEL)
{
WRITEINT16(save->p, mobj->lightlevel);
}
if (diff2 & MD2_HITLAG) if (diff2 & MD2_HITLAG)
{ {
WRITEINT32(save->p, mobj->hitlag); WRITEINT32(save->p, mobj->hitlag);
@ -3275,6 +3298,19 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
WRITEUINT32(save->p, SaveMobjnum(mobj->terrainOverlay)); WRITEUINT32(save->p, SaveMobjnum(mobj->terrainOverlay));
} }
if (diff3 & MD3_LIGHTLEVEL)
{
WRITEINT16(save->p, mobj->lightlevel);
}
if (diff3 & MD3_REAPPEAR)
{
WRITEUINT32(save->p, mobj->reappear);
}
if (diff3 & MD3_PUNT_REF)
{
WRITEUINT32(save->p, mobj->punt_ref->mobjnum);
}
WRITEUINT32(save->p, mobj->mobjnum); WRITEUINT32(save->p, mobj->mobjnum);
} }
@ -4148,6 +4184,7 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
mobj_t *mobj; mobj_t *mobj;
UINT32 diff; UINT32 diff;
UINT32 diff2; UINT32 diff2;
UINT32 diff3;
INT32 i; INT32 i;
fixed_t z, floorz, ceilingz; fixed_t z, floorz, ceilingz;
ffloor_t *floorrover = NULL, *ceilingrover = NULL; ffloor_t *floorrover = NULL, *ceilingrover = NULL;
@ -4159,6 +4196,11 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
else else
diff2 = 0; diff2 = 0;
if (diff2 & MD2_MORE)
diff3 = READUINT32(save->p);
else
diff3 = 0;
z = READFIXED(save->p); // Force this so 3dfloor problems don't arise. z = READFIXED(save->p); // Force this so 3dfloor problems don't arise.
floorz = READFIXED(save->p); floorz = READFIXED(save->p);
ceilingz = READFIXED(save->p); ceilingz = READFIXED(save->p);
@ -4484,10 +4526,6 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
P_UpdateSlopeLightOffset(slope); P_UpdateSlopeLightOffset(slope);
} }
if (diff2 & MD2_LIGHTLEVEL)
{
mobj->lightlevel = READINT16(save->p);
}
if (diff2 & MD2_HITLAG) if (diff2 & MD2_HITLAG)
{ {
mobj->hitlag = READINT32(save->p); mobj->hitlag = READINT32(save->p);
@ -4514,6 +4552,19 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
mobj->terrain = NULL; mobj->terrain = NULL;
} }
if (diff3 & MD3_LIGHTLEVEL)
{
mobj->lightlevel = READINT16(save->p);
}
if (diff3 & MD3_REAPPEAR)
{
mobj->reappear = READUINT32(save->p);
}
if (diff3 & MD3_PUNT_REF)
{
mobj->punt_ref = (mobj_t *)(size_t)READUINT32(save->p);
}
// set sprev, snext, bprev, bnext, subsector // set sprev, snext, bprev, bnext, subsector
P_SetThingPosition(mobj); P_SetThingPosition(mobj);
@ -5553,6 +5604,13 @@ static void P_RelinkPointers(void)
if (!P_SetTarget(&mobj->terrainOverlay, P_FindNewPosition(temp))) if (!P_SetTarget(&mobj->terrainOverlay, P_FindNewPosition(temp)))
CONS_Debug(DBG_GAMELOGIC, "terrainOverlay not found on %d\n", mobj->type); CONS_Debug(DBG_GAMELOGIC, "terrainOverlay not found on %d\n", mobj->type);
} }
if (mobj->punt_ref)
{
temp = (UINT32)(size_t)mobj->punt_ref;
mobj->punt_ref = NULL;
if (!P_SetTarget(&mobj->punt_ref, P_FindNewPosition(temp)))
CONS_Debug(DBG_GAMELOGIC, "punt_ref not found on %d\n", mobj->type);
}
} }
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)

View file

@ -1168,6 +1168,9 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
K_ReduceVFX(ghost, mobj->player); K_ReduceVFX(ghost, mobj->player);
ghost->reappear = mobj->reappear;
P_SetTarget(&ghost->punt_ref, mobj->punt_ref);
return ghost; return ghost;
} }
@ -2714,9 +2717,6 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
if (!(mo->flags & MF_SHOOTABLE) && (mo->type != MT_SPB)) // Don't want to give SPB MF_SHOOTABLE, to ensure it's undamagable through other means if (!(mo->flags & MF_SHOOTABLE) && (mo->type != MT_SPB)) // Don't want to give SPB MF_SHOOTABLE, to ensure it's undamagable through other means
continue; continue;
if (mo->flags & MF_MONITOR)
continue; // Monitors cannot be 'nuked'.
if (abs(inflictor->x - mo->x) > radius || abs(inflictor->y - mo->y) > radius || abs(inflictor->z - mo->z) > radius) if (abs(inflictor->x - mo->x) > radius || abs(inflictor->y - mo->y) > radius || abs(inflictor->z - mo->z) > radius)
continue; // Workaround for possible integer overflow in the below -Red continue; // Workaround for possible integer overflow in the below -Red
@ -4397,12 +4397,12 @@ void P_PlayerThink(player_t *player)
} }
} }
boolean deathcontrolled = (player->respawn.state != RESPAWNST_NONE && player->respawn.truedeath == true)
|| (player->pflags & PF_NOCONTEST) || (player->karmadelay);
boolean powercontrolled = (player->hyudorotimer) || (player->growshrinktimer > 0);
// Flash player after being hit. // Flash player after being hit.
if (!(player->hyudorotimer // SRB2kart - fixes Hyudoro not flashing when it should. if (!deathcontrolled && !powercontrolled)
|| player->growshrinktimer > 0 // Grow doesn't flash either.
|| (player->respawn.state != RESPAWNST_NONE && player->respawn.truedeath == true) // Respawn timer (for drop dash effect)
|| (player->pflags & PF_NOCONTEST) // NO CONTEST explosion
|| player->karmadelay))
{ {
if (player->flashing > 1 && player->flashing < K_GetKartFlashing(player) if (player->flashing > 1 && player->flashing < K_GetKartFlashing(player)
&& (leveltime & 1)) && (leveltime & 1))
@ -4410,6 +4410,10 @@ void P_PlayerThink(player_t *player)
else else
player->mo->renderflags &= ~RF_DONTDRAW; player->mo->renderflags &= ~RF_DONTDRAW;
} }
else if (!deathcontrolled)
{
player->mo->renderflags &= ~RF_DONTDRAW;
}
if (player->stairjank > 0) if (player->stairjank > 0)
{ {

View file

@ -240,7 +240,7 @@ static boolean is_tangible (mobj_t *thing)
// These objects probably do nothing! :D // These objects probably do nothing! :D
if ((thing->flags & (MF_SPECIAL|MF_SOLID|MF_SHOOTABLE if ((thing->flags & (MF_SPECIAL|MF_SOLID|MF_SHOOTABLE
|MF_PUSHABLE|MF_BOSS|MF_MISSILE|MF_SPRING |MF_PUSHABLE|MF_BOSS|MF_MISSILE|MF_SPRING
|MF_MONITOR|MF_ENEMY|MF_PAIN|MF_STICKY |MF_ELEMENTAL|MF_ENEMY|MF_PAIN|MF_DONTPUNT
|MF_PICKUPFROMBELOW)) == 0U) |MF_PICKUPFROMBELOW)) == 0U)
{ {
return false; return false;

View file

@ -140,6 +140,10 @@ void R_InterpolateView(fixed_t frac)
prevview = newview; prevview = newview;
} }
viewx = R_LerpFixed(prevview->x, newview->x, frac);
viewy = R_LerpFixed(prevview->y, newview->y, frac);
viewz = R_LerpFixed(prevview->z, newview->z, frac);
viewangle = R_LerpAngle(prevview->angle, newview->angle, frac); viewangle = R_LerpAngle(prevview->angle, newview->angle, frac);
aimingangle = R_LerpAngle(prevview->aim, newview->aim, frac); aimingangle = R_LerpAngle(prevview->aim, newview->aim, frac);
viewroll = R_LerpAngle(prevview->roll, newview->roll, frac); viewroll = R_LerpAngle(prevview->roll, newview->roll, frac);
@ -147,12 +151,6 @@ void R_InterpolateView(fixed_t frac)
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
fixed_t zoom = R_LerpFixed(prevview->zoom, newview->zoom, frac);
viewx = R_LerpFixed(prevview->x, newview->x, frac) - FixedMul(viewcos, zoom);
viewy = R_LerpFixed(prevview->y, newview->y, frac) - FixedMul(viewsin, zoom);
viewz = R_LerpFixed(prevview->z, newview->z, frac);
viewplayer = newview->player; viewplayer = newview->player;
viewsector = R_PointInSubsector(viewx, viewy)->sector; viewsector = R_PointInSubsector(viewx, viewy)->sector;

View file

@ -48,7 +48,6 @@ struct viewvars_t {
fixed_t x; fixed_t x;
fixed_t y; fixed_t y;
fixed_t z; fixed_t z;
fixed_t zoom;
boolean sky; boolean sky;
sector_t *sector; sector_t *sector;
player_t *player; player_t *player;

View file

@ -1244,7 +1244,6 @@ void R_SetupFrame(int s)
newview->x = r_viewmobj->x; newview->x = r_viewmobj->x;
newview->y = r_viewmobj->y; newview->y = r_viewmobj->y;
newview->z = r_viewmobj->z; newview->z = r_viewmobj->z;
newview->zoom = 0;
R_SetupCommonFrame(player, r_viewmobj->subsector); R_SetupCommonFrame(player, r_viewmobj->subsector);
} }
@ -1253,13 +1252,9 @@ void R_SetupFrame(int s)
{ {
r_viewmobj = NULL; r_viewmobj = NULL;
fixed_t x = player->mo ? player->mo->x : thiscam->x; newview->x = thiscam->x;
fixed_t y = player->mo ? player->mo->y : thiscam->y; newview->y = thiscam->y;
newview->x = x;
newview->y = y;
newview->z = thiscam->z + (thiscam->height>>1); newview->z = thiscam->z + (thiscam->height>>1);
newview->zoom = FixedHypot(thiscam->x - x, thiscam->y - y);
R_SetupCommonFrame(player, thiscam->subsector); R_SetupCommonFrame(player, thiscam->subsector);
} }
@ -1272,7 +1267,6 @@ void R_SetupFrame(int s)
newview->x = r_viewmobj->x; newview->x = r_viewmobj->x;
newview->y = r_viewmobj->y; newview->y = r_viewmobj->y;
newview->z = player->viewz; newview->z = player->viewz;
newview->zoom = 0;
R_SetupCommonFrame(player, r_viewmobj->subsector); R_SetupCommonFrame(player, r_viewmobj->subsector);
} }
@ -1303,7 +1297,6 @@ void R_SkyboxFrame(int s)
newview->x = r_viewmobj->x; newview->x = r_viewmobj->x;
newview->y = r_viewmobj->y; newview->y = r_viewmobj->y;
newview->z = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle! newview->z = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
newview->zoom = 0;
if (mapheaderinfo[gamemap-1]) if (mapheaderinfo[gamemap-1])
{ {

View file

@ -3746,6 +3746,12 @@ boolean R_ThingVisible (mobj_t *thing)
if (r_viewmobj && (thing == r_viewmobj || (r_viewmobj->player && r_viewmobj->player->followmobj == thing))) if (r_viewmobj && (thing == r_viewmobj || (r_viewmobj->player && r_viewmobj->player->followmobj == thing)))
return false; return false;
if (tic_t t = P_MobjIsReappearing(thing))
{
// Flicker back in
return t <= 2*TICRATE && (leveltime & 1);
}
if ((viewssnum == 0 && (thing->renderflags & RF_DONTDRAWP1)) if ((viewssnum == 0 && (thing->renderflags & RF_DONTDRAWP1))
|| (viewssnum == 1 && (thing->renderflags & RF_DONTDRAWP2)) || (viewssnum == 1 && (thing->renderflags & RF_DONTDRAWP2))
|| (viewssnum == 2 && (thing->renderflags & RF_DONTDRAWP3)) || (viewssnum == 2 && (thing->renderflags & RF_DONTDRAWP3))

View file

@ -426,6 +426,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
for (i = 0; i <= r_splitscreen; i++) for (i = 0; i <= r_splitscreen; i++)
{ {
player_t *player = &players[displayplayers[i]]; player_t *player = &players[displayplayers[i]];
boolean camaway = false;
memset(&listener[i], 0, sizeof (listener[i])); memset(&listener[i], 0, sizeof (listener[i]));
listenmobj[i] = NULL; listenmobj[i] = NULL;
@ -442,9 +443,11 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
else else
{ {
listenmobj[i] = player->mo; listenmobj[i] = player->mo;
if (player->exiting)
camaway = true;
} }
if (origin && origin == listenmobj[i] && !camera[i].freecam) if (origin && origin == listenmobj[i] && !camera[i].freecam && !camaway)
{ {
itsUs = true; itsUs = true;
} }
@ -763,6 +766,9 @@ void S_UpdateSounds(void)
if (c->origin != listenmobj[i]) if (c->origin != listenmobj[i])
continue; continue;
if (listenmobj[i]->player && listenmobj[i]->player->exiting)
continue;
itsUs = true; itsUs = true;
} }
@ -942,6 +948,9 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
if (!listener) if (!listener)
return false; return false;
if (source->thinker.function.acp1 == (actionf_p1)P_MobjThinker && P_MobjIsReappearing(source))
return false;
// Init listensource with default listener // Init listensource with default listener
listensource.x = listener->x; listensource.x = listener->x;
listensource.y = listener->y; listensource.y = listener->y;