mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-23 03:12:38 +00:00
Merge branch 'new-acz-minecarts' into 'master'
ACZ hardcoding (including minecarts) See merge request STJr/SRB2Internal!231
This commit is contained in:
commit
e20949ef77
13 changed files with 3206 additions and 180 deletions
|
@ -232,7 +232,8 @@ typedef enum
|
|||
// Specific level gimmicks.
|
||||
CR_ZOOMTUBE,
|
||||
CR_ROPEHANG,
|
||||
CR_MACESPIN
|
||||
CR_MACESPIN,
|
||||
CR_MINECART
|
||||
} carrytype_t; // pw_carry
|
||||
|
||||
// Player powers. (don't edit this comment)
|
||||
|
|
183
src/dehacked.c
183
src/dehacked.c
|
@ -2265,6 +2265,9 @@ static actionpointer_t actionpointers[] =
|
|||
{{A_CrushclawLaunch}, "A_CRUSHCLAWLAUNCH"},
|
||||
{{A_VultureVtol}, "A_VULTUREVTOL"},
|
||||
{{A_VultureCheck}, "A_VULTURECHECK"},
|
||||
{{A_VultureHover}, "A_VULTUREHOVER"},
|
||||
{{A_VultureBlast}, "A_VULTUREBLAST"},
|
||||
{{A_VultureFly}, "A_VULTUREFLY"},
|
||||
{{A_SkimChase}, "A_SKIMCHASE"},
|
||||
{{A_1upThinker}, "A_1UPTHINKER"},
|
||||
{{A_SkullAttack}, "A_SKULLATTACK"},
|
||||
|
@ -2393,8 +2396,18 @@ static actionpointer_t actionpointers[] =
|
|||
{{A_Boss5MakeItRain}, "A_BOSS5MAKEITRAIN"},
|
||||
{{A_LookForBetter}, "A_LOOKFORBETTER"},
|
||||
{{A_Boss5BombExplode}, "A_BOSS5BOMBEXPLODE"},
|
||||
|
||||
{{NULL}, "NONE"},
|
||||
{{A_DustDevilThink}, "A_DUSTDEVILTHINK"},
|
||||
{{A_TNTExplode}, "A_TNTEXPLODE"},
|
||||
{{A_DebrisRandom}, "A_DEBRISRANDOM"},
|
||||
{{A_TrainCameo}, "A_TRAINCAMEO"},
|
||||
{{A_TrainCameo2}, "A_TRAINCAMEO2"},
|
||||
{{A_CanarivoreGas}, "A_CANARIVOREGAS"},
|
||||
{{A_KillSegments}, "A_KILLSEGMENTS"},
|
||||
{{A_SnapperSpawn}, "A_SNAPPERSPAWN"},
|
||||
{{A_SnapperThinker}, "A_SNAPPERTHINKER"},
|
||||
{{A_SaloonDoorSpawn}, "A_SALOONDOORSPAWN"},
|
||||
{{A_MinecartSparkThink}, "A_MINECARTSPARKTHINK"},
|
||||
{{NULL}, "NONE"},
|
||||
|
||||
// This NULL entry must be the last in the list
|
||||
{{NULL}, NULL},
|
||||
|
@ -4381,15 +4394,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
|
||||
// Vulture
|
||||
"S_VULTURE_STND",
|
||||
"S_VULTURE_VTOL1",
|
||||
"S_VULTURE_VTOL2",
|
||||
"S_VULTURE_VTOL3",
|
||||
"S_VULTURE_VTOL4",
|
||||
"S_VULTURE_DRIFT",
|
||||
"S_VULTURE_ZOOM1",
|
||||
"S_VULTURE_ZOOM2",
|
||||
"S_VULTURE_ZOOM3",
|
||||
"S_VULTURE_ZOOM4",
|
||||
"S_VULTURE_ZOOM5",
|
||||
"S_VULTURE_STUNNED",
|
||||
|
||||
// Pointy
|
||||
"S_POINTY1",
|
||||
|
@ -4440,15 +4448,31 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_EGGSHIELDBREAK",
|
||||
|
||||
// Green Snapper
|
||||
"S_SNAPPER_SPAWN",
|
||||
"S_SNAPPER_SPAWN2",
|
||||
"S_GSNAPPER_STND",
|
||||
"S_GSNAPPER1",
|
||||
"S_GSNAPPER2",
|
||||
"S_GSNAPPER3",
|
||||
"S_GSNAPPER4",
|
||||
"S_SNAPPER_XPLD",
|
||||
"S_SNAPPER_LEG",
|
||||
"S_SNAPPER_LEGRAISE",
|
||||
"S_SNAPPER_HEAD",
|
||||
|
||||
// Minus
|
||||
"S_MINUS_INIT",
|
||||
"S_MINUS_STND",
|
||||
"S_MINUS_DIGGING",
|
||||
"S_MINUS_DIGGING1",
|
||||
"S_MINUS_DIGGING2",
|
||||
"S_MINUS_DIGGING3",
|
||||
"S_MINUS_DIGGING4",
|
||||
"S_MINUS_BURST0",
|
||||
"S_MINUS_BURST1",
|
||||
"S_MINUS_BURST2",
|
||||
"S_MINUS_BURST3",
|
||||
"S_MINUS_BURST4",
|
||||
"S_MINUS_BURST5",
|
||||
"S_MINUS_POPUP",
|
||||
"S_MINUS_UPWARD1",
|
||||
"S_MINUS_UPWARD2",
|
||||
|
@ -4467,6 +4491,15 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_MINUS_DOWNWARD7",
|
||||
"S_MINUS_DOWNWARD8",
|
||||
|
||||
// Minus dirt
|
||||
"S_MINUSDIRT1",
|
||||
"S_MINUSDIRT2",
|
||||
"S_MINUSDIRT3",
|
||||
"S_MINUSDIRT4",
|
||||
"S_MINUSDIRT5",
|
||||
"S_MINUSDIRT6",
|
||||
"S_MINUSDIRT7",
|
||||
|
||||
// Spring Shell
|
||||
"S_SSHELL_STND",
|
||||
"S_SSHELL_RUN1",
|
||||
|
@ -4494,6 +4527,28 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_UNIDUS_RUN",
|
||||
"S_UNIDUS_BALL",
|
||||
|
||||
// Canarivore
|
||||
"S_CANARIVORE_LOOK",
|
||||
"S_CANARIVORE_AWAKEN1",
|
||||
"S_CANARIVORE_AWAKEN2",
|
||||
"S_CANARIVORE_AWAKEN3",
|
||||
"S_CANARIVORE_GAS1",
|
||||
"S_CANARIVORE_GAS2",
|
||||
"S_CANARIVORE_GAS3",
|
||||
"S_CANARIVORE_GAS4",
|
||||
"S_CANARIVORE_GAS5",
|
||||
"S_CANARIVORE_GASREPEAT",
|
||||
"S_CANARIVORE_CLOSE1",
|
||||
"S_CANARIVORE_CLOSE2",
|
||||
"S_CANARIVOREGAS_1",
|
||||
"S_CANARIVOREGAS_2",
|
||||
"S_CANARIVOREGAS_3",
|
||||
"S_CANARIVOREGAS_4",
|
||||
"S_CANARIVOREGAS_5",
|
||||
"S_CANARIVOREGAS_6",
|
||||
"S_CANARIVOREGAS_7",
|
||||
"S_CANARIVOREGAS_8",
|
||||
|
||||
// Boss Explosion
|
||||
"S_BOSSEXPLODE",
|
||||
|
||||
|
@ -5681,6 +5736,85 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_ARIDSIGN_CACTI",
|
||||
"S_ARIDSIGN_SHARPTURN",
|
||||
|
||||
// Oil lamp
|
||||
"S_OILLAMP",
|
||||
"S_OILLAMPFLARE",
|
||||
|
||||
// TNT barrel
|
||||
"S_TNTBARREL_STND1",
|
||||
"S_TNTBARREL_EXPL1",
|
||||
"S_TNTBARREL_EXPL2",
|
||||
"S_TNTBARREL_EXPL3",
|
||||
"S_TNTBARREL_EXPL4",
|
||||
"S_TNTBARREL_EXPL5",
|
||||
"S_TNTBARREL_EXPL6",
|
||||
"S_TNTBARREL_FLYING",
|
||||
|
||||
// TNT proximity shell
|
||||
"S_PROXIMITY_TNT",
|
||||
"S_PROXIMITY_TNT_TRIGGER1",
|
||||
"S_PROXIMITY_TNT_TRIGGER2",
|
||||
"S_PROXIMITY_TNT_TRIGGER3",
|
||||
"S_PROXIMITY_TNT_TRIGGER4",
|
||||
"S_PROXIMITY_TNT_TRIGGER5",
|
||||
"S_PROXIMITY_TNT_TRIGGER6",
|
||||
"S_PROXIMITY_TNT_TRIGGER7",
|
||||
"S_PROXIMITY_TNT_TRIGGER8",
|
||||
"S_PROXIMITY_TNT_TRIGGER9",
|
||||
"S_PROXIMITY_TNT_TRIGGER10",
|
||||
"S_PROXIMITY_TNT_TRIGGER11",
|
||||
"S_PROXIMITY_TNT_TRIGGER12",
|
||||
"S_PROXIMITY_TNT_TRIGGER13",
|
||||
"S_PROXIMITY_TNT_TRIGGER14",
|
||||
"S_PROXIMITY_TNT_TRIGGER15",
|
||||
"S_PROXIMITY_TNT_TRIGGER16",
|
||||
"S_PROXIMITY_TNT_TRIGGER17",
|
||||
"S_PROXIMITY_TNT_TRIGGER18",
|
||||
"S_PROXIMITY_TNT_TRIGGER19",
|
||||
"S_PROXIMITY_TNT_TRIGGER20",
|
||||
"S_PROXIMITY_TNT_TRIGGER21",
|
||||
"S_PROXIMITY_TNT_TRIGGER22",
|
||||
"S_PROXIMITY_TNT_TRIGGER23",
|
||||
|
||||
// Dust devil
|
||||
"S_DUSTDEVIL",
|
||||
"S_DUSTLAYER1",
|
||||
"S_DUSTLAYER2",
|
||||
"S_DUSTLAYER3",
|
||||
"S_DUSTLAYER4",
|
||||
"S_DUSTLAYER5",
|
||||
"S_ARIDDUST1",
|
||||
"S_ARIDDUST2",
|
||||
"S_ARIDDUST3",
|
||||
|
||||
// Minecart
|
||||
"S_MINECART_IDLE",
|
||||
"S_MINECART_DTH1",
|
||||
"S_MINECARTEND",
|
||||
"S_MINECARTSEG_FRONT",
|
||||
"S_MINECARTSEG_BACK",
|
||||
"S_MINECARTSEG_LEFT",
|
||||
"S_MINECARTSEG_RIGHT",
|
||||
"S_MINECARTSIDEMARK1",
|
||||
"S_MINECARTSIDEMARK2",
|
||||
"S_MINECARTSPARK",
|
||||
|
||||
// Saloon door
|
||||
"S_SALOONDOOR",
|
||||
"S_SALOONDOORTHINKER",
|
||||
|
||||
// Train cameo
|
||||
"S_TRAINCAMEOSPAWNER_1",
|
||||
"S_TRAINCAMEOSPAWNER_2",
|
||||
"S_TRAINCAMEOSPAWNER_3",
|
||||
"S_TRAINCAMEOSPAWNER_4",
|
||||
"S_TRAINCAMEOSPAWNER_5",
|
||||
"S_TRAINPUFFMAKER",
|
||||
|
||||
// Train
|
||||
"S_TRAINDUST",
|
||||
"S_TRAINSTEAM",
|
||||
|
||||
// Flame jet
|
||||
"S_FLAMEJETSTND",
|
||||
"S_FLAMEJETSTART",
|
||||
|
@ -7003,6 +7137,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_DUST3",
|
||||
"S_DUST4",
|
||||
|
||||
"S_WOODDEBRIS",
|
||||
|
||||
"S_ROCKSPAWN",
|
||||
|
||||
"S_ROCKCRUMBLEA",
|
||||
|
@ -7066,11 +7202,16 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_EGGGUARD", // Egg Guard
|
||||
"MT_EGGSHIELD", // Egg Guard's shield
|
||||
"MT_GSNAPPER", // Green Snapper
|
||||
"MT_SNAPPER_LEG", // Green Snapper leg
|
||||
"MT_SNAPPER_HEAD", // Green Snapper head
|
||||
"MT_MINUS", // Minus
|
||||
"MT_MINUSDIRT", // Minus dirt
|
||||
"MT_SPRINGSHELL", // Spring Shell
|
||||
"MT_YELLOWSHELL", // Spring Shell (yellow)
|
||||
"MT_UNIDUS", // Unidus
|
||||
"MT_UNIBALL", // Unidus Ball
|
||||
"MT_CANARIVORE", // Canarivore
|
||||
"MT_CANARIVORE_GAS", // Canarivore gas
|
||||
|
||||
// Generic Boss Items
|
||||
"MT_BOSSEXPLODE",
|
||||
|
@ -7369,6 +7510,26 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_ARIDSIGN_CAUTION",
|
||||
"MT_ARIDSIGN_CACTI",
|
||||
"MT_ARIDSIGN_SHARPTURN",
|
||||
"MT_OILLAMP",
|
||||
"MT_TNTBARREL",
|
||||
"MT_PROXIMITYTNT",
|
||||
"MT_DUSTDEVIL",
|
||||
"MT_DUSTLAYER",
|
||||
"MT_ARIDDUST",
|
||||
"MT_MINECART",
|
||||
"MT_MINECARTSEG",
|
||||
"MT_MINECARTSPAWNER",
|
||||
"MT_MINECARTEND",
|
||||
"MT_MINECARTENDSOLID",
|
||||
"MT_MINECARTSIDEMARK",
|
||||
"MT_MINECARTSPARK",
|
||||
"MT_SALOONDOOR",
|
||||
"MT_SALOONDOORTHINKER",
|
||||
"MT_TRAINCAMEOSPAWNER",
|
||||
"MT_TRAINSEG",
|
||||
"MT_TRAINDUSTSPAWNER",
|
||||
"MT_TRAINSTEAMSPAWNER",
|
||||
"MT_MINECARTSWITCHPOINT",
|
||||
|
||||
// Red Volcano Scenery
|
||||
"MT_FLAMEJET",
|
||||
|
@ -7691,6 +7852,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_EXPLODE", // Robot Explosion
|
||||
"MT_UWEXPLODE", // Underwater Explosion
|
||||
"MT_DUST",
|
||||
"MT_WOODDEBRIS",
|
||||
"MT_ROCKSPAWNER",
|
||||
"MT_FALLINGROCK",
|
||||
"MT_ROCKCRUMBLE1",
|
||||
|
@ -8366,6 +8528,7 @@ struct {
|
|||
{"CR_ZOOMTUBE",CR_ZOOMTUBE},
|
||||
{"CR_ROPEHANG",CR_ROPEHANG},
|
||||
{"CR_MACESPIN",CR_MACESPIN},
|
||||
{"CR_MINECART",CR_MINECART},
|
||||
|
||||
// Ring weapons (ringweapons_t)
|
||||
// Useful for A_GiveWeapon
|
||||
|
|
|
@ -172,9 +172,14 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_SPSH
|
||||
&lspr[NOLIGHT], // SPR_ESHI
|
||||
&lspr[NOLIGHT], // SPR_GSNP
|
||||
&lspr[NOLIGHT], // SPR_GSNL
|
||||
&lspr[NOLIGHT], // SPR_GSNH
|
||||
&lspr[NOLIGHT], // SPR_MNUS
|
||||
&lspr[NOLIGHT], // SPR_MNUD
|
||||
&lspr[NOLIGHT], // SPR_SSHL
|
||||
&lspr[NOLIGHT], // SPR_UNID
|
||||
&lspr[NOLIGHT], // SPR_CANA
|
||||
&lspr[NOLIGHT], // SPR_CANG
|
||||
|
||||
// Generic Boos Items
|
||||
&lspr[JETLIGHT_L], // SPR_JETF // Boss jet fumes
|
||||
|
@ -350,6 +355,19 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_WWSG
|
||||
&lspr[NOLIGHT], // SPR_WWS2
|
||||
&lspr[NOLIGHT], // SPR_WWS3
|
||||
&lspr[NOLIGHT], // SPR_OILL
|
||||
&lspr[NOLIGHT], // SPR_OILF
|
||||
&lspr[NOLIGHT], // SPR_BARR
|
||||
&lspr[NOLIGHT], // SPR_REMT
|
||||
&lspr[NOLIGHT], // SPR_TAZD
|
||||
&lspr[NOLIGHT], // SPR_ADST
|
||||
&lspr[NOLIGHT], // SPR_MCRT
|
||||
&lspr[NOLIGHT], // SPR_MCSP
|
||||
&lspr[NOLIGHT], // SPR_NON2
|
||||
&lspr[NOLIGHT], // SPR_SALD
|
||||
&lspr[NOLIGHT], // SPR_TRAE
|
||||
&lspr[NOLIGHT], // SPR_TRAI
|
||||
&lspr[NOLIGHT], // SPR_STEA
|
||||
|
||||
// Red Volcano Scenery
|
||||
&lspr[REDBALL_L], // SPR_FLME
|
||||
|
@ -542,6 +560,7 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[SUPERSPARK_L], // SPR_BOM3
|
||||
&lspr[NOLIGHT], // SPR_BOM4
|
||||
&lspr[REDBALL_L], // SPR_BMNB
|
||||
&lspr[NOLIGHT], // SPR_WDDB
|
||||
|
||||
// Crumbly rocks
|
||||
&lspr[NOLIGHT], // SPR_ROIA
|
||||
|
|
971
src/info.c
971
src/info.c
File diff suppressed because it is too large
Load diff
198
src/info.h
198
src/info.h
|
@ -115,6 +115,9 @@ void A_CrushclawAim();
|
|||
void A_CrushclawLaunch();
|
||||
void A_VultureVtol();
|
||||
void A_VultureCheck();
|
||||
void A_VultureHover();
|
||||
void A_VultureBlast();
|
||||
void A_VultureFly();
|
||||
void A_SkimChase();
|
||||
void A_SkullAttack();
|
||||
void A_LobShot();
|
||||
|
@ -251,6 +254,17 @@ void A_Boss5PinchShot();
|
|||
void A_Boss5MakeItRain();
|
||||
void A_LookForBetter();
|
||||
void A_Boss5BombExplode();
|
||||
void A_DustDevilThink();
|
||||
void A_TNTExplode();
|
||||
void A_DebrisRandom();
|
||||
void A_TrainCameo();
|
||||
void A_TrainCameo2();
|
||||
void A_CanarivoreGas();
|
||||
void A_KillSegments();
|
||||
void A_SnapperSpawn();
|
||||
void A_SnapperThinker();
|
||||
void A_SaloonDoorSpawn();
|
||||
void A_MinecartSparkThink();
|
||||
|
||||
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
||||
#define NUMMOBJFREESLOTS 512
|
||||
|
@ -291,9 +305,14 @@ typedef enum sprite
|
|||
SPR_SPSH, // Egg Guard
|
||||
SPR_ESHI, // Egg Guard's shield
|
||||
SPR_GSNP, // Green Snapper
|
||||
SPR_GSNL, // Green Snapper leg
|
||||
SPR_GSNH, // Green Snapper head
|
||||
SPR_MNUS, // Minus
|
||||
SPR_MNUD, // Minus dirt
|
||||
SPR_SSHL, // Spring Shell
|
||||
SPR_UNID, // Unidus
|
||||
SPR_CANA, // Canarivore
|
||||
SPR_CANG, // Canarivore gas
|
||||
|
||||
// Generic Boss Items
|
||||
SPR_JETF, // Boss jet fumes
|
||||
|
@ -476,6 +495,19 @@ typedef enum sprite
|
|||
SPR_WWSG, // Caution Sign
|
||||
SPR_WWS2, // Cacti Sign
|
||||
SPR_WWS3, // Sharp Turn Sign
|
||||
SPR_OILL, // Oil lamp
|
||||
SPR_OILF, // Oil lamp flare
|
||||
SPR_BARR, // TNT barrel
|
||||
SPR_REMT, // TNT proximity shell
|
||||
SPR_TAZD, // Dust devil
|
||||
SPR_ADST, // Arid dust
|
||||
SPR_MCRT, // Minecart
|
||||
SPR_MCSP, // Minecart spark
|
||||
SPR_NON2, // Saloon door thinker
|
||||
SPR_SALD, // Saloon door
|
||||
SPR_TRAE, // Train cameo locomotive
|
||||
SPR_TRAI, // Train cameo wagon
|
||||
SPR_STEA, // Train steam
|
||||
|
||||
// Red Volcano Scenery
|
||||
SPR_FLME, // Flame jet
|
||||
|
@ -668,6 +700,7 @@ typedef enum sprite
|
|||
SPR_BOM3, // Boss Explosion 2
|
||||
SPR_BOM4, // Underwater Explosion
|
||||
SPR_BMNB, // Mine Explosion
|
||||
SPR_WDDB, // Wood Debris
|
||||
|
||||
// Crumbly rocks
|
||||
SPR_ROIA,
|
||||
|
@ -1126,15 +1159,10 @@ typedef enum state
|
|||
|
||||
// Vulture
|
||||
S_VULTURE_STND,
|
||||
S_VULTURE_VTOL1,
|
||||
S_VULTURE_VTOL2,
|
||||
S_VULTURE_VTOL3,
|
||||
S_VULTURE_VTOL4,
|
||||
S_VULTURE_DRIFT,
|
||||
S_VULTURE_ZOOM1,
|
||||
S_VULTURE_ZOOM2,
|
||||
S_VULTURE_ZOOM3,
|
||||
S_VULTURE_ZOOM4,
|
||||
S_VULTURE_ZOOM5,
|
||||
S_VULTURE_STUNNED,
|
||||
|
||||
// Pointy
|
||||
S_POINTY1,
|
||||
|
@ -1185,15 +1213,31 @@ typedef enum state
|
|||
S_EGGSHIELDBREAK,
|
||||
|
||||
// Green Snapper
|
||||
S_SNAPPER_SPAWN,
|
||||
S_SNAPPER_SPAWN2,
|
||||
S_GSNAPPER_STND,
|
||||
S_GSNAPPER1,
|
||||
S_GSNAPPER2,
|
||||
S_GSNAPPER3,
|
||||
S_GSNAPPER4,
|
||||
S_SNAPPER_XPLD,
|
||||
S_SNAPPER_LEG,
|
||||
S_SNAPPER_LEGRAISE,
|
||||
S_SNAPPER_HEAD,
|
||||
|
||||
// Minus
|
||||
S_MINUS_INIT,
|
||||
S_MINUS_STND,
|
||||
S_MINUS_DIGGING,
|
||||
S_MINUS_DIGGING1,
|
||||
S_MINUS_DIGGING2,
|
||||
S_MINUS_DIGGING3,
|
||||
S_MINUS_DIGGING4,
|
||||
S_MINUS_BURST0,
|
||||
S_MINUS_BURST1,
|
||||
S_MINUS_BURST2,
|
||||
S_MINUS_BURST3,
|
||||
S_MINUS_BURST4,
|
||||
S_MINUS_BURST5,
|
||||
S_MINUS_POPUP,
|
||||
S_MINUS_UPWARD1,
|
||||
S_MINUS_UPWARD2,
|
||||
|
@ -1212,6 +1256,15 @@ typedef enum state
|
|||
S_MINUS_DOWNWARD7,
|
||||
S_MINUS_DOWNWARD8,
|
||||
|
||||
// Minus dirt
|
||||
S_MINUSDIRT1,
|
||||
S_MINUSDIRT2,
|
||||
S_MINUSDIRT3,
|
||||
S_MINUSDIRT4,
|
||||
S_MINUSDIRT5,
|
||||
S_MINUSDIRT6,
|
||||
S_MINUSDIRT7,
|
||||
|
||||
// Spring Shell
|
||||
S_SSHELL_STND,
|
||||
S_SSHELL_RUN1,
|
||||
|
@ -1239,6 +1292,28 @@ typedef enum state
|
|||
S_UNIDUS_RUN,
|
||||
S_UNIDUS_BALL,
|
||||
|
||||
// Canarivore
|
||||
S_CANARIVORE_LOOK,
|
||||
S_CANARIVORE_AWAKEN1,
|
||||
S_CANARIVORE_AWAKEN2,
|
||||
S_CANARIVORE_AWAKEN3,
|
||||
S_CANARIVORE_GAS1,
|
||||
S_CANARIVORE_GAS2,
|
||||
S_CANARIVORE_GAS3,
|
||||
S_CANARIVORE_GAS4,
|
||||
S_CANARIVORE_GAS5,
|
||||
S_CANARIVORE_GASREPEAT,
|
||||
S_CANARIVORE_CLOSE1,
|
||||
S_CANARIVORE_CLOSE2,
|
||||
S_CANARIVOREGAS_1,
|
||||
S_CANARIVOREGAS_2,
|
||||
S_CANARIVOREGAS_3,
|
||||
S_CANARIVOREGAS_4,
|
||||
S_CANARIVOREGAS_5,
|
||||
S_CANARIVOREGAS_6,
|
||||
S_CANARIVOREGAS_7,
|
||||
S_CANARIVOREGAS_8,
|
||||
|
||||
// Boss Explosion
|
||||
S_BOSSEXPLODE,
|
||||
|
||||
|
@ -2426,6 +2501,85 @@ typedef enum state
|
|||
S_ARIDSIGN_CACTI,
|
||||
S_ARIDSIGN_SHARPTURN,
|
||||
|
||||
// Oil lamp
|
||||
S_OILLAMP,
|
||||
S_OILLAMPFLARE,
|
||||
|
||||
// TNT barrel
|
||||
S_TNTBARREL_STND1,
|
||||
S_TNTBARREL_EXPL1,
|
||||
S_TNTBARREL_EXPL2,
|
||||
S_TNTBARREL_EXPL3,
|
||||
S_TNTBARREL_EXPL4,
|
||||
S_TNTBARREL_EXPL5,
|
||||
S_TNTBARREL_EXPL6,
|
||||
S_TNTBARREL_FLYING,
|
||||
|
||||
// TNT proximity shell
|
||||
S_PROXIMITY_TNT,
|
||||
S_PROXIMITY_TNT_TRIGGER1,
|
||||
S_PROXIMITY_TNT_TRIGGER2,
|
||||
S_PROXIMITY_TNT_TRIGGER3,
|
||||
S_PROXIMITY_TNT_TRIGGER4,
|
||||
S_PROXIMITY_TNT_TRIGGER5,
|
||||
S_PROXIMITY_TNT_TRIGGER6,
|
||||
S_PROXIMITY_TNT_TRIGGER7,
|
||||
S_PROXIMITY_TNT_TRIGGER8,
|
||||
S_PROXIMITY_TNT_TRIGGER9,
|
||||
S_PROXIMITY_TNT_TRIGGER10,
|
||||
S_PROXIMITY_TNT_TRIGGER11,
|
||||
S_PROXIMITY_TNT_TRIGGER12,
|
||||
S_PROXIMITY_TNT_TRIGGER13,
|
||||
S_PROXIMITY_TNT_TRIGGER14,
|
||||
S_PROXIMITY_TNT_TRIGGER15,
|
||||
S_PROXIMITY_TNT_TRIGGER16,
|
||||
S_PROXIMITY_TNT_TRIGGER17,
|
||||
S_PROXIMITY_TNT_TRIGGER18,
|
||||
S_PROXIMITY_TNT_TRIGGER19,
|
||||
S_PROXIMITY_TNT_TRIGGER20,
|
||||
S_PROXIMITY_TNT_TRIGGER21,
|
||||
S_PROXIMITY_TNT_TRIGGER22,
|
||||
S_PROXIMITY_TNT_TRIGGER23,
|
||||
|
||||
// Dust devil
|
||||
S_DUSTDEVIL,
|
||||
S_DUSTLAYER1,
|
||||
S_DUSTLAYER2,
|
||||
S_DUSTLAYER3,
|
||||
S_DUSTLAYER4,
|
||||
S_DUSTLAYER5,
|
||||
S_ARIDDUST1,
|
||||
S_ARIDDUST2,
|
||||
S_ARIDDUST3,
|
||||
|
||||
// Minecart
|
||||
S_MINECART_IDLE,
|
||||
S_MINECART_DTH1,
|
||||
S_MINECARTEND,
|
||||
S_MINECARTSEG_FRONT,
|
||||
S_MINECARTSEG_BACK,
|
||||
S_MINECARTSEG_LEFT,
|
||||
S_MINECARTSEG_RIGHT,
|
||||
S_MINECARTSIDEMARK1,
|
||||
S_MINECARTSIDEMARK2,
|
||||
S_MINECARTSPARK,
|
||||
|
||||
// Saloon door
|
||||
S_SALOONDOOR,
|
||||
S_SALOONDOORTHINKER,
|
||||
|
||||
// Train cameo
|
||||
S_TRAINCAMEOSPAWNER_1,
|
||||
S_TRAINCAMEOSPAWNER_2,
|
||||
S_TRAINCAMEOSPAWNER_3,
|
||||
S_TRAINCAMEOSPAWNER_4,
|
||||
S_TRAINCAMEOSPAWNER_5,
|
||||
S_TRAINPUFFMAKER,
|
||||
|
||||
// Train
|
||||
S_TRAINDUST,
|
||||
S_TRAINSTEAM,
|
||||
|
||||
// Flame jet
|
||||
S_FLAMEJETSTND,
|
||||
S_FLAMEJETSTART,
|
||||
|
@ -3748,6 +3902,8 @@ typedef enum state
|
|||
S_DUST3,
|
||||
S_DUST4,
|
||||
|
||||
S_WOODDEBRIS,
|
||||
|
||||
S_ROCKSPAWN,
|
||||
|
||||
S_ROCKCRUMBLEA,
|
||||
|
@ -3831,11 +3987,16 @@ typedef enum mobj_type
|
|||
MT_EGGGUARD, // Egg Guard
|
||||
MT_EGGSHIELD, // Egg Guard's shield
|
||||
MT_GSNAPPER, // Green Snapper
|
||||
MT_SNAPPER_LEG, // Green Snapper leg
|
||||
MT_SNAPPER_HEAD, // Green Snapper head
|
||||
MT_MINUS, // Minus
|
||||
MT_MINUSDIRT, // Minus dirt
|
||||
MT_SPRINGSHELL, // Spring Shell
|
||||
MT_YELLOWSHELL, // Spring Shell (yellow)
|
||||
MT_UNIDUS, // Unidus
|
||||
MT_UNIBALL, // Unidus Ball
|
||||
MT_CANARIVORE, // Canarivore
|
||||
MT_CANARIVORE_GAS, // Canarivore gas
|
||||
|
||||
// Generic Boss Items
|
||||
MT_BOSSEXPLODE,
|
||||
|
@ -4134,6 +4295,26 @@ typedef enum mobj_type
|
|||
MT_ARIDSIGN_CAUTION, // Caution Sign
|
||||
MT_ARIDSIGN_CACTI, // Cacti Sign
|
||||
MT_ARIDSIGN_SHARPTURN, // Sharp Turn Sign
|
||||
MT_OILLAMP,
|
||||
MT_TNTBARREL,
|
||||
MT_PROXIMITYTNT,
|
||||
MT_DUSTDEVIL,
|
||||
MT_DUSTLAYER,
|
||||
MT_ARIDDUST,
|
||||
MT_MINECART,
|
||||
MT_MINECARTSEG,
|
||||
MT_MINECARTSPAWNER,
|
||||
MT_MINECARTEND,
|
||||
MT_MINECARTENDSOLID,
|
||||
MT_MINECARTSIDEMARK,
|
||||
MT_MINECARTSPARK,
|
||||
MT_SALOONDOOR,
|
||||
MT_SALOONDOORTHINKER,
|
||||
MT_TRAINCAMEOSPAWNER,
|
||||
MT_TRAINSEG,
|
||||
MT_TRAINDUSTSPAWNER,
|
||||
MT_TRAINSTEAMSPAWNER,
|
||||
MT_MINECARTSWITCHPOINT,
|
||||
|
||||
// Red Volcano Scenery
|
||||
MT_FLAMEJET,
|
||||
|
@ -4456,6 +4637,7 @@ typedef enum mobj_type
|
|||
MT_EXPLODE, // Robot Explosion
|
||||
MT_UWEXPLODE, // Underwater Explosion
|
||||
MT_DUST,
|
||||
MT_WOODDEBRIS,
|
||||
MT_ROCKSPAWNER,
|
||||
MT_FALLINGROCK,
|
||||
MT_ROCKCRUMBLE1,
|
||||
|
|
1130
src/p_enemy.c
1130
src/p_enemy.c
File diff suppressed because it is too large
Load diff
|
@ -1699,6 +1699,73 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
}
|
||||
return;
|
||||
|
||||
case MT_CANARIVORE_GAS:
|
||||
// if player and gas touch, attach gas to player (overriding any gas that already attached) and apply slowdown effect
|
||||
P_UnsetThingPosition(special);
|
||||
special->x = toucher->x - toucher->momx/2;
|
||||
special->y = toucher->y - toucher->momy/2;
|
||||
special->z = toucher->z - toucher->momz/2;
|
||||
P_SetThingPosition(special);
|
||||
toucher->momx = FixedMul(toucher->momx, 50*FRACUNIT/51);
|
||||
toucher->momy = FixedMul(toucher->momy, 50*FRACUNIT/51);
|
||||
special->momx = toucher->momx;
|
||||
special->momy = toucher->momy;
|
||||
special->momz = toucher->momz;
|
||||
return;
|
||||
|
||||
case MT_MINECARTSPAWNER:
|
||||
if (!special->fuse || player->powers[pw_carry] != CR_MINECART)
|
||||
{
|
||||
mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART);
|
||||
P_SetTarget(&mcart->target, toucher);
|
||||
mcart->angle = toucher->angle = player->drawangle = special->angle;
|
||||
mcart->friction = FRACUNIT;
|
||||
|
||||
P_ResetPlayer(player);
|
||||
player->pflags |= PF_JUMPDOWN;
|
||||
player->powers[pw_carry] = CR_MINECART;
|
||||
toucher->player->pflags &= ~PF_APPLYAUTOBRAKE;
|
||||
P_SetTarget(&toucher->tracer, mcart);
|
||||
toucher->momx = toucher->momy = toucher->momz = 0;
|
||||
|
||||
special->fuse = 3*TICRATE;
|
||||
special->flags2 |= MF2_DONTDRAW;
|
||||
}
|
||||
return;
|
||||
|
||||
case MT_MINECARTEND:
|
||||
if (player->powers[pw_carry] == CR_MINECART && toucher->tracer && !P_MobjWasRemoved(toucher->tracer) && toucher->tracer->health)
|
||||
{
|
||||
fixed_t maxz = max(toucher->z, special->z + 35*special->scale);
|
||||
|
||||
toucher->momx = toucher->tracer->momx/2;
|
||||
toucher->momy = toucher->tracer->momy/2;
|
||||
toucher->momz = toucher->tracer->momz + P_AproxDistance(toucher->tracer->momx, toucher->tracer->momy)/2;
|
||||
P_ResetPlayer(player);
|
||||
player->pflags &= ~PF_APPLYAUTOBRAKE;
|
||||
P_SetPlayerMobjState(toucher, S_PLAY_FALL);
|
||||
P_SetTarget(&toucher->tracer->target, NULL);
|
||||
P_KillMobj(toucher->tracer, toucher, special, 0);
|
||||
P_SetTarget(&toucher->tracer, NULL);
|
||||
player->powers[pw_carry] = CR_NONE;
|
||||
P_UnsetThingPosition(toucher);
|
||||
toucher->x = special->x;
|
||||
toucher->y = special->y;
|
||||
toucher->z = maxz;
|
||||
P_SetThingPosition(toucher);
|
||||
}
|
||||
return;
|
||||
|
||||
case MT_MINECARTSWITCHPOINT:
|
||||
if (player->powers[pw_carry] == CR_MINECART && toucher->tracer && !P_MobjWasRemoved(toucher->tracer) && toucher->tracer->health)
|
||||
{
|
||||
mobjflag2_t destambush = special->flags2 & MF2_AMBUSH;
|
||||
angle_t angdiff = toucher->tracer->angle - special->angle;
|
||||
if (angdiff > ANGLE_90 && angdiff < ANGLE_270)
|
||||
destambush ^= MF2_AMBUSH;
|
||||
toucher->tracer->flags2 = (toucher->tracer->flags2 & ~MF2_AMBUSH) | destambush;
|
||||
}
|
||||
return;
|
||||
default: // SOC or script pickup
|
||||
if (player->bot)
|
||||
return;
|
||||
|
@ -2546,6 +2613,13 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
target->fuse = TICRATE*2;
|
||||
break;
|
||||
|
||||
case MT_MINECART:
|
||||
A_Scream(target);
|
||||
target->momx = target->momy = target->momz = 0;
|
||||
if (target->target && target->target->health)
|
||||
P_KillMobj(target->target, target, source, 0);
|
||||
break;
|
||||
|
||||
case MT_PLAYER:
|
||||
{
|
||||
target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player)
|
||||
|
@ -2960,6 +3034,9 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
|||
|
||||
P_ResetPlayer(player);
|
||||
|
||||
if (!player->spectator)
|
||||
player->mo->flags2 &= ~MF2_DONTDRAW;
|
||||
|
||||
P_SetPlayerMobjState(player->mo, player->mo->info->deathstate);
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
|
@ -3591,9 +3668,6 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
}
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
mo->momz *= -1;
|
||||
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
player->powers[pw_carry] = CR_NONE;
|
||||
}
|
||||
|
||||
player->losstime += 10*TICRATE;
|
||||
|
|
|
@ -229,6 +229,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
|
|||
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
|
||||
void P_RunShields(void);
|
||||
void P_RunOverlays(void);
|
||||
void P_HandleMinecartSegments(mobj_t *mobj);
|
||||
void P_MobjThinker(mobj_t *mobj);
|
||||
boolean P_RailThinker(mobj_t *mobj);
|
||||
void P_PushableThinker(mobj_t *mobj);
|
||||
|
|
87
src/p_map.c
87
src/p_map.c
|
@ -818,6 +818,83 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (tmthing->type == MT_MINECART)
|
||||
{
|
||||
//height check
|
||||
if (tmthing->z > thing->z + thing->height || thing->z > tmthing->z + tmthing->height || !(thing->health))
|
||||
return true;
|
||||
|
||||
if (thing->type == MT_TNTBARREL)
|
||||
P_KillMobj(thing, tmthing, tmthing->target, 0);
|
||||
else if ((thing->flags & MF_MONITOR) || (thing->flags & MF_ENEMY))
|
||||
{
|
||||
P_KillMobj(thing, tmthing, tmthing->target, 0);
|
||||
if (tmthing->momz*P_MobjFlip(tmthing) < 0)
|
||||
tmthing->momz = abs(tmthing->momz)*P_MobjFlip(tmthing);
|
||||
}
|
||||
}
|
||||
|
||||
if (thing->type == MT_SALOONDOOR && tmthing->player)
|
||||
{
|
||||
if (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer) && tmthing->tracer->health)
|
||||
{
|
||||
fixed_t dx = tmthing->tracer->momx;
|
||||
fixed_t dy = tmthing->tracer->momy;
|
||||
fixed_t dm = min(FixedHypot(dx, dy), 16*FRACUNIT);
|
||||
angle_t ang = R_PointToAngle2(0, 0, dx, dy) - thing->angle;
|
||||
fixed_t s = FINESINE((ang >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
S_StartSound(tmthing, thing->info->activesound);
|
||||
thing->extravalue2 += 2*FixedMul(s, dm)/3;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (thing->type == MT_TNTBARREL && tmthing->player)
|
||||
{
|
||||
if (tmthing->momz < 0)
|
||||
{
|
||||
if (tmthing->z + tmthing->momz > thing->z + thing->height)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmthing->z > thing->z + thing->height)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tmthing->momz > 0)
|
||||
{
|
||||
if (tmthing->z + tmthing->height + tmthing->momz < thing->z)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmthing->z + tmthing->height < thing->z)
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((tmthing->player->pflags & (PF_SPINNING | PF_GLIDING))
|
||||
|| ((tmthing->player->pflags & PF_JUMPED)
|
||||
&& (!(tmthing->player->pflags & PF_NOJUMPDAMAGE)
|
||||
|| (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
|
||||
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
|
||||
|| ((tmthing->player->charflags & SF_STOMPDAMAGE || tmthing->player->pflags & PF_BOUNCING)
|
||||
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height / 2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))
|
||||
|| (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (tmthing->player->pflags & PF_SHIELDABILITY)))
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
||||
}
|
||||
|
||||
if (thing->type == MT_VULTURE && tmthing->type == MT_VULTURE)
|
||||
{
|
||||
fixed_t dx = thing->x - tmthing->x;
|
||||
fixed_t dy = thing->y - tmthing->y;
|
||||
fixed_t dz = thing->z - tmthing->z;
|
||||
fixed_t dm = FixedHypot(dz, FixedHypot(dx, dy));
|
||||
thing->momx += FixedDiv(dx, dm);
|
||||
thing->momy += FixedDiv(dy, dm);
|
||||
thing->momz += FixedDiv(dz, dm);
|
||||
}
|
||||
|
||||
if (tmthing->type == MT_FANG && thing->type == MT_FSGNB)
|
||||
{
|
||||
if (thing->z > tmthing->z + tmthing->height)
|
||||
|
@ -1395,7 +1472,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
if (thing->type == MT_FAN || thing->type == MT_STEAM)
|
||||
P_DoFanAndGasJet(thing, tmthing);
|
||||
else if (thing->flags & MF_SPRING)
|
||||
else if (thing->flags & MF_SPRING && tmthing->player->powers[pw_carry] != CR_MINECART)
|
||||
{
|
||||
if ( thing->z <= tmthing->z + tmthing->height
|
||||
&& tmthing->z <= thing->z + thing->height)
|
||||
|
@ -3859,6 +3936,8 @@ static boolean nofit;
|
|||
static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
|
||||
{
|
||||
mobj_t *killer = NULL;
|
||||
//If a thing is both pushable and vulnerable, it doesn't block the crusher because it gets killed.
|
||||
boolean immunepushable = ((thing->flags & (MF_PUSHABLE | MF_SHOOTABLE)) == MF_PUSHABLE);
|
||||
|
||||
if (P_ThingHeightClip(thing))
|
||||
{
|
||||
|
@ -3877,7 +3956,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
|
|||
// just be blocked by another object - check if it's really a ceiling!
|
||||
if (thing->z + thing->height > thing->ceilingz && thing->z <= thing->ceilingz)
|
||||
{
|
||||
if (thing->flags & MF_PUSHABLE && thing->z + thing->height > thing->subsector->sector->ceilingheight)
|
||||
if (immunepushable && thing->z + thing->height > thing->subsector->sector->ceilingheight)
|
||||
{
|
||||
//Thing is a pushable and blocks the moving ceiling
|
||||
nofit = true;
|
||||
|
@ -3885,7 +3964,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
|
|||
}
|
||||
|
||||
//Check FOFs in the sector
|
||||
if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE))
|
||||
if (thing->subsector->sector->ffloors && (realcrush || immunepushable))
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
@ -3912,7 +3991,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
|
|||
delta2 = thingtop - (bottomheight + topheight)/2;
|
||||
if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2))
|
||||
{
|
||||
if (thing->flags & MF_PUSHABLE)
|
||||
if (immunepushable)
|
||||
{
|
||||
//FOF is blocked by pushable
|
||||
nofit = true;
|
||||
|
|
256
src/p_mobj.c
256
src/p_mobj.c
|
@ -2580,9 +2580,9 @@ static boolean P_ZMovement(mobj_t *mo)
|
|||
|
||||
if (!mo->player && P_CheckDeathPitCollide(mo))
|
||||
{
|
||||
if (mo->flags & MF_ENEMY || mo->flags & MF_BOSS)
|
||||
if (mo->flags & MF_ENEMY || mo->flags & MF_BOSS || mo->type == MT_MINECART)
|
||||
{
|
||||
// Kill enemies and bosses that fall into death pits.
|
||||
// Kill enemies, bosses and minecarts that fall into death pits.
|
||||
if (mo->health)
|
||||
{
|
||||
P_KillMobj(mo, NULL, NULL, 0);
|
||||
|
@ -6728,6 +6728,67 @@ static void P_KoopaThinker(mobj_t *koopa)
|
|||
}
|
||||
}
|
||||
|
||||
// Spawns and chains the minecart sides.
|
||||
static void P_SpawnMinecartSegments(mobj_t *mobj, boolean mode)
|
||||
{
|
||||
fixed_t x = mobj->x;
|
||||
fixed_t y = mobj->y;
|
||||
fixed_t z = mobj->z;
|
||||
mobj_t *prevseg = mobj;
|
||||
mobj_t *seg;
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
seg = P_SpawnMobj(x, y, z, MT_MINECARTSEG);
|
||||
P_SetMobjState(seg, (statenum_t)(S_MINECARTSEG_FRONT + i));
|
||||
if (i >= 2)
|
||||
seg->extravalue1 = (i == 2) ? -18 : 18;
|
||||
else
|
||||
{
|
||||
seg->extravalue2 = (i == 0) ? 24 : -24;
|
||||
seg->cusval = -90;
|
||||
}
|
||||
if (!mode)
|
||||
seg->frame &= ~FF_ANIMATE;
|
||||
P_SetTarget(&prevseg->tracer, seg);
|
||||
prevseg = seg;
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the chained segments.
|
||||
static void P_UpdateMinecartSegments(mobj_t *mobj)
|
||||
{
|
||||
mobj_t *seg = mobj->tracer;
|
||||
fixed_t x = mobj->x;
|
||||
fixed_t y = mobj->y;
|
||||
fixed_t z = mobj->z;
|
||||
angle_t ang = mobj->angle;
|
||||
angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t c = FINECOSINE(fa);
|
||||
fixed_t s = FINESINE(fa);
|
||||
INT32 dx, dy;
|
||||
INT32 sang;
|
||||
|
||||
while (seg)
|
||||
{
|
||||
dx = seg->extravalue1;
|
||||
dy = seg->extravalue2;
|
||||
sang = seg->cusval;
|
||||
P_TeleportMove(seg, x + s*dx + c*dy, y - c*dx + s*dy, z);
|
||||
seg->angle = ang + FixedAngle(FRACUNIT*sang);
|
||||
seg->flags2 = (seg->flags2 & ~MF2_DONTDRAW) | (mobj->flags2 & MF2_DONTDRAW);
|
||||
seg = seg->tracer;
|
||||
}
|
||||
}
|
||||
|
||||
void P_HandleMinecartSegments(mobj_t *mobj)
|
||||
{
|
||||
if (!mobj->tracer)
|
||||
P_SpawnMinecartSegments(mobj, (mobj->type == MT_MINECART));
|
||||
P_UpdateMinecartSegments(mobj);
|
||||
}
|
||||
|
||||
//
|
||||
// P_MobjThinker
|
||||
//
|
||||
|
@ -7502,38 +7563,35 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
break;
|
||||
case MT_PLAYER:
|
||||
/// \todo Have the player's dead body completely finish its animation even if they've already respawned.
|
||||
if (!(mobj->flags2 & MF2_DONTDRAW))
|
||||
{
|
||||
if (!mobj->fuse)
|
||||
{ // Go away.
|
||||
/// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it.
|
||||
mobj->momz = 0;
|
||||
if (mobj->player)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
else // safe to remove, nobody's going to complain!
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else // Apply gravity to fall downwards.
|
||||
if (!mobj->fuse)
|
||||
{ // Go away.
|
||||
/// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it.
|
||||
mobj->momz = 0;
|
||||
if (mobj->player)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
else // safe to remove, nobody's going to complain!
|
||||
{
|
||||
if (mobj->player && !(mobj->fuse % 8) && (mobj->player->charflags & SF_MACHINE))
|
||||
{
|
||||
fixed_t r = mobj->radius>>FRACBITS;
|
||||
mobj_t *explosion = P_SpawnMobj(
|
||||
mobj->x + (P_RandomRange(r, -r)<<FRACBITS),
|
||||
mobj->y + (P_RandomRange(r, -r)<<FRACBITS),
|
||||
mobj->z + (P_RandomKey(mobj->height>>FRACBITS)<<FRACBITS),
|
||||
MT_BOSSEXPLODE);
|
||||
S_StartSound(explosion, sfx_cybdth);
|
||||
}
|
||||
if (mobj->movedir == DMG_DROWNED)
|
||||
P_SetObjectMomZ(mobj, -FRACUNIT/2, true); // slower fall from drowning
|
||||
else
|
||||
P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true);
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else // Apply gravity to fall downwards.
|
||||
{
|
||||
if (mobj->player && !(mobj->fuse % 8) && (mobj->player->charflags & SF_MACHINE))
|
||||
{
|
||||
fixed_t r = mobj->radius >> FRACBITS;
|
||||
mobj_t *explosion = P_SpawnMobj(
|
||||
mobj->x + (P_RandomRange(r, -r) << FRACBITS),
|
||||
mobj->y + (P_RandomRange(r, -r) << FRACBITS),
|
||||
mobj->z + (P_RandomKey(mobj->height >> FRACBITS) << FRACBITS),
|
||||
MT_BOSSEXPLODE);
|
||||
S_StartSound(explosion, sfx_cybdth);
|
||||
}
|
||||
if (mobj->movedir == DMG_DROWNED)
|
||||
P_SetObjectMomZ(mobj, -FRACUNIT / 2, true); // slower fall from drowning
|
||||
else
|
||||
P_SetObjectMomZ(mobj, -2 * FRACUNIT / 3, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -8412,6 +8470,114 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
}
|
||||
break;
|
||||
case MT_TRAINDUSTSPAWNER:
|
||||
if (leveltime % 5 == 0) {
|
||||
mobj_t *traindust = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PARTICLE);
|
||||
traindust->flags = MF_SCENERY;
|
||||
P_SetMobjState(traindust, S_TRAINDUST);
|
||||
traindust->frame = P_RandomRange(0, 8) | FF_TRANS90;
|
||||
traindust->angle = mobj->angle;
|
||||
traindust->tics = TICRATE * 4;
|
||||
traindust->destscale = FRACUNIT * 64;
|
||||
traindust->scalespeed = FRACUNIT / 24;
|
||||
P_SetScale(traindust, FRACUNIT * 6);
|
||||
}
|
||||
break;
|
||||
case MT_TRAINSTEAMSPAWNER:
|
||||
if (leveltime % 5 == 0) {
|
||||
mobj_t *steam = P_SpawnMobj(mobj->x + FRACUNIT*P_SignedRandom() / 2, mobj->y + FRACUNIT*P_SignedRandom() / 2, mobj->z, MT_PARTICLE);
|
||||
P_SetMobjState(steam, S_TRAINSTEAM);
|
||||
steam->frame = P_RandomRange(0, 1) | FF_TRANS90;
|
||||
steam->tics = TICRATE * 8;
|
||||
steam->destscale = FRACUNIT * 64;
|
||||
steam->scalespeed = FRACUNIT / 8;
|
||||
P_SetScale(steam, FRACUNIT * 16);
|
||||
steam->momx = P_SignedRandom() * 32;
|
||||
steam->momy = -64 * FRACUNIT;
|
||||
steam->momz = 2 * FRACUNIT;
|
||||
}
|
||||
break;
|
||||
case MT_CANARIVORE_GAS:
|
||||
{
|
||||
fixed_t momz;
|
||||
|
||||
if (mobj->flags2 & MF2_AMBUSH)
|
||||
{
|
||||
mobj->momx = FixedMul(mobj->momx, 50 * FRACUNIT / 51);
|
||||
mobj->momy = FixedMul(mobj->momy, 50 * FRACUNIT / 51);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if ((mobj->z + mobj->height + mobj->momz) <= mobj->ceilingz)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((mobj->z + mobj->momz) >= mobj->floorz)
|
||||
break;
|
||||
}
|
||||
|
||||
momz = abs(mobj->momz);
|
||||
if (R_PointToDist2(0, 0, mobj->momx, mobj->momy) < momz)
|
||||
P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), momz);
|
||||
mobj->flags |= MF_NOGRAVITY|MF_NOCLIPHEIGHT;
|
||||
mobj->flags2 |= MF2_AMBUSH;
|
||||
break;
|
||||
}
|
||||
case MT_SALOONDOOR:
|
||||
{
|
||||
fixed_t x = mobj->tracer->x;
|
||||
fixed_t y = mobj->tracer->y;
|
||||
fixed_t z = mobj->tracer->z;
|
||||
angle_t oang = FixedAngle(mobj->extravalue1);
|
||||
angle_t fa = (oang >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t c0 = -96*FINECOSINE(fa);
|
||||
fixed_t s0 = -96*FINESINE(fa);
|
||||
angle_t fma;
|
||||
fixed_t c, s;
|
||||
angle_t angdiff;
|
||||
|
||||
// Adjust angular speed
|
||||
fixed_t da = AngleFixed(mobj->angle - oang);
|
||||
if (da > 180*FRACUNIT)
|
||||
da -= 360*FRACUNIT;
|
||||
mobj->extravalue2 = 8*(mobj->extravalue2 - da/32)/9;
|
||||
|
||||
// Update angle
|
||||
mobj->angle += FixedAngle(mobj->extravalue2);
|
||||
|
||||
angdiff = mobj->angle - FixedAngle(mobj->extravalue1);
|
||||
if (angdiff > (ANGLE_90 - ANG2) && angdiff < ANGLE_180)
|
||||
{
|
||||
mobj->angle = FixedAngle(mobj->extravalue1) + (ANGLE_90 - ANG2);
|
||||
mobj->extravalue2 /= 2;
|
||||
}
|
||||
else if (angdiff < (ANGLE_270 + ANG2) && angdiff >= ANGLE_180)
|
||||
{
|
||||
mobj->angle = FixedAngle(mobj->extravalue1) + (ANGLE_270 + ANG2);
|
||||
mobj->extravalue2 /= 2;
|
||||
}
|
||||
|
||||
// Update position
|
||||
fma = (mobj->angle >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
c = 48*FINECOSINE(fma);
|
||||
s = 48*FINESINE(fma);
|
||||
P_TeleportMove(mobj, x + c0 + c, y + s0 + s, z);
|
||||
break;
|
||||
}
|
||||
case MT_MINECARTSPAWNER:
|
||||
P_HandleMinecartSegments(mobj);
|
||||
if (!mobj->fuse || mobj->fuse > TICRATE)
|
||||
break;
|
||||
if (mobj->fuse == 2)
|
||||
{
|
||||
mobj->fuse = 0;
|
||||
break;
|
||||
}
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
break;
|
||||
case MT_SPINFIRE:
|
||||
if (mobj->flags & MF_NOGRAVITY)
|
||||
{
|
||||
|
@ -8488,6 +8654,10 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
// Check fuse
|
||||
if (mobj->fuse)
|
||||
{
|
||||
|
||||
if (mobj->type == MT_SNAPPER_HEAD || mobj->type == MT_SNAPPER_LEG || mobj->type == MT_MINECARTSEG)
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
|
||||
mobj->fuse--;
|
||||
if (!mobj->fuse)
|
||||
{
|
||||
|
@ -8789,6 +8959,16 @@ void P_PushableThinker(mobj_t *mobj)
|
|||
if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy))
|
||||
P_TryMove(mobj, mobj->x, mobj->y, true);
|
||||
|
||||
if (mobj->type == MT_MINECART && mobj->health)
|
||||
{
|
||||
// If player is ded, remove this minecart
|
||||
if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->health || !mobj->target->player || mobj->target->player->powers[pw_carry] != CR_MINECART)
|
||||
{
|
||||
P_KillMobj(mobj, NULL, NULL, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mobj->fuse == 1) // it would explode in the MobjThinker code
|
||||
{
|
||||
mobj_t *spawnmo;
|
||||
|
@ -9152,6 +9332,20 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
case MT_FBOMB:
|
||||
mobj->flags2 |= MF2_EXPLOSION;
|
||||
break;
|
||||
case MT_OILLAMP:
|
||||
{
|
||||
mobj_t* overlay = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY);
|
||||
P_SetTarget(&overlay->target, mobj);
|
||||
P_SetMobjState(overlay, S_OILLAMPFLARE);
|
||||
break;
|
||||
}
|
||||
case MT_TNTBARREL:
|
||||
mobj->momx = 1; //stack hack
|
||||
break;
|
||||
case MT_MINECARTEND:
|
||||
mobj->tracer = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID);
|
||||
mobj->tracer->angle = mobj->angle + ANGLE_90;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
434
src/p_user.c
434
src/p_user.c
|
@ -963,7 +963,7 @@ void P_ResetPlayer(player_t *player)
|
|||
{
|
||||
player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY|PF_BOUNCING);
|
||||
|
||||
if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_NIGHTSFALL || player->powers[pw_carry] == CR_BRAKGOOP))
|
||||
if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_NIGHTSFALL || player->powers[pw_carry] == CR_BRAKGOOP || player->powers[pw_carry] == CR_MINECART))
|
||||
player->powers[pw_carry] = CR_NONE;
|
||||
|
||||
player->secondjump = 0;
|
||||
|
@ -9753,6 +9753,417 @@ void P_DoPityCheck(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *nz)
|
||||
{
|
||||
sector_t *sec = R_PointInSubsector(x, y)->sector;
|
||||
|
||||
if ((sec->ceilingheight - sec->floorheight) < 64*FRACUNIT)
|
||||
return NULL;
|
||||
|
||||
if (sec->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
*nz = *rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight;
|
||||
if (abs(z - *nz) <= 56*FRACUNIT)
|
||||
{
|
||||
sec = §ors[rover->secnum];
|
||||
return sec;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*nz = sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : sec->floorheight;
|
||||
if (abs(z - *nz) > 56*FRACUNIT)
|
||||
return NULL;
|
||||
|
||||
return sec;
|
||||
}
|
||||
|
||||
static INT32 P_GetMinecartSpecialLine(sector_t *sec)
|
||||
{
|
||||
INT32 line = -1;
|
||||
|
||||
if (!sec)
|
||||
return line;
|
||||
|
||||
if (sec->tag != 0)
|
||||
line = P_FindSpecialLineFromTag(16, sec->tag, -1);
|
||||
|
||||
// Also try for lines facing the sector itself, with tag 0.
|
||||
{
|
||||
UINT32 i;
|
||||
for (i = 0; i < sec->linecount; i++)
|
||||
{
|
||||
line_t *li = sec->lines[i];
|
||||
if (li->tag == 0 && li->special == 16 && li->frontsector == sec)
|
||||
line = li - lines;
|
||||
}
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
// Get an axis of a certain ID number
|
||||
static mobj_t *P_GetAxis(INT32 num)
|
||||
{
|
||||
thinker_t *th;
|
||||
mobj_t *mobj;
|
||||
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mobj = (mobj_t *)th;
|
||||
|
||||
// NiGHTS axes spawn before anything else. If this mobj doesn't have MF2_AXIS, it means we reached the axes' end.
|
||||
if (!(mobj->flags2 & MF2_AXIS))
|
||||
break;
|
||||
|
||||
// Skip if this axis isn't the one we want.
|
||||
if (mobj->health != num)
|
||||
continue;
|
||||
|
||||
return mobj;
|
||||
}
|
||||
CONS_Alert(CONS_WARNING, "P_GetAxis: Track segment %d is missing!\n", num);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Auxiliary function. For a given position and axis, it calculates the nearest "valid" snap-on position.
|
||||
static void P_GetAxisPosition(fixed_t x, fixed_t y, mobj_t *amo, fixed_t *newx, fixed_t *newy, angle_t *targetangle, angle_t *grind)
|
||||
{
|
||||
fixed_t ax = amo->x;
|
||||
fixed_t ay = amo->y;
|
||||
angle_t ang;
|
||||
angle_t gr = 0;
|
||||
|
||||
if (amo->type == MT_AXISTRANSFERLINE)
|
||||
{
|
||||
ang = amo->angle;
|
||||
// Extra security for cardinal directions.
|
||||
if (ang == ANGLE_90 || ang == ANGLE_270) // Vertical lines
|
||||
x = ax;
|
||||
else if (ang == 0 || ang == ANGLE_180) // Horizontal lines
|
||||
y = ay;
|
||||
else // Diagonal lines
|
||||
{
|
||||
fixed_t distance = R_PointToDist2(ax, ay, x, y);
|
||||
angle_t fad = ((R_PointToAngle2(ax, ay, x, y) - ang) >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t cosine = FINECOSINE(fad);
|
||||
angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
distance = FixedMul(distance, cosine);
|
||||
x = ax + FixedMul(distance, FINECOSINE(fa));
|
||||
y = ay + FixedMul(distance, FINESINE(fa));
|
||||
}
|
||||
}
|
||||
else // Keep minecart to circle
|
||||
{
|
||||
fixed_t rad = amo->radius;
|
||||
fixed_t distfactor = FixedDiv(rad, R_PointToDist2(ax, ay, x, y));
|
||||
|
||||
gr = R_PointToAngle2(ax, ay, x, y);
|
||||
ang = gr + ANGLE_90;
|
||||
x = ax + FixedMul(x - ax, distfactor);
|
||||
y = ay + FixedMul(y - ay, distfactor);
|
||||
}
|
||||
|
||||
*newx = x;
|
||||
*newy = y;
|
||||
*targetangle = ang;
|
||||
*grind = gr;
|
||||
}
|
||||
|
||||
static void P_SpawnSparks(mobj_t *mo, angle_t maindir)
|
||||
{
|
||||
angle_t fa = (mo->angle >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t c = FixedMul(FINECOSINE(fa), mo->radius);
|
||||
fixed_t s = FixedMul(FINESINE(fa), mo->radius);
|
||||
mobj_t *spark;
|
||||
SINT8 b1 = (leveltime & 1) ? 1 : -1;
|
||||
SINT8 b2 = (leveltime & 2) ? 1 : -1;
|
||||
fixed_t r1 = FRACUNIT*P_RandomRange(-1, 1);
|
||||
fixed_t r2 = FRACUNIT*P_RandomRange(-1, 1);
|
||||
fixed_t r3 = FRACUNIT*P_RandomRange(-1, 1);
|
||||
fixed_t fm = (maindir >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
|
||||
spark = P_SpawnMobj(mo->x - b2*s + b1*c, mo->y + b2*c + b1*s, mo->z, MT_MINECARTSPARK);
|
||||
spark->momx = mo->momx + r1 + 8*FINECOSINE(fm);
|
||||
spark->momy = mo->momy + r2 + 8*FINESINE(fm);
|
||||
spark->momz = mo->momz + r3;
|
||||
|
||||
P_Thrust(spark, R_PointToAngle2(mo->x, mo->y, spark->x, spark->y), 8*FRACUNIT);
|
||||
P_SetScale(spark, FRACUNIT/4);
|
||||
spark->destscale = spark->scale;
|
||||
spark->fuse = TICRATE/3;
|
||||
}
|
||||
|
||||
// Performs a proximity check on a given direction looking for rails.
|
||||
static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t targetangle, fixed_t xcom, fixed_t ycom)
|
||||
{
|
||||
INT16 interval = 16;
|
||||
INT16 fwooffset = FixedHypot(mobj->momx, mobj->momy) >> FRACBITS;
|
||||
fixed_t x = mobj->x;
|
||||
fixed_t y = mobj->y;
|
||||
fixed_t z = mobj->z;
|
||||
UINT8 i;
|
||||
|
||||
for (i = 4; i <= 10; i++)
|
||||
{
|
||||
fixed_t nz;
|
||||
INT32 lline;
|
||||
|
||||
x += interval*xcom*i + fwooffset*c*i;
|
||||
y += interval*ycom*i + fwooffset*s*i;
|
||||
|
||||
lline = P_GetMinecartSpecialLine(P_GetMinecartSector(x, y, z, &nz));
|
||||
if (lline != -1)
|
||||
{
|
||||
fixed_t nx, ny;
|
||||
angle_t nang, dummy, angdiff;
|
||||
mobj_t *mark;
|
||||
mobj_t *snax = P_GetAxis(sides[lines[lline].sidenum[0]].textureoffset >> FRACBITS);
|
||||
if (!snax)
|
||||
return NULL;
|
||||
P_GetAxisPosition(x, y, snax, &nx, &ny, &nang, &dummy);
|
||||
angdiff = ((nang - targetangle) + ANG10/2) & ~ANGLE_180;
|
||||
//Axes must be directly parallel or antiparallel, give or take 5 degrees.
|
||||
if (angdiff < ANG10)
|
||||
{
|
||||
mark = P_SpawnMobj(nx, ny, nz, mobj->info->raisestate);
|
||||
return mark;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void P_ParabolicMove(mobj_t *mo, fixed_t x, fixed_t y, fixed_t z, fixed_t g, fixed_t speed)
|
||||
{
|
||||
fixed_t dx = x - mo->x;
|
||||
fixed_t dy = y - mo->y;
|
||||
fixed_t dz = z - mo->z;
|
||||
fixed_t dh = P_AproxDistance(dx, dy);
|
||||
fixed_t c = FixedDiv(dx, dh);
|
||||
fixed_t s = FixedDiv(dy, dh);
|
||||
fixed_t fixConst = FixedDiv(speed, g);
|
||||
|
||||
mo->momx = FixedMul(c, speed);
|
||||
mo->momy = FixedMul(s, speed);
|
||||
mo->momz = FixedDiv(dh, 2*fixConst) + FixedDiv(dz, FixedDiv(dh, fixConst/2));
|
||||
}
|
||||
|
||||
static void P_MinecartThink(player_t *player)
|
||||
{
|
||||
mobj_t *minecart = player->mo->tracer;
|
||||
angle_t fa;
|
||||
|
||||
if (!minecart || P_MobjWasRemoved(minecart) || !minecart->health)
|
||||
{
|
||||
// Minecart died on you, so kill yourself.
|
||||
P_KillMobj(player->mo, NULL, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
//Limit player's angle to a cone.
|
||||
#define MINECARTCONEMAX FixedAngle(20*FRACUNIT)
|
||||
{
|
||||
angle_t angdiff = player->mo->angle - minecart->angle;
|
||||
if (angdiff < ANGLE_180 && angdiff > MINECARTCONEMAX)
|
||||
player->mo->angle = minecart->angle + MINECARTCONEMAX;
|
||||
else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX))
|
||||
player->mo->angle = minecart->angle - MINECARTCONEMAX;
|
||||
|
||||
if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_AnalogMove(player)))
|
||||
{
|
||||
if (player == &players[consoleplayer])
|
||||
localangle = player->mo->angle;
|
||||
else if (player == &players[secondarydisplayplayer])
|
||||
localangle2 = player->mo->angle;
|
||||
}
|
||||
}
|
||||
|
||||
// Player holding jump?
|
||||
if (!(player->cmd.buttons & BT_JUMP))
|
||||
player->pflags &= ~PF_JUMPDOWN;
|
||||
|
||||
// Handle segments.
|
||||
P_HandleMinecartSegments(minecart);
|
||||
|
||||
// Force 0 friction.
|
||||
minecart->friction = FRACUNIT;
|
||||
|
||||
fa = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
if (!P_TryMove(minecart, minecart->x + FINECOSINE(fa), minecart->y + FINESINE(fa), true))
|
||||
{
|
||||
P_KillMobj(minecart, NULL, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (P_IsObjectOnGround(minecart))
|
||||
{
|
||||
sector_t *sec;
|
||||
INT32 lnum;
|
||||
fixed_t dummy;
|
||||
|
||||
// Just hit floor.
|
||||
if (minecart->eflags & MFE_JUSTHITFLOOR)
|
||||
{
|
||||
S_StopSound(minecart);
|
||||
S_StartSound(minecart, sfx_s3k96);
|
||||
}
|
||||
|
||||
sec = P_GetMinecartSector(minecart->x, minecart->y, minecart->z, &dummy);
|
||||
|
||||
if (sec)
|
||||
lnum = P_GetMinecartSpecialLine(sec);
|
||||
|
||||
// Update axis if the cart is standing on a rail.
|
||||
if (sec && lnum != -1)
|
||||
{
|
||||
mobj_t *axis = P_GetAxis(sides[lines[lnum].sidenum[0]].textureoffset >> FRACBITS);
|
||||
fixed_t newx, newy;
|
||||
angle_t targetangle, grind;
|
||||
angle_t prevangle, angdiff;
|
||||
mobj_t *detleft = NULL;
|
||||
mobj_t *detright = NULL;
|
||||
mobj_t *sidelock = NULL;
|
||||
boolean jumped = false;
|
||||
fixed_t currentSpeed;
|
||||
|
||||
if (!axis)
|
||||
{
|
||||
P_KillMobj(minecart, NULL, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
minecart->movefactor = 0;
|
||||
P_ResetScore(player);
|
||||
// Handle angle and position
|
||||
P_GetAxisPosition(minecart->x, minecart->y, axis, &newx, &newy, &targetangle, &grind);
|
||||
if (axis->type != MT_AXISTRANSFERLINE)
|
||||
P_SpawnSparks(minecart, grind);
|
||||
P_TryMove(minecart, newx, newy, true);
|
||||
|
||||
// Set angle based on target
|
||||
prevangle = minecart->angle;
|
||||
angdiff = targetangle - minecart->angle;
|
||||
if (angdiff < ANGLE_90 + ANG2 || angdiff > ANGLE_270 - ANG2)
|
||||
minecart->angle = targetangle;
|
||||
else
|
||||
minecart->angle = targetangle + ANGLE_180;
|
||||
angdiff = (minecart->angle - prevangle);
|
||||
if (angdiff && (!demoplayback || P_AnalogMove(player))) // maintain relative angle on turns
|
||||
{
|
||||
player->mo->angle += angdiff;
|
||||
if (player == &players[consoleplayer])
|
||||
localangle += angdiff;
|
||||
else if (player == &players[secondarydisplayplayer])
|
||||
localangle2 += angdiff;
|
||||
}
|
||||
|
||||
// Sideways detection
|
||||
if (minecart->flags2 & MF2_AMBUSH)
|
||||
{
|
||||
angle_t fa2 = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t c = FINECOSINE(fa2);
|
||||
fixed_t s = FINESINE(fa2);
|
||||
|
||||
detleft = P_LookForRails(minecart, c, s, targetangle, -s, c);
|
||||
detright = P_LookForRails(minecart, c, s, targetangle, s, -c);
|
||||
}
|
||||
|
||||
// How fast are we going?
|
||||
currentSpeed = FixedHypot(minecart->momx, minecart->momy);
|
||||
angdiff = R_PointToAngle2(0, 0, minecart->momx, minecart->momy) - minecart->angle;
|
||||
if (angdiff > ANGLE_90 && angdiff < ANGLE_270)
|
||||
currentSpeed *= -1;
|
||||
|
||||
// Player-specific behavior.
|
||||
if (detleft && player->cmd.sidemove < 0)
|
||||
sidelock = detleft;
|
||||
else if (detright && player->cmd.sidemove > 0)
|
||||
sidelock = detright;
|
||||
|
||||
//if (player->cmd.buttons & BT_USE && currentSpeed > 4*FRACUNIT)
|
||||
// currentSpeed -= FRACUNIT/8;
|
||||
|
||||
// Jumping
|
||||
if (sidelock || ((player->cmd.buttons & BT_JUMP) && !(player->pflags & PF_JUMPDOWN)))
|
||||
{
|
||||
player->pflags |= PF_JUMPDOWN;
|
||||
|
||||
if (minecart->eflags & MFE_ONGROUND)
|
||||
minecart->eflags &= ~MFE_ONGROUND;
|
||||
minecart->z += P_MobjFlip(minecart);
|
||||
if (sidelock)
|
||||
P_ParabolicMove(minecart, sidelock->x, sidelock->y, sidelock->z, gravity, max(currentSpeed, 10 * FRACUNIT));
|
||||
else
|
||||
minecart->momz = 10 * FRACUNIT;
|
||||
|
||||
S_StartSound(minecart, sfx_s3k51);
|
||||
jumped = true;
|
||||
}
|
||||
|
||||
if (!jumped)
|
||||
{
|
||||
// Natural acceleration and boosters
|
||||
if (currentSpeed < minecart->info->speed)
|
||||
currentSpeed += FRACUNIT/4;
|
||||
|
||||
if (minecart->standingslope)
|
||||
{
|
||||
fixed_t fa2 = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t front = P_GetZAt(minecart->standingslope, minecart->x, minecart->y);
|
||||
fixed_t back = P_GetZAt(minecart->standingslope, minecart->x - FINECOSINE(fa2), minecart->y - FINESINE(fa2));
|
||||
|
||||
if (abs(front - back) < 3*FRACUNIT)
|
||||
currentSpeed += (back - front)/3;
|
||||
}
|
||||
|
||||
// Go forward at our current speed
|
||||
P_InstaThrust(minecart, minecart->angle, currentSpeed);
|
||||
|
||||
// On-track ka-klong sound FX.
|
||||
minecart->movecount += abs(currentSpeed);
|
||||
if (minecart->movecount > 128*FRACUNIT)
|
||||
{
|
||||
minecart->movecount %= 128*FRACUNIT;
|
||||
S_StartSound(minecart, minecart->info->activesound);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
minecart->movefactor++;
|
||||
if ((P_IsObjectOnGround(minecart) && minecart->movefactor >= 5) // off rail
|
||||
|| (abs(minecart->momx) < minecart->scale/2 && abs(minecart->momy) < minecart->scale/2)) // hit a wall
|
||||
{
|
||||
P_KillMobj(minecart, NULL, NULL, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||
|
||||
// Move player to minecart.
|
||||
P_TeleportMove(player->mo, minecart->x - minecart->momx, minecart->y - minecart->momy, minecart->z + max(minecart->momz, 0) + 8*FRACUNIT);
|
||||
if (player->powers[pw_carry] != CR_MINECART)
|
||||
return;
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
P_TryMove(player->mo, player->mo->x + minecart->momx, player->mo->y + minecart->momy, true);
|
||||
|
||||
if (player->powers[pw_flashing] == flashingtics)
|
||||
player->powers[pw_flashing]--;
|
||||
}
|
||||
|
||||
//
|
||||
// P_PlayerThink
|
||||
//
|
||||
|
@ -10052,6 +10463,17 @@ void P_PlayerThink(player_t *player)
|
|||
// for a bit after a teleport.
|
||||
if (player->mo->reactiontime)
|
||||
player->mo->reactiontime--;
|
||||
else if (player->powers[pw_carry] == CR_MINECART)
|
||||
{
|
||||
if (!P_AnalogMove(player))
|
||||
player->mo->angle = (cmd->angleturn << 16 /* not FRACBITS */);
|
||||
|
||||
ticruned++;
|
||||
if ((cmd->angleturn & TICCMD_RECEIVED) == 0)
|
||||
ticmiss++;
|
||||
|
||||
P_MinecartThink(player);
|
||||
}
|
||||
else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_ZOOMTUBE))
|
||||
{
|
||||
if (player->powers[pw_carry] == CR_ROPEHANG)
|
||||
|
@ -10113,7 +10535,15 @@ void P_PlayerThink(player_t *player)
|
|||
switch (player->powers[pw_carry])
|
||||
{
|
||||
case CR_PLAYER:
|
||||
player->drawangle = (player->mo->tracer->player ? player->mo->tracer->player->drawangle : player->mo->tracer->angle);
|
||||
if (player->mo->tracer->player)
|
||||
{
|
||||
player->drawangle = player->mo->tracer->player->drawangle;
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case CR_MINECART:
|
||||
case CR_GENERIC:
|
||||
player->drawangle = player->mo->tracer->angle;
|
||||
break;
|
||||
/* -- in case we wanted to have the camera freely movable during zoom tubes
|
||||
case CR_ZOOMTUBE:*/
|
||||
|
|
22
src/sounds.c
22
src/sounds.c
|
@ -195,6 +195,8 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"boingf", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bouncing"},
|
||||
{"corkp", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork fired"},
|
||||
{"corkh", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork hit"},
|
||||
{"bowl", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bowling"},
|
||||
{"chuchu", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Train horn"},
|
||||
|
||||
// Menu, interface
|
||||
{"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Score"},
|
||||
|
@ -311,13 +313,13 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"s3k48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pulse"},
|
||||
{"s3k49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"},
|
||||
{"s3k4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Grab"},
|
||||
{"s3k4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Water splash"},
|
||||
{"s3k4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"},
|
||||
{"s3k4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy hit"},
|
||||
{"s3k4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing bullet"},
|
||||
{"s3k4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Big explosion"},
|
||||
{"s3k4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"},
|
||||
{"s3k50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Siren"},
|
||||
{"s3k51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling hazard"},
|
||||
{"s3k51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling"},
|
||||
{"s3k52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spike"},
|
||||
{"s3k53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"},
|
||||
{"s3k54", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Firing"}, // MetalSonic shot fire
|
||||
|
@ -362,7 +364,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"s3k7b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Soft bounce"},
|
||||
{"s3k7c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnet"},
|
||||
{"s3k7d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"s3k7e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Eating dirt"},
|
||||
{"s3k7e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Dust"},
|
||||
{"s3k7f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Freeze"},
|
||||
{"s3k80", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ice spike burst"},
|
||||
{"s3k81", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"},
|
||||
|
@ -373,7 +375,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"s3k86", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Alarm"},
|
||||
{"s3k87", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"},
|
||||
{"s3k88", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic squeak"},
|
||||
{"s3k89", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Advanced technology"},
|
||||
{"s3k89", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Advanced tech"},
|
||||
{"s3k8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boing"},
|
||||
{"s3k8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful hit"},
|
||||
{"s3k8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Humming power"},
|
||||
|
@ -383,10 +385,10 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"},
|
||||
{"s3k91", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Closed"},
|
||||
{"s3k92", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ghost"},
|
||||
{"s3k93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rebuilding"},
|
||||
{"s3k93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gas release"},
|
||||
{"s3k94", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spike"},
|
||||
{"s3k95", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Lava burst"},
|
||||
{"s3k96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling object"},
|
||||
{"s3k96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Landing"},
|
||||
{"s3k97", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind"},
|
||||
{"s3k98", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling spike"},
|
||||
{"s3k99", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"},
|
||||
|
@ -454,13 +456,13 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"s3kcas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"},
|
||||
{"s3kcal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"}, // ditto
|
||||
{"s3kcbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"},
|
||||
{"s3kcbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominuous rumbling"}, // ditto
|
||||
{"s3kcbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, // ditto
|
||||
{"s3kccs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"},
|
||||
{"s3kccl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"}, // ditto
|
||||
{"s3kcds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"},
|
||||
{"s3kcdl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, // ditto
|
||||
{"s3kces", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind tunnel"},
|
||||
{"s3kcel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind tunnel"}, // ditto
|
||||
{"s3kcel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Dust devil"}, // ditto
|
||||
{"s3kcfs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"s3kcfl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto
|
||||
{"s3kd0s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising"},
|
||||
|
@ -469,8 +471,8 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"s3kd1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto
|
||||
{"s3kd2s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turning"},
|
||||
{"s3kd2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Moving chain"}, // ditto
|
||||
{"s3kd3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"s3kd3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto
|
||||
{"s3kd3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Digging"},
|
||||
{"s3kd3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Digging"}, // ditto
|
||||
{"s3kd4s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Engine"},
|
||||
{"s3kd4l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Engine"}, // ditto
|
||||
{"s3kd5s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling lava"},
|
||||
|
|
|
@ -261,6 +261,8 @@ typedef enum
|
|||
sfx_boingf,
|
||||
sfx_corkp,
|
||||
sfx_corkh,
|
||||
sfx_bowl,
|
||||
sfx_chuchu,
|
||||
|
||||
// Menu, interface
|
||||
sfx_chchng,
|
||||
|
|
Loading…
Reference in a new issue