mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-28 04:51:42 +00:00
Merge remote-tracking branch 'origin/duel-stuff'
This commit is contained in:
commit
f3545a6e6f
16 changed files with 489 additions and 58 deletions
|
|
@ -139,7 +139,7 @@ skins
|
||||||
// Gametypes
|
// Gametypes
|
||||||
gametypes
|
gametypes
|
||||||
{
|
{
|
||||||
-1 = "Single Player";
|
-1 = "Grand Prix";
|
||||||
0 = "Race";
|
0 = "Race";
|
||||||
1 = "Battle";
|
1 = "Battle";
|
||||||
}
|
}
|
||||||
|
|
@ -5113,6 +5113,7 @@ thingtypes
|
||||||
height = 92;
|
height = 92;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
waypoints
|
waypoints
|
||||||
{
|
{
|
||||||
color = 4; // Red
|
color = 4; // Red
|
||||||
|
|
@ -5161,6 +5162,80 @@ thingtypes
|
||||||
fixedrotation = 1;
|
fixedrotation = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
duel
|
||||||
|
{
|
||||||
|
color = 4; // Red
|
||||||
|
arrow = 0;
|
||||||
|
title = "Duel Objects";
|
||||||
|
sprite = "SPBMA2A8";
|
||||||
|
flags1text = "[1] Spawn in all modes";
|
||||||
|
|
||||||
|
2050
|
||||||
|
{
|
||||||
|
title = "Duel Bomb";
|
||||||
|
width = 24;
|
||||||
|
height = 48;
|
||||||
|
arrow = 1;
|
||||||
|
flags8text = "[8] Flip strafe";
|
||||||
|
}
|
||||||
|
|
||||||
|
2051
|
||||||
|
{
|
||||||
|
title = "Banana";
|
||||||
|
sprite = "BANAA2A8";
|
||||||
|
width = 16;
|
||||||
|
height = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
2052
|
||||||
|
{
|
||||||
|
title = "Eggman Item";
|
||||||
|
sprite = "FITMA0";
|
||||||
|
width = 24;
|
||||||
|
height = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
2053
|
||||||
|
{
|
||||||
|
title = "Proximity Mine";
|
||||||
|
sprite = "SSMNA0";
|
||||||
|
width = 16;
|
||||||
|
height = 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
2054
|
||||||
|
{
|
||||||
|
title = "Land Mine";
|
||||||
|
sprite = "LNDMALAR";
|
||||||
|
width = 24;
|
||||||
|
height = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
2055
|
||||||
|
{
|
||||||
|
title = "Hyudoro";
|
||||||
|
sprite = "HYUUA2A8";
|
||||||
|
width = 32;
|
||||||
|
height = 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
2056
|
||||||
|
{
|
||||||
|
title = "Drop Target";
|
||||||
|
sprite = "DTRGALAR";
|
||||||
|
width = 45;
|
||||||
|
height = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
2057
|
||||||
|
{
|
||||||
|
title = "Pogo Spring";
|
||||||
|
sprite = "POGSA0";
|
||||||
|
width = 48;
|
||||||
|
height = 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Default things filters
|
//Default things filters
|
||||||
|
|
@ -5183,24 +5258,6 @@ thingsfilters
|
||||||
}
|
}
|
||||||
|
|
||||||
filter2
|
filter2
|
||||||
{
|
|
||||||
name = "Enemies";
|
|
||||||
category = "enemies";
|
|
||||||
type = -1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
filter3
|
|
||||||
{
|
|
||||||
name = "NiGHTS Track";
|
|
||||||
category = "nightstrk";
|
|
||||||
type = -1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
filter4
|
|
||||||
{
|
{
|
||||||
name = "Normal Gravity";
|
name = "Normal Gravity";
|
||||||
category = "";
|
category = "";
|
||||||
|
|
@ -5213,8 +5270,7 @@ thingsfilters
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filter3
|
||||||
filter5
|
|
||||||
{
|
{
|
||||||
name = "Reverse Gravity";
|
name = "Reverse Gravity";
|
||||||
category = "";
|
category = "";
|
||||||
|
|
@ -5226,11 +5282,4 @@ thingsfilters
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filter6
|
|
||||||
{
|
|
||||||
name = "Boss Waypoints";
|
|
||||||
category = "";
|
|
||||||
type = 292;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5372,6 +5372,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
||||||
"MT_SINK_SHIELD",
|
"MT_SINK_SHIELD",
|
||||||
"MT_SINKTRAIL",
|
"MT_SINKTRAIL",
|
||||||
|
|
||||||
|
"MT_DUELBOMB", // Duel mode bombs
|
||||||
|
|
||||||
"MT_BATTLEBUMPER", // Battle Mode bumper
|
"MT_BATTLEBUMPER", // Battle Mode bumper
|
||||||
"MT_BATTLEBUMPER_DEBRIS",
|
"MT_BATTLEBUMPER_DEBRIS",
|
||||||
"MT_BATTLEBUMPER_BLAST",
|
"MT_BATTLEBUMPER_BLAST",
|
||||||
|
|
|
||||||
|
|
@ -669,6 +669,7 @@ extern boolean thwompsactive;
|
||||||
extern UINT8 lastLowestLap;
|
extern UINT8 lastLowestLap;
|
||||||
extern SINT8 spbplace;
|
extern SINT8 spbplace;
|
||||||
extern boolean rainbowstartavailable;
|
extern boolean rainbowstartavailable;
|
||||||
|
extern boolean inDuel;
|
||||||
|
|
||||||
extern tic_t bombflashtimer; // Used to avoid causing seizures if multiple mines explode close to you :)
|
extern tic_t bombflashtimer; // Used to avoid causing seizures if multiple mines explode close to you :)
|
||||||
extern boolean legitimateexit;
|
extern boolean legitimateexit;
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,7 @@ boolean thwompsactive; // Thwomps activate on lap 2
|
||||||
UINT8 lastLowestLap; // Last lowest lap, for activating race lap executors
|
UINT8 lastLowestLap; // Last lowest lap, for activating race lap executors
|
||||||
SINT8 spbplace; // SPB exists, give the person behind better items
|
SINT8 spbplace; // SPB exists, give the person behind better items
|
||||||
boolean rainbowstartavailable; // Boolean, keeps track of if the rainbow start was gotten
|
boolean rainbowstartavailable; // Boolean, keeps track of if the rainbow start was gotten
|
||||||
|
boolean inDuel; // Boolean, keeps track of if it is a 1v1
|
||||||
|
|
||||||
// Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players)
|
// Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players)
|
||||||
tic_t bombflashtimer = 0; // Cooldown before another FlashPal can be intialized by a bomb exploding near a displayplayer. Avoids seizures.
|
tic_t bombflashtimer = 0; // Cooldown before another FlashPal can be intialized by a bomb exploding near a displayplayer. Avoids seizures.
|
||||||
|
|
|
||||||
41
src/info.c
41
src/info.c
|
|
@ -8315,7 +8315,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_POGOSPRING
|
{ // MT_POGOSPRING
|
||||||
-1, // doomednum
|
2057, // doomednum
|
||||||
S_POGOSPRING1, // spawnstate
|
S_POGOSPRING1, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_POGOSPRING2B, // seestate
|
S_POGOSPRING2B, // seestate
|
||||||
|
|
@ -23317,7 +23317,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_EGGMANITEM
|
{ // MT_EGGMANITEM
|
||||||
-1, // doomednum
|
2052, // doomednum
|
||||||
S_EGGMANITEM1, // spawnstate
|
S_EGGMANITEM1, // spawnstate
|
||||||
2, // spawnhealth
|
2, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
|
|
@ -23371,7 +23371,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_BANANA
|
{ // MT_BANANA
|
||||||
-1, // doomednum
|
2051, // doomednum
|
||||||
S_BANANA, // spawnstate
|
S_BANANA, // spawnstate
|
||||||
2, // spawnhealth
|
2, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
|
|
@ -23560,7 +23560,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_SSMINE
|
{ // MT_SSMINE
|
||||||
-1, // doomednum
|
2053, // doomednum
|
||||||
S_SSMINE_AIR1, // spawnstate
|
S_SSMINE_AIR1, // spawnstate
|
||||||
1, // spawnhealth
|
1, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
|
|
@ -23695,7 +23695,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_LANDMINE
|
{ // MT_LANDMINE
|
||||||
-1, // doomednum
|
2054, // doomednum
|
||||||
S_LANDMINE, // spawnstate
|
S_LANDMINE, // spawnstate
|
||||||
2, // spawnhealth
|
2, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
|
|
@ -23722,7 +23722,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_DROPTARGET
|
{ // MT_DROPTARGET
|
||||||
-1, // doomednum
|
2056, // doomednum
|
||||||
S_DROPTARGET, // spawnstate
|
S_DROPTARGET, // spawnstate
|
||||||
3, // spawnhealth
|
3, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
|
|
@ -24154,7 +24154,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_HYUDORO_CENTER
|
{ // MT_HYUDORO_CENTER
|
||||||
-1, // doomednum
|
2055, // doomednum
|
||||||
S_INVISIBLE, // spawnstate
|
S_INVISIBLE, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
|
|
@ -24423,6 +24423,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // MT_DUELBOMB
|
||||||
|
2050, // doomednum
|
||||||
|
S_SPB1, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_None, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
64*FRACUNIT, // speed
|
||||||
|
24*FRACUNIT, // radius
|
||||||
|
48*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
0, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_SPECIAL|MF_DONTENCOREMAP|MF_APPLYTERRAIN, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
{ // MT_BATTLEBUMPER
|
{ // MT_BATTLEBUMPER
|
||||||
-1, // doomednum
|
-1, // doomednum
|
||||||
S_BATTLEBUMPER1,// spawnstate
|
S_BATTLEBUMPER1,// spawnstate
|
||||||
|
|
|
||||||
|
|
@ -6418,6 +6418,8 @@ typedef enum mobj_type
|
||||||
MT_SINK_SHIELD,
|
MT_SINK_SHIELD,
|
||||||
MT_SINKTRAIL,
|
MT_SINKTRAIL,
|
||||||
|
|
||||||
|
MT_DUELBOMB, // Duel mode bombs
|
||||||
|
|
||||||
MT_BATTLEBUMPER, // Battle Mode bumpers
|
MT_BATTLEBUMPER, // Battle Mode bumpers
|
||||||
MT_BATTLEBUMPER_DEBRIS,
|
MT_BATTLEBUMPER_DEBRIS,
|
||||||
MT_BATTLEBUMPER_BLAST,
|
MT_BATTLEBUMPER_BLAST,
|
||||||
|
|
|
||||||
|
|
@ -422,6 +422,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
||||||
case MT_BALLHOG:
|
case MT_BALLHOG:
|
||||||
case MT_SPB:
|
case MT_SPB:
|
||||||
case MT_BUBBLESHIELDTRAP:
|
case MT_BUBBLESHIELDTRAP:
|
||||||
|
case MT_DUELBOMB:
|
||||||
K_AddDodgeObject(thing, side, 20);
|
K_AddDodgeObject(thing, side, 20);
|
||||||
break;
|
break;
|
||||||
case MT_SHRINK_GUN:
|
case MT_SHRINK_GUN:
|
||||||
|
|
|
||||||
53
src/k_kart.c
53
src/k_kart.c
|
|
@ -49,10 +49,53 @@
|
||||||
// battlewanted is an array of the WANTED player nums, -1 for no player in that slot
|
// battlewanted is an array of the WANTED player nums, -1 for no player in that slot
|
||||||
// mapreset is set when enough players fill an empty server
|
// mapreset is set when enough players fill an empty server
|
||||||
|
|
||||||
|
boolean K_IsDuelItem(mobjtype_t type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case MT_DUELBOMB:
|
||||||
|
case MT_BANANA:
|
||||||
|
case MT_EGGMANITEM:
|
||||||
|
case MT_SSMINE:
|
||||||
|
case MT_LANDMINE:
|
||||||
|
case MT_HYUDORO_CENTER:
|
||||||
|
case MT_DROPTARGET:
|
||||||
|
case MT_POGOSPRING:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean K_DuelItemAlwaysSpawns(mapthing_t *mt)
|
||||||
|
{
|
||||||
|
return (mt->options & MTF_EXTRA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void K_SpawnDuelOnlyItems(void)
|
||||||
|
{
|
||||||
|
mapthing_t *mt = NULL;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
mt = mapthings;
|
||||||
|
for (i = 0; i < nummapthings; i++, mt++)
|
||||||
|
{
|
||||||
|
mobjtype_t type = P_GetMobjtype(mt->type);
|
||||||
|
|
||||||
|
if (K_IsDuelItem(type) == true
|
||||||
|
&& K_DuelItemAlwaysSpawns(mt) == false)
|
||||||
|
{
|
||||||
|
P_SpawnMapThing(mt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void K_TimerReset(void)
|
void K_TimerReset(void)
|
||||||
{
|
{
|
||||||
starttime = introtime = 3;
|
starttime = introtime = 3;
|
||||||
numbulbs = 1;
|
numbulbs = 1;
|
||||||
|
inDuel = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void K_TimerInit(void)
|
void K_TimerInit(void)
|
||||||
|
|
@ -78,6 +121,9 @@ void K_TimerInit(void)
|
||||||
numPlayers++;
|
numPlayers++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1v1 activates DUEL rules!
|
||||||
|
inDuel = (numPlayers == 2);
|
||||||
|
|
||||||
if (numPlayers >= 2)
|
if (numPlayers >= 2)
|
||||||
{
|
{
|
||||||
rainbowstartavailable = true;
|
rainbowstartavailable = true;
|
||||||
|
|
@ -106,6 +152,12 @@ void K_TimerInit(void)
|
||||||
|
|
||||||
// NOW you can try to spawn in the Battle capsules, if there's not enough players for a match
|
// NOW you can try to spawn in the Battle capsules, if there's not enough players for a match
|
||||||
K_BattleInit();
|
K_BattleInit();
|
||||||
|
|
||||||
|
if (inDuel == true)
|
||||||
|
{
|
||||||
|
K_SpawnDuelOnlyItems();
|
||||||
|
}
|
||||||
|
|
||||||
//CONS_Printf("numbulbs set to %d (%d players, %d spectators) on tic %d\n", numbulbs, numPlayers, numspec, leveltime);
|
//CONS_Printf("numbulbs set to %d (%d players, %d spectators) on tic %d\n", numbulbs, numPlayers, numspec, leveltime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1437,6 +1489,7 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against)
|
||||||
break;
|
break;
|
||||||
case MT_ORBINAUT:
|
case MT_ORBINAUT:
|
||||||
case MT_ORBINAUT_SHIELD:
|
case MT_ORBINAUT_SHIELD:
|
||||||
|
case MT_DUELBOMB:
|
||||||
if (against->player)
|
if (against->player)
|
||||||
weight = K_PlayerWeight(against, NULL);
|
weight = K_PlayerWeight(against, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,9 @@ angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t
|
||||||
|
|
||||||
void K_RegisterKartStuff(void);
|
void K_RegisterKartStuff(void);
|
||||||
|
|
||||||
|
boolean K_IsDuelItem(mobjtype_t type);
|
||||||
|
boolean K_DuelItemAlwaysSpawns(mapthing_t *mt);
|
||||||
|
|
||||||
void K_TimerReset(void);
|
void K_TimerReset(void);
|
||||||
void K_TimerInit(void);
|
void K_TimerInit(void);
|
||||||
UINT32 K_GetPlayerDontDrawFlag(player_t *player);
|
UINT32 K_GetPlayerDontDrawFlag(player_t *player);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#define k_objects_H
|
#define k_objects_H
|
||||||
|
|
||||||
/* Hyudoro */
|
/* Hyudoro */
|
||||||
|
void Obj_InitHyudoroCenter(mobj_t *center, mobj_t *master);
|
||||||
void Obj_HyudoroDeploy(mobj_t *master);
|
void Obj_HyudoroDeploy(mobj_t *master);
|
||||||
void Obj_HyudoroThink(mobj_t *actor);
|
void Obj_HyudoroThink(mobj_t *actor);
|
||||||
void Obj_HyudoroCenterThink(mobj_t *actor);
|
void Obj_HyudoroCenterThink(mobj_t *actor);
|
||||||
|
|
@ -47,4 +48,10 @@ void Obj_OrbinautJawzMoveHeld(player_t *player);
|
||||||
void Obj_JawzThink(mobj_t *th);
|
void Obj_JawzThink(mobj_t *th);
|
||||||
void Obj_JawzThrown(mobj_t *th, fixed_t finalSpeed, SINT8 dir);
|
void Obj_JawzThrown(mobj_t *th, fixed_t finalSpeed, SINT8 dir);
|
||||||
|
|
||||||
|
/* Duel Bomb */
|
||||||
|
void Obj_DuelBombThink(mobj_t *bomb);
|
||||||
|
void Obj_DuelBombReverse(mobj_t *bomb);
|
||||||
|
void Obj_DuelBombTouch(mobj_t *bomb, mobj_t *toucher);
|
||||||
|
void Obj_DuelBombInit(mobj_t *bomb);
|
||||||
|
|
||||||
#endif/*k_objects_H*/
|
#endif/*k_objects_H*/
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,4 @@ spb.c
|
||||||
manta-ring.c
|
manta-ring.c
|
||||||
orbinaut.c
|
orbinaut.c
|
||||||
jawz.c
|
jawz.c
|
||||||
|
duel-bomb.c
|
||||||
|
|
|
||||||
97
src/objects/duel-bomb.c
Normal file
97
src/objects/duel-bomb.c
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
// DR. ROBOTNIK'S RING RACERS
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||||
|
// Copyright (C) 2022 by Kart Krew
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file duel-bomb.c
|
||||||
|
/// \brief Duel mode bombs.
|
||||||
|
|
||||||
|
#include "../doomdef.h"
|
||||||
|
#include "../doomstat.h"
|
||||||
|
#include "../info.h"
|
||||||
|
#include "../k_kart.h"
|
||||||
|
#include "../k_objects.h"
|
||||||
|
#include "../m_random.h"
|
||||||
|
#include "../p_local.h"
|
||||||
|
#include "../r_main.h"
|
||||||
|
#include "../s_sound.h"
|
||||||
|
#include "../g_game.h"
|
||||||
|
#include "../z_zone.h"
|
||||||
|
#include "../k_waypoint.h"
|
||||||
|
#include "../k_respawn.h"
|
||||||
|
#include "../k_collide.h"
|
||||||
|
|
||||||
|
#define bomb_dir(o) ((o)->movedir)
|
||||||
|
|
||||||
|
static fixed_t GetBombSpeed(mobj_t *bomb)
|
||||||
|
{
|
||||||
|
return FixedMul(bomb->info->speed, bomb->scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateBombMovement(mobj_t *bomb)
|
||||||
|
{
|
||||||
|
const fixed_t spd = GetBombSpeed(bomb);
|
||||||
|
bomb->momx = FixedMul(spd, FINECOSINE(bomb_dir(bomb) >> ANGLETOFINESHIFT));
|
||||||
|
bomb->momy = FixedMul(spd, FINESINE(bomb_dir(bomb) >> ANGLETOFINESHIFT));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Obj_DuelBombThink(mobj_t *bomb)
|
||||||
|
{
|
||||||
|
boolean grounded = P_IsObjectOnGround(bomb);
|
||||||
|
|
||||||
|
if (grounded == true)
|
||||||
|
{
|
||||||
|
UpdateBombMovement(bomb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Obj_DuelBombReverse(mobj_t *bomb)
|
||||||
|
{
|
||||||
|
bomb_dir(bomb) += ANGLE_180;
|
||||||
|
UpdateBombMovement(bomb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Obj_DuelBombTouch(mobj_t *bomb, mobj_t *toucher)
|
||||||
|
{
|
||||||
|
player_t *player = toucher->player;
|
||||||
|
mobj_t *boom = NULL;
|
||||||
|
|
||||||
|
if (bomb->health <= 0 || toucher->health <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->flashing > 0 || player->hyudorotimer > 0 || P_PlayerInPain(player))
|
||||||
|
{
|
||||||
|
// No interaction
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create explosion
|
||||||
|
boom = P_SpawnMobjFromMobj(bomb, 0, 0, 0, MT_BOOMEXPLODE);
|
||||||
|
boom->momz = 5 * boom->scale;
|
||||||
|
boom->color = SKINCOLOR_KETCHUP;
|
||||||
|
S_StartSound(boom, bomb->info->attacksound);
|
||||||
|
|
||||||
|
if (player->invincibilitytimer > 0
|
||||||
|
|| K_IsBigger(toucher, bomb) == true
|
||||||
|
|| player->flamedash > 0)
|
||||||
|
{
|
||||||
|
// Kill without damaging.
|
||||||
|
P_KillMobj(bomb, toucher, toucher, DMG_NORMAL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
P_DamageMobj(toucher, bomb, bomb, 1, DMG_TUMBLE);
|
||||||
|
P_KillMobj(bomb, toucher, toucher, DMG_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Obj_DuelBombInit(mobj_t *bomb)
|
||||||
|
{
|
||||||
|
bomb_dir(bomb) = bomb->angle + ANGLE_90;
|
||||||
|
UpdateBombMovement(bomb);
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,15 @@
|
||||||
|
// DR. ROBOTNIK'S RING RACERS
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2022 by James R.
|
||||||
|
// Copyright (C) 2022 by Kart Krew
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file hyudoro.c
|
||||||
|
/// \brief Hyudoro item code.
|
||||||
|
|
||||||
#include "../doomdef.h"
|
#include "../doomdef.h"
|
||||||
#include "../doomstat.h"
|
#include "../doomstat.h"
|
||||||
#include "../info.h"
|
#include "../info.h"
|
||||||
|
|
@ -7,6 +19,7 @@
|
||||||
#include "../p_local.h"
|
#include "../p_local.h"
|
||||||
#include "../r_main.h"
|
#include "../r_main.h"
|
||||||
#include "../s_sound.h"
|
#include "../s_sound.h"
|
||||||
|
#include "../g_game.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HYU_PATROL,
|
HYU_PATROL,
|
||||||
|
|
@ -39,11 +52,14 @@ K_ChangePlayerItem
|
||||||
#define hyudoro_hover_stack(o) ((o)->threshold)
|
#define hyudoro_hover_stack(o) ((o)->threshold)
|
||||||
#define hyudoro_next(o) ((o)->tracer)
|
#define hyudoro_next(o) ((o)->tracer)
|
||||||
#define hyudoro_stackpos(o) ((o)->reactiontime)
|
#define hyudoro_stackpos(o) ((o)->reactiontime)
|
||||||
|
#define hyudoro_delivered(o) (hyudoro_itemtype(o) == KITEM_NONE)
|
||||||
|
|
||||||
// cannot be combined
|
// cannot be combined
|
||||||
#define hyudoro_center(o) ((o)->target)
|
#define hyudoro_center(o) ((o)->target)
|
||||||
#define hyudoro_target(o) ((o)->target)
|
#define hyudoro_target(o) ((o)->target)
|
||||||
|
|
||||||
|
#define hyudoro_stolefrom(o) ((o)->hnext)
|
||||||
|
|
||||||
#define hyudoro_center_max_radius(o) ((o)->threshold)
|
#define hyudoro_center_max_radius(o) ((o)->threshold)
|
||||||
#define hyudoro_center_master(o) ((o)->target)
|
#define hyudoro_center_master(o) ((o)->target)
|
||||||
|
|
||||||
|
|
@ -101,6 +117,16 @@ sine_bob
|
||||||
sineofs + FINESINE(a >> ANGLETOFINESHIFT));
|
sineofs + FINESINE(a >> ANGLETOFINESHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bob_in_place
|
||||||
|
( mobj_t * hyu,
|
||||||
|
INT32 bob_speed)
|
||||||
|
{
|
||||||
|
sine_bob(hyu,
|
||||||
|
(leveltime & (bob_speed - 1)) *
|
||||||
|
(ANGLE_MAX / bob_speed), -(3*FRACUNIT/4));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
project_hyudoro (mobj_t *hyu)
|
project_hyudoro (mobj_t *hyu)
|
||||||
{
|
{
|
||||||
|
|
@ -127,8 +153,6 @@ project_hyudoro (mobj_t *hyu)
|
||||||
static void
|
static void
|
||||||
project_hyudoro_hover (mobj_t *hyu)
|
project_hyudoro_hover (mobj_t *hyu)
|
||||||
{
|
{
|
||||||
const INT32 bob_speed = 64;
|
|
||||||
|
|
||||||
mobj_t *target = hyudoro_target(hyu);
|
mobj_t *target = hyudoro_target(hyu);
|
||||||
|
|
||||||
// Turns a bit toward its target
|
// Turns a bit toward its target
|
||||||
|
|
@ -154,9 +178,7 @@ project_hyudoro_hover (mobj_t *hyu)
|
||||||
hyu->pitch = target->pitch;
|
hyu->pitch = target->pitch;
|
||||||
hyu->roll = target->roll;
|
hyu->roll = target->roll;
|
||||||
|
|
||||||
sine_bob(hyu,
|
bob_in_place(hyu, 64);
|
||||||
(leveltime & (bob_speed - 1)) *
|
|
||||||
(ANGLE_MAX / bob_speed), -(3*FRACUNIT/4));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -173,6 +195,79 @@ spawn_hyudoro_shadow (mobj_t *hyu)
|
||||||
P_SetTarget(&shadow->tracer, hyu);
|
P_SetTarget(&shadow->tracer, hyu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mobj_t *
|
||||||
|
find_duel_target (mobj_t *ignore)
|
||||||
|
{
|
||||||
|
mobj_t *ret = NULL;
|
||||||
|
UINT8 bestPosition = UINT8_MAX;
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
player_t *player = NULL;
|
||||||
|
|
||||||
|
if (playeringame[i] == false)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
player = &players[i];
|
||||||
|
if (player->spectator || player->exiting)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player->mo || P_MobjWasRemoved(player->mo))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignore != NULL && player->mo == ignore)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->position < bestPosition)
|
||||||
|
{
|
||||||
|
ret = player->mo;
|
||||||
|
bestPosition = player->position;
|
||||||
|
|
||||||
|
if (bestPosition <= 1)
|
||||||
|
{
|
||||||
|
// Can't get any lower
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_confused (mobj_t *hyu)
|
||||||
|
{
|
||||||
|
// Hyudoro is confused.
|
||||||
|
// Spin around, try to find a new target.
|
||||||
|
|
||||||
|
if (hyudoro_delivered(hyu))
|
||||||
|
{
|
||||||
|
// Already delivered, not confused
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find new target
|
||||||
|
P_SetTarget(&hyudoro_target(hyu),
|
||||||
|
find_duel_target(hyudoro_stolefrom(hyu)));
|
||||||
|
|
||||||
|
// Spin in circles
|
||||||
|
hyu->angle += ANGLE_45;
|
||||||
|
|
||||||
|
// Bob very fast
|
||||||
|
bob_in_place(hyu, 32);
|
||||||
|
|
||||||
|
hyu->sprzoff += hyu->height;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
move_to_player (mobj_t *hyu)
|
move_to_player (mobj_t *hyu)
|
||||||
{
|
{
|
||||||
|
|
@ -181,8 +276,11 @@ move_to_player (mobj_t *hyu)
|
||||||
angle_t angle;
|
angle_t angle;
|
||||||
fixed_t speed;
|
fixed_t speed;
|
||||||
|
|
||||||
if (!target)
|
if (!target || P_MobjWasRemoved(target))
|
||||||
|
{
|
||||||
|
do_confused(hyu);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
angle = R_PointToAngle2(
|
angle = R_PointToAngle2(
|
||||||
hyu->x, hyu->y, target->x, target->y);
|
hyu->x, hyu->y, target->x, target->y);
|
||||||
|
|
@ -232,6 +330,9 @@ deliver_item (mobj_t *hyu)
|
||||||
hyu->destscale = target->scale / 4;
|
hyu->destscale = target->scale / 4;
|
||||||
hyu->scalespeed =
|
hyu->scalespeed =
|
||||||
abs(hyu->scale - hyu->destscale) / hyu->tics;
|
abs(hyu->scale - hyu->destscale) / hyu->tics;
|
||||||
|
|
||||||
|
// sets as already delivered
|
||||||
|
hyudoro_itemtype(hyu) = KITEM_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -287,11 +388,14 @@ hyudoro_patrol_hit_player
|
||||||
|
|
||||||
mobj_t *center = hyudoro_center(hyu);
|
mobj_t *center = hyudoro_center(hyu);
|
||||||
|
|
||||||
|
mobj_t *master = NULL;
|
||||||
|
|
||||||
if (!player)
|
if (!player)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Cannot hit its master
|
// Cannot hit its master
|
||||||
if (toucher == get_hyudoro_master(hyu))
|
master = get_hyudoro_master(hyu);
|
||||||
|
if (toucher == master)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Don't punish a punished player
|
// Don't punish a punished player
|
||||||
|
|
@ -313,8 +417,15 @@ hyudoro_patrol_hit_player
|
||||||
player->hyudorotimer = hyudorotime;
|
player->hyudorotimer = hyudorotime;
|
||||||
player->stealingtimer = hyudorotime;
|
player->stealingtimer = hyudorotime;
|
||||||
|
|
||||||
P_SetTarget(&hyudoro_target(hyu),
|
P_SetTarget(&hyudoro_stolefrom(hyu), toucher);
|
||||||
hyudoro_center_master(center));
|
|
||||||
|
if (master == NULL || P_MobjWasRemoved(master))
|
||||||
|
{
|
||||||
|
// if master is NULL, it is probably a DUEL
|
||||||
|
master = find_duel_target(toucher);
|
||||||
|
}
|
||||||
|
|
||||||
|
P_SetTarget(&hyudoro_target(hyu), master);
|
||||||
|
|
||||||
if (center)
|
if (center)
|
||||||
P_RemoveMobj(center);
|
P_RemoveMobj(center);
|
||||||
|
|
@ -388,11 +499,8 @@ hyudoro_hover_await_stack (mobj_t *hyu)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Obj_HyudoroDeploy (mobj_t *master)
|
Obj_InitHyudoroCenter (mobj_t * center, mobj_t * master)
|
||||||
{
|
{
|
||||||
mobj_t *center = P_SpawnMobjFromMobj(
|
|
||||||
master, 0, 0, 0, MT_HYUDORO_CENTER);
|
|
||||||
|
|
||||||
mobj_t *hyu = P_SpawnMobjFromMobj(
|
mobj_t *hyu = P_SpawnMobjFromMobj(
|
||||||
center, 0, 0, 0, MT_HYUDORO);
|
center, 0, 0, 0, MT_HYUDORO);
|
||||||
|
|
||||||
|
|
@ -405,20 +513,30 @@ Obj_HyudoroDeploy (mobj_t *master)
|
||||||
|
|
||||||
center->radius = hyu->radius;
|
center->radius = hyu->radius;
|
||||||
|
|
||||||
hyu->angle = master->angle;
|
hyu->angle = center->angle;
|
||||||
P_SetTarget(&hyudoro_center(hyu), center);
|
P_SetTarget(&hyudoro_center(hyu), center);
|
||||||
P_SetTarget(&hyudoro_center_master(center), master);
|
P_SetTarget(&hyudoro_center_master(center), master);
|
||||||
|
|
||||||
hyudoro_mode(hyu) = HYU_PATROL;
|
hyudoro_mode(hyu) = HYU_PATROL;
|
||||||
|
|
||||||
// Set splitscreen player visibility
|
// Set splitscreen player visibility
|
||||||
if (master->player)
|
hyu->renderflags |= RF_DONTDRAW;
|
||||||
|
if (master && !P_MobjWasRemoved(master) && master->player)
|
||||||
{
|
{
|
||||||
hyu->renderflags |= RF_DONTDRAW &
|
hyu->renderflags &= ~(K_GetPlayerDontDrawFlag(master->player));
|
||||||
~(K_GetPlayerDontDrawFlag(master->player));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spawn_hyudoro_shadow(hyu); // this sucks btw
|
spawn_hyudoro_shadow(hyu); // this sucks btw
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Obj_HyudoroDeploy (mobj_t *master)
|
||||||
|
{
|
||||||
|
mobj_t *center = P_SpawnMobjFromMobj(
|
||||||
|
master, 0, 0, 0, MT_HYUDORO_CENTER);
|
||||||
|
|
||||||
|
center->angle = master->angle;
|
||||||
|
Obj_InitHyudoroCenter(center, master);
|
||||||
|
|
||||||
S_StartSound(master, sfx_s3k92); // scary ghost noise
|
S_StartSound(master, sfx_s3k92); // scary ghost noise
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -356,6 +356,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
Obj_SPBTouch(special, toucher);
|
Obj_SPBTouch(special, toucher);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case MT_DUELBOMB:
|
||||||
|
{
|
||||||
|
Obj_DuelBombTouch(special, toucher);
|
||||||
|
return;
|
||||||
|
}
|
||||||
case MT_EMERALD:
|
case MT_EMERALD:
|
||||||
if (!P_CanPickupItem(player, 0))
|
if (!P_CanPickupItem(player, 0))
|
||||||
return;
|
return;
|
||||||
|
|
@ -1012,7 +1017,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
||||||
{
|
{
|
||||||
target->fuse = 2;
|
target->fuse = 2;
|
||||||
}
|
}
|
||||||
else
|
else if (inDuel == false)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
|
|
|
||||||
72
src/p_mobj.c
72
src/p_mobj.c
|
|
@ -1707,7 +1707,13 @@ void P_XYMovement(mobj_t *mo)
|
||||||
|
|
||||||
if (walltransferred == false)
|
if (walltransferred == false)
|
||||||
{
|
{
|
||||||
if (mo->flags & MF_SLIDEME)
|
if (mo->type == MT_DUELBOMB)
|
||||||
|
{
|
||||||
|
P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BUMP);
|
||||||
|
Obj_DuelBombReverse(mo);
|
||||||
|
xmove = ymove = 0;
|
||||||
|
}
|
||||||
|
else if (mo->flags & MF_SLIDEME)
|
||||||
{
|
{
|
||||||
P_SlideMove(mo);
|
P_SlideMove(mo);
|
||||||
if (P_MobjWasRemoved(mo))
|
if (P_MobjWasRemoved(mo))
|
||||||
|
|
@ -1759,13 +1765,13 @@ void P_XYMovement(mobj_t *mo)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MT_BUBBLESHIELDTRAP:
|
||||||
|
S_StartSound(mo, sfx_s3k44); // Bubble bounce
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bubble bounce
|
|
||||||
if (mo->type == MT_BUBBLESHIELDTRAP)
|
|
||||||
S_StartSound(mo, sfx_s3k44);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5132,6 +5138,7 @@ boolean P_IsKartFieldItem(INT32 type)
|
||||||
case MT_POGOSPRING:
|
case MT_POGOSPRING:
|
||||||
case MT_SINK:
|
case MT_SINK:
|
||||||
case MT_DROPTARGET:
|
case MT_DROPTARGET:
|
||||||
|
case MT_DUELBOMB:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -7008,6 +7015,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
case MT_LANDMINE:
|
case MT_LANDMINE:
|
||||||
mobj->friction = ORIG_FRICTION/4;
|
mobj->friction = ORIG_FRICTION/4;
|
||||||
|
|
||||||
|
if (mobj->target && mobj->target->player)
|
||||||
|
mobj->color = mobj->target->player->skincolor;
|
||||||
|
else
|
||||||
|
mobj->color = SKINCOLOR_SAPPHIRE;
|
||||||
|
|
||||||
if (mobj->momx || mobj->momy || mobj->momz)
|
if (mobj->momx || mobj->momy || mobj->momz)
|
||||||
{
|
{
|
||||||
mobj_t *ghost = P_SpawnGhostMobj(mobj);
|
mobj_t *ghost = P_SpawnGhostMobj(mobj);
|
||||||
|
|
@ -7066,6 +7078,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
case MT_SPBEXPLOSION:
|
case MT_SPBEXPLOSION:
|
||||||
mobj->health--;
|
mobj->health--;
|
||||||
break;
|
break;
|
||||||
|
case MT_DUELBOMB:
|
||||||
|
{
|
||||||
|
Obj_DuelBombThink(mobj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MT_EMERALD:
|
case MT_EMERALD:
|
||||||
{
|
{
|
||||||
if (battleovertime.enabled >= 10*TICRATE)
|
if (battleovertime.enabled >= 10*TICRATE)
|
||||||
|
|
@ -9890,6 +9907,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
||||||
case MT_SINK:
|
case MT_SINK:
|
||||||
case MT_ROCKETSNEAKER:
|
case MT_ROCKETSNEAKER:
|
||||||
case MT_SPB:
|
case MT_SPB:
|
||||||
|
case MT_DUELBOMB:
|
||||||
thing->shadowscale = 3*FRACUNIT/2;
|
thing->shadowscale = 3*FRACUNIT/2;
|
||||||
break;
|
break;
|
||||||
case MT_BANANA_SHIELD:
|
case MT_BANANA_SHIELD:
|
||||||
|
|
@ -11741,10 +11759,22 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inDuel == false)
|
||||||
|
{
|
||||||
|
if (K_IsDuelItem(i) == true
|
||||||
|
&& K_DuelItemAlwaysSpawns(mthing) == false)
|
||||||
|
{
|
||||||
|
// Only spawns in Duels.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// No bosses outside of a combat situation.
|
// No bosses outside of a combat situation.
|
||||||
// (just in case we want boss arenas to do double duty as battle maps)
|
// (just in case we want boss arenas to do double duty as battle maps)
|
||||||
if (!bossinfo.boss && (mobjinfo[i].flags & MF_BOSS))
|
if (!bossinfo.boss && (mobjinfo[i].flags & MF_BOSS))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (metalrecording) // Metal Sonic can't use these things.
|
if (metalrecording) // Metal Sonic can't use these things.
|
||||||
{
|
{
|
||||||
|
|
@ -12903,6 +12933,33 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
||||||
|
|
||||||
// Increment no. of capsules on the map counter
|
// Increment no. of capsules on the map counter
|
||||||
maptargets++;
|
maptargets++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MT_DUELBOMB:
|
||||||
|
{
|
||||||
|
// Duel Bomb needs init to match real map thing's angle
|
||||||
|
mobj->angle = FixedAngle(mthing->angle << FRACBITS);
|
||||||
|
Obj_DuelBombInit(mobj);
|
||||||
|
*doangle = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MT_BANANA:
|
||||||
|
{
|
||||||
|
// Give Duel bananas a random angle
|
||||||
|
mobj->angle = FixedMul(P_RandomFixed(PR_DECORATION), ANGLE_MAX);
|
||||||
|
*doangle = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MT_HYUDORO_CENTER:
|
||||||
|
{
|
||||||
|
Obj_InitHyudoroCenter(mobj, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MT_POGOSPRING:
|
||||||
|
{
|
||||||
|
// Start as tumble version.
|
||||||
|
mobj->reactiontime++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -12943,6 +13000,11 @@ static void P_SetAmbush(mobj_t *mobj)
|
||||||
mobj->type != MT_NIGHTSBUMPER &&
|
mobj->type != MT_NIGHTSBUMPER &&
|
||||||
mobj->type != MT_STARPOST)
|
mobj->type != MT_STARPOST)
|
||||||
mobj->flags2 |= MF2_AMBUSH;
|
mobj->flags2 |= MF2_AMBUSH;
|
||||||
|
|
||||||
|
if (mobj->type == MT_DUELBOMB)
|
||||||
|
{
|
||||||
|
Obj_DuelBombReverse(mobj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_SetObjectSpecial(mobj_t *mobj)
|
static void P_SetObjectSpecial(mobj_t *mobj)
|
||||||
|
|
|
||||||
|
|
@ -4591,6 +4591,7 @@ static void P_NetArchiveMisc(boolean resending)
|
||||||
WRITEUINT8(save_p, lastLowestLap);
|
WRITEUINT8(save_p, lastLowestLap);
|
||||||
WRITESINT8(save_p, spbplace);
|
WRITESINT8(save_p, spbplace);
|
||||||
WRITEUINT8(save_p, rainbowstartavailable);
|
WRITEUINT8(save_p, rainbowstartavailable);
|
||||||
|
WRITEUINT8(save_p, inDuel);
|
||||||
|
|
||||||
WRITEUINT32(save_p, introtime);
|
WRITEUINT32(save_p, introtime);
|
||||||
WRITEUINT32(save_p, starttime);
|
WRITEUINT32(save_p, starttime);
|
||||||
|
|
@ -4750,6 +4751,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
||||||
lastLowestLap = READUINT8(save_p);
|
lastLowestLap = READUINT8(save_p);
|
||||||
spbplace = READSINT8(save_p);
|
spbplace = READSINT8(save_p);
|
||||||
rainbowstartavailable = (boolean)READUINT8(save_p);
|
rainbowstartavailable = (boolean)READUINT8(save_p);
|
||||||
|
inDuel = (boolean)READUINT8(save_p);
|
||||||
|
|
||||||
introtime = READUINT32(save_p);
|
introtime = READUINT32(save_p);
|
||||||
starttime = READUINT32(save_p);
|
starttime = READUINT32(save_p);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue