mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-04-18 00:11:48 +00:00
Merge branch 'master' into spd
This commit is contained in:
commit
de34298bbd
71 changed files with 2949 additions and 1271 deletions
extras/conf
src
b_bot.cd_clisrv.cd_clisrv.hd_main.cd_main.hd_netcmd.cd_netcmd.hd_netfil.cd_player.hdehacked.c
djgppdos
doomstat.hf_finale.cf_finale.hf_wipe.cg_game.cg_game.hhardware
hu_stuff.chu_stuff.hinfo.cinfo.hlua_baselib.clua_hud.hlua_hudlib.clua_playerlib.cm_argv.cm_cond.cm_fixed.hm_menu.cm_menu.hm_misc.cm_misc.hp_enemy.cp_inter.cp_local.hp_map.cp_mobj.cp_setup.cp_spec.cp_tick.cp_user.cr_data.cr_defs.hr_main.cr_main.hr_plane.cr_segs.cr_state.hr_things.cs_sound.cs_sound.hscreen.cscreen.hsdl
sounds.cst_stuff.cst_stuff.hstrcasestr.cv_video.cv_video.hw_wad.cwin32
y_inter.cy_inter.h
|
@ -3,6 +3,7 @@
|
|||
For Sonic Robo Blast 2 Version 2.2
|
||||
Contributors (alphabetical):
|
||||
* Foxboy
|
||||
* FuriousFox
|
||||
* JJames19119
|
||||
* Kalaron
|
||||
* Kristos
|
||||
|
@ -44,27 +45,32 @@ formatinterface = "SRB2MapSetIO";
|
|||
//Sky textures for vanilla maps
|
||||
defaultskytextures
|
||||
{
|
||||
SKY1 = "MAP01,MAP02,MAP03,MAP50,MAPA1,MAPA2,MAPA5,MAPA6,MAPA9,MAPAA,MAPAB,MAPAC,MAPAD,MAPAE,MAPAG,MAPAJ,MAPAK,MAPF0,MAPF1,MAPFA,MAPM0,MAPM8,MAPMA,MAPMB,MAPMC";
|
||||
SKY4 = "MAP04,MAP06,MAP51,MAPF8,MAPM1";
|
||||
SKY6 = "MAP05";
|
||||
SKY7 = "MAP07,MAP08,MAP09,MAP52,MAPM2,MAPM5";
|
||||
SKY10 = "MAP12,MAP53,MAPM3";
|
||||
SKY11 = "MAP10,MAP11,MAP16,MAP55,MAPF2,MAPF5,MAPF6,MAPF9,MAPM7";
|
||||
SKY13 = "MAP13,MAP54,MAPAS";
|
||||
SKY21 = "MAPAF,MAPF7,MAPM4";
|
||||
SKY22 = "MAP22,MAP23,MAP24,MAP25,MAP56,MAPAN,MAPAO,MAPF4,MAPM6";
|
||||
SKY29 = "MAP58,MAPAV";
|
||||
SKY1 = "MAP01,MAP02,MAP03,MAP33,MAP50,MAP60,MAPF0,MAPM0";
|
||||
SKY2 = "MAPM7,MAPMB";
|
||||
SKY4 = "MAP04,MAP06,MAP61,MAPF6,MAPM1";
|
||||
SKY6 = "MAP05,MAP51,MAPMA";
|
||||
SKY7 = "MAPM2,MAPM5";
|
||||
SKY8 = "MAP07,MAP08,MAP09,MAP52,MAP62,MAPF1";
|
||||
SKY10 = "MAP10,MAP12,MAP53,MAP63,MAPM3";
|
||||
SKY11 = "MAP11,MAPF7";
|
||||
SKY13 = "MAP13,MAP64";
|
||||
SKY14 = "MAP14";
|
||||
SKY15 = "MAP15,MAP54";
|
||||
SKY17 = "MAP70";
|
||||
SKY20 = "MAP32,MAP55,MAP65,MAPF2,MAPF5";
|
||||
SKY21 = "MAPM4";
|
||||
SKY22 = "MAP22,MAP23,MAP25,MAP26,MAP27,MAP56,MAP66,MAPF4,MAPM6";
|
||||
SKY30 = "MAP30";
|
||||
SKY35 = "MAP41";
|
||||
SKY40 = "MAP40";
|
||||
SKY55 = "MAPF3,MAPM9";
|
||||
SKY66 = "MAPAT";
|
||||
SKY99 = "MAP57";
|
||||
SKY103 = "MAPA3,MAPA4,MAPAU";
|
||||
SKY107 = "MAPA7,MAPA8";
|
||||
SKY117 = "MAPAH,MAPAI";
|
||||
SKY127 = "MAPAR";
|
||||
SKY132 = "MAPAW";
|
||||
SKY31 = "MAP31";
|
||||
SKY35 = "MAP42";
|
||||
SKY40 = "MAP41,MAP71,MAPM9";
|
||||
SKY55 = "MAPF3,MAPM8";
|
||||
SKY68 = "MAPF8";
|
||||
SKY99 = "MAP57,MAPZ0";
|
||||
SKY159 = "MAP16";
|
||||
SKY172 = "MAP40";
|
||||
SKY300 = "MAP72";
|
||||
SKY301 = "MAP73";
|
||||
}
|
||||
|
||||
// Default lump name for new map
|
||||
|
@ -90,9 +96,9 @@ skins
|
|||
Sonic;
|
||||
Tails;
|
||||
Knuckles;
|
||||
Metalsonic;
|
||||
Fang;
|
||||
Amy;
|
||||
Fang;
|
||||
Metalsonic;
|
||||
}
|
||||
|
||||
// Gametypes
|
||||
|
@ -3422,7 +3428,7 @@ thingtypes
|
|||
121
|
||||
{
|
||||
title = "Minus";
|
||||
sprite = "MNUSA1";
|
||||
sprite = "MNUSA0";
|
||||
width = 24;
|
||||
height = 32;
|
||||
}
|
||||
|
@ -3457,6 +3463,13 @@ thingtypes
|
|||
height = 34;
|
||||
flags8text = "[8] Start on fire";
|
||||
}
|
||||
137
|
||||
{
|
||||
title = "Dragonbomber";
|
||||
sprite = "DRABA1";
|
||||
width = 28;
|
||||
height = 48;
|
||||
}
|
||||
105
|
||||
{
|
||||
title = "Jetty-Syn Bomber";
|
||||
|
@ -5726,6 +5739,24 @@ thingtypes
|
|||
width = 24;
|
||||
height = 32;
|
||||
}
|
||||
1505
|
||||
{
|
||||
title = "Green Flame";
|
||||
sprite = "CFLMA0E0";
|
||||
width = 8;
|
||||
height = 32;
|
||||
}
|
||||
1506
|
||||
{
|
||||
arrow = 1;
|
||||
blocking = 2;
|
||||
title = "Blue Gargoyle";
|
||||
sprite = "BGARD1";
|
||||
width = 16;
|
||||
height = 40;
|
||||
flags4text = "[4] Slides when pushed";
|
||||
flags8text = "[8] Not pushable";
|
||||
}
|
||||
}
|
||||
|
||||
dreamhill
|
||||
|
|
336
src/b_bot.c
336
src/b_bot.c
|
@ -24,12 +24,47 @@ static boolean lastForward = false;
|
|||
static boolean lastBlocked = false;
|
||||
static boolean blocked = false;
|
||||
|
||||
static boolean jump_last = false;
|
||||
static boolean spin_last = false;
|
||||
static UINT8 anxiety = 0;
|
||||
static boolean panic = false;
|
||||
static UINT8 flymode = 0;
|
||||
static boolean spinmode = false;
|
||||
static boolean thinkfly = false;
|
||||
|
||||
static inline void B_ResetAI(void)
|
||||
{
|
||||
jump_last = false;
|
||||
spin_last = false;
|
||||
anxiety = 0;
|
||||
panic = false;
|
||||
flymode = 0;
|
||||
spinmode = false;
|
||||
thinkfly = false;
|
||||
}
|
||||
|
||||
static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
|
||||
{
|
||||
boolean forward=false, backward=false, left=false, right=false, jump=false, spin=false;
|
||||
angle_t angle;
|
||||
INT16 rangle;
|
||||
fixed_t dist;
|
||||
|
||||
player_t *player = sonic->player, *bot = tails->player;
|
||||
ticcmd_t *pcmd = &player->cmd;
|
||||
boolean water = tails->eflags & MFE_UNDERWATER;
|
||||
SINT8 flip = P_MobjFlip(tails);
|
||||
boolean _2d = (tails->flags2 & MF2_TWOD) || twodlevel;
|
||||
fixed_t scale = tails->scale;
|
||||
|
||||
fixed_t dist = P_AproxDistance(sonic->x - tails->x, sonic->y - tails->y);
|
||||
fixed_t zdist = flip * (sonic->z - tails->z);
|
||||
angle_t ang = R_PointToAngle2(tails->x, tails->y, sonic->x, sonic->y);
|
||||
fixed_t pmom = P_AproxDistance(sonic->momx, sonic->momy);
|
||||
fixed_t bmom = P_AproxDistance(tails->momx, tails->momy);
|
||||
fixed_t followmax = 128 * 8 * scale; // Max follow distance before AI begins to enter "panic" state
|
||||
fixed_t followthres = 92 * scale; // Distance that AI will try to reach
|
||||
fixed_t followmin = 32 * scale;
|
||||
fixed_t comfortheight = 96 * scale;
|
||||
fixed_t touchdist = 24 * scale;
|
||||
boolean stalled = (bmom < scale >> 1) && dist > followthres; // Helps to see if the AI is having trouble catching up
|
||||
|
||||
// We can't follow Sonic if he's not around!
|
||||
if (!sonic || sonic->health <= 0)
|
||||
|
@ -58,46 +93,263 @@ static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cm
|
|||
return;
|
||||
}
|
||||
|
||||
// Gather data about the environment
|
||||
dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y);
|
||||
if (tails->player->pflags & PF_STARTDASH)
|
||||
angle = sonic->angle;
|
||||
// Adapted from CobaltBW's tails_AI.wad
|
||||
|
||||
// Check water
|
||||
if (water)
|
||||
{
|
||||
followmin = 0;
|
||||
followthres = 16*scale;
|
||||
followmax >>= 1;
|
||||
thinkfly = false;
|
||||
}
|
||||
|
||||
// Check anxiety
|
||||
if (spinmode)
|
||||
{
|
||||
anxiety = 0;
|
||||
panic = false;
|
||||
}
|
||||
else if (dist > followmax || zdist > comfortheight || stalled)
|
||||
{
|
||||
anxiety = min(anxiety + 2, 70);
|
||||
if (anxiety >= 70)
|
||||
panic = true;
|
||||
}
|
||||
else
|
||||
angle = R_PointToAngle2(tails->x, tails->y, sonic->x, sonic->y);
|
||||
|
||||
// Decide which direction to turn
|
||||
angle = (tails->angle - angle);
|
||||
if (angle < ANGLE_180) {
|
||||
right = true; // We need to turn right
|
||||
rangle = AngleFixed(angle)>>FRACBITS;
|
||||
} else {
|
||||
left = true; // We need to turn left
|
||||
rangle = 360-(AngleFixed(angle)>>FRACBITS);
|
||||
{
|
||||
anxiety = max(anxiety - 1, 0);
|
||||
panic = false;
|
||||
}
|
||||
|
||||
// Decide to move forward if you're finished turning
|
||||
if (abs(rangle) < 10) { // We're facing the right way?
|
||||
left = right = false; // Stop turning
|
||||
forward = true; // and walk forward instead.
|
||||
// Orientation
|
||||
if ((bot->pflags & (PF_SPINNING|PF_STARTDASH)) || flymode == 2)
|
||||
{
|
||||
cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->angleturn = (ang - tails->angle) >> FRACBITS;
|
||||
}
|
||||
if (dist < (sonic->radius+tails->radius)*3) // We're close enough?
|
||||
forward = false; // Stop walking.
|
||||
|
||||
// Decide when to jump
|
||||
if (!(tails->player->pflags & (PF_JUMPED|PF_JUMPDOWN))) { // We're not jumping yet...
|
||||
if (forward && lastForward && blocked && lastBlocked) // We've been stopped by a wall or something
|
||||
jump = true; // Try to jump up
|
||||
} else if ((tails->player->pflags & (PF_JUMPDOWN|PF_JUMPED)) == (PF_JUMPDOWN|PF_JUMPED)) { // When we're already jumping...
|
||||
if (lastForward && blocked) // We're still stuck on something?
|
||||
// ********
|
||||
// FLY MODE
|
||||
// spinmode check
|
||||
if (spinmode || player->exiting)
|
||||
thinkfly = false;
|
||||
else
|
||||
{
|
||||
// Activate co-op flight
|
||||
if (thinkfly && player->pflags & PF_JUMPED)
|
||||
{
|
||||
if (!jump_last)
|
||||
{
|
||||
jump = true;
|
||||
flymode = 1;
|
||||
thinkfly = false;
|
||||
bot->pflags |= PF_CANCARRY;
|
||||
}
|
||||
}
|
||||
|
||||
// Check positioning
|
||||
// Thinker for co-op flight
|
||||
if (!(water || pmom || bmom)
|
||||
&& (dist < touchdist)
|
||||
&& !(pcmd->forwardmove || pcmd->sidemove || player->dashspeed)
|
||||
&& P_IsObjectOnGround(sonic) && P_IsObjectOnGround(tails)
|
||||
&& !(player->pflags & PF_STASIS)
|
||||
&& bot->charability == CA_FLY)
|
||||
thinkfly = true;
|
||||
else
|
||||
thinkfly = false;
|
||||
|
||||
// Ready for takeoff
|
||||
if (flymode == 1)
|
||||
{
|
||||
thinkfly = false;
|
||||
if (zdist < -64*scale || (flip * tails->momz) > scale) // Make sure we're not too high up
|
||||
spin = true;
|
||||
else if (!jump_last)
|
||||
jump = true;
|
||||
|
||||
// Abort if the player moves away or spins
|
||||
if (dist > followthres || player->dashspeed)
|
||||
flymode = 0;
|
||||
|
||||
// Set carried state
|
||||
if (player->powers[pw_carry] == CR_PLAYER && sonic->tracer == tails)
|
||||
{
|
||||
flymode = 2;
|
||||
}
|
||||
}
|
||||
// Read player inputs while carrying
|
||||
else if (flymode == 2)
|
||||
{
|
||||
cmd->forwardmove = pcmd->forwardmove;
|
||||
cmd->sidemove = pcmd->sidemove;
|
||||
if (pcmd->buttons & BT_USE)
|
||||
{
|
||||
spin = true;
|
||||
jump = false;
|
||||
}
|
||||
else if (!jump_last)
|
||||
jump = true;
|
||||
// End flymode
|
||||
if (player->powers[pw_carry] != CR_PLAYER)
|
||||
{
|
||||
flymode = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flymode && P_IsObjectOnGround(tails) && !(pcmd->buttons & BT_JUMP))
|
||||
flymode = 0;
|
||||
|
||||
// ********
|
||||
// SPINNING
|
||||
if (panic || flymode || !(player->pflags & PF_SPINNING) || (player->pflags & PF_JUMPED))
|
||||
spinmode = false;
|
||||
else
|
||||
{
|
||||
if (!_2d)
|
||||
{
|
||||
// Spindash
|
||||
if (player->dashspeed)
|
||||
{
|
||||
if (dist < followthres && dist > touchdist) // Do positioning
|
||||
{
|
||||
cmd->angleturn = (ang - tails->angle) >> FRACBITS;
|
||||
cmd->forwardmove = 50;
|
||||
spinmode = true;
|
||||
}
|
||||
else if (dist < touchdist)
|
||||
{
|
||||
if (!bmom && (!(bot->pflags & PF_SPINNING) || (bot->dashspeed && bot->pflags & PF_SPINNING)))
|
||||
{
|
||||
cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS;
|
||||
spin = true;
|
||||
}
|
||||
spinmode = true;
|
||||
}
|
||||
else
|
||||
spinmode = false;
|
||||
}
|
||||
// Spin
|
||||
else if (player->dashspeed == bot->dashspeed && player->pflags & PF_SPINNING)
|
||||
{
|
||||
if (bot->pflags & PF_SPINNING || !spin_last)
|
||||
{
|
||||
spin = true;
|
||||
cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS;
|
||||
cmd->forwardmove = MAXPLMOVE;
|
||||
spinmode = true;
|
||||
}
|
||||
else
|
||||
spinmode = false;
|
||||
}
|
||||
}
|
||||
// 2D mode
|
||||
else
|
||||
{
|
||||
if (((player->dashspeed && !bmom) || (player->dashspeed == bot->dashspeed && (player->pflags & PF_SPINNING)))
|
||||
&& ((bot->pflags & PF_SPINNING) || !spin_last))
|
||||
{
|
||||
spin = true;
|
||||
spinmode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ********
|
||||
// FOLLOW
|
||||
if (!(flymode || spinmode))
|
||||
{
|
||||
// Too far
|
||||
if (panic || dist > followthres)
|
||||
{
|
||||
if (!_2d)
|
||||
cmd->forwardmove = MAXPLMOVE;
|
||||
else if (sonic->x > tails->x)
|
||||
cmd->sidemove = MAXPLMOVE;
|
||||
else
|
||||
cmd->sidemove = -MAXPLMOVE;
|
||||
}
|
||||
// Within threshold
|
||||
else if (!panic && dist > followmin && abs(zdist) < 192*scale)
|
||||
{
|
||||
if (!_2d)
|
||||
cmd->forwardmove = FixedHypot(pcmd->forwardmove, pcmd->sidemove);
|
||||
else
|
||||
cmd->sidemove = pcmd->sidemove;
|
||||
}
|
||||
// Below min
|
||||
else if (dist < followmin)
|
||||
{
|
||||
// Copy inputs
|
||||
cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS;
|
||||
bot->drawangle = ang;
|
||||
cmd->forwardmove = 8 * pcmd->forwardmove / 10;
|
||||
cmd->sidemove = 8 * pcmd->sidemove / 10;
|
||||
}
|
||||
}
|
||||
|
||||
// ********
|
||||
// JUMP
|
||||
if (!(flymode || spinmode))
|
||||
{
|
||||
// Flying catch-up
|
||||
if (bot->pflags & PF_THOKKED)
|
||||
{
|
||||
cmd->forwardmove = min(MAXPLMOVE, (dist/scale)>>3);
|
||||
if (zdist < -64*scale)
|
||||
spin = true;
|
||||
else if (zdist > 0 && !jump_last)
|
||||
jump = true;
|
||||
}
|
||||
|
||||
// Just landed
|
||||
if (tails->eflags & MFE_JUSTHITFLOOR)
|
||||
jump = false;
|
||||
// Start jump
|
||||
else if (!jump_last && !(bot->pflags & PF_JUMPED) //&& !(player->pflags & PF_SPINNING)
|
||||
&& ((zdist > 32*scale && player->pflags & PF_JUMPED) // Following
|
||||
|| (zdist > 64*scale && panic) // Vertical catch-up
|
||||
|| (stalled && anxiety > 20 && bot->powers[pw_carry] == CR_NONE)
|
||||
//|| (bmom < scale>>3 && dist > followthres && !(bot->powers[pw_carry])) // Stopped & not in carry state
|
||||
|| (bot->pflags & PF_SPINNING && !(bot->pflags & PF_JUMPED)))) // Spinning
|
||||
jump = true;
|
||||
// Hold jump
|
||||
else if (bot->pflags & PF_JUMPED && jump_last && tails->momz*flip > 0 && (zdist > 0 || panic))
|
||||
jump = true;
|
||||
if (sonic->floorz > tails->floorz) // He's still above us? Jump HIGHER, then!
|
||||
// Start flying
|
||||
else if (bot->pflags & PF_JUMPED && panic && !jump_last && bot->charability == CA_FLY)
|
||||
jump = true;
|
||||
}
|
||||
|
||||
// Decide when to spin
|
||||
if (sonic->player->pflags & PF_STARTDASH
|
||||
&& (tails->player->pflags & PF_STARTDASH || (P_AproxDistance(tails->momx, tails->momy) < 2*FRACUNIT && !forward)))
|
||||
spin = true;
|
||||
// ********
|
||||
// HISTORY
|
||||
jump_last = jump;
|
||||
spin_last = spin;
|
||||
|
||||
// ********
|
||||
// Thinkfly overlay
|
||||
if (thinkfly)
|
||||
{
|
||||
if (!tails->target)
|
||||
{
|
||||
P_SetTarget(&tails->target, P_SpawnMobjFromMobj(tails, 0, 0, 0, MT_OVERLAY));
|
||||
if (tails->target)
|
||||
{
|
||||
P_SetTarget(&tails->target->target, tails);
|
||||
P_SetMobjState(tails->target, S_FLIGHTINDICATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tails->target && tails->target->type == MT_OVERLAY && tails->target->state == states+S_FLIGHTINDICATOR)
|
||||
{
|
||||
P_RemoveMobj(tails->target);
|
||||
P_SetTarget(&tails->target, NULL);
|
||||
}
|
||||
|
||||
// Turn the virtual keypresses into ticcmd_t.
|
||||
B_KeysToTiccmd(tails, cmd, forward, backward, left, right, false, false, jump, spin);
|
||||
|
@ -141,7 +393,7 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward, boolean left, boolean right, boolean strafeleft, boolean straferight, boolean jump, boolean spin)
|
||||
{
|
||||
// don't try to do stuff if your sonic is in a minecart or something
|
||||
if (players[consoleplayer].powers[pw_carry])
|
||||
if (players[consoleplayer].powers[pw_carry] && players[consoleplayer].powers[pw_carry] != CR_PLAYER)
|
||||
return;
|
||||
// Turn the virtual keypresses into ticcmd_t.
|
||||
if (twodlevel || mo->flags2 & MF2_TWOD) {
|
||||
|
@ -179,6 +431,7 @@ void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward
|
|||
cmd->sidemove += MAXPLMOVE<<FRACBITS>>16;
|
||||
}
|
||||
} else {
|
||||
angle_t angle;
|
||||
if (forward)
|
||||
cmd->forwardmove += MAXPLMOVE<<FRACBITS>>16;
|
||||
if (backward)
|
||||
|
@ -191,6 +444,15 @@ void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward
|
|||
cmd->sidemove -= MAXPLMOVE<<FRACBITS>>16;
|
||||
if (straferight)
|
||||
cmd->sidemove += MAXPLMOVE<<FRACBITS>>16;
|
||||
|
||||
// cap inputs so the bot can't accelerate faster diagonally
|
||||
angle = R_PointToAngle2(0, 0, cmd->sidemove << FRACBITS, cmd->forwardmove << FRACBITS);
|
||||
{
|
||||
INT32 maxforward = abs(P_ReturnThrustY(NULL, angle, MAXPLMOVE));
|
||||
INT32 maxside = abs(P_ReturnThrustX(NULL, angle, MAXPLMOVE));
|
||||
cmd->forwardmove = max(min(cmd->forwardmove, maxforward), -maxforward);
|
||||
cmd->sidemove = max(min(cmd->sidemove, maxside), -maxside);
|
||||
}
|
||||
}
|
||||
if (jump)
|
||||
cmd->buttons |= BT_JUMP;
|
||||
|
@ -217,7 +479,7 @@ boolean B_CheckRespawn(player_t *player)
|
|||
// If he's doing any of these things, he probably doesn't want to see us.
|
||||
if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_BOUNCING)
|
||||
|| (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK)
|
||||
|| (sonic->player->powers[pw_carry]))
|
||||
|| (sonic->player->powers[pw_carry] && sonic->player->powers[pw_carry] != CR_PLAYER))
|
||||
return false;
|
||||
|
||||
// Low ceiling, do not want!
|
||||
|
@ -252,6 +514,8 @@ void B_RespawnBot(INT32 playernum)
|
|||
if (!sonic || sonic->health <= 0)
|
||||
return;
|
||||
|
||||
B_ResetAI();
|
||||
|
||||
player->bot = 1;
|
||||
P_SpawnPlayer(playernum);
|
||||
tails = player->mo;
|
||||
|
|
|
@ -90,6 +90,7 @@ SINT8 nodetoplayer[MAXNETNODES];
|
|||
SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen)
|
||||
UINT8 playerpernode[MAXNETNODES]; // used specialy for scplitscreen
|
||||
boolean nodeingame[MAXNETNODES]; // set false as nodes leave game
|
||||
tic_t servermaxping = 800; // server's max ping. Defaults to 800
|
||||
static tic_t nettics[MAXNETNODES]; // what tic the client have received
|
||||
static tic_t supposedtics[MAXNETNODES]; // nettics prevision for smaller packet
|
||||
static UINT8 nodewaiting[MAXNETNODES];
|
||||
|
@ -610,6 +611,11 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
|
||||
rsp->health = LONG(players[i].mo->health);
|
||||
rsp->angle = (angle_t)LONG(players[i].mo->angle);
|
||||
#ifdef ROTSPRITE
|
||||
rsp->rollangle = (angle_t)LONG(players[i].mo->rollangle);
|
||||
#else
|
||||
rsp->rollangle = 0;
|
||||
#endif
|
||||
rsp->x = LONG(players[i].mo->x);
|
||||
rsp->y = LONG(players[i].mo->y);
|
||||
rsp->z = LONG(players[i].mo->z);
|
||||
|
@ -760,6 +766,9 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
//At this point, the player should have a body, whether they were respawned or not.
|
||||
P_UnsetThingPosition(players[i].mo);
|
||||
players[i].mo->angle = (angle_t)LONG(rsp->angle);
|
||||
#ifdef ROTSPRITE
|
||||
players[i].mo->rollangle = (angle_t)LONG(rsp->rollangle);
|
||||
#endif
|
||||
players[i].mo->eflags = (UINT16)SHORT(rsp->eflags);
|
||||
players[i].mo->flags = LONG(rsp->flags);
|
||||
players[i].mo->flags2 = LONG(rsp->flags2);
|
||||
|
@ -1292,10 +1301,23 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
|
||||
M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16);
|
||||
|
||||
if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, ""))
|
||||
strncpy(netbuffer->u.serverinfo.maptitle, (char *)mapheaderinfo[gamemap-1]->lvlttl, 33);
|
||||
if (*mapheaderinfo[gamemap-1]->lvlttl)
|
||||
{
|
||||
char *read = mapheaderinfo[gamemap-1]->lvlttl, *writ = netbuffer->u.serverinfo.maptitle;
|
||||
while (writ < (netbuffer->u.serverinfo.maptitle+32) && *read != '\0')
|
||||
{
|
||||
if (!(*read & 0x80))
|
||||
{
|
||||
*writ = toupper(*read);
|
||||
writ++;
|
||||
}
|
||||
read++;
|
||||
}
|
||||
*writ = '\0';
|
||||
//strncpy(netbuffer->u.serverinfo.maptitle, (char *)mapheaderinfo[gamemap-1]->lvlttl, 33);
|
||||
}
|
||||
else
|
||||
strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 33);
|
||||
strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 32);
|
||||
|
||||
netbuffer->u.serverinfo.maptitle[32] = '\0';
|
||||
|
||||
|
@ -1349,7 +1371,11 @@ static void SV_SendPlayerInfo(INT32 node)
|
|||
|
||||
netbuffer->u.playerinfo[i].score = LONG(players[i].score);
|
||||
netbuffer->u.playerinfo[i].timeinserver = SHORT((UINT16)(players[i].jointime / TICRATE));
|
||||
netbuffer->u.playerinfo[i].skin = (UINT8)players[i].skin;
|
||||
netbuffer->u.playerinfo[i].skin = (UINT8)(players[i].skin
|
||||
#ifdef DEVELOP // it's safe to do this only because PLAYERINFO isn't read by the game itself
|
||||
% 3
|
||||
#endif
|
||||
);
|
||||
|
||||
// Extra data
|
||||
netbuffer->u.playerinfo[i].data = 0; //players[i].skincolor;
|
||||
|
@ -1607,7 +1633,7 @@ static void CL_LoadReceivedSavegame(void)
|
|||
{
|
||||
CONS_Printf(": %s", mapheaderinfo[gamemap-1]->lvlttl);
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||
CONS_Printf(M_GetText(" ZONE"));
|
||||
CONS_Printf(M_GetText(" Zone"));
|
||||
if (actnum > 0)
|
||||
CONS_Printf(" %2d", actnum);
|
||||
}
|
||||
|
@ -4208,10 +4234,12 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
//Update client ping table from the server.
|
||||
if (client)
|
||||
{
|
||||
INT32 i;
|
||||
UINT8 i;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
|
||||
|
||||
servermaxping = (tic_t)netbuffer->u.pingtable[MAXPLAYERS];
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -4591,7 +4619,7 @@ static void Local_Maketic(INT32 realtics)
|
|||
{
|
||||
I_OsPolling(); // I_Getevent
|
||||
D_ProcessEvents(); // menu responder, cons responder,
|
||||
// game responder calls HU_Responder, AM_Responder, F_Responder,
|
||||
// game responder calls HU_Responder, AM_Responder,
|
||||
// and G_MapEventsToControls
|
||||
if (!dedicated) rendergametic = gametic;
|
||||
// translate inputs (keyboard/mouse/joystick) into game controls
|
||||
|
@ -4733,6 +4761,14 @@ void TryRunTics(tic_t realtics)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Ping Update except better:
|
||||
We call this once per second and check for people's pings. If their ping happens to be too high, we increment some timer and kick them out.
|
||||
If they're not lagging, decrement the timer by 1. Of course, reset all of this if they leave.
|
||||
*/
|
||||
|
||||
static INT32 pingtimeout[MAXPLAYERS];
|
||||
|
||||
static inline void PingUpdate(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
@ -4753,6 +4789,8 @@ static inline void PingUpdate(void)
|
|||
laggers[i] = true;
|
||||
numlaggers++;
|
||||
}
|
||||
else
|
||||
pingtimeout[i] = 0;
|
||||
}
|
||||
|
||||
//kick lagging players... unless everyone but the server's ping sucks.
|
||||
|
@ -4763,12 +4801,27 @@ static inline void PingUpdate(void)
|
|||
{
|
||||
if (playeringame[i] && laggers[i])
|
||||
{
|
||||
char buf[2];
|
||||
pingtimeout[i]++;
|
||||
if (pingtimeout[i] > cv_pingtimeout.value)
|
||||
// ok your net has been bad for too long, you deserve to die.
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
buf[0] = (char)i;
|
||||
buf[1] = KICK_MSG_PING_HIGH;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
pingtimeout[i] = 0;
|
||||
|
||||
buf[0] = (char)i;
|
||||
buf[1] = KICK_MSG_PING_HIGH;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
}
|
||||
/*
|
||||
you aren't lagging,
|
||||
but you aren't free yet.
|
||||
In case you'll keep spiking,
|
||||
we just make the timer go back down. (Very unstable net must still get kicked).
|
||||
*/
|
||||
else
|
||||
pingtimeout[i] = (pingtimeout[i] == 0 ? 0 : pingtimeout[i]-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4783,10 +4836,13 @@ static inline void PingUpdate(void)
|
|||
realpingtable[i] = 0; //Reset each as we go.
|
||||
}
|
||||
|
||||
// send the server's maxping as last element of our ping table. This is useful to let us know when we're about to get kicked.
|
||||
netbuffer->u.pingtable[MAXPLAYERS] = cv_maxping.value;
|
||||
|
||||
//send out our ping packets
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
if (nodeingame[i])
|
||||
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
|
||||
HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1));
|
||||
|
||||
pingmeasurecount = 1; //Reset count
|
||||
}
|
||||
|
@ -4816,7 +4872,7 @@ void NetUpdate(void)
|
|||
|
||||
if (server)
|
||||
{
|
||||
if (netgame && !(gametime % 255))
|
||||
if (netgame && !(gametime % 35)) // update once per second.
|
||||
PingUpdate();
|
||||
// update node latency values so we can take an average later.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
|
@ -255,6 +255,7 @@ typedef struct
|
|||
|
||||
INT32 health;
|
||||
angle_t angle;
|
||||
angle_t rollangle;
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
fixed_t z;
|
||||
|
@ -423,9 +424,9 @@ typedef struct
|
|||
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
|
||||
askinfo_pak askinfo; // 61 bytes
|
||||
msaskinfo_pak msaskinfo; // 22 bytes
|
||||
plrinfo playerinfo[MAXPLAYERS]; // 1152 bytes (I'd say 36~38)
|
||||
plrconfig playerconfig[MAXPLAYERS]; // (up to) 896 bytes (welp they ARE)
|
||||
UINT32 pingtable[MAXPLAYERS]; // 128 bytes
|
||||
plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?)
|
||||
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
|
||||
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK doomdata_t;
|
||||
|
||||
|
@ -487,6 +488,7 @@ extern tic_t jointimeout;
|
|||
extern UINT16 pingmeasurecount;
|
||||
extern UINT32 realpingtable[MAXPLAYERS];
|
||||
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||
extern tic_t servermaxping;
|
||||
|
||||
extern consvar_t cv_joinnextround, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
|
||||
|
|
133
src/d_main.c
133
src/d_main.c
|
@ -274,7 +274,7 @@ static void D_Display(void)
|
|||
&& wipetypepre != UINT8_MAX)
|
||||
{
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeColorFill(31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
|
||||
}
|
||||
|
@ -291,8 +291,11 @@ static void D_Display(void)
|
|||
switch (gamestate)
|
||||
{
|
||||
case GS_TITLESCREEN:
|
||||
F_TitleScreenDrawer();
|
||||
break;
|
||||
if (!titlemapinaction || !curbghide) {
|
||||
F_TitleScreenDrawer();
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case GS_LEVEL:
|
||||
if (!gametic)
|
||||
break;
|
||||
|
@ -363,11 +366,56 @@ static void D_Display(void)
|
|||
|
||||
// clean up border stuff
|
||||
// see if the border needs to be initially drawn
|
||||
if (gamestate == GS_LEVEL)
|
||||
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap)))
|
||||
{
|
||||
// draw the view directly
|
||||
|
||||
D_Render();
|
||||
if (!automapactive && !dedicated && cv_renderview.value)
|
||||
{
|
||||
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
|
||||
{
|
||||
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
|
||||
objectsdrawn = 0;
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
HWR_RenderPlayerView(0, &players[displayplayer]);
|
||||
else
|
||||
#endif
|
||||
if (rendermode != render_none)
|
||||
R_RenderPlayerView(&players[displayplayer]);
|
||||
}
|
||||
|
||||
// render the second screen
|
||||
if (splitscreen && players[secondarydisplayplayer].mo)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
|
||||
else
|
||||
#endif
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
viewwindowy = vid.height / 2;
|
||||
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
|
||||
|
||||
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
|
||||
|
||||
R_RenderPlayerView(&players[secondarydisplayplayer]);
|
||||
|
||||
viewwindowy = 0;
|
||||
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
|
||||
}
|
||||
}
|
||||
|
||||
// Image postprocessing effect
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
if (postimgtype)
|
||||
V_DoPostProcessor(0, postimgtype, postimgparam);
|
||||
if (postimgtype2)
|
||||
V_DoPostProcessor(1, postimgtype2, postimgparam2);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastdraw)
|
||||
{
|
||||
|
@ -380,9 +428,14 @@ static void D_Display(void)
|
|||
lastdraw = false;
|
||||
}
|
||||
|
||||
ST_Drawer();
|
||||
F_TextPromptDrawer();
|
||||
HU_Drawer();
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
ST_Drawer();
|
||||
F_TextPromptDrawer();
|
||||
HU_Drawer();
|
||||
}
|
||||
else
|
||||
F_TitleScreenDrawer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,6 +488,15 @@ static void D_Display(void)
|
|||
if (rendermode != render_none)
|
||||
{
|
||||
F_WipeEndScreen();
|
||||
// Funny.
|
||||
if (WipeStageTitle && st_overlay)
|
||||
{
|
||||
lt_ticker--;
|
||||
lt_lasttic = lt_ticker;
|
||||
ST_preLevelTitleCardDrawer(0, false);
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
|
||||
F_WipeStartScreen();
|
||||
}
|
||||
F_RunWipe(wipetypepost, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
|
||||
}
|
||||
|
||||
|
@ -444,7 +506,7 @@ static void D_Display(void)
|
|||
framecount = 0;
|
||||
demostarttime = I_GetTime();
|
||||
}
|
||||
|
||||
|
||||
wipetypepost = -1;
|
||||
}
|
||||
else
|
||||
|
@ -485,56 +547,6 @@ static void D_Display(void)
|
|||
}
|
||||
}
|
||||
|
||||
void D_Render(void)
|
||||
{
|
||||
if (!automapactive && !dedicated && cv_renderview.value)
|
||||
{
|
||||
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
|
||||
{
|
||||
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
|
||||
objectsdrawn = 0;
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
HWR_RenderPlayerView(0, &players[displayplayer]);
|
||||
else
|
||||
#endif
|
||||
if (rendermode != render_none)
|
||||
R_RenderPlayerView(&players[displayplayer]);
|
||||
}
|
||||
|
||||
// render the second screen
|
||||
if (splitscreen && players[secondarydisplayplayer].mo)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
|
||||
else
|
||||
#endif
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
viewwindowy = vid.height / 2;
|
||||
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
|
||||
|
||||
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
|
||||
|
||||
R_RenderPlayerView(&players[secondarydisplayplayer]);
|
||||
|
||||
viewwindowy = 0;
|
||||
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
|
||||
}
|
||||
}
|
||||
|
||||
// Image postprocessing effect
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
if (postimgtype)
|
||||
V_DoPostProcessor(0, postimgtype, postimgparam);
|
||||
if (postimgtype2)
|
||||
V_DoPostProcessor(1, postimgtype2, postimgparam2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// D_SRB2Loop
|
||||
// =========================================================================
|
||||
|
@ -655,6 +667,7 @@ void D_SRB2Loop(void)
|
|||
|
||||
// consoleplayer -> displayplayer (hear sounds from viewpoint)
|
||||
S_UpdateSounds(); // move positional sounds
|
||||
S_UpdateClosedCaptions();
|
||||
|
||||
// check for media change, loop music..
|
||||
I_UpdateCD();
|
||||
|
@ -720,6 +733,8 @@ void D_StartTitle(void)
|
|||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
CL_ClearPlayer(i);
|
||||
|
||||
players[consoleplayer].availabilities = players[1].availabilities = R_GetSkinAvailabilities(); // players[1] is supposed to be for 2p
|
||||
|
||||
splitscreen = false;
|
||||
SplitScreen_OnChange();
|
||||
botingame = false;
|
||||
|
|
|
@ -54,7 +54,4 @@ const char *D_Home(void);
|
|||
void D_AdvanceDemo(void);
|
||||
void D_StartTitle(void);
|
||||
|
||||
/* Here for title maps */
|
||||
void D_Render(void);
|
||||
|
||||
#endif //__D_MAIN__
|
||||
|
|
|
@ -87,6 +87,7 @@ static void JoinTimeout_OnChange(void);
|
|||
|
||||
static void CoopStarposts_OnChange(void);
|
||||
static void CoopLives_OnChange(void);
|
||||
static void ExitMove_OnChange(void);
|
||||
|
||||
static void Ringslinger_OnChange(void);
|
||||
static void Gravity_OnChange(void);
|
||||
|
@ -341,21 +342,32 @@ consvar_t cv_nettimeout = {"nettimeout", "350", CV_CALL|CV_SAVE, nettimeout_cons
|
|||
static CV_PossibleValue_t jointimeout_cons_t[] = {{5*TICRATE, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_jointimeout = {"jointimeout", "350", CV_CALL|CV_SAVE, jointimeout_cons_t, JoinTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t pingtimeout_cons_t[] = {{8, "MIN"}, {120, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// show your ping on the HUD next to framerate. Defaults to warning only (shows up if your ping is > maxping)
|
||||
static CV_PossibleValue_t showping_cons_t[] = {{0, "Off"}, {1, "Always"}, {2, "Warning"}, {0, NULL}};
|
||||
consvar_t cv_showping = {"showping", "Warning", CV_SAVE, showping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Intermission time Tails 04-19-2002
|
||||
static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t coopstarposts_cons_t[] = {{0, "Per-player"}, {1, "Shared"}, {2, "Teamwork"}, {0, NULL}};
|
||||
consvar_t cv_coopstarposts = {"coopstarposts", "Teamwork", CV_NETVAR|CV_CALL|CV_CHEAT, coopstarposts_cons_t, CoopStarposts_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_coopstarposts = {"coopstarposts", "Per-player", CV_NETVAR|CV_CALL, coopstarposts_cons_t, CoopStarposts_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t cooplives_cons_t[] = {{0, "Infinite"}, {1, "Per-player"}, {2, "Avoid Game Over"}, {3, "Single pool"}, {0, NULL}};
|
||||
consvar_t cv_cooplives = {"cooplives", "Avoid Game Over", CV_NETVAR|CV_CALL|CV_CHEAT, cooplives_cons_t, CoopLives_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}};
|
||||
consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "1/4"}, {2, "Half"}, {3, "3/4"}, {4, "All"}, {0, NULL}};
|
||||
consvar_t cv_playersforexit = {"playersforexit", "All", CV_NETVAR, playersforexit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_exitmove = {"exitmove", "Off", CV_NETVAR|CV_CALL, CV_OnOff, ExitMove_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_runscripts = {"runscripts", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_pause = {"pausepermission", "Server", CV_NETVAR, pause_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -514,6 +526,7 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_inttime);
|
||||
CV_RegisterVar(&cv_advancemap);
|
||||
CV_RegisterVar(&cv_playersforexit);
|
||||
CV_RegisterVar(&cv_exitmove);
|
||||
CV_RegisterVar(&cv_timelimit);
|
||||
CV_RegisterVar(&cv_playbackspeed);
|
||||
CV_RegisterVar(&cv_forceskin);
|
||||
|
@ -577,6 +590,8 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_skipmapcheck);
|
||||
CV_RegisterVar(&cv_sleep);
|
||||
CV_RegisterVar(&cv_maxping);
|
||||
CV_RegisterVar(&cv_pingtimeout);
|
||||
CV_RegisterVar(&cv_showping);
|
||||
|
||||
#ifdef SEENAMES
|
||||
CV_RegisterVar(&cv_allowseenames);
|
||||
|
@ -1213,16 +1228,16 @@ static void SendNameAndColor(void)
|
|||
}
|
||||
else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUsable(consoleplayer, foundskin))
|
||||
{
|
||||
boolean notsame;
|
||||
//boolean notsame;
|
||||
|
||||
cv_skin.value = foundskin;
|
||||
|
||||
notsame = (cv_skin.value != players[consoleplayer].skin);
|
||||
//notsame = (cv_skin.value != players[consoleplayer].skin);
|
||||
|
||||
SetPlayerSkin(consoleplayer, cv_skin.string);
|
||||
CV_StealthSet(&cv_skin, skins[cv_skin.value].name);
|
||||
|
||||
if (notsame)
|
||||
/*if (notsame)
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor, skins[cv_skin.value].prefcolor);
|
||||
|
||||
|
@ -1230,7 +1245,7 @@ static void SendNameAndColor(void)
|
|||
|
||||
if (players[consoleplayer].mo)
|
||||
players[consoleplayer].mo->color = (UINT8)players[consoleplayer].skincolor;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1341,15 +1356,16 @@ static void SendNameAndColor2(void)
|
|||
}
|
||||
else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1 && R_SkinUsable(secondplaya, foundskin))
|
||||
{
|
||||
boolean notsame;
|
||||
//boolean notsame;
|
||||
|
||||
cv_skin2.value = foundskin;
|
||||
|
||||
notsame = (cv_skin2.value != players[secondplaya].skin);
|
||||
//notsame = (cv_skin2.value != players[secondplaya].skin);
|
||||
|
||||
SetPlayerSkin(secondplaya, cv_skin2.string);
|
||||
CV_StealthSet(&cv_skin2, skins[cv_skin2.value].name);
|
||||
|
||||
if (notsame)
|
||||
/*if (notsame)
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor);
|
||||
|
||||
|
@ -1357,7 +1373,7 @@ static void SendNameAndColor2(void)
|
|||
|
||||
if (players[secondplaya].mo)
|
||||
players[secondplaya].mo->color = players[secondplaya].skincolor;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1924,6 +1940,17 @@ static void Command_Map_f(void)
|
|||
d = atoi(gametypename);
|
||||
if (d >= 0 && d < NUMGAMETYPES)
|
||||
newgametype = d;
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_ERROR,
|
||||
"Gametype number %d is out of range. Use a number between"
|
||||
" 0 and %d inclusive. ...Or just use the name. :v\n",
|
||||
d,
|
||||
NUMGAMETYPES-1);
|
||||
Z_Free(realmapname);
|
||||
Z_Free(mapname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2039,7 +2066,9 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
lastgametype = gametype;
|
||||
gametype = READUINT8(*cp);
|
||||
|
||||
if (gametype != lastgametype)
|
||||
if (gametype < 0 || gametype >= NUMGAMETYPES)
|
||||
gametype = lastgametype;
|
||||
else if (gametype != lastgametype)
|
||||
D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype
|
||||
|
||||
skipprecutscene = ((flags & (1<<2)) != 0);
|
||||
|
@ -3778,6 +3807,17 @@ static void CoopLives_OnChange(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void ExitMove_OnChange(void)
|
||||
{
|
||||
if (!(netgame || multiplayer) || gametype != GT_COOP)
|
||||
return;
|
||||
|
||||
if (cv_exitmove.value)
|
||||
CONS_Printf(M_GetText("Players can now move after completing the level.\n"));
|
||||
else
|
||||
CONS_Printf(M_GetText("Players can no longer move after completing the level.\n"));
|
||||
}
|
||||
|
||||
UINT32 timelimitintics = 0;
|
||||
|
||||
/** Deals with a timelimit change by printing the change to the console.
|
||||
|
@ -4250,6 +4290,8 @@ void Command_ExitGame_f(void)
|
|||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
CL_ClearPlayer(i);
|
||||
|
||||
players[consoleplayer].availabilities = players[1].availabilities = R_GetSkinAvailabilities(); // players[1] is supposed to be for 2p
|
||||
|
||||
splitscreen = false;
|
||||
SplitScreen_OnChange();
|
||||
botingame = false;
|
||||
|
@ -4310,9 +4352,9 @@ static void Command_Isgamemodified_f(void)
|
|||
if (savemoddata)
|
||||
CONS_Printf(M_GetText("modifiedgame is true, but you can save emblem and time data in this mod.\n"));
|
||||
else if (modifiedgame)
|
||||
CONS_Printf(M_GetText("modifiedgame is true, secrets will not be unlocked\n"));
|
||||
CONS_Printf(M_GetText("modifiedgame is true, extras will not be unlocked\n"));
|
||||
else
|
||||
CONS_Printf(M_GetText("modifiedgame is false, you can unlock secrets\n"));
|
||||
CONS_Printf(M_GetText("modifiedgame is false, you can unlock extras\n"));
|
||||
}
|
||||
|
||||
static void Command_Cheats_f(void)
|
||||
|
|
|
@ -94,7 +94,7 @@ extern consvar_t cv_recycler;
|
|||
|
||||
extern consvar_t cv_itemfinder;
|
||||
|
||||
extern consvar_t cv_inttime, cv_coopstarposts, cv_cooplives, cv_advancemap, cv_playersforexit;
|
||||
extern consvar_t cv_inttime, cv_coopstarposts, cv_cooplives, cv_advancemap, cv_playersforexit, cv_exitmove;
|
||||
extern consvar_t cv_overtime;
|
||||
extern consvar_t cv_startinglives;
|
||||
|
||||
|
@ -106,6 +106,9 @@ extern consvar_t cv_ringslinger, cv_soundtest;
|
|||
extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes;
|
||||
|
||||
extern consvar_t cv_maxping;
|
||||
extern consvar_t cv_pingtimeout;
|
||||
extern consvar_t cv_showping;
|
||||
|
||||
|
||||
extern consvar_t cv_skipmapcheck;
|
||||
|
||||
|
|
|
@ -716,7 +716,7 @@ void SV_FileSendTicker(void)
|
|||
if (ram)
|
||||
M_Memcpy(p->data, &f->id.ram[transfer[i].position], size);
|
||||
else if (fread(p->data, 1, size, transfer[i].currentfile) != size)
|
||||
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, strerror(ferror(transfer[i].currentfile)));
|
||||
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transfer[i].currentfile));
|
||||
p->position = LONG(transfer[i].position);
|
||||
// Put flag so receiver knows the total size
|
||||
if (transfer[i].position + size == f->size)
|
||||
|
@ -794,7 +794,7 @@ void Got_Filetxpak(void)
|
|||
// We can receive packet in the wrong order, anyway all os support gaped file
|
||||
fseek(file->file, pos, SEEK_SET);
|
||||
if (fwrite(netbuffer->u.filetxpak.data,size,1,file->file) != 1)
|
||||
I_Error("Can't write to %s: %s\n",filename, strerror(ferror(file->file)));
|
||||
I_Error("Can't write to %s: %s\n",filename, M_FileError(file->file));
|
||||
file->currentsize += size;
|
||||
|
||||
// Finished?
|
||||
|
|
|
@ -151,6 +151,7 @@ typedef enum
|
|||
/*** misc ***/
|
||||
PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs
|
||||
PF_CANCARRY = 1<<29, // Can carry another player?
|
||||
PF_FINISHED = 1<<30, // The player finished the level. NOT the same as exiting
|
||||
|
||||
// up to 1<<31 is free
|
||||
} pflags_t;
|
||||
|
|
239
src/dehacked.c
239
src/dehacked.c
|
@ -1201,6 +1201,14 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
word2 = tmp += 2;
|
||||
i = atoi(word2); // used for numerical settings
|
||||
|
||||
|
||||
if (fastcmp(word, "LEVELNAME"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2,
|
||||
sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num));
|
||||
strlcpy(mapheaderinfo[num-1]->selectheading, word2, sizeof(mapheaderinfo[num-1]->selectheading)); // not deh_ so only complains once
|
||||
continue;
|
||||
}
|
||||
// CHEAP HACK: move this over here for lowercase subtitles
|
||||
if (fastcmp(word, "SUBTITLE"))
|
||||
{
|
||||
|
@ -1344,12 +1352,6 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
}
|
||||
|
||||
// Strings that can be truncated
|
||||
else if (fastcmp(word, "LEVELNAME"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2,
|
||||
sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num));
|
||||
strlcpy(mapheaderinfo[num-1]->selectheading, word2, sizeof(mapheaderinfo[num-1]->selectheading)); // not deh_ so only complains once
|
||||
}
|
||||
else if (fastcmp(word, "SELECTHEADING"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->selectheading, word2,
|
||||
|
@ -1573,6 +1575,20 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
else
|
||||
mapheaderinfo[num-1]->levelflags &= ~LF_MIXNIGHTSCOUNTDOWN;
|
||||
}
|
||||
else if (fastcmp(word, "WARNINGTITLE"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->levelflags |= LF_WARNINGTITLE;
|
||||
else
|
||||
mapheaderinfo[num-1]->levelflags &= ~LF_WARNINGTITLE;
|
||||
}
|
||||
else if (fastcmp(word, "NOTITLECARD"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->levelflags |= LF_NOTITLECARD;
|
||||
else
|
||||
mapheaderinfo[num-1]->levelflags &= ~LF_NOTITLECARD;
|
||||
}
|
||||
|
||||
// Individual triggers for menu flags
|
||||
else if (fastcmp(word, "HIDDEN"))
|
||||
|
@ -2781,6 +2797,9 @@ static actionpointer_t actionpointers[] =
|
|||
{{A_PterabyteHover}, "A_PTERABYTEHOVER"},
|
||||
{{A_RolloutSpawn}, "A_ROLLOUTSPAWN"},
|
||||
{{A_RolloutRock}, "A_ROLLOUTROCK"},
|
||||
{{A_DragonbomberSpawn}, "A_DRAGONBOMERSPAWN"},
|
||||
{{A_DragonWing}, "A_DRAGONWING"},
|
||||
{{A_DragonSegment}, "A_DRAGONSEGMENT"},
|
||||
{{NULL}, "NONE"},
|
||||
|
||||
// This NULL entry must be the last in the list
|
||||
|
@ -3165,7 +3184,6 @@ static void readextraemblemdata(MYFILE *f, INT32 num)
|
|||
|
||||
// Now get the part after
|
||||
word2 = tmp += 2;
|
||||
strupr(word2);
|
||||
|
||||
value = atoi(word2); // used for numerical settings
|
||||
|
||||
|
@ -3177,22 +3195,26 @@ static void readextraemblemdata(MYFILE *f, INT32 num)
|
|||
sizeof (extraemblems[num-1].description), va("Extra emblem %d: objective", num));
|
||||
else if (fastcmp(word, "CONDITIONSET"))
|
||||
extraemblems[num-1].conditionset = (UINT8)value;
|
||||
else if (fastcmp(word, "SPRITE"))
|
||||
{
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
value = word2[0];
|
||||
else
|
||||
value += 'A'-1;
|
||||
|
||||
if (value < 'A' || value > 'Z')
|
||||
deh_warning("Emblem %d: sprite must be from A - Z (1 - 26)", num);
|
||||
else
|
||||
extraemblems[num-1].sprite = (UINT8)value;
|
||||
}
|
||||
else if (fastcmp(word, "COLOR"))
|
||||
extraemblems[num-1].color = get_number(word2);
|
||||
else
|
||||
deh_warning("Extra emblem %d: unknown word '%s'", num, word);
|
||||
{
|
||||
strupr(word2);
|
||||
if (fastcmp(word, "SPRITE"))
|
||||
{
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
value = word2[0];
|
||||
else
|
||||
value += 'A'-1;
|
||||
|
||||
if (value < 'A' || value > 'Z')
|
||||
deh_warning("Emblem %d: sprite must be from A - Z (1 - 26)", num);
|
||||
else
|
||||
extraemblems[num-1].sprite = (UINT8)value;
|
||||
}
|
||||
else if (fastcmp(word, "COLOR"))
|
||||
extraemblems[num-1].color = get_number(word2);
|
||||
else
|
||||
deh_warning("Extra emblem %d: unknown word '%s'", num, word);
|
||||
}
|
||||
}
|
||||
} while (!myfeof(f));
|
||||
|
||||
|
@ -3243,7 +3265,6 @@ static void readunlockable(MYFILE *f, INT32 num)
|
|||
|
||||
// Now get the part after
|
||||
word2 = tmp += 2;
|
||||
strupr(word2);
|
||||
|
||||
i = atoi(word2); // used for numerical settings
|
||||
|
||||
|
@ -3253,54 +3274,58 @@ static void readunlockable(MYFILE *f, INT32 num)
|
|||
else if (fastcmp(word, "OBJECTIVE"))
|
||||
deh_strlcpy(unlockables[num].objective, word2,
|
||||
sizeof (unlockables[num].objective), va("Unlockable %d: objective", num));
|
||||
else if (fastcmp(word, "HEIGHT"))
|
||||
unlockables[num].height = (UINT16)i;
|
||||
else if (fastcmp(word, "CONDITIONSET"))
|
||||
unlockables[num].conditionset = (UINT8)i;
|
||||
else if (fastcmp(word, "NOCECHO"))
|
||||
unlockables[num].nocecho = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
else if (fastcmp(word, "NOCHECKLIST"))
|
||||
unlockables[num].nochecklist = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
else if (fastcmp(word, "TYPE"))
|
||||
{
|
||||
if (fastcmp(word2, "NONE"))
|
||||
unlockables[num].type = SECRET_NONE;
|
||||
else if (fastcmp(word2, "ITEMFINDER"))
|
||||
unlockables[num].type = SECRET_ITEMFINDER;
|
||||
else if (fastcmp(word2, "EMBLEMHINTS"))
|
||||
unlockables[num].type = SECRET_EMBLEMHINTS;
|
||||
else if (fastcmp(word2, "PANDORA"))
|
||||
unlockables[num].type = SECRET_PANDORA;
|
||||
else if (fastcmp(word2, "CREDITS"))
|
||||
unlockables[num].type = SECRET_CREDITS;
|
||||
else if (fastcmp(word2, "RECORDATTACK"))
|
||||
unlockables[num].type = SECRET_RECORDATTACK;
|
||||
else if (fastcmp(word2, "NIGHTSMODE"))
|
||||
unlockables[num].type = SECRET_NIGHTSMODE;
|
||||
else if (fastcmp(word2, "HEADER"))
|
||||
unlockables[num].type = SECRET_HEADER;
|
||||
else if (fastcmp(word2, "LEVELSELECT"))
|
||||
unlockables[num].type = SECRET_LEVELSELECT;
|
||||
else if (fastcmp(word2, "WARP"))
|
||||
unlockables[num].type = SECRET_WARP;
|
||||
else if (fastcmp(word2, "SOUNDTEST"))
|
||||
unlockables[num].type = SECRET_SOUNDTEST;
|
||||
else
|
||||
unlockables[num].type = (INT16)i;
|
||||
}
|
||||
else if (fastcmp(word, "VAR"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
i = M_MapNumber(word2[0], word2[1]);
|
||||
|
||||
unlockables[num].variable = (INT16)i;
|
||||
}
|
||||
else
|
||||
deh_warning("Unlockable %d: unknown word '%s'", num+1, word);
|
||||
{
|
||||
strupr(word2);
|
||||
if (fastcmp(word, "HEIGHT"))
|
||||
unlockables[num].height = (UINT16)i;
|
||||
else if (fastcmp(word, "CONDITIONSET"))
|
||||
unlockables[num].conditionset = (UINT8)i;
|
||||
else if (fastcmp(word, "NOCECHO"))
|
||||
unlockables[num].nocecho = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
else if (fastcmp(word, "NOCHECKLIST"))
|
||||
unlockables[num].nochecklist = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
else if (fastcmp(word, "TYPE"))
|
||||
{
|
||||
if (fastcmp(word2, "NONE"))
|
||||
unlockables[num].type = SECRET_NONE;
|
||||
else if (fastcmp(word2, "ITEMFINDER"))
|
||||
unlockables[num].type = SECRET_ITEMFINDER;
|
||||
else if (fastcmp(word2, "EMBLEMHINTS"))
|
||||
unlockables[num].type = SECRET_EMBLEMHINTS;
|
||||
else if (fastcmp(word2, "PANDORA"))
|
||||
unlockables[num].type = SECRET_PANDORA;
|
||||
else if (fastcmp(word2, "CREDITS"))
|
||||
unlockables[num].type = SECRET_CREDITS;
|
||||
else if (fastcmp(word2, "RECORDATTACK"))
|
||||
unlockables[num].type = SECRET_RECORDATTACK;
|
||||
else if (fastcmp(word2, "NIGHTSMODE"))
|
||||
unlockables[num].type = SECRET_NIGHTSMODE;
|
||||
else if (fastcmp(word2, "HEADER"))
|
||||
unlockables[num].type = SECRET_HEADER;
|
||||
else if (fastcmp(word2, "LEVELSELECT"))
|
||||
unlockables[num].type = SECRET_LEVELSELECT;
|
||||
else if (fastcmp(word2, "WARP"))
|
||||
unlockables[num].type = SECRET_WARP;
|
||||
else if (fastcmp(word2, "SOUNDTEST"))
|
||||
unlockables[num].type = SECRET_SOUNDTEST;
|
||||
else
|
||||
unlockables[num].type = (INT16)i;
|
||||
}
|
||||
else if (fastcmp(word, "VAR"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
i = M_MapNumber(word2[0], word2[1]);
|
||||
|
||||
unlockables[num].variable = (INT16)i;
|
||||
}
|
||||
else
|
||||
deh_warning("Unlockable %d: unknown word '%s'", num+1, word);
|
||||
}
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
|
@ -4950,22 +4975,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_MINUS_BURST4",
|
||||
"S_MINUS_BURST5",
|
||||
"S_MINUS_POPUP",
|
||||
"S_MINUS_UPWARD1",
|
||||
"S_MINUS_UPWARD2",
|
||||
"S_MINUS_UPWARD3",
|
||||
"S_MINUS_UPWARD4",
|
||||
"S_MINUS_UPWARD5",
|
||||
"S_MINUS_UPWARD6",
|
||||
"S_MINUS_UPWARD7",
|
||||
"S_MINUS_UPWARD8",
|
||||
"S_MINUS_DOWNWARD1",
|
||||
"S_MINUS_DOWNWARD2",
|
||||
"S_MINUS_DOWNWARD3",
|
||||
"S_MINUS_DOWNWARD4",
|
||||
"S_MINUS_DOWNWARD5",
|
||||
"S_MINUS_DOWNWARD6",
|
||||
"S_MINUS_DOWNWARD7",
|
||||
"S_MINUS_DOWNWARD8",
|
||||
"S_MINUS_AERIAL1",
|
||||
"S_MINUS_AERIAL2",
|
||||
"S_MINUS_AERIAL3",
|
||||
"S_MINUS_AERIAL4",
|
||||
|
||||
// Minus dirt
|
||||
"S_MINUSDIRT1",
|
||||
|
@ -5041,6 +5054,26 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_PTERABYTE_SWOOPDOWN",
|
||||
"S_PTERABYTE_SWOOPUP",
|
||||
|
||||
// Dragonbomber
|
||||
"S_DRAGONBOMBER",
|
||||
"S_DRAGONWING1",
|
||||
"S_DRAGONWING2",
|
||||
"S_DRAGONWING3",
|
||||
"S_DRAGONWING4",
|
||||
"S_DRAGONTAIL_LOADED",
|
||||
"S_DRAGONTAIL_EMPTY",
|
||||
"S_DRAGONTAIL_EMPTYLOOP",
|
||||
"S_DRAGONTAIL_RELOAD",
|
||||
"S_DRAGONMINE",
|
||||
"S_DRAGONMINE_LAND1",
|
||||
"S_DRAGONMINE_LAND2",
|
||||
"S_DRAGONMINE_SLOWFLASH1",
|
||||
"S_DRAGONMINE_SLOWFLASH2",
|
||||
"S_DRAGONMINE_SLOWLOOP",
|
||||
"S_DRAGONMINE_FASTFLASH1",
|
||||
"S_DRAGONMINE_FASTFLASH2",
|
||||
"S_DRAGONMINE_FASTLOOP",
|
||||
|
||||
// Boss Explosion
|
||||
"S_BOSSEXPLODE",
|
||||
|
||||
|
@ -5343,6 +5376,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_FSGNA",
|
||||
"S_FSGNB",
|
||||
"S_FSGNC",
|
||||
"S_FSGND",
|
||||
|
||||
// Black Eggman (Boss 7)
|
||||
"S_BLACKEGG_STND",
|
||||
|
@ -7139,6 +7173,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_FOUR2",
|
||||
"S_FIVE2",
|
||||
|
||||
"S_FLIGHTINDICATOR",
|
||||
|
||||
"S_LOCKON1",
|
||||
"S_LOCKON2",
|
||||
"S_LOCKON3",
|
||||
|
@ -7322,13 +7358,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_FIREFLOWER2",
|
||||
"S_FIREFLOWER3",
|
||||
"S_FIREFLOWER4",
|
||||
"S_FIREBALL1",
|
||||
"S_FIREBALL2",
|
||||
"S_FIREBALL3",
|
||||
"S_FIREBALL4",
|
||||
"S_FIREBALLEXP1",
|
||||
"S_FIREBALLEXP2",
|
||||
"S_FIREBALLEXP3",
|
||||
"S_FIREBALL",
|
||||
"S_FIREBALLTRAIL1",
|
||||
"S_FIREBALLTRAIL2",
|
||||
"S_SHELL",
|
||||
"S_PUMA_START1",
|
||||
"S_PUMA_START2",
|
||||
|
@ -7497,6 +7529,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_POPHAT_SHOOT1",
|
||||
"S_POPHAT_SHOOT2",
|
||||
"S_POPHAT_SHOOT3",
|
||||
"S_POPHAT_SHOOT4",
|
||||
"S_POPSHOT",
|
||||
"S_POPSHOT_TRAIL",
|
||||
|
||||
"S_HIVEELEMENTAL_LOOK",
|
||||
"S_HIVEELEMENTAL_PREPARE1",
|
||||
|
@ -7628,8 +7663,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_DUST3",
|
||||
"S_DUST4",
|
||||
|
||||
"S_WOODDEBRIS",
|
||||
|
||||
"S_ROCKSPAWN",
|
||||
|
||||
"S_ROCKCRUMBLEA",
|
||||
|
@ -7648,7 +7681,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_ROCKCRUMBLEN",
|
||||
"S_ROCKCRUMBLEO",
|
||||
"S_ROCKCRUMBLEP",
|
||||
"S_GFZDEBRIS",
|
||||
"S_BRICKDEBRIS",
|
||||
"S_WOODDEBRIS",
|
||||
|
||||
#ifdef SEENAMES
|
||||
"S_NAMECHECK",
|
||||
|
@ -7712,6 +7747,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_PTERABYTESPAWNER", // Pterabyte spawner
|
||||
"MT_PTERABYTEWAYPOINT", // Pterabyte waypoint
|
||||
"MT_PTERABYTE", // Pterabyte
|
||||
"MT_DRAGONBOMBER", // Dragonbomber
|
||||
"MT_DRAGONWING", // Dragonbomber wing
|
||||
"MT_DRAGONTAIL", // Dragonbomber tail segment
|
||||
"MT_DRAGONMINE", // Dragonbomber mine
|
||||
|
||||
// Generic Boss Items
|
||||
"MT_BOSSEXPLODE",
|
||||
|
@ -8317,6 +8356,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_BLUEGOOMBA",
|
||||
"MT_FIREFLOWER",
|
||||
"MT_FIREBALL",
|
||||
"MT_FIREBALLTRAIL",
|
||||
"MT_SHELL",
|
||||
"MT_PUMA",
|
||||
"MT_PUMATRAIL",
|
||||
|
@ -8361,6 +8401,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_PENGUINATOR",
|
||||
"MT_POPHAT",
|
||||
"MT_POPSHOT",
|
||||
"MT_POPSHOT_TRAIL",
|
||||
|
||||
"MT_HIVEELEMENTAL",
|
||||
"MT_BUMBLEBORE",
|
||||
|
@ -8398,7 +8439,6 @@ 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",
|
||||
|
@ -8417,7 +8457,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_ROCKCRUMBLE14",
|
||||
"MT_ROCKCRUMBLE15",
|
||||
"MT_ROCKCRUMBLE16",
|
||||
"MT_GFZDEBRIS",
|
||||
"MT_BRICKDEBRIS",
|
||||
"MT_WOODDEBRIS",
|
||||
|
||||
#ifdef SEENAMES
|
||||
"MT_NAMECHECK",
|
||||
|
@ -8570,6 +8612,7 @@ static const char *const PLAYERFLAG_LIST[] = {
|
|||
/*** misc ***/
|
||||
"FORCESTRAFE", // Translate turn inputs into strafe inputs
|
||||
"CANCARRY", // Can carry?
|
||||
"FINISHED",
|
||||
|
||||
NULL // stop loop here.
|
||||
};
|
||||
|
@ -8856,7 +8899,7 @@ static const char *const MENUTYPES_LIST[] = {
|
|||
"OP_SCREENSHOTS",
|
||||
"OP_ERASEDATA",
|
||||
|
||||
// Secrets
|
||||
// Extras
|
||||
"SR_MAIN",
|
||||
"SR_PANDORA",
|
||||
"SR_LEVELSELECT",
|
||||
|
@ -9012,6 +9055,8 @@ struct {
|
|||
{"LF_NOZONE",LF_NOZONE},
|
||||
{"LF_SAVEGAME",LF_SAVEGAME},
|
||||
{"LF_MIXNIGHTSCOUNTDOWN",LF_MIXNIGHTSCOUNTDOWN},
|
||||
{"LF_NOTITLECARD",LF_NOTITLECARD},
|
||||
{"LF_WARNINGTITLE",LF_WARNINGTITLE},
|
||||
// And map flags
|
||||
{"LF2_HIDEINMENU",LF2_HIDEINMENU},
|
||||
{"LF2_HIDEINSTATS",LF2_HIDEINSTATS},
|
||||
|
|
|
@ -98,6 +98,9 @@ void I_FinishUpdate (void)
|
|||
if (cv_ticrate.value)
|
||||
SCR_DisplayTicRate();
|
||||
|
||||
if (cv_showping.value && netgame && consoleplayer != serverplayer)
|
||||
SCR_DisplayLocalPing();
|
||||
|
||||
//blast it to the screen
|
||||
// this code sucks
|
||||
//memcpy(dascreen,screens[0],screenwidth*screenheight);
|
||||
|
|
|
@ -349,6 +349,8 @@ typedef struct
|
|||
#define LF_NOZONE 16 ///< Don't include "ZONE" on level title
|
||||
#define LF_SAVEGAME 32 ///< Save the game upon loading this level
|
||||
#define LF_MIXNIGHTSCOUNTDOWN 64 ///< Play sfx_timeup instead of music change for NiGHTS countdown
|
||||
#define LF_WARNINGTITLE 128 ///< WARNING! WARNING! WARNING! WARNING!
|
||||
#define LF_NOTITLECARD 256 ///< Don't start the title card
|
||||
|
||||
#define LF2_HIDEINMENU 1 ///< Hide in the multiplayer menu
|
||||
#define LF2_HIDEINSTATS 2 ///< Hide in the statistics screen
|
||||
|
@ -433,7 +435,6 @@ typedef struct
|
|||
tic_t time; ///< Time in which the level was finished.
|
||||
UINT32 score; ///< Score when the level was finished.
|
||||
UINT16 rings; ///< Rings when the level was finished.
|
||||
boolean gotperfect; ///< Got perfect bonus?
|
||||
} recorddata_t;
|
||||
|
||||
/** Setup for one NiGHTS map.
|
||||
|
|
|
@ -856,7 +856,7 @@ void F_IntroDrawer(void)
|
|||
if (rendermode != render_none)
|
||||
{
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeColorFill(31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
|
@ -866,10 +866,11 @@ void F_IntroDrawer(void)
|
|||
else if (intro_scenenum == 10)
|
||||
{
|
||||
// The only fade to white in the entire damn game.
|
||||
// (not true)
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
|
||||
F_WipeColorFill(0);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
|
@ -879,7 +880,7 @@ void F_IntroDrawer(void)
|
|||
if (rendermode != render_none)
|
||||
{
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeColorFill(31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
|
@ -926,7 +927,7 @@ void F_IntroDrawer(void)
|
|||
patch_t *radar = W_CachePatchName("RADAR", PU_CACHE);
|
||||
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeColorFill(31);
|
||||
V_DrawScaledPatch(0, 0, 0, radar);
|
||||
W_UnlockCachedPatch(radar);
|
||||
V_DrawString(8, 128, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
|
@ -939,7 +940,7 @@ void F_IntroDrawer(void)
|
|||
patch_t *grass = W_CachePatchName("SGRASS5", PU_CACHE);
|
||||
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeColorFill(31);
|
||||
V_DrawScaledPatch(0, 0, 0, grass);
|
||||
W_UnlockCachedPatch(grass);
|
||||
V_DrawString(8, 128, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
|
@ -952,7 +953,7 @@ void F_IntroDrawer(void)
|
|||
patch_t *confront = W_CachePatchName("CONFRONT", PU_CACHE);
|
||||
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeColorFill(31);
|
||||
V_DrawSmallScaledPatch(0, 0, 0, confront);
|
||||
W_UnlockCachedPatch(confront);
|
||||
V_DrawString(8, 128, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
|
@ -965,7 +966,7 @@ void F_IntroDrawer(void)
|
|||
patch_t *sdo = W_CachePatchName("SONICDO2", PU_CACHE);
|
||||
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeColorFill(31);
|
||||
V_DrawSmallScaledPatch(0, 0, 0, sdo);
|
||||
W_UnlockCachedPatch(sdo);
|
||||
V_DrawString(224, 8, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
|
@ -1385,13 +1386,16 @@ boolean F_CreditResponder(event_t *event)
|
|||
|
||||
void F_StartGameEvaluation(void)
|
||||
{
|
||||
// Credits option in secrets menu
|
||||
// Credits option in extras menu
|
||||
if (cursaveslot == -1)
|
||||
{
|
||||
S_FadeOutStopMusic(2*MUSICRATE);
|
||||
F_StartGameEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
S_FadeOutStopMusic(5*MUSICRATE);
|
||||
|
||||
G_SetGamestate(GS_EVALUATION);
|
||||
|
||||
// Just in case they're open ... somehow
|
||||
|
@ -1537,9 +1541,9 @@ void F_GameEvaluationDrawer(void)
|
|||
}
|
||||
}
|
||||
else if (netgame)
|
||||
V_DrawString(8, 96, V_YELLOWMAP, "Prizes only\nawarded in\nsingle player!");
|
||||
V_DrawString(8, 96, V_YELLOWMAP, "Multiplayer games\ncan't unlock\nextras!");
|
||||
else
|
||||
V_DrawString(8, 96, V_YELLOWMAP, "Prizes not\nawarded in\nmodified games!");
|
||||
V_DrawString(8, 96, V_YELLOWMAP, "Modified games\ncan't unlock\nextras!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1586,7 +1590,7 @@ void F_GameEvaluationTicker(void)
|
|||
{
|
||||
HU_SetCEchoFlags(V_YELLOWMAP|V_RETURN8);
|
||||
HU_SetCEchoDuration(6);
|
||||
HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Prizes only awarded in singleplayer!");
|
||||
HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Multiplayer games can't unlock extras!");
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
}
|
||||
else if (!modifiedgame || savemoddata)
|
||||
|
@ -1608,7 +1612,7 @@ void F_GameEvaluationTicker(void)
|
|||
{
|
||||
HU_SetCEchoFlags(V_YELLOWMAP|V_RETURN8);
|
||||
HU_SetCEchoDuration(6);
|
||||
HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Prizes not awarded in modified games!");
|
||||
HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Modified games can't unlock extras!");
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
}
|
||||
}
|
||||
|
@ -1621,6 +1625,7 @@ void F_GameEvaluationTicker(void)
|
|||
// ==========
|
||||
|
||||
#define INFLECTIONPOINT (6*TICRATE)
|
||||
#define STOPPINGPOINT (14*TICRATE)
|
||||
#define SPARKLLOOPTIME 15 // must be odd
|
||||
|
||||
void F_StartEnding(void)
|
||||
|
@ -1638,7 +1643,7 @@ void F_StartEnding(void)
|
|||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
S_StopMusic(); // todo: placeholder
|
||||
S_StopMusic();
|
||||
S_StopSounds();
|
||||
|
||||
finalecount = -10; // what? this totally isn't a hack. why are you asking?
|
||||
|
@ -1679,7 +1684,7 @@ void F_StartEnding(void)
|
|||
UINT8 skinnum = players[consoleplayer].skin;
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= (XTRA_ENDING+2)+1)
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes > (XTRA_ENDING+2))
|
||||
{
|
||||
sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
// character head, skin specific
|
||||
|
@ -1712,13 +1717,16 @@ void F_StartEnding(void)
|
|||
|
||||
void F_EndingTicker(void)
|
||||
{
|
||||
if (++finalecount > INFLECTIONPOINT*2)
|
||||
if (++finalecount > STOPPINGPOINT)
|
||||
{
|
||||
F_StartCredits();
|
||||
wipetypepre = INT16_MAX;
|
||||
return;
|
||||
}
|
||||
|
||||
if (finalecount == -8)
|
||||
S_ChangeMusicInternal((goodending ? "_endg" : "_endb"), false);
|
||||
|
||||
if (goodending && finalecount == INFLECTIONPOINT) // time to swap some assets
|
||||
{
|
||||
endegrk[0] = W_CachePatchName("ENDEGRK2", PU_LEVEL);
|
||||
|
@ -2105,26 +2113,26 @@ void F_EndingDrawer(void)
|
|||
|
||||
if (finalecount < 10)
|
||||
trans = (10-finalecount)/2;
|
||||
else if (finalecount > (2*INFLECTIONPOINT) - 20)
|
||||
else if (finalecount > STOPPINGPOINT - 20)
|
||||
{
|
||||
trans = 10 + (finalecount/2) - INFLECTIONPOINT;
|
||||
trans = 10 + (finalecount - STOPPINGPOINT)/2;
|
||||
donttouch = true;
|
||||
}
|
||||
|
||||
if (trans != 10)
|
||||
if (trans < 10)
|
||||
{
|
||||
//colset(linkmap, 164, 165, 169); -- the ideal purple colour to represent a clicked in-game link, but not worth it just for a soundtest-controlled secret
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 8, V_ALLOWLOWERCASE|(trans<<V_ALPHASHIFT), str);
|
||||
V_DrawCharacter(32, BASEVIDHEIGHT-16, '>'|(trans<<V_ALPHASHIFT), false);
|
||||
V_DrawString(40, ((finalecount == (2*INFLECTIONPOINT)-(20+TICRATE)) ? 1 : 0)+BASEVIDHEIGHT-16, ((timesBeaten || finalecount >= (2*INFLECTIONPOINT)-TICRATE) ? V_PURPLEMAP : V_BLUEMAP)|(trans<<V_ALPHASHIFT), " [S] ===>");
|
||||
V_DrawString(40, ((finalecount == STOPPINGPOINT-(20+TICRATE)) ? 1 : 0)+BASEVIDHEIGHT-16, ((timesBeaten || finalecount >= STOPPINGPOINT-TICRATE) ? V_PURPLEMAP : V_BLUEMAP)|(trans<<V_ALPHASHIFT), " [S] ===>");
|
||||
}
|
||||
|
||||
if (finalecount > (2*INFLECTIONPOINT)-(20+(2*TICRATE)))
|
||||
if (finalecount > STOPPINGPOINT-(20+(2*TICRATE)))
|
||||
{
|
||||
INT32 trans2 = abs((5*FINECOSINE((FixedAngle((finalecount*5)<<FRACBITS)>>ANGLETOFINESHIFT & FINEMASK)))>>FRACBITS)+2;
|
||||
if (!donttouch)
|
||||
{
|
||||
trans = 10 + ((2*INFLECTIONPOINT)-(20+(2*TICRATE))) - finalecount;
|
||||
trans = 10 + (STOPPINGPOINT-(20+(2*TICRATE))) - finalecount;
|
||||
if (trans > trans2)
|
||||
trans2 = trans;
|
||||
}
|
||||
|
@ -2148,7 +2156,6 @@ void F_StartGameEnd(void)
|
|||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
S_StopMusic();
|
||||
S_StopSounds();
|
||||
|
||||
// In case menus are still up?!!
|
||||
|
@ -2582,9 +2589,7 @@ void F_TitleScreenDrawer(void)
|
|||
// Draw that sky!
|
||||
if (curbgcolor >= 0)
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor);
|
||||
else if (titlemapinaction && curbghide && ! hidetitlemap)
|
||||
D_Render();
|
||||
else
|
||||
else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS)
|
||||
F_SkyScroll(curbgxspeed, curbgyspeed, curbgname);
|
||||
|
||||
// Don't draw outside of the title screen, or if the patch isn't there.
|
||||
|
@ -3344,6 +3349,10 @@ void F_TitleScreenTicker(boolean run)
|
|||
if (run)
|
||||
finalecount++;
|
||||
|
||||
// don't trigger if doing anything besides idling on title
|
||||
if (gameaction != ga_nothing || gamestate != GS_TITLESCREEN)
|
||||
return;
|
||||
|
||||
// Execute the titlemap camera settings
|
||||
if (titlemapinaction)
|
||||
{
|
||||
|
@ -3390,10 +3399,6 @@ void F_TitleScreenTicker(boolean run)
|
|||
}
|
||||
}
|
||||
|
||||
// don't trigger if doing anything besides idling on title
|
||||
if (gameaction != ga_nothing || gamestate != GS_TITLESCREEN)
|
||||
return;
|
||||
|
||||
// no demos to play? or, are they disabled?
|
||||
if (!cv_rollingdemos.value || !numDemos)
|
||||
return;
|
||||
|
@ -3546,7 +3551,7 @@ void F_ContinueDrawer(void)
|
|||
if (timetonext >= (11*TICRATE)+10)
|
||||
return;
|
||||
|
||||
V_DrawLevelTitle(x - (V_LevelNameWidth("CONTINUE")>>1), 16, 0, "CONTINUE");
|
||||
V_DrawLevelTitle(x - (V_LevelNameWidth("Continue?")>>1), 16, 0, "Continue?");
|
||||
|
||||
// Two stars...
|
||||
patch = W_CachePatchName("CONTSTAR", PU_CACHE);
|
||||
|
|
|
@ -141,11 +141,42 @@ void F_MenuPresTicker(boolean run);
|
|||
#define FORCEWIPEOFF -2
|
||||
|
||||
extern boolean WipeInAction;
|
||||
extern boolean WipeStageTitle;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIPESTYLE_NORMAL,
|
||||
WIPESTYLE_LEVEL
|
||||
} wipestyle_t;
|
||||
extern wipestyle_t wipestyle;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WSF_FADEOUT = 1,
|
||||
WSF_FADEIN = 1<<1,
|
||||
WSF_TOWHITE = 1<<2,
|
||||
WSF_CROSSFADE = 1<<3,
|
||||
} wipestyleflags_t;
|
||||
extern wipestyleflags_t wipestyleflags;
|
||||
|
||||
#define FADECOLORMAPDIV 8
|
||||
#define FADECOLORMAPROWS (256/FADECOLORMAPDIV)
|
||||
|
||||
#define FADEREDFACTOR 15
|
||||
#define FADEGREENFACTOR 15
|
||||
#define FADEBLUEFACTOR 10
|
||||
|
||||
extern INT32 lastwipetic;
|
||||
|
||||
// Don't know where else to place this constant
|
||||
// But this file seems appropriate
|
||||
#define PRELEVELTIME 24 // frames in tics
|
||||
|
||||
void F_WipeStartScreen(void);
|
||||
void F_WipeEndScreen(void);
|
||||
void F_RunWipe(UINT8 wipetype, boolean drawMenu);
|
||||
void F_WipeStageTitle(void);
|
||||
#define F_WipeColorFill(c) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, c)
|
||||
tic_t F_GetWipeLength(UINT8 wipetype);
|
||||
boolean F_WipeExists(UINT8 wipetype);
|
||||
|
||||
|
|
95
src/f_wipe.c
95
src/f_wipe.c
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include "r_draw.h" // transtable
|
||||
#include "p_pspr.h" // tr_transxxx
|
||||
#include "p_local.h"
|
||||
#include "st_stuff.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
|
@ -25,8 +27,15 @@
|
|||
#include "m_menu.h"
|
||||
#include "console.h"
|
||||
#include "d_main.h"
|
||||
#include "g_game.h"
|
||||
#include "m_misc.h" // movie mode
|
||||
|
||||
#include "doomstat.h"
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
#include "lua_hud.h" // level title
|
||||
#endif
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
#endif
|
||||
|
@ -82,8 +91,12 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
|
|||
//--------------------------------------------------------------------------
|
||||
|
||||
boolean WipeInAction = false;
|
||||
boolean WipeStageTitle = false;
|
||||
INT32 lastwipetic = 0;
|
||||
|
||||
wipestyle_t wipestyle = WIPESTYLE_NORMAL;
|
||||
wipestyleflags_t wipestyleflags = WSF_CROSSFADE;
|
||||
|
||||
#ifndef NOWIPE
|
||||
static UINT8 *wipe_scr_start; //screen 3
|
||||
static UINT8 *wipe_scr_end; //screen 4
|
||||
|
@ -148,7 +161,10 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
|
|||
{
|
||||
// Determine pixel to use from fademask
|
||||
pcolor = &pMasterPalette[*lump++];
|
||||
*mask++ = FixedDiv((pcolor->s.red+1)<<FRACBITS, paldiv)>>FRACBITS;
|
||||
if (wipestyle == WIPESTYLE_LEVEL)
|
||||
*mask++ = pcolor->s.red / FADECOLORMAPDIV;
|
||||
else
|
||||
*mask++ = FixedDiv((pcolor->s.red+1)<<FRACBITS, paldiv)>>FRACBITS;
|
||||
}
|
||||
|
||||
fm.xscale = FixedDiv(vid.width<<FRACBITS, fm.width<<FRACBITS);
|
||||
|
@ -169,6 +185,21 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/** Draw the stage title.
|
||||
*/
|
||||
void F_WipeStageTitle(void)
|
||||
{
|
||||
// draw level title
|
||||
if ((WipeStageTitle && st_overlay)
|
||||
&& (wipestyle == WIPESTYLE_LEVEL)
|
||||
&& !(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)
|
||||
&& *mapheaderinfo[gamemap-1]->lvlttl != '\0')
|
||||
{
|
||||
ST_runTitleCard();
|
||||
ST_drawWipeTitleCard();
|
||||
}
|
||||
}
|
||||
|
||||
/** Wipe ticker
|
||||
*
|
||||
* \param fademask pixels to change
|
||||
|
@ -251,7 +282,7 @@ static void F_DoWipe(fademask_t *fademask)
|
|||
relativepos += vid.width;
|
||||
}
|
||||
}
|
||||
else if (*mask == 10)
|
||||
else if (*mask >= ((wipestyle == WIPESTYLE_LEVEL) ? FADECOLORMAPROWS : 10))
|
||||
{
|
||||
// shortcut - memcpy target to work
|
||||
while (draw_linestogo--)
|
||||
|
@ -262,8 +293,25 @@ static void F_DoWipe(fademask_t *fademask)
|
|||
}
|
||||
else
|
||||
{
|
||||
// pointer to transtable that this mask would use
|
||||
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
|
||||
if (wipestyle == WIPESTYLE_LEVEL)
|
||||
{
|
||||
int nmask;
|
||||
UINT8 *fade = fadecolormap;
|
||||
|
||||
if (wipestyleflags & WSF_TOWHITE)
|
||||
fade = fadecolormap + (FADECOLORMAPROWS * 256);
|
||||
|
||||
nmask = *mask;
|
||||
if (wipestyleflags & WSF_FADEIN)
|
||||
nmask = (FADECOLORMAPROWS-1) - nmask;
|
||||
|
||||
transtbl = fade + (nmask * 256);
|
||||
}
|
||||
else
|
||||
{
|
||||
// pointer to transtable that this mask would use
|
||||
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
|
||||
}
|
||||
|
||||
// DRAWING LOOP
|
||||
while (draw_linestogo--)
|
||||
|
@ -273,8 +321,16 @@ static void F_DoWipe(fademask_t *fademask)
|
|||
e = e_base + relativepos;
|
||||
draw_rowstogo = draw_rowend - draw_rowstart;
|
||||
|
||||
while (draw_rowstogo--)
|
||||
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
|
||||
if (wipestyle == WIPESTYLE_LEVEL)
|
||||
{
|
||||
while (draw_rowstogo--)
|
||||
*w++ = transtbl[*e++];
|
||||
}
|
||||
else
|
||||
{
|
||||
while (draw_rowstogo--)
|
||||
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
|
||||
}
|
||||
|
||||
relativepos += vid.width;
|
||||
}
|
||||
|
@ -346,6 +402,15 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
WipeInAction = true;
|
||||
wipe_scr = screens[0];
|
||||
|
||||
// don't know where else to put this.
|
||||
// this any good?
|
||||
if ((gamestate == GS_LEVEL || gamestate == GS_TITLESCREEN)
|
||||
&& (wipestyleflags & (WSF_FADEIN|WSF_FADEOUT)) // only if one of those wipestyleflags are actually set
|
||||
&& !(wipestyleflags & WSF_CROSSFADE)) // and if not crossfading
|
||||
wipestyle = WIPESTYLE_LEVEL;
|
||||
else
|
||||
wipestyle = WIPESTYLE_NORMAL;
|
||||
|
||||
// lastwipetic should either be 0 or the tic we last wiped
|
||||
// on for fade-to-black
|
||||
for (;;)
|
||||
|
@ -362,10 +427,20 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
HWR_DoWipe(wipetype, wipeframe-1); // send in the wipe type and wipeframe because we need to cache the graphic
|
||||
{
|
||||
// send in the wipe type and wipe frame because we need to cache the graphic
|
||||
if (wipestyle == WIPESTYLE_LEVEL)
|
||||
HWR_DoTintedWipe(wipetype, wipeframe-1);
|
||||
else
|
||||
HWR_DoWipe(wipetype, wipeframe-1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
F_DoWipe(fmask);
|
||||
F_DoWipe(fmask);
|
||||
|
||||
if (wipestyle == WIPESTYLE_LEVEL)
|
||||
F_WipeStageTitle();
|
||||
|
||||
I_OsPolling();
|
||||
I_UpdateNoBlit();
|
||||
|
||||
|
@ -377,7 +452,9 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
}
|
||||
|
||||
WipeInAction = false;
|
||||
WipeStageTitle = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -408,6 +485,8 @@ tic_t F_GetWipeLength(UINT8 wipetype)
|
|||
#endif
|
||||
}
|
||||
|
||||
/** Does the specified wipe exist?
|
||||
*/
|
||||
boolean F_WipeExists(UINT8 wipetype)
|
||||
{
|
||||
#ifdef NOWIPE
|
||||
|
|
293
src/g_game.c
293
src/g_game.c
|
@ -47,6 +47,10 @@
|
|||
#include "m_cond.h" // condition sets
|
||||
#include "md5.h" // demo checksums
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
#include "lua_hud.h"
|
||||
#endif
|
||||
|
||||
gameaction_t gameaction;
|
||||
gamestate_t gamestate = GS_NULL;
|
||||
UINT8 ultimatemode = false;
|
||||
|
@ -168,6 +172,7 @@ mapheader_t* mapheaderinfo[NUMMAPS] = {NULL};
|
|||
|
||||
static boolean exitgame = false;
|
||||
static boolean retrying = false;
|
||||
static boolean retryingmodeattack = false;
|
||||
|
||||
UINT8 stagefailed; // Used for GEMS BONUS? Also to see if you beat the stage.
|
||||
|
||||
|
@ -536,11 +541,99 @@ void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare)
|
|||
ntemprecords.nummares = mare;
|
||||
}
|
||||
|
||||
//
|
||||
// G_UpdateRecordReplays
|
||||
//
|
||||
// Update replay files/data, etc. for Record Attack
|
||||
// See G_SetNightsRecords for NiGHTS Attack.
|
||||
//
|
||||
static void G_UpdateRecordReplays(void)
|
||||
{
|
||||
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
|
||||
char *gpath;
|
||||
char lastdemo[256], bestdemo[256];
|
||||
UINT8 earnedEmblems;
|
||||
|
||||
// Record new best time
|
||||
if (!mainrecords[gamemap-1])
|
||||
G_AllocMainRecordData(gamemap-1);
|
||||
|
||||
if (players[consoleplayer].score > mainrecords[gamemap-1]->score)
|
||||
mainrecords[gamemap-1]->score = players[consoleplayer].score;
|
||||
|
||||
if ((mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < mainrecords[gamemap-1]->time))
|
||||
mainrecords[gamemap-1]->time = players[consoleplayer].realtime;
|
||||
|
||||
if ((UINT16)(players[consoleplayer].rings) > mainrecords[gamemap-1]->rings)
|
||||
mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings);
|
||||
|
||||
// Save demo!
|
||||
bestdemo[255] = '\0';
|
||||
lastdemo[255] = '\0';
|
||||
G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].rings));
|
||||
G_CheckDemoStatus();
|
||||
|
||||
I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
|
||||
I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755);
|
||||
|
||||
if ((gpath = malloc(glen)) == NULL)
|
||||
I_Error("Out of memory for replay filepath\n");
|
||||
|
||||
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
|
||||
snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name);
|
||||
|
||||
if (FIL_FileExists(lastdemo))
|
||||
{
|
||||
UINT8 *buf;
|
||||
size_t len = FIL_ReadFile(lastdemo, &buf);
|
||||
|
||||
snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
|
||||
if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1)
|
||||
{ // Better time, save this demo.
|
||||
if (FIL_FileExists(bestdemo))
|
||||
remove(bestdemo);
|
||||
FIL_WriteFile(bestdemo, buf, len);
|
||||
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo);
|
||||
}
|
||||
|
||||
snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
|
||||
if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1)))
|
||||
{ // Better score, save this demo.
|
||||
if (FIL_FileExists(bestdemo))
|
||||
remove(bestdemo);
|
||||
FIL_WriteFile(bestdemo, buf, len);
|
||||
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW HIGH SCORE!"), M_GetText("Saved replay as"), bestdemo);
|
||||
}
|
||||
|
||||
snprintf(bestdemo, 255, "%s-%s-rings-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
|
||||
if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<2)))
|
||||
{ // Better rings, save this demo.
|
||||
if (FIL_FileExists(bestdemo))
|
||||
remove(bestdemo);
|
||||
FIL_WriteFile(bestdemo, buf, len);
|
||||
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW MOST RINGS!"), M_GetText("Saved replay as"), bestdemo);
|
||||
}
|
||||
|
||||
//CONS_Printf("%s '%s'\n", M_GetText("Saved replay as"), lastdemo);
|
||||
|
||||
Z_Free(buf);
|
||||
}
|
||||
free(gpath);
|
||||
|
||||
// Check emblems when level data is updated
|
||||
if ((earnedEmblems = M_CheckLevelEmblems()))
|
||||
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for Record Attack records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
|
||||
|
||||
// Update timeattack menu's replay availability.
|
||||
Nextmap_OnChange();
|
||||
}
|
||||
|
||||
void G_SetNightsRecords(void)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 totalscore = 0;
|
||||
tic_t totaltime = 0;
|
||||
UINT8 earnedEmblems;
|
||||
|
||||
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
|
||||
char *gpath;
|
||||
|
@ -640,6 +733,9 @@ void G_SetNightsRecords(void)
|
|||
}
|
||||
free(gpath);
|
||||
|
||||
if ((earnedEmblems = M_CheckLevelEmblems()))
|
||||
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for NiGHTS records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
|
||||
|
||||
// If the mare count changed, this will update the score display
|
||||
Nextmap_OnChange();
|
||||
}
|
||||
|
@ -923,11 +1019,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
movebkey = PLAYER1INPUTDOWN(gc_backward);
|
||||
|
||||
mouseaiming = (PLAYER1INPUTDOWN(gc_mouseaiming)) ^
|
||||
(cv_chasecam.value ? cv_chasefreelook.value : cv_alwaysfreelook.value);
|
||||
((cv_chasecam.value && !player->spectator) ? cv_chasefreelook.value : cv_alwaysfreelook.value);
|
||||
analogjoystickmove = cv_usejoystick.value && !Joystick.bGamepadStyle;
|
||||
gamepadjoystickmove = cv_usejoystick.value && Joystick.bGamepadStyle;
|
||||
|
||||
thisjoyaiming = (cv_chasecam.value) ? cv_chasefreelook.value : cv_alwaysfreelook.value;
|
||||
thisjoyaiming = (cv_chasecam.value && !player->spectator) ? cv_chasefreelook.value : cv_alwaysfreelook.value;
|
||||
|
||||
// Reset the vertical look if we're no longer joyaiming
|
||||
if (!thisjoyaiming && joyaiming)
|
||||
|
@ -1252,11 +1348,11 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
movebkey = PLAYER2INPUTDOWN(gc_backward);
|
||||
|
||||
mouseaiming = (PLAYER2INPUTDOWN(gc_mouseaiming)) ^
|
||||
(cv_chasecam2.value ? cv_chasefreelook2.value : cv_alwaysfreelook2.value);
|
||||
((cv_chasecam2.value && !player->spectator) ? cv_chasefreelook2.value : cv_alwaysfreelook2.value);
|
||||
analogjoystickmove = cv_usejoystick2.value && !Joystick2.bGamepadStyle;
|
||||
gamepadjoystickmove = cv_usejoystick2.value && Joystick2.bGamepadStyle;
|
||||
|
||||
thisjoyaiming = (cv_chasecam2.value) ? cv_chasefreelook2.value : cv_alwaysfreelook2.value;
|
||||
thisjoyaiming = (cv_chasecam2.value && !player->spectator) ? cv_chasefreelook2.value : cv_alwaysfreelook2.value;
|
||||
|
||||
// Reset the vertical look if we're no longer joyaiming
|
||||
if (!thisjoyaiming && joyaiming)
|
||||
|
@ -1703,6 +1799,58 @@ void G_DoLoadLevel(boolean resetplayer)
|
|||
CON_ClearHUD();
|
||||
}
|
||||
|
||||
//
|
||||
// Start the title card.
|
||||
//
|
||||
void G_StartTitleCard(void)
|
||||
{
|
||||
wipestyleflags |= WSF_FADEIN;
|
||||
wipestyleflags &= ~WSF_FADEOUT;
|
||||
|
||||
// The title card has been disabled for this map.
|
||||
// Oh well.
|
||||
if (mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)
|
||||
{
|
||||
WipeStageTitle = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// clear the hud
|
||||
CON_ClearHUD();
|
||||
|
||||
// prepare status bar
|
||||
ST_startTitleCard();
|
||||
|
||||
// start the title card
|
||||
WipeStageTitle = (!titlemapinaction);
|
||||
}
|
||||
|
||||
//
|
||||
// Run the title card before fading in to the level.
|
||||
//
|
||||
void G_PreLevelTitleCard(tic_t ticker, boolean update)
|
||||
{
|
||||
tic_t starttime = I_GetTime();
|
||||
tic_t endtime = starttime + (PRELEVELTIME*NEWTICRATERATIO);
|
||||
tic_t nowtime = starttime;
|
||||
tic_t lasttime = starttime;
|
||||
while (nowtime < endtime)
|
||||
{
|
||||
// draw loop
|
||||
while (!((nowtime = I_GetTime()) - lasttime))
|
||||
I_Sleep();
|
||||
lasttime = nowtime;
|
||||
|
||||
ST_runTitleCard();
|
||||
ST_preLevelTitleCardDrawer(ticker, update);
|
||||
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
if (takescreenshot) // Only take screenshots after drawing.
|
||||
M_DoScreenShot();
|
||||
}
|
||||
}
|
||||
|
||||
INT32 pausedelay = 0;
|
||||
boolean pausebreakkey = false;
|
||||
static INT32 camtoggledelay, camtoggledelay2 = 0;
|
||||
|
@ -1868,7 +2016,7 @@ boolean G_Responder(event_t *ev)
|
|||
pausedelay = 1+(NEWTICRATE/2);
|
||||
else if (++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3))
|
||||
{
|
||||
G_SetRetryFlag();
|
||||
G_SetModeAttackRetryFlag();
|
||||
return true;
|
||||
}
|
||||
pausedelay++; // counteract subsequent subtraction this frame
|
||||
|
@ -1992,7 +2140,7 @@ void G_Ticker(boolean run)
|
|||
if (titledemo)
|
||||
F_TitleDemoTicker();
|
||||
P_Ticker(run); // tic the game
|
||||
ST_Ticker();
|
||||
ST_Ticker(run);
|
||||
F_TextPromptTicker();
|
||||
AM_Ticker();
|
||||
HU_Ticker();
|
||||
|
@ -2175,6 +2323,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
outofcoop = players[player].outofcoop;
|
||||
pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER));
|
||||
|
||||
if (!betweenmaps)
|
||||
pflags |= (players[player].pflags & PF_FINISHED);
|
||||
|
||||
// As long as we're not in multiplayer, carry over cheatcodes from map to map
|
||||
if (!(netgame || multiplayer))
|
||||
pflags |= (players[player].pflags & (PF_GODMODE|PF_NOCLIP|PF_INVIS));
|
||||
|
@ -2709,6 +2860,7 @@ void G_DoReborn(INT32 playernum)
|
|||
|
||||
// Do a wipe
|
||||
wipegamestate = -1;
|
||||
wipestyleflags = WSF_CROSSFADE;
|
||||
|
||||
if (camera.chase)
|
||||
P_ResetCamera(&players[displayplayer], &camera);
|
||||
|
@ -2829,10 +2981,35 @@ void G_AddPlayer(INT32 playernum)
|
|||
if (G_GametypeUsesLives() || ((netgame || multiplayer) && gametype == GT_COOP))
|
||||
p->lives = cv_startinglives.value;
|
||||
|
||||
if (countplayers && !notexiting)
|
||||
if ((countplayers && !notexiting) || G_IsSpecialStage(gamemap))
|
||||
P_DoPlayerExit(p);
|
||||
}
|
||||
|
||||
boolean G_EnoughPlayersFinished(void)
|
||||
{
|
||||
UINT8 numneeded = (G_IsSpecialStage(gamemap) ? 4 : cv_playersforexit.value);
|
||||
INT32 total = 0;
|
||||
INT32 exiting = 0;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator || players[i].bot)
|
||||
continue;
|
||||
if (players[i].lives <= 0)
|
||||
continue;
|
||||
|
||||
total++;
|
||||
if ((players[i].pflags & PF_FINISHED) || players[i].exiting)
|
||||
exiting++;
|
||||
}
|
||||
|
||||
if (exiting)
|
||||
return exiting * 4 / total >= numneeded;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void G_ExitLevel(void)
|
||||
{
|
||||
if (gamestate == GS_LEVEL)
|
||||
|
@ -2925,7 +3102,7 @@ boolean G_GametypeUsesLives(void)
|
|||
// Coop, Competitive
|
||||
if ((gametype == GT_COOP || gametype == GT_COMPETITION)
|
||||
&& !(modeattacking || metalrecording) // No lives in Time Attack
|
||||
//&& !G_IsSpecialStage(gamemap)
|
||||
&& !G_IsSpecialStage(gamemap)
|
||||
&& !(maptol & TOL_NIGHTS)) // No lives in NiGHTS
|
||||
return true;
|
||||
return false;
|
||||
|
@ -3038,12 +3215,51 @@ static INT16 RandMap(INT16 tolflags, INT16 pprevmap)
|
|||
return ix;
|
||||
}
|
||||
|
||||
//
|
||||
// G_UpdateVisited
|
||||
//
|
||||
static void G_UpdateVisited(void)
|
||||
{
|
||||
boolean spec = G_IsSpecialStage(gamemap);
|
||||
// Update visitation flags?
|
||||
if ((!modifiedgame || savemoddata) // Not modified
|
||||
&& !multiplayer && !demoplayback && (gametype == GT_COOP) // SP/RA/NiGHTS mode
|
||||
&& !(spec && stagefailed)) // Not failed the special stage
|
||||
{
|
||||
UINT8 earnedEmblems;
|
||||
|
||||
// Update visitation flags
|
||||
mapvisited[gamemap-1] |= MV_BEATEN;
|
||||
// eh, what the hell
|
||||
if (ultimatemode)
|
||||
mapvisited[gamemap-1] |= MV_ULTIMATE;
|
||||
// may seem incorrect but IS possible in what the main game uses as special stages, and nummaprings will be -1 in NiGHTS
|
||||
if (nummaprings > 0 && players[consoleplayer].rings >= nummaprings)
|
||||
mapvisited[gamemap-1] |= MV_PERFECT;
|
||||
if (!spec)
|
||||
{
|
||||
// not available to special stages because they can only really be done in one order in an unmodified game, so impossible for first six and trivial for seventh
|
||||
if (ALL7EMERALDS(emeralds))
|
||||
mapvisited[gamemap-1] |= MV_ALLEMERALDS;
|
||||
}
|
||||
|
||||
if (modeattacking == ATTACKING_RECORD)
|
||||
G_UpdateRecordReplays();
|
||||
else if (modeattacking == ATTACKING_NIGHTS)
|
||||
G_SetNightsRecords();
|
||||
|
||||
if ((earnedEmblems = M_CompletionEmblems()))
|
||||
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// G_DoCompleted
|
||||
//
|
||||
static void G_DoCompleted(void)
|
||||
{
|
||||
INT32 i;
|
||||
boolean spec = G_IsSpecialStage(gamemap);
|
||||
|
||||
tokenlist = 0; // Reset the list
|
||||
|
||||
|
@ -3076,14 +3292,14 @@ static void G_DoCompleted(void)
|
|||
nextmap = (INT16)(mapheaderinfo[gamemap-1]->nextlevel-1);
|
||||
|
||||
// Remember last map for when you come out of the special stage.
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
if (!spec)
|
||||
lastmap = nextmap;
|
||||
|
||||
// If nextmap is actually going to get used, make sure it points to
|
||||
// a map of the proper gametype -- skip levels that don't support
|
||||
// the current gametype. (Helps avoid playing boss levels in Race,
|
||||
// for instance).
|
||||
if (!token && !G_IsSpecialStage(gamemap)
|
||||
if (!token && !spec
|
||||
&& (nextmap >= 0 && nextmap < NUMMAPS))
|
||||
{
|
||||
register INT16 cm = nextmap;
|
||||
|
@ -3147,7 +3363,7 @@ static void G_DoCompleted(void)
|
|||
gottoken = false;
|
||||
}
|
||||
|
||||
if (G_IsSpecialStage(gamemap) && !gottoken)
|
||||
if (spec && !gottoken)
|
||||
nextmap = lastmap; // Exiting from a special stage? Go back to the game. Tails 08-11-2001
|
||||
|
||||
automapactive = false;
|
||||
|
@ -3166,17 +3382,29 @@ static void G_DoCompleted(void)
|
|||
if (nextmap < NUMMAPS && !mapheaderinfo[nextmap])
|
||||
P_AllocMapHeader(nextmap);
|
||||
|
||||
if (skipstats && !modeattacking) // Don't skip stats if we're in record attack
|
||||
if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed))
|
||||
{
|
||||
G_UpdateVisited();
|
||||
G_AfterIntermission();
|
||||
}
|
||||
else
|
||||
{
|
||||
G_SetGamestate(GS_INTERMISSION);
|
||||
Y_StartIntermission();
|
||||
G_UpdateVisited();
|
||||
}
|
||||
}
|
||||
|
||||
void G_AfterIntermission(void)
|
||||
{
|
||||
Y_CleanupScreenBuffer();
|
||||
|
||||
if (modeattacking)
|
||||
{
|
||||
M_EndModeAttackRun();
|
||||
return;
|
||||
}
|
||||
|
||||
HU_ClearCEcho();
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1) // Start a custom cutscene.
|
||||
|
@ -3343,7 +3571,6 @@ void G_LoadGameData(void)
|
|||
UINT32 recscore;
|
||||
tic_t rectime;
|
||||
UINT16 recrings;
|
||||
boolean gotperf;
|
||||
|
||||
UINT8 recmares;
|
||||
INT32 curmare;
|
||||
|
@ -3441,7 +3668,7 @@ void G_LoadGameData(void)
|
|||
recscore = READUINT32(save_p);
|
||||
rectime = (tic_t)READUINT32(save_p);
|
||||
recrings = READUINT16(save_p);
|
||||
gotperf = (boolean)READUINT8(save_p);
|
||||
save_p++; // compat
|
||||
|
||||
if (recrings > 10000 || recscore > MAXSCORE)
|
||||
goto datacorrupt;
|
||||
|
@ -3453,9 +3680,6 @@ void G_LoadGameData(void)
|
|||
mainrecords[i]->time = rectime;
|
||||
mainrecords[i]->rings = recrings;
|
||||
}
|
||||
|
||||
if (gotperf)
|
||||
mainrecords[i]->gotperfect = gotperf;
|
||||
}
|
||||
|
||||
// Nights records
|
||||
|
@ -3587,15 +3811,14 @@ void G_SaveGameData(void)
|
|||
WRITEUINT32(save_p, mainrecords[i]->score);
|
||||
WRITEUINT32(save_p, mainrecords[i]->time);
|
||||
WRITEUINT16(save_p, mainrecords[i]->rings);
|
||||
WRITEUINT8(save_p, mainrecords[i]->gotperfect);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITEUINT32(save_p, 0);
|
||||
WRITEUINT32(save_p, 0);
|
||||
WRITEUINT16(save_p, 0);
|
||||
WRITEUINT8(save_p, 0);
|
||||
}
|
||||
WRITEUINT8(save_p, 0); // compat
|
||||
}
|
||||
|
||||
// NiGHTS records
|
||||
|
@ -4031,7 +4254,7 @@ char *G_BuildMapTitle(INT32 mapnum)
|
|||
len += strlen(mapheaderinfo[mapnum-1]->lvlttl);
|
||||
if (!(mapheaderinfo[mapnum-1]->levelflags & LF_NOZONE))
|
||||
{
|
||||
zonetext = M_GetText("ZONE");
|
||||
zonetext = M_GetText("Zone");
|
||||
len += strlen(zonetext) + 1; // ' ' + zonetext
|
||||
}
|
||||
if (actnum > 0)
|
||||
|
@ -4642,6 +4865,12 @@ void G_WriteGhostTic(mobj_t *ghost)
|
|||
oldghost.flags2 |= MF2_AMBUSH;
|
||||
}
|
||||
|
||||
if (ghost->player->followmobj->scale != ghost->scale)
|
||||
{
|
||||
followtic |= FZT_SCALE;
|
||||
WRITEFIXED(demo_p,ghost->player->followmobj->scale);
|
||||
}
|
||||
|
||||
temp = (INT16)((ghost->player->followmobj->x-ghost->x)>>8);
|
||||
WRITEINT16(demo_p,temp);
|
||||
temp = (INT16)((ghost->player->followmobj->y-ghost->y)>>8);
|
||||
|
@ -4653,11 +4882,6 @@ void G_WriteGhostTic(mobj_t *ghost)
|
|||
WRITEUINT16(demo_p,ghost->player->followmobj->sprite);
|
||||
WRITEUINT8(demo_p,(ghost->player->followmobj->frame & FF_FRAMEMASK));
|
||||
WRITEUINT8(demo_p,ghost->player->followmobj->color);
|
||||
if (ghost->player->followmobj->scale != ghost->scale)
|
||||
{
|
||||
followtic |= FZT_SCALE;
|
||||
WRITEFIXED(demo_p,ghost->player->followmobj->scale);
|
||||
}
|
||||
|
||||
*followtic_p = followtic;
|
||||
}
|
||||
|
@ -5194,7 +5418,10 @@ void G_ReadMetalTic(mobj_t *metal)
|
|||
{ // But wait, there's more!
|
||||
xziptic = READUINT8(metal_p);
|
||||
if (xziptic & EZT_FLIP)
|
||||
{
|
||||
metal->eflags ^= MFE_VERTICALFLIP;
|
||||
metal->flags2 ^= MF2_OBJECTFLIP;
|
||||
}
|
||||
if (xziptic & EZT_SCALE)
|
||||
{
|
||||
metal->destscale = READFIXED(metal_p);
|
||||
|
@ -6702,6 +6929,22 @@ boolean G_GetRetryFlag(void)
|
|||
return retrying;
|
||||
}
|
||||
|
||||
void G_SetModeAttackRetryFlag(void)
|
||||
{
|
||||
retryingmodeattack = true;
|
||||
G_SetRetryFlag();
|
||||
}
|
||||
|
||||
void G_ClearModeAttackRetryFlag(void)
|
||||
{
|
||||
retryingmodeattack = false;
|
||||
}
|
||||
|
||||
boolean G_GetModeAttackRetryFlag(void)
|
||||
{
|
||||
return retryingmodeattack;
|
||||
}
|
||||
|
||||
// Time utility functions
|
||||
INT32 G_TicsToHours(tic_t tics)
|
||||
{
|
||||
|
|
|
@ -140,7 +140,8 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost);
|
|||
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar,
|
||||
boolean SSSG, boolean FLS);
|
||||
void G_DoLoadLevel(boolean resetplayer);
|
||||
|
||||
void G_StartTitleCard(void);
|
||||
void G_PreLevelTitleCard(tic_t ticker, boolean update);
|
||||
void G_DeferedPlayDemo(const char *demo);
|
||||
|
||||
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
|
||||
|
@ -208,6 +209,7 @@ boolean G_GametypeHasSpectators(void);
|
|||
boolean G_RingSlingerGametype(void);
|
||||
boolean G_PlatformGametype(void);
|
||||
boolean G_TagGametype(void);
|
||||
boolean G_EnoughPlayersFinished(void);
|
||||
void G_ExitLevel(void);
|
||||
void G_NextLevel(void);
|
||||
void G_Continue(void);
|
||||
|
@ -223,10 +225,14 @@ void G_AddPlayer(INT32 playernum);
|
|||
void G_SetExitGameFlag(void);
|
||||
void G_ClearExitGameFlag(void);
|
||||
boolean G_GetExitGameFlag(void);
|
||||
|
||||
void G_SetRetryFlag(void);
|
||||
void G_ClearRetryFlag(void);
|
||||
boolean G_GetRetryFlag(void);
|
||||
|
||||
void G_SetModeAttackRetryFlag(void);
|
||||
void G_ClearModeAttackRetryFlag(void);
|
||||
boolean G_GetModeAttackRetryFlag(void);
|
||||
|
||||
void G_LoadGameData(void);
|
||||
void G_LoadGameSettings(void);
|
||||
|
|
|
@ -771,18 +771,25 @@ void HWR_InitTextureCache(void)
|
|||
gr_textures2 = NULL;
|
||||
}
|
||||
|
||||
|
||||
// Callback function for HWR_FreeTextureCache.
|
||||
static void FreeMipmapColormap(INT32 patchnum, void *patch)
|
||||
{
|
||||
GLPatch_t* const grpatch = patch;
|
||||
GLPatch_t* const pat = patch;
|
||||
(void)patchnum; //unused
|
||||
while (grpatch->mipmap->nextcolormap)
|
||||
while (pat->mipmap && pat->mipmap->nextcolormap) // The mipmap must be valid, obviously
|
||||
{
|
||||
GLMipmap_t *grmip = grpatch->mipmap->nextcolormap;
|
||||
grpatch->mipmap->nextcolormap = grmip->nextcolormap;
|
||||
if (grmip->grInfo.data) Z_Free(grmip->grInfo.data);
|
||||
free(grmip);
|
||||
// Confusing at first, but pat->mipmap->nextcolormap
|
||||
// at the beginning of the loop is the first colormap
|
||||
// from the linked list of colormaps
|
||||
GLMipmap_t *next = pat->mipmap->nextcolormap;
|
||||
// Set the first colormap
|
||||
// to the one that comes after it
|
||||
pat->mipmap->nextcolormap = next->nextcolormap;
|
||||
// Free image data from memory
|
||||
if (next->grInfo.data)
|
||||
Z_Free(next->grInfo.data);
|
||||
// Free the old colormap from memory
|
||||
free(next);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -799,7 +806,7 @@ void HWR_FreeTextureCache(void)
|
|||
|
||||
// Alam: free the Z_Blocks before freeing it's users
|
||||
|
||||
// free all skin after each level: must be done after pfnClearMipMapCache!
|
||||
// free all patch colormaps after each level: must be done after ClearMipMapCache!
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap);
|
||||
|
||||
|
|
|
@ -380,9 +380,9 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
|
|||
{
|
||||
FSurfaceInfo Surf;
|
||||
Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff;
|
||||
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value];
|
||||
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[cv_translucenthud.value];
|
||||
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value];
|
||||
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[st_translucency];
|
||||
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[st_translucency];
|
||||
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[st_translucency];
|
||||
else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel];
|
||||
flags |= PF_Modulated;
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
|
||||
|
@ -538,9 +538,9 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
|
|||
{
|
||||
FSurfaceInfo Surf;
|
||||
Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff;
|
||||
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value];
|
||||
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[cv_translucenthud.value];
|
||||
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value];
|
||||
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[st_translucency];
|
||||
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[st_translucency];
|
||||
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[st_translucency];
|
||||
else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel];
|
||||
flags |= PF_Modulated;
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
|
||||
|
|
|
@ -184,6 +184,7 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_CANG
|
||||
&lspr[NOLIGHT], // SPR_PYRE
|
||||
&lspr[NOLIGHT], // SPR_PTER
|
||||
&lspr[NOLIGHT], // SPR_DRAB
|
||||
|
||||
// Generic Boos Items
|
||||
&lspr[JETLIGHT_L], // SPR_JETF // Boss jet fumes
|
||||
|
@ -505,6 +506,7 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
// Game Indicators
|
||||
&lspr[NOLIGHT], // SPR_SCOR
|
||||
&lspr[NOLIGHT], // SPR_DRWN
|
||||
&lspr[NOLIGHT], // SPR_FLII
|
||||
&lspr[NOLIGHT], // SPR_LCKN
|
||||
&lspr[NOLIGHT], // SPR_TTAG
|
||||
&lspr[NOLIGHT], // SPR_GFLG
|
||||
|
@ -584,7 +586,6 @@ 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
|
||||
|
@ -604,8 +605,10 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_ROIO
|
||||
&lspr[NOLIGHT], // SPR_ROIP
|
||||
|
||||
// Bricks
|
||||
// Level debris
|
||||
&lspr[NOLIGHT], // SPR_GFZD
|
||||
&lspr[NOLIGHT], // SPR_BRIC
|
||||
&lspr[NOLIGHT], // SPR_WDDB
|
||||
|
||||
// Gravity Well Objects
|
||||
&lspr[NOLIGHT], // SPR_GWLG
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "../st_stuff.h"
|
||||
#include "../i_system.h"
|
||||
#include "../m_cheat.h"
|
||||
#include "../f_finale.h"
|
||||
#ifdef ESLOPE
|
||||
#include "../p_slopes.h"
|
||||
#endif
|
||||
|
@ -111,7 +112,6 @@ static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0,
|
|||
static consvar_t cv_gralpha = {"gr_alpha", "160", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static float HWRWipeCounter = 1.0f;
|
||||
consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grFov_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned,
|
||||
|
@ -1973,7 +1973,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
|||
{
|
||||
// Single sided line... Deal only with the middletexture (if one exists)
|
||||
gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture);
|
||||
if (gr_midtexture && gr_linedef->special != 41) // Ignore horizon line for OGL
|
||||
if (gr_midtexture && gr_linedef->special != HORIZONSPECIAL) // Ignore horizon line for OGL
|
||||
{
|
||||
{
|
||||
fixed_t texturevpeg;
|
||||
|
@ -4068,6 +4068,7 @@ static gr_vissprite_t *HWR_NewVisSprite(void)
|
|||
return HWR_GetVisSprite(gr_visspritecount++);
|
||||
}
|
||||
|
||||
#ifdef GLBADSHADOWS
|
||||
// Finds a floor through which light does not pass.
|
||||
static fixed_t HWR_OpaqueFloorAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
|
||||
{
|
||||
|
@ -4098,6 +4099,7 @@ static fixed_t HWR_OpaqueFloorAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t hei
|
|||
|
||||
return floorz;
|
||||
}
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
|
||||
//
|
||||
// HWR_DoCulling
|
||||
|
@ -4139,6 +4141,7 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef GLBADSHADOWS
|
||||
static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float this_scale)
|
||||
{
|
||||
FOutVector swallVerts[4];
|
||||
|
@ -4311,6 +4314,7 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t
|
|||
HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip);
|
||||
}
|
||||
}
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
|
||||
// This is expecting a pointer to an array containing 4 wallVerts for a sprite
|
||||
static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts)
|
||||
|
@ -4386,6 +4390,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
HWR_GetMappedPatch(gpatch, spr->colormap);
|
||||
|
||||
#ifdef GLBADSHADOWS
|
||||
// Draw shadow BEFORE sprite
|
||||
if (cv_shadow.value // Shadows enabled
|
||||
&& (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
|
||||
|
@ -4401,6 +4406,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
////////////////////
|
||||
HWR_DrawSpriteShadow(spr, gpatch, this_scale);
|
||||
}
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
|
||||
baseWallVerts[0].x = baseWallVerts[3].x = spr->x1;
|
||||
baseWallVerts[2].x = baseWallVerts[1].x = spr->x2;
|
||||
|
@ -4788,6 +4794,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
HWR_GetMappedPatch(gpatch, spr->colormap);
|
||||
|
||||
#ifdef GLBADSHADOWS
|
||||
// Draw shadow BEFORE sprite
|
||||
if (cv_shadow.value // Shadows enabled
|
||||
&& (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
|
||||
|
@ -4803,6 +4810,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
////////////////////
|
||||
HWR_DrawSpriteShadow(spr, gpatch, this_scale);
|
||||
}
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
|
||||
// if it has a dispoffset, push it a little towards the camera
|
||||
if (spr->dispoffset) {
|
||||
|
@ -7017,7 +7025,6 @@ void HWR_StartScreenWipe(void)
|
|||
|
||||
void HWR_EndScreenWipe(void)
|
||||
{
|
||||
HWRWipeCounter = 0.0f;
|
||||
//CONS_Debug(DBG_RENDER, "In HWR_EndScreenWipe()\n");
|
||||
HWD.pfnEndScreenWipe();
|
||||
}
|
||||
|
@ -7027,38 +7034,55 @@ void HWR_DrawIntermissionBG(void)
|
|||
HWD.pfnDrawIntermissionBG();
|
||||
}
|
||||
|
||||
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
|
||||
//
|
||||
// hwr mode wipes
|
||||
//
|
||||
static lumpnum_t wipelumpnum;
|
||||
|
||||
// puts wipe lumpname in wipename[9]
|
||||
static boolean HWR_WipeCheck(UINT8 wipenum, UINT8 scrnnum)
|
||||
{
|
||||
static char lumpname[9] = "FADEmmss";
|
||||
lumpnum_t lumpnum;
|
||||
size_t lsize;
|
||||
|
||||
if (wipenum > 99 || scrnnum > 99) // not a valid wipe number
|
||||
return; // shouldn't end up here really, the loop should've stopped running beforehand
|
||||
// not a valid wipe number
|
||||
if (wipenum > 99 || scrnnum > 99)
|
||||
return false; // shouldn't end up here really, the loop should've stopped running beforehand
|
||||
|
||||
// puts the numbers into the lumpname
|
||||
sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)wipenum, (UINT16)scrnnum);
|
||||
lumpnum = W_CheckNumForName(lumpname);
|
||||
// puts the numbers into the wipename
|
||||
lumpname[4] = '0'+(wipenum/10);
|
||||
lumpname[5] = '0'+(wipenum%10);
|
||||
lumpname[6] = '0'+(scrnnum/10);
|
||||
lumpname[7] = '0'+(scrnnum%10);
|
||||
wipelumpnum = W_CheckNumForName(lumpname);
|
||||
|
||||
if (lumpnum == LUMPERROR) // again, shouldn't be here really
|
||||
return;
|
||||
|
||||
lsize = W_LumpLength(lumpnum);
|
||||
// again, shouldn't be here really
|
||||
if (wipelumpnum == LUMPERROR)
|
||||
return false;
|
||||
|
||||
lsize = W_LumpLength(wipelumpnum);
|
||||
if (!(lsize == 256000 || lsize == 64000 || lsize == 16000 || lsize == 4000))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Fade mask lump %s of incorrect size, ignored\n", lumpname);
|
||||
return; // again, shouldn't get here if it is a bad size
|
||||
return false; // again, shouldn't get here if it is a bad size
|
||||
}
|
||||
|
||||
HWR_GetFadeMask(lumpnum);
|
||||
return true;
|
||||
}
|
||||
|
||||
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
|
||||
{
|
||||
if (!HWR_WipeCheck(wipenum, scrnnum))
|
||||
return;
|
||||
|
||||
HWR_GetFadeMask(wipelumpnum);
|
||||
HWD.pfnDoScreenWipe();
|
||||
}
|
||||
|
||||
HWRWipeCounter += 0.05f; // increase opacity of end screen
|
||||
|
||||
if (HWRWipeCounter > 1.0f)
|
||||
HWRWipeCounter = 1.0f;
|
||||
void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum)
|
||||
{
|
||||
// It does the same thing
|
||||
HWR_DoWipe(wipenum, scrnnum);
|
||||
}
|
||||
|
||||
void HWR_MakeScreenFinalTexture(void)
|
||||
|
|
|
@ -66,6 +66,7 @@ void HWR_StartScreenWipe(void);
|
|||
void HWR_EndScreenWipe(void);
|
||||
void HWR_DrawIntermissionBG(void);
|
||||
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
|
||||
void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum);
|
||||
void HWR_MakeScreenFinalTexture(void);
|
||||
void HWR_DrawScreenFinalTexture(int width, int height);
|
||||
|
||||
|
|
|
@ -2587,7 +2587,6 @@ EXPORT void HWRAPI(DoScreenWipe)(void)
|
|||
tex_downloaded = endScreenWipe;
|
||||
}
|
||||
|
||||
|
||||
// Create a texture from the screen.
|
||||
EXPORT void HWRAPI(MakeScreenTexture) (void)
|
||||
{
|
||||
|
|
|
@ -2322,13 +2322,14 @@ void HU_Erase(void)
|
|||
//
|
||||
// HU_drawPing
|
||||
//
|
||||
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
|
||||
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags)
|
||||
{
|
||||
UINT8 numbars = 1; // how many ping bars do we draw?
|
||||
UINT8 barcolor = 35; // color we use for the bars (green, yellow or red)
|
||||
SINT8 i = 0;
|
||||
SINT8 yoffset = 6;
|
||||
INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2);
|
||||
INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping),
|
||||
V_ALLOWLOWERCASE|flags)/2);
|
||||
|
||||
if (ping < 128)
|
||||
{
|
||||
|
@ -2342,13 +2343,13 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
|
|||
}
|
||||
|
||||
if (!notext || vid.width >= 640) // how sad, we're using a shit resolution.
|
||||
V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE, va("%dms", ping));
|
||||
V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE|flags, va("%dms", ping));
|
||||
|
||||
for (i=0; (i<3); i++) // Draw the ping bar
|
||||
{
|
||||
V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31);
|
||||
V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31|flags);
|
||||
if (i < numbars)
|
||||
V_DrawFill(x+2 *(i-1), y+yoffset-3, 1, 8-yoffset-1, barcolor);
|
||||
V_DrawFill(x+2 *(i-1), y+yoffset-3, 1, 8-yoffset-1, barcolor|flags);
|
||||
|
||||
yoffset -= 2;
|
||||
}
|
||||
|
@ -2379,7 +2380,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
if (!splitscreen) // don't draw it on splitscreen,
|
||||
{
|
||||
if (!(tab[i].num == serverplayer))
|
||||
HU_drawPing(x+ 253, y+2, playerpingtable[tab[i].num], false);
|
||||
HU_drawPing(x+ 253, y, playerpingtable[tab[i].num], false, 0);
|
||||
//else
|
||||
// V_DrawSmallString(x+ 246, y+4, V_YELLOWMAP, "SERVER");
|
||||
}
|
||||
|
@ -2443,7 +2444,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
V_DrawSmallScaledPatch(x-32, y-4, 0, tagico);
|
||||
}
|
||||
|
||||
if (players[tab[i].num].exiting)
|
||||
if (players[tab[i].num].exiting || (players[tab[i].num].pflags & PF_FINISHED))
|
||||
V_DrawSmallScaledPatch(x - SHORT(exiticon->width)/2 - 1, y-3, 0, exiticon);
|
||||
|
||||
if (gametype == GT_RACE)
|
||||
|
@ -2578,7 +2579,7 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
if (!splitscreen)
|
||||
{
|
||||
if (!(tab[i].num == serverplayer))
|
||||
HU_drawPing(x+ 135, y+3, playerpingtable[tab[i].num], true);
|
||||
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
|
||||
//else
|
||||
//V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
|
||||
}
|
||||
|
@ -2702,7 +2703,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
if (!splitscreen)
|
||||
{
|
||||
if (!(tab[i].num == serverplayer))
|
||||
HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false);
|
||||
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
|
||||
//else
|
||||
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
|
||||
}
|
||||
|
@ -2733,7 +2734,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
|||
|
||||
strlcpy(name, tab[i].name, 7);
|
||||
if (!(tab[i].num == serverplayer))
|
||||
HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false);
|
||||
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
|
||||
//else
|
||||
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
|
||||
|
||||
|
@ -2747,7 +2748,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
|||
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
||||
V_DrawSmallScaledPatch(x-28, y-4, 0, tagico);
|
||||
|
||||
if (players[tab[i].num].exiting)
|
||||
if (players[tab[i].num].exiting || (players[tab[i].num].pflags & PF_FINISHED))
|
||||
V_DrawSmallScaledPatch(x - SHORT(exiticon->width)/2 - 1, y-3, 0, exiticon);
|
||||
|
||||
// Draw emeralds
|
||||
|
@ -2841,7 +2842,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
|
|||
if (!splitscreen) // don't draw it on splitscreen,
|
||||
{
|
||||
if (!(tab[i].num == serverplayer))
|
||||
HU_drawPing(x+ 135, y+3, playerpingtable[tab[i].num], true);
|
||||
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
|
||||
//else
|
||||
// V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
// Level title font
|
||||
#define LT_FONTSTART '!' // the first font characters
|
||||
#define LT_FONTEND 'Z' // the last font characters
|
||||
#define LT_FONTEND 'z' // the last font characters
|
||||
#define LT_FONTSIZE (LT_FONTEND - LT_FONTSTART + 1)
|
||||
|
||||
#define CRED_FONTSTART '!' // the first font character
|
||||
|
@ -113,7 +113,7 @@ void HU_Drawer(void);
|
|||
char HU_dequeueChatChar(void);
|
||||
void HU_Erase(void);
|
||||
void HU_clearChatChars(void);
|
||||
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext); // Lat': Ping drawer for scoreboard.
|
||||
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags); // Lat': Ping drawer for scoreboard.
|
||||
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
|
||||
void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
|
||||
void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
|
||||
|
|
375
src/info.c
375
src/info.c
|
@ -72,6 +72,7 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"CANG", // Canarivore gas
|
||||
"PYRE", // Pyre Fly
|
||||
"PTER", // Pterabyte
|
||||
"DRAB", // Dragonbomber
|
||||
|
||||
// Generic Boss Items
|
||||
"JETF", // Boss jet fumes
|
||||
|
@ -402,6 +403,7 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
// Game Indicators
|
||||
"SCOR", // Score logo
|
||||
"DRWN", // Drowning Timer
|
||||
"FLII", // Flight indicator
|
||||
"LCKN", // Target
|
||||
"TTAG", // Tag Sign
|
||||
"GFLG", // Got Flag sign
|
||||
|
@ -481,7 +483,6 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"BOM3", // Boss Explosion 2
|
||||
"BOM4", // Underwater Explosion
|
||||
"BMNB", // Mine Explosion
|
||||
"WDDB", // Wood Debris
|
||||
|
||||
// Crumbly rocks
|
||||
"ROIA",
|
||||
|
@ -501,8 +502,10 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"ROIO",
|
||||
"ROIP",
|
||||
|
||||
// Bricks
|
||||
"BRIC",
|
||||
// Level debris
|
||||
"GFZD", // GFZ debris
|
||||
"BRIC", // Bricks
|
||||
"WDDB", // Wood Debris
|
||||
|
||||
// Gravity Well Objects
|
||||
"GWLG",
|
||||
|
@ -632,7 +635,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
|
|||
0, // SPR2_TRNS,
|
||||
|
||||
FF_SPR2SUPER|SPR2_STND, // SPR2_NSTD,
|
||||
FF_SPR2SUPER|SPR2_FLT , // SPR2_NFLT,
|
||||
FF_SPR2SUPER|SPR2_FALL, // SPR2_NFLT,
|
||||
0, // SPR2_NFLY, (will never be referenced unless skin 0 lacks this)
|
||||
SPR2_NFLY, // SPR2_NDRL,
|
||||
FF_SPR2SUPER|SPR2_STUN, // SPR2_NSTN,
|
||||
|
@ -1071,23 +1074,11 @@ state_t states[NUMSTATES] =
|
|||
{SPR_MNUD, 2|FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUS_BURST4}, // S_MINUS_BURST3
|
||||
{SPR_MNUD, 3|FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUS_BURST5}, // S_MINUS_BURST4
|
||||
{SPR_MNUD, 4|FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUSDIRT2}, // S_MINUS_BURST5
|
||||
{SPR_MNUS, 0, 1, {A_MinusPopup}, 0, 0, S_MINUS_UPWARD1}, // S_MINUS_POPUP
|
||||
{SPR_MNUS, 0, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD2}, // S_MINUS_UPWARD1
|
||||
{SPR_MNUS, 1, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD3}, // S_MINUS_UPWARD2
|
||||
{SPR_MNUS, 2, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD4}, // S_MINUS_UPWARD3
|
||||
{SPR_MNUS, 3, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD5}, // S_MINUS_UPWARD4
|
||||
{SPR_MNUS, 4, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD6}, // S_MINUS_UPWARD5
|
||||
{SPR_MNUS, 5, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD7}, // S_MINUS_UPWARD6
|
||||
{SPR_MNUS, 6, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD8}, // S_MINUS_UPWARD7
|
||||
{SPR_MNUS, 7, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD1}, // S_MINUS_UPWARD8
|
||||
{SPR_MNUS, 8, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD2}, // S_MINUS_DOWNWARD1
|
||||
{SPR_MNUS, 9, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD3}, // S_MINUS_DOWNWARD2
|
||||
{SPR_MNUS, 10, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD4}, // S_MINUS_DOWNWARD3
|
||||
{SPR_MNUS, 11, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD5}, // S_MINUS_DOWNWARD4
|
||||
{SPR_MNUS, 12, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD6}, // S_MINUS_DOWNWARD5
|
||||
{SPR_MNUS, 13, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD7}, // S_MINUS_DOWNWARD6
|
||||
{SPR_MNUS, 14, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD8}, // S_MINUS_DOWNWARD7
|
||||
{SPR_MNUS, 15, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD1}, // S_MINUS_DOWNWARD8
|
||||
{SPR_MNUS, 3, 1, {A_MinusPopup}, 0, 0, S_MINUS_AERIAL1}, // S_MINUS_POPUP
|
||||
{SPR_MNUS, 0, 1, {A_MinusCheck}, 0, 1, S_MINUS_AERIAL2}, // S_MINUS_AERIAL1
|
||||
{SPR_MNUS, 1, 1, {A_MinusCheck}, 0, 1, S_MINUS_AERIAL3}, // S_MINUS_AERIAL2
|
||||
{SPR_MNUS, 2, 1, {A_MinusCheck}, 0, 1, S_MINUS_AERIAL4}, // S_MINUS_AERIAL3
|
||||
{SPR_MNUS, 3, 1, {A_MinusCheck}, 0, 1, S_MINUS_AERIAL1}, // S_MINUS_AERIAL4
|
||||
|
||||
{SPR_MNUD, FF_ANIMATE, 6, {NULL}, 1, 5, S_MINUSDIRT2}, // S_MINUSDIRT1
|
||||
{SPR_MNUD, 5, 8, {NULL}, 3, 5, S_MINUSDIRT3}, // S_MINUSDIRT2
|
||||
|
@ -1163,6 +1154,26 @@ state_t states[NUMSTATES] =
|
|||
{SPR_PTER, 4, 1, {NULL}, 0, 0, S_PTERABYTE_SWOOPDOWN}, // S_PTERABYTE_SWOOPDOWN
|
||||
{SPR_PTER, 0, 1, {NULL}, 0, 0, S_PTERABYTE_SWOOPUP}, // S_PTERABYTE_SWOOPUP
|
||||
|
||||
// Dragonbomber
|
||||
{SPR_DRAB, 0, -1, {A_DragonbomberSpawn}, 6, 0, S_NULL}, // S_DRAGONBOMBER
|
||||
{SPR_DRAB, FF_PAPERSPRITE|7, 1, {A_DragonWing}, 0, 0, S_DRAGONWING2}, // S_DRAGONWING1
|
||||
{SPR_DRAB, FF_PAPERSPRITE|8, 1, {A_DragonWing}, 0, 0, S_DRAGONWING3}, // S_DRAGONWING2
|
||||
{SPR_DRAB, FF_PAPERSPRITE|9, 1, {A_DragonWing}, 0, 0, S_DRAGONWING4}, // S_DRAGONWING3
|
||||
{SPR_DRAB, FF_PAPERSPRITE|10, 1, {A_DragonWing}, 0, 0, S_DRAGONWING1}, // S_DRAGONWING4
|
||||
{SPR_DRAB, 1, 1, {A_DragonSegment}, 0, 0, S_DRAGONTAIL_LOADED}, // S_DRAGONTAIL_LOADED
|
||||
{SPR_DRAB, 2, 1, {A_DragonSegment}, 0, 0, S_DRAGONTAIL_EMPTYLOOP}, // S_DRAGONTAIL_EMPTY
|
||||
{SPR_DRAB, 2, 0, {A_Repeat}, 3*TICRATE, S_DRAGONTAIL_EMPTY, S_DRAGONTAIL_RELOAD}, // S_DRAGONTAIL_EMPTYLOOP
|
||||
{SPR_DRAB, 1, 0, {A_PlayActiveSound}, 0, 0, S_DRAGONTAIL_LOADED}, // S_DRAGONTAIL_RELOAD
|
||||
{SPR_DRAB, 3, 1, {A_MinusCheck}, S_DRAGONMINE_LAND1, 0, S_DRAGONMINE}, // S_DRAGONMINE
|
||||
{SPR_DRAB, 4, 0, {A_PlayActiveSound}, 0, 0, S_DRAGONMINE_LAND2}, // S_DRAGONMINE_LAND1
|
||||
{SPR_DRAB, 4, 2, {A_Thrust}, 0, 1, S_DRAGONMINE_SLOWFLASH1}, // S_DRAGONMINE_LAND2
|
||||
{SPR_DRAB, 5, 11, {NULL}, 0, 0, S_DRAGONMINE_SLOWFLASH2}, // S_DRAGONMINE_SLOWFLASH1
|
||||
{SPR_DRAB, FF_FULLBRIGHT|6, 1, {A_PlayAttackSound}, 0, 0, S_DRAGONMINE_SLOWLOOP}, // S_DRAGONMINE_SLOWFLASH2
|
||||
{SPR_DRAB, 5, 0, {A_Repeat}, 4, S_DRAGONMINE_SLOWFLASH1, S_DRAGONMINE_FASTFLASH1}, // S_DRAGONMINE_SLOWLOOP
|
||||
{SPR_DRAB, 5, 3, {NULL}, 0, 0, S_DRAGONMINE_FASTFLASH2}, // S_DRAGONMINE_FASTFLASH1
|
||||
{SPR_DRAB, FF_FULLBRIGHT|6, 1, {A_PlayAttackSound}, 0, 0, S_DRAGONMINE_FASTLOOP}, // S_DRAGONMINE_FASTFLASH2
|
||||
{SPR_DRAB, 5, 0, {A_Repeat}, 5, S_DRAGONMINE_FASTFLASH1, S_DEATHSTATE}, // S_DRAGONMINE_FASTLOOP
|
||||
|
||||
// Boss Explosion
|
||||
{SPR_BOM2, FF_FULLBRIGHT|FF_ANIMATE, (5*7), {NULL}, 6, 5, S_NULL}, // S_BOSSEXPLODE
|
||||
|
||||
|
@ -1487,6 +1498,7 @@ state_t states[NUMSTATES] =
|
|||
{SPR_FSGN, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNA
|
||||
{SPR_FSGN, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNB
|
||||
{SPR_FSGN, 2|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNC
|
||||
{SPR_FSGN, 3|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGND
|
||||
|
||||
// Black Eggman (Boss 7)
|
||||
{SPR_BRAK, 0, 1, {A_SetReactionTime}, 0, 0, S_BLACKEGG_STND2}, // S_BLACKEGG_STND
|
||||
|
@ -3319,6 +3331,9 @@ state_t states[NUMSTATES] =
|
|||
{SPR_DRWN, 10, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR2
|
||||
{SPR_DRWN, 11, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE2
|
||||
|
||||
// Flight indicator
|
||||
{SPR_FLII, FF_FULLBRIGHT|FF_ANIMATE|0, -1, {NULL}, 4, 4, S_NULL}, // S_FLIGHTINDICATOR
|
||||
|
||||
{SPR_LCKN, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LOCKON1
|
||||
{SPR_LCKN, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LOCKON2
|
||||
{SPR_LCKN, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LOCKON3
|
||||
|
@ -3527,13 +3542,9 @@ state_t states[NUMSTATES] =
|
|||
{SPR_FFWR, 3, 3, {NULL}, 0, 0, S_FIREFLOWER1}, // S_FIREFLOWER4
|
||||
|
||||
// Thrown Mario Fireball
|
||||
{SPR_FBLL, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FIREBALL2}, // S_FIREBALL1
|
||||
{SPR_FBLL, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_FIREBALL3}, // S_FIREBALL2
|
||||
{SPR_FBLL, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_FIREBALL4}, // S_FIREBALL3
|
||||
{SPR_FBLL, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_FIREBALL1}, // S_FIREBALL4
|
||||
{SPR_FBLL, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_FIREBALLEXP2}, // S_FIREBALLEXP1
|
||||
{SPR_FBLL, FF_FULLBRIGHT|5, 3, {NULL}, 0, 0, S_FIREBALLEXP3}, // S_FIREBALLEXP2
|
||||
{SPR_FBLL, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_NULL}, // S_FIREBALLEXP3
|
||||
{SPR_FBLL, FF_FULLBRIGHT, 1, {A_SpawnObjectRelative}, 0, MT_FIREBALLTRAIL, S_FIREBALL}, // S_FIREBALL
|
||||
{SPR_FBLL, 1|FF_FULLBRIGHT|FF_TRANS50, 1, {A_SetScale}, FRACUNIT*3/4, 0, S_FIREBALLTRAIL2}, // S_FIREBALLTRAIL1
|
||||
{SPR_FBLL, 1|FF_FULLBRIGHT|FF_TRANS50, 8, {A_SetScale}, FRACUNIT/6, 1, S_NULL}, // S_FIREBALLTRAIL2
|
||||
|
||||
// Turtle Shell
|
||||
{SPR_SHLL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHELL
|
||||
|
@ -3722,9 +3733,12 @@ state_t states[NUMSTATES] =
|
|||
{SPR_PENG, 0, 5, {A_FaceTarget}, 0, 0, S_PENGUINATOR_LOOK}, // S_PENGUINATOR_SLIDE5
|
||||
|
||||
{SPR_POPH, 0, 2, {A_Look}, (2048<<16)|1, 0, S_POPHAT_LOOK}, // S_POPHAT_LOOK
|
||||
{SPR_POPH, 1, 2, {A_LobShot}, MT_POPSHOT, (70<<16)|60, S_POPHAT_SHOOT2}, // S_POPHAT_SHOOT1
|
||||
{SPR_POPH, 2, 1, {NULL}, 0, 0, S_POPHAT_SHOOT3}, // S_POPHAT_SHOOT2
|
||||
{SPR_POPH, 0, 57, {NULL}, 0, 0, S_POPHAT_LOOK}, // S_POPHAT_SHOOT3
|
||||
{SPR_POPH, 1, 0, {A_MultiShotDist}, (MT_SPINDUST<<16)|4, 24, S_POPHAT_SHOOT2}, // S_POPHAT_SHOOT1
|
||||
{SPR_POPH, 1, 2, {A_LobShot}, MT_POPSHOT, (70<<16)|60, S_POPHAT_SHOOT3}, // S_POPHAT_SHOOT2
|
||||
{SPR_POPH, 2, 1, {NULL}, 0, 0, S_POPHAT_SHOOT4}, // S_POPHAT_SHOOT3
|
||||
{SPR_POPH, 0, 57, {NULL}, 0, 0, S_POPHAT_LOOK}, // S_POPHAT_SHOOT4
|
||||
{SPR_POPH, 3, 3, {A_SpawnObjectRelative}, 0, MT_POPSHOT_TRAIL, S_POPSHOT}, // S_POPSHOT
|
||||
{SPR_NULL, 0, 2, {NULL}, 0, 0, S_SPINDUST1}, // S_POPSHOT_TRAIL
|
||||
|
||||
{SPR_HIVE, 0, 5, {A_Look}, 1, 1, S_HIVEELEMENTAL_LOOK}, // S_HIVEELEMENTAL_LOOK
|
||||
{SPR_HIVE, 0, 14, {A_PlaySound}, sfx_s3k76, 1, S_HIVEELEMENTAL_PREPARE2}, // S_HIVEELEMENTAL_PREPARE1
|
||||
|
@ -3858,8 +3872,6 @@ state_t states[NUMSTATES] =
|
|||
{SPR_DUST, 2|FF_TRANS60, 3, {NULL}, 0, 0, S_DUST4}, // S_DUST3
|
||||
{SPR_DUST, 3|FF_TRANS70, 2, {NULL}, 0, 0, S_NULL}, // S_DUST4
|
||||
|
||||
{SPR_WDDB, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL}, // S_WOODDEBRIS
|
||||
|
||||
{SPR_NULL, 0, 1, {A_RockSpawn}, 0, 0, S_ROCKSPAWN}, // S_ROCKSPAWN
|
||||
|
||||
{SPR_ROIA, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEA
|
||||
|
@ -3879,7 +3891,9 @@ state_t states[NUMSTATES] =
|
|||
{SPR_ROIO, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEO
|
||||
{SPR_ROIP, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEP
|
||||
|
||||
{SPR_GFZD, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_GFZDEBRIS
|
||||
{SPR_BRIC, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL}, // S_BRICKDEBRIS
|
||||
{SPR_WDDB, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL}, // S_WOODDEBRIS
|
||||
|
||||
#ifdef SEENAMES
|
||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK
|
||||
|
@ -5238,6 +5252,114 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DRAGONBOMBER
|
||||
137, // doomednum
|
||||
S_DRAGONBOMBER, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
6, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_XPLD_FLICKY, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_pop, // deathsound
|
||||
10*FRACUNIT, // speed
|
||||
28*FRACUNIT, // radius
|
||||
48*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_BOUNCE|MF_RUNSPAWNFUNC, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DRAGONWING
|
||||
-1, // doomednum
|
||||
S_DRAGONWING1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_XPLD_FLICKY, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_pop, // deathsound
|
||||
0, // speed
|
||||
12*FRACUNIT, // radius
|
||||
12*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DRAGONTAIL
|
||||
-1, // doomednum
|
||||
S_DRAGONTAIL_LOADED, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
MT_DRAGONMINE, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_XPLD1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
20*FRACUNIT, // radius
|
||||
40*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_tink, // activesound
|
||||
MF_NOGRAVITY|MF_SLIDEME|MF_PAIN, // flags
|
||||
S_DRAGONTAIL_EMPTY // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DRAGONMINE
|
||||
-1, // doomednum
|
||||
S_DRAGONMINE, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_s3k76, // seesound
|
||||
0, // reactiontime
|
||||
sfx_s3k89, // attacksound
|
||||
S_NULL, // painstate
|
||||
6, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_TNTBARREL_EXPL1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_s3k6e, // deathsound
|
||||
0, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_s3k5d, // activesound
|
||||
MF_SPECIAL|MF_SHOOTABLE, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BOSSEXPLODE
|
||||
-1, // doomednum
|
||||
S_BOSSEXPLODE, // spawnstate
|
||||
|
@ -6115,11 +6237,11 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_FSGNC, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
S_FSGND, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
124*FRACUNIT, // radius
|
||||
640*FRACUNIT, // height
|
||||
74*FRACUNIT, // radius
|
||||
320*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
|
@ -13247,7 +13369,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SPECIAL|MF_PAIN|MF_NOGRAVITY, // flags
|
||||
MF_SPECIAL|MF_PAIN|MF_NOGRAVITY|MF_FIRE, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -13315,7 +13437,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
12*TICRATE, // painchance (sets how long an unridden rock should last before disappearing - set to 0 to disable)
|
||||
sfx_None, // painsound
|
||||
sfx_s3k49, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
|
@ -18910,31 +19032,58 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
|
||||
{ // MT_FIREBALL
|
||||
-1, // doomednum
|
||||
S_FIREBALL1, // spawnstate
|
||||
S_FIREBALL, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_FIREBALLEXP1, // seestate
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_FIREBALLEXP1, // meleestate
|
||||
S_FIREBALLEXP1, // missilestate
|
||||
S_FIREBALLEXP1, // deathstate
|
||||
S_FIREBALLEXP1, // xdeathstate
|
||||
sfx_mario1, // deathsound
|
||||
10*FRACUNIT, // speed
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
40*FRACUNIT, // speed
|
||||
4*FRACUNIT, // radius
|
||||
8*FRACUNIT, // height
|
||||
0, // display offset
|
||||
DMG_FIRE, // mass
|
||||
1, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_FIRE|MF_MISSILE, // flags
|
||||
MF_FIRE|MF_BOUNCE|MF_MISSILE, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_FIREBALLTRAIL
|
||||
-1, // doomednum
|
||||
S_FIREBALLTRAIL1, // 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
|
||||
0, // speed
|
||||
16*FRACUNIT, // radius
|
||||
16*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
1, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_RUNSPAWNFUNC, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_SHELL
|
||||
1804, // doomednum
|
||||
S_SHELL, // spawnstate
|
||||
|
@ -19989,10 +20138,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
|
||||
{ // MT_POPSHOT
|
||||
-1, // doomednum
|
||||
S_ROCKCRUMBLEI, // spawnstate
|
||||
S_POPSHOT, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_cannon, // seesound
|
||||
sfx_kc4c, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
|
@ -20000,9 +20149,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_XPLD1, // deathstate
|
||||
S_SONIC3KBOSSEXPLOSION1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_pop, // deathsound
|
||||
sfx_cybdth, // deathsound
|
||||
0, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
|
@ -20014,6 +20163,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_POPSHOT_TRAIL
|
||||
-1, // doomednum
|
||||
S_POPSHOT_TRAIL,// 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
|
||||
4*FRACUNIT, // speed
|
||||
4*FRACUNIT, // radius
|
||||
4*FRACUNIT, // height
|
||||
0, // display offset
|
||||
4, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_HIVEELEMENTAL
|
||||
127, // doomednum
|
||||
S_HIVEELEMENTAL_LOOK, // spawnstate
|
||||
|
@ -20773,33 +20949,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_WOODDEBRIS
|
||||
-1, // doomednum
|
||||
S_WOODDEBRIS, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
16*FRACUNIT, // radius
|
||||
16*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_wbreak, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_ROCKSPAWNER
|
||||
1202, // doomednum
|
||||
S_ROCKSPAWN, // spawnstate
|
||||
|
@ -21286,16 +21435,16 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BRICKDEBRIS
|
||||
{ // MT_GFZDEBRIS
|
||||
-1, // doomednum
|
||||
S_BRICKDEBRIS, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_GFZDEBRIS, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
|
@ -21303,16 +21452,70 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BRICKDEBRIS
|
||||
-1, // doomednum
|
||||
S_BRICKDEBRIS, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
16*FRACUNIT, // radius
|
||||
16*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_WOODDEBRIS
|
||||
-1, // doomednum
|
||||
S_WOODDEBRIS, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
16*FRACUNIT, // radius
|
||||
16*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_wbreak, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
#ifdef SEENAMES
|
||||
{ // MT_NAMECHECK
|
||||
-1, // doomednum
|
||||
|
|
85
src/info.h
85
src/info.h
|
@ -282,6 +282,9 @@ void A_SpawnPterabytes();
|
|||
void A_PterabyteHover();
|
||||
void A_RolloutSpawn();
|
||||
void A_RolloutRock();
|
||||
void A_DragonbomberSpawn();
|
||||
void A_DragonWing();
|
||||
void A_DragonSegment();
|
||||
|
||||
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
||||
#define NUMMOBJFREESLOTS 512
|
||||
|
@ -334,6 +337,7 @@ typedef enum sprite
|
|||
SPR_CANG, // Canarivore gas
|
||||
SPR_PYRE, // Pyre Fly
|
||||
SPR_PTER, // Pterabyte
|
||||
SPR_DRAB, // Dragonbomber
|
||||
|
||||
// Generic Boss Items
|
||||
SPR_JETF, // Boss jet fumes
|
||||
|
@ -664,6 +668,7 @@ typedef enum sprite
|
|||
// Game Indicators
|
||||
SPR_SCOR, // Score logo
|
||||
SPR_DRWN, // Drowning Timer
|
||||
SPR_FLII, // AI flight indicator
|
||||
SPR_LCKN, // Target
|
||||
SPR_TTAG, // Tag Sign
|
||||
SPR_GFLG, // Got Flag sign
|
||||
|
@ -743,7 +748,6 @@ typedef enum sprite
|
|||
SPR_BOM3, // Boss Explosion 2
|
||||
SPR_BOM4, // Underwater Explosion
|
||||
SPR_BMNB, // Mine Explosion
|
||||
SPR_WDDB, // Wood Debris
|
||||
|
||||
// Crumbly rocks
|
||||
SPR_ROIA,
|
||||
|
@ -763,8 +767,10 @@ typedef enum sprite
|
|||
SPR_ROIO,
|
||||
SPR_ROIP,
|
||||
|
||||
// Bricks
|
||||
SPR_BRIC,
|
||||
// Level debris
|
||||
SPR_GFZD, // GFZ debris
|
||||
SPR_BRIC, // Bricks
|
||||
SPR_WDDB, // Wood Debris
|
||||
|
||||
// Gravity Well Objects
|
||||
SPR_GWLG,
|
||||
|
@ -1264,22 +1270,10 @@ typedef enum state
|
|||
S_MINUS_BURST4,
|
||||
S_MINUS_BURST5,
|
||||
S_MINUS_POPUP,
|
||||
S_MINUS_UPWARD1,
|
||||
S_MINUS_UPWARD2,
|
||||
S_MINUS_UPWARD3,
|
||||
S_MINUS_UPWARD4,
|
||||
S_MINUS_UPWARD5,
|
||||
S_MINUS_UPWARD6,
|
||||
S_MINUS_UPWARD7,
|
||||
S_MINUS_UPWARD8,
|
||||
S_MINUS_DOWNWARD1,
|
||||
S_MINUS_DOWNWARD2,
|
||||
S_MINUS_DOWNWARD3,
|
||||
S_MINUS_DOWNWARD4,
|
||||
S_MINUS_DOWNWARD5,
|
||||
S_MINUS_DOWNWARD6,
|
||||
S_MINUS_DOWNWARD7,
|
||||
S_MINUS_DOWNWARD8,
|
||||
S_MINUS_AERIAL1,
|
||||
S_MINUS_AERIAL2,
|
||||
S_MINUS_AERIAL3,
|
||||
S_MINUS_AERIAL4,
|
||||
|
||||
// Minus dirt
|
||||
S_MINUSDIRT1,
|
||||
|
@ -1355,6 +1349,26 @@ typedef enum state
|
|||
S_PTERABYTE_SWOOPDOWN,
|
||||
S_PTERABYTE_SWOOPUP,
|
||||
|
||||
// Dragonbomber
|
||||
S_DRAGONBOMBER,
|
||||
S_DRAGONWING1,
|
||||
S_DRAGONWING2,
|
||||
S_DRAGONWING3,
|
||||
S_DRAGONWING4,
|
||||
S_DRAGONTAIL_LOADED,
|
||||
S_DRAGONTAIL_EMPTY,
|
||||
S_DRAGONTAIL_EMPTYLOOP,
|
||||
S_DRAGONTAIL_RELOAD,
|
||||
S_DRAGONMINE,
|
||||
S_DRAGONMINE_LAND1,
|
||||
S_DRAGONMINE_LAND2,
|
||||
S_DRAGONMINE_SLOWFLASH1,
|
||||
S_DRAGONMINE_SLOWFLASH2,
|
||||
S_DRAGONMINE_SLOWLOOP,
|
||||
S_DRAGONMINE_FASTFLASH1,
|
||||
S_DRAGONMINE_FASTFLASH2,
|
||||
S_DRAGONMINE_FASTLOOP,
|
||||
|
||||
// Boss Explosion
|
||||
S_BOSSEXPLODE,
|
||||
|
||||
|
@ -1657,6 +1671,7 @@ typedef enum state
|
|||
S_FSGNA,
|
||||
S_FSGNB,
|
||||
S_FSGNC,
|
||||
S_FSGND,
|
||||
|
||||
// Black Eggman (Boss 7)
|
||||
S_BLACKEGG_STND,
|
||||
|
@ -3454,6 +3469,8 @@ typedef enum state
|
|||
S_FOUR2,
|
||||
S_FIVE2,
|
||||
|
||||
S_FLIGHTINDICATOR,
|
||||
|
||||
S_LOCKON1,
|
||||
S_LOCKON2,
|
||||
S_LOCKON3,
|
||||
|
@ -3637,13 +3654,9 @@ typedef enum state
|
|||
S_FIREFLOWER2,
|
||||
S_FIREFLOWER3,
|
||||
S_FIREFLOWER4,
|
||||
S_FIREBALL1,
|
||||
S_FIREBALL2,
|
||||
S_FIREBALL3,
|
||||
S_FIREBALL4,
|
||||
S_FIREBALLEXP1,
|
||||
S_FIREBALLEXP2,
|
||||
S_FIREBALLEXP3,
|
||||
S_FIREBALL,
|
||||
S_FIREBALLTRAIL1,
|
||||
S_FIREBALLTRAIL2,
|
||||
S_SHELL,
|
||||
S_PUMA_START1,
|
||||
S_PUMA_START2,
|
||||
|
@ -3812,6 +3825,9 @@ typedef enum state
|
|||
S_POPHAT_SHOOT1,
|
||||
S_POPHAT_SHOOT2,
|
||||
S_POPHAT_SHOOT3,
|
||||
S_POPHAT_SHOOT4,
|
||||
S_POPSHOT,
|
||||
S_POPSHOT_TRAIL,
|
||||
|
||||
S_HIVEELEMENTAL_LOOK,
|
||||
S_HIVEELEMENTAL_PREPARE1,
|
||||
|
@ -3943,8 +3959,6 @@ typedef enum state
|
|||
S_DUST3,
|
||||
S_DUST4,
|
||||
|
||||
S_WOODDEBRIS,
|
||||
|
||||
S_ROCKSPAWN,
|
||||
|
||||
S_ROCKCRUMBLEA,
|
||||
|
@ -3964,8 +3978,10 @@ typedef enum state
|
|||
S_ROCKCRUMBLEO,
|
||||
S_ROCKCRUMBLEP,
|
||||
|
||||
// Bricks
|
||||
// Level debris
|
||||
S_GFZDEBRIS,
|
||||
S_BRICKDEBRIS,
|
||||
S_WOODDEBRIS,
|
||||
|
||||
#ifdef SEENAMES
|
||||
S_NAMECHECK,
|
||||
|
@ -4049,6 +4065,10 @@ typedef enum mobj_type
|
|||
MT_PTERABYTESPAWNER, // Pterabyte spawner
|
||||
MT_PTERABYTEWAYPOINT, // Pterabyte waypoint
|
||||
MT_PTERABYTE, // Pterabyte
|
||||
MT_DRAGONBOMBER, // Dragonbomber
|
||||
MT_DRAGONWING, // Dragonbomber wing
|
||||
MT_DRAGONTAIL, // Dragonbomber tail segment
|
||||
MT_DRAGONMINE, // Dragonbomber mine
|
||||
|
||||
// Generic Boss Items
|
||||
MT_BOSSEXPLODE,
|
||||
|
@ -4654,6 +4674,7 @@ typedef enum mobj_type
|
|||
MT_BLUEGOOMBA,
|
||||
MT_FIREFLOWER,
|
||||
MT_FIREBALL,
|
||||
MT_FIREBALLTRAIL,
|
||||
MT_SHELL,
|
||||
MT_PUMA,
|
||||
MT_PUMATRAIL,
|
||||
|
@ -4698,6 +4719,7 @@ typedef enum mobj_type
|
|||
MT_PENGUINATOR,
|
||||
MT_POPHAT,
|
||||
MT_POPSHOT,
|
||||
MT_POPSHOT_TRAIL,
|
||||
|
||||
MT_HIVEELEMENTAL,
|
||||
MT_BUMBLEBORE,
|
||||
|
@ -4735,7 +4757,6 @@ typedef enum mobj_type
|
|||
MT_EXPLODE, // Robot Explosion
|
||||
MT_UWEXPLODE, // Underwater Explosion
|
||||
MT_DUST,
|
||||
MT_WOODDEBRIS,
|
||||
MT_ROCKSPAWNER,
|
||||
MT_FALLINGROCK,
|
||||
MT_ROCKCRUMBLE1,
|
||||
|
@ -4755,8 +4776,10 @@ typedef enum mobj_type
|
|||
MT_ROCKCRUMBLE15,
|
||||
MT_ROCKCRUMBLE16,
|
||||
|
||||
// Bricks
|
||||
// Level debris
|
||||
MT_GFZDEBRIS,
|
||||
MT_BRICKDEBRIS,
|
||||
MT_WOODDEBRIS,
|
||||
|
||||
#ifdef SEENAMES
|
||||
MT_NAMECHECK,
|
||||
|
|
|
@ -1165,6 +1165,17 @@ static int lib_pElementalFire(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pDoPlayerFinish(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
P_DoPlayerFinish(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pDoPlayerExit(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
@ -2674,6 +2685,13 @@ static int lib_gSetCustomExitVars(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_gEnoughPlayersFinished(lua_State *L)
|
||||
{
|
||||
INLEVEL
|
||||
lua_pushboolean(L, G_EnoughPlayersFinished());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_gExitLevel(lua_State *L)
|
||||
{
|
||||
int n = lua_gettop(L); // Num arguments
|
||||
|
@ -2869,6 +2887,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_DoBubbleBounce",lib_pDoBubbleBounce},
|
||||
{"P_BlackOw",lib_pBlackOw},
|
||||
{"P_ElementalFire",lib_pElementalFire},
|
||||
{"P_DoPlayerFinish",lib_pDoPlayerFinish},
|
||||
{"P_DoPlayerExit",lib_pDoPlayerExit},
|
||||
{"P_InstaThrust",lib_pInstaThrust},
|
||||
{"P_ReturnThrustX",lib_pReturnThrustX},
|
||||
|
@ -2981,6 +3000,7 @@ static luaL_Reg lib[] = {
|
|||
{"G_BuildMapName",lib_gBuildMapName},
|
||||
{"G_DoReborn",lib_gDoReborn},
|
||||
{"G_SetCustomExitVars",lib_gSetCustomExitVars},
|
||||
{"G_EnoughPlayersFinished",lib_gEnoughPlayersFinished},
|
||||
{"G_ExitLevel",lib_gExitLevel},
|
||||
{"G_IsSpecialStage",lib_gIsSpecialStage},
|
||||
{"G_GametypeUsesLives",lib_gGametypeUsesLives},
|
||||
|
|
|
@ -43,3 +43,4 @@ boolean LUA_HudEnabled(enum hud option);
|
|||
void LUAh_GameHUD(player_t *stplyr);
|
||||
void LUAh_ScoresHUD(void);
|
||||
void LUAh_TitleHUD(void);
|
||||
void LUAh_TitleCardHUD(player_t *stplyr);
|
||||
|
|
|
@ -92,12 +92,14 @@ static const char *const patch_opt[] = {
|
|||
enum hudhook {
|
||||
hudhook_game = 0,
|
||||
hudhook_scores,
|
||||
hudhook_title
|
||||
hudhook_title,
|
||||
hudhook_titlecard
|
||||
};
|
||||
static const char *const hudhook_opt[] = {
|
||||
"game",
|
||||
"scores",
|
||||
"title",
|
||||
"titlecard",
|
||||
NULL};
|
||||
|
||||
// alignment types for v.drawString
|
||||
|
@ -910,9 +912,17 @@ static int libd_RandomChance(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// 30/10/18 Lat': Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int
|
||||
// 30/10/18 Lat': Get st_translucency's value for HUD rendering as a normal V_xxTRANS int
|
||||
// Could as well be thrown in global vars for ease of access but I guess it makes sense for it to be a HUD fn
|
||||
static int libd_getlocaltransflag(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
lua_pushinteger(L, (10-st_translucency)*V_10TRANS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int
|
||||
static int libd_getusertransflag(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
lua_pushinteger(L, (10-cv_translucenthud.value)*V_10TRANS); // A bit weird that it's called "translucenthud" yet 10 is fully opaque :V
|
||||
|
@ -954,6 +964,7 @@ static luaL_Reg lib_draw[] = {
|
|||
{"dupy", libd_dupy},
|
||||
{"renderer", libd_renderer},
|
||||
{"localTransFlag", libd_getlocaltransflag},
|
||||
{"userTransFlag", libd_getusertransflag},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -1043,6 +1054,9 @@ int LUA_HudLib(lua_State *L)
|
|||
|
||||
lua_newtable(L);
|
||||
lua_rawseti(L, -2, 4); // HUD[3] = title rendering functions array
|
||||
|
||||
lua_newtable(L);
|
||||
lua_rawseti(L, -2, 5); // HUD[4] = title card rendering functions array
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "HUD");
|
||||
|
||||
luaL_newmetatable(L, META_HUDINFO);
|
||||
|
@ -1180,4 +1194,38 @@ void LUAh_TitleHUD(void)
|
|||
hud_running = false;
|
||||
}
|
||||
|
||||
void LUAh_TitleCardHUD(player_t *stplayr)
|
||||
{
|
||||
if (!gL || !(hudAvailable & (1<<hudhook_titlecard)))
|
||||
return;
|
||||
|
||||
hud_running = true;
|
||||
lua_pop(gL, -1);
|
||||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 5); // HUD[5] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_remove(gL, -3); // pop HUD
|
||||
|
||||
LUA_PushUserdata(gL, stplayr, META_PLAYER);
|
||||
lua_pushinteger(gL, lt_ticker);
|
||||
lua_pushinteger(gL, (lt_endtime + TICRATE));
|
||||
lua_pushnil(gL);
|
||||
|
||||
while (lua_next(gL, -6) != 0) {
|
||||
lua_pushvalue(gL, -6); // graphics library (HUD[1])
|
||||
lua_pushvalue(gL, -6); // stplayr
|
||||
lua_pushvalue(gL, -6); // lt_ticker
|
||||
lua_pushvalue(gL, -6); // lt_endtime
|
||||
LUA_Call(gL, 4);
|
||||
}
|
||||
|
||||
lua_pop(gL, -1);
|
||||
hud_running = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -744,7 +744,7 @@ static int power_get(lua_State *L)
|
|||
UINT16 *powers = *((UINT16 **)luaL_checkudata(L, 1, META_POWERS));
|
||||
powertype_t p = luaL_checkinteger(L, 2);
|
||||
if (p >= NUMPOWERS)
|
||||
return luaL_error(L, LUA_QL("powertype_t") " cannot be %u", p);
|
||||
return luaL_error(L, LUA_QL("powertype_t") " cannot be %d", (INT16)p);
|
||||
lua_pushinteger(L, powers[p]);
|
||||
return 1;
|
||||
}
|
||||
|
@ -756,7 +756,7 @@ static int power_set(lua_State *L)
|
|||
powertype_t p = luaL_checkinteger(L, 2);
|
||||
UINT16 i = (UINT16)luaL_checkinteger(L, 3);
|
||||
if (p >= NUMPOWERS)
|
||||
return luaL_error(L, LUA_QL("powertype_t") " cannot be %u", p);
|
||||
return luaL_error(L, LUA_QL("powertype_t") " cannot be %d", (INT16)p);
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||
powers[p] = i;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "command.h"
|
||||
#include "m_argv.h"
|
||||
#include "m_misc.h"
|
||||
|
||||
/** \brief number of arg
|
||||
*/
|
||||
|
@ -161,7 +162,7 @@ void M_FindResponseFile(void)
|
|||
if (!file)
|
||||
I_Error("No more free memory for the response file");
|
||||
if (fread(file, size, 1, handle) != 1)
|
||||
I_Error("Couldn't read response file because %s", strerror(ferror(handle)));
|
||||
I_Error("Couldn't read response file because %s", M_FileError(handle));
|
||||
fclose(handle);
|
||||
|
||||
// keep all the command line arguments following @responsefile
|
||||
|
|
|
@ -284,6 +284,8 @@ void M_SilentUpdateUnlockablesAndEmblems(void)
|
|||
continue;
|
||||
unlockables[i].unlocked = M_Achieved(unlockables[i].conditionset - 1);
|
||||
}
|
||||
|
||||
players[consoleplayer].availabilities = players[1].availabilities = R_GetSkinAvailabilities(); // players[1] is supposed to be for 2p
|
||||
}
|
||||
|
||||
// Emblem unlocking shit
|
||||
|
|
|
@ -201,14 +201,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedDiv(fixed_t a, fixed_t b)
|
|||
*/
|
||||
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRem(fixed_t x, fixed_t y)
|
||||
{
|
||||
const boolean n = x < 0;
|
||||
x = abs(x);
|
||||
while (x >= y)
|
||||
x -= y;
|
||||
if (n)
|
||||
return -x;
|
||||
else
|
||||
return x;
|
||||
return x % y;
|
||||
}
|
||||
|
||||
/** \brief The FixedSqrt function
|
||||
|
|
201
src/m_menu.c
201
src/m_menu.c
|
@ -312,9 +312,7 @@ menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ColorOptionsDef;
|
|||
menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef, OP_OpenGLColorDef;
|
||||
#endif
|
||||
menu_t OP_SoundOptionsDef;
|
||||
#ifdef HAVE_MIXERX
|
||||
menu_t OP_SoundAdvancedDef;
|
||||
#endif
|
||||
|
||||
//Misc
|
||||
menu_t OP_DataOptionsDef, OP_ScreenshotOptionsDef, OP_EraseDataDef;
|
||||
|
@ -474,25 +472,25 @@ static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dum
|
|||
// ---------
|
||||
static menuitem_t MainMenu[] =
|
||||
{
|
||||
{IT_STRING|IT_CALL, NULL, "Secrets", M_SecretsMenu, 76},
|
||||
{IT_STRING|IT_CALL, NULL, "1 player", M_SinglePlayerMenu, 84},
|
||||
{IT_STRING|IT_CALL, NULL, "1 Player", M_SinglePlayerMenu, 76},
|
||||
#ifndef NONET
|
||||
{IT_STRING|IT_SUBMENU, NULL, "multiplayer", &MP_MainDef, 92},
|
||||
{IT_STRING|IT_SUBMENU, NULL, "Multiplayer", &MP_MainDef, 84},
|
||||
#else
|
||||
{IT_STRING|IT_CALL, NULL, "multiplayer", M_StartSplitServerMenu, 92},
|
||||
{IT_STRING|IT_CALL, NULL, "Multiplayer", M_StartSplitServerMenu, 84},
|
||||
#endif
|
||||
{IT_STRING|IT_CALL, NULL, "options", M_Options, 100},
|
||||
{IT_CALL |IT_STRING, NULL, "addons", M_Addons, 108},
|
||||
{IT_STRING|IT_CALL, NULL, "quit game", M_QuitSRB2, 116},
|
||||
{IT_STRING|IT_CALL, NULL, "Extras", M_SecretsMenu, 92},
|
||||
{IT_CALL |IT_STRING, NULL, "Addons", M_Addons, 100},
|
||||
{IT_STRING|IT_CALL, NULL, "Options", M_Options, 108},
|
||||
{IT_STRING|IT_CALL, NULL, "Quit Game", M_QuitSRB2, 116},
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
secrets = 0,
|
||||
singleplr,
|
||||
singleplr = 0,
|
||||
multiplr,
|
||||
options,
|
||||
secrets,
|
||||
addons,
|
||||
options,
|
||||
quitdoom
|
||||
} main_e;
|
||||
|
||||
|
@ -661,7 +659,7 @@ static menuitem_t SR_PandorasBox[] =
|
|||
// Sky Room Custom Unlocks
|
||||
static menuitem_t SR_MainMenu[] =
|
||||
{
|
||||
{IT_STRING|IT_SUBMENU,NULL, "Secrets Checklist", &SR_UnlockChecklistDef, 0},
|
||||
{IT_STRING|IT_SUBMENU,NULL, "Extras Checklist", &SR_UnlockChecklistDef, 0},
|
||||
{IT_DISABLED, NULL, "", NULL, 0}, // Custom1
|
||||
{IT_DISABLED, NULL, "", NULL, 0}, // Custom2
|
||||
{IT_DISABLED, NULL, "", NULL, 0}, // Custom3
|
||||
|
@ -726,19 +724,19 @@ static menuitem_t SR_EmblemHintMenu[] =
|
|||
// Single Player Main
|
||||
static menuitem_t SP_MainMenu[] =
|
||||
{
|
||||
{IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 84},
|
||||
{IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92},
|
||||
{IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100},
|
||||
{IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108},
|
||||
{IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Statistics", M_Statistics, 116},
|
||||
{IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 84},
|
||||
{IT_SECRET, NULL, "Record Attack", M_TimeAttack, 92},
|
||||
{IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 100},
|
||||
{IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 108},
|
||||
{IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Statistics", M_Statistics, 116}
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
sptutorial,
|
||||
sploadgame,
|
||||
sprecordattack,
|
||||
spnightsmode,
|
||||
sptutorial,
|
||||
spstatistics
|
||||
};
|
||||
|
||||
|
@ -1224,32 +1222,33 @@ static menuitem_t OP_VideoOptionsMenu[] =
|
|||
NULL, "HUD Transparency", &cv_translucenthud, 66},
|
||||
{IT_STRING | IT_CVAR, NULL, "Score/Time/Rings", &cv_timetic, 71},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show Powerups", &cv_powerupdisplay, 76},
|
||||
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 81}, // shows ping next to framerate if we want to.
|
||||
#ifdef SEENAMES
|
||||
{IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 81},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 86},
|
||||
#endif
|
||||
|
||||
{IT_HEADER, NULL, "Console", NULL, 90},
|
||||
{IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 96},
|
||||
{IT_STRING | IT_CVAR, NULL, "Text Size", &cv_constextsize, 101},
|
||||
{IT_HEADER, NULL, "Console", NULL, 95},
|
||||
{IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 101},
|
||||
{IT_STRING | IT_CVAR, NULL, "Text Size", &cv_constextsize, 106},
|
||||
|
||||
{IT_HEADER, NULL, "Chat", NULL, 110},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 116},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 121},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 126},
|
||||
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 131},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 136},
|
||||
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 141},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat background tint", &cv_chatbacktint, 146},
|
||||
{IT_HEADER, NULL, "Chat", NULL, 115},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 121},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 126},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 131},
|
||||
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 136},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 141},
|
||||
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 146},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat background tint", &cv_chatbacktint, 151},
|
||||
|
||||
{IT_HEADER, NULL, "Level", NULL, 155},
|
||||
{IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 161},
|
||||
{IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 166},
|
||||
{IT_STRING | IT_CVAR, NULL, "NiGHTS Hoop Draw Dist.", &cv_drawdist_nights, 171},
|
||||
{IT_HEADER, NULL, "Level", NULL, 160},
|
||||
{IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 166},
|
||||
{IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 171},
|
||||
{IT_STRING | IT_CVAR, NULL, "NiGHTS Hoop Draw Dist.", &cv_drawdist_nights, 176},
|
||||
|
||||
{IT_HEADER, NULL, "Diagnostic", NULL, 180},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 186},
|
||||
{IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 191},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 196},
|
||||
{IT_HEADER, NULL, "Diagnostic", NULL, 184},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 190},
|
||||
{IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 195},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 200},
|
||||
};
|
||||
|
||||
static menuitem_t OP_VideoModeMenu[] =
|
||||
|
@ -1347,29 +1346,22 @@ static menuitem_t OP_OpenGLColorMenu[] =
|
|||
static menuitem_t OP_SoundOptionsMenu[] =
|
||||
{
|
||||
{IT_HEADER, NULL, "Game Audio", NULL, 0},
|
||||
{IT_STRING | IT_CVAR, NULL, "Sound Effects", &cv_gamesounds, 6},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 11},
|
||||
{IT_STRING | IT_CVAR, NULL, "Sound Effects", &cv_gamesounds, 12},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 22},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 21},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume, 26},
|
||||
{IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 42},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume, 52},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 36},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 41},
|
||||
{IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 72},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 82},
|
||||
|
||||
{IT_HEADER, NULL, "Accessibility", NULL, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 56},
|
||||
{IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 61},
|
||||
{IT_HEADER, NULL, "Miscellaneous", NULL, 102},
|
||||
{IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 114},
|
||||
{IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 124},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Play Sound Effects if Unfocused", &cv_playsoundsifunfocused, 71},
|
||||
{IT_STRING | IT_CVAR, NULL, "Play Music if Unfocused", &cv_playmusicifunfocused, 76},
|
||||
|
||||
#ifdef HAVE_MIXERX
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 94},
|
||||
#endif
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 144},
|
||||
};
|
||||
|
||||
#ifdef HAVE_MIXERX
|
||||
|
||||
#ifdef HAVE_OPENMPT
|
||||
#define OPENMPT_MENUOFFSET 32
|
||||
#else
|
||||
|
@ -1385,24 +1377,25 @@ static menuitem_t OP_SoundOptionsMenu[] =
|
|||
static menuitem_t OP_SoundAdvancedMenu[] =
|
||||
{
|
||||
#ifdef HAVE_OPENMPT
|
||||
{IT_HEADER, NULL, "OpenMPT Settings", NULL, 10},
|
||||
{IT_STRING | IT_CVAR, NULL, "Instrument Filter", &cv_modfilter, 22},
|
||||
{IT_HEADER, NULL, "OpenMPT Settings", NULL, 0},
|
||||
{IT_STRING | IT_CVAR, NULL, "Instrument Filter", &cv_modfilter, 12},
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MIXERX
|
||||
{IT_HEADER, NULL, "MIDI Settings", NULL, OPENMPT_MENUOFFSET+10},
|
||||
{IT_STRING | IT_CVAR, NULL, "MIDI Player", &cv_midiplayer, OPENMPT_MENUOFFSET+22},
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "FluidSynth Sound Font File", &cv_midisoundfontpath, OPENMPT_MENUOFFSET+34},
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "TiMidity++ Config Folder", &cv_miditimiditypath, OPENMPT_MENUOFFSET+61},
|
||||
{IT_HEADER, NULL, "MIDI Settings", NULL, OPENMPT_MENUOFFSET},
|
||||
{IT_STRING | IT_CVAR, NULL, "MIDI Player", &cv_midiplayer, OPENMPT_MENUOFFSET+12},
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "FluidSynth Sound Font File", &cv_midisoundfontpath, OPENMPT_MENUOFFSET+24},
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "TiMidity++ Config Folder", &cv_miditimiditypath, OPENMPT_MENUOFFSET+51},
|
||||
#endif
|
||||
|
||||
{IT_HEADER, NULL, "Miscellaneous", NULL, OPENMPT_MENUOFFSET+MIXERX_MENUOFFSET+10},
|
||||
{IT_STRING | IT_CVAR, NULL, "Let Levels Force Reset Music", &cv_resetmusicbyheader, OPENMPT_MENUOFFSET+MIXERX_MENUOFFSET+22},
|
||||
{IT_HEADER, NULL, "Miscellaneous", NULL, OPENMPT_MENUOFFSET+MIXERX_MENUOFFSET},
|
||||
{IT_STRING | IT_CVAR, NULL, "Play Sound Effects if Unfocused", &cv_playsoundsifunfocused, OPENMPT_MENUOFFSET+MIXERX_MENUOFFSET+12},
|
||||
{IT_STRING | IT_CVAR, NULL, "Play Music if Unfocused", &cv_playmusicifunfocused, OPENMPT_MENUOFFSET+MIXERX_MENUOFFSET+22},
|
||||
{IT_STRING | IT_CVAR, NULL, "Let Levels Force Reset Music", &cv_resetmusicbyheader, OPENMPT_MENUOFFSET+MIXERX_MENUOFFSET+32},
|
||||
};
|
||||
|
||||
#undef OPENMPT_MENUOFFSET
|
||||
#undef MIXERX_MENUOFFSET
|
||||
#endif
|
||||
|
||||
static menuitem_t OP_DataOptionsMenu[] =
|
||||
{
|
||||
|
@ -1454,7 +1447,7 @@ enum
|
|||
static menuitem_t OP_EraseDataMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_CALL, NULL, "Erase Record Data", M_EraseData, 10},
|
||||
{IT_STRING | IT_CALL, NULL, "Erase Secrets Data", M_EraseData, 20},
|
||||
{IT_STRING | IT_CALL, NULL, "Erase Extras Data", M_EraseData, 20},
|
||||
|
||||
{IT_STRING | IT_CALL, NULL, "\x85" "Erase ALL Data", M_EraseData, 40},
|
||||
};
|
||||
|
@ -1665,7 +1658,7 @@ menu_t SP_MainDef = //CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72);
|
|||
SP_MainMenu,
|
||||
M_DrawCenteredMenu,
|
||||
BASEVIDWIDTH/2, 72,
|
||||
1, // start at "Start Game" on first entry
|
||||
0,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1991,12 +1984,10 @@ menu_t OP_ColorOptionsDef =
|
|||
0,
|
||||
NULL
|
||||
};
|
||||
menu_t OP_SoundOptionsDef = DEFAULTSCROLLMENUSTYLE(
|
||||
menu_t OP_SoundOptionsDef = DEFAULTMENUSTYLE(
|
||||
MN_OP_MAIN + (MN_OP_SOUND << 6),
|
||||
"M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30);
|
||||
#ifdef HAVE_MIXERX
|
||||
menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(MN_OP_MAIN + (MN_OP_SOUND << 6), "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30);
|
||||
#endif
|
||||
|
||||
menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE(
|
||||
MN_OP_MAIN + (MN_OP_SERVER << 6),
|
||||
|
@ -3363,13 +3354,15 @@ boolean M_Responder(event_t *ev)
|
|||
//
|
||||
void M_Drawer(void)
|
||||
{
|
||||
boolean wipe = WipeInAction;
|
||||
|
||||
if (currentMenu == &MessageDef)
|
||||
menuactive = true;
|
||||
|
||||
if (menuactive)
|
||||
{
|
||||
// now that's more readable with a faded background (yeah like Quake...)
|
||||
if (!WipeInAction && (curfadevalue || (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK)))
|
||||
if (!wipe && (curfadevalue || (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK)))
|
||||
V_DrawFadeScreen(0xFF00, (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK) ? 16 : curfadevalue);
|
||||
|
||||
if (currentMenu->drawroutine)
|
||||
|
@ -3431,6 +3424,8 @@ void M_StartControlPanel(void)
|
|||
if (!Playing())
|
||||
{
|
||||
// Secret menu!
|
||||
MainMenu[singleplr].alphaKey = (M_AnySecretUnlocked()) ? 76 : 84;
|
||||
MainMenu[multiplr].alphaKey = (M_AnySecretUnlocked()) ? 84 : 92;
|
||||
MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
|
||||
|
||||
currentMenu = &MainDef;
|
||||
|
@ -3532,6 +3527,7 @@ void M_StartControlPanel(void)
|
|||
|
||||
void M_EndModeAttackRun(void)
|
||||
{
|
||||
G_ClearModeAttackRetryFlag();
|
||||
M_ModeAttackEndGame(0);
|
||||
}
|
||||
|
||||
|
@ -6692,7 +6688,7 @@ static void M_DrawChecklist(void)
|
|||
|| !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS)
|
||||
continue;
|
||||
|
||||
V_DrawString(currentMenu->x, y, ((unlockables[i].unlocked) ? V_GREENMAP : V_TRANSLUCENT), ((unlockables[i].unlocked || !unlockables[i].nochecklist) ? unlockables[i].name : M_CreateSecretMenuOption(unlockables[i].name)));
|
||||
V_DrawString(currentMenu->x, y, ((unlockables[i].unlocked) ? V_GREENMAP : V_TRANSLUCENT)|V_ALLOWLOWERCASE, ((unlockables[i].unlocked || !unlockables[i].nochecklist) ? unlockables[i].name : M_CreateSecretMenuOption(unlockables[i].name)));
|
||||
|
||||
for (j = i+1; j < MAXUNLOCKABLES; j++)
|
||||
{
|
||||
|
@ -7175,7 +7171,7 @@ static void M_DrawSoundTest(void)
|
|||
titl = va("%s - ", curplaying->title);
|
||||
}
|
||||
else
|
||||
titl = "NONE - ";
|
||||
titl = "None - ";
|
||||
|
||||
i = V_LevelNameWidth(titl);
|
||||
|
||||
|
@ -7189,7 +7185,7 @@ static void M_DrawSoundTest(void)
|
|||
while (x > y)
|
||||
{
|
||||
x -= i;
|
||||
V_DrawLevelTitle(x, 24, 0, titl);
|
||||
V_DrawLevelTitle(x, 22, 0, titl);
|
||||
}
|
||||
|
||||
if (curplaying)
|
||||
|
@ -8338,16 +8334,12 @@ static void M_SetupChoosePlayer(INT32 choice)
|
|||
{
|
||||
INT32 skinnum;
|
||||
UINT8 i;
|
||||
UINT8 firstvalid = 255;
|
||||
UINT8 lastvalid = 0;
|
||||
UINT8 firstvalid = 255, lastvalid = 255;
|
||||
boolean allowed = false;
|
||||
char *and;
|
||||
(void)choice;
|
||||
|
||||
if (!(mapheaderinfo[startmap-1]
|
||||
&& (mapheaderinfo[startmap-1]->forcecharacter[0] != '\0'
|
||||
|| (mapheaderinfo[startmap-1]->typeoflevel & TOL_NIGHTS)) // remove this later when everyone gets their own nights sprites, maybe
|
||||
))
|
||||
if (!mapheaderinfo[startmap-1] || mapheaderinfo[startmap-1]->forcecharacter[0] == '\0')
|
||||
{
|
||||
for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks.
|
||||
{
|
||||
|
@ -8357,6 +8349,8 @@ static void M_SetupChoosePlayer(INT32 choice)
|
|||
if (and)
|
||||
{
|
||||
char firstskin[SKINNAMESIZE+1];
|
||||
if (mapheaderinfo[startmap-1]->typeoflevel & TOL_NIGHTS) // skip tagteam characters for NiGHTS levels
|
||||
continue;
|
||||
strncpy(firstskin, description[i].skinname, (and - description[i].skinname));
|
||||
firstskin[(and - description[i].skinname)] = '\0';
|
||||
description[i].skinnum[0] = R_SkinAvailable(firstskin);
|
||||
|
@ -8385,7 +8379,7 @@ static void M_SetupChoosePlayer(INT32 choice)
|
|||
|
||||
if (!(description[i].picname[0]))
|
||||
{
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= XTRA_CHARSEL+1)
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_CHARSEL)
|
||||
{
|
||||
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL];
|
||||
|
@ -8410,17 +8404,16 @@ static void M_SetupChoosePlayer(INT32 choice)
|
|||
}
|
||||
}
|
||||
|
||||
if (firstvalid != 255)
|
||||
{ // One last bit of order we can't do in the iteration above.
|
||||
description[firstvalid].prev = lastvalid;
|
||||
description[lastvalid].next = firstvalid;
|
||||
}
|
||||
else // We're being forced into a specific character, so might as well just skip it.
|
||||
if (firstvalid == lastvalid) // We're being forced into a specific character, so might as well just skip it.
|
||||
{
|
||||
M_ChoosePlayer(-1);
|
||||
M_ChoosePlayer(firstvalid);
|
||||
return;
|
||||
}
|
||||
|
||||
// One last bit of order we can't do in the iteration above.
|
||||
description[firstvalid].prev = lastvalid;
|
||||
description[lastvalid].next = firstvalid;
|
||||
|
||||
M_ChangeMenuMusic("_chsel", true);
|
||||
|
||||
/* the menus suck -James */
|
||||
|
@ -8747,7 +8740,7 @@ static void M_ChoosePlayer(INT32 choice)
|
|||
UINT8 skinnum;
|
||||
|
||||
// skip this if forcecharacter or no characters available
|
||||
if (choice == -1)
|
||||
if (choice == 255)
|
||||
{
|
||||
skinnum = botskin = 0;
|
||||
botingame = false;
|
||||
|
@ -8859,9 +8852,9 @@ static void M_DrawStatsMaps(int location)
|
|||
M_DrawMapEmblems(mnum+1, 292, y);
|
||||
|
||||
if (mapheaderinfo[mnum]->actnum != 0)
|
||||
V_DrawString(20, y, V_YELLOWMAP, va("%s %d", mapheaderinfo[mnum]->lvlttl, mapheaderinfo[mnum]->actnum));
|
||||
V_DrawString(20, y, V_YELLOWMAP|V_ALLOWLOWERCASE, va("%s %d", mapheaderinfo[mnum]->lvlttl, mapheaderinfo[mnum]->actnum));
|
||||
else
|
||||
V_DrawString(20, y, V_YELLOWMAP, mapheaderinfo[mnum]->lvlttl);
|
||||
V_DrawString(20, y, V_YELLOWMAP|V_ALLOWLOWERCASE, mapheaderinfo[mnum]->lvlttl);
|
||||
|
||||
y += 8;
|
||||
|
||||
|
@ -8905,7 +8898,7 @@ static void M_DrawStatsMaps(int location)
|
|||
else
|
||||
V_DrawSmallScaledPatch(292, y, 0, W_CachePatchName("NEEDIT", PU_CACHE));
|
||||
|
||||
V_DrawString(20, y, V_YELLOWMAP, va("%s", exemblem->description));
|
||||
V_DrawString(20, y, V_YELLOWMAP|V_ALLOWLOWERCASE, va("%s", exemblem->description));
|
||||
}
|
||||
|
||||
y += 8;
|
||||
|
@ -9116,7 +9109,7 @@ void M_DrawTimeAttackMenu(void)
|
|||
|
||||
// Character face!
|
||||
{
|
||||
if (skins[cv_chooseskin.value-1].sprites[SPR2_XTRA].numframes >= XTRA_CHARSEL+1)
|
||||
if (skins[cv_chooseskin.value-1].sprites[SPR2_XTRA].numframes > XTRA_CHARSEL)
|
||||
{
|
||||
spritedef_t *sprdef = &skins[cv_chooseskin.value-1].sprites[SPR2_XTRA];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL];
|
||||
|
@ -9240,10 +9233,7 @@ void M_DrawTimeAttackMenu(void)
|
|||
|
||||
V_DrawString(104-72, 73+lsheadingheight/2, V_YELLOWMAP, "RINGS:");
|
||||
|
||||
if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->gotperfect)
|
||||
V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE, beststr);
|
||||
else
|
||||
V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE|V_YELLOWMAP, beststr);
|
||||
V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE|((mapvisited[cv_nextmap.value-1] & MV_PERFECT) ? V_YELLOWMAP : 0), beststr);
|
||||
|
||||
V_DrawRightAlignedString(104+72, 83+lsheadingheight/2, V_ALLOWLOWERCASE, reqrings);
|
||||
}
|
||||
|
@ -9395,6 +9385,7 @@ void M_DrawNightsAttackMenu(void)
|
|||
{
|
||||
emblem_t *em;
|
||||
INT32 yHeight;
|
||||
INT32 xpos;
|
||||
patch_t *PictureOfLevel;
|
||||
lumpnum_t lumpnum;
|
||||
char beststr[40];
|
||||
|
@ -9454,17 +9445,23 @@ void M_DrawNightsAttackMenu(void)
|
|||
{
|
||||
switch (em->type)
|
||||
{
|
||||
case ET_NGRADE: yHeight = 48; break;
|
||||
case ET_NTIME: yHeight = 68; break;
|
||||
case ET_NGRADE:
|
||||
xpos = 104+38;
|
||||
yHeight = 48;
|
||||
break;
|
||||
case ET_NTIME:
|
||||
xpos = 104+76;
|
||||
yHeight = 68;
|
||||
break;
|
||||
default:
|
||||
goto skipThisOne;
|
||||
}
|
||||
|
||||
if (em->collected)
|
||||
V_DrawSmallMappedPatch(104+38, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em, false), PU_CACHE),
|
||||
V_DrawSmallMappedPatch(xpos, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em, false), PU_CACHE),
|
||||
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE));
|
||||
else
|
||||
V_DrawSmallScaledPatch(104+38, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_CACHE));
|
||||
V_DrawSmallScaledPatch(xpos, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_CACHE));
|
||||
|
||||
skipThisOne:
|
||||
em = M_GetLevelEmblems(-1);
|
||||
|
@ -10905,7 +10902,7 @@ static void M_EraseData(INT32 choice)
|
|||
if (choice == 0)
|
||||
eschoice = M_GetText("Record Attack data");
|
||||
else if (choice == 1)
|
||||
eschoice = M_GetText("Secrets data");
|
||||
eschoice = M_GetText("Extras data");
|
||||
else
|
||||
eschoice = M_GetText("ALL game data");
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ typedef enum
|
|||
MN_OP_SCREENSHOTS,
|
||||
MN_OP_ERASEDATA,
|
||||
|
||||
// Secrets
|
||||
// Extras
|
||||
MN_SR_MAIN,
|
||||
MN_SR_PANDORA,
|
||||
MN_SR_LEVELSELECT,
|
||||
|
|
14
src/m_misc.c
14
src/m_misc.c
|
@ -23,6 +23,8 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
// Extended map support.
|
||||
#include <ctype.h>
|
||||
|
||||
|
@ -787,7 +789,7 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
|
|||
if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->lvlttl[0] != '\0')
|
||||
snprintf(lvlttltext, 48, "%s%s%s",
|
||||
mapheaderinfo[gamemap-1]->lvlttl,
|
||||
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE",
|
||||
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " Zone",
|
||||
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(" %d",mapheaderinfo[gamemap-1]->actnum) : "");
|
||||
else
|
||||
snprintf(lvlttltext, 48, "Unknown");
|
||||
|
@ -2441,3 +2443,13 @@ void M_SetupMemcpy(void)
|
|||
M_Memcpy = cpu_cpy;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Return the appropriate message for a file error or end of file.
|
||||
*/
|
||||
const char *M_FileError(FILE *fp)
|
||||
{
|
||||
if (ferror(fp))
|
||||
return strerror(errno);
|
||||
else
|
||||
return "end-of-file";
|
||||
}
|
||||
|
|
|
@ -94,6 +94,8 @@ void strcatbf(char *s1, const char *s2, const char *s3);
|
|||
|
||||
void M_SetupMemcpy(void);
|
||||
|
||||
const char *M_FileError(FILE *handle);
|
||||
|
||||
// counting bits, for weapon ammo code, usually
|
||||
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
|
||||
|
||||
|
|
218
src/p_enemy.c
218
src/p_enemy.c
|
@ -312,6 +312,9 @@ void A_SpawnPterabytes(mobj_t *actor);
|
|||
void A_PterabyteHover(mobj_t *actor);
|
||||
void A_RolloutSpawn(mobj_t *actor);
|
||||
void A_RolloutRock(mobj_t *actor);
|
||||
void A_DragonbomberSpawn(mobj_t *actor);
|
||||
void A_DragonWing(mobj_t *actor);
|
||||
void A_DragonSegment(mobj_t *actor);
|
||||
|
||||
//for p_enemy.c
|
||||
|
||||
|
@ -2473,12 +2476,8 @@ void A_VultureBlast(mobj_t *actor)
|
|||
void A_VultureFly(mobj_t *actor)
|
||||
{
|
||||
fixed_t speedmax = 18*FRACUNIT;
|
||||
angle_t angledif = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) - actor->angle;
|
||||
fixed_t dx = actor->target->x - actor->x;
|
||||
fixed_t dy = actor->target->y - actor->y;
|
||||
fixed_t dz = actor->target->z - actor->z;
|
||||
fixed_t dxy = FixedHypot(dx, dy);
|
||||
fixed_t dm;
|
||||
angle_t angledif;
|
||||
fixed_t dx, dy, dz, dxy, dm;
|
||||
mobj_t *dust;
|
||||
fixed_t momm;
|
||||
|
||||
|
@ -2487,6 +2486,18 @@ void A_VultureFly(mobj_t *actor)
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (!actor->target || P_MobjWasRemoved(actor->target))
|
||||
{
|
||||
P_SetMobjState(actor, actor->info->spawnstate);
|
||||
return;
|
||||
}
|
||||
|
||||
angledif = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) - actor->angle;
|
||||
dx = actor->target->x - actor->x;
|
||||
dy = actor->target->y - actor->y;
|
||||
dz = actor->target->z - actor->z;
|
||||
dxy = FixedHypot(dx, dy);
|
||||
|
||||
if (leveltime % 4 == 0)
|
||||
S_StartSound(actor, actor->info->activesound);
|
||||
|
||||
|
@ -4070,19 +4081,28 @@ bossjustdie:
|
|||
mobj_t *pole = P_SpawnMobj(
|
||||
mo->tracer->x - P_ReturnThrustX(mo->tracer, mo->tracer->angle, speed*time),
|
||||
mo->tracer->y - P_ReturnThrustY(mo->tracer, mo->tracer->angle, speed*time),
|
||||
mo->tracer->floorz + 4*FRACUNIT,
|
||||
mo->tracer->floorz + (256+1)*FRACUNIT,
|
||||
MT_FSGNB);
|
||||
P_SetTarget(&pole->tracer, P_SpawnMobj(
|
||||
pole->x, pole->y,
|
||||
pole->z - 256*FRACUNIT,
|
||||
MT_FSGNB));
|
||||
P_SetTarget(&pole->tracer->tracer, P_SpawnMobj(
|
||||
pole->x + P_ReturnThrustX(pole, mo->tracer->angle, FRACUNIT),
|
||||
pole->y + P_ReturnThrustY(pole, mo->tracer->angle, FRACUNIT),
|
||||
pole->z + 256*FRACUNIT,
|
||||
MT_FSGNA));
|
||||
pole->angle = mo->tracer->angle;
|
||||
pole->tracer->angle = pole->angle - ANGLE_90;
|
||||
pole->tracer->flags |= MF_NOCLIPTHING;
|
||||
P_SetScale(pole, (pole->destscale = 2*FRACUNIT));
|
||||
P_SetScale(pole->tracer, (pole->tracer->destscale = 2*FRACUNIT));
|
||||
pole->angle = pole->tracer->angle = mo->tracer->angle;
|
||||
pole->tracer->tracer->angle = pole->angle - ANGLE_90;
|
||||
pole->momx = P_ReturnThrustX(pole, pole->angle, speed);
|
||||
pole->momy = P_ReturnThrustY(pole, pole->angle, speed);
|
||||
pole->tracer->momx = pole->momx;
|
||||
pole->tracer->momy = pole->momy;
|
||||
pole->tracer->tracer->momx = pole->momx;
|
||||
pole->tracer->tracer->momy = pole->momy;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5121,7 +5141,7 @@ void A_SignPlayer(mobj_t *actor)
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins)
|
||||
if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins || signcolor >= MAXTRANSLATIONS)
|
||||
return;
|
||||
|
||||
// if no face overlay, spawn one
|
||||
|
@ -5148,26 +5168,9 @@ void A_SignPlayer(mobj_t *actor)
|
|||
if (signcolor)
|
||||
;
|
||||
else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
|
||||
{
|
||||
signcolor = skin->prefoppositecolor;
|
||||
/*
|
||||
If you're here from the comment above Color_Opposite,
|
||||
the following line is the one which is dependent on the
|
||||
array being symmetrical. It gets the opposite of the
|
||||
opposite of your desired colour just so it can get the
|
||||
brightness frame for the End Sign. It's not a great
|
||||
design choice, but it's constant time array access and
|
||||
the idea that the colours should be OPPOSITES is kind
|
||||
of in the name. If you have a better idea, feel free
|
||||
to let me know. ~toast 2016/07/20
|
||||
*/
|
||||
signframe += (15 - Color_Opposite[Color_Opposite[skin->prefoppositecolor - 1][0] - 1][1]);
|
||||
}
|
||||
else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor.
|
||||
{
|
||||
signcolor = Color_Opposite[actor->target->player->skincolor - 1][0];
|
||||
signframe += (15 - Color_Opposite[actor->target->player->skincolor - 1][1]);
|
||||
}
|
||||
else
|
||||
signcolor = SKINCOLOR_NONE;
|
||||
}
|
||||
|
@ -5188,10 +5191,10 @@ void A_SignPlayer(mobj_t *actor)
|
|||
skinnum = P_RandomKey(skincount);
|
||||
for (skincount = 0; skincount < numskins; skincount++)
|
||||
{
|
||||
if (skincheck(skincount))
|
||||
skinnum++;
|
||||
if (skincount > skinnum)
|
||||
break;
|
||||
if (skincheck(skincount))
|
||||
skinnum++;
|
||||
}
|
||||
}
|
||||
else // otherwise, advance 1 skin
|
||||
|
@ -5203,42 +5206,46 @@ void A_SignPlayer(mobj_t *actor)
|
|||
skin = &skins[skinnum];
|
||||
}
|
||||
else // specific skin
|
||||
{
|
||||
skin = &skins[locvar1];
|
||||
}
|
||||
|
||||
facecolor = skin->prefcolor;
|
||||
if (signcolor)
|
||||
;
|
||||
else if (skin->prefoppositecolor)
|
||||
{
|
||||
signcolor = skin->prefoppositecolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
else if (facecolor)
|
||||
signcolor = Color_Opposite[facecolor - 1][0];
|
||||
}
|
||||
signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]);
|
||||
}
|
||||
|
||||
if (skin != NULL && skin->sprites[SPR2_SIGN].numframes) // player face
|
||||
if (skin && skin->sprites[SPR2_SIGN].numframes) // player face
|
||||
{
|
||||
ov->color = facecolor;
|
||||
ov->skin = skin;
|
||||
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
|
||||
actor->tracer->color = signcolor;
|
||||
actor->tracer->frame = signframe;
|
||||
}
|
||||
else // Eggman face
|
||||
{
|
||||
ov->color = SKINCOLOR_NONE;
|
||||
P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN
|
||||
if (signcolor)
|
||||
actor->tracer->color = signcolor;
|
||||
else
|
||||
actor->tracer->color = signcolor = SKINCOLOR_CARBON;
|
||||
actor->tracer->frame = signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]);
|
||||
if (!signcolor)
|
||||
signcolor = SKINCOLOR_CARBON;
|
||||
}
|
||||
|
||||
actor->tracer->color = signcolor;
|
||||
/*
|
||||
If you're here from the comment above Color_Opposite,
|
||||
the following line is the one which is dependent on the
|
||||
array being symmetrical. It gets the opposite of the
|
||||
opposite of your desired colour just so it can get the
|
||||
brightness frame for the End Sign. It's not a great
|
||||
design choice, but it's constant time array access and
|
||||
the idea that the colours should be OPPOSITES is kind
|
||||
of in the name. If you have a better idea, feel free
|
||||
to let me know. ~toast 2016/07/20
|
||||
*/
|
||||
if (signcolor && signcolor < MAXSKINCOLORS)
|
||||
signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]);
|
||||
actor->tracer->frame = signframe;
|
||||
}
|
||||
|
||||
// Function: A_OverlayThink
|
||||
|
@ -5665,10 +5672,10 @@ void A_MinusPopup(mobj_t *actor)
|
|||
S_StartSound(actor, sfx_s3k82);
|
||||
for (i = 1; i <= num; i++)
|
||||
{
|
||||
mobj_t *rock = P_SpawnMobj(actor->x, actor->y, actor->z + actor->height/4, MT_ROCKCRUMBLE1);
|
||||
mobj_t *rock = P_SpawnMobjFromMobj(actor, 0, 0, actor->height/4, MT_ROCKCRUMBLE1);
|
||||
P_Thrust(rock, ani*i, FRACUNIT);
|
||||
rock->momz = 3*FRACUNIT;
|
||||
P_SetScale(rock, FRACUNIT/3);
|
||||
P_SetObjectMomZ(rock, 3*FRACUNIT, false);
|
||||
P_SetScale(rock, rock->scale/3);
|
||||
}
|
||||
P_RadiusAttack(actor, actor, 2*actor->radius, 0);
|
||||
if (actor->tracer)
|
||||
|
@ -5682,11 +5689,12 @@ void A_MinusPopup(mobj_t *actor)
|
|||
// Description: If the minus hits the floor, dig back into the ground.
|
||||
//
|
||||
// var1 = State to switch to (if 0, use seestate).
|
||||
// var2 = unused
|
||||
// var2 = If not 0, spawn debris when hitting the floor.
|
||||
//
|
||||
void A_MinusCheck(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_MinusCheck", actor))
|
||||
|
@ -5697,6 +5705,18 @@ void A_MinusCheck(mobj_t *actor)
|
|||
{
|
||||
P_SetMobjState(actor, locvar1 ? (statenum_t)locvar1 : actor->info->seestate);
|
||||
actor->flags = actor->info->flags;
|
||||
if (locvar2)
|
||||
{
|
||||
INT32 i, num = 6;
|
||||
angle_t ani = FixedAngle(FRACUNIT*360/num);
|
||||
for (i = 1; i <= num; i++)
|
||||
{
|
||||
mobj_t *rock = P_SpawnMobjFromMobj(actor, 0, 0, actor->height/4, MT_ROCKCRUMBLE1);
|
||||
P_Thrust(rock, ani*i, FRACUNIT);
|
||||
P_SetObjectMomZ(rock, 3*FRACUNIT, false);
|
||||
P_SetScale(rock, rock->scale/3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14535,6 +14555,9 @@ void A_RolloutRock(mobj_t *actor)
|
|||
|
||||
actor->friction = FRACUNIT; // turns out riding on solids sucks, so let's just make it easier on ourselves
|
||||
|
||||
if (actor->eflags & MFE_JUSTHITFLOOR)
|
||||
S_StartSound(actor, actor->info->painsound);
|
||||
|
||||
if (actor->threshold)
|
||||
actor->threshold--;
|
||||
|
||||
|
@ -14588,6 +14611,9 @@ void A_RolloutRock(mobj_t *actor)
|
|||
|
||||
actor->frame = actor->reactiontime % maxframes; // set frame
|
||||
|
||||
if (!actor->tracer || P_MobjWasRemoved(actor->tracer) || !actor->tracer->health)
|
||||
actor->flags |= MF_PUSHABLE;
|
||||
|
||||
if (!(actor->flags & MF_PUSHABLE)) // if being ridden, don't disappear
|
||||
actor->fuse = 0;
|
||||
else if (!actor->fuse && actor->movecount == 1) // otherwise if rock has moved, set its fuse
|
||||
|
@ -14597,3 +14623,97 @@ void A_RolloutRock(mobj_t *actor)
|
|||
actor->flags2 ^= MF2_DONTDRAW;
|
||||
|
||||
}
|
||||
|
||||
// Function: A_DragonbomberSpawn
|
||||
//
|
||||
// Description: Spawns the body parts for Dragonbomber
|
||||
//
|
||||
// var1 = Tail segments to spawn
|
||||
// var2 = unused
|
||||
//
|
||||
void A_DragonbomberSpawn(mobj_t *actor)
|
||||
{
|
||||
UINT8 i;
|
||||
mobj_t *mo = actor;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_DragonbomberSpawn", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < var1; i++) // spawn tail segments
|
||||
{
|
||||
mobj_t *segment;
|
||||
fixed_t x, y;
|
||||
x = P_ReturnThrustX(mo, mo->angle, -mo->radius << 1);
|
||||
y = P_ReturnThrustY(mo, mo->angle, -mo->radius << 1);
|
||||
segment = P_SpawnMobjFromMobj(mo, x, y, 0, MT_DRAGONTAIL);
|
||||
P_SetTarget(&segment->target, mo);
|
||||
P_SetTarget(&mo->tracer, segment);
|
||||
segment->angle = mo->angle;
|
||||
mo = segment;
|
||||
}
|
||||
for (i = 0; i < 2; i++) // spawn wings
|
||||
{
|
||||
mo = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_DRAGONWING);
|
||||
P_SetTarget(&mo->target, actor);
|
||||
mo->movedir = ANGLE_90 + i * ANGLE_180;
|
||||
}
|
||||
}
|
||||
|
||||
// Function: A_DragonWing
|
||||
//
|
||||
// Description: Moves actor such that it is placed away from its target at a distance equal to the target's radius in the direction of its target's angle.
|
||||
// The actor's movedir can be used to offset the angle.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
//
|
||||
void A_DragonWing(mobj_t *actor)
|
||||
{
|
||||
mobj_t *target = actor->target;
|
||||
fixed_t x, y;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_DragonWing", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (target == NULL || !target->health)
|
||||
{
|
||||
P_RemoveMobj(actor);
|
||||
return;
|
||||
}
|
||||
actor->angle = target->angle + actor->movedir;
|
||||
x = target->x + P_ReturnThrustX(actor, actor->angle, -target->radius);
|
||||
y = target->y + P_ReturnThrustY(actor, actor->angle, -target->radius);
|
||||
P_TeleportMove(actor, x, y, target->z);
|
||||
}
|
||||
|
||||
// Function: A_DragonSegment
|
||||
//
|
||||
// Description: Moves actor such that it is placed away from its target at an absolute distance equal to the sum of the two mobjs' radii.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
//
|
||||
void A_DragonSegment(mobj_t *actor)
|
||||
{
|
||||
mobj_t *target = actor->target;
|
||||
fixed_t dist = P_AproxDistance(P_AproxDistance(actor->x - target->x, actor->y - target->y), actor->z - target->z);
|
||||
fixed_t radius = actor->radius + target->radius;
|
||||
angle_t hangle = R_PointToAngle2(target->x, target->y, actor->x, actor->y);
|
||||
angle_t zangle = R_PointToAngle2(0, target->z, dist, actor->z);
|
||||
fixed_t hdist = P_ReturnThrustX(target, zangle, radius);
|
||||
fixed_t xdist = P_ReturnThrustX(target, hangle, hdist);
|
||||
fixed_t ydist = P_ReturnThrustY(target, hangle, hdist);
|
||||
fixed_t zdist = P_ReturnThrustY(target, zangle, radius);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_DragonSegment", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
actor->angle = hangle;
|
||||
P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist);
|
||||
}
|
||||
|
|
|
@ -148,15 +148,19 @@ void P_ResetStarposts(void)
|
|||
//
|
||||
boolean P_CanPickupItem(player_t *player, boolean weapon)
|
||||
{
|
||||
if (player->bot && weapon)
|
||||
if (!player->mo || player->mo->health <= 0)
|
||||
return false;
|
||||
|
||||
if (player->bot)
|
||||
{
|
||||
if (weapon)
|
||||
return false;
|
||||
return P_CanPickupItem(&players[consoleplayer], true); // weapon is true to prevent infinite recursion if p1 is bot - doesn't occur in vanilla, but may be relevant for mods
|
||||
}
|
||||
|
||||
if (player->powers[pw_flashing] > (flashingtics/4)*3 && player->powers[pw_flashing] < UINT16_MAX)
|
||||
return false;
|
||||
|
||||
if (player->mo && player->mo->health <= 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2521,7 +2525,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
|
||||
if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0))
|
||||
;
|
||||
else if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap) && (target->player->lives != INFLIVES)
|
||||
else if (!target->player->bot && !target->player->spectator && (target->player->lives != INFLIVES)
|
||||
&& G_GametypeUsesLives())
|
||||
{
|
||||
target->player->lives -= 1; // Lose a life Tails 03-11-2000
|
||||
|
@ -2678,6 +2682,17 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
target->flags = (target->flags|MF_NOCLIPHEIGHT) & ~MF_NOGRAVITY;
|
||||
break;
|
||||
|
||||
case MT_DRAGONBOMBER:
|
||||
{
|
||||
mobj_t *segment = target;
|
||||
while (segment->tracer != NULL)
|
||||
{
|
||||
P_KillMobj(segment->tracer, NULL, NULL, 0);
|
||||
segment = segment->tracer;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MT_EGGMOBILE3:
|
||||
{
|
||||
mobj_t *mo2;
|
||||
|
@ -2741,7 +2756,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
|
||||
case MT_EGGTRAP:
|
||||
// Time for birdies! Yaaaaaaaay!
|
||||
target->fuse = TICRATE*2;
|
||||
target->fuse = TICRATE;
|
||||
break;
|
||||
|
||||
case MT_MINECART:
|
||||
|
@ -2803,13 +2818,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
if (flip)
|
||||
momz *= -1;
|
||||
#define makechunk(angtweak, xmov, ymov) \
|
||||
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE);\
|
||||
chunk->eflags |= flip;\
|
||||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);\
|
||||
P_SetMobjState(chunk, target->info->xdeathstate);\
|
||||
chunk->health = 0;\
|
||||
chunk->angle = angtweak;\
|
||||
chunk->destscale = scale;\
|
||||
P_SetScale(chunk, scale);\
|
||||
P_UnsetThingPosition(chunk);\
|
||||
chunk->flags = MF_NOCLIP;\
|
||||
chunk->x += xmov;\
|
||||
|
@ -2828,14 +2840,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
if (flip)
|
||||
momz *= -1;
|
||||
|
||||
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE);
|
||||
chunk->eflags |= flip;
|
||||
|
||||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);
|
||||
P_SetMobjState(chunk, target->info->deathstate);
|
||||
chunk->health = 0;
|
||||
chunk->angle = ang + ANGLE_180;
|
||||
chunk->destscale = scale;
|
||||
P_SetScale(chunk, scale);
|
||||
P_UnsetThingPosition(chunk);
|
||||
chunk->flags = MF_NOCLIP;
|
||||
chunk->x -= xoffs;
|
||||
|
@ -2878,13 +2886,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
sprflip = P_RandomChance(FRACUNIT/2);
|
||||
|
||||
#define makechunk(angtweak, xmov, ymov) \
|
||||
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE);\
|
||||
chunk->eflags |= flip;\
|
||||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);\
|
||||
P_SetMobjState(chunk, target->info->xdeathstate);\
|
||||
chunk->health = 0;\
|
||||
chunk->angle = target->angle;\
|
||||
chunk->destscale = scale;\
|
||||
P_SetScale(chunk, scale);\
|
||||
P_UnsetThingPosition(chunk);\
|
||||
chunk->flags = MF_NOCLIP;\
|
||||
chunk->x += xmov - forwardxoffs;\
|
||||
|
@ -2906,14 +2911,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
|
||||
sprflip = P_RandomChance(FRACUNIT/2);
|
||||
|
||||
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE);
|
||||
chunk->eflags |= flip;
|
||||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);
|
||||
|
||||
P_SetMobjState(chunk, target->info->deathstate);
|
||||
chunk->health = 0;
|
||||
chunk->angle = target->angle;
|
||||
chunk->destscale = scale;
|
||||
P_SetScale(chunk, scale);
|
||||
P_UnsetThingPosition(chunk);
|
||||
chunk->flags = MF_NOCLIP;
|
||||
chunk->x += forwardxoffs - xoffs;
|
||||
|
@ -3002,6 +3004,10 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
|
|||
P_SetPlayerMobjState(target, S_PLAY_NIGHTS_STUN);
|
||||
S_StartSound(target, sfx_nghurt);
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
player->mo->rollangle = 0;
|
||||
#endif
|
||||
|
||||
if (oldnightstime > 10*TICRATE
|
||||
&& player->nightstime < 10*TICRATE)
|
||||
{
|
||||
|
@ -3517,7 +3523,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|
||||
// Make sure that boxes cannot be popped by enemies, red rings, etc.
|
||||
if (target->flags & MF_MONITOR && ((!source || !source->player || source->player->bot)
|
||||
|| (inflictor && inflictor->type >= MT_REDRING && inflictor->type <= MT_GRENADERING)))
|
||||
|| (inflictor && (inflictor->type == MT_REDRING || (inflictor->type >= MT_THROWNBOUNCE && inflictor->type <= MT_THROWNGRENADE)))))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -172,6 +172,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle);
|
|||
void P_DoPityCheck(player_t *player);
|
||||
void P_PlayerThink(player_t *player);
|
||||
void P_PlayerAfterThink(player_t *player);
|
||||
void P_DoPlayerFinish(player_t *player);
|
||||
void P_DoPlayerExit(player_t *player);
|
||||
void P_NightserizePlayer(player_t *player, INT32 ptime);
|
||||
|
||||
|
@ -322,6 +323,7 @@ SINT8 P_MobjFlip(mobj_t *mobj);
|
|||
fixed_t P_GetMobjGravity(mobj_t *mo);
|
||||
FUNCMATH boolean P_WeaponOrPanel(mobjtype_t type);
|
||||
|
||||
void P_CalcChasePostImg(player_t *player, camera_t *thiscam);
|
||||
boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled);
|
||||
|
||||
void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab);
|
||||
|
|
86
src/p_map.c
86
src/p_map.c
|
@ -592,7 +592,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
|
|||
if (!(tails->pflags & PF_CANCARRY))
|
||||
return;
|
||||
|
||||
if (tails->bot == 1)
|
||||
if (sonic->pflags & PF_FINISHED)
|
||||
return;
|
||||
|
||||
if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP))
|
||||
|
@ -661,31 +661,32 @@ static void P_SlapStick(mobj_t *fang, mobj_t *pole)
|
|||
momx2 = fang->momx/dist;
|
||||
momy2 = fang->momy/dist;
|
||||
|
||||
pole->tracer->momx = momx1 + (dist-1)*momx2;
|
||||
pole->tracer->momy = momy1 + (dist-1)*momy2;
|
||||
pole->tracer->tracer->momx = momx1 + (dist-1)*momx2;
|
||||
pole->tracer->tracer->momy = momy1 + (dist-1)*momy2;
|
||||
fang->momx = (dist-1)*momx1 + momx2;
|
||||
fang->momy = (dist-1)*momy1 + momy2;
|
||||
#undef dist
|
||||
|
||||
P_SetMobjState(pole, pole->info->deathstate);
|
||||
|
||||
P_SetObjectMomZ(pole->tracer, 6*FRACUNIT, false);
|
||||
pole->tracer->flags &= ~(MF_NOGRAVITY|MF_NOCLIP);
|
||||
pole->tracer->movedir = ANGLE_67h;
|
||||
if ((R_PointToAngle(fang->x - pole->tracer->x, fang->y - pole->tracer->y) - pole->angle) > ANGLE_180)
|
||||
pole->tracer->movedir = InvAngle(pole->tracer->movedir);
|
||||
P_SetObjectMomZ(pole->tracer->tracer, 6*FRACUNIT, false);
|
||||
pole->tracer->tracer->flags &= ~(MF_NOGRAVITY|MF_NOCLIP);
|
||||
pole->tracer->tracer->movedir = ANGLE_67h;
|
||||
if ((R_PointToAngle(fang->x - pole->tracer->tracer->x, fang->y - pole->tracer->tracer->y) - pole->angle) > ANGLE_180)
|
||||
pole->tracer->tracer->movedir = InvAngle(pole->tracer->movedir);
|
||||
|
||||
P_SetObjectMomZ(fang, 14*FRACUNIT, false);
|
||||
fang->flags |= MF_NOGRAVITY|MF_NOCLIP;
|
||||
P_SetMobjState(fang, fang->info->xdeathstate);
|
||||
|
||||
pole->tracer->tics = pole->tics = fang->tics;
|
||||
pole->tracer->tracer->tics = pole->tracer->tics = pole->tics = fang->tics;
|
||||
|
||||
var1 = var2 = 0;
|
||||
A_Scream(pole->tracer);
|
||||
A_Scream(pole->tracer->tracer);
|
||||
S_StartSound(fang, sfx_altdi1);
|
||||
|
||||
P_SetTarget(&pole->tracer->tracer, NULL);
|
||||
P_SetMobjState(pole->tracer, pole->info->xdeathstate);
|
||||
P_SetTarget(&pole->tracer, NULL);
|
||||
P_SetMobjState(pole, pole->info->deathstate);
|
||||
}
|
||||
|
||||
static void P_PlayerBarrelCollide(mobj_t *toucher, mobj_t *barrel)
|
||||
|
@ -783,12 +784,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (thing->type == MT_SPIKE
|
||||
|| thing->type == MT_WALLSPIKE)
|
||||
{
|
||||
mobjtype_t type = thing->type;
|
||||
mobj_t *iter;
|
||||
if (thing->flags & MF_SOLID)
|
||||
S_StartSound(tmthing, thing->info->deathsound);
|
||||
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
|
||||
if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale))
|
||||
P_KillMobj(thing, tmthing, tmthing, 0);
|
||||
for (iter = thing->subsector->sector->thinglist; iter; iter = iter->snext)
|
||||
if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || P_AproxDistance(P_AproxDistance(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale))
|
||||
P_KillMobj(iter, tmthing, tmthing, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -822,12 +823,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (thing->type == MT_SPIKE
|
||||
|| thing->type == MT_WALLSPIKE)
|
||||
{
|
||||
mobjtype_t type = thing->type;
|
||||
mobj_t *iter;
|
||||
if (thing->flags & MF_SOLID)
|
||||
S_StartSound(tmthing, thing->info->deathsound);
|
||||
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
|
||||
if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale))
|
||||
P_KillMobj(thing, tmthing, tmthing, 0);
|
||||
for (iter = thing->subsector->sector->thinglist; iter; iter = iter->snext)
|
||||
if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || P_AproxDistance(P_AproxDistance(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale))
|
||||
P_KillMobj(iter, tmthing, tmthing, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1020,7 +1021,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if ((thing->flags & MF_PUSHABLE) // not carrying a player
|
||||
&& (tmthing->player->powers[pw_carry] == CR_NONE) // player is not already riding something
|
||||
&& ((tmthing->eflags & MFE_VERTICALFLIP) == (thing->eflags & MFE_VERTICALFLIP))
|
||||
&& (P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < (thing->radius))
|
||||
&& (P_MobjFlip(tmthing)*tmthing->momz <= 0)
|
||||
&& ((!(tmthing->eflags & MFE_VERTICALFLIP) && abs(thing->z + thing->height - tmthing->z) < (thing->height>>2))
|
||||
|| (tmthing->eflags & MFE_VERTICALFLIP && abs(tmthing->z + tmthing->height - thing->z) < (thing->height>>2))))
|
||||
|
@ -1032,7 +1032,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
P_SetPlayerMobjState(tmthing, S_PLAY_WALK);
|
||||
tmthing->player->powers[pw_carry] = CR_ROLLOUT;
|
||||
P_SetTarget(&tmthing->tracer, thing);
|
||||
P_SetObjectMomZ(thing, tmthing->momz, true);
|
||||
if (!P_IsObjectOnGround(thing))
|
||||
thing->momz += tmthing->momz;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1063,6 +1064,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
thing->momy = tmthing->momy;
|
||||
tmthing->momx = tempmomx;
|
||||
tmthing->momy = tempmomy;
|
||||
S_StartSound(thing, thing->info->painsound);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1089,7 +1091,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true; // overhead
|
||||
if (thing->z + thing->height < tmthing->z)
|
||||
return true; // underneath
|
||||
if (!thing->tracer)
|
||||
if (!thing->tracer || !thing->tracer->tracer)
|
||||
return true;
|
||||
P_SlapStick(tmthing, thing);
|
||||
// no return value was used in the original prototype script at this point,
|
||||
|
@ -1349,6 +1351,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
P_DamageMobj(thing, tmthing, tmthing->target, 1, damagetype);
|
||||
}
|
||||
|
||||
// Fireball touched an enemy
|
||||
// Don't bounce though, just despawn right there
|
||||
if ((tmthing->type == MT_FIREBALL) && (thing->flags & MF_ENEMY))
|
||||
P_KillMobj(tmthing, NULL, NULL, 0);
|
||||
|
||||
// don't traverse any more
|
||||
|
||||
if (tmthing->type == MT_SHELL)
|
||||
|
@ -1712,8 +1719,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
}
|
||||
}
|
||||
|
||||
if ((tmthing->flags & MF_SPRING || tmthing->type == MT_STEAM) && (thing->player))
|
||||
; // springs and gas jets should never be able to step up onto a player
|
||||
if ((tmthing->flags & MF_SPRING || tmthing->type == MT_STEAM || tmthing->type == MT_SPIKE || tmthing->type == MT_WALLSPIKE) && (thing->player))
|
||||
; // springs, gas jets and springs should never be able to step up onto a player
|
||||
// z checking at last
|
||||
// Treat noclip things as non-solid!
|
||||
else if ((thing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID
|
||||
|
@ -3464,7 +3471,7 @@ isblocking:
|
|||
}
|
||||
|
||||
// see about climbing on the wall
|
||||
if (!(checkline->flags & ML_NOCLIMB))
|
||||
if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL)
|
||||
{
|
||||
boolean canclimb;
|
||||
angle_t climbangle, climbline;
|
||||
|
@ -3751,6 +3758,33 @@ void P_SlideMove(mobj_t *mo)
|
|||
v2.x = tmhitthing->x + cosradius;
|
||||
v2.y = tmhitthing->y + sinradius;
|
||||
|
||||
// Can we box collision our way into smooth movement..?
|
||||
if (sinradius && mo->y + mo->radius <= min(v1.y, v2.y))
|
||||
{
|
||||
mo->momy = 0;
|
||||
P_TryMove(mo, mo->x + mo->momx, min(v1.y, v2.y) - mo->radius, true);
|
||||
return;
|
||||
}
|
||||
else if (sinradius && mo->y - mo->radius >= max(v1.y, v2.y))
|
||||
{
|
||||
mo->momy = 0;
|
||||
P_TryMove(mo, mo->x + mo->momx, max(v1.y, v2.y) + mo->radius, true);
|
||||
return;
|
||||
}
|
||||
else if (cosradius && mo->x + mo->radius <= min(v1.x, v2.x))
|
||||
{
|
||||
mo->momx = 0;
|
||||
P_TryMove(mo, min(v1.x, v2.x) - mo->radius, mo->y + mo->momy, true);
|
||||
return;
|
||||
}
|
||||
else if (cosradius && mo->x - mo->radius >= max(v1.x, v2.x))
|
||||
{
|
||||
mo->momx = 0;
|
||||
P_TryMove(mo, max(v1.x, v2.x) + mo->radius, mo->y + mo->momy, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// nope, gotta fuck around with a fake linedef!
|
||||
junk.v1 = &v1;
|
||||
junk.v2 = &v2;
|
||||
junk.dx = 2*cosradius; // v2.x - v1.x;
|
||||
|
|
174
src/p_mobj.c
174
src/p_mobj.c
|
@ -246,6 +246,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
{
|
||||
case S_PLAY_STND:
|
||||
case S_PLAY_WAIT:
|
||||
case S_PLAY_NIGHTS_STAND:
|
||||
player->panim = PA_IDLE;
|
||||
break;
|
||||
case S_PLAY_EDGE:
|
||||
|
@ -269,6 +270,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
break;
|
||||
case S_PLAY_ROLL:
|
||||
//case S_PLAY_SPINDASH: -- everyone can ROLL thanks to zoom tubes...
|
||||
case S_PLAY_NIGHTS_ATTACK:
|
||||
player->panim = PA_ROLL;
|
||||
break;
|
||||
case S_PLAY_JUMP:
|
||||
|
@ -278,6 +280,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
player->panim = PA_SPRING;
|
||||
break;
|
||||
case S_PLAY_FALL:
|
||||
case S_PLAY_NIGHTS_FLOAT:
|
||||
player->panim = PA_FALL;
|
||||
break;
|
||||
case S_PLAY_FLY:
|
||||
|
@ -3405,7 +3408,7 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
|
||||
// Drown timer setting
|
||||
if ((p->powers[pw_shield] & SH_PROTECTWATER) // Has water protection
|
||||
|| (p->exiting) // Or exiting
|
||||
|| (p->exiting) || (p->pflags & PF_FINISHED) // Or finished/exiting
|
||||
|| (maptol & TOL_NIGHTS) // Or in NiGHTS mode
|
||||
|| (mariomode)) // Or in Mario mode...
|
||||
{
|
||||
|
@ -3721,17 +3724,10 @@ void P_DestroyRobots(void)
|
|||
}
|
||||
}
|
||||
|
||||
// P_CameraThinker
|
||||
//
|
||||
// Process the mobj-ish required functions of the camera
|
||||
boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled)
|
||||
// the below is chasecam only, if you're curious. check out P_CalcPostImg in p_user.c for first person
|
||||
void P_CalcChasePostImg(player_t *player, camera_t *thiscam)
|
||||
{
|
||||
boolean itsatwodlevel = false;
|
||||
postimg_t postimg = postimg_none;
|
||||
if (twodlevel
|
||||
|| (thiscam == &camera && players[displayplayer].mo && (players[displayplayer].mo->flags2 & MF2_TWOD))
|
||||
|| (thiscam == &camera2 && players[secondarydisplayplayer].mo && (players[secondarydisplayplayer].mo->flags2 & MF2_TWOD)))
|
||||
itsatwodlevel = true;
|
||||
|
||||
if (player->pflags & PF_FLIPCAM && !(player->powers[pw_carry] == CR_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP)
|
||||
postimg = postimg_flip;
|
||||
|
@ -3759,13 +3755,27 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
|
|||
postimg = postimg_heat;
|
||||
}
|
||||
|
||||
if (postimg != postimg_none)
|
||||
{
|
||||
if (splitscreen && player == &players[secondarydisplayplayer])
|
||||
postimgtype2 = postimg;
|
||||
else
|
||||
postimgtype = postimg;
|
||||
}
|
||||
if (postimg == postimg_none)
|
||||
return;
|
||||
|
||||
if (splitscreen && player == &players[secondarydisplayplayer])
|
||||
postimgtype2 = postimg;
|
||||
else
|
||||
postimgtype = postimg;
|
||||
}
|
||||
|
||||
// P_CameraThinker
|
||||
//
|
||||
// Process the mobj-ish required functions of the camera
|
||||
boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled)
|
||||
{
|
||||
boolean itsatwodlevel = false;
|
||||
if (twodlevel
|
||||
|| (thiscam == &camera && players[displayplayer].mo && (players[displayplayer].mo->flags2 & MF2_TWOD))
|
||||
|| (thiscam == &camera2 && players[secondarydisplayplayer].mo && (players[secondarydisplayplayer].mo->flags2 & MF2_TWOD)))
|
||||
itsatwodlevel = true;
|
||||
|
||||
P_CalcChasePostImg(player, thiscam);
|
||||
|
||||
if (thiscam->momx || thiscam->momy)
|
||||
{
|
||||
|
@ -4535,23 +4545,29 @@ static void P_Boss3Thinker(mobj_t *mobj)
|
|||
}
|
||||
else if (mobj->movecount) // Firing mode
|
||||
{
|
||||
// look for a new target
|
||||
P_BossTargetPlayer(mobj, false);
|
||||
|
||||
if (!mobj->target || !mobj->target->player)
|
||||
return;
|
||||
|
||||
// Always face your target.
|
||||
A_FaceTarget(mobj);
|
||||
|
||||
// Check if the attack animation is running. If not, play it.
|
||||
if (mobj->state < &states[mobj->info->missilestate] || mobj->state > &states[mobj->info->raisestate])
|
||||
{
|
||||
// look for a new target
|
||||
P_BossTargetPlayer(mobj, true);
|
||||
|
||||
if (!mobj->target || !mobj->target->player)
|
||||
return;
|
||||
|
||||
if (mobj->health <= mobj->info->damage) // pinch phase
|
||||
mobj->movecount--; // limited number of shots before diving again
|
||||
if (mobj->movecount)
|
||||
P_SetMobjState(mobj, mobj->info->missilestate+1);
|
||||
}
|
||||
else if (mobj->target && mobj->target->player)
|
||||
{
|
||||
angle_t diff = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y) - mobj->angle;
|
||||
if (diff > ANGLE_180)
|
||||
diff = InvAngle(InvAngle(diff)/4);
|
||||
else
|
||||
diff /= 4;
|
||||
mobj->angle += diff;
|
||||
}
|
||||
}
|
||||
else if (mobj->threshold >= 0) // Traveling mode
|
||||
{
|
||||
|
@ -4666,13 +4682,10 @@ static void P_Boss3Thinker(mobj_t *mobj)
|
|||
S_StartSound(mobj, shock->info->seesound);
|
||||
|
||||
// look for a new target
|
||||
P_BossTargetPlayer(mobj, false);
|
||||
P_BossTargetPlayer(mobj, true);
|
||||
|
||||
if (mobj->target && mobj->target->player)
|
||||
{
|
||||
A_FaceTarget(mobj);
|
||||
P_SetMobjState(mobj, mobj->info->missilestate);
|
||||
}
|
||||
}
|
||||
else if (mobj->flags2 & (MF2_STRONGBOX|MF2_CLASSICPUSH)) // just hit the bottom of your tube
|
||||
{
|
||||
|
@ -7076,7 +7089,7 @@ static void P_SpawnMinecartSegments(mobj_t *mobj, boolean mode)
|
|||
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;
|
||||
seg->extravalue1 = (i == 2) ? -20 : 20;
|
||||
else
|
||||
{
|
||||
seg->extravalue2 = (i == 0) ? 24 : -24;
|
||||
|
@ -8227,7 +8240,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
break;
|
||||
case MT_EGGTRAP: // Egg Capsule animal release
|
||||
if (mobj->fuse > 0 && mobj->fuse < 2*TICRATE-(TICRATE/7))
|
||||
if (mobj->fuse > 0)// && mobj->fuse < TICRATE-(TICRATE/7))
|
||||
{
|
||||
INT32 i;
|
||||
fixed_t x,y,z;
|
||||
|
@ -8236,9 +8249,9 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj_t *flicky;
|
||||
|
||||
z = mobj->subsector->sector->floorheight + FRACUNIT + (P_RandomKey(64)<<FRACBITS);
|
||||
for (i = 0; i < 2; i++)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
const angle_t fa = (P_RandomByte()*FINEANGLES/16) & FINEMASK;
|
||||
const angle_t fa = P_RandomKey(FINEANGLES) & FINEMASK;
|
||||
ns = 64 * FRACUNIT;
|
||||
x = mobj->x + FixedMul(FINESINE(fa),ns);
|
||||
y = mobj->y + FixedMul(FINECOSINE(fa),ns);
|
||||
|
@ -8690,6 +8703,13 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
case MT_KOOPA:
|
||||
P_KoopaThinker(mobj);
|
||||
break;
|
||||
case MT_FIREBALL:
|
||||
if (P_AproxDistance(mobj->momx, mobj->momy) <= 16*FRACUNIT) // Once fireballs lose enough speed, kill them
|
||||
{
|
||||
P_KillMobj(mobj, NULL, NULL, 0);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case MT_REDRING:
|
||||
if (((mobj->z < mobj->floorz) || (mobj->z + mobj->height > mobj->ceilingz))
|
||||
&& mobj->flags & MF_MISSILE)
|
||||
|
@ -9622,6 +9642,90 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case MT_DRAGONBOMBER:
|
||||
{
|
||||
#define DRAGONTURNSPEED ANG2
|
||||
mobj->movecount = (mobj->movecount + 9) % 360;
|
||||
P_SetObjectMomZ(mobj, 4*FINESINE(((mobj->movecount*ANG1) >> ANGLETOFINESHIFT) & FINEMASK), false);
|
||||
if (mobj->threshold > 0) // are we dropping mines?
|
||||
{
|
||||
mobj->threshold--;
|
||||
if (mobj->threshold == 0) // if the timer hits 0, look for a mine to drop!
|
||||
{
|
||||
mobj_t *segment = mobj;
|
||||
while (segment->tracer != NULL && !P_MobjWasRemoved(segment->tracer) && segment->tracer->state == &states[segment->tracer->info->spawnstate])
|
||||
{
|
||||
segment = segment->tracer;
|
||||
}
|
||||
if (segment != mobj) // found an unactivated segment?
|
||||
{
|
||||
mobj_t *mine = P_SpawnMobjFromMobj(segment, 0, 0, 0, segment->info->painchance);
|
||||
mine->angle = segment->angle;
|
||||
P_InstaThrust(mine, mobj->angle, P_AproxDistance(mobj->momx, mobj->momy) >> 1);
|
||||
P_SetObjectMomZ(mine, -2*FRACUNIT, true);
|
||||
S_StartSound(mine, mine->info->seesound);
|
||||
P_SetMobjState(segment, segment->info->raisestate);
|
||||
mobj->threshold = mobj->info->painchance;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mobj->target != NULL) // Are we chasing a player?
|
||||
{
|
||||
fixed_t dist = P_AproxDistance(mobj->x - mobj->target->x, mobj->y - mobj->target->y);
|
||||
if (dist > 2000 * mobj->scale) // Not anymore!
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
else
|
||||
{
|
||||
fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale);
|
||||
fixed_t z = mobj->target->z + (mobj->height >> 1) + (mobj->flags & MFE_VERTICALFLIP ? -128*mobj->scale : 128*mobj->scale + mobj->target->height);
|
||||
angle_t diff = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y) - mobj->angle;
|
||||
if (diff > ANGLE_180)
|
||||
mobj->angle -= DRAGONTURNSPEED;
|
||||
else
|
||||
mobj->angle += DRAGONTURNSPEED;
|
||||
if (!mobj->threshold && dist < 512 * mobj->scale) // Close enough to drop bombs
|
||||
{
|
||||
mobj->threshold = mobj->info->painchance;
|
||||
}
|
||||
mobj->momz += max(min(z - mobj->z, vspeed), -vspeed);
|
||||
}
|
||||
}
|
||||
else // Can we find a player to chase?
|
||||
{
|
||||
if (mobj->tracer == NULL || mobj->tracer->state != &states[mobj->tracer->info->spawnstate]
|
||||
|| !P_LookForPlayers(mobj, true, false, 2000*mobj->scale)) // if not, circle around the spawnpoint
|
||||
{
|
||||
if (!mobj->spawnpoint) // unless we don't have one, in which case uhhh just circle around wherever we currently are I guess??
|
||||
mobj->angle += DRAGONTURNSPEED;
|
||||
else
|
||||
{
|
||||
fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale);
|
||||
fixed_t x = mobj->spawnpoint->x << FRACBITS;
|
||||
fixed_t y = mobj->spawnpoint->y << FRACBITS;
|
||||
fixed_t z = mobj->spawnpoint->z << FRACBITS;
|
||||
angle_t diff = R_PointToAngle2(mobj->x, mobj->y, x, y) - mobj->angle;
|
||||
if (diff > ANGLE_180)
|
||||
mobj->angle -= DRAGONTURNSPEED;
|
||||
else
|
||||
mobj->angle += DRAGONTURNSPEED;
|
||||
mobj->momz += max(min(z - mobj->z, vspeed), -vspeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
P_InstaThrust(mobj, mobj->angle, FixedMul(mobj->info->speed, mobj->scale));
|
||||
#undef DRAGONTURNSPEED
|
||||
}
|
||||
break;
|
||||
case MT_MINUS:
|
||||
#ifdef ROTSPRITE
|
||||
{
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
mobj->rollangle = 0;
|
||||
else
|
||||
mobj->rollangle = R_PointToAngle2(0, 0, mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1));
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case MT_SPINFIRE:
|
||||
if (mobj->flags & MF_NOGRAVITY)
|
||||
{
|
||||
|
@ -11207,7 +11311,7 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
mobj->radius = FixedMul(skins[p->skin].radius, mobj->scale);
|
||||
mobj->height = P_GetPlayerHeight(p);
|
||||
|
||||
if (!leveltime && ((maptol & TOL_NIGHTS) == TOL_NIGHTS) != (G_IsSpecialStage(gamemap))) // non-special NiGHTS stage or special non-NiGHTS stage
|
||||
if (!leveltime && !p->spectator && ((maptol & TOL_NIGHTS) == TOL_NIGHTS) != (G_IsSpecialStage(gamemap))) // non-special NiGHTS stage or special non-NiGHTS stage
|
||||
{
|
||||
if (maptol & TOL_NIGHTS)
|
||||
{
|
||||
|
|
|
@ -2704,6 +2704,7 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
|
||||
// Cancel all d_main.c fadeouts (keep fade in though).
|
||||
wipegamestate = FORCEWIPEOFF;
|
||||
wipestyleflags = 0;
|
||||
|
||||
// Special stage fade to white
|
||||
// This is handled BEFORE sounds are stopped.
|
||||
|
@ -2724,11 +2725,22 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_towhite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE)
|
||||
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
|
||||
wipestyleflags |= (WSF_FADEOUT|WSF_TOWHITE);
|
||||
|
||||
#ifdef HWRENDER
|
||||
// uh..........
|
||||
if (rendermode == render_opengl)
|
||||
F_WipeColorFill(0);
|
||||
#endif
|
||||
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipedefs[wipe_speclevel_towhite], false);
|
||||
|
||||
I_OsPolling();
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
|
||||
nowtime = lastwipetic;
|
||||
|
||||
// Hold on white for extra effect.
|
||||
|
@ -2745,6 +2757,13 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
ranspecialwipe = 1;
|
||||
}
|
||||
|
||||
if (G_GetModeAttackRetryFlag())
|
||||
{
|
||||
if (modeattacking)
|
||||
wipestyleflags |= (WSF_FADEOUT|WSF_TOWHITE);
|
||||
G_ClearModeAttackRetryFlag();
|
||||
}
|
||||
|
||||
// Make sure all sounds are stopped before Z_FreeTags.
|
||||
S_StopSounds();
|
||||
S_ClearSfx();
|
||||
|
@ -2762,7 +2781,13 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
if (rendermode != render_none && !ranspecialwipe)
|
||||
{
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
wipestyleflags |= WSF_FADEOUT;
|
||||
|
||||
#ifdef HWRENDER
|
||||
// uh..........
|
||||
if (rendermode == render_opengl)
|
||||
F_WipeColorFill(31);
|
||||
#endif
|
||||
|
||||
F_WipeEndScreen();
|
||||
// for titlemap: run a specific wipe if specified
|
||||
|
@ -2787,12 +2812,12 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
{
|
||||
// Don't include these in the fade!
|
||||
char tx[64];
|
||||
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
|
||||
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE|V_TRANSLUCENT|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Speeding off to..."));
|
||||
snprintf(tx, 63, "%s%s%s",
|
||||
mapheaderinfo[gamemap-1]->lvlttl,
|
||||
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE",
|
||||
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : "");
|
||||
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx);
|
||||
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " Zone",
|
||||
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(" %d",mapheaderinfo[gamemap-1]->actnum) : "");
|
||||
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE|V_TRANSLUCENT|V_SNAPTOLEFT|V_SNAPTOBOTTOM, tx);
|
||||
I_UpdateNoVsync();
|
||||
}
|
||||
|
||||
|
@ -3177,7 +3202,7 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
|
||||
// Remove the loading shit from the screen
|
||||
if (rendermode != render_none && !titlemapinaction)
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
|
||||
F_WipeColorFill(levelfadecol);
|
||||
|
||||
if (precache || dedicated)
|
||||
R_PrecacheLevel();
|
||||
|
@ -3226,44 +3251,22 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
#endif
|
||||
}
|
||||
|
||||
// Stage title!
|
||||
if (rendermode != render_none
|
||||
&& (!titlemapinaction)
|
||||
&& ranspecialwipe != 2
|
||||
&& *mapheaderinfo[gamemap-1]->lvlttl != '\0'
|
||||
#ifdef HAVE_BLUA
|
||||
&& LUA_HudEnabled(hud_stagetitle)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
tic_t starttime = I_GetTime();
|
||||
tic_t endtime = starttime + (10*NEWTICRATERATIO);
|
||||
tic_t nowtime = starttime;
|
||||
tic_t lasttime = starttime;
|
||||
while (nowtime < endtime)
|
||||
{
|
||||
// draw loop
|
||||
while (!((nowtime = I_GetTime()) - lasttime))
|
||||
I_Sleep();
|
||||
lasttime = nowtime;
|
||||
// No render mode, stop here.
|
||||
if (rendermode == render_none)
|
||||
return true;
|
||||
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
|
||||
stplyr = &players[consoleplayer];
|
||||
ST_drawLevelTitle(nowtime - starttime);
|
||||
if (splitscreen)
|
||||
{
|
||||
stplyr = &players[secondarydisplayplayer];
|
||||
ST_drawLevelTitle(nowtime - starttime);
|
||||
}
|
||||
// Title card!
|
||||
G_StartTitleCard();
|
||||
|
||||
I_OsPolling();
|
||||
I_UpdateNoBlit();
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
// Can the title card actually run, though?
|
||||
if (!WipeStageTitle)
|
||||
return true;
|
||||
if (ranspecialwipe == 2)
|
||||
return true;
|
||||
|
||||
if (moviemode) // make sure we save frames for the white hold too
|
||||
M_SaveFrame();
|
||||
}
|
||||
}
|
||||
// If so...
|
||||
if ((!(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)) && (*mapheaderinfo[gamemap-1]->lvlttl != '\0'))
|
||||
G_PreLevelTitleCard(lt_ticker, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
127
src/p_spec.c
127
src/p_spec.c
|
@ -2721,6 +2721,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
|
||||
if (line->tag != 0) // Do special stuff only if a non-zero linedef tag is set
|
||||
{
|
||||
// Play sounds from tagged sectors' origins.
|
||||
if (line->flags & ML_EFFECT5) // Repeat Midtexture
|
||||
{
|
||||
// Additionally play the sound from tagged sectors' soundorgs
|
||||
|
@ -2732,31 +2733,45 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
S_StartSound(&sec->soundorg, sfxnum);
|
||||
}
|
||||
}
|
||||
else if (mo) // A mobj must have triggered the executor
|
||||
|
||||
// Play the sound without origin for anyone, as long as they're inside tagged areas.
|
||||
else
|
||||
{
|
||||
// Only trigger if mobj is touching the tag
|
||||
UINT8 i = 0;
|
||||
mobj_t* camobj = players[displayplayer].mo;
|
||||
ffloor_t *rover;
|
||||
boolean foundit = false;
|
||||
|
||||
for(rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
|
||||
for (i = 0; i < 2; camobj = players[secondarydisplayplayer].mo, i++)
|
||||
{
|
||||
if (rover->master->frontsector->tag != line->tag)
|
||||
if (!camobj)
|
||||
continue;
|
||||
|
||||
if (mo->z > P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector))
|
||||
continue;
|
||||
if (foundit || (camobj->subsector->sector->tag == line->tag))
|
||||
{
|
||||
foundit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mo->z + mo->height < P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector))
|
||||
continue;
|
||||
// Only trigger if mobj is touching the tag
|
||||
for(rover = camobj->subsector->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector->tag != line->tag)
|
||||
continue;
|
||||
|
||||
foundit = true;
|
||||
if (camobj->z > P_GetSpecialTopZ(camobj, sectors + rover->secnum, camobj->subsector->sector))
|
||||
continue;
|
||||
|
||||
if (camobj->z + camobj->height < P_GetSpecialBottomZ(camobj, sectors + rover->secnum, camobj->subsector->sector))
|
||||
continue;
|
||||
|
||||
foundit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mo->subsector->sector->tag == line->tag)
|
||||
foundit = true;
|
||||
|
||||
if (!foundit)
|
||||
return;
|
||||
if (foundit)
|
||||
S_StartSound(NULL, sfxnum);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -4439,59 +4454,55 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
case 3: // Linedef executor requires all players present
|
||||
/// \todo check continues for proper splitscreen support?
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && !players[i].bot && players[i].mo && (gametype != GT_COOP || players[i].lives > 0))
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
if (!players[i].mo)
|
||||
continue;
|
||||
if (players[i].spectator)
|
||||
continue;
|
||||
if (players[i].bot)
|
||||
continue;
|
||||
if (gametype == GT_COOP && players[i].lives <= 0)
|
||||
continue;
|
||||
if (roversector)
|
||||
{
|
||||
if (roversector)
|
||||
if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
{
|
||||
if (players[i].mo->subsector->sector == roversector)
|
||||
;
|
||||
else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
msecnode_t *node;
|
||||
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
boolean insector = false;
|
||||
msecnode_t *node;
|
||||
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (node->m_sector == roversector)
|
||||
{
|
||||
insector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!insector)
|
||||
goto DoneSection2;
|
||||
if (P_ThingIsOnThe3DFloor(players[i].mo, sector, node->m_sector))
|
||||
break;
|
||||
}
|
||||
else
|
||||
if (!node)
|
||||
goto DoneSection2;
|
||||
|
||||
if (!P_ThingIsOnThe3DFloor(players[i].mo, sector, roversector))
|
||||
}
|
||||
else if (players[i].mo->subsector && !P_ThingIsOnThe3DFloor(players[i].mo, sector, players[i].mo->subsector->sector)) // this function handles basically everything for us lmao
|
||||
goto DoneSection2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[i].mo->subsector->sector == sector)
|
||||
;
|
||||
else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
{
|
||||
msecnode_t *node;
|
||||
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (node->m_sector == sector)
|
||||
break;
|
||||
}
|
||||
if (!node)
|
||||
goto DoneSection2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[i].mo->subsector->sector == sector)
|
||||
;
|
||||
else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||
{
|
||||
boolean insector = false;
|
||||
msecnode_t *node;
|
||||
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (node->m_sector == sector)
|
||||
{
|
||||
insector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!insector)
|
||||
goto DoneSection2;
|
||||
}
|
||||
else
|
||||
goto DoneSection2;
|
||||
goto DoneSection2;
|
||||
|
||||
if (special == 3 && !P_MobjReadyToTrigger(players[i].mo, sector))
|
||||
goto DoneSection2;
|
||||
}
|
||||
if (special == 3 && !P_MobjReadyToTrigger(players[i].mo, sector))
|
||||
goto DoneSection2;
|
||||
}
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case 4: // Linedef executor that doesn't require touching floor
|
||||
case 5: // Linedef executor
|
||||
|
@ -4675,7 +4686,7 @@ DoneSection2:
|
|||
{
|
||||
INT32 lineindex;
|
||||
|
||||
P_DoPlayerExit(player);
|
||||
P_DoPlayerFinish(player);
|
||||
|
||||
P_SetupSignExit(player);
|
||||
// important: use sector->tag on next line instead of player->mo->subsector->tag
|
||||
|
|
|
@ -481,6 +481,9 @@ static inline void P_DoSpecialStageStuff(void)
|
|||
tic_t oldnightstime = players[i].nightstime;
|
||||
countspheres += players[i].spheres;
|
||||
|
||||
if (!oldnightstime)
|
||||
continue;
|
||||
|
||||
// If in water, deplete timer 6x as fast.
|
||||
if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER) && !(players[i].powers[pw_shield] & SH_PROTECTWATER))
|
||||
players[i].nightstime -= 5;
|
||||
|
@ -506,12 +509,11 @@ static inline void P_DoSpecialStageStuff(void)
|
|||
{
|
||||
// Halt all the players
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
if (playeringame[i] && !players[i].exiting)
|
||||
{
|
||||
players[i].mo->momx = players[i].mo->momy = 0;
|
||||
players[i].exiting = (14*TICRATE)/5 + 1;
|
||||
}
|
||||
|
||||
sstimer = 0;
|
||||
P_GiveEmerald(true);
|
||||
P_RestoreMusic(&players[consoleplayer]);
|
||||
|
|
207
src/p_user.c
207
src/p_user.c
|
@ -343,13 +343,15 @@ void P_GiveEmerald(boolean spawnObj)
|
|||
continue;
|
||||
|
||||
emmo = P_SpawnMobjFromMobj(players[i].mo, 0, 0, players[i].mo->height, MT_GOTEMERALD);
|
||||
if (!emmo)
|
||||
continue;
|
||||
P_SetTarget(&emmo->target, players[i].mo);
|
||||
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
|
||||
P_SetTarget(&players[i].mo->tracer, emmo);
|
||||
|
||||
if (pnum == 255)
|
||||
{
|
||||
i = pnum;
|
||||
pnum = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -636,6 +638,10 @@ static void P_DeNightserizePlayer(player_t *player)
|
|||
player->marebonuslap = 0;
|
||||
player->flyangle = 0;
|
||||
player->anotherflyangle = 0;
|
||||
#ifdef ROTSPRITE
|
||||
player->mo->rollangle = 0;
|
||||
#endif
|
||||
|
||||
P_SetTarget(&player->mo->target, NULL);
|
||||
P_SetTarget(&player->axis1, P_SetTarget(&player->axis2, NULL));
|
||||
|
||||
|
@ -762,6 +768,9 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
|||
player->secondjump = 0;
|
||||
player->flyangle = 0;
|
||||
player->anotherflyangle = 0;
|
||||
#ifdef ROTSPRITE
|
||||
player->mo->rollangle = 0;
|
||||
#endif
|
||||
|
||||
player->powers[pw_shield] = SH_NONE;
|
||||
player->powers[pw_super] = 0;
|
||||
|
@ -1216,6 +1225,7 @@ void P_GivePlayerSpheres(player_t *player, INT32 num_spheres)
|
|||
//
|
||||
void P_GivePlayerLives(player_t *player, INT32 numlives)
|
||||
{
|
||||
UINT8 prevlives = player->lives;
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
|
@ -1232,10 +1242,9 @@ void P_GivePlayerLives(player_t *player, INT32 numlives)
|
|||
|
||||
if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0)
|
||||
{
|
||||
UINT8 prevlives = player->lives;
|
||||
P_GivePlayerRings(player, 100*numlives);
|
||||
if (player->lives - prevlives >= numlives)
|
||||
return;
|
||||
goto docooprespawn;
|
||||
|
||||
numlives = (numlives + prevlives - player->lives);
|
||||
}
|
||||
|
@ -1249,6 +1258,15 @@ void P_GivePlayerLives(player_t *player, INT32 numlives)
|
|||
player->lives = 99;
|
||||
else if (player->lives < 1)
|
||||
player->lives = 1;
|
||||
|
||||
docooprespawn:
|
||||
if (cv_coopstarposts.value)
|
||||
return;
|
||||
if (prevlives > 0)
|
||||
return;
|
||||
if (!player->spectator)
|
||||
return;
|
||||
P_SpectatorJoinGame(player);
|
||||
}
|
||||
|
||||
void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound)
|
||||
|
@ -2124,6 +2142,34 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type)
|
|||
P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do
|
||||
}
|
||||
|
||||
/** Called when \p player finishes the level.
|
||||
*
|
||||
* Only use for cases where the player should be able to move
|
||||
* while waiting for others to finish. Otherwise, use P_DoPlayerExit().
|
||||
*
|
||||
* In single player or if ::cv_exitmove is disabled, this will also cause
|
||||
* P_PlayerThink() to call P_DoPlayerExit(), so you do not need to
|
||||
* make a special cases for those.
|
||||
*
|
||||
* \param player The player who finished the level.
|
||||
* \sa P_DoPlayerExit
|
||||
*
|
||||
*/
|
||||
void P_DoPlayerFinish(player_t *player)
|
||||
{
|
||||
if (player->pflags & PF_FINISHED)
|
||||
return;
|
||||
|
||||
player->pflags |= PF_FINISHED;
|
||||
|
||||
if (netgame)
|
||||
CONS_Printf(M_GetText("%s has completed the level.\n"), player_names[player-players]);
|
||||
|
||||
player->powers[pw_underwater] = 0;
|
||||
player->powers[pw_spacetime] = 0;
|
||||
P_RestoreMusic(player);
|
||||
}
|
||||
|
||||
//
|
||||
// P_DoPlayerExit
|
||||
//
|
||||
|
@ -2158,12 +2204,14 @@ void P_DoPlayerExit(player_t *player)
|
|||
player->pflags |= P_GetJumpFlags(player);
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
|
||||
}
|
||||
else if (player->pflags & PF_STARTDASH)
|
||||
{
|
||||
player->pflags &= ~PF_STARTDASH;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||
}
|
||||
player->powers[pw_underwater] = 0;
|
||||
player->powers[pw_spacetime] = 0;
|
||||
P_RestoreMusic(player);
|
||||
|
||||
if (playeringame[player-players] && netgame && !circuitmap)
|
||||
CONS_Printf(M_GetText("%s has completed the level.\n"), player_names[player-players]);
|
||||
}
|
||||
|
||||
#define SPACESPECIAL 12
|
||||
|
@ -2263,7 +2311,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
|||
else if (!player->skidtime)
|
||||
player->pflags &= ~PF_GLIDING;
|
||||
}
|
||||
else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && !(player->pflags & PF_SHIELDABILITY) && player->mo->state-states == S_PLAY_FALL)
|
||||
else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && !(player->pflags & (PF_JUMPED|PF_SHIELDABILITY)) && player->mo->state-states == S_PLAY_FALL)
|
||||
{
|
||||
if (player->mo->state-states != S_PLAY_GLIDE_LANDING)
|
||||
{
|
||||
|
@ -2326,11 +2374,23 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
|||
;
|
||||
else if (player->panim != PA_IDLE && player->panim != PA_WALK && player->panim != PA_RUN && player->panim != PA_DASH)
|
||||
{
|
||||
fixed_t runspd = FixedMul(player->runspeed, player->mo->scale);
|
||||
|
||||
// See comments in P_MovePlayer for explanation of changes.
|
||||
|
||||
if (player->powers[pw_super])
|
||||
runspd = FixedMul(runspd, 5*FRACUNIT/3);
|
||||
|
||||
runspd = FixedMul(runspd, player->mo->movefactor);
|
||||
|
||||
if (maptol & TOL_2D)
|
||||
runspd = FixedMul(runspd, 2*FRACUNIT/3);
|
||||
|
||||
if (player->cmomx || player->cmomy)
|
||||
{
|
||||
if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
|
||||
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
|
||||
else if (player->speed >= runspd
|
||||
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
|
||||
else if ((player->rmomx || player->rmomy)
|
||||
|
@ -2343,7 +2403,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
|||
{
|
||||
if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
|
||||
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
|
||||
else if (player->speed >= runspd
|
||||
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
|
||||
else if ((player->mo->momx || player->mo->momy)
|
||||
|
@ -2827,7 +2887,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
|
|||
{
|
||||
tic_t timeleft = (player->powers[pw_spacetime]) ? player->powers[pw_spacetime] : player->powers[pw_underwater];
|
||||
|
||||
if (player->exiting)
|
||||
if (player->exiting || (player->pflags & PF_FINISHED))
|
||||
player->powers[pw_underwater] = player->powers[pw_spacetime] = 0;
|
||||
|
||||
timeleft--; // The original code was all n*TICRATE + 1, so let's remove 1 tic for simplicity
|
||||
|
@ -3478,7 +3538,7 @@ static void P_DoClimbing(player_t *player)
|
|||
{
|
||||
P_SetObjectMomZ(player->mo, 2*FRACUNIT, true);
|
||||
if (cmd->forwardmove)
|
||||
P_SetObjectMomZ(player->mo, 2*player->mo->momz/3, false);
|
||||
player->mo->momz = 2*player->mo->momz/3;
|
||||
}
|
||||
if (thrust)
|
||||
P_Thrust(player->mo, player->mo->angle, FixedMul(4*FRACUNIT, player->mo->scale)); // Lil' boost up.
|
||||
|
@ -3993,12 +4053,14 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
|
|||
if (player->pflags & PF_ATTACKDOWN || player->climbing || (G_TagGametype() && !(player->pflags & PF_TAGIT)))
|
||||
return;
|
||||
|
||||
if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER)
|
||||
if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->weapondelay))
|
||||
{
|
||||
player->pflags |= PF_ATTACKDOWN;
|
||||
mo = P_SpawnPlayerMissile(player->mo, MT_FIREBALL, 0);
|
||||
P_InstaThrust(mo, player->mo->angle, ((mo->info->speed>>FRACBITS)*player->mo->scale) + player->speed);
|
||||
if (mo)
|
||||
P_InstaThrust(mo, player->mo->angle, ((mo->info->speed>>FRACBITS)*player->mo->scale) + player->speed);
|
||||
S_StartSound(player->mo, sfx_mario7);
|
||||
P_SetWeaponDelay(player, TICRATE); // Short delay between fireballs so you can't spam them everywhere
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4017,8 +4079,8 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
mo = P_SpawnPlayerMissile(player->mo, MT_THROWNBOUNCE, MF2_BOUNCERING);
|
||||
|
||||
if (mo)
|
||||
mo->fuse = 3*TICRATE; // Bounce Ring time
|
||||
if (mo)
|
||||
mo->fuse = 3*TICRATE; // Bounce Ring time
|
||||
}
|
||||
// Rail ring
|
||||
else if (player->currentweapon == WEP_RAIL && player->powers[pw_railring])
|
||||
|
@ -4391,7 +4453,11 @@ void P_DoJump(player_t *player, boolean soundandstate)
|
|||
}
|
||||
else if (player->powers[pw_carry] == CR_ROLLOUT)
|
||||
{
|
||||
player->mo->momz = 9*FRACUNIT + player->mo->tracer->momz;
|
||||
player->mo->momz = 9*FRACUNIT;
|
||||
if (P_MobjFlip(player->mo->tracer)*player->mo->tracer->momz > 0)
|
||||
player->mo->momz += player->mo->tracer->momz;
|
||||
if (!P_IsObjectOnGround(player->mo->tracer))
|
||||
P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true);
|
||||
player->powers[pw_carry] = CR_NONE;
|
||||
player->mo->tracer->flags |= MF_PUSHABLE;
|
||||
P_SetTarget(&player->mo->tracer->tracer, NULL);
|
||||
|
@ -4562,6 +4628,13 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
|
|||
// Revving
|
||||
else if ((cmd->buttons & BT_USE) && (player->pflags & PF_STARTDASH))
|
||||
{
|
||||
if (player->speed > 5*player->mo->scale)
|
||||
{
|
||||
player->pflags &= ~PF_STARTDASH;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
|
||||
S_StartSound(player->mo, sfx_spin);
|
||||
break;
|
||||
}
|
||||
if (player->dashspeed < player->maxdash)
|
||||
{
|
||||
#define chargecalculation (6*(player->dashspeed - player->mindash))/(player->maxdash - player->mindash)
|
||||
|
@ -4577,7 +4650,6 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
|
|||
G_GhostAddRev();
|
||||
}
|
||||
}
|
||||
|
||||
// If not moving up or down, and travelling faster than a speed of five while not holding
|
||||
// down the spin button and not spinning.
|
||||
// AKA Just go into a spin on the ground, you idiot. ;)
|
||||
|
@ -4729,10 +4801,10 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
// Rolling normally
|
||||
if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH)
|
||||
&& player->speed < FixedMul(5*FRACUNIT,player->mo->scale) && canstand)
|
||||
&& player->speed < 5*player->mo->scale && canstand)
|
||||
{
|
||||
if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player)))
|
||||
P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale));
|
||||
P_InstaThrust(player->mo, player->mo->angle, 10*player->mo->scale);
|
||||
else
|
||||
{
|
||||
player->skidtime = 0;
|
||||
|
@ -5295,7 +5367,10 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
player->powers[pw_tailsfly] = tailsflytics + 1; // Set the fly timer
|
||||
|
||||
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_STARTDASH);
|
||||
player->pflags |= (PF_THOKKED|PF_CANCARRY);
|
||||
if (player->bot == 1)
|
||||
player->pflags |= PF_THOKKED;
|
||||
else
|
||||
player->pflags |= (PF_THOKKED|PF_CANCARRY);
|
||||
}
|
||||
break;
|
||||
case CA_GLIDEANDCLIMB:
|
||||
|
@ -5496,7 +5571,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
else
|
||||
potentialmomz = ((player->speed < 10*player->mo->scale)
|
||||
? (player->speed - 10*player->mo->scale)/5
|
||||
: 0);
|
||||
: -1); // Should be 0, but made negative to ensure P_PlayerHitFloor runs upon touching ground
|
||||
if (P_MobjFlip(player->mo)*player->mo->momz < potentialmomz)
|
||||
player->mo->momz = P_MobjFlip(player->mo)*potentialmomz;
|
||||
player->pflags &= ~PF_SPINNING;
|
||||
|
@ -5891,6 +5966,8 @@ static void P_3dMovement(player_t *player)
|
|||
// When sliding, don't allow forward/back
|
||||
if (player->pflags & PF_SLIDING)
|
||||
cmd->forwardmove = 0;
|
||||
else if (onground && player->mo->state == states+S_PLAY_PAIN)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
|
||||
|
||||
player->aiming = cmd->aiming<<FRACBITS;
|
||||
|
||||
|
@ -7705,6 +7782,9 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
|
|||
else
|
||||
ground = player->mo->floorz;
|
||||
|
||||
if (cropcircle)
|
||||
ground += P_MobjFlip(player->mo);
|
||||
|
||||
if (cropcircle)
|
||||
{
|
||||
#define numangles 8
|
||||
|
@ -7882,6 +7962,11 @@ static void P_MovePlayer(player_t *player)
|
|||
cmd = &player->cmd;
|
||||
runspd = FixedMul(player->runspeed, player->mo->scale);
|
||||
|
||||
// This was done in Sonic 3 & Knuckles, but has been missed in Sonic Mania and the Taxman/Stealth mobile remakes. Thanks to NeoHazard for his 2017 blogpost on the matter, because this oversight otherwise almost made it all the way to 2.2's release.
|
||||
//https://s3unlocked.blogspot.com/2017/12/over-threshold.html
|
||||
if (player->powers[pw_super])
|
||||
runspd = FixedMul(runspd, 5*FRACUNIT/3);
|
||||
|
||||
// Let's have some movement speed fun on low-friction surfaces, JUST for players... (high friction surfaces shouldn't have any adjustment, since the acceleration in this game is super high and that ends up cheesing high-friction surfaces.)
|
||||
runspd = FixedMul(runspd, player->mo->movefactor);
|
||||
|
||||
|
@ -8364,7 +8449,7 @@ static void P_MovePlayer(player_t *player)
|
|||
|
||||
// Tails Put-Put noise
|
||||
if (player->charability == CA_FLY
|
||||
&& player->bot != 1
|
||||
&& (player->pflags & PF_CANCARRY)
|
||||
&& !(player->mo->eflags & MFE_UNDERWATER)
|
||||
&& leveltime % 10 == 0
|
||||
&& !player->spectator)
|
||||
|
@ -9420,7 +9505,6 @@ static void P_DeathThink(player_t *player)
|
|||
}
|
||||
else if ((netgame || multiplayer) && player->deadtimer >= 8*TICRATE)
|
||||
{
|
||||
|
||||
INT32 i, deadtimercheck = INT32_MAX;
|
||||
|
||||
// In a net/multiplayer game, and out of lives
|
||||
|
@ -9590,8 +9674,25 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
|
||||
mo = player->mo;
|
||||
|
||||
if (player->exiting && mo->target && mo->target->type == MT_SIGN)
|
||||
sign = mo->target;
|
||||
if (player->playerstate == PST_REBORN)
|
||||
{
|
||||
P_CalcChasePostImg(player, thiscam);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player->exiting)
|
||||
{
|
||||
if (mo->target && mo->target->type == MT_SIGN && mo->target->spawnpoint
|
||||
&& !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value))
|
||||
sign = mo->target;
|
||||
else if ((player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1]
|
||||
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6]))
|
||||
{
|
||||
P_CalcChasePostImg(player, thiscam);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
cameranoclip = (player->powers[pw_carry] == CR_NIGHTSMODE || player->pflags & PF_NOCLIP) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
|
||||
|
||||
|
@ -9671,7 +9772,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
camorbit = (!stricmp(cv_cam_orbit.defaultvalue, "off")) ? false : true;
|
||||
camrotate = atoi(cv_cam_rotate.defaultvalue);
|
||||
camdist = FixedMul((INT32)(atof(cv_cam_dist.defaultvalue) * FRACUNIT), mo->scale);
|
||||
camheight = FixedMul((INT32)(atof(cv_cam_height.defaultvalue) * FRACUNIT), FixedMul(player->camerascale, mo->scale));
|
||||
camheight = FixedMul((INT32)(atof(cv_cam_height.defaultvalue) * FRACUNIT), mo->scale);
|
||||
}
|
||||
else if (thiscam == &camera)
|
||||
{
|
||||
|
@ -9680,7 +9781,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
camorbit = cv_cam_orbit.value;
|
||||
camrotate = cv_cam_rotate.value;
|
||||
camdist = FixedMul(cv_cam_dist.value, mo->scale);
|
||||
camheight = FixedMul(cv_cam_height.value, FixedMul(player->camerascale, mo->scale));
|
||||
camheight = FixedMul(cv_cam_height.value, mo->scale);
|
||||
}
|
||||
else // Camera 2
|
||||
{
|
||||
|
@ -9689,9 +9790,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
camorbit = cv_cam2_orbit.value;
|
||||
camrotate = cv_cam2_rotate.value;
|
||||
camdist = FixedMul(cv_cam2_dist.value, mo->scale);
|
||||
camheight = FixedMul(cv_cam2_height.value, FixedMul(player->camerascale, mo->scale));
|
||||
camheight = FixedMul(cv_cam2_height.value, mo->scale);
|
||||
}
|
||||
|
||||
if (!(twodlevel || (mo->flags2 & MF2_TWOD)) && !(player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
camheight = FixedMul(camheight, player->camerascale);
|
||||
|
||||
#ifdef REDSANALOG
|
||||
if (P_AnalogMove(player) && (player->cmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT)) {
|
||||
camstill = true;
|
||||
|
@ -9802,9 +9906,10 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
dist <<= 1;
|
||||
}
|
||||
|
||||
if (!(twodlevel || (mo->flags2 & MF2_TWOD)) && !(player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
dist = FixedMul(dist, player->camerascale);
|
||||
|
||||
|
||||
checkdist = (dist = FixedMul(dist, player->camerascale));
|
||||
checkdist = dist;
|
||||
|
||||
if (checkdist < 128*FRACUNIT)
|
||||
checkdist = 128*FRACUNIT;
|
||||
|
@ -9889,10 +9994,20 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
|
||||
pviewheight = FixedMul(41*player->height/48, mo->scale);
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
z = mo->z + mo->height - pviewheight - camheight + distz;
|
||||
if (sign)
|
||||
{
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
z = sign->ceilingz - pviewheight - camheight;
|
||||
else
|
||||
z = sign->floorz + pviewheight + camheight;
|
||||
}
|
||||
else
|
||||
z = mo->z + pviewheight + camheight + distz;
|
||||
{
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
z = mo->z + mo->height - pviewheight - camheight + distz;
|
||||
else
|
||||
z = mo->z + pviewheight + camheight + distz;
|
||||
}
|
||||
|
||||
// move camera down to move under lower ceilings
|
||||
newsubsec = R_IsPointInSubsector(((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1), ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1));
|
||||
|
@ -10112,17 +10227,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
if (!camstill && !resetcalled && !paused)
|
||||
thiscam->angle = R_PointToAngle2(thiscam->x, thiscam->y, viewpointx, viewpointy);
|
||||
|
||||
if (sign)
|
||||
{
|
||||
viewpointx = sign->x + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
viewpointy = sign->y + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
}
|
||||
else
|
||||
{
|
||||
viewpointx = mo->x + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
viewpointy = mo->y + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
}
|
||||
|
||||
/*
|
||||
if (twodlevel || (mo->flags2 & MF2_TWOD))
|
||||
thiscam->angle = angle;
|
||||
|
@ -10166,9 +10270,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
dist = FixedHypot(f1, f2);
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player));
|
||||
angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, (sign ? sign->ceilingz : mo->z + mo->height) - P_GetPlayerHeight(player));
|
||||
else
|
||||
angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player));
|
||||
angle = R_PointToAngle2(0, thiscam->z, dist, (sign ? sign->floorz : mo->z) + P_GetPlayerHeight(player));
|
||||
if (player->playerstate != PST_DEAD)
|
||||
angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;'
|
||||
|
||||
|
@ -10328,6 +10432,7 @@ boolean P_SpectatorJoinGame(player_t *player)
|
|||
return false;
|
||||
}
|
||||
|
||||
// the below is first person only, if you're curious. check out P_CalcChasePostImg in p_mobj.c for chasecam
|
||||
static void P_CalcPostImg(player_t *player)
|
||||
{
|
||||
sector_t *sector = player->mo->subsector->sector;
|
||||
|
@ -11400,6 +11505,14 @@ void P_PlayerThink(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
if (player->pflags & PF_FINISHED)
|
||||
{
|
||||
if ((gametype == GT_COOP && cv_exitmove.value) && !G_EnoughPlayersFinished())
|
||||
player->exiting = 0;
|
||||
else
|
||||
P_DoPlayerExit(player);
|
||||
}
|
||||
|
||||
// check water content, set stuff in mobj
|
||||
P_MobjCheckWater(player->mo);
|
||||
|
||||
|
@ -12276,7 +12389,7 @@ void P_PlayerAfterThink(player_t *player)
|
|||
player->mo->momz = tails->momz;
|
||||
}
|
||||
|
||||
if (gametype == GT_COOP)
|
||||
if (gametype == GT_COOP && (!tails->player || tails->player->bot != 1))
|
||||
{
|
||||
player->mo->angle = tails->angle;
|
||||
|
||||
|
|
100
src/r_data.c
100
src/r_data.c
|
@ -24,6 +24,7 @@
|
|||
#include "z_zone.h"
|
||||
#include "p_setup.h" // levelflats
|
||||
#include "v_video.h" // pMasterPalette
|
||||
#include "f_finale.h" // wipes
|
||||
#include "byteptr.h"
|
||||
#include "dehacked.h"
|
||||
|
||||
|
@ -113,6 +114,7 @@ INT32 *texturetranslation;
|
|||
sprcache_t *spritecachedinfo;
|
||||
|
||||
lighttable_t *colormaps;
|
||||
lighttable_t *fadecolormap;
|
||||
|
||||
// for debugging/info purposes
|
||||
size_t flatmemory, spritememory, texturememory;
|
||||
|
@ -1455,18 +1457,111 @@ static void R_InitSpriteLumps(void)
|
|||
Z_Malloc(max_spritelumps*sizeof(*spritecachedinfo), PU_STATIC, &spritecachedinfo);
|
||||
}
|
||||
|
||||
//
|
||||
// R_CreateFadeColormaps
|
||||
//
|
||||
|
||||
static void R_CreateFadeColormaps(void)
|
||||
{
|
||||
UINT8 px, fade;
|
||||
RGBA_t rgba;
|
||||
INT32 r, g, b;
|
||||
size_t len, i;
|
||||
|
||||
len = (256 * FADECOLORMAPROWS);
|
||||
fadecolormap = Z_MallocAlign(len*2, PU_STATIC, NULL, 8);
|
||||
for (i = 0; i < len*2; i++)
|
||||
fadecolormap[i] = (i%256);
|
||||
|
||||
// Load in the light tables, now 64k aligned for smokie...
|
||||
{
|
||||
lumpnum_t lump = W_CheckNumForName("FADECMAP");
|
||||
lumpnum_t wlump = W_CheckNumForName("FADEWMAP");
|
||||
|
||||
// to black
|
||||
if (lump != LUMPERROR)
|
||||
W_ReadLumpHeader(lump, fadecolormap, len, 0U);
|
||||
// to white
|
||||
if (wlump != LUMPERROR)
|
||||
W_ReadLumpHeader(wlump, fadecolormap+len, len, 0U);
|
||||
|
||||
// missing "to white" colormap lump
|
||||
if (lump != LUMPERROR && wlump == LUMPERROR)
|
||||
goto makewhite;
|
||||
// missing "to black" colormap lump
|
||||
else if (lump == LUMPERROR && wlump != LUMPERROR)
|
||||
goto makeblack;
|
||||
// both lumps found
|
||||
else if (lump != LUMPERROR && wlump != LUMPERROR)
|
||||
return;
|
||||
}
|
||||
|
||||
#define GETCOLOR \
|
||||
px = colormaps[i%256]; \
|
||||
fade = (i/256) * (256 / FADECOLORMAPROWS); \
|
||||
rgba = V_GetColor(px);
|
||||
|
||||
// to black
|
||||
makeblack:
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
// find pixel and fade amount
|
||||
GETCOLOR;
|
||||
|
||||
// subtractive color blending
|
||||
r = rgba.s.red - FADEREDFACTOR*fade/10;
|
||||
g = rgba.s.green - FADEGREENFACTOR*fade/10;
|
||||
b = rgba.s.blue - FADEBLUEFACTOR*fade/10;
|
||||
|
||||
// clamp values
|
||||
if (r < 0) r = 0;
|
||||
if (g < 0) g = 0;
|
||||
if (b < 0) b = 0;
|
||||
|
||||
// find nearest color in palette
|
||||
fadecolormap[i] = NearestColor(r,g,b);
|
||||
}
|
||||
|
||||
// to white
|
||||
makewhite:
|
||||
for (i = len; i < len*2; i++)
|
||||
{
|
||||
// find pixel and fade amount
|
||||
GETCOLOR;
|
||||
|
||||
// additive color blending
|
||||
r = rgba.s.red + FADEREDFACTOR*fade/10;
|
||||
g = rgba.s.green + FADEGREENFACTOR*fade/10;
|
||||
b = rgba.s.blue + FADEBLUEFACTOR*fade/10;
|
||||
|
||||
// clamp values
|
||||
if (r > 255) r = 255;
|
||||
if (g > 255) g = 255;
|
||||
if (b > 255) b = 255;
|
||||
|
||||
// find nearest color in palette
|
||||
fadecolormap[i] = NearestColor(r,g,b);
|
||||
}
|
||||
#undef GETCOLOR
|
||||
}
|
||||
|
||||
//
|
||||
// R_InitColormaps
|
||||
//
|
||||
static void R_InitColormaps(void)
|
||||
{
|
||||
size_t len;
|
||||
lumpnum_t lump;
|
||||
|
||||
// Load in the light tables
|
||||
lump = W_GetNumForName("COLORMAP");
|
||||
colormaps = Z_MallocAlign(W_LumpLength (lump), PU_STATIC, NULL, 8);
|
||||
len = W_LumpLength(lump);
|
||||
colormaps = Z_MallocAlign(len, PU_STATIC, NULL, 8);
|
||||
W_ReadLump(lump, colormaps);
|
||||
|
||||
// Make colormap for fades
|
||||
R_CreateFadeColormaps();
|
||||
|
||||
// Init Boom colormaps.
|
||||
R_ClearColormaps();
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
|
@ -1495,6 +1590,9 @@ void R_ReInitColormaps(UINT16 num)
|
|||
}
|
||||
|
||||
W_ReadLumpHeader(lump, colormaps, W_LumpLength(basecolormaplump), 0U);
|
||||
if (fadecolormap)
|
||||
Z_Free(fadecolormap);
|
||||
R_CreateFadeColormaps();
|
||||
|
||||
// Init Boom colormaps.
|
||||
R_ClearColormaps();
|
||||
|
|
|
@ -410,6 +410,8 @@ typedef enum
|
|||
ST_NEGATIVE
|
||||
} slopetype_t;
|
||||
|
||||
#define HORIZONSPECIAL 41
|
||||
|
||||
typedef struct line_s
|
||||
{
|
||||
// Vertices, from v1 to v2.
|
||||
|
|
|
@ -123,8 +123,12 @@ consvar_t cv_chasecam2 = {"chasecam2", "On", CV_CALL, CV_OnOff, ChaseCam2_OnChan
|
|||
consvar_t cv_flipcam = {"flipcam", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
|
||||
consvar_t cv_shadow = {"shadow", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif //#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
|
||||
#ifdef GLBADSHADOWS
|
||||
consvar_t cv_shadowoffs = {"offsetshadows", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -1172,8 +1176,12 @@ void R_RegisterEngineStuff(void)
|
|||
|
||||
CV_RegisterVar(&cv_chasecam);
|
||||
CV_RegisterVar(&cv_chasecam2);
|
||||
#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
|
||||
CV_RegisterVar(&cv_shadow);
|
||||
#endif //#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
|
||||
#ifdef GLBADSHADOWS
|
||||
CV_RegisterVar(&cv_shadowoffs);
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
CV_RegisterVar(&cv_skybox);
|
||||
|
||||
CV_RegisterVar(&cv_cam_dist);
|
||||
|
|
|
@ -76,7 +76,12 @@ extern consvar_t cv_showhud, cv_translucenthud;
|
|||
extern consvar_t cv_homremoval;
|
||||
extern consvar_t cv_chasecam, cv_chasecam2;
|
||||
extern consvar_t cv_flipcam, cv_flipcam2;
|
||||
extern consvar_t cv_shadow, cv_shadowoffs;
|
||||
#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
|
||||
extern consvar_t cv_shadow;
|
||||
#endif
|
||||
#ifdef GLBADSHADOWS
|
||||
extern conscar_t cv_shadowoffs;
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
extern consvar_t cv_translucency;
|
||||
extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip;
|
||||
extern consvar_t cv_skybox;
|
||||
|
|
|
@ -1007,6 +1007,8 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
R_CheckFlatLength(W_LumpLength(levelflat->u.flat.lumpnum));
|
||||
// Raw flats always have dimensions that are powers-of-two numbers.
|
||||
ds_powersoftwo = true;
|
||||
if (spanfunc == basespanfunc)
|
||||
spanfunc = mmxspanfunc;
|
||||
break;
|
||||
default:
|
||||
switch (type)
|
||||
|
|
|
@ -2694,7 +2694,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
worldbottomslope >>= 4;
|
||||
#endif
|
||||
|
||||
if (linedef->special == 41) { // HORIZON LINES
|
||||
if (linedef->special == HORIZONSPECIAL) { // HORIZON LINES
|
||||
topstep = bottomstep = 0;
|
||||
topfrac = bottomfrac = (centeryfrac>>4);
|
||||
topfrac++; // Prevent 1px HOM
|
||||
|
@ -2825,7 +2825,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
#ifdef ESLOPE
|
||||
ffloor[i].f_pos_slope >>= 4;
|
||||
#endif
|
||||
if (linedef->special == 41) // Horizon lines extend FOFs in contact with them too.
|
||||
if (linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too.
|
||||
{
|
||||
ffloor[i].f_step = 0;
|
||||
ffloor[i].f_frac = (centeryfrac>>4);
|
||||
|
|
|
@ -38,6 +38,7 @@ typedef struct
|
|||
extern sprcache_t *spritecachedinfo;
|
||||
|
||||
extern lighttable_t *colormaps;
|
||||
extern lighttable_t *fadecolormap;
|
||||
|
||||
// Boom colormaps.
|
||||
extern extracolormap_t *extra_colormaps;
|
||||
|
|
|
@ -1137,8 +1137,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
UINT32 rollangle = AngleFixed(arollangle)>>FRACBITS;
|
||||
#endif
|
||||
|
||||
fixed_t ang_scale = FRACUNIT;
|
||||
|
||||
// transform the origin point
|
||||
tr_x = thing->x - viewx;
|
||||
tr_y = thing->y - viewy;
|
||||
|
@ -1196,20 +1194,20 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
#ifdef ROTSPRITE
|
||||
sprinfo = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (rot >= sprdef->numframes)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"),
|
||||
sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]);
|
||||
thing->sprite = states[S_UNKNOWN].sprite;
|
||||
thing->frame = states[S_UNKNOWN].frame;
|
||||
sprdef = &sprites[thing->sprite];
|
||||
rot = thing->frame&FF_FRAMEMASK;
|
||||
if (!thing->skin)
|
||||
if (rot >= sprdef->numframes)
|
||||
{
|
||||
thing->state->sprite = thing->sprite;
|
||||
thing->state->frame = thing->frame;
|
||||
CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"),
|
||||
sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]);
|
||||
if (thing->sprite == thing->state->sprite && thing->frame == thing->state->frame)
|
||||
{
|
||||
thing->state->sprite = states[S_UNKNOWN].sprite;
|
||||
thing->state->frame = states[S_UNKNOWN].frame;
|
||||
}
|
||||
thing->sprite = states[S_UNKNOWN].sprite;
|
||||
thing->frame = states[S_UNKNOWN].frame;
|
||||
sprdef = &sprites[thing->sprite];
|
||||
rot = thing->frame&FF_FRAMEMASK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1223,8 +1221,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (sprframe->rotate != SRF_SINGLE || papersprite)
|
||||
{
|
||||
ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle);
|
||||
if (papersprite)
|
||||
ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT));
|
||||
}
|
||||
|
||||
if (sprframe->rotate == SRF_SINGLE)
|
||||
|
@ -1286,24 +1282,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
offset = -spr_offset;
|
||||
offset = FixedMul(offset, this_scale);
|
||||
tx += FixedMul(offset, ang_scale);
|
||||
x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS;
|
||||
|
||||
// off the right side?
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
offset2 = FixedMul(spr_width, this_scale);
|
||||
tx += FixedMul(offset2, ang_scale);
|
||||
x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1);
|
||||
|
||||
// off the left side
|
||||
if (x2 < 0)
|
||||
return;
|
||||
|
||||
if (papersprite)
|
||||
{
|
||||
fixed_t yscale2, cosmul, sinmul, tz2;
|
||||
fixed_t xscale2, yscale2, cosmul, sinmul, tz2;
|
||||
INT32 range;
|
||||
|
||||
if (ang >= ANGLE_180)
|
||||
|
@ -1323,6 +1306,16 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
yscale = FixedDiv(projectiony, tz);
|
||||
if (yscale < 64) return; // Fix some funky visuals
|
||||
|
||||
gxt = -FixedMul(tr_x, viewsin);
|
||||
gyt = FixedMul(tr_y, viewcos);
|
||||
tx = -(gyt + gxt);
|
||||
xscale = FixedDiv(projection, tz);
|
||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||
|
||||
// off the right side?
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
tr_x += FixedMul(offset2, cosmul);
|
||||
tr_y += FixedMul(offset2, sinmul);
|
||||
gxt = FixedMul(tr_x, viewcos);
|
||||
|
@ -1331,15 +1324,25 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
yscale2 = FixedDiv(projectiony, tz2);
|
||||
if (yscale2 < 64) return; // ditto
|
||||
|
||||
gxt = -FixedMul(tr_x, viewsin);
|
||||
gyt = FixedMul(tr_y, viewcos);
|
||||
tx = -(gyt + gxt);
|
||||
xscale2 = FixedDiv(projection, tz2);
|
||||
x2 = (centerxfrac + FixedMul(tx,xscale2))>>FRACBITS; x2--;
|
||||
|
||||
// off the left side
|
||||
if (x2 < 0)
|
||||
return;
|
||||
|
||||
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
|
||||
return;
|
||||
|
||||
if (x2 > x1)
|
||||
range = (x2 - x1);
|
||||
else
|
||||
if ((range = x2 - x1) <= 0)
|
||||
range = 1;
|
||||
|
||||
scalestep = (yscale2 - yscale)/range ?: 1;
|
||||
scalestep = (yscale2 - yscale)/range;
|
||||
scalestep = scalestep ? scalestep : 1;
|
||||
xscale = FixedDiv(range<<FRACBITS, abs(offset2))+1;
|
||||
|
||||
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
|
||||
// sortscale = max(yscale, yscale2);
|
||||
|
@ -1349,9 +1352,20 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
{
|
||||
scalestep = 0;
|
||||
yscale = sortscale;
|
||||
}
|
||||
tx += offset;
|
||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||
|
||||
xscale = FixedMul(xscale, ang_scale);
|
||||
// off the right side?
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
tx += offset2;
|
||||
x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--;
|
||||
|
||||
// off the left side
|
||||
if (x2 < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
|
||||
{
|
||||
|
|
|
@ -860,7 +860,6 @@ static INT32 actualmidimusicvolume;
|
|||
void S_UpdateSounds(void)
|
||||
{
|
||||
INT32 audible, cnum, volume, sep, pitch;
|
||||
UINT8 i;
|
||||
channel_t *c;
|
||||
|
||||
listener_t listener;
|
||||
|
@ -1017,28 +1016,30 @@ void S_UpdateSounds(void)
|
|||
|
||||
notinlevel:
|
||||
I_UpdateSound();
|
||||
}
|
||||
|
||||
void S_UpdateClosedCaptions(void)
|
||||
{
|
||||
UINT8 i;
|
||||
boolean gamestopped = (paused || P_AutoPause());
|
||||
for (i = 0; i < NUMCAPTIONS; i++) // update captions
|
||||
{
|
||||
boolean gamestopped = (paused || P_AutoPause());
|
||||
for (i = 0; i < NUMCAPTIONS; i++) // update captions
|
||||
if (!closedcaptions[i].s)
|
||||
continue;
|
||||
|
||||
if (i == 0 && (closedcaptions[0].s-S_sfx == sfx_None) && gamestopped)
|
||||
continue;
|
||||
|
||||
if (!(--closedcaptions[i].t))
|
||||
{
|
||||
if (!closedcaptions[i].s)
|
||||
continue;
|
||||
|
||||
if (i == 0 && (closedcaptions[0].s-S_sfx == sfx_None) && gamestopped)
|
||||
continue;
|
||||
|
||||
if (!(--closedcaptions[i].t))
|
||||
{
|
||||
closedcaptions[i].c = NULL;
|
||||
closedcaptions[i].s = NULL;
|
||||
}
|
||||
else if (closedcaptions[i].c && !I_SoundIsPlaying(closedcaptions[i].c->handle))
|
||||
{
|
||||
closedcaptions[i].c = NULL;
|
||||
if (closedcaptions[i].t > CAPTIONFADETICS)
|
||||
closedcaptions[i].t = CAPTIONFADETICS;
|
||||
}
|
||||
closedcaptions[i].c = NULL;
|
||||
closedcaptions[i].s = NULL;
|
||||
}
|
||||
else if (closedcaptions[i].c && !I_SoundIsPlaying(closedcaptions[i].c->handle))
|
||||
{
|
||||
closedcaptions[i].c = NULL;
|
||||
if (closedcaptions[i].t > CAPTIONFADETICS)
|
||||
closedcaptions[i].t = CAPTIONFADETICS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1685,7 +1686,7 @@ boolean S_PrepareSoundTest(void)
|
|||
soundtestdefs[pos++] = def;
|
||||
if (def->soundtestcond > 0 && !(mapvisited[def->soundtestcond-1] & MV_BEATEN))
|
||||
continue;
|
||||
if (def->soundtestcond < 0 && !M_Achieved(1-def->soundtestcond))
|
||||
if (def->soundtestcond < 0 && !M_Achieved(-1-def->soundtestcond))
|
||||
continue;
|
||||
def->allowed = true;
|
||||
}
|
||||
|
|
|
@ -303,6 +303,7 @@ boolean S_FadeOutStopMusic(UINT32 ms);
|
|||
// Updates music & sounds
|
||||
//
|
||||
void S_UpdateSounds(void);
|
||||
void S_UpdateClosedCaptions(void);
|
||||
|
||||
FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
|
||||
|
||||
|
|
15
src/screen.c
15
src/screen.c
|
@ -421,13 +421,24 @@ void SCR_DisplayTicRate(void)
|
|||
else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP;
|
||||
|
||||
V_DrawString(vid.width-(72*vid.dupx), h,
|
||||
V_YELLOWMAP|V_NOSCALESTART|V_HUDTRANS, "FPS:");
|
||||
V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:");
|
||||
V_DrawString(vid.width-(40*vid.dupx), h,
|
||||
ticcntcolor|V_NOSCALESTART|V_HUDTRANS, va("%02d/%02u", totaltics, TICRATE));
|
||||
ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d/%02u", totaltics, TICRATE));
|
||||
|
||||
lasttic = ontic;
|
||||
}
|
||||
|
||||
void SCR_DisplayLocalPing(void)
|
||||
{
|
||||
UINT32 ping = playerpingtable[consoleplayer]; // consoleplayer's ping is everyone's ping in a splitnetgame :P
|
||||
if (cv_showping.value == 1 || (cv_showping.value == 2 && servermaxping && ping > servermaxping)) // only show 2 (warning) if our ping is at a bad level
|
||||
{
|
||||
INT32 dispy = cv_ticrate.value ? 180 : 189;
|
||||
HU_drawPing(307, dispy, ping, true, V_SNAPTORIGHT | V_SNAPTOBOTTOM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCR_ClosedCaptions(void)
|
||||
{
|
||||
UINT8 i;
|
||||
|
|
|
@ -167,5 +167,6 @@ FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
|
|||
// move out to main code for consistency
|
||||
void SCR_DisplayTicRate(void);
|
||||
void SCR_ClosedCaptions(void);
|
||||
void SCR_DisplayLocalPing(void);
|
||||
#undef DNWH
|
||||
#endif //__SCREEN_H__
|
||||
|
|
|
@ -1176,11 +1176,11 @@ void I_FinishUpdate(void)
|
|||
if (cv_closedcaptioning.value)
|
||||
SCR_ClosedCaptions();
|
||||
|
||||
if (st_overlay)
|
||||
{
|
||||
if (cv_ticrate.value)
|
||||
SCR_DisplayTicRate();
|
||||
}
|
||||
if (cv_ticrate.value)
|
||||
SCR_DisplayTicRate();
|
||||
|
||||
if (cv_showping.value && netgame && consoleplayer != serverplayer)
|
||||
SCR_DisplayLocalPing();
|
||||
|
||||
if (rendermode == render_soft && screens[0])
|
||||
{
|
||||
|
|
|
@ -92,7 +92,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"pstop", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crusher stomp"},
|
||||
{"steam1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Steam jet"}, // Tails 06-19-2001
|
||||
{"steam2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Steam jet"}, // Tails 06-19-2001
|
||||
{"wbreak", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wood breaking"},
|
||||
{"wbreak", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wood breaking"},
|
||||
{"ambmac", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Machinery"},
|
||||
{"spsmsh", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy impact"},
|
||||
|
||||
|
@ -208,7 +208,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"shrpsp", true, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spincushion"},
|
||||
{"shrpgo", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Launch"},
|
||||
{"mswarp", false, 60, 16, -1, NULL, 0, -1, -1, LUMPERROR, "Spinning out"},
|
||||
{"mspogo", false, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Breaking through"},
|
||||
{"mspogo", true, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Breaking through"},
|
||||
{"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"},
|
||||
|
@ -779,7 +779,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"kc49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pop-shot"},
|
||||
{"kc4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power up"},
|
||||
{"kc4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
|
281
src/st_stuff.c
281
src/st_stuff.c
|
@ -23,6 +23,7 @@
|
|||
#include "v_video.h"
|
||||
#include "z_zone.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "console.h"
|
||||
#include "s_sound.h"
|
||||
#include "i_system.h"
|
||||
#include "m_menu.h"
|
||||
|
@ -186,14 +187,18 @@ boolean ST_SameTeam(player_t *a, player_t *b)
|
|||
|
||||
static boolean st_stopped = true;
|
||||
|
||||
void ST_Ticker(void)
|
||||
void ST_Ticker(boolean run)
|
||||
{
|
||||
if (st_stopped)
|
||||
return;
|
||||
|
||||
if (run)
|
||||
ST_runTitleCard();
|
||||
}
|
||||
|
||||
// 0 is default, any others are special palettes.
|
||||
INT32 st_palette = 0;
|
||||
INT32 st_translucency = 10;
|
||||
|
||||
void ST_doPaletteStuff(void)
|
||||
{
|
||||
|
@ -348,12 +353,12 @@ void ST_LoadGraphics(void)
|
|||
// made separate so that skins code can reload custom face graphics
|
||||
void ST_LoadFaceGraphics(INT32 skinnum)
|
||||
{
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes)
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_LIFEPIC)
|
||||
{
|
||||
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_LIFEPIC];
|
||||
faceprefix[skinnum] = W_CachePatchNum(sprframe->lumppat[0], PU_HUDGFX);
|
||||
if (skins[skinnum].sprites[(SPR2_XTRA|FF_SPR2SUPER)].numframes)
|
||||
if (skins[skinnum].sprites[(SPR2_XTRA|FF_SPR2SUPER)].numframes > XTRA_LIFEPIC)
|
||||
{
|
||||
sprdef = &skins[skinnum].sprites[SPR2_XTRA|FF_SPR2SUPER];
|
||||
sprframe = &sprdef->spriteframes[0];
|
||||
|
@ -818,7 +823,7 @@ static void ST_drawLivesArea(void)
|
|||
face = superprefix[stplyr->skin];
|
||||
V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y,
|
||||
hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, face, colormap);
|
||||
if (cv_translucenthud.value == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer)
|
||||
if (st_translucency == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer)
|
||||
{
|
||||
INT32 v_supertrans = (stplyr->mo->tracer->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
|
||||
if (v_supertrans < 10)
|
||||
|
@ -1160,16 +1165,142 @@ static void ST_drawInput(void)
|
|||
V_DrawThinString(x, y, hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!");
|
||||
}
|
||||
|
||||
void ST_drawLevelTitle(tic_t titletime)
|
||||
static patch_t *lt_patches[3];
|
||||
static INT32 lt_scroll = 0;
|
||||
static INT32 lt_mom = 0;
|
||||
static INT32 lt_zigzag = 0;
|
||||
|
||||
tic_t lt_ticker = 0, lt_lasttic = 0;
|
||||
tic_t lt_exitticker = 0, lt_endtime = 0;
|
||||
|
||||
//
|
||||
// Load the graphics for the title card.
|
||||
//
|
||||
static void ST_cacheLevelTitle(void)
|
||||
{
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE))
|
||||
{
|
||||
lt_patches[0] = (patch_t *)W_CachePatchName("LTACTBLU", PU_HUDGFX);
|
||||
lt_patches[1] = (patch_t *)W_CachePatchName("LTZIGZAG", PU_HUDGFX);
|
||||
lt_patches[2] = (patch_t *)W_CachePatchName("LTZZTEXT", PU_HUDGFX);
|
||||
}
|
||||
else // boss map
|
||||
{
|
||||
lt_patches[0] = (patch_t *)W_CachePatchName("LTACTRED", PU_HUDGFX);
|
||||
lt_patches[1] = (patch_t *)W_CachePatchName("LTZIGRED", PU_HUDGFX);
|
||||
lt_patches[2] = (patch_t *)W_CachePatchName("LTZZWARN", PU_HUDGFX);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Start the title card.
|
||||
//
|
||||
void ST_startTitleCard(void)
|
||||
{
|
||||
// cache every HUD patch used
|
||||
ST_cacheLevelTitle();
|
||||
|
||||
// initialize HUD variables
|
||||
lt_ticker = lt_exitticker = lt_lasttic = 0;
|
||||
lt_endtime = 2*TICRATE + (10*NEWTICRATERATIO);
|
||||
lt_scroll = BASEVIDWIDTH * FRACUNIT;
|
||||
lt_zigzag = -((lt_patches[1])->width * FRACUNIT);
|
||||
lt_mom = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// What happens before drawing the title card.
|
||||
// Which is just setting the HUD translucency.
|
||||
//
|
||||
void ST_preDrawTitleCard(void)
|
||||
{
|
||||
if (lt_ticker >= (lt_endtime + TICRATE))
|
||||
return;
|
||||
|
||||
if (!lt_exitticker)
|
||||
st_translucency = 0;
|
||||
else
|
||||
st_translucency = max(0, min((INT32)lt_exitticker-4, cv_translucenthud.value));
|
||||
}
|
||||
|
||||
//
|
||||
// Run the title card.
|
||||
// Called from ST_Ticker.
|
||||
//
|
||||
void ST_runTitleCard(void)
|
||||
{
|
||||
if (lt_ticker >= (lt_endtime + TICRATE))
|
||||
return;
|
||||
|
||||
if (!(paused || P_AutoPause()))
|
||||
{
|
||||
// tick
|
||||
lt_ticker++;
|
||||
if (lt_ticker >= lt_endtime)
|
||||
lt_exitticker++;
|
||||
|
||||
// scroll to screen (level title)
|
||||
if (!lt_exitticker)
|
||||
{
|
||||
if (abs(lt_scroll) > FRACUNIT)
|
||||
lt_scroll -= (lt_scroll>>2);
|
||||
else
|
||||
lt_scroll = 0;
|
||||
}
|
||||
// scroll away from screen (level title)
|
||||
else
|
||||
{
|
||||
lt_mom -= FRACUNIT*6;
|
||||
lt_scroll += lt_mom;
|
||||
}
|
||||
|
||||
// scroll to screen (zigzag)
|
||||
if (!lt_exitticker)
|
||||
{
|
||||
if (abs(lt_zigzag) > FRACUNIT)
|
||||
lt_zigzag -= (lt_zigzag>>2);
|
||||
else
|
||||
lt_zigzag = 0;
|
||||
}
|
||||
// scroll away from screen (zigzag)
|
||||
else
|
||||
lt_zigzag += lt_mom;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Draw the title card itself.
|
||||
//
|
||||
void ST_drawTitleCard(void)
|
||||
{
|
||||
char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl;
|
||||
char *subttl = mapheaderinfo[gamemap-1]->subttl;
|
||||
INT32 actnum = mapheaderinfo[gamemap-1]->actnum;
|
||||
INT32 lvlttly, zoney, lvlttlxpos, ttlnumxpos, zonexpos;
|
||||
INT32 lvlttlxpos, ttlnumxpos, zonexpos;
|
||||
INT32 subttlxpos = BASEVIDWIDTH/2;
|
||||
INT32 ttlscroll = FixedInt(lt_scroll);
|
||||
INT32 zzticker;
|
||||
patch_t *actpat, *zigzag, *zztext;
|
||||
|
||||
if (!(titletime > 2 && titletime-3 < 110))
|
||||
#ifdef HAVE_BLUA
|
||||
if (!LUA_HudEnabled(hud_stagetitle))
|
||||
goto luahook;
|
||||
#endif
|
||||
|
||||
if (lt_ticker >= (lt_endtime + TICRATE))
|
||||
#ifdef HAVE_BLUA
|
||||
goto luahook;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
if ((lt_ticker-lt_lasttic) > 1)
|
||||
lt_ticker = lt_lasttic+1;
|
||||
|
||||
ST_cacheLevelTitle();
|
||||
actpat = lt_patches[0];
|
||||
zigzag = lt_patches[1];
|
||||
zztext = lt_patches[2];
|
||||
|
||||
lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2));
|
||||
|
||||
|
@ -1177,72 +1308,71 @@ void ST_drawLevelTitle(tic_t titletime)
|
|||
lvlttlxpos -= V_LevelActNumWidth(actnum);
|
||||
|
||||
ttlnumxpos = lvlttlxpos + V_LevelNameWidth(lvlttl);
|
||||
zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("ZONE"));
|
||||
zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("Zone"));
|
||||
ttlnumxpos++;
|
||||
|
||||
if (lvlttlxpos < 0)
|
||||
lvlttlxpos = 0;
|
||||
|
||||
#if 0 // toaster's experiment. srb2&toast.exe one day, maybe? Requires stuff below to be converted to fixed point.
|
||||
#define MIDTTLY 79
|
||||
#define MIDZONEY 105
|
||||
#define MIDDIFF 4
|
||||
|
||||
if (titletime < 10)
|
||||
if (!splitscreen || (splitscreen && stplyr == &players[displayplayer]))
|
||||
{
|
||||
fixed_t z = ((titletime - 3)<<FRACBITS)/7;
|
||||
INT32 ttlh = V_LevelNameHeight(lvlttl);
|
||||
zoney = (200<<FRACBITS) - ((200 - (MIDZONEY + MIDDIFF))*z);
|
||||
lvlttly = ((MIDTTLY + ttlh - MIDDIFF)*z) - (ttlh<<FRACBITS);
|
||||
zzticker = lt_ticker;
|
||||
V_DrawScaledPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag);
|
||||
V_DrawScaledPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag);
|
||||
V_DrawScaledPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext);
|
||||
V_DrawScaledPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext);
|
||||
}
|
||||
else if (titletime < 105)
|
||||
{
|
||||
fixed_t z = (((titletime - 10)*MIDDIFF)<<(FRACBITS+1))/95;
|
||||
zoney = ((MIDZONEY + MIDDIFF)<<FRACBITS) - z;
|
||||
lvlttly = ((MIDTTLY - MIDDIFF)<<FRACBITS) + z;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t z = ((titletime - 105)<<FRACBITS)/7;
|
||||
INT32 zoneh = V_LevelNameHeight(M_GetText("ZONE"));
|
||||
zoney = (MIDZONEY + zoneh - MIDDIFF)*(FRACUNIT - z) - (zoneh<<FRACBITS);
|
||||
lvlttly = ((MIDTTLY + MIDDIFF)<<FRACBITS) + ((200 - (MIDTTLY + MIDDIFF))*z);
|
||||
}
|
||||
|
||||
#undef MIDTTLY
|
||||
#undef MIDZONEY
|
||||
#undef MIDDIFF
|
||||
#else
|
||||
// There's no consistent algorithm that can accurately define the old positions
|
||||
// so I just ended up resorting to a single switch statement to define them
|
||||
switch (titletime-3)
|
||||
{
|
||||
case 0: zoney = 200; lvlttly = 0; break;
|
||||
case 1: zoney = 188; lvlttly = 12; break;
|
||||
case 2: zoney = 176; lvlttly = 24; break;
|
||||
case 3: zoney = 164; lvlttly = 36; break;
|
||||
case 4: zoney = 152; lvlttly = 48; break;
|
||||
case 5: zoney = 140; lvlttly = 60; break;
|
||||
case 6: zoney = 128; lvlttly = 72; break;
|
||||
case 105: zoney = 80; lvlttly = 104; break;
|
||||
case 106: zoney = 56; lvlttly = 128; break;
|
||||
case 107: zoney = 32; lvlttly = 152; break;
|
||||
case 108: zoney = 8; lvlttly = 176; break;
|
||||
case 109: zoney = 0; lvlttly = 200; break;
|
||||
default: zoney = 104; lvlttly = 80; break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (actnum)
|
||||
V_DrawLevelActNum(ttlnumxpos, zoney, V_PERPLAYER, actnum);
|
||||
|
||||
V_DrawLevelTitle(lvlttlxpos, lvlttly, V_PERPLAYER, lvlttl);
|
||||
{
|
||||
if (!splitscreen)
|
||||
V_DrawScaledPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat);
|
||||
V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum);
|
||||
}
|
||||
|
||||
V_DrawLevelTitle(lvlttlxpos - ttlscroll, 80, V_PERPLAYER, lvlttl);
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||
V_DrawLevelTitle(zonexpos, zoney, V_PERPLAYER, M_GetText("ZONE"));
|
||||
V_DrawLevelTitle(zonexpos + ttlscroll, 104, V_PERPLAYER, M_GetText("Zone"));
|
||||
V_DrawCenteredString(subttlxpos - ttlscroll, 135, V_PERPLAYER|V_ALLOWLOWERCASE, subttl);
|
||||
|
||||
if (lvlttly+48 < 200)
|
||||
V_DrawCenteredString(subttlxpos, lvlttly+48, V_PERPLAYER|V_ALLOWLOWERCASE, subttl);
|
||||
lt_lasttic = lt_ticker;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
luahook:
|
||||
LUAh_TitleCardHUD(stplyr);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Drawer for G_PreLevelTitleCard.
|
||||
//
|
||||
void ST_preLevelTitleCardDrawer(tic_t ticker, boolean update)
|
||||
{
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
|
||||
if (ticker < PRELEVELTIME-1)
|
||||
ST_drawWipeTitleCard();
|
||||
|
||||
I_OsPolling();
|
||||
I_UpdateNoBlit();
|
||||
if (update)
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
}
|
||||
|
||||
//
|
||||
// Draw the title card while on a wipe.
|
||||
// Also used in G_PreLevelTitleCard.
|
||||
//
|
||||
void ST_drawWipeTitleCard(void)
|
||||
{
|
||||
stplyr = &players[consoleplayer];
|
||||
ST_preDrawTitleCard();
|
||||
ST_drawTitleCard();
|
||||
if (splitscreen)
|
||||
{
|
||||
stplyr = &players[secondarydisplayplayer];
|
||||
ST_preDrawTitleCard();
|
||||
ST_drawTitleCard();
|
||||
}
|
||||
}
|
||||
|
||||
static void ST_drawPowerupHUD(void)
|
||||
|
@ -2106,7 +2236,7 @@ static void ST_drawTextHUD(void)
|
|||
textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game"))
|
||||
}
|
||||
|
||||
if (gametype == GT_COOP && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && stplyr->exiting)
|
||||
if (gametype == GT_COOP && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && (stplyr->exiting || (stplyr->pflags & PF_FINISHED)))
|
||||
{
|
||||
UINT8 numneeded = (G_IsSpecialStage(gamemap) ? 4 : cv_playersforexit.value);
|
||||
if (numneeded)
|
||||
|
@ -2121,7 +2251,7 @@ static void ST_drawTextHUD(void)
|
|||
continue;
|
||||
|
||||
total++;
|
||||
if (players[i].exiting)
|
||||
if (players[i].exiting || (players[i].pflags & PF_FINISHED))
|
||||
exiting++;
|
||||
}
|
||||
|
||||
|
@ -2394,12 +2524,25 @@ static void ST_doItemFinderIconsAndSound(void)
|
|||
S_StartSound(NULL, sfx_emfind);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw the status bar overlay, customisable: the user chooses which
|
||||
// kind of information to overlay
|
||||
//
|
||||
static void ST_overlayDrawer(void)
|
||||
{
|
||||
//hu_showscores = auto hide score/time/rings when tab rankings are shown
|
||||
// Decide whether to draw the stage title or not
|
||||
boolean stagetitle = false;
|
||||
|
||||
// Check for a valid level title
|
||||
// If the HUD is enabled
|
||||
// And, if Lua is running, if the HUD library has the stage title enabled
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD) && *mapheaderinfo[gamemap-1]->lvlttl != '\0' && !(hu_showscores && (netgame || multiplayer)))
|
||||
{
|
||||
stagetitle = true;
|
||||
ST_preDrawTitleCard();
|
||||
}
|
||||
|
||||
// hu_showscores = auto hide score/time/rings when tab rankings are shown
|
||||
if (!(hu_showscores && (netgame || multiplayer)))
|
||||
{
|
||||
if ((maptol & TOL_NIGHTS || G_IsSpecialStage(gamemap)) &&
|
||||
|
@ -2550,12 +2693,8 @@ static void ST_overlayDrawer(void)
|
|||
#endif
|
||||
|
||||
// draw level title Tails
|
||||
if (*mapheaderinfo[gamemap-1]->lvlttl != '\0' && !(hu_showscores && (netgame || multiplayer))
|
||||
#ifdef HAVE_BLUA
|
||||
&& LUA_HudEnabled(hud_stagetitle)
|
||||
#endif
|
||||
)
|
||||
ST_drawLevelTitle(timeinmap+70);
|
||||
if (stagetitle && (!WipeInAction) && (!WipeStageTitle))
|
||||
ST_drawTitleCard();
|
||||
|
||||
if (!hu_showscores && (netgame || multiplayer)
|
||||
#ifdef HAVE_BLUA
|
||||
|
@ -2631,6 +2770,8 @@ void ST_Drawer(void)
|
|||
}
|
||||
}
|
||||
|
||||
st_translucency = cv_translucenthud.value;
|
||||
|
||||
if (st_overlay)
|
||||
{
|
||||
// No deadview!
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
//
|
||||
|
||||
// Called by main loop.
|
||||
void ST_Ticker(void);
|
||||
void ST_Ticker(boolean run);
|
||||
|
||||
// Called by main loop.
|
||||
void ST_Drawer(void);
|
||||
|
@ -47,8 +47,16 @@ void ST_ReloadSkinFaceGraphics(void);
|
|||
|
||||
void ST_doPaletteStuff(void);
|
||||
|
||||
// level title draw
|
||||
void ST_drawLevelTitle(tic_t titletime);
|
||||
// title card
|
||||
void ST_startTitleCard(void);
|
||||
void ST_runTitleCard(void);
|
||||
void ST_drawTitleCard(void);
|
||||
void ST_preDrawTitleCard(void);
|
||||
void ST_preLevelTitleCardDrawer(tic_t ticker, boolean update);
|
||||
void ST_drawWipeTitleCard(void);
|
||||
|
||||
extern tic_t lt_ticker, lt_lasttic;
|
||||
extern tic_t lt_exitticker, lt_endtime;
|
||||
|
||||
// return if player a is in the same team as player b
|
||||
boolean ST_SameTeam(player_t *a, player_t *b);
|
||||
|
@ -59,6 +67,7 @@ boolean ST_SameTeam(player_t *a, player_t *b);
|
|||
|
||||
extern boolean st_overlay; // sb overlay on or off when fullscreen
|
||||
extern INT32 st_palette; // 0 is default, any others are special palettes.
|
||||
extern INT32 st_translucency;
|
||||
|
||||
extern lumpnum_t st_borderpatchnum;
|
||||
// patches, also used in intermission
|
||||
|
|
|
@ -75,7 +75,7 @@ strcasestr (const char *s, const char *q)
|
|||
if (!( (intptr_t)up|(intptr_t)lp ))
|
||||
return 0;
|
||||
|
||||
if (!lp || up < lp)
|
||||
if (!lp || ( up && up < lp ))
|
||||
{
|
||||
ppa = &up;
|
||||
ppb = &lp;
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
#include "p_local.h" // stplyr
|
||||
#include "g_game.h" // players
|
||||
#include "v_video.h"
|
||||
#include "st_stuff.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "f_finale.h"
|
||||
#include "r_draw.h"
|
||||
#include "console.h"
|
||||
|
||||
|
@ -574,11 +576,11 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
|
|||
if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT)))
|
||||
{
|
||||
if (alphalevel == 13)
|
||||
alphalevel = hudminusalpha[cv_translucenthud.value];
|
||||
alphalevel = hudminusalpha[st_translucency];
|
||||
else if (alphalevel == 14)
|
||||
alphalevel = 10 - cv_translucenthud.value;
|
||||
alphalevel = 10 - st_translucency;
|
||||
else if (alphalevel == 15)
|
||||
alphalevel = hudplusalpha[cv_translucenthud.value];
|
||||
alphalevel = hudplusalpha[st_translucency];
|
||||
|
||||
if (alphalevel >= 10)
|
||||
return; // invis
|
||||
|
@ -874,11 +876,11 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
|
|||
if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT)))
|
||||
{
|
||||
if (alphalevel == 13)
|
||||
alphalevel = hudminusalpha[cv_translucenthud.value];
|
||||
alphalevel = hudminusalpha[st_translucency];
|
||||
else if (alphalevel == 14)
|
||||
alphalevel = 10 - cv_translucenthud.value;
|
||||
alphalevel = 10 - st_translucency;
|
||||
else if (alphalevel == 15)
|
||||
alphalevel = hudplusalpha[cv_translucenthud.value];
|
||||
alphalevel = hudplusalpha[st_translucency];
|
||||
|
||||
if (alphalevel >= 10)
|
||||
return; // invis
|
||||
|
@ -1074,7 +1076,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
|
|||
//
|
||||
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
|
||||
{
|
||||
if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes >= 4)
|
||||
if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_CONTINUE)
|
||||
{
|
||||
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CONTINUE];
|
||||
|
@ -1393,11 +1395,11 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
|||
if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT)))
|
||||
{
|
||||
if (alphalevel == 13)
|
||||
alphalevel = hudminusalpha[cv_translucenthud.value];
|
||||
alphalevel = hudminusalpha[st_translucency];
|
||||
else if (alphalevel == 14)
|
||||
alphalevel = 10 - cv_translucenthud.value;
|
||||
alphalevel = 10 - st_translucency;
|
||||
else if (alphalevel == 15)
|
||||
alphalevel = hudplusalpha[cv_translucenthud.value];
|
||||
alphalevel = hudplusalpha[st_translucency];
|
||||
|
||||
if (alphalevel >= 10)
|
||||
return; // invis
|
||||
|
@ -1860,7 +1862,9 @@ void V_DrawFadeScreen(UINT16 color, UINT8 strength)
|
|||
|
||||
{
|
||||
const UINT8 *fadetable = ((color & 0xFF00) // Color is not palette index?
|
||||
? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade.
|
||||
? ((UINT8 *)(((color & 0x0F00) == 0x0A00) ? fadecolormap // Do fadecolormap fade.
|
||||
: (((color & 0x0F00) == 0x0B00) ? fadecolormap + (256 * FADECOLORMAPROWS) // Do white fadecolormap fade.
|
||||
: colormaps)) + strength*256) // Do COLORMAP fade.
|
||||
: ((UINT8 *)transtables + ((9-strength)<<FF_TRANSSHIFT) + color*256)); // Else, do TRANSMAP** fade.
|
||||
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
UINT8 *buf = screens[0];
|
||||
|
@ -1898,14 +1902,15 @@ void V_DrawPromptBack(INT32 boxheight, INT32 color)
|
|||
{
|
||||
UINT8 *deststop, *buf;
|
||||
|
||||
boxheight = ((boxheight * 4) + (boxheight/2)*5);
|
||||
|
||||
if (color >= 256 && color < 512)
|
||||
{
|
||||
boxheight = ((boxheight * 4) + (boxheight/2)*5);
|
||||
V_DrawFill((BASEVIDWIDTH-(vid.width/vid.dupx))/2, BASEVIDHEIGHT-boxheight, (vid.width/vid.dupx),boxheight, (color-256)|V_SNAPTOBOTTOM);
|
||||
return;
|
||||
}
|
||||
|
||||
boxheight *= vid.dupy;
|
||||
|
||||
if (color == INT32_MAX)
|
||||
color = cons_backcolor.value;
|
||||
|
||||
|
@ -1947,7 +1952,7 @@ void V_DrawPromptBack(INT32 boxheight, INT32 color)
|
|||
// heavily simplified -- we don't need to know x or y position,
|
||||
// just the start and stop positions
|
||||
deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
buf = deststop - vid.rowbytes * boxheight * vid.dupy; // 4 lines of space plus gaps between and some leeway
|
||||
buf = deststop - vid.rowbytes * ((boxheight * 4) + (boxheight/2)*5); // 4 lines of space plus gaps between and some leeway
|
||||
for (; buf < deststop; ++buf)
|
||||
*buf = promptbgmap[*buf];
|
||||
}
|
||||
|
@ -2899,7 +2904,7 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string)
|
|||
continue;
|
||||
}
|
||||
|
||||
c = toupper(*ch) - LT_FONTSTART;
|
||||
c = *ch - LT_FONTSTART;
|
||||
if (c < 0 || c >= LT_FONTSIZE || !lt_font[c])
|
||||
{
|
||||
cx += 16*dupx;
|
||||
|
@ -2934,7 +2939,7 @@ INT32 V_LevelNameWidth(const char *string)
|
|||
{
|
||||
if (string[i] & 0x80)
|
||||
continue;
|
||||
c = toupper(string[i]) - LT_FONTSTART;
|
||||
c = string[i] - LT_FONTSTART;
|
||||
if (c < 0 || c >= LT_FONTSIZE || !lt_font[c])
|
||||
w += 16;
|
||||
else
|
||||
|
@ -2953,7 +2958,7 @@ INT32 V_LevelNameHeight(const char *string)
|
|||
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
c = toupper(string[i]) - LT_FONTSTART;
|
||||
c = string[i] - LT_FONTSTART;
|
||||
if (c < 0 || c >= LT_FONTSIZE || !lt_font[c])
|
||||
continue;
|
||||
|
||||
|
@ -2964,7 +2969,7 @@ INT32 V_LevelNameHeight(const char *string)
|
|||
return w;
|
||||
}
|
||||
|
||||
// For ST_drawLevelTitle
|
||||
// For ST_drawTitleCard
|
||||
// Returns the width of the act num patch
|
||||
INT32 V_LevelActNumWidth(INT32 num)
|
||||
{
|
||||
|
|
|
@ -106,6 +106,10 @@ extern RGBA_t *pMasterPalette;
|
|||
#define V_HUDTRANSHALF 0x000D0000
|
||||
#define V_HUDTRANS 0x000E0000 // draw the hud translucent
|
||||
#define V_HUDTRANSDOUBLE 0x000F0000
|
||||
// Macros follow
|
||||
#define V_USERHUDTRANSHALF ((10-(cv_translucenthud.value/2))<<V_ALPHASHIFT)
|
||||
#define V_USERHUDTRANS ((10-cv_translucenthud.value)<<V_ALPHASHIFT)
|
||||
#define V_USERHUDTRANSDOUBLE ((10-min(cv_translucenthud.value*2, 10))<<V_ALPHASHIFT)
|
||||
|
||||
#define V_AUTOFADEOUT 0x00100000 // used by CECHOs, automatic fade out when almost over
|
||||
#define V_RETURN8 0x00200000 // 8 pixel return instead of 12
|
||||
|
|
12
src/w_wad.c
12
src/w_wad.c
|
@ -383,7 +383,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
|
|||
// read the header
|
||||
if (fread(&header, 1, sizeof header, handle) < sizeof header)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't read wad header because %s\n"), strerror(ferror(handle)));
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't read wad header because %s\n"), M_FileError(handle));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -406,7 +406,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
|
|||
if (fseek(handle, header.infotableofs, SEEK_SET) == -1
|
||||
|| fread(fileinfo, 1, i, handle) < i)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Corrupt wadfile directory (%s)\n"), strerror(ferror(handle)));
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Corrupt wadfile directory (%s)\n"), M_FileError(handle));
|
||||
free(fileinfov);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
|
|||
handle) < sizeof realsize)
|
||||
{
|
||||
I_Error("corrupt compressed file: %s; maybe %s", /// \todo Avoid the bailout?
|
||||
filename, strerror(ferror(handle)));
|
||||
filename, M_FileError(handle));
|
||||
}
|
||||
realsize = LONG(realsize);
|
||||
if (realsize != 0)
|
||||
|
@ -565,7 +565,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
|
|||
fseek(handle, -4, SEEK_CUR);
|
||||
if (fread(&zend, 1, sizeof zend, handle) < sizeof zend)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Corrupt central directory (%s)\n", strerror(ferror(handle)));
|
||||
CONS_Alert(CONS_ERROR, "Corrupt central directory (%s)\n", M_FileError(handle));
|
||||
return NULL;
|
||||
}
|
||||
numlumps = zend.entries;
|
||||
|
@ -582,7 +582,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
|
|||
|
||||
if (fread(zentry, 1, sizeof(zentry_t), handle) < sizeof(zentry_t))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Failed to read central directory (%s)\n", strerror(ferror(handle)));
|
||||
CONS_Alert(CONS_ERROR, "Failed to read central directory (%s)\n", M_FileError(handle));
|
||||
Z_Free(lumpinfo);
|
||||
free(zentries);
|
||||
return NULL;
|
||||
|
@ -602,7 +602,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
|
|||
fullname = malloc(zentry->namelen + 1);
|
||||
if (fgets(fullname, zentry->namelen + 1, handle) != fullname)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Unable to read lumpname (%s)\n", strerror(ferror(handle)));
|
||||
CONS_Alert(CONS_ERROR, "Unable to read lumpname (%s)\n", M_FileError(handle));
|
||||
Z_Free(lumpinfo);
|
||||
free(zentries);
|
||||
free(fullname);
|
||||
|
|
|
@ -371,6 +371,9 @@ void I_FinishUpdate(void)
|
|||
if (cv_ticrate.value)
|
||||
SCR_DisplayTicRate();
|
||||
|
||||
if (cv_showping.value && netgame && consoleplayer != serverplayer)
|
||||
SCR_DisplayLocalPing();
|
||||
|
||||
//
|
||||
if (bDIBMode)
|
||||
{
|
||||
|
|
251
src/y_inter.c
251
src/y_inter.c
|
@ -166,13 +166,11 @@ static INT32 endtic = -1;
|
|||
intertype_t intertype = int_none;
|
||||
|
||||
static void Y_RescaleScreenBuffer(void);
|
||||
static void Y_CleanupScreenBuffer(void);
|
||||
static void Y_AwardCoopBonuses(void);
|
||||
static void Y_AwardSpecialStageBonus(void);
|
||||
static void Y_CalculateCompetitionWinners(void);
|
||||
static void Y_CalculateTimeRaceWinners(void);
|
||||
static void Y_CalculateMatchWinners(void);
|
||||
static void Y_FollowIntermission(void);
|
||||
static void Y_UnloadData(void);
|
||||
|
||||
// Stuff copy+pasted from st_stuff.c
|
||||
|
@ -293,7 +291,7 @@ static void Y_RescaleScreenBuffer(void)
|
|||
//
|
||||
// Free all related memory.
|
||||
//
|
||||
static void Y_CleanupScreenBuffer(void)
|
||||
void Y_CleanupScreenBuffer(void)
|
||||
{
|
||||
// Who knows?
|
||||
if (y_buffer == NULL)
|
||||
|
@ -399,10 +397,13 @@ void Y_IntermissionDrawer(void)
|
|||
|
||||
// draw the "got through act" lines and act number
|
||||
V_DrawLevelTitle(data.coop.passedx1, 49, 0, data.coop.passed1);
|
||||
V_DrawLevelTitle(data.coop.passedx2, 49+V_LevelNameHeight(data.coop.passed2)+2, 0, data.coop.passed2);
|
||||
{
|
||||
INT32 h = V_LevelNameHeight(data.coop.passed2);
|
||||
V_DrawLevelTitle(data.coop.passedx2, 49+h+2, 0, data.coop.passed2);
|
||||
|
||||
if (data.coop.actnum)
|
||||
V_DrawLevelActNum(244, 57, 0, data.coop.actnum);
|
||||
if (data.coop.actnum)
|
||||
V_DrawLevelActNum(244, 42+h, 0, data.coop.actnum);
|
||||
}
|
||||
|
||||
bonusy = 150;
|
||||
// Total
|
||||
|
@ -485,10 +486,10 @@ void Y_IntermissionDrawer(void)
|
|||
|
||||
if (drawsection == 1)
|
||||
{
|
||||
const char *ringtext = "\x82" "50 RINGS, NO SHIELD";
|
||||
const char *tut1text = "\x82" "PRESS " "\x80" "SPIN";
|
||||
const char *tut2text = "\x82" "MID-" "\x80" "JUMP";
|
||||
ttheight = 16;
|
||||
const char *ringtext = "\x82" "50 rings, no shield";
|
||||
const char *tut1text = "\x82" "press " "\x80" "spin";
|
||||
const char *tut2text = "\x82" "mid-" "\x80" "jump";
|
||||
ttheight = 8;
|
||||
V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
|
||||
ttheight += V_LevelNameHeight(data.spec.passed3) + 2;
|
||||
V_DrawLevelTitle(data.spec.passedx3 + xoffset2, ttheight, 0, data.spec.passed3);
|
||||
|
@ -497,9 +498,9 @@ void Y_IntermissionDrawer(void)
|
|||
|
||||
ttheight = 108;
|
||||
V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset4 - (V_LevelNameWidth(ringtext)/2), ttheight, 0, ringtext);
|
||||
ttheight += V_LevelNameHeight(ringtext) + 2;
|
||||
V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset5 - (V_LevelNameWidth(tut1text)/2), ttheight, 0, tut1text);
|
||||
ttheight += V_LevelNameHeight(tut1text) + 2;
|
||||
V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset5 - (V_LevelNameWidth(tut1text)/2), ttheight, 0, tut1text);
|
||||
ttheight += V_LevelNameHeight(tut2text) + 2;
|
||||
V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset6 - (V_LevelNameWidth(tut2text)/2), ttheight, 0, tut2text);
|
||||
}
|
||||
else
|
||||
|
@ -816,7 +817,7 @@ void Y_IntermissionDrawer(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (intertype == int_classicrace)
|
||||
else if (intertype == int_comp)
|
||||
{
|
||||
INT32 x = 4;
|
||||
INT32 y = 48;
|
||||
|
@ -950,7 +951,7 @@ void Y_Ticker(void)
|
|||
if (!--timer)
|
||||
{
|
||||
Y_EndIntermission();
|
||||
Y_FollowIntermission();
|
||||
G_AfterIntermission();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -958,7 +959,7 @@ void Y_Ticker(void)
|
|||
else if (intertic == endtic)
|
||||
{
|
||||
Y_EndIntermission();
|
||||
Y_FollowIntermission();
|
||||
G_AfterIntermission();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1142,7 +1143,7 @@ void Y_Ticker(void)
|
|||
if (data.match.numplayers != D_NumPlayers())
|
||||
Y_CalculateMatchWinners();
|
||||
}
|
||||
else if (intertype == int_race || intertype == int_classicrace) // race
|
||||
else if (intertype == int_race || intertype == int_comp) // race
|
||||
{
|
||||
if (!intertic) // first time only
|
||||
S_ChangeMusicInternal("_inter", true); // loop it
|
||||
|
@ -1151,96 +1152,6 @@ void Y_Ticker(void)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Y_UpdateRecordReplays
|
||||
//
|
||||
// Update replay files/data, etc. for Record Attack
|
||||
// See G_SetNightsRecords for NiGHTS Attack.
|
||||
//
|
||||
static void Y_UpdateRecordReplays(void)
|
||||
{
|
||||
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
|
||||
char *gpath;
|
||||
char lastdemo[256], bestdemo[256];
|
||||
UINT8 earnedEmblems;
|
||||
|
||||
// Record new best time
|
||||
if (!mainrecords[gamemap-1])
|
||||
G_AllocMainRecordData(gamemap-1);
|
||||
|
||||
if (players[consoleplayer].score > mainrecords[gamemap-1]->score)
|
||||
mainrecords[gamemap-1]->score = players[consoleplayer].score;
|
||||
|
||||
if ((mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < mainrecords[gamemap-1]->time))
|
||||
mainrecords[gamemap-1]->time = players[consoleplayer].realtime;
|
||||
|
||||
if ((UINT16)(players[consoleplayer].rings) > mainrecords[gamemap-1]->rings)
|
||||
mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings);
|
||||
|
||||
if (data.coop.gotperfbonus)
|
||||
mainrecords[gamemap-1]->gotperfect = true;
|
||||
|
||||
// Save demo!
|
||||
bestdemo[255] = '\0';
|
||||
lastdemo[255] = '\0';
|
||||
G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].rings));
|
||||
G_CheckDemoStatus();
|
||||
|
||||
I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
|
||||
I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755);
|
||||
|
||||
if ((gpath = malloc(glen)) == NULL)
|
||||
I_Error("Out of memory for replay filepath\n");
|
||||
|
||||
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
|
||||
snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name);
|
||||
|
||||
if (FIL_FileExists(lastdemo))
|
||||
{
|
||||
UINT8 *buf;
|
||||
size_t len = FIL_ReadFile(lastdemo, &buf);
|
||||
|
||||
snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
|
||||
if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1)
|
||||
{ // Better time, save this demo.
|
||||
if (FIL_FileExists(bestdemo))
|
||||
remove(bestdemo);
|
||||
FIL_WriteFile(bestdemo, buf, len);
|
||||
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo);
|
||||
}
|
||||
|
||||
snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
|
||||
if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1)))
|
||||
{ // Better score, save this demo.
|
||||
if (FIL_FileExists(bestdemo))
|
||||
remove(bestdemo);
|
||||
FIL_WriteFile(bestdemo, buf, len);
|
||||
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW HIGH SCORE!"), M_GetText("Saved replay as"), bestdemo);
|
||||
}
|
||||
|
||||
snprintf(bestdemo, 255, "%s-%s-rings-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
|
||||
if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<2)))
|
||||
{ // Better rings, save this demo.
|
||||
if (FIL_FileExists(bestdemo))
|
||||
remove(bestdemo);
|
||||
FIL_WriteFile(bestdemo, buf, len);
|
||||
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW MOST RINGS!"), M_GetText("Saved replay as"), bestdemo);
|
||||
}
|
||||
|
||||
//CONS_Printf("%s '%s'\n", M_GetText("Saved replay as"), lastdemo);
|
||||
|
||||
Z_Free(buf);
|
||||
}
|
||||
free(gpath);
|
||||
|
||||
// Check emblems when level data is updated
|
||||
if ((earnedEmblems = M_CheckLevelEmblems()))
|
||||
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for Record Attack records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
|
||||
|
||||
// Update timeattack menu's replay availability.
|
||||
Nextmap_OnChange();
|
||||
}
|
||||
|
||||
//
|
||||
// Y_StartIntermission
|
||||
//
|
||||
|
@ -1249,7 +1160,6 @@ static void Y_UpdateRecordReplays(void)
|
|||
void Y_StartIntermission(void)
|
||||
{
|
||||
INT32 i;
|
||||
UINT8 completionEmblems = M_CompletionEmblems();
|
||||
|
||||
intertic = -1;
|
||||
|
||||
|
@ -1262,10 +1172,7 @@ void Y_StartIntermission(void)
|
|||
{
|
||||
timer = 0;
|
||||
|
||||
if (G_IsSpecialStage(gamemap))
|
||||
intertype = (maptol & TOL_NIGHTS) ? int_nightsspec : int_spec;
|
||||
else
|
||||
intertype = (maptol & TOL_NIGHTS) ? int_nights : int_coop;
|
||||
intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1280,14 +1187,7 @@ void Y_StartIntermission(void)
|
|||
}
|
||||
|
||||
if (gametype == GT_COOP)
|
||||
{
|
||||
// Nights intermission is single player only
|
||||
// Don't add it here
|
||||
if (G_IsSpecialStage(gamemap))
|
||||
intertype = int_spec;
|
||||
else
|
||||
intertype = int_coop;
|
||||
}
|
||||
intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop;
|
||||
else if (gametype == GT_TEAMMATCH)
|
||||
intertype = int_teammatch;
|
||||
else if (gametype == GT_MATCH
|
||||
|
@ -1297,7 +1197,7 @@ void Y_StartIntermission(void)
|
|||
else if (gametype == GT_RACE)
|
||||
intertype = int_race;
|
||||
else if (gametype == GT_COMPETITION)
|
||||
intertype = int_classicrace;
|
||||
intertype = int_comp;
|
||||
else if (gametype == GT_CTF)
|
||||
intertype = int_ctf;
|
||||
}
|
||||
|
@ -1312,20 +1212,6 @@ void Y_StartIntermission(void)
|
|||
|
||||
switch (intertype)
|
||||
{
|
||||
case int_nights:
|
||||
// Can't fail
|
||||
G_SetNightsRecords();
|
||||
|
||||
// Check records
|
||||
{
|
||||
UINT8 earnedEmblems = M_CheckLevelEmblems();
|
||||
if (earnedEmblems)
|
||||
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for NiGHTS records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
|
||||
}
|
||||
|
||||
// fall back into the coop intermission for now
|
||||
intertype = int_coop;
|
||||
/* FALLTHRU */
|
||||
case int_coop: // coop or single player, normal level
|
||||
{
|
||||
// award time and ring bonuses
|
||||
|
@ -1334,24 +1220,6 @@ void Y_StartIntermission(void)
|
|||
// setup time data
|
||||
data.coop.tics = players[consoleplayer].realtime;
|
||||
|
||||
if ((!modifiedgame || savemoddata) && !multiplayer && !demoplayback)
|
||||
{
|
||||
// Update visitation flags
|
||||
mapvisited[gamemap-1] |= MV_BEATEN;
|
||||
if (ALL7EMERALDS(emeralds))
|
||||
mapvisited[gamemap-1] |= MV_ALLEMERALDS;
|
||||
if (ultimatemode)
|
||||
mapvisited[gamemap-1] |= MV_ULTIMATE;
|
||||
if (data.coop.gotperfbonus)
|
||||
mapvisited[gamemap-1] |= MV_PERFECT;
|
||||
|
||||
if (modeattacking == ATTACKING_RECORD)
|
||||
Y_UpdateRecordReplays();
|
||||
|
||||
if (completionEmblems)
|
||||
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : "");
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_STATIC);
|
||||
data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_STATIC);
|
||||
|
@ -1384,21 +1252,21 @@ void Y_StartIntermission(void)
|
|||
// too long so just show "YOU GOT THROUGH THE ACT"
|
||||
if (strlen(skins[players[consoleplayer].skin].realname) > 13)
|
||||
{
|
||||
strcpy(data.coop.passed1, "YOU GOT");
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "THROUGH ACT" : "THROUGH THE ACT");
|
||||
strcpy(data.coop.passed1, "you got");
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
|
||||
}
|
||||
// long enough that "X GOT" won't fit so use "X PASSED THE ACT"
|
||||
else if (strlen(skins[players[consoleplayer].skin].realname) > 8)
|
||||
{
|
||||
strcpy(data.coop.passed1, skins[players[consoleplayer].skin].realname);
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "PASSED ACT" : "PASSED THE ACT");
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "passed act" : "passed the act");
|
||||
}
|
||||
// length is okay for normal use
|
||||
else
|
||||
{
|
||||
snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s GOT",
|
||||
snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s got",
|
||||
skins[players[consoleplayer].skin].realname);
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "THROUGH ACT" : "THROUGH THE ACT");
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
|
||||
}
|
||||
|
||||
// set X positions
|
||||
|
@ -1418,40 +1286,8 @@ void Y_StartIntermission(void)
|
|||
break;
|
||||
}
|
||||
|
||||
case int_nightsspec:
|
||||
if (modeattacking && stagefailed)
|
||||
{
|
||||
// Nuh-uh. Get out of here.
|
||||
Y_EndIntermission();
|
||||
Y_FollowIntermission();
|
||||
break;
|
||||
}
|
||||
if (!stagefailed)
|
||||
G_SetNightsRecords();
|
||||
|
||||
// Check records
|
||||
{
|
||||
UINT8 earnedEmblems = M_CheckLevelEmblems();
|
||||
if (earnedEmblems)
|
||||
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for NiGHTS records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
|
||||
}
|
||||
|
||||
// fall back into the special stage intermission for now
|
||||
intertype = int_spec;
|
||||
/* FALLTHRU */
|
||||
case int_spec: // coop or single player, special stage
|
||||
{
|
||||
// Update visitation flags?
|
||||
if ((!modifiedgame || savemoddata) && !multiplayer && !demoplayback)
|
||||
{
|
||||
if (!stagefailed)
|
||||
mapvisited[gamemap-1] |= MV_BEATEN;
|
||||
|
||||
// all emeralds/ultimate/perfect emblems won't be possible in ss, oh well?
|
||||
if (completionEmblems)
|
||||
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : "");
|
||||
}
|
||||
|
||||
// give out ring bonuses
|
||||
Y_AwardSpecialStageBonus();
|
||||
|
||||
|
@ -1498,7 +1334,7 @@ void Y_StartIntermission(void)
|
|||
// set up the "got through act" message according to skin name
|
||||
if (stagefailed)
|
||||
{
|
||||
strcpy(data.spec.passed2, "SPECIAL STAGE");
|
||||
strcpy(data.spec.passed2, "Special Stage");
|
||||
data.spec.passed1[0] = '\0';
|
||||
}
|
||||
else if (ALL7EMERALDS(emeralds))
|
||||
|
@ -1507,13 +1343,13 @@ void Y_StartIntermission(void)
|
|||
sizeof data.spec.passed1, "%s",
|
||||
skins[players[consoleplayer].skin].realname);
|
||||
data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0';
|
||||
strcpy(data.spec.passed2, "GOT THEM ALL!");
|
||||
strcpy(data.spec.passed2, "got them all!");
|
||||
|
||||
if (players[consoleplayer].charflags & SF_SUPER)
|
||||
{
|
||||
strcpy(data.spec.passed3, "CAN NOW BECOME");
|
||||
strcpy(data.spec.passed3, "can now become");
|
||||
snprintf(data.spec.passed4,
|
||||
sizeof data.spec.passed4, "SUPER %s",
|
||||
sizeof data.spec.passed4, "Super %s",
|
||||
skins[players[consoleplayer].skin].realname);
|
||||
data.spec.passed4[sizeof data.spec.passed4 - 1] = '\0';
|
||||
}
|
||||
|
@ -1523,13 +1359,13 @@ void Y_StartIntermission(void)
|
|||
if (strlen(skins[players[consoleplayer].skin].realname) <= SKINNAMESIZE-5)
|
||||
{
|
||||
snprintf(data.spec.passed1,
|
||||
sizeof data.spec.passed1, "%s GOT",
|
||||
sizeof data.spec.passed1, "%s got",
|
||||
skins[players[consoleplayer].skin].realname);
|
||||
data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0';
|
||||
}
|
||||
else
|
||||
strcpy(data.spec.passed1, "YOU GOT");
|
||||
strcpy(data.spec.passed2, "A CHAOS EMERALD");
|
||||
strcpy(data.spec.passed1, "You got");
|
||||
strcpy(data.spec.passed2, "a Chaos Emerald");
|
||||
if (P_GetNextEmerald() > 6)
|
||||
{
|
||||
data.spec.passed2[15] = '?';
|
||||
|
@ -1637,7 +1473,7 @@ void Y_StartIntermission(void)
|
|||
break;
|
||||
}
|
||||
|
||||
case int_classicrace: // classic (full race)
|
||||
case int_comp: // classic (full race)
|
||||
{
|
||||
// find out who won
|
||||
Y_CalculateCompetitionWinners();
|
||||
|
@ -2192,23 +2028,6 @@ void Y_EndIntermission(void)
|
|||
usebuffer = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Y_FollowIntermission
|
||||
//
|
||||
static void Y_FollowIntermission(void)
|
||||
{
|
||||
if (modeattacking)
|
||||
{
|
||||
M_EndModeAttackRun();
|
||||
return;
|
||||
}
|
||||
|
||||
// This handles whether to play a post-level cutscene, end the game,
|
||||
// or simply go to the next level.
|
||||
// No need to duplicate the code here!
|
||||
G_AfterIntermission();
|
||||
}
|
||||
|
||||
#define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL
|
||||
|
||||
//
|
||||
|
@ -2221,8 +2040,6 @@ static void Y_UnloadData(void)
|
|||
if (rendermode != render_soft)
|
||||
return;
|
||||
|
||||
Y_CleanupScreenBuffer();
|
||||
|
||||
// unload the background patches
|
||||
UNLOAD(bgpatch);
|
||||
UNLOAD(widebgpatch);
|
||||
|
@ -2258,7 +2075,7 @@ static void Y_UnloadData(void)
|
|||
break;
|
||||
default:
|
||||
//without this default,
|
||||
//int_none, int_tag, int_chaos, and int_classicrace
|
||||
//int_none, int_tag, int_chaos, and int_comp
|
||||
//are not handled
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ void Y_Ticker(void);
|
|||
void Y_StartIntermission(void);
|
||||
void Y_EndIntermission(void);
|
||||
void Y_ConsiderScreenBuffer(void);
|
||||
void Y_CleanupScreenBuffer(void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -26,9 +27,7 @@ typedef enum
|
|||
// int_tag, // Tag
|
||||
int_ctf, // CTF
|
||||
int_spec, // Special Stage
|
||||
int_nights, // NiGHTS into Dreams
|
||||
int_nightsspec,// NiGHTS special stage
|
||||
int_race, // Race
|
||||
int_classicrace, // Competition
|
||||
int_comp, // Competition
|
||||
} intertype_t;
|
||||
extern intertype_t intertype;
|
||||
|
|
Loading…
Reference in a new issue