mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-17 23:21:22 +00:00
Merge branch 'master' into metalstuff
This commit is contained in:
commit
ca768b044d
61 changed files with 3222 additions and 879 deletions
|
@ -1527,7 +1527,7 @@ linedeftypes
|
|||
title = "Bustable Block";
|
||||
prefix = "(254)";
|
||||
flags8text = "[3] Slope skew sides";
|
||||
flags64text = "[6] Only bustable by Knuckles";
|
||||
flags64text = "[6] Strong characters only";
|
||||
flags128text = "[7] Only block non-players";
|
||||
flags512text = "[9] Shattered by pushables";
|
||||
flags1024text = "[10] Trigger linedef executor";
|
||||
|
@ -2175,7 +2175,7 @@ linedeftypes
|
|||
title = "Award Rings";
|
||||
prefix = "(460)";
|
||||
}
|
||||
|
||||
|
||||
461
|
||||
{
|
||||
title = "Spawn Object";
|
||||
|
@ -3302,36 +3302,6 @@ thingtypes
|
|||
height = 40;
|
||||
flags8text = "[8] Cannot move";
|
||||
}
|
||||
124
|
||||
{
|
||||
title = "AquaBuzz";
|
||||
sprite = "BBUZA1";
|
||||
width = 20;
|
||||
height = 24;
|
||||
}
|
||||
105
|
||||
{
|
||||
title = "Jetty-Syn Bomber";
|
||||
sprite = "JETBB1";
|
||||
width = 20;
|
||||
height = 50;
|
||||
flags8text = "[8] Cannot move";
|
||||
}
|
||||
106
|
||||
{
|
||||
title = "Jetty-Syn Gunner";
|
||||
sprite = "JETGB1";
|
||||
width = 20;
|
||||
height = 48;
|
||||
flags8text = "[8] Cannot move";
|
||||
}
|
||||
107
|
||||
{
|
||||
title = "Crawla Commander";
|
||||
sprite = "CCOMA1";
|
||||
width = 16;
|
||||
height = 32;
|
||||
}
|
||||
108
|
||||
{
|
||||
title = "Deton";
|
||||
|
@ -3339,13 +3309,6 @@ thingtypes
|
|||
width = 20;
|
||||
height = 32;
|
||||
}
|
||||
109
|
||||
{
|
||||
title = "Skim";
|
||||
sprite = "SKIMA1";
|
||||
width = 16;
|
||||
height = 24;
|
||||
}
|
||||
110
|
||||
{
|
||||
title = "Turret";
|
||||
|
@ -3361,10 +3324,24 @@ thingtypes
|
|||
height = 64;
|
||||
angletext = "Firing delay";
|
||||
}
|
||||
112
|
||||
122
|
||||
{
|
||||
title = "Spincushion";
|
||||
sprite = "SHRPA1";
|
||||
title = "Spring Shell (Green)";
|
||||
sprite = "SSHLA1";
|
||||
width = 24;
|
||||
height = 40;
|
||||
}
|
||||
125
|
||||
{
|
||||
title = "Spring Shell (Yellow)";
|
||||
sprite = "SSHLI1";
|
||||
width = 24;
|
||||
height = 40;
|
||||
}
|
||||
109
|
||||
{
|
||||
title = "Skim";
|
||||
sprite = "SKIMA1";
|
||||
width = 16;
|
||||
height = 24;
|
||||
}
|
||||
|
@ -3375,26 +3352,21 @@ thingtypes
|
|||
width = 12;
|
||||
height = 20;
|
||||
}
|
||||
114
|
||||
126
|
||||
{
|
||||
title = "Snailer";
|
||||
sprite = "SNLRA3A7";
|
||||
title = "Crushstacean";
|
||||
sprite = "CRABA0";
|
||||
width = 24;
|
||||
height = 48;
|
||||
height = 32;
|
||||
flags8text = "[8] Move left from spawn";
|
||||
}
|
||||
115
|
||||
136
|
||||
{
|
||||
title = "Bird Aircraft Strike Hazard";
|
||||
sprite = "VLTRF1";
|
||||
width = 12;
|
||||
height = 24;
|
||||
}
|
||||
116
|
||||
{
|
||||
title = "Pointy";
|
||||
sprite = "PNTYA1";
|
||||
width = 8;
|
||||
height = 16;
|
||||
title = "Banpyura";
|
||||
sprite = "CR2BA0";
|
||||
width = 24;
|
||||
height = 32;
|
||||
flags8text = "[8] Move left from spawn";
|
||||
}
|
||||
117
|
||||
{
|
||||
|
@ -3427,6 +3399,13 @@ thingtypes
|
|||
flags4text = "[4] 90 degrees clockwise";
|
||||
flags8text = "[8] Double speed";
|
||||
}
|
||||
115
|
||||
{
|
||||
title = "Bird Aircraft Strike Hazard";
|
||||
sprite = "VLTRF1";
|
||||
width = 12;
|
||||
height = 24;
|
||||
}
|
||||
120
|
||||
{
|
||||
title = "Green Snapper";
|
||||
|
@ -3441,19 +3420,13 @@ thingtypes
|
|||
width = 24;
|
||||
height = 32;
|
||||
}
|
||||
122
|
||||
134
|
||||
{
|
||||
title = "Spring Shell (Green)";
|
||||
sprite = "SSHLA1";
|
||||
width = 24;
|
||||
height = 40;
|
||||
}
|
||||
125
|
||||
{
|
||||
title = "Spring Shell (Yellow)";
|
||||
sprite = "SSHLI1";
|
||||
width = 24;
|
||||
height = 40;
|
||||
title = "Canarivore";
|
||||
sprite = "CANAA0";
|
||||
width = 12;
|
||||
height = 80;
|
||||
hangs = 1;
|
||||
}
|
||||
123
|
||||
{
|
||||
|
@ -3462,28 +3435,51 @@ thingtypes
|
|||
width = 18;
|
||||
height = 36;
|
||||
}
|
||||
126
|
||||
135
|
||||
{
|
||||
title = "Crushstacean";
|
||||
sprite = "CRABA0";
|
||||
width = 24;
|
||||
height = 32;
|
||||
flags8text = "[8] Move left from spawn";
|
||||
}
|
||||
127
|
||||
{
|
||||
title = "Hive Elemental";
|
||||
sprite = "HIVEA0";
|
||||
width = 32;
|
||||
height = 80;
|
||||
parametertext = "No. bees";
|
||||
}
|
||||
128
|
||||
{
|
||||
title = "Bumble Bore";
|
||||
sprite = "BUMBA1";
|
||||
title = "Pterabyte Spawner";
|
||||
sprite = "PTERA2A8";
|
||||
width = 16;
|
||||
height = 32;
|
||||
height = 16;
|
||||
parametertext = "No. Pterabytes";
|
||||
}
|
||||
136
|
||||
{
|
||||
title = "Pyre Fly";
|
||||
sprite = "PYREA0";
|
||||
width = 24;
|
||||
height = 34;
|
||||
flags8text = "[8] Start on fire";
|
||||
}
|
||||
105
|
||||
{
|
||||
title = "Jetty-Syn Bomber";
|
||||
sprite = "JETBB1";
|
||||
width = 20;
|
||||
height = 50;
|
||||
flags8text = "[8] Cannot move";
|
||||
}
|
||||
106
|
||||
{
|
||||
title = "Jetty-Syn Gunner";
|
||||
sprite = "JETGB1";
|
||||
width = 20;
|
||||
height = 48;
|
||||
flags8text = "[8] Cannot move";
|
||||
}
|
||||
112
|
||||
{
|
||||
title = "Spincushion";
|
||||
sprite = "SHRPA1";
|
||||
width = 16;
|
||||
height = 24;
|
||||
}
|
||||
114
|
||||
{
|
||||
title = "Snailer";
|
||||
sprite = "SNLRA3A7";
|
||||
width = 24;
|
||||
height = 48;
|
||||
}
|
||||
129
|
||||
{
|
||||
|
@ -3499,6 +3495,13 @@ thingtypes
|
|||
width = 24;
|
||||
height = 32;
|
||||
}
|
||||
107
|
||||
{
|
||||
title = "Crawla Commander";
|
||||
sprite = "CCOMA1";
|
||||
width = 16;
|
||||
height = 32;
|
||||
}
|
||||
131
|
||||
{
|
||||
title = "Spinbobert";
|
||||
|
@ -3522,29 +3525,34 @@ thingtypes
|
|||
height = 24;
|
||||
hangs = 1;
|
||||
}
|
||||
134
|
||||
127
|
||||
{
|
||||
title = "Canarivore";
|
||||
sprite = "CANAA0";
|
||||
width = 12;
|
||||
title = "Hive Elemental";
|
||||
sprite = "HIVEA0";
|
||||
width = 32;
|
||||
height = 80;
|
||||
hangs = 1;
|
||||
parametertext = "No. bees";
|
||||
}
|
||||
135
|
||||
128
|
||||
{
|
||||
title = "Pterabyte Spawner";
|
||||
sprite = "PTERA2A8";
|
||||
title = "Bumblebore";
|
||||
sprite = "BUMBA1";
|
||||
width = 16;
|
||||
height = 16;
|
||||
parametertext = "No. Pterabytes";
|
||||
height = 32;
|
||||
}
|
||||
136
|
||||
124
|
||||
{
|
||||
title = "Pyre Fly";
|
||||
sprite = "PYREA0";
|
||||
width = 24;
|
||||
height = 34;
|
||||
flags8text = "[8] Start on fire";
|
||||
title = "AquaBuzz";
|
||||
sprite = "BBUZA1";
|
||||
width = 20;
|
||||
height = 24;
|
||||
}
|
||||
116
|
||||
{
|
||||
title = "Pointy";
|
||||
sprite = "PNTYA1";
|
||||
width = 8;
|
||||
height = 16;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4141,6 +4149,34 @@ thingtypes
|
|||
angletext = "Retraction interval";
|
||||
parametertext = "Initial delay";
|
||||
}
|
||||
1130
|
||||
{
|
||||
title = "Small Mace";
|
||||
sprite = "SMCEA0";
|
||||
width = 17;
|
||||
height = 34;
|
||||
}
|
||||
1131
|
||||
{
|
||||
title = "Big Mace";
|
||||
sprite = "BMCEA0";
|
||||
width = 34;
|
||||
height = 68;
|
||||
}
|
||||
1136
|
||||
{
|
||||
title = "Small Fireball";
|
||||
sprite = "SFBRA0";
|
||||
width = 17;
|
||||
height = 34;
|
||||
}
|
||||
1137
|
||||
{
|
||||
title = "Large Fireball";
|
||||
sprite = "BFBRA0";
|
||||
width = 34;
|
||||
height = 68;
|
||||
}
|
||||
}
|
||||
|
||||
springs
|
||||
|
@ -4257,6 +4293,38 @@ thingtypes
|
|||
width = 16;
|
||||
height = 32;
|
||||
}
|
||||
1134
|
||||
{
|
||||
title = "Yellow Spring Ball";
|
||||
sprite = "YSPBA0";
|
||||
width = 17;
|
||||
height = 34;
|
||||
}
|
||||
1135
|
||||
{
|
||||
title = "Red Spring Ball";
|
||||
sprite = "RSPBA0";
|
||||
width = 17;
|
||||
height = 34;
|
||||
}
|
||||
544
|
||||
{
|
||||
arrow = 1;
|
||||
title = "Yellow Boost Panel";
|
||||
sprite = "BSTYA0";
|
||||
flags8text = "[8] Force spin";
|
||||
width = 28;
|
||||
height = 2;
|
||||
}
|
||||
545
|
||||
{
|
||||
arrow = 1;
|
||||
title = "Red Boost Panel";
|
||||
sprite = "BSTRA0";
|
||||
flags8text = "[8] Force spin";
|
||||
width = 28;
|
||||
height = 2;
|
||||
}
|
||||
}
|
||||
|
||||
patterns
|
||||
|
@ -4837,7 +4905,7 @@ thingtypes
|
|||
}
|
||||
1104
|
||||
{
|
||||
title = "Mace";
|
||||
title = "Mace Spawnpoint";
|
||||
sprite = "SMCEA0";
|
||||
width = 17;
|
||||
height = 34;
|
||||
|
@ -4847,7 +4915,7 @@ thingtypes
|
|||
}
|
||||
1105
|
||||
{
|
||||
title = "Chain & Maces";
|
||||
title = "Chain with Maces Spawnpoint";
|
||||
sprite = "SMCEA0";
|
||||
width = 17;
|
||||
height = 34;
|
||||
|
@ -4857,7 +4925,7 @@ thingtypes
|
|||
}
|
||||
1106
|
||||
{
|
||||
title = "Chained Spring";
|
||||
title = "Chained Spring Spawnpoint";
|
||||
sprite = "YSPBA0";
|
||||
width = 17;
|
||||
height = 34;
|
||||
|
@ -4867,7 +4935,7 @@ thingtypes
|
|||
}
|
||||
1107
|
||||
{
|
||||
title = "Chain";
|
||||
title = "Chain Spawnpoint";
|
||||
sprite = "BMCHA0";
|
||||
width = 17;
|
||||
height = 34;
|
||||
|
@ -4877,7 +4945,7 @@ thingtypes
|
|||
1108
|
||||
{
|
||||
arrow = 1;
|
||||
title = "Chain (Hidden)";
|
||||
title = "Hidden Chain Spawnpoint";
|
||||
sprite = "internal:chain3";
|
||||
width = 17;
|
||||
height = 34;
|
||||
|
@ -4885,7 +4953,7 @@ thingtypes
|
|||
}
|
||||
1109
|
||||
{
|
||||
title = "Firebar";
|
||||
title = "Firebar Spawnpoint";
|
||||
sprite = "BFBRA0";
|
||||
width = 17;
|
||||
height = 34;
|
||||
|
@ -4895,7 +4963,7 @@ thingtypes
|
|||
}
|
||||
1110
|
||||
{
|
||||
title = "Custom Mace";
|
||||
title = "Custom Mace Spawnpoint";
|
||||
sprite = "SMCEA0";
|
||||
width = 17;
|
||||
height = 34;
|
||||
|
@ -5580,30 +5648,16 @@ thingtypes
|
|||
title = "BSZ Clover";
|
||||
sprite = "BSZ8B0";
|
||||
}
|
||||
1472
|
||||
{
|
||||
title = "Palm Tree Trunk (Big)";
|
||||
width = 16;
|
||||
height = 160;
|
||||
sprite = "BSZ8C0";
|
||||
}
|
||||
1473
|
||||
{
|
||||
title = "Palm Tree Leaves (Big)";
|
||||
title = "Palm Tree (Big)";
|
||||
width = 16;
|
||||
height = 160;
|
||||
sprite = "BSZ8D0";
|
||||
}
|
||||
1474
|
||||
{
|
||||
title = "Palm Tree Trunk (Small)";
|
||||
width = 8;
|
||||
height = 80;
|
||||
sprite = "BSZ8E0";
|
||||
}
|
||||
1475
|
||||
{
|
||||
title = "Palm Tree Leaves (Small)";
|
||||
title = "Palm Tree (Small)";
|
||||
width = 16;
|
||||
height = 80;
|
||||
sprite = "BSZ8F0";
|
||||
|
@ -6425,4 +6479,4 @@ thingsfilters
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
246
src/command.c
246
src/command.c
|
@ -49,6 +49,7 @@ static void COM_Exec_f(void);
|
|||
static void COM_Wait_f(void);
|
||||
static void COM_Help_f(void);
|
||||
static void COM_Toggle_f(void);
|
||||
static void COM_Add_f(void);
|
||||
|
||||
static void CV_EnforceExecVersion(void);
|
||||
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr);
|
||||
|
@ -291,6 +292,7 @@ void COM_Init(void)
|
|||
COM_AddCommand("wait", COM_Wait_f);
|
||||
COM_AddCommand("help", COM_Help_f);
|
||||
COM_AddCommand("toggle", COM_Toggle_f);
|
||||
COM_AddCommand("add", COM_Add_f);
|
||||
RegisterNetXCmd(XD_NETVAR, Got_NetVar);
|
||||
}
|
||||
|
||||
|
@ -709,15 +711,21 @@ static void COM_Help_f(void)
|
|||
|
||||
if (COM_Argc() > 1)
|
||||
{
|
||||
cvar = CV_FindVar(COM_Argv(1));
|
||||
const char *help = COM_Argv(1);
|
||||
cvar = CV_FindVar(help);
|
||||
if (cvar)
|
||||
{
|
||||
CONS_Printf(M_GetText("Variable %s:\n"), cvar->name);
|
||||
boolean floatmode = false;
|
||||
const char *cvalue = NULL;
|
||||
CONS_Printf("\x82""Variable %s:\n", cvar->name);
|
||||
CONS_Printf(M_GetText(" flags :"));
|
||||
if (cvar->flags & CV_SAVE)
|
||||
CONS_Printf("AUTOSAVE ");
|
||||
if (cvar->flags & CV_FLOAT)
|
||||
{
|
||||
CONS_Printf("FLOAT ");
|
||||
floatmode = true;
|
||||
}
|
||||
if (cvar->flags & CV_NETVAR)
|
||||
CONS_Printf("NETVAR ");
|
||||
if (cvar->flags & CV_CALL)
|
||||
|
@ -727,59 +735,113 @@ static void COM_Help_f(void)
|
|||
CONS_Printf("\n");
|
||||
if (cvar->PossibleValue)
|
||||
{
|
||||
if (stricmp(cvar->PossibleValue[0].strvalue, "MIN") == 0)
|
||||
{
|
||||
for (i = 1; cvar->PossibleValue[i].strvalue != NULL; i++)
|
||||
if (!stricmp(cvar->PossibleValue[i].strvalue, "MAX"))
|
||||
break;
|
||||
CONS_Printf(M_GetText(" range from %d to %d\n"), cvar->PossibleValue[0].value,
|
||||
cvar->PossibleValue[i].value);
|
||||
CONS_Printf(M_GetText(" Current value: %d\n"), cvar->value);
|
||||
}
|
||||
CONS_Printf(" Possible values:\n");
|
||||
if (cvar->PossibleValue == CV_YesNo)
|
||||
CONS_Printf(" Yes or No (On or Off, 1 or 0)\n");
|
||||
else if (cvar->PossibleValue == CV_OnOff)
|
||||
CONS_Printf(" On or Off (Yes or No, 1 or 0)\n");
|
||||
else
|
||||
{
|
||||
const char *cvalue = NULL;
|
||||
CONS_Printf(M_GetText(" possible value : %s\n"), cvar->name);
|
||||
#define MINVAL 0
|
||||
#define MAXVAL 1
|
||||
if (!stricmp(cvar->PossibleValue[MINVAL].strvalue, "MIN"))
|
||||
{
|
||||
if (floatmode)
|
||||
CONS_Printf(" range from %f to %f\n", FIXED_TO_FLOAT(cvar->PossibleValue[MINVAL].value),
|
||||
FIXED_TO_FLOAT(cvar->PossibleValue[MAXVAL].value));
|
||||
else
|
||||
CONS_Printf(" range from %d to %d\n", cvar->PossibleValue[MINVAL].value,
|
||||
cvar->PossibleValue[MAXVAL].value);
|
||||
i = MAXVAL+1;
|
||||
}
|
||||
#undef MINVAL
|
||||
#undef MAXVAL
|
||||
|
||||
//CONS_Printf(M_GetText(" possible value : %s\n"), cvar->name);
|
||||
while (cvar->PossibleValue[i].strvalue)
|
||||
{
|
||||
CONS_Printf(" %-2d : %s\n", cvar->PossibleValue[i].value,
|
||||
cvar->PossibleValue[i].strvalue);
|
||||
if (floatmode)
|
||||
CONS_Printf(" %-2f : %s\n", FIXED_TO_FLOAT(cvar->PossibleValue[i].value),
|
||||
cvar->PossibleValue[i].strvalue);
|
||||
else
|
||||
CONS_Printf(" %-2d : %s\n", cvar->PossibleValue[i].value,
|
||||
cvar->PossibleValue[i].strvalue);
|
||||
if (cvar->PossibleValue[i].value == cvar->value)
|
||||
cvalue = cvar->PossibleValue[i].strvalue;
|
||||
i++;
|
||||
}
|
||||
if (cvalue)
|
||||
CONS_Printf(M_GetText(" Current value: %s\n"), cvalue);
|
||||
else
|
||||
CONS_Printf(M_GetText(" Current value: %d\n"), cvar->value);
|
||||
}
|
||||
}
|
||||
|
||||
if (cvalue)
|
||||
CONS_Printf(" Current value: %s\n", cvalue);
|
||||
else if (cvar->string)
|
||||
CONS_Printf(" Current value: %s\n", cvar->string);
|
||||
else
|
||||
CONS_Printf(M_GetText(" Current value: %d\n"), cvar->value);
|
||||
CONS_Printf(" Current value: %d\n", cvar->value);
|
||||
}
|
||||
else
|
||||
CONS_Printf(M_GetText("No help for this command/variable\n"));
|
||||
{
|
||||
for (cmd = com_commands; cmd; cmd = cmd->next)
|
||||
{
|
||||
if (strcmp(cmd->name, help))
|
||||
continue;
|
||||
|
||||
CONS_Printf("\x82""Command %s:\n", cmd->name);
|
||||
CONS_Printf(" help is not available for commands");
|
||||
CONS_Printf("\x82""\nCheck wiki.srb2.org for more or try typing <name> without arguments\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CONS_Printf("No exact match, searching...\n");
|
||||
|
||||
// variables
|
||||
CONS_Printf("\x82""Variables:\n");
|
||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||
{
|
||||
if ((cvar->flags & CV_NOSHOWHELP) || (!strstr(cvar->name, help)))
|
||||
continue;
|
||||
CONS_Printf("%s ", cvar->name);
|
||||
i++;
|
||||
}
|
||||
|
||||
// commands
|
||||
CONS_Printf("\x82""\nCommands:\n");
|
||||
for (cmd = com_commands; cmd; cmd = cmd->next)
|
||||
{
|
||||
if (!strstr(cmd->name, help))
|
||||
continue;
|
||||
CONS_Printf("%s ",cmd->name);
|
||||
i++;
|
||||
}
|
||||
|
||||
CONS_Printf("\x82""\nCheck wiki.srb2.org for more or type help <command or variable>\n");
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "\x87Total : %d\n", i);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// variables
|
||||
CONS_Printf("\x82""Variables:\n");
|
||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||
{
|
||||
if (cvar->flags & CV_NOSHOWHELP)
|
||||
continue;
|
||||
CONS_Printf("%s ", cvar->name);
|
||||
i++;
|
||||
}
|
||||
|
||||
// commands
|
||||
CONS_Printf("\x82%s", M_GetText("Commands\n"));
|
||||
CONS_Printf("\x82""\nCommands:\n");
|
||||
for (cmd = com_commands; cmd; cmd = cmd->next)
|
||||
{
|
||||
CONS_Printf("%s ",cmd->name);
|
||||
i++;
|
||||
}
|
||||
|
||||
// variables
|
||||
CONS_Printf("\n\x82%s", M_GetText("Variables\n"));
|
||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||
{
|
||||
if (!(cvar->flags & CV_NOSHOWHELP))
|
||||
CONS_Printf("%s ", cvar->name);
|
||||
i++;
|
||||
}
|
||||
|
||||
CONS_Printf("\n\x82%s", M_GetText("Read help file for more or type help <command or variable>\n"));
|
||||
CONS_Printf("\x82""\nCheck wiki.srb2.org for more or type help <command or variable>\n");
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "\x82Total : %d\n", i);
|
||||
}
|
||||
|
@ -816,6 +878,30 @@ static void COM_Toggle_f(void)
|
|||
CV_AddValue(cvar, +1);
|
||||
}
|
||||
|
||||
/** Command variant of CV_AddValue
|
||||
*/
|
||||
static void COM_Add_f(void)
|
||||
{
|
||||
consvar_t *cvar;
|
||||
|
||||
if (COM_Argc() != 3)
|
||||
{
|
||||
CONS_Printf(M_GetText("Add <cvar_name> <value>: Add to the value of a cvar. Negative values work too!\n"));
|
||||
return;
|
||||
}
|
||||
cvar = CV_FindVar(COM_Argv(1));
|
||||
if (!cvar)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("%s is not a cvar\n"), COM_Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (( cvar->flags & CV_FLOAT ))
|
||||
CV_Set(cvar, va("%f", FIXED_TO_FLOAT (cvar->value) + atof(COM_Argv(2))));
|
||||
else
|
||||
CV_AddValue(cvar, atoi(COM_Argv(2)));
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// VARIABLE SIZE BUFFERS
|
||||
// =========================================================================
|
||||
|
@ -1123,32 +1209,42 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
|
|||
|
||||
if (var->PossibleValue[0].strvalue && !stricmp(var->PossibleValue[0].strvalue, "MIN")) // bounded cvar
|
||||
{
|
||||
#define MINVAL 0
|
||||
#define MAXVAL 1
|
||||
INT32 i;
|
||||
// search for maximum
|
||||
for (i = 1; var->PossibleValue[i].strvalue; i++)
|
||||
if (!stricmp(var->PossibleValue[i].strvalue, "MAX"))
|
||||
break;
|
||||
#ifdef PARANOIA
|
||||
if (!var->PossibleValue[i].strvalue)
|
||||
if (!var->PossibleValue[MAXVAL].strvalue)
|
||||
I_Error("Bounded cvar \"%s\" without maximum!\n", var->name);
|
||||
#endif
|
||||
|
||||
if ((v != INT32_MIN && v < var->PossibleValue[0].value) || !stricmp(valstr, "MIN"))
|
||||
// search for other
|
||||
for (i = MAXVAL+1; var->PossibleValue[i].strvalue; i++)
|
||||
if (v == var->PossibleValue[i].value || !stricmp(var->PossibleValue[i].strvalue, valstr))
|
||||
{
|
||||
var->value = var->PossibleValue[i].value;
|
||||
var->string = var->PossibleValue[i].strvalue;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
||||
if ((v != INT32_MIN && v < var->PossibleValue[MINVAL].value) || !stricmp(valstr, "MIN"))
|
||||
{
|
||||
v = var->PossibleValue[0].value;
|
||||
valstr = var->PossibleValue[0].strvalue;
|
||||
v = var->PossibleValue[MINVAL].value;
|
||||
valstr = var->PossibleValue[MINVAL].strvalue;
|
||||
override = true;
|
||||
overrideval = v;
|
||||
}
|
||||
else if ((v != INT32_MIN && v > var->PossibleValue[i].value) || !stricmp(valstr, "MAX"))
|
||||
else if ((v != INT32_MIN && v > var->PossibleValue[MAXVAL].value) || !stricmp(valstr, "MAX"))
|
||||
{
|
||||
v = var->PossibleValue[i].value;
|
||||
valstr = var->PossibleValue[i].strvalue;
|
||||
v = var->PossibleValue[MAXVAL].value;
|
||||
valstr = var->PossibleValue[MAXVAL].strvalue;
|
||||
override = true;
|
||||
overrideval = v;
|
||||
}
|
||||
if (v == INT32_MIN)
|
||||
goto badinput;
|
||||
#undef MINVAL
|
||||
#undef MAXVAL
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1515,6 +1611,9 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
{
|
||||
INT32 newvalue, max;
|
||||
|
||||
if (!increment)
|
||||
return;
|
||||
|
||||
// count pointlimit better
|
||||
if (var == &cv_pointlimit && (gametype == GT_MATCH))
|
||||
increment *= 50;
|
||||
|
@ -1538,13 +1637,11 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
|
||||
if (var->PossibleValue)
|
||||
{
|
||||
#define MINVAL 0
|
||||
if (var == &cv_nextmap)
|
||||
{
|
||||
// Special case for the nextmap variable, used only directly from the menu
|
||||
INT32 oldvalue = var->value - 1, gt;
|
||||
gt = cv_newgametype.value;
|
||||
if (increment != 0) // Going up!
|
||||
{
|
||||
newvalue = var->value - 1;
|
||||
do
|
||||
|
@ -1575,21 +1672,58 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
return;
|
||||
}
|
||||
}
|
||||
#define MINVAL 0
|
||||
#define MAXVAL 1
|
||||
else if (var->PossibleValue[MINVAL].strvalue && !strcmp(var->PossibleValue[MINVAL].strvalue, "MIN"))
|
||||
{
|
||||
// search the next to last
|
||||
for (max = 0; var->PossibleValue[max+1].strvalue; max++)
|
||||
;
|
||||
#ifdef PARANOIA
|
||||
if (!var->PossibleValue[MAXVAL].strvalue)
|
||||
I_Error("Bounded cvar \"%s\" without maximum!\n", var->name);
|
||||
#endif
|
||||
|
||||
if (newvalue < var->PossibleValue[MINVAL].value) // add the max+1
|
||||
newvalue += var->PossibleValue[max].value - var->PossibleValue[MINVAL].value + 1;
|
||||
if (newvalue < var->PossibleValue[MINVAL].value || newvalue > var->PossibleValue[MAXVAL].value)
|
||||
{
|
||||
INT32 currentindice = -1, newindice;
|
||||
for (max = MAXVAL+1; var->PossibleValue[max].strvalue; max++)
|
||||
{
|
||||
if (var->PossibleValue[max].value == newvalue)
|
||||
{
|
||||
increment = 0;
|
||||
currentindice = max;
|
||||
}
|
||||
else if (var->PossibleValue[max].value == var->value)
|
||||
currentindice = max;
|
||||
}
|
||||
|
||||
newvalue = var->PossibleValue[MINVAL].value + (newvalue - var->PossibleValue[MINVAL].value)
|
||||
% (var->PossibleValue[max].value - var->PossibleValue[MINVAL].value + 1);
|
||||
if (increment)
|
||||
{
|
||||
increment = (increment > 0) ? 1 : -1;
|
||||
if (currentindice == -1 && max != MAXVAL+1)
|
||||
newindice = ((increment > 0) ? MAXVAL : max) + increment;
|
||||
else
|
||||
newindice = currentindice + increment;
|
||||
|
||||
CV_SetValue(var, newvalue);
|
||||
#undef MINVAL
|
||||
if (newindice >= max || newindice <= MAXVAL)
|
||||
{
|
||||
if (var == &cv_pointlimit && (gametype == GT_MATCH) && increment > 0)
|
||||
CV_SetValue(var, 50);
|
||||
else
|
||||
{
|
||||
newvalue = var->PossibleValue[((increment > 0) ? MINVAL : MAXVAL)].value;
|
||||
CV_SetValue(var, newvalue);
|
||||
}
|
||||
}
|
||||
else
|
||||
CV_Set(var, var->PossibleValue[newindice].strvalue);
|
||||
}
|
||||
else
|
||||
CV_Set(var, var->PossibleValue[currentindice].strvalue);
|
||||
}
|
||||
else
|
||||
CV_SetValue(var, newvalue);
|
||||
}
|
||||
#undef MINVAL
|
||||
#undef MAXVAL
|
||||
else
|
||||
{
|
||||
INT32 currentindice = -1, newindice;
|
||||
|
@ -1599,8 +1733,6 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
if (var->PossibleValue[max].value == var->value)
|
||||
currentindice = max;
|
||||
|
||||
max--;
|
||||
|
||||
if (var == &cv_chooseskin)
|
||||
{
|
||||
// Special case for the chooseskin variable, used only directly from the menu
|
||||
|
@ -1632,7 +1764,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
var->value);
|
||||
#endif
|
||||
|
||||
newindice = (currentindice + increment + max + 1) % (max+1);
|
||||
newindice = (currentindice + increment + max) % max;
|
||||
CV_Set(var, var->PossibleValue[newindice].strvalue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,11 +175,11 @@ static void CONS_Clear_f(void)
|
|||
|
||||
// Choose english keymap
|
||||
//
|
||||
static void CONS_English_f(void)
|
||||
/*static void CONS_English_f(void)
|
||||
{
|
||||
shiftxform = english_shiftxform;
|
||||
CONS_Printf(M_GetText("%s keymap.\n"), M_GetText("English"));
|
||||
}
|
||||
}*/
|
||||
|
||||
static char *bindtable[NUMINPUTS];
|
||||
|
||||
|
@ -394,7 +394,7 @@ void CON_Init(void)
|
|||
// register our commands
|
||||
//
|
||||
COM_AddCommand("cls", CONS_Clear_f);
|
||||
COM_AddCommand("english", CONS_English_f);
|
||||
//COM_AddCommand("english", CONS_English_f);
|
||||
// set console full screen for game startup MAKE SURE VID_Init() done !!!
|
||||
con_destlines = vid.height;
|
||||
con_curlines = vid.height;
|
||||
|
|
|
@ -83,11 +83,9 @@ tic_t jointimeout = (10*TICRATE);
|
|||
static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame?
|
||||
static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout?
|
||||
|
||||
#ifdef NEWPING
|
||||
UINT16 pingmeasurecount = 1;
|
||||
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
|
||||
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
|
||||
#endif
|
||||
SINT8 nodetoplayer[MAXNETNODES];
|
||||
SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen)
|
||||
UINT8 playerpernode[MAXNETNODES]; // used specialy for scplitscreen
|
||||
|
@ -1266,7 +1264,8 @@ static boolean CL_SendJoin(void)
|
|||
netbuffer->u.clientcfg.localplayers = localplayers;
|
||||
netbuffer->u.clientcfg.version = VERSION;
|
||||
netbuffer->u.clientcfg.subversion = SUBVERSION;
|
||||
|
||||
strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME);
|
||||
strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME);
|
||||
return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak));
|
||||
}
|
||||
|
||||
|
@ -1325,33 +1324,13 @@ static void SV_SendPlayerInfo(INT32 node)
|
|||
continue;
|
||||
}
|
||||
|
||||
netbuffer->u.playerinfo[i].node = (UINT8)playernode[i];
|
||||
netbuffer->u.playerinfo[i].node = i;
|
||||
strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1);
|
||||
netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0';
|
||||
|
||||
//fetch IP address
|
||||
{
|
||||
const char *claddress;
|
||||
UINT32 numericaddress[4];
|
||||
|
||||
memset(netbuffer->u.playerinfo[i].address, 0, 4);
|
||||
if (playernode[i] == 0)
|
||||
{
|
||||
//127.0.0.1
|
||||
netbuffer->u.playerinfo[i].address[0] = 127;
|
||||
netbuffer->u.playerinfo[i].address[3] = 1;
|
||||
}
|
||||
else if (playernode[i] > 0 && I_GetNodeAddress && (claddress = I_GetNodeAddress(playernode[i])) != NULL)
|
||||
{
|
||||
if (sscanf(claddress, "%d.%d.%d.%d", &numericaddress[0], &numericaddress[1], &numericaddress[2], &numericaddress[3]) < 4)
|
||||
goto badaddress;
|
||||
netbuffer->u.playerinfo[i].address[0] = (UINT8)numericaddress[0];
|
||||
netbuffer->u.playerinfo[i].address[1] = (UINT8)numericaddress[1];
|
||||
netbuffer->u.playerinfo[i].address[2] = (UINT8)numericaddress[2];
|
||||
netbuffer->u.playerinfo[i].address[3] = (UINT8)numericaddress[3];
|
||||
}
|
||||
}
|
||||
badaddress:
|
||||
//No, don't do that, you fuckface.
|
||||
memset(netbuffer->u.playerinfo[i].address, 0, 4);
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
|
@ -2883,12 +2862,10 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false);
|
||||
kickreason = KR_KICK;
|
||||
break;
|
||||
#ifdef NEWPING
|
||||
case KICK_MSG_PING_HIGH:
|
||||
HU_AddChatText(va("\x82*%s left the game (Broke ping limit)", player_names[pnum]), false);
|
||||
kickreason = KR_PINGLIMIT;
|
||||
break;
|
||||
#endif
|
||||
case KICK_MSG_CON_FAIL:
|
||||
HU_AddChatText(va("\x82*%s left the game (Synch Failure)", player_names[pnum]), false);
|
||||
kickreason = KR_SYNCH;
|
||||
|
@ -2961,10 +2938,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
D_StartTitle();
|
||||
if (msg == KICK_MSG_CON_FAIL)
|
||||
M_StartMessage(M_GetText("Server closed connection\n(synch failure)\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
#ifdef NEWPING
|
||||
else if (msg == KICK_MSG_PING_HIGH)
|
||||
M_StartMessage(M_GetText("Server closed connection\n(Broke ping limit)\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
#endif
|
||||
else if (msg == KICK_MSG_BANNED)
|
||||
M_StartMessage(M_GetText("You have been banned by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
else if (msg == KICK_MSG_CUSTOM_KICK)
|
||||
|
@ -2982,7 +2957,7 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, N
|
|||
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
|
||||
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t resynchattempts_cons_t[] = {{0, "MIN"}, {20, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "No"}, {0, NULL}};
|
||||
consvar_t cv_resynchattempts = {"resynchattempts", "10", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
|
||||
|
@ -3212,6 +3187,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
if (!splitscreen && !botingame)
|
||||
CL_ClearPlayer(newplayernum);
|
||||
playeringame[newplayernum] = true;
|
||||
READSTRINGN(*p, player_names[newplayernum], MAXPLAYERNAME);
|
||||
G_AddPlayer(newplayernum);
|
||||
if (newplayernum+1 > doomcom->numslots)
|
||||
doomcom->numslots = (INT16)(newplayernum+1);
|
||||
|
@ -3244,10 +3220,10 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
{
|
||||
const char *address;
|
||||
if (I_GetNodeAddress && (address = I_GetNodeAddress(node)) != NULL)
|
||||
HU_AddChatText(va("\x82*Player %d has joined the game (node %d) (%s)", newplayernum+1, node, address), false); // merge join notification + IP to avoid clogging console/chat.
|
||||
HU_AddChatText(va("\x82*%s has joined the game (node %d) (%s)", player_names[newplayernum], node, address), false); // merge join notification + IP to avoid clogging console/chat.
|
||||
}
|
||||
else
|
||||
HU_AddChatText(va("\x82*Player %d has joined the game (node %d)", newplayernum+1, node), false); // if you don't wanna see the join address.
|
||||
HU_AddChatText(va("\x82*%s has joined the game (node %d)", player_names[newplayernum], node), false); // if you don't wanna see the join address.
|
||||
}
|
||||
|
||||
if (server && multiplayer && motd[0] != '\0')
|
||||
|
@ -3258,10 +3234,11 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
#endif
|
||||
}
|
||||
|
||||
static boolean SV_AddWaitingPlayers(void)
|
||||
static boolean SV_AddWaitingPlayers(const char *name, const char *name2)
|
||||
{
|
||||
INT32 node, n, newplayer = false;
|
||||
UINT8 buf[2];
|
||||
UINT8 buf[2 + MAXPLAYERNAME];
|
||||
UINT8 *p;
|
||||
UINT8 newplayernum = 0;
|
||||
|
||||
// What is the reason for this? Why can't newplayernum always be 0?
|
||||
|
@ -3344,18 +3321,23 @@ static boolean SV_AddWaitingPlayers(void)
|
|||
|
||||
playernode[newplayernum] = (UINT8)node;
|
||||
|
||||
p = buf + 2;
|
||||
buf[0] = (UINT8)node;
|
||||
buf[1] = newplayernum;
|
||||
if (playerpernode[node] < 1)
|
||||
{
|
||||
nodetoplayer[node] = newplayernum;
|
||||
WRITESTRINGN(p, name, MAXPLAYERNAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodetoplayer2[node] = newplayernum;
|
||||
buf[1] |= 0x80;
|
||||
WRITESTRINGN(p, name2, MAXPLAYERNAME);
|
||||
}
|
||||
playerpernode[node]++;
|
||||
|
||||
SendNetXCmd(XD_ADDPLAYER, &buf, 2);
|
||||
SendNetXCmd(XD_ADDPLAYER, &buf, p - buf);
|
||||
|
||||
DEBFILE(va("Server added player %d node %d\n", newplayernum, node));
|
||||
// use the next free slot (we can't put playeringame[newplayernum] = true here)
|
||||
|
@ -3417,7 +3399,7 @@ boolean SV_SpawnServer(void)
|
|||
else doomcom->numslots = 1;
|
||||
}
|
||||
|
||||
return SV_AddWaitingPlayers();
|
||||
return SV_AddWaitingPlayers(cv_playername.zstring, cv_playername2.zstring);
|
||||
}
|
||||
|
||||
void SV_StopServer(void)
|
||||
|
@ -3488,6 +3470,9 @@ static size_t TotalTextCmdPerTic(tic_t tic)
|
|||
*/
|
||||
static void HandleConnect(SINT8 node)
|
||||
{
|
||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
|
||||
INT32 i;
|
||||
|
||||
if (bannednode && bannednode[node])
|
||||
SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server"));
|
||||
else if (netbuffer->u.clientcfg.version != VERSION
|
||||
|
@ -3507,6 +3492,16 @@ static void HandleConnect(SINT8 node)
|
|||
boolean newnode = false;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++)
|
||||
{
|
||||
strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1);
|
||||
if (!EnsurePlayerNameIsGood(names[i], -1))
|
||||
{
|
||||
SV_SendRefuse(node, "Bad player name");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// client authorised to join
|
||||
nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]);
|
||||
if (!nodeingame[node])
|
||||
|
@ -3547,7 +3542,7 @@ static void HandleConnect(SINT8 node)
|
|||
SV_SendSaveGame(node); // send a complete game state
|
||||
DEBFILE("send savegame\n");
|
||||
}
|
||||
SV_AddWaitingPlayers();
|
||||
SV_AddWaitingPlayers(names[0], names[1]);
|
||||
player_joining = true;
|
||||
}
|
||||
#else
|
||||
|
@ -4188,7 +4183,6 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
resynch_local_inprogress = true;
|
||||
CL_AcknowledgeResynch(&netbuffer->u.resynchpak);
|
||||
break;
|
||||
#ifdef NEWPING
|
||||
case PT_PING:
|
||||
// Only accept PT_PING from the server.
|
||||
if (node != servernode)
|
||||
|
@ -4216,7 +4210,6 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
case PT_SERVERCFG:
|
||||
break;
|
||||
case PT_FILEFRAGMENT:
|
||||
|
@ -4730,7 +4723,6 @@ void TryRunTics(tic_t realtics)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef NEWPING
|
||||
static inline void PingUpdate(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
@ -4788,7 +4780,6 @@ static inline void PingUpdate(void)
|
|||
|
||||
pingmeasurecount = 1; //Reset count
|
||||
}
|
||||
#endif
|
||||
|
||||
void NetUpdate(void)
|
||||
{
|
||||
|
@ -4813,7 +4804,6 @@ void NetUpdate(void)
|
|||
|
||||
gametime = nowtime;
|
||||
|
||||
#ifdef NEWPING
|
||||
if (server)
|
||||
{
|
||||
if (netgame && !(gametime % 255))
|
||||
|
@ -4824,7 +4814,6 @@ void NetUpdate(void)
|
|||
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
||||
pingmeasurecount++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (client)
|
||||
maketic = neededtic;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "d_ticcmd.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "d_net.h"
|
||||
#include "tables.h"
|
||||
#include "d_player.h"
|
||||
|
||||
|
@ -73,9 +74,7 @@ typedef enum
|
|||
|
||||
PT_LOGIN, // Login attempt from the client.
|
||||
|
||||
#ifdef NEWPING
|
||||
PT_PING, // Packet sent to tell clients the other client's latency to server.
|
||||
#endif
|
||||
NUMPACKETTYPE
|
||||
} packettype_t;
|
||||
|
||||
|
@ -326,6 +325,7 @@ typedef struct
|
|||
UINT8 subversion; // Contains build version
|
||||
UINT8 localplayers;
|
||||
UINT8 mode;
|
||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME];
|
||||
} ATTRPACK clientconfig_pak;
|
||||
|
||||
#define MAXSERVERNAME 32
|
||||
|
@ -425,9 +425,7 @@ typedef struct
|
|||
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)
|
||||
#ifdef NEWPING
|
||||
UINT32 pingtable[MAXPLAYERS]; // 128 bytes
|
||||
#endif
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK doomdata_t;
|
||||
|
||||
|
@ -461,9 +459,7 @@ extern consvar_t cv_playbackspeed;
|
|||
#define KICK_MSG_PLAYER_QUIT 3
|
||||
#define KICK_MSG_TIMEOUT 4
|
||||
#define KICK_MSG_BANNED 5
|
||||
#ifdef NEWPING
|
||||
#define KICK_MSG_PING_HIGH 6
|
||||
#endif
|
||||
#define KICK_MSG_CUSTOM_KICK 7
|
||||
#define KICK_MSG_CUSTOM_BAN 8
|
||||
|
||||
|
@ -488,11 +484,9 @@ extern SINT8 servernode;
|
|||
void Command_Ping_f(void);
|
||||
extern tic_t connectiontimeout;
|
||||
extern tic_t jointimeout;
|
||||
#ifdef NEWPING
|
||||
extern UINT16 pingmeasurecount;
|
||||
extern UINT32 realpingtable[MAXPLAYERS];
|
||||
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||
#endif
|
||||
|
||||
extern consvar_t cv_joinnextround, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
|
||||
|
|
46
src/d_main.c
46
src/d_main.c
|
@ -359,7 +359,7 @@ static void D_Display(void)
|
|||
|
||||
// clean up border stuff
|
||||
// see if the border needs to be initially drawn
|
||||
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide))
|
||||
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap)))
|
||||
{
|
||||
// draw the view directly
|
||||
|
||||
|
@ -1244,24 +1244,40 @@ void D_SRB2Main(void)
|
|||
sound_disabled = true;
|
||||
midi_disabled = digital_disabled = true;
|
||||
}
|
||||
if (M_CheckParm("-noaudio")) // combines -nosound and -nomusic
|
||||
{
|
||||
sound_disabled = true;
|
||||
digital_disabled = true;
|
||||
midi_disabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (M_CheckParm("-nosound"))
|
||||
sound_disabled = true;
|
||||
if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
|
||||
{
|
||||
digital_disabled = true;
|
||||
midi_disabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (M_CheckParm("-nomidimusic"))
|
||||
midi_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
|
||||
if (M_CheckParm("-nodigmusic"))
|
||||
digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
|
||||
}
|
||||
}
|
||||
if (!( sound_disabled && digital_disabled
|
||||
#ifndef NO_MIDI
|
||||
&& midi_disabled
|
||||
#endif
|
||||
))
|
||||
{
|
||||
CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
|
||||
I_StartupSound();
|
||||
I_InitMusic();
|
||||
S_InitSfxChannels(cv_soundvolume.value);
|
||||
}
|
||||
if (M_CheckParm("-nosound"))
|
||||
sound_disabled = true;
|
||||
if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
|
||||
midi_disabled = digital_disabled = true;
|
||||
else
|
||||
{
|
||||
if (M_CheckParm("-nomidimusic"))
|
||||
midi_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
|
||||
if (M_CheckParm("-nodigmusic"))
|
||||
digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
|
||||
}
|
||||
I_StartupSound();
|
||||
I_InitMusic();
|
||||
S_InitSfxChannels(cv_soundvolume.value);
|
||||
|
||||
CONS_Printf("ST_Init(): Init status bar.\n");
|
||||
ST_Init();
|
||||
|
|
125
src/d_net.c
125
src/d_net.c
|
@ -185,22 +185,10 @@ typedef struct
|
|||
UINT8 nextacknum;
|
||||
|
||||
UINT8 flags;
|
||||
#ifndef NEWPING
|
||||
// jacobson tcp timeout evaluation algorithm (Karn variation)
|
||||
fixed_t ping;
|
||||
fixed_t varping;
|
||||
INT32 timeout; // computed with ping and varping
|
||||
#endif
|
||||
} node_t;
|
||||
|
||||
static node_t nodes[MAXNETNODES];
|
||||
#ifndef NEWPING
|
||||
#define PINGDEFAULT ((200*TICRATE*FRACUNIT)/1000)
|
||||
#define VARPINGDEFAULT ((50*TICRATE*FRACUNIT)/1000)
|
||||
#define TIMEOUT(p,v) (p+4*v+FRACUNIT/2)>>FRACBITS;
|
||||
#else
|
||||
#define NODETIMEOUT 14 //What the above boiled down to...
|
||||
#endif
|
||||
#define NODETIMEOUT 14
|
||||
|
||||
#ifndef NONET
|
||||
// return <0 if a < b (mod 256)
|
||||
|
@ -320,19 +308,7 @@ static UINT8 GetAcktosend(INT32 node)
|
|||
static void RemoveAck(INT32 i)
|
||||
{
|
||||
INT32 node = ackpak[i].destinationnode;
|
||||
#ifndef NEWPING
|
||||
fixed_t trueping = (I_GetTime() - ackpak[i].senttime)<<FRACBITS;
|
||||
if (ackpak[i].resentnum)
|
||||
{
|
||||
// +FRACUNIT/2 for round
|
||||
nodes[node].ping = (nodes[node].ping*7 + trueping)/8;
|
||||
nodes[node].varping = (nodes[node].varping*7 + abs(nodes[node].ping-trueping))/8;
|
||||
nodes[node].timeout = TIMEOUT(nodes[node].ping,nodes[node].varping);
|
||||
}
|
||||
DEBFILE(va("Remove ack %d trueping %d ping %f var %f timeout %d\n",ackpak[i].acknum,trueping>>FRACBITS,(double)FIXED_TO_FLOAT(nodes[node].ping),(double)FIXED_TO_FLOAT(nodes[node].varping),nodes[node].timeout));
|
||||
#else
|
||||
DEBFILE(va("Remove ack %d\n",ackpak[i].acknum));
|
||||
#endif
|
||||
ackpak[i].acknum = 0;
|
||||
if (nodes[node].flags & NF_CLOSE)
|
||||
Net_CloseConnection(node);
|
||||
|
@ -519,11 +495,7 @@ void Net_AckTicker(void)
|
|||
{
|
||||
const INT32 nodei = ackpak[i].destinationnode;
|
||||
node_t *node = &nodes[nodei];
|
||||
#ifdef NEWPING
|
||||
if (ackpak[i].acknum && ackpak[i].senttime + NODETIMEOUT < I_GetTime())
|
||||
#else
|
||||
if (ackpak[i].acknum && ackpak[i].senttime + node->timeout < I_GetTime())
|
||||
#endif
|
||||
{
|
||||
if (ackpak[i].resentnum > 10 && (node->flags & NF_CLOSE))
|
||||
{
|
||||
|
@ -534,13 +506,8 @@ void Net_AckTicker(void)
|
|||
ackpak[i].acknum = 0;
|
||||
continue;
|
||||
}
|
||||
#ifdef NEWPING
|
||||
DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime,
|
||||
NODETIMEOUT, I_GetTime()));
|
||||
#else
|
||||
DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime,
|
||||
node->timeout, I_GetTime()));
|
||||
#endif
|
||||
M_Memcpy(netbuffer, ackpak[i].pak.raw, ackpak[i].length);
|
||||
ackpak[i].senttime = I_GetTime();
|
||||
ackpak[i].resentnum++;
|
||||
|
@ -658,11 +625,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
|
|||
static void InitNode(node_t *node)
|
||||
{
|
||||
node->acktosend_head = node->acktosend_tail = 0;
|
||||
#ifndef NEWPING
|
||||
node->ping = PINGDEFAULT;
|
||||
node->varping = VARPINGDEFAULT;
|
||||
node->timeout = TIMEOUT(node->ping, node->varping);
|
||||
#endif
|
||||
node->firstacktosend = 0;
|
||||
node->nextacknum = 1;
|
||||
node->remotefirstack = 0;
|
||||
|
@ -843,9 +805,7 @@ static const char *packettypename[NUMPACKETTYPE] =
|
|||
"CLIENTJOIN",
|
||||
"NODETIMEOUT",
|
||||
"RESYNCHING",
|
||||
#ifdef NEWPING
|
||||
"PING"
|
||||
#endif
|
||||
};
|
||||
|
||||
static void DebugPrintpacket(const char *header)
|
||||
|
@ -1384,30 +1344,73 @@ boolean D_CheckNetGame(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct pingcell
|
||||
{
|
||||
INT32 num;
|
||||
INT32 ms;
|
||||
};
|
||||
|
||||
static int pingcellcmp(const void *va, const void *vb)
|
||||
{
|
||||
const struct pingcell *a, *b;
|
||||
a = va;
|
||||
b = vb;
|
||||
return ( a->ms - b->ms );
|
||||
}
|
||||
|
||||
/*
|
||||
New ping command formatted nicely to present ping in
|
||||
ascending order. And with equally spaced columns.
|
||||
The caller's ping is presented at the bottom too, for
|
||||
convenience.
|
||||
*/
|
||||
|
||||
void Command_Ping_f(void)
|
||||
{
|
||||
#ifndef NEWPING
|
||||
if(server)
|
||||
struct pingcell pingv[MAXPLAYERS];
|
||||
INT32 pingc;
|
||||
|
||||
int name_width = 0;
|
||||
int ms_width = 0;
|
||||
|
||||
int n;
|
||||
INT32 i;
|
||||
|
||||
pingc = 0;
|
||||
for (i = 1; i < MAXPLAYERS; ++i)
|
||||
if (playeringame[i])
|
||||
{
|
||||
#endif
|
||||
INT32 i;
|
||||
for (i = 0; i < MAXPLAYERS;i++)
|
||||
{
|
||||
#ifndef NEWPING
|
||||
const INT32 node = playernode[i];
|
||||
if (playeringame[i] && node != 0)
|
||||
CONS_Printf(M_GetText("%.2d : %s\n %d tics, %d ms.\n"), i, player_names[i],
|
||||
GetLag(node), G_TicsToMilliseconds(GetLag(node)));
|
||||
#else
|
||||
if (playeringame[i] && i != 0)
|
||||
CONS_Printf(M_GetText("%.2d : %s\n %d ms\n"), i, player_names[i], playerpingtable[i]);
|
||||
#endif
|
||||
}
|
||||
#ifndef NEWPING
|
||||
n = strlen(player_names[i]);
|
||||
if (n > name_width)
|
||||
name_width = n;
|
||||
|
||||
n = playerpingtable[i];
|
||||
if (n > ms_width)
|
||||
ms_width = n;
|
||||
|
||||
pingv[pingc].num = i;
|
||||
pingv[pingc].ms = playerpingtable[i];
|
||||
pingc++;
|
||||
}
|
||||
|
||||
if (ms_width < 10) ms_width = 1;
|
||||
else if (ms_width < 100) ms_width = 2;
|
||||
else ms_width = 3;
|
||||
|
||||
qsort(pingv, pingc, sizeof (struct pingcell), &pingcellcmp);
|
||||
|
||||
for (i = 0; i < pingc; ++i)
|
||||
{
|
||||
CONS_Printf("%02d : %-*s %*d ms\n",
|
||||
pingv[i].num,
|
||||
name_width, player_names[pingv[i].num],
|
||||
ms_width, pingv[i].ms);
|
||||
}
|
||||
|
||||
if (!server && playeringame[consoleplayer])
|
||||
{
|
||||
CONS_Printf("\nYour ping is %d ms\n", playerpingtable[consoleplayer]);
|
||||
}
|
||||
else
|
||||
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void D_CloseConnection(void)
|
||||
|
|
|
@ -74,6 +74,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum);
|
|||
static void PointLimit_OnChange(void);
|
||||
static void TimeLimit_OnChange(void);
|
||||
static void NumLaps_OnChange(void);
|
||||
static void BaseNumLaps_OnChange(void);
|
||||
static void Mute_OnChange(void);
|
||||
|
||||
static void Hidetime_OnChange(void);
|
||||
|
@ -210,7 +211,7 @@ consvar_t cv_allowteamchange = {"allowteamchange", "Yes", CV_NETVAR, CV_YesNo, N
|
|||
|
||||
consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT, startingliveslimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t respawntime_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t respawntime_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||
consvar_t cv_respawntime = {"respawndelay", "3", CV_NETVAR|CV_CHEAT, respawntime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_competitionboxes = {"competitionboxes", "Mystery", CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -315,16 +316,17 @@ consvar_t cv_timetic = {"timerres", "Classic", CV_SAVE, timetic_cons_t, NULL, 0,
|
|||
static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}};
|
||||
consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t,
|
||||
static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, {0, "None"}, {0, NULL}};
|
||||
consvar_t cv_pointlimit = {"pointlimit", "None", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t,
|
||||
PointLimit_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_timelimit = {"timelimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t,
|
||||
static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}};
|
||||
consvar_t cv_timelimit = {"timelimit", "None", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t,
|
||||
TimeLimit_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t numlaps_cons_t[] = {{0, "MIN"}, {50, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_numlaps = {"numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t,
|
||||
NumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_usemapnumlaps = {"usemaplaps", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}};
|
||||
consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// log elemental hazards -- not a netvar, is local to current player
|
||||
consvar_t cv_hazardlog = {"hazardlog", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -340,9 +342,7 @@ static CV_PossibleValue_t nettimeout_cons_t[] = {{TICRATE/7, "MIN"}, {60*TICRATE
|
|||
consvar_t cv_nettimeout = {"nettimeout", "350", CV_CALL|CV_SAVE, nettimeout_cons_t, NetTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
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};
|
||||
#ifdef NEWPING
|
||||
consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif
|
||||
// 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};
|
||||
|
@ -497,7 +497,7 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_friendlyfire);
|
||||
CV_RegisterVar(&cv_pointlimit);
|
||||
CV_RegisterVar(&cv_numlaps);
|
||||
CV_RegisterVar(&cv_usemapnumlaps);
|
||||
CV_RegisterVar(&cv_basenumlaps);
|
||||
|
||||
CV_RegisterVar(&cv_hazardlog);
|
||||
|
||||
|
@ -573,9 +573,7 @@ void D_RegisterServerCommands(void)
|
|||
|
||||
CV_RegisterVar(&cv_skipmapcheck);
|
||||
CV_RegisterVar(&cv_sleep);
|
||||
#ifdef NEWPING
|
||||
CV_RegisterVar(&cv_maxping);
|
||||
#endif
|
||||
|
||||
#ifdef SEENAMES
|
||||
CV_RegisterVar(&cv_allowseenames);
|
||||
|
@ -740,6 +738,8 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_chasefreelook);
|
||||
CV_RegisterVar(&cv_chasefreelook2);
|
||||
CV_RegisterVar(&cv_tutorialprompt);
|
||||
CV_RegisterVar(&cv_showfocuslost);
|
||||
CV_RegisterVar(&cv_pauseifunfocused);
|
||||
|
||||
// g_input.c
|
||||
CV_RegisterVar(&cv_sideaxis);
|
||||
|
@ -879,7 +879,7 @@ void D_RegisterClientCommands(void)
|
|||
* \sa CleanupPlayerName, SetPlayerName, Got_NameAndColor
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
*/
|
||||
static boolean IsNameGood(char *name, INT32 playernum)
|
||||
boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
|
||||
{
|
||||
INT32 ix;
|
||||
|
||||
|
@ -920,14 +920,14 @@ static boolean IsNameGood(char *name, INT32 playernum)
|
|||
if (len > 1)
|
||||
{
|
||||
name[len-1] = '\0';
|
||||
if (!IsNameGood (name, playernum))
|
||||
if (!EnsurePlayerNameIsGood (name, playernum))
|
||||
return false;
|
||||
}
|
||||
else if (len == 1) // Agh!
|
||||
{
|
||||
// Last ditch effort...
|
||||
sprintf(name, "%d", M_RandomKey(10));
|
||||
if (!IsNameGood (name, playernum))
|
||||
if (!EnsurePlayerNameIsGood (name, playernum))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -1056,12 +1056,12 @@ static void CleanupPlayerName(INT32 playernum, const char *newname)
|
|||
* \param newname New name for that player. Should be good, but won't
|
||||
* necessarily be if the client is maliciously modified or
|
||||
* buggy.
|
||||
* \sa CleanupPlayerName, IsNameGood
|
||||
* \sa CleanupPlayerName, EnsurePlayerNameIsGood
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
*/
|
||||
static void SetPlayerName(INT32 playernum, char *newname)
|
||||
{
|
||||
if (IsNameGood(newname, playernum))
|
||||
if (EnsurePlayerNameIsGood(newname, playernum))
|
||||
{
|
||||
if (strcasecmp(newname, player_names[playernum]) != 0)
|
||||
{
|
||||
|
@ -1692,7 +1692,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
|||
// Kick bot from special stages
|
||||
if (botskin)
|
||||
{
|
||||
if (G_IsSpecialStage(mapnum))
|
||||
if (G_IsSpecialStage(mapnum) || (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->typeoflevel & TOL_NIGHTS)))
|
||||
{
|
||||
if (botingame)
|
||||
{
|
||||
|
@ -2032,8 +2032,6 @@ static void Command_Suicide(void)
|
|||
UINT8 buf[4];
|
||||
UINT8 *cp = buf;
|
||||
|
||||
WRITEINT32(cp, consoleplayer);
|
||||
|
||||
if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION))
|
||||
{
|
||||
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
||||
|
@ -2053,6 +2051,7 @@ static void Command_Suicide(void)
|
|||
return;
|
||||
}
|
||||
|
||||
WRITEINT32(cp, consoleplayer);
|
||||
SendNetXCmd(XD_SUICIDE, &buf, 4);
|
||||
}
|
||||
|
||||
|
@ -4465,3 +4464,14 @@ static void Command_ShowTime_f(void)
|
|||
|
||||
CONS_Printf(M_GetText("The current time is %f.\nThe timelimit is %f\n"), (double)leveltime/TICRATE, (double)timelimitintics/TICRATE);
|
||||
}
|
||||
|
||||
static void BaseNumLaps_OnChange(void)
|
||||
{
|
||||
if (gametype == GT_RACE)
|
||||
{
|
||||
if (cv_basenumlaps.value)
|
||||
CONS_Printf(M_GetText("Number of laps will be changed to map defaults next round.\n"));
|
||||
else
|
||||
CONS_Printf(M_GetText("Number of laps will be changed to %d next round.\n"), cv_basenumlaps.value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ extern consvar_t cv_friendlyfire;
|
|||
extern consvar_t cv_pointlimit;
|
||||
extern consvar_t cv_timelimit;
|
||||
extern consvar_t cv_numlaps;
|
||||
extern consvar_t cv_usemapnumlaps;
|
||||
extern consvar_t cv_basenumlaps;
|
||||
extern UINT32 timelimitintics;
|
||||
extern consvar_t cv_allowexitlevel;
|
||||
|
||||
|
@ -107,9 +107,7 @@ extern consvar_t cv_ringslinger, cv_soundtest;
|
|||
|
||||
extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes;
|
||||
|
||||
#ifdef NEWPING
|
||||
extern consvar_t cv_maxping;
|
||||
#endif
|
||||
|
||||
extern consvar_t cv_skipmapcheck;
|
||||
|
||||
|
@ -190,6 +188,7 @@ typedef union {
|
|||
// add game commands, needs cleanup
|
||||
void D_RegisterServerCommands(void);
|
||||
void D_RegisterClientCommands(void);
|
||||
boolean EnsurePlayerNameIsGood(char *name, INT32 playernum);
|
||||
void D_SendPlayerConfig(void);
|
||||
void Command_ExitGame_f(void);
|
||||
void Command_Retry_f(void);
|
||||
|
|
|
@ -252,6 +252,8 @@ typedef enum
|
|||
pw_spacetime, // In space, no one can hear you spin!
|
||||
pw_extralife, // Extra Life timer
|
||||
pw_pushing,
|
||||
pw_justsprung,
|
||||
pw_noautobrake,
|
||||
|
||||
pw_super, // Are you super?
|
||||
pw_gravityboots, // gravity boots
|
||||
|
|
153
src/dehacked.c
153
src/dehacked.c
|
@ -313,7 +313,13 @@ static boolean findFreeSlot(INT32 *num)
|
|||
if (*num >= MAXSKINS)
|
||||
return false;
|
||||
|
||||
description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
|
||||
// Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
|
||||
description[*num].picname[0] = '\0';
|
||||
description[*num].nametag[0] = '\0';
|
||||
description[*num].displayname[0] = '\0';
|
||||
description[*num].oppositecolor = SKINCOLOR_NONE;
|
||||
description[*num].tagtextcolor = SKINCOLOR_NONE;
|
||||
description[*num].tagoutlinecolor = SKINCOLOR_NONE;
|
||||
|
||||
// Found one! ^_^
|
||||
return (description[*num].used = true);
|
||||
|
@ -326,9 +332,16 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
char *displayname = ZZ_Alloc(MAXLINELEN+1);
|
||||
INT32 i;
|
||||
boolean slotfound = false;
|
||||
|
||||
#define SLOTFOUND \
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false) \
|
||||
goto done;
|
||||
|
||||
displayname[MAXLINELEN] = '\0';
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
|
@ -336,6 +349,17 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
for (i = 0; i < MAXLINELEN-3; i++)
|
||||
{
|
||||
char *tmp;
|
||||
if (s[i] == '=')
|
||||
{
|
||||
tmp = &s[i+2];
|
||||
strncpy(displayname, tmp, SKINNAMESIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
|
@ -346,8 +370,7 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
{
|
||||
char *playertext = NULL;
|
||||
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
SLOTFOUND
|
||||
|
||||
for (i = 0; i < MAXLINELEN-3; i++)
|
||||
{
|
||||
|
@ -395,11 +418,54 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
|
||||
if (fastcmp(word, "PICNAME"))
|
||||
{
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
|
||||
SLOTFOUND
|
||||
strncpy(description[num].picname, word2, 8);
|
||||
}
|
||||
// new character select
|
||||
else if (fastcmp(word, "DISPLAYNAME"))
|
||||
{
|
||||
SLOTFOUND
|
||||
// replace '#' with line breaks
|
||||
// (also remove any '\n')
|
||||
{
|
||||
char *cur = NULL;
|
||||
|
||||
// remove '\n'
|
||||
cur = strchr(displayname, '\n');
|
||||
if (cur)
|
||||
*cur = '\0';
|
||||
|
||||
// turn '#' into '\n'
|
||||
cur = strchr(displayname, '#');
|
||||
while (cur)
|
||||
{
|
||||
*cur = '\n';
|
||||
cur = strchr(cur, '#');
|
||||
}
|
||||
}
|
||||
// copy final string
|
||||
strncpy(description[num].displayname, displayname, SKINNAMESIZE);
|
||||
}
|
||||
else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR"))
|
||||
{
|
||||
SLOTFOUND
|
||||
description[num].oppositecolor = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME"))
|
||||
{
|
||||
SLOTFOUND
|
||||
strncpy(description[num].nametag, word2, 8);
|
||||
}
|
||||
else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR"))
|
||||
{
|
||||
SLOTFOUND
|
||||
description[num].tagtextcolor = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "TAGOUTLINECOLOR") || fastcmp(word, "TAGOUTLINECOLOUR"))
|
||||
{
|
||||
SLOTFOUND
|
||||
description[num].tagoutlinecolor = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "STATUS"))
|
||||
{
|
||||
/*
|
||||
|
@ -417,9 +483,7 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
else if (fastcmp(word, "SKINNAME"))
|
||||
{
|
||||
// Send to free slot.
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
|
||||
SLOTFOUND
|
||||
strlcpy(description[num].skinname, word2, sizeof description[num].skinname);
|
||||
strlwr(description[num].skinname);
|
||||
}
|
||||
|
@ -427,8 +491,9 @@ static void readPlayer(MYFILE *f, INT32 num)
|
|||
deh_warning("readPlayer %d: unknown word '%s'", num, word);
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
#undef SLOTFOUND
|
||||
done:
|
||||
Z_Free(displayname);
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
|
@ -4443,6 +4508,21 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_CRUSHCLAW_WAIT",
|
||||
"S_CRUSHCHAIN",
|
||||
|
||||
// Banpyura
|
||||
"S_BANPYURA_ROAM1",
|
||||
"S_BANPYURA_ROAM2",
|
||||
"S_BANPYURA_ROAM3",
|
||||
"S_BANPYURA_ROAM4",
|
||||
"S_BANPYURA_ROAMPAUSE",
|
||||
"S_CDIAG1",
|
||||
"S_CDIAG2",
|
||||
"S_CDIAG3",
|
||||
"S_CDIAG4",
|
||||
"S_CDIAG5",
|
||||
"S_CDIAG6",
|
||||
"S_CDIAG7",
|
||||
"S_CDIAG8",
|
||||
|
||||
// Jet Jaw
|
||||
"S_JETJAW_ROAM1",
|
||||
"S_JETJAW_ROAM2",
|
||||
|
@ -5909,6 +5989,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_FLAMEJETFLAME1",
|
||||
"S_FLAMEJETFLAME2",
|
||||
"S_FLAMEJETFLAME3",
|
||||
"S_FLAMEJETFLAME4",
|
||||
"S_FLAMEJETFLAME5",
|
||||
"S_FLAMEJETFLAME6",
|
||||
"S_FLAMEJETFLAME7",
|
||||
"S_FLAMEJETFLAME8",
|
||||
"S_FLAMEJETFLAME9",
|
||||
|
||||
// Spinning flame jets
|
||||
"S_FJSPINAXISA1", // Counter-clockwise
|
||||
|
@ -5974,6 +6060,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_TARGET_RESPAWN",
|
||||
"S_TARGET_ALLDONE",
|
||||
|
||||
// ATZ's green flame
|
||||
"S_GREENFLAME",
|
||||
|
||||
// Stalagmites
|
||||
"S_STG0",
|
||||
"S_STG1",
|
||||
|
@ -6663,6 +6752,16 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_BHORIZ7",
|
||||
"S_BHORIZ8",
|
||||
|
||||
"S_BOOSTERSOUND",
|
||||
"S_YELLOWBOOSTERROLLER",
|
||||
"S_YELLOWBOOSTERSEG_LEFT",
|
||||
"S_YELLOWBOOSTERSEG_RIGHT",
|
||||
"S_YELLOWBOOSTERSEG_FACE",
|
||||
"S_REDBOOSTERROLLER",
|
||||
"S_REDBOOSTERSEG_LEFT",
|
||||
"S_REDBOOSTERSEG_RIGHT",
|
||||
"S_REDBOOSTERSEG_FACE",
|
||||
|
||||
// Rain
|
||||
"S_RAIN1",
|
||||
"S_RAINRETURN",
|
||||
|
@ -7316,6 +7415,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_CRUSHSTACEAN", // Crushstacean
|
||||
"MT_CRUSHCLAW", // Big meaty claw
|
||||
"MT_CRUSHCHAIN", // Chain
|
||||
"MT_BANPYURA", // Banpyura
|
||||
"MT_BANPSPRING", // Banpyura spring
|
||||
"MT_JETJAW", // Jet Jaw
|
||||
"MT_SNAILER", // Snailer
|
||||
"MT_VULTURE", // BASH
|
||||
|
@ -7453,6 +7554,11 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_REDHORIZ",
|
||||
"MT_BLUEHORIZ",
|
||||
|
||||
"MT_BOOSTERSEG",
|
||||
"MT_BOOSTERROLLER",
|
||||
"MT_YELLOWBOOSTER",
|
||||
"MT_REDBOOSTER",
|
||||
|
||||
// Interactive Objects
|
||||
"MT_BUBBLES", // Bubble source
|
||||
"MT_SIGN", // Level end sign
|
||||
|
@ -7711,6 +7817,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_TRAPGOYLEDOWN",
|
||||
"MT_TRAPGOYLELONG",
|
||||
"MT_TARGET",
|
||||
"MT_GREENFLAME",
|
||||
|
||||
// Stalagmites
|
||||
"MT_STALAGMITE0",
|
||||
|
@ -8356,6 +8463,8 @@ static const char *const POWERS_LIST[] = {
|
|||
"SPACETIME", // In space, no one can hear you spin!
|
||||
"EXTRALIFE", // Extra Life timer
|
||||
"PUSHING",
|
||||
"JUSTSPRUNG",
|
||||
"NOAUTOBRAKE",
|
||||
|
||||
"SUPER", // Are you super?
|
||||
"GRAVITYBOOTS", // gravity boots
|
||||
|
@ -8919,9 +9028,9 @@ struct {
|
|||
{"FF_PLATFORM",FF_PLATFORM}, ///< You can jump up through this to the top.
|
||||
{"FF_REVERSEPLATFORM",FF_REVERSEPLATFORM}, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
|
||||
{"FF_INTANGABLEFLATS",FF_INTANGABLEFLATS}, ///< Both flats are intangable, but the sides are still solid.
|
||||
{"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Thinks everyone's Knuckles.
|
||||
{"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Jump or fall onto it while curled in a ball.
|
||||
{"FF_ONLYKNUX",FF_ONLYKNUX}, ///< Used with ::FF_BUSTUP. Only Knuckles can break this rock.
|
||||
{"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Bustable on mere touch.
|
||||
{"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames.
|
||||
{"FF_STRONGBUST",FF_STRONGBUST }, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
|
||||
{"FF_RIPPLE",FF_RIPPLE}, ///< Ripple the flats
|
||||
{"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel
|
||||
{"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
|
||||
|
@ -9052,6 +9161,7 @@ struct {
|
|||
{"V_OFFSET",V_OFFSET},
|
||||
{"V_ALLOWLOWERCASE",V_ALLOWLOWERCASE},
|
||||
{"V_FLIP",V_FLIP},
|
||||
{"V_CENTERNAMETAG",V_CENTERNAMETAG},
|
||||
{"V_SNAPTOTOP",V_SNAPTOTOP},
|
||||
{"V_SNAPTOBOTTOM",V_SNAPTOBOTTOM},
|
||||
{"V_SNAPTOLEFT",V_SNAPTOLEFT},
|
||||
|
@ -10072,6 +10182,23 @@ static inline int lib_getenum(lua_State *L)
|
|||
} else if (fastcmp(word,"mapmusposition")) {
|
||||
lua_pushinteger(L, mapmusposition);
|
||||
return 1;
|
||||
// local player variables, by popular request
|
||||
} else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1)
|
||||
if (consoleplayer < 0 || !playeringame[consoleplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"displayplayer")) { // player visible on screen (aka display player 1)
|
||||
if (displayplayer < 0 || !playeringame[displayplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[displayplayer], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen
|
||||
if (!splitscreen || secondarydisplayplayer < 0 || !playeringame[secondarydisplayplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER);
|
||||
return 1;
|
||||
// end local player variables
|
||||
} else if (fastcmp(word,"server")) {
|
||||
if ((!multiplayer || !netgame) && !playeringame[serverplayer])
|
||||
return 0;
|
||||
|
|
|
@ -509,13 +509,17 @@ INT32 I_GetKey(void);
|
|||
// Max gamepad/joysticks that can be detected/used.
|
||||
#define MAX_JOYSTICKS 4
|
||||
|
||||
#ifndef M_PIl
|
||||
#define M_PIl 3.1415926535897932384626433832795029L
|
||||
#endif
|
||||
|
||||
// Floating point comparison epsilons from float.h
|
||||
#ifndef FLT_EPSILON
|
||||
#define FLT_EPSILON 1.1920928955078125e-7f
|
||||
#endif
|
||||
|
||||
#ifndef DBL_EPSILON
|
||||
#define DBL_EPSILON 2.2204460492503131e-16
|
||||
#define DBL_EPSILON 2.2204460492503131e-16l
|
||||
#endif
|
||||
|
||||
// An assert-type mechanism.
|
||||
|
@ -561,9 +565,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
|||
/// Polyobject fake flat code
|
||||
#define POLYOBJECTS_PLANES
|
||||
|
||||
/// Improved way of dealing with ping values and a ping limit.
|
||||
#define NEWPING
|
||||
|
||||
/// See name of player in your crosshair
|
||||
#define SEENAMES
|
||||
|
||||
|
|
|
@ -327,7 +327,7 @@ typedef struct
|
|||
// Music stuff.
|
||||
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
|
||||
char musintername[7]; ///< Intermission screen music.
|
||||
|
||||
|
||||
char muspostbossname[7]; ///< Post-bossdeath music.
|
||||
UINT16 muspostbosstrack; ///< Post-bossdeath track.
|
||||
UINT32 muspostbosspos; ///< Post-bossdeath position
|
||||
|
@ -433,6 +433,7 @@ 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.
|
||||
|
|
|
@ -75,6 +75,7 @@ INT32 curbgcolor;
|
|||
INT32 curbgxspeed;
|
||||
INT32 curbgyspeed;
|
||||
boolean curbghide;
|
||||
boolean hidetitlemap; // WARNING: set to false by M_SetupNextMenu and M_ClearMenus
|
||||
|
||||
static UINT8 curDemo = 0;
|
||||
static UINT32 demoDelayLeft;
|
||||
|
@ -1585,15 +1586,15 @@ void F_StartEnding(void)
|
|||
UINT8 skinnum = players[consoleplayer].skin;
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 7)
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= (XTRA_ENDING+2)+1)
|
||||
{
|
||||
sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
// character head, skin specific
|
||||
sprframe = &sprdef->spriteframes[4];
|
||||
sprframe = &sprdef->spriteframes[XTRA_ENDING];
|
||||
endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
|
||||
sprframe = &sprdef->spriteframes[5];
|
||||
sprframe = &sprdef->spriteframes[XTRA_ENDING+1];
|
||||
endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
|
||||
sprframe = &sprdef->spriteframes[6];
|
||||
sprframe = &sprdef->spriteframes[XTRA_ENDING+2];
|
||||
endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
|
||||
}
|
||||
else // Show a star if your character doesn't have an ending firework display. (Basically the MISSINGs for this)
|
||||
|
@ -2098,12 +2099,12 @@ void F_InitMenuPresValues(void)
|
|||
curfadevalue = 16;
|
||||
curhidepics = hidetitlepics;
|
||||
curbgcolor = -1;
|
||||
curbgxspeed = titlescrollxspeed;
|
||||
curbgyspeed = titlescrollyspeed;
|
||||
curbghide = true;
|
||||
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
|
||||
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 22 : titlescrollyspeed;
|
||||
curbghide = (gamestate == GS_TIMEATTACK) ? false : true;
|
||||
|
||||
// Find current presentation values
|
||||
M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "SRB2BACK" : "TITLESKY");
|
||||
M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "RECATTBG" : "TITLESKY");
|
||||
M_SetMenuCurFadeValue(16);
|
||||
M_SetMenuCurHideTitlePics();
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ extern INT32 curbgcolor;
|
|||
extern INT32 curbgxspeed;
|
||||
extern INT32 curbgyspeed;
|
||||
extern boolean curbghide;
|
||||
extern boolean hidetitlemap;
|
||||
|
||||
#define TITLEBACKGROUNDACTIVE (curfadevalue >= 0 || curbgname[0])
|
||||
|
||||
|
|
127
src/g_game.c
127
src/g_game.c
|
@ -361,6 +361,8 @@ consvar_t cv_chatbacktint = {"chatbacktint", "On", CV_SAVE, CV_OnOff, NULL, 0, N
|
|||
static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}};
|
||||
consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Pause game upon window losing focus
|
||||
consvar_t cv_pauseifunfocused = {"pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -1713,65 +1715,6 @@ static INT32 camtoggledelay, camtoggledelay2 = 0;
|
|||
//
|
||||
boolean G_Responder(event_t *ev)
|
||||
{
|
||||
// allow spy mode changes even during the demo
|
||||
if (gamestate == GS_LEVEL && ev->type == ev_keydown
|
||||
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1]))
|
||||
{
|
||||
if (splitscreen || !netgame)
|
||||
displayplayer = consoleplayer;
|
||||
else
|
||||
{
|
||||
// spy mode
|
||||
do
|
||||
{
|
||||
displayplayer++;
|
||||
if (displayplayer == MAXPLAYERS)
|
||||
displayplayer = 0;
|
||||
|
||||
if (!playeringame[displayplayer])
|
||||
continue;
|
||||
|
||||
if (players[displayplayer].spectator)
|
||||
continue;
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (players[consoleplayer].ctfteam
|
||||
&& players[displayplayer].ctfteam != players[consoleplayer].ctfteam)
|
||||
continue;
|
||||
}
|
||||
else if (gametype == GT_HIDEANDSEEK)
|
||||
{
|
||||
if (players[consoleplayer].pflags & PF_TAGIT)
|
||||
continue;
|
||||
}
|
||||
// Other Tag-based gametypes?
|
||||
else if (G_TagGametype())
|
||||
{
|
||||
if (!players[consoleplayer].spectator
|
||||
&& (players[consoleplayer].pflags & PF_TAGIT) != (players[displayplayer].pflags & PF_TAGIT))
|
||||
continue;
|
||||
}
|
||||
else if (G_GametypeHasSpectators() && G_RingSlingerGametype())
|
||||
{
|
||||
if (!players[consoleplayer].spectator)
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
} while (displayplayer != consoleplayer);
|
||||
|
||||
// change statusbar also if playing back demo
|
||||
if (singledemo)
|
||||
ST_changeDemoView();
|
||||
|
||||
// tell who's the view
|
||||
CONS_Printf(M_GetText("Viewpoint: %s\n"), player_names[displayplayer]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// any other key pops up menu if in demos
|
||||
if (gameaction == ga_nothing && !singledemo &&
|
||||
((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN))
|
||||
|
@ -1848,6 +1791,65 @@ boolean G_Responder(event_t *ev)
|
|||
if (HU_Responder(ev))
|
||||
return true; // chat ate the event
|
||||
|
||||
// allow spy mode changes even during the demo
|
||||
if (gamestate == GS_LEVEL && ev->type == ev_keydown
|
||||
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1]))
|
||||
{
|
||||
if (splitscreen || !netgame)
|
||||
displayplayer = consoleplayer;
|
||||
else
|
||||
{
|
||||
// spy mode
|
||||
do
|
||||
{
|
||||
displayplayer++;
|
||||
if (displayplayer == MAXPLAYERS)
|
||||
displayplayer = 0;
|
||||
|
||||
if (!playeringame[displayplayer])
|
||||
continue;
|
||||
|
||||
if (players[displayplayer].spectator)
|
||||
continue;
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (players[consoleplayer].ctfteam
|
||||
&& players[displayplayer].ctfteam != players[consoleplayer].ctfteam)
|
||||
continue;
|
||||
}
|
||||
else if (gametype == GT_HIDEANDSEEK)
|
||||
{
|
||||
if (players[consoleplayer].pflags & PF_TAGIT)
|
||||
continue;
|
||||
}
|
||||
// Other Tag-based gametypes?
|
||||
else if (G_TagGametype())
|
||||
{
|
||||
if (!players[consoleplayer].spectator
|
||||
&& (players[consoleplayer].pflags & PF_TAGIT) != (players[displayplayer].pflags & PF_TAGIT))
|
||||
continue;
|
||||
}
|
||||
else if (G_GametypeHasSpectators() && G_RingSlingerGametype())
|
||||
{
|
||||
if (!players[consoleplayer].spectator)
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
} while (displayplayer != consoleplayer);
|
||||
|
||||
// change statusbar also if playing back demo
|
||||
if (singledemo)
|
||||
ST_changeDemoView();
|
||||
|
||||
// tell who's the view
|
||||
CONS_Printf(M_GetText("Viewpoint: %s\n"), player_names[displayplayer]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// update keys current state
|
||||
G_MapEventsToControls(ev);
|
||||
|
||||
|
@ -3341,6 +3343,7 @@ void G_LoadGameData(void)
|
|||
UINT32 recscore;
|
||||
tic_t rectime;
|
||||
UINT16 recrings;
|
||||
boolean gotperf;
|
||||
|
||||
UINT8 recmares;
|
||||
INT32 curmare;
|
||||
|
@ -3433,6 +3436,7 @@ void G_LoadGameData(void)
|
|||
recscore = READUINT32(save_p);
|
||||
rectime = (tic_t)READUINT32(save_p);
|
||||
recrings = READUINT16(save_p);
|
||||
gotperf = (boolean)READUINT8(save_p);
|
||||
|
||||
if (recrings > 10000 || recscore > MAXSCORE)
|
||||
goto datacorrupt;
|
||||
|
@ -3444,6 +3448,9 @@ void G_LoadGameData(void)
|
|||
mainrecords[i]->time = rectime;
|
||||
mainrecords[i]->rings = recrings;
|
||||
}
|
||||
|
||||
if (gotperf)
|
||||
mainrecords[i]->gotperfect = gotperf;
|
||||
}
|
||||
|
||||
// Nights records
|
||||
|
@ -3575,12 +3582,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@ extern boolean pausebreakkey;
|
|||
|
||||
extern boolean promptactive;
|
||||
|
||||
extern consvar_t cv_pauseifunfocused;
|
||||
|
||||
// used in game menu
|
||||
extern consvar_t cv_tutorialprompt;
|
||||
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard;
|
||||
|
|
|
@ -201,7 +201,7 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
|
|||
// (do not accept hit with the extensions)
|
||||
num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx;
|
||||
frac = num / den;
|
||||
if (frac < 0.0 || frac > 1.0)
|
||||
if (frac < 0.0l || frac > 1.0l)
|
||||
return NULL;
|
||||
|
||||
// now get the frac along the BSP line
|
||||
|
|
|
@ -61,9 +61,6 @@ typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR;
|
|||
// ==========================================================================
|
||||
|
||||
// Constants
|
||||
#ifndef M_PIl
|
||||
#define M_PIl 3.1415926535897932384626433832795029L
|
||||
#endif
|
||||
#define DEGREE (0.017453292519943295769236907684883l) // 2*PI/360
|
||||
|
||||
void DBG_Printf(const char *lpFmt, ...) /*FUNCPRINTF*/;
|
||||
|
|
|
@ -162,6 +162,8 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_TURR
|
||||
&lspr[NOLIGHT], // SPR_SHRP
|
||||
&lspr[NOLIGHT], // SPR_CRAB
|
||||
&lspr[NOLIGHT], // SPR_CR2B
|
||||
&lspr[NOLIGHT], // SPR_CSPR
|
||||
&lspr[NOLIGHT], // SPR_JJAW
|
||||
&lspr[NOLIGHT], // SPR_SNLR
|
||||
&lspr[NOLIGHT], // SPR_VLTR
|
||||
|
@ -199,7 +201,7 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_EGGO
|
||||
&lspr[NOLIGHT], // SPR_SEBH
|
||||
&lspr[NOLIGHT], // SPR_FAKE
|
||||
&lspr[NOLIGHT], // SPR_SHCK
|
||||
&lspr[LBLUESHINE_L],// SPR_SHCK
|
||||
|
||||
// Boss 4 (Castle Eggman)
|
||||
&lspr[NOLIGHT], // SPR_EGGP
|
||||
|
@ -404,6 +406,11 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_HHPL
|
||||
&lspr[NOLIGHT], // SPR_SHRM
|
||||
&lspr[NOLIGHT], // SPR_HHZM
|
||||
|
||||
// Azure Temple Scenery
|
||||
&lspr[NOLIGHT], // SPR_BGAR
|
||||
&lspr[NOLIGHT], // SPR_RCRY
|
||||
&lspr[GREENBALL_L], // SPR_CFLM
|
||||
|
||||
// Botanic Serenity Scenery
|
||||
&lspr[NOLIGHT], // SPR_BSZ1
|
||||
|
@ -424,7 +431,6 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
// Misc Scenery
|
||||
&lspr[NOLIGHT], // SPR_STLG
|
||||
&lspr[NOLIGHT], // SPR_DBAL
|
||||
&lspr[NOLIGHT], // SPR_RCRY
|
||||
|
||||
// Powerup Indicators
|
||||
&lspr[NOLIGHT], // SPR_ARMA
|
||||
|
@ -478,6 +484,8 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_SSWY
|
||||
&lspr[NOLIGHT], // SPR_SSWR
|
||||
&lspr[NOLIGHT], // SPR_SSWB
|
||||
&lspr[NOLIGHT], // SPR_BSTY
|
||||
&lspr[NOLIGHT], // SPR_BSTR
|
||||
|
||||
// Environmental Effects
|
||||
&lspr[NOLIGHT], // SPR_RAIN
|
||||
|
|
|
@ -71,6 +71,10 @@ patch_t *lt_font[LT_FONTSIZE];
|
|||
patch_t *cred_font[CRED_FONTSIZE];
|
||||
patch_t *ttlnum[20]; // act numbers (0-19)
|
||||
|
||||
// Name tag fonts
|
||||
patch_t *ntb_font[NT_FONTSIZE];
|
||||
patch_t *nto_font[NT_FONTSIZE];
|
||||
|
||||
static player_t *plr;
|
||||
boolean chat_on; // entering a chat message?
|
||||
static char w_chat[HU_MAXMSGLEN];
|
||||
|
@ -246,6 +250,32 @@ void HU_LoadGraphics(void)
|
|||
ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
// cache the base name tag font for entire game execution
|
||||
j = NT_FONTSTART;
|
||||
for (i = 0; i < NT_FONTSIZE; i++)
|
||||
{
|
||||
sprintf(buffer, "NTFNT%.3d", j);
|
||||
j++;
|
||||
|
||||
if (W_CheckNumForName(buffer) == LUMPERROR)
|
||||
ntb_font[i] = NULL;
|
||||
else
|
||||
ntb_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
// cache the outline name tag font for entire game execution
|
||||
j = NT_FONTSTART;
|
||||
for (i = 0; i < NT_FONTSIZE; i++)
|
||||
{
|
||||
sprintf(buffer, "NTFNO%.3d", j);
|
||||
j++;
|
||||
|
||||
if (W_CheckNumForName(buffer) == LUMPERROR)
|
||||
nto_font[i] = NULL;
|
||||
else
|
||||
nto_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
// cache the crosshairs, don't bother to know which one is being used,
|
||||
// just cache all 3, they're so small anyway.
|
||||
for (i = 0; i < HU_CROSSHAIRS; i++)
|
||||
|
|
|
@ -35,6 +35,12 @@
|
|||
#define CRED_FONTEND 'Z' // the last font character
|
||||
#define CRED_FONTSIZE (CRED_FONTEND - CRED_FONTSTART + 1)
|
||||
|
||||
// Name tag font
|
||||
// Used by base and outline font set
|
||||
#define NT_FONTSTART '!' // the first font character
|
||||
#define NT_FONTEND 'Z' // the last font character
|
||||
#define NT_FONTSIZE (NT_FONTEND - NT_FONTSTART + 1)
|
||||
|
||||
#define HU_CROSSHAIRS 3 // maximum of 9 - see HU_Init();
|
||||
|
||||
extern char *shiftxform; // english translation shift table
|
||||
|
@ -77,6 +83,8 @@ extern patch_t *tallnum[10];
|
|||
extern patch_t *nightsnum[10];
|
||||
extern patch_t *lt_font[LT_FONTSIZE];
|
||||
extern patch_t *cred_font[CRED_FONTSIZE];
|
||||
extern patch_t *ntb_font[NT_FONTSIZE];
|
||||
extern patch_t *nto_font[NT_FONTSIZE];
|
||||
extern patch_t *ttlnum[20];
|
||||
extern patch_t *emeraldpics[3][8];
|
||||
extern patch_t *rflagico;
|
||||
|
|
36
src/i_tcp.c
36
src/i_tcp.c
|
@ -776,6 +776,8 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
#endif
|
||||
#endif
|
||||
mysockaddr_t straddr;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len = sizeof(sin);
|
||||
|
||||
if (s == (SOCKET_TYPE)ERRSOCKET)
|
||||
return (SOCKET_TYPE)ERRSOCKET;
|
||||
|
@ -869,12 +871,16 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
|
||||
}
|
||||
|
||||
if (getsockname(s, (struct sockaddr *)&sin, &len) == -1)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n"));
|
||||
else
|
||||
current_port = (UINT16)ntohs(sin.sin_port);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static boolean UDP_Socket(void)
|
||||
{
|
||||
const char *sock_port = NULL;
|
||||
size_t s;
|
||||
struct my_addrinfo *ai, *runp, hints;
|
||||
int gaie;
|
||||
|
@ -896,20 +902,11 @@ static boolean UDP_Socket(void)
|
|||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
if (M_CheckParm("-clientport"))
|
||||
{
|
||||
if (!M_IsNextParm())
|
||||
I_Error("syntax: -clientport <portnum>");
|
||||
sock_port = M_GetNextParm();
|
||||
}
|
||||
else
|
||||
sock_port = port_name;
|
||||
|
||||
if (M_CheckParm("-bindaddr"))
|
||||
{
|
||||
while (M_IsNextParm())
|
||||
{
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), sock_port, &hints, &ai);
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -930,7 +927,7 @@ static boolean UDP_Socket(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
gaie = I_getaddrinfo("0.0.0.0", sock_port, &hints, &ai);
|
||||
gaie = I_getaddrinfo("0.0.0.0", port_name, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -945,8 +942,8 @@ static boolean UDP_Socket(void)
|
|||
#ifdef HAVE_MINIUPNPC
|
||||
if (UPNP_support)
|
||||
{
|
||||
I_UPnP_rem(sock_port, "UDP");
|
||||
I_UPnP_add(NULL, sock_port, "UDP");
|
||||
I_UPnP_rem(port_name, "UDP");
|
||||
I_UPnP_add(NULL, port_name, "UDP");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -963,7 +960,7 @@ static boolean UDP_Socket(void)
|
|||
{
|
||||
while (M_IsNextParm())
|
||||
{
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), sock_port, &hints, &ai);
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -984,7 +981,7 @@ static boolean UDP_Socket(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
gaie = I_getaddrinfo("::", sock_port, &hints, &ai);
|
||||
gaie = I_getaddrinfo("::", port_name, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -1260,7 +1257,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
|||
int gaie;
|
||||
|
||||
if (!port || !port[0])
|
||||
port = port_name;
|
||||
port = DEFAULTPORT;
|
||||
|
||||
DEBFILE(va("Creating new node: %s@%s\n", address, port));
|
||||
|
||||
|
@ -1424,14 +1421,15 @@ boolean I_InitTcpNetwork(void)
|
|||
if (!I_InitTcpDriver())
|
||||
return false;
|
||||
|
||||
if (M_CheckParm("-udpport"))
|
||||
if (M_CheckParm("-port"))
|
||||
// Combined -udpport and -clientport into -port
|
||||
// As it was really redundant having two seperate parms that does the same thing
|
||||
{
|
||||
if (M_IsNextParm())
|
||||
strcpy(port_name, M_GetNextParm());
|
||||
else
|
||||
strcpy(port_name, "0");
|
||||
}
|
||||
current_port = (UINT16)atoi(port_name);
|
||||
|
||||
// parse network game options,
|
||||
if (M_CheckParm("-server") || dedicated)
|
||||
|
|
305
src/info.c
305
src/info.c
|
@ -50,6 +50,8 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"TURR", // Pop-Up Turret
|
||||
"SHRP", // Sharp
|
||||
"CRAB", // Crushstacean
|
||||
"CR2B", // Banpyura
|
||||
"CSPR", // Banpyura spring
|
||||
"JJAW", // Jet Jaw
|
||||
"SNLR", // Snailer
|
||||
"VLTR", // BASH
|
||||
|
@ -299,6 +301,11 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"SHRM", // Mushroom
|
||||
"HHZM", // Misc
|
||||
|
||||
// Azure Temple Scenery
|
||||
"BGAR", // ATZ Gargoyles
|
||||
"RCRY", // ATZ Red Crystal (Target)
|
||||
"CFLM", // Green torch flame
|
||||
|
||||
// Botanic Serenity Scenery
|
||||
"BSZ1", // Tall flowers
|
||||
"BSZ2", // Medium flowers
|
||||
|
@ -318,7 +325,6 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
// Misc Scenery
|
||||
"STLG", // Stalagmites
|
||||
"DBAL", // Disco
|
||||
"RCRY", // ATZ Red Crystal (Target)
|
||||
|
||||
// Powerup Indicators
|
||||
"ARMA", // Armageddon Shield Orb
|
||||
|
@ -372,6 +378,8 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"SSWY", // Yellow Side Spring
|
||||
"SSWR", // Red Side Spring
|
||||
"SSWB", // Blue Side Spring
|
||||
"BSTY", // Yellow Booster
|
||||
"BSTR", // Red Booster
|
||||
|
||||
// Environmental Effects
|
||||
"RAIN", // Rain
|
||||
|
@ -1008,6 +1016,22 @@ state_t states[NUMSTATES] =
|
|||
{SPR_CRAB, 3, 37, {NULL}, 0, 0, S_CRUSHCLAW_AIM}, // S_CRUSHCLAW_WAIT
|
||||
{SPR_CRAB, 4, -1, {NULL}, 0, 0, S_NULL}, // S_CRUSHCHAIN
|
||||
|
||||
// Banpyura
|
||||
{SPR_CR2B, 0, 3, {A_CrushstaceanWalk}, 0, S_BANPYURA_ROAMPAUSE, S_BANPYURA_ROAM2}, // S_BANPYURA_ROAM1
|
||||
{SPR_CR2B, 1, 3, {A_CrushstaceanWalk}, 0, S_BANPYURA_ROAMPAUSE, S_BANPYURA_ROAM3}, // S_BANPYURA_ROAM2
|
||||
{SPR_CR2B, 0, 3, {A_CrushstaceanWalk}, 0, S_BANPYURA_ROAMPAUSE, S_BANPYURA_ROAM4}, // S_BANPYURA_ROAM3
|
||||
{SPR_CR2B, 2, 3, {A_CrushstaceanWalk}, 0, S_BANPYURA_ROAMPAUSE, S_BANPYURA_ROAM1}, // S_BANPYURA_ROAM4
|
||||
{SPR_CR2B, 0, 40, {NULL}, 0, 0, S_BANPYURA_ROAM1}, // S_BANPYURA_ROAMPAUSE
|
||||
|
||||
{SPR_CSPR, 0, 1, {A_CrushclawAim}, 50, 20, S_CDIAG1}, // S_CDIAG1
|
||||
{SPR_CSPR, 1, 1, {A_Pain}, 0, 0, S_CDIAG3}, // S_CDIAG2
|
||||
{SPR_CSPR, 2, 1, {A_CrushclawAim}, 50, 20, S_CDIAG4}, // S_CDIAG3
|
||||
{SPR_CSPR, 3, 1, {A_CrushclawAim}, 50, 20, S_CDIAG5}, // S_CDIAG4
|
||||
{SPR_CSPR, 4, 1, {A_CrushclawAim}, 50, 20, S_CDIAG6}, // S_CDIAG5
|
||||
{SPR_CSPR, 3, 1, {A_CrushclawAim}, 50, 20, S_CDIAG7}, // S_CDIAG6
|
||||
{SPR_CSPR, 2, 1, {A_CrushclawAim}, 50, 20, S_CDIAG8}, // S_CDIAG7
|
||||
{SPR_CSPR, 1, 1, {A_CrushclawAim}, 50, 20, S_CDIAG1}, // S_CDIAG8
|
||||
|
||||
// Jet Jaw
|
||||
{SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM2}, // S_JETJAW_ROAM1
|
||||
{SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM3}, // S_JETJAW_ROAM2
|
||||
|
@ -2511,6 +2535,12 @@ state_t states[NUMSTATES] =
|
|||
{SPR_FLME, FF_FULLBRIGHT , 4, {NULL}, 0, 0, S_FLAMEJETFLAME2}, // S_FLAMEJETFLAME1
|
||||
{SPR_FLME, FF_FULLBRIGHT|1, 5, {NULL}, 0, 0, S_FLAMEJETFLAME3}, // S_FLAMEJETFLAME2
|
||||
{SPR_FLME, FF_FULLBRIGHT|2, 11, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAME3
|
||||
{SPR_FLME, FF_FULLBRIGHT|3, 4, {NULL}, 0, 0, S_FLAMEJETFLAME5}, // S_FLAMEJETFLAME4
|
||||
{SPR_FLME, FF_FULLBRIGHT|4, 5, {NULL}, 0, 0, S_FLAMEJETFLAME6}, // S_FLAMEJETFLAME5
|
||||
{SPR_FLME, FF_FULLBRIGHT|5, 11, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAME6
|
||||
{SPR_FLME, FF_FULLBRIGHT|6, 4, {NULL}, 0, 0, S_FLAMEJETFLAME8}, // S_FLAMEJETFLAME7
|
||||
{SPR_FLME, FF_FULLBRIGHT|7, 5, {NULL}, 0, 0, S_FLAMEJETFLAME9}, // S_FLAMEJETFLAME8
|
||||
{SPR_FLME, FF_FULLBRIGHT|8, 11, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAME9
|
||||
|
||||
// Spinning flame jets
|
||||
// A: Counter-clockwise
|
||||
|
@ -2549,31 +2579,31 @@ state_t states[NUMSTATES] =
|
|||
{SPR_WVIN, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_WALLVINE_SHORT
|
||||
|
||||
// Trapgoyles
|
||||
{SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLE_CHECK}, // S_TRAPGOYLE
|
||||
{SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLE_FIRE1}, // S_TRAPGOYLE_CHECK
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE2}, // S_TRAPGOYLE_FIRE1
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE3}, // S_TRAPGOYLE_FIRE2
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE}, // S_TRAPGOYLE_FIRE3
|
||||
{SPR_BGAR, 0, 67, {NULL}, 0, 0, S_TRAPGOYLE_CHECK}, // S_TRAPGOYLE
|
||||
{SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLE_FIRE1}, // S_TRAPGOYLE_CHECK
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE2}, // S_TRAPGOYLE_FIRE1
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE3}, // S_TRAPGOYLE_FIRE2
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE}, // S_TRAPGOYLE_FIRE3
|
||||
|
||||
{SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEUP_CHECK}, // S_TRAPGOYLEUP
|
||||
{SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEUP_FIRE1}, // S_TRAPGOYLEUP_CHECK
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE2}, // S_TRAPGOYLEUP_FIRE1
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE3}, // S_TRAPGOYLEUP_FIRE2
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP}, // S_TRAPGOYLEUP_FIRE3
|
||||
{SPR_BGAR, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEUP_CHECK}, // S_TRAPGOYLEUP
|
||||
{SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEUP_FIRE1}, // S_TRAPGOYLEUP_CHECK
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE2}, // S_TRAPGOYLEUP_FIRE1
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE3}, // S_TRAPGOYLEUP_FIRE2
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP}, // S_TRAPGOYLEUP_FIRE3
|
||||
|
||||
{SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEDOWN_CHECK}, // S_TRAPGOYLEDOWN
|
||||
{SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEDOWN_FIRE1}, // S_TRAPGOYLEDOWN_CHECK
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE2}, // S_TRAPGOYLEDOWN_FIRE1
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE3}, // S_TRAPGOYLEDOWN_FIRE2
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN}, // S_TRAPGOYLEDOWN_FIRE3
|
||||
{SPR_BGAR, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEDOWN_CHECK}, // S_TRAPGOYLEDOWN
|
||||
{SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEDOWN_FIRE1}, // S_TRAPGOYLEDOWN_CHECK
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE2}, // S_TRAPGOYLEDOWN_FIRE1
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE3}, // S_TRAPGOYLEDOWN_FIRE2
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN}, // S_TRAPGOYLEDOWN_FIRE3
|
||||
|
||||
{SPR_GARG, 0, 135, {NULL}, 0, 0, S_TRAPGOYLELONG_CHECK}, // S_TRAPGOYLELONG
|
||||
{SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLELONG_FIRE1}, // S_TRAPGOYLELONG_CHECK
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE2}, // S_TRAPGOYLELONG_FIRE1
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE3}, // S_TRAPGOYLELONG_FIRE2
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE4}, // S_TRAPGOYLELONG_FIRE3
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE5}, // S_TRAPGOYLELONG_FIRE4
|
||||
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG}, // S_TRAPGOYLELONG_FIRE5
|
||||
{SPR_BGAR, 0, 135, {NULL}, 0, 0, S_TRAPGOYLELONG_CHECK}, // S_TRAPGOYLELONG
|
||||
{SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLELONG_FIRE1}, // S_TRAPGOYLELONG_CHECK
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE2}, // S_TRAPGOYLELONG_FIRE1
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE3}, // S_TRAPGOYLELONG_FIRE2
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE4}, // S_TRAPGOYLELONG_FIRE3
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE5}, // S_TRAPGOYLELONG_FIRE4
|
||||
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG}, // S_TRAPGOYLELONG_FIRE5
|
||||
|
||||
// Target/Red Crystal
|
||||
{SPR_RCRY, 0, -1, {NULL}, 0, 0, S_TARGET_IDLE}, // S_TARGET_IDLE
|
||||
|
@ -2582,6 +2612,9 @@ state_t states[NUMSTATES] =
|
|||
{SPR_RCRY, 1, 0, {A_SpawnObjectRelative}, 0, MT_TARGET, S_NULL}, // S_TARGET_RESPAWN
|
||||
{SPR_RCRY, FF_FULLBRIGHT|1, -1, {A_SetObjectFlags}, MF_PUSHABLE, 1, S_TARGET_ALLDONE}, // S_TARGET_ALLDONE
|
||||
|
||||
// Green flame
|
||||
{SPR_CFLM, FF_FULLBRIGHT|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 3, S_GREENFLAME}, // S_GREENFLAME
|
||||
|
||||
// Stalagmites
|
||||
{SPR_STLG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_STG0
|
||||
{SPR_STLG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_STG1
|
||||
|
@ -3275,6 +3308,17 @@ state_t states[NUMSTATES] =
|
|||
{SPR_SSWB, 2, 1, {NULL}, 0, 0, S_BHORIZ8}, // S_BHORIZ7
|
||||
{SPR_SSWB, 1, 1, {NULL}, 0, 0, S_BHORIZ1}, // S_BHORIZ8
|
||||
|
||||
// Boosters
|
||||
{SPR_NULL, 0, 1, {A_Pain}, 0, 0, S_INVISIBLE}, // S_BOOSTERSOUND
|
||||
{SPR_BSTY, FF_ANIMATE, -1, {NULL}, 2, 1, S_NULL}, // S_YELLOWBOOSTERROLLER
|
||||
{SPR_BSTY, 3|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_YELLOWBOOSTERSEG_LEFT
|
||||
{SPR_BSTY, 6|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_YELLOWBOOSTERSEG_RIGHT
|
||||
{SPR_BSTY, 9|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_YELLOWBOOSTERSEG_FACE
|
||||
{SPR_BSTR, FF_ANIMATE, -1, {NULL}, 2, 1, S_NULL}, // S_REDBOOSTERROLLER
|
||||
{SPR_BSTR, 3|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_REDBOOSTERSEG_LEFT
|
||||
{SPR_BSTR, 6|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_REDBOOSTERSEG_RIGHT
|
||||
{SPR_BSTR, 9|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_REDBOOSTERSEG_FACE
|
||||
|
||||
// Rain
|
||||
{SPR_RAIN, FF_FULLBRIGHT|FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1
|
||||
{SPR_RAIN, FF_FULLBRIGHT|FF_TRANS50, 1, {NULL}, 0, 0, S_RAIN1}, // S_RAINRETURN
|
||||
|
@ -4062,7 +4106,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
MT_THOK, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID|MF_SHOOTABLE, // flags
|
||||
MT_NULL // raisestate
|
||||
(statenum_t)MT_NULL// raisestate
|
||||
},
|
||||
|
||||
{ // MT_TAILSOVERLAY
|
||||
|
@ -4513,7 +4557,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_XPLD1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_pop, // deathsound
|
||||
1, // speed
|
||||
600, // speed
|
||||
22*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
|
@ -4521,7 +4565,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // damage
|
||||
sfx_s3kd2l, // activesound
|
||||
MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||
MT_CRUSHCHAIN // raisestate
|
||||
(statenum_t)MT_CRUSHCHAIN// raisestate
|
||||
},
|
||||
|
||||
{ // MT_CRUSHCHAIN
|
||||
|
@ -4551,6 +4595,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BANPYURA
|
||||
138, // doomednum
|
||||
S_BANPYURA_ROAM1, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
32, // 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
|
||||
8, // speed
|
||||
24*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BANPSPRING
|
||||
-1, // doomednum
|
||||
S_CDIAG1, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_CDIAG2, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_cdfm08, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_XPLD1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
300, // speed
|
||||
22*FRACUNIT, // radius
|
||||
22*FRACUNIT, // height
|
||||
0, // display offset
|
||||
11*FRACUNIT, // mass
|
||||
11*FRACUNIT, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SPRING|MF_NOGRAVITY, // flags
|
||||
S_CDIAG2 // raisestate
|
||||
},
|
||||
|
||||
{ // MT_JETJAW
|
||||
113, // doomednum
|
||||
S_JETJAW_ROAM1, // spawnstate
|
||||
|
@ -7590,12 +7688,120 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
1*FRACUNIT, // damage
|
||||
11*FRACUNIT, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SPRING|MF_NOGRAVITY, // flags
|
||||
S_BHORIZ2 // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BOOSTERSEG
|
||||
-1, // doomednum
|
||||
S_INVISIBLE, // 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
|
||||
28*FRACUNIT, // radius
|
||||
16*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BOOSTERROLLER
|
||||
-1, // doomednum
|
||||
S_INVISIBLE, // 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
|
||||
14*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_YELLOWBOOSTER
|
||||
544, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
3, // painchance
|
||||
sfx_cdfm62, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
28*FRACUNIT, // radius
|
||||
FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
36*FRACUNIT, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SPRING|MF_NOGRAVITY, // flags
|
||||
S_BOOSTERSOUND // raisestate
|
||||
},
|
||||
|
||||
{ // MT_REDBOOSTER
|
||||
545, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
3, // painchance
|
||||
sfx_cdfm62, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
28*FRACUNIT, // radius
|
||||
FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
72*FRACUNIT, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SPRING|MF_NOGRAVITY, // flags
|
||||
S_BOOSTERSOUND // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BUBBLES
|
||||
500, // doomednum
|
||||
S_BUBBLES1, // spawnstate
|
||||
|
@ -11134,7 +11340,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
},
|
||||
|
||||
{ // MT_SMALLMACE
|
||||
-1, // doomednum
|
||||
1130, // doomednum
|
||||
S_SMALLMACE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
|
@ -11161,7 +11367,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
},
|
||||
|
||||
{ // MT_BIGMACE
|
||||
-1, // doomednum
|
||||
1131, // doomednum
|
||||
S_BIGMACE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
|
@ -11216,7 +11422,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
|
||||
{ // MT_BIGGRABCHAIN
|
||||
-1, // doomednum
|
||||
S_BIGGRABCHAIN, // spawnstate
|
||||
S_BIGGRABCHAIN, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
@ -11242,7 +11448,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
},
|
||||
|
||||
{ // MT_YELLOWSPRINGBALL
|
||||
-1, // doomednum
|
||||
1134, // doomednum
|
||||
S_YELLOWSPRINGBALL, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_YELLOWSPRINGBALL2, // seestate
|
||||
|
@ -11269,7 +11475,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
},
|
||||
|
||||
{ // MT_REDSPRINGBALL
|
||||
-1, // doomednum
|
||||
1135, // doomednum
|
||||
S_REDSPRINGBALL, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_REDSPRINGBALL2, // seestate
|
||||
|
@ -11296,7 +11502,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
},
|
||||
|
||||
{ // MT_SMALLFIREBAR
|
||||
-1, // doomednum
|
||||
1136, // doomednum
|
||||
S_SMALLFIREBAR1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
|
@ -11323,7 +11529,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
},
|
||||
|
||||
{ // MT_BIGFIREBAR
|
||||
-1, // doomednum
|
||||
1137, // doomednum
|
||||
S_BIGFIREBAR1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
|
@ -11859,7 +12065,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags
|
||||
MT_ROCKCRUMBLE3 // raisestate
|
||||
(statenum_t)MT_ROCKCRUMBLE3// raisestate
|
||||
},
|
||||
|
||||
{ // MT_BRAMBLES
|
||||
|
@ -12561,7 +12767,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // damage
|
||||
sfx_s3k76, // activesound
|
||||
MF_PUSHABLE, // flags
|
||||
MT_MINECARTSIDEMARK // raisestate
|
||||
(statenum_t)MT_MINECARTSIDEMARK// raisestate
|
||||
},
|
||||
|
||||
{ // MT_MINECARTSEG
|
||||
|
@ -13509,6 +13715,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_GREENFLAME
|
||||
1505, // doomednum
|
||||
S_GREENFLAME, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
MT_NULL, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_PAIN, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_STALAGMITE0
|
||||
1900, // doomednum
|
||||
S_STG0, // spawnstate
|
||||
|
|
59
src/info.h
59
src/info.h
|
@ -306,6 +306,8 @@ typedef enum sprite
|
|||
SPR_TURR, // Pop-Up Turret
|
||||
SPR_SHRP, // Sharp
|
||||
SPR_CRAB, // Crushstacean
|
||||
SPR_CR2B, // Banpyura
|
||||
SPR_CSPR, // Banpyura spring
|
||||
SPR_JJAW, // Jet Jaw
|
||||
SPR_SNLR, // Snailer
|
||||
SPR_VLTR, // BASH
|
||||
|
@ -554,6 +556,11 @@ typedef enum sprite
|
|||
SPR_HHPL, // Dr Seuss Trees
|
||||
SPR_SHRM, // Mushroom
|
||||
SPR_HHZM, // Misc
|
||||
|
||||
// Azure Temple Scenery
|
||||
SPR_BGAR, // ATZ Gargoyles
|
||||
SPR_RCRY, // ATZ Red Crystal (Target)
|
||||
SPR_CFLM, // Green torch flame
|
||||
|
||||
// Botanic Serenity Scenery
|
||||
SPR_BSZ1, // Tall flowers
|
||||
|
@ -574,7 +581,6 @@ typedef enum sprite
|
|||
// Misc Scenery
|
||||
SPR_STLG, // Stalagmites
|
||||
SPR_DBAL, // Disco
|
||||
SPR_RCRY, // ATZ Red Crystal (Target)
|
||||
|
||||
// Powerup Indicators
|
||||
SPR_ARMA, // Armageddon Shield Orb
|
||||
|
@ -628,6 +634,8 @@ typedef enum sprite
|
|||
SPR_SSWY, // Yellow Side Spring
|
||||
SPR_SSWR, // Red Side Spring
|
||||
SPR_SSWB, // Blue Side Spring
|
||||
SPR_BSTY, // Yellow Booster
|
||||
SPR_BSTR, // Red Booster
|
||||
|
||||
// Environmental Effects
|
||||
SPR_RAIN, // Rain
|
||||
|
@ -871,6 +879,12 @@ typedef enum playersprite
|
|||
NUMPLAYERSPRITES
|
||||
} playersprite_t;
|
||||
|
||||
// SPR2_XTRA
|
||||
#define XTRA_LIFEPIC 0 // Life icon patch
|
||||
#define XTRA_CHARSEL 1 // Character select picture
|
||||
#define XTRA_CONTINUE 2 // Continue icon
|
||||
#define XTRA_ENDING 3 // Ending finale patches
|
||||
|
||||
typedef enum state
|
||||
{
|
||||
S_NULL,
|
||||
|
@ -1167,6 +1181,21 @@ typedef enum state
|
|||
S_CRUSHCLAW_WAIT,
|
||||
S_CRUSHCHAIN,
|
||||
|
||||
// Banpyura
|
||||
S_BANPYURA_ROAM1,
|
||||
S_BANPYURA_ROAM2,
|
||||
S_BANPYURA_ROAM3,
|
||||
S_BANPYURA_ROAM4,
|
||||
S_BANPYURA_ROAMPAUSE,
|
||||
S_CDIAG1,
|
||||
S_CDIAG2,
|
||||
S_CDIAG3,
|
||||
S_CDIAG4,
|
||||
S_CDIAG5,
|
||||
S_CDIAG6,
|
||||
S_CDIAG7,
|
||||
S_CDIAG8,
|
||||
|
||||
// Jet Jaw
|
||||
S_JETJAW_ROAM1,
|
||||
S_JETJAW_ROAM2,
|
||||
|
@ -2633,6 +2662,12 @@ typedef enum state
|
|||
S_FLAMEJETFLAME1,
|
||||
S_FLAMEJETFLAME2,
|
||||
S_FLAMEJETFLAME3,
|
||||
S_FLAMEJETFLAME4,
|
||||
S_FLAMEJETFLAME5,
|
||||
S_FLAMEJETFLAME6,
|
||||
S_FLAMEJETFLAME7,
|
||||
S_FLAMEJETFLAME8,
|
||||
S_FLAMEJETFLAME9,
|
||||
|
||||
// Spinning flame jets
|
||||
S_FJSPINAXISA1, // Counter-clockwise
|
||||
|
@ -2698,6 +2733,9 @@ typedef enum state
|
|||
S_TARGET_RESPAWN,
|
||||
S_TARGET_ALLDONE,
|
||||
|
||||
// ATZ's green flame
|
||||
S_GREENFLAME,
|
||||
|
||||
// Stalagmites
|
||||
S_STG0,
|
||||
S_STG1,
|
||||
|
@ -3387,6 +3425,17 @@ typedef enum state
|
|||
S_BHORIZ7,
|
||||
S_BHORIZ8,
|
||||
|
||||
// Booster
|
||||
S_BOOSTERSOUND,
|
||||
S_YELLOWBOOSTERROLLER,
|
||||
S_YELLOWBOOSTERSEG_LEFT,
|
||||
S_YELLOWBOOSTERSEG_RIGHT,
|
||||
S_YELLOWBOOSTERSEG_FACE,
|
||||
S_REDBOOSTERROLLER,
|
||||
S_REDBOOSTERSEG_LEFT,
|
||||
S_REDBOOSTERSEG_RIGHT,
|
||||
S_REDBOOSTERSEG_FACE,
|
||||
|
||||
// Rain
|
||||
S_RAIN1,
|
||||
S_RAINRETURN,
|
||||
|
@ -4062,6 +4111,8 @@ typedef enum mobj_type
|
|||
MT_CRUSHSTACEAN, // Crushstacean
|
||||
MT_CRUSHCLAW, // Big meaty claw
|
||||
MT_CRUSHCHAIN, // Chain
|
||||
MT_BANPYURA, // Banpyura
|
||||
MT_BANPSPRING, // Banpyura spring
|
||||
MT_JETJAW, // Jet Jaw
|
||||
MT_SNAILER, // Snailer
|
||||
MT_VULTURE, // BASH
|
||||
|
@ -4199,6 +4250,11 @@ typedef enum mobj_type
|
|||
MT_REDHORIZ,
|
||||
MT_BLUEHORIZ,
|
||||
|
||||
MT_BOOSTERSEG,
|
||||
MT_BOOSTERROLLER,
|
||||
MT_YELLOWBOOSTER,
|
||||
MT_REDBOOSTER,
|
||||
|
||||
// Interactive Objects
|
||||
MT_BUBBLES, // Bubble source
|
||||
MT_SIGN, // Level end sign
|
||||
|
@ -4457,6 +4513,7 @@ typedef enum mobj_type
|
|||
MT_TRAPGOYLEDOWN,
|
||||
MT_TRAPGOYLELONG,
|
||||
MT_TARGET, // AKA Red Crystal
|
||||
MT_GREENFLAME,
|
||||
|
||||
// Stalagmites
|
||||
MT_STALAGMITE0,
|
||||
|
|
|
@ -50,6 +50,7 @@ enum hook {
|
|||
hook_FollowMobj,
|
||||
hook_PlayerCanDamage,
|
||||
hook_PlayerQuit,
|
||||
hook_IntermissionThinker,
|
||||
|
||||
hook_MAX // last hook
|
||||
};
|
||||
|
@ -91,5 +92,6 @@ boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnM
|
|||
boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following
|
||||
UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage
|
||||
void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting
|
||||
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,7 @@ const char *const hookNames[hook_MAX+1] = {
|
|||
"FollowMobj",
|
||||
"PlayerCanDamage",
|
||||
"PlayerQuit",
|
||||
"IntermissionThinker",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1322,4 +1323,27 @@ void LUAh_PlayerQuit(player_t *plr, int reason)
|
|||
lua_settop(gL, 0);
|
||||
}
|
||||
|
||||
// Hook for Y_Ticker
|
||||
void LUAh_IntermissionThinker(void)
|
||||
{
|
||||
hook_p hookp;
|
||||
if (!gL || !(hooksAvailable[hook_IntermissionThinker/8] & (1<<(hook_IntermissionThinker%8))))
|
||||
return;
|
||||
|
||||
for (hookp = roothook; hookp; hookp = hookp->next)
|
||||
{
|
||||
if (hookp->type != hook_IntermissionThinker)
|
||||
continue;
|
||||
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
if (lua_pcall(gL, 0, 0, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
hookp->error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -637,6 +637,68 @@ static int libd_drawString(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libd_drawNameTag(lua_State *L)
|
||||
{
|
||||
INT32 x;
|
||||
INT32 y;
|
||||
const char *str;
|
||||
INT32 flags;
|
||||
UINT8 basecolor;
|
||||
UINT8 outlinecolor;
|
||||
UINT8 *basecolormap = NULL;
|
||||
UINT8 *outlinecolormap = NULL;
|
||||
|
||||
HUDONLY
|
||||
|
||||
x = luaL_checkinteger(L, 1);
|
||||
y = luaL_checkinteger(L, 2);
|
||||
str = luaL_checkstring(L, 3);
|
||||
flags = luaL_optinteger(L, 4, 0);
|
||||
basecolor = luaL_optinteger(L, 5, SKINCOLOR_BLUE);
|
||||
outlinecolor = luaL_optinteger(L, 6, SKINCOLOR_ORANGE);
|
||||
if (basecolor != SKINCOLOR_NONE)
|
||||
basecolormap = R_GetTranslationColormap(TC_DEFAULT, basecolor, GTC_CACHE);
|
||||
if (outlinecolor != SKINCOLOR_NONE)
|
||||
outlinecolormap = R_GetTranslationColormap(TC_DEFAULT, outlinecolor, GTC_CACHE);
|
||||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
V_DrawNameTag(x, y, flags, FRACUNIT, basecolormap, outlinecolormap, str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libd_drawScaledNameTag(lua_State *L)
|
||||
{
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
const char *str;
|
||||
INT32 flags;
|
||||
fixed_t scale;
|
||||
UINT8 basecolor;
|
||||
UINT8 outlinecolor;
|
||||
UINT8 *basecolormap = NULL;
|
||||
UINT8 *outlinecolormap = NULL;
|
||||
|
||||
HUDONLY
|
||||
|
||||
x = luaL_checkfixed(L, 1);
|
||||
y = luaL_checkfixed(L, 2);
|
||||
str = luaL_checkstring(L, 3);
|
||||
flags = luaL_optinteger(L, 4, 0);
|
||||
scale = luaL_optinteger(L, 5, FRACUNIT);
|
||||
if (scale < 0)
|
||||
return luaL_error(L, "negative scale");
|
||||
basecolor = luaL_optinteger(L, 6, SKINCOLOR_BLUE);
|
||||
outlinecolor = luaL_optinteger(L, 7, SKINCOLOR_ORANGE);
|
||||
if (basecolor != SKINCOLOR_NONE)
|
||||
basecolormap = R_GetTranslationColormap(TC_DEFAULT, basecolor, GTC_CACHE);
|
||||
if (outlinecolor != SKINCOLOR_NONE)
|
||||
outlinecolormap = R_GetTranslationColormap(TC_DEFAULT, outlinecolor, GTC_CACHE);
|
||||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
V_DrawNameTag(FixedInt(x), FixedInt(y), flags, scale, basecolormap, outlinecolormap, str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libd_stringWidth(lua_State *L)
|
||||
{
|
||||
const char *str = luaL_checkstring(L, 1);
|
||||
|
@ -659,6 +721,13 @@ static int libd_stringWidth(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int libd_nameTagWidth(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
lua_pushinteger(L, V_NameTagWidth(luaL_checkstring(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int libd_getColormap(lua_State *L)
|
||||
{
|
||||
INT32 skinnum = TC_DEFAULT;
|
||||
|
@ -837,9 +906,12 @@ static luaL_Reg lib_draw[] = {
|
|||
{"drawPaddedNum", libd_drawPaddedNum},
|
||||
{"drawFill", libd_drawFill},
|
||||
{"drawString", libd_drawString},
|
||||
{"drawNameTag", libd_drawNameTag},
|
||||
{"drawScaledNameTag", libd_drawScaledNameTag},
|
||||
{"fadeScreen", libd_fadeScreen},
|
||||
// misc
|
||||
{"stringWidth", libd_stringWidth},
|
||||
{"nameTagWidth", libd_nameTagWidth},
|
||||
// m_random
|
||||
{"RandomFixed",libd_RandomFixed},
|
||||
{"RandomByte",libd_RandomByte},
|
||||
|
|
|
@ -411,37 +411,53 @@ static int sector_iterate(lua_State *L)
|
|||
|
||||
// sector.lines, i -> sector.lines[i]
|
||||
// sector.lines.valid, for validity checking
|
||||
//
|
||||
// 25/9/19 Monster Iestyn
|
||||
// Modified this and _num to use triple pointers, to allow for a new hack of mine involving offsetof
|
||||
// this way we don't need to check frontsector or backsector of line #0 in the array
|
||||
//
|
||||
static int sectorlines_get(lua_State *L)
|
||||
{
|
||||
line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES));
|
||||
line_t ***seclines = *((line_t ****)luaL_checkudata(L, 1, META_SECTORLINES));
|
||||
size_t i;
|
||||
size_t numoflines = 0;
|
||||
lua_settop(L, 2);
|
||||
if (!lua_isnumber(L, 2))
|
||||
{
|
||||
int field = luaL_checkoption(L, 2, NULL, valid_opt);
|
||||
if (!seclines)
|
||||
if (!seclines || !(*seclines))
|
||||
{
|
||||
if (field == 0) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed sector_t doesn't exist anymore.");
|
||||
return luaL_error(L, "accessed sector_t.lines doesn't exist anymore.");
|
||||
} else if (field == 0) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* a snip from sector_t struct in r_defs.h, for reference
|
||||
size_t linecount;
|
||||
struct line_s **lines; // [linecount] size
|
||||
*/
|
||||
// get the "linecount" by shifting our retrieved memory address of "lines" to where "linecount" is in the sector_t, then dereferencing the result
|
||||
// we need this to determine the array's actual size, and therefore also the maximum value allowed as an index
|
||||
// this only works if seclines is actually a pointer to a sector's lines member in memory, oh boy
|
||||
numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount))));
|
||||
|
||||
/* OLD HACK
|
||||
// check first linedef to figure which of its sectors owns this sector->lines pointer
|
||||
// then check that sector's linecount to get a maximum index
|
||||
//if (!seclines[0])
|
||||
//if (!(*seclines)[0])
|
||||
//return luaL_error(L, "no lines found!"); // no first linedef?????
|
||||
if (seclines[0]->frontsector->lines == seclines)
|
||||
numoflines = seclines[0]->frontsector->linecount;
|
||||
else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first
|
||||
numoflines = seclines[0]->backsector->linecount;
|
||||
if ((*seclines)[0]->frontsector->lines == *seclines)
|
||||
numoflines = (*seclines)[0]->frontsector->linecount;
|
||||
else if ((*seclines)[0]->backsector && *seclines[0]->backsector->lines == *seclines) // check backsector exists first
|
||||
numoflines = (*seclines)[0]->backsector->linecount;
|
||||
//if neither sector has it then ???
|
||||
*/
|
||||
|
||||
if (!numoflines)
|
||||
return luaL_error(L, "no lines found!");
|
||||
|
@ -449,23 +465,21 @@ static int sectorlines_get(lua_State *L)
|
|||
i = (size_t)lua_tointeger(L, 2);
|
||||
if (i >= numoflines)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, seclines[i], META_LINE);
|
||||
LUA_PushUserdata(L, (*seclines)[i], META_LINE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// #(sector.lines) -> sector.linecount
|
||||
static int sectorlines_num(lua_State *L)
|
||||
{
|
||||
line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES));
|
||||
line_t ***seclines = *((line_t ****)luaL_checkudata(L, 1, META_SECTORLINES));
|
||||
size_t numoflines = 0;
|
||||
// check first linedef to figure which of its sectors owns this sector->lines pointer
|
||||
// then check that sector's linecount to get a maximum index
|
||||
//if (!seclines[0])
|
||||
//return luaL_error(L, "no lines found!"); // no first linedef?????
|
||||
if (seclines[0]->frontsector->lines == seclines)
|
||||
numoflines = seclines[0]->frontsector->linecount;
|
||||
else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first
|
||||
numoflines = seclines[0]->backsector->linecount;
|
||||
//if neither sector has it then ???
|
||||
|
||||
if (!seclines || !(*seclines))
|
||||
return luaL_error(L, "accessed sector_t.lines doesn't exist anymore.");
|
||||
|
||||
// see comments in the _get function above
|
||||
numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount))));
|
||||
lua_pushinteger(L, numoflines);
|
||||
return 1;
|
||||
}
|
||||
|
@ -543,7 +557,7 @@ static int sector_get(lua_State *L)
|
|||
LUA_PushUserdata(L, §ors[sector->camsec], META_SECTOR);
|
||||
return 1;
|
||||
case sector_lines: // lines
|
||||
LUA_PushUserdata(L, sector->lines, META_SECTORLINES);
|
||||
LUA_PushUserdata(L, §or->lines, META_SECTORLINES); // push the address of the "lines" member in the struct, to allow our hacks in sectorlines_get/_num to work
|
||||
return 1;
|
||||
case sector_ffloors: // ffloors
|
||||
lua_pushcfunction(L, lib_iterateSectorFFloors);
|
||||
|
@ -579,6 +593,7 @@ static int sector_set(lua_State *L)
|
|||
case sector_thinglist: // thinglist
|
||||
case sector_heightsec: // heightsec
|
||||
case sector_camsec: // camsec
|
||||
case sector_lines: // lines
|
||||
case sector_ffloors: // ffloors
|
||||
#ifdef ESLOPE
|
||||
case sector_fslope: // f_slope
|
||||
|
|
|
@ -164,6 +164,8 @@ static int mobj_get(lua_State *L)
|
|||
enum mobj_e field = Lua_optoption(L, 2, NULL, mobj_opt);
|
||||
lua_settop(L, 2);
|
||||
|
||||
INLEVEL
|
||||
|
||||
if (!mo) {
|
||||
if (field == mobj_valid) {
|
||||
lua_pushboolean(L, 0);
|
||||
|
@ -409,6 +411,8 @@ static int mobj_set(lua_State *L)
|
|||
enum mobj_e field = Lua_optoption(L, 2, mobj_opt[0], mobj_opt);
|
||||
lua_settop(L, 3);
|
||||
|
||||
INLEVEL
|
||||
|
||||
if (!mo)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
static int lib_iteratePlayers(lua_State *L)
|
||||
{
|
||||
INT32 i = -1;
|
||||
INLEVEL
|
||||
if (lua_gettop(L) < 2)
|
||||
{
|
||||
//return luaL_error(L, "Don't call players.iterate() directly, use it as 'for player in players.iterate do <block> end'.");
|
||||
|
@ -52,7 +51,6 @@ static int lib_getPlayer(lua_State *L)
|
|||
{
|
||||
const char *field;
|
||||
// i -> players[i]
|
||||
INLEVEL
|
||||
if (lua_type(L, 2) == LUA_TNUMBER)
|
||||
{
|
||||
lua_Integer i = luaL_checkinteger(L, 2);
|
||||
|
|
|
@ -431,7 +431,7 @@ void LUA_InvalidateLevel(void)
|
|||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
LUA_InvalidateUserdata(§ors[i]);
|
||||
LUA_InvalidateUserdata(sectors[i].lines);
|
||||
LUA_InvalidateUserdata(§ors[i].lines);
|
||||
if (sectors[i].ffloors)
|
||||
{
|
||||
for (rover = sectors[i].ffloors; rover; rover = rover->next)
|
||||
|
|
32
src/m_cond.c
32
src/m_cond.c
|
@ -528,12 +528,22 @@ skincolors_t M_GetEmblemColor(emblem_t *em)
|
|||
return em->color;
|
||||
}
|
||||
|
||||
const char *M_GetEmblemPatch(emblem_t *em)
|
||||
const char *M_GetEmblemPatch(emblem_t *em, boolean big)
|
||||
{
|
||||
static char pnamebuf[7] = "GOTITn";
|
||||
static char pnamebuf[7];
|
||||
|
||||
if (!big)
|
||||
strcpy(pnamebuf, "GOTITn");
|
||||
else
|
||||
strcpy(pnamebuf, "EMBMn0");
|
||||
|
||||
I_Assert(em->sprite >= 'A' && em->sprite <= 'Z');
|
||||
pnamebuf[5] = em->sprite;
|
||||
|
||||
if (!big)
|
||||
pnamebuf[5] = em->sprite;
|
||||
else
|
||||
pnamebuf[4] = em->sprite;
|
||||
|
||||
return pnamebuf;
|
||||
}
|
||||
|
||||
|
@ -544,11 +554,21 @@ skincolors_t M_GetExtraEmblemColor(extraemblem_t *em)
|
|||
return em->color;
|
||||
}
|
||||
|
||||
const char *M_GetExtraEmblemPatch(extraemblem_t *em)
|
||||
const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big)
|
||||
{
|
||||
static char pnamebuf[7] = "GOTITn";
|
||||
static char pnamebuf[7];
|
||||
|
||||
if (!big)
|
||||
strcpy(pnamebuf, "GOTITn");
|
||||
else
|
||||
strcpy(pnamebuf, "EMBMn0");
|
||||
|
||||
I_Assert(em->sprite >= 'A' && em->sprite <= 'Z');
|
||||
pnamebuf[5] = em->sprite;
|
||||
|
||||
if (!big)
|
||||
pnamebuf[5] = em->sprite;
|
||||
else
|
||||
pnamebuf[4] = em->sprite;
|
||||
|
||||
return pnamebuf;
|
||||
}
|
||||
|
|
|
@ -171,9 +171,9 @@ INT32 M_CountEmblems(void);
|
|||
// Emblem shit
|
||||
emblem_t *M_GetLevelEmblems(INT32 mapnum);
|
||||
skincolors_t M_GetEmblemColor(emblem_t *em);
|
||||
const char *M_GetEmblemPatch(emblem_t *em);
|
||||
const char *M_GetEmblemPatch(emblem_t *em, boolean big);
|
||||
skincolors_t M_GetExtraEmblemColor(extraemblem_t *em);
|
||||
const char *M_GetExtraEmblemPatch(extraemblem_t *em);
|
||||
const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big);
|
||||
|
||||
// If you're looking to compare stats for unlocks or what not, use these
|
||||
// They stop checking upon reaching the target number so they
|
||||
|
|
853
src/m_menu.c
853
src/m_menu.c
File diff suppressed because it is too large
Load diff
14
src/m_menu.h
14
src/m_menu.h
|
@ -63,6 +63,7 @@ typedef enum
|
|||
MN_MP_CONNECT,
|
||||
MN_MP_ROOM,
|
||||
MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
|
||||
MN_MP_SERVER_OPTIONS,
|
||||
|
||||
// Options
|
||||
MN_OP_MAIN,
|
||||
|
@ -103,6 +104,7 @@ typedef enum
|
|||
MN_SR_LEVELSELECT,
|
||||
MN_SR_UNLOCKCHECKLIST,
|
||||
MN_SR_EMBLEMHINT,
|
||||
MN_SR_PLAYER,
|
||||
|
||||
// Addons (Part of MISC, but let's make it our own)
|
||||
MN_AD_MAIN,
|
||||
|
@ -323,9 +325,18 @@ typedef struct
|
|||
char notes[441];
|
||||
char picname[8];
|
||||
char skinname[SKINNAMESIZE*2+2]; // skin&skin\0
|
||||
patch_t *pic;
|
||||
patch_t *charpic;
|
||||
UINT8 prev;
|
||||
UINT8 next;
|
||||
|
||||
// new character select
|
||||
char displayname[SKINNAMESIZE+1];
|
||||
SINT8 skinnum[2];
|
||||
UINT8 oppositecolor;
|
||||
char nametag[8];
|
||||
patch_t *namepic;
|
||||
UINT8 tagtextcolor;
|
||||
UINT8 tagoutlinecolor;
|
||||
} description_t;
|
||||
|
||||
// level select platter
|
||||
|
@ -374,6 +385,7 @@ typedef struct
|
|||
|
||||
extern description_t description[MAXSKINS];
|
||||
|
||||
extern consvar_t cv_showfocuslost;
|
||||
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
|
||||
extern CV_PossibleValue_t gametype_cons_t[];
|
||||
|
||||
|
|
|
@ -197,7 +197,7 @@ INT32 M_MapNumber(char first, char second)
|
|||
// ==========================================================================
|
||||
|
||||
// some libcs has no access function, make our own
|
||||
#if defined (_WIN32_WCE)
|
||||
#if 0
|
||||
int access(const char *path, int amode)
|
||||
{
|
||||
int accesshandle = -1;
|
||||
|
|
|
@ -2027,6 +2027,7 @@ void A_CrushstaceanWalk(mobj_t *actor)
|
|||
|| (actor->reactiontime-- <= 0))
|
||||
{
|
||||
actor->flags2 ^= MF2_AMBUSH;
|
||||
P_SetTarget(&actor->target, NULL);
|
||||
P_SetMobjState(actor, locvar2);
|
||||
actor->reactiontime = actor->info->reactiontime;
|
||||
}
|
||||
|
@ -2087,7 +2088,7 @@ void A_CrushclawAim(mobj_t *actor)
|
|||
return; // there is only one step and it is crab
|
||||
}
|
||||
|
||||
if (crab->target || P_LookForPlayers(crab, true, false, 600*crab->scale))
|
||||
if (crab->target || P_LookForPlayers(crab, true, false, actor->info->speed*crab->scale))
|
||||
ang = R_PointToAngle2(crab->x, crab->y, crab->target->x, crab->target->y);
|
||||
else
|
||||
ang = crab->angle + ((crab->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);
|
||||
|
@ -2170,7 +2171,7 @@ void A_CrushclawLaunch(mobj_t *actor)
|
|||
UINT8 i = 0;
|
||||
for (i = 0; (i < CSEGS); i++)
|
||||
{
|
||||
mobj_t *newchain = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->info->raisestate);
|
||||
mobj_t *newchain = P_SpawnMobjFromMobj(actor, 0, 0, 0, (mobjtype_t)actor->info->raisestate);
|
||||
P_SetTarget(&prevchain->target, newchain);
|
||||
prevchain = newchain;
|
||||
}
|
||||
|
|
|
@ -2425,7 +2425,7 @@ void T_RaiseSector(levelspecthink_t *raise)
|
|||
mobj_t *thing;
|
||||
sector_t *sector;
|
||||
INT32 i;
|
||||
boolean playeronme = false;
|
||||
boolean playeronme = false, active = false;
|
||||
fixed_t ceilingdestination, floordestination;
|
||||
result_e res = 0;
|
||||
|
||||
|
@ -2459,8 +2459,53 @@ void T_RaiseSector(levelspecthink_t *raise)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (raise->vars[9]) // Dynamically Sinking Platform^tm
|
||||
{
|
||||
#define shaketime 10
|
||||
if (raise->vars[11] > shaketime) // State: moving
|
||||
{
|
||||
if (playeronme) // If player is standing on the platform, accelerate
|
||||
{
|
||||
raise->vars[10] += (FRACUNIT >> 5);
|
||||
}
|
||||
else // otherwise, decelerate until inflection
|
||||
{
|
||||
raise->vars[10] -= FRACUNIT >> 3;
|
||||
if (raise->vars[10] <= 0) // inflection!
|
||||
{
|
||||
raise->vars[10] = 0;
|
||||
raise->vars[11] = 0; // allow the shake to occur again (fucks over players attempting to jump-cheese)
|
||||
}
|
||||
}
|
||||
active = raise->vars[10] > 0;
|
||||
}
|
||||
else // State: shaking
|
||||
{
|
||||
if (playeronme || raise->vars[11])
|
||||
{
|
||||
active = true;
|
||||
if (++raise->vars[11] > shaketime)
|
||||
{
|
||||
if (playeronme)
|
||||
raise->vars[10] = FRACUNIT >> 5;
|
||||
else
|
||||
raise->vars[10] = FRACUNIT << 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
raise->vars[10] = ((shaketime/2) - raise->vars[11]) << FRACBITS;
|
||||
if (raise->vars[10] < -raise->vars[2]/2)
|
||||
raise->vars[10] = -raise->vars[2]/2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef shaketime
|
||||
}
|
||||
else // Air bobbing platform (not a Dynamically Sinking Platform^tm)
|
||||
active = playeronme;
|
||||
|
||||
if (playeronme)
|
||||
if (active)
|
||||
{
|
||||
raise->vars[3] = raise->vars[2];
|
||||
|
||||
|
@ -2554,6 +2599,8 @@ void T_RaiseSector(levelspecthink_t *raise)
|
|||
raise->vars[3] = origspeed;
|
||||
}
|
||||
|
||||
raise->vars[3] += raise->vars[10];
|
||||
|
||||
res = T_MovePlane
|
||||
(
|
||||
raise->sector, // sector
|
||||
|
|
|
@ -1496,8 +1496,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
P_SetMobjState(mo2, mo2->info->painstate);
|
||||
}
|
||||
}
|
||||
|
||||
S_StartSound(toucher, special->info->painsound);
|
||||
return;
|
||||
|
||||
case MT_FAKEMOBILE:
|
||||
|
@ -2471,6 +2469,28 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY;
|
||||
P_SetThingPosition(target);
|
||||
|
||||
if (target->player->powers[pw_super])
|
||||
{
|
||||
target->player->powers[pw_super] = 0;
|
||||
if (P_IsLocalPlayer(target->player))
|
||||
{
|
||||
music_stack_noposition = true; // HACK: Do not reposition next music
|
||||
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
|
||||
}
|
||||
P_RestoreMusic(target->player);
|
||||
|
||||
if (gametype != GT_COOP)
|
||||
{
|
||||
HU_SetCEchoFlags(0);
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[target->player-players]));
|
||||
}
|
||||
}
|
||||
|
||||
target->color = target->player->skincolor;
|
||||
target->colorized = false;
|
||||
G_GhostAddColor(GHC_NORMAL);
|
||||
|
||||
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)
|
||||
|
@ -2616,6 +2636,14 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
}
|
||||
break;
|
||||
|
||||
case MT_BANPYURA:
|
||||
if (target->tracer)
|
||||
{
|
||||
S_StopSound(target->tracer);
|
||||
P_KillMobj(target->tracer, inflictor, source, damagetype);
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_EGGSHIELD:
|
||||
P_SetObjectMomZ(target, 4*target->scale, false);
|
||||
P_InstaThrust(target, target->angle, 3*target->scale);
|
||||
|
|
62
src/p_map.c
62
src/p_map.c
|
@ -124,6 +124,7 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
|||
// Positive spring modes are minor variants of vanilla spring behaviour.
|
||||
// 1 = launch players in jump
|
||||
// 2 = don't modify player at all, just add momentum
|
||||
// 3 = speed-booster mode (force onto ground, MF_AMBUSH causes auto-spin)
|
||||
// Negative spring modes are mildly-related gimmicks with customisation.
|
||||
// -1 = pinball bumper
|
||||
// Any other spring mode defaults to standard vanilla spring behaviour,
|
||||
|
@ -151,7 +152,9 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
|
||||
if (object->player)
|
||||
{
|
||||
if (object->player->charability == CA_TWINSPIN && object->player->panim == PA_ABILITY)
|
||||
if (spring->info->painchance == 3)
|
||||
;
|
||||
else if (object->player->charability == CA_TWINSPIN && object->player->panim == PA_ABILITY)
|
||||
strong = 1;
|
||||
else if (object->player->charability2 == CA2_MELEE && object->player->panim == PA_ABILITY2)
|
||||
strong = 2;
|
||||
|
@ -286,7 +289,27 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
if (spring->info->painchance != 2)
|
||||
{
|
||||
if (object->player)
|
||||
{
|
||||
object->player->pflags &= ~PF_APPLYAUTOBRAKE;
|
||||
#ifndef SPRINGSPIN
|
||||
object->player->powers[pw_justsprung] = 5;
|
||||
if (horizspeed)
|
||||
object->player->powers[pw_noautobrake] = ((horizspeed*TICRATE)>>(FRACBITS+3))/9; // TICRATE at 72*FRACUNIT
|
||||
else if (P_MobjFlip(object) == P_MobjFlip(spring))
|
||||
object->player->powers[pw_justsprung] |= (1<<15);
|
||||
#else
|
||||
object->player->powers[pw_justsprung] = 15;
|
||||
if (horizspeed)
|
||||
object->player->powers[pw_noautobrake] = ((horizspeed*TICRATE)>>(FRACBITS+3))/9; // TICRATE at 72*FRACUNIT
|
||||
else
|
||||
{
|
||||
if (abs(object->player->rmomx) > object->scale || abs(object->player->rmomy) > object->scale)
|
||||
object->player->drawangle = R_PointToAngle2(0, 0, object->player->rmomx, object->player->rmomy);
|
||||
if (P_MobjFlip(object) == P_MobjFlip(spring))
|
||||
object->player->powers[pw_justsprung] |= (1<<15);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((horizspeed && vertispeed) || (object->player && object->player->homing)) // Mimic SA
|
||||
{
|
||||
|
@ -321,6 +344,14 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
|
||||
// Set position!
|
||||
P_TryMove(object, spring->x + offx, spring->y + offy, true);
|
||||
|
||||
if ((spring->info->painchance == 3))
|
||||
{
|
||||
object->z = spring->z;
|
||||
if (spring->eflags & MFE_VERTICALFLIP)
|
||||
object->z -= object->height;
|
||||
object->momz = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,8 +375,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
|
||||
if (horizspeed)
|
||||
{
|
||||
object->player->drawangle = spring->angle;
|
||||
object->angle = spring->angle;
|
||||
object->angle = object->player->drawangle = spring->angle;
|
||||
|
||||
if (!demoplayback || P_AnalogMove(object->player))
|
||||
{
|
||||
|
@ -356,11 +386,25 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
}
|
||||
}
|
||||
|
||||
pflags = object->player->pflags & (PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // I still need these.
|
||||
secondjump = object->player->secondjump;
|
||||
washoming = object->player->homing;
|
||||
if (object->player->pflags & PF_GLIDING)
|
||||
P_SetPlayerMobjState(object, S_PLAY_FALL);
|
||||
if ((spring->info->painchance == 3))
|
||||
{
|
||||
if (!(pflags = (object->player->pflags & PF_SPINNING)) &&
|
||||
(((object->player->charability2 == CA2_SPINDASH) && (object->player->cmd.buttons & BT_USE))
|
||||
|| (spring->flags2 & MF2_AMBUSH)))
|
||||
{
|
||||
pflags = PF_SPINNING;
|
||||
P_SetPlayerMobjState(object, S_PLAY_ROLL);
|
||||
S_StartSound(object, sfx_spin);
|
||||
}
|
||||
else
|
||||
P_SetPlayerMobjState(object, S_PLAY_ROLL);
|
||||
}
|
||||
else
|
||||
pflags = object->player->pflags & (PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // I still need these.
|
||||
secondjump = object->player->secondjump;
|
||||
washoming = object->player->homing;
|
||||
P_ResetPlayer(object->player);
|
||||
|
||||
if (spring->info->painchance == 1) // For all those ancient, SOC'd abilities.
|
||||
|
@ -368,7 +412,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
object->player->pflags |= P_GetJumpFlags(object->player);
|
||||
P_SetPlayerMobjState(object, S_PLAY_JUMP);
|
||||
}
|
||||
else if ((spring->info->painchance == 2) || (pflags & PF_BOUNCING)) // Adding momentum only.
|
||||
else if ((spring->info->painchance == 2) || ((spring->info->painchance != 3) && (pflags & PF_BOUNCING))) // Adding momentum only.
|
||||
{
|
||||
object->player->pflags |= (pflags &~ PF_STARTJUMP);
|
||||
object->player->secondjump = secondjump;
|
||||
|
@ -382,6 +426,10 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
object->player->pflags |= pflags;
|
||||
object->player->secondjump = secondjump;
|
||||
}
|
||||
else if (object->player->dashmode >= 3*TICRATE)
|
||||
P_SetPlayerMobjState(object, S_PLAY_DASH);
|
||||
else if (P_IsObjectOnGround(object) && horizspeed >= FixedMul(object->player->runspeed, object->scale))
|
||||
P_SetPlayerMobjState(object, S_PLAY_RUN);
|
||||
else
|
||||
P_SetPlayerMobjState(object, S_PLAY_WALK);
|
||||
}
|
||||
|
|
|
@ -674,7 +674,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
|
||||
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
|
||||
if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF
|
||||
{
|
||||
if (bottomheight < opentop) {
|
||||
opentop = bottomheight;
|
||||
|
@ -687,7 +687,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
highceiling = bottomheight;
|
||||
}
|
||||
|
||||
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
|
||||
if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
|
||||
{
|
||||
if (topheight > openbottom) {
|
||||
openbottom = topheight;
|
||||
|
@ -720,7 +720,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
|
||||
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
|
||||
if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF
|
||||
{
|
||||
if (bottomheight < opentop) {
|
||||
opentop = bottomheight;
|
||||
|
@ -733,7 +733,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
highceiling = bottomheight;
|
||||
}
|
||||
|
||||
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
|
||||
if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
|
||||
{
|
||||
if (topheight > openbottom) {
|
||||
openbottom = topheight;
|
||||
|
|
123
src/p_mobj.c
123
src/p_mobj.c
|
@ -1990,6 +1990,8 @@ void P_XYMovement(mobj_t *mo)
|
|||
{
|
||||
mo->momz = transfermomz;
|
||||
mo->standingslope = NULL;
|
||||
if (player->pflags & PF_SPINNING)
|
||||
player->pflags = (player->pflags & ~PF_SPINNING) | (PF_JUMPED | PF_THOKKED);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -4716,13 +4718,17 @@ static void P_Boss4MoveSpikeballs(mobj_t *mobj, angle_t angle, fixed_t fz)
|
|||
}
|
||||
}
|
||||
|
||||
#define CEZ3TILT
|
||||
|
||||
// Pull them closer.
|
||||
static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz)
|
||||
{
|
||||
INT32 s;
|
||||
mobj_t *base = mobj, *seg;
|
||||
fixed_t originx, originy, workx, worky, dx, dy, bz = mobj->watertop+(8<<FRACBITS);
|
||||
|
||||
fixed_t workx, worky, dx, dy, bz = mobj->watertop+(8<<FRACBITS);
|
||||
fixed_t rad = (9*132)<<FRACBITS;
|
||||
#ifdef CEZ3TILT
|
||||
fixed_t originx, originy;
|
||||
if (mobj->spawnpoint)
|
||||
{
|
||||
originx = mobj->spawnpoint->x << FRACBITS;
|
||||
|
@ -4733,13 +4739,25 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz)
|
|||
originx = mobj->x;
|
||||
originy = mobj->y;
|
||||
}
|
||||
#else
|
||||
if (mobj->spawnpoint)
|
||||
{
|
||||
rad -= R_PointToDist2(mobj->x, mobj->y,
|
||||
(mobj->spawnpoint->x<<FRACBITS), (mobj->spawnpoint->y<<FRACBITS));
|
||||
}
|
||||
#endif
|
||||
|
||||
dz /= 9;
|
||||
|
||||
while ((base = base->tracer)) // there are 10 per spoke, remember that
|
||||
{
|
||||
dx = (originx + P_ReturnThrustX(mobj, angle, (9*132)<<FRACBITS) - mobj->x)/9;
|
||||
dy = (originy + P_ReturnThrustY(mobj, angle, (9*132)<<FRACBITS) - mobj->y)/9;
|
||||
#ifdef CEZ3TILT
|
||||
dx = (originx + P_ReturnThrustX(mobj, angle, rad) - mobj->x)/9;
|
||||
dy = (originy + P_ReturnThrustY(mobj, angle, rad) - mobj->y)/9;
|
||||
#else
|
||||
dx = P_ReturnThrustX(mobj, angle, rad)/9;
|
||||
dy = P_ReturnThrustY(mobj, angle, rad)/9;
|
||||
#endif
|
||||
workx = mobj->x + P_ReturnThrustX(mobj, angle, (112)<<FRACBITS);
|
||||
worky = mobj->y + P_ReturnThrustY(mobj, angle, (112)<<FRACBITS);
|
||||
for (seg = base, s = 9; seg; seg = seg->hnext, --s)
|
||||
|
@ -4929,6 +4947,7 @@ static void P_Boss4Thinker(mobj_t *mobj)
|
|||
mobj->movecount += mobj->threshold;
|
||||
if (mobj->movecount <= 0)
|
||||
{
|
||||
mobj->flags2 &= ~MF2_INVERTAIMABLE;
|
||||
mobj->movecount = 0;
|
||||
mobj->movedir++; // Initialization complete, next phase!
|
||||
}
|
||||
|
@ -7552,6 +7571,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->fuse -= 2;
|
||||
|
||||
flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME);
|
||||
P_SetMobjState(flame, S_FLAMEJETFLAME4);
|
||||
|
||||
flame->angle = mobj->angle;
|
||||
|
||||
|
@ -7596,7 +7616,10 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
flame->momz = -strength;
|
||||
}
|
||||
else
|
||||
{
|
||||
flame->momz = strength;
|
||||
P_SetMobjState(flame, S_FLAMEJETFLAME7);
|
||||
}
|
||||
P_InstaThrust(flame, mobj->angle, FixedDiv(mobj->fuse*FRACUNIT,3*FRACUNIT));
|
||||
S_StartSound(flame, sfx_fire);
|
||||
}
|
||||
|
@ -7735,7 +7758,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
actualwork = work = FixedHypot(mobj->x-players[i].mo->x, mobj->y-players[i].mo->y);
|
||||
if (player)
|
||||
{
|
||||
if (players[i].skin == 0 || players[i].skin == 3)
|
||||
if (players[i].skin == 0 || players[i].skin == 5)
|
||||
work = (2*work)/3;
|
||||
if (work >= pdist)
|
||||
continue;
|
||||
|
@ -7773,7 +7796,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (mobj->target != player->mo)
|
||||
P_SetTarget(&mobj->target, player->mo);
|
||||
targonground = (P_IsObjectOnGround(mobj->target) && (player->panim == PA_IDLE || player->panim == PA_WALK || player->panim == PA_RUN));
|
||||
love = (player->skin == 0 || player->skin == 3);
|
||||
love = (player->skin == 0 || player->skin == 5);
|
||||
|
||||
switch (stat)
|
||||
{
|
||||
|
@ -10283,6 +10306,15 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
mobj->reactiontime >>= 1;
|
||||
}
|
||||
break;
|
||||
case MT_BANPYURA:
|
||||
{
|
||||
mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BANPSPRING);
|
||||
bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);;
|
||||
P_SetTarget(&mobj->tracer, bigmeatyclaw);
|
||||
P_SetTarget(&bigmeatyclaw->tracer, mobj);
|
||||
mobj->reactiontime >>= 1;
|
||||
}
|
||||
break;
|
||||
case MT_BIGMINE:
|
||||
mobj->extravalue1 = FixedHypot(mobj->x, mobj->y)>>FRACBITS;
|
||||
break;
|
||||
|
@ -10308,6 +10340,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
mobj->movefactor = -512*FRACUNIT;
|
||||
mobj->flags2 |= MF2_CLASSICPUSH;
|
||||
break;
|
||||
case MT_EGGMOBILE4:
|
||||
mobj->flags2 |= MF2_INVERTAIMABLE;
|
||||
break;
|
||||
case MT_FLICKY_08:
|
||||
mobj->color = (P_RandomChance(FRACUNIT/2) ? SKINCOLOR_RED : SKINCOLOR_AQUA);
|
||||
break;
|
||||
|
@ -10366,13 +10401,13 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
break;
|
||||
case MT_METALSONIC_BATTLE:
|
||||
case MT_METALSONIC_RACE:
|
||||
sc = 3;
|
||||
sc = 5;
|
||||
break;
|
||||
case MT_FANG:
|
||||
sc = 4;
|
||||
break;
|
||||
case MT_ROSY:
|
||||
sc = 5;
|
||||
sc = 3;
|
||||
break;
|
||||
case MT_CORK:
|
||||
mobj->flags2 |= MF2_SUPERFIRE;
|
||||
|
@ -11562,7 +11597,7 @@ You should think about modifying the deathmatch starts to take full advantage of
|
|||
return; // she doesn't hang out here
|
||||
else if (mariomode)
|
||||
i = MT_TOAD; // don't remove on penalty of death
|
||||
else if (!(netgame || multiplayer) && players[consoleplayer].skin == 5)
|
||||
else if (!(netgame || multiplayer) && players[consoleplayer].skin == 3)
|
||||
return; // no doubles
|
||||
}
|
||||
|
||||
|
@ -12486,6 +12521,76 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
}
|
||||
break;
|
||||
}
|
||||
case MT_REDBOOSTER:
|
||||
{
|
||||
angle_t angle = FixedAngle(mthing->angle << FRACBITS);
|
||||
fixed_t x1 = FINECOSINE((angle >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t y1 = FINESINE((angle >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t x2 = FINECOSINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t y2 = FINESINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
|
||||
mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle-ANGLE_90;
|
||||
P_SetMobjState(seg, S_REDBOOSTERSEG_FACE);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle+ANGLE_90;
|
||||
P_SetMobjState(seg, S_REDBOOSTERSEG_FACE);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERSEG_LEFT);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERSEG_RIGHT);
|
||||
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1+x2), 13*(y1+y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1-x2), 13*(y1-y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1+x2), -13*(y1+y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1-x2), -13*(y1-y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERROLLER);
|
||||
break;
|
||||
}
|
||||
case MT_YELLOWBOOSTER:
|
||||
{
|
||||
angle_t angle = FixedAngle(mthing->angle << FRACBITS);
|
||||
fixed_t x1 = FINECOSINE((angle >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t y1 = FINESINE((angle >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t x2 = FINECOSINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t y2 = FINESINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
|
||||
mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle-ANGLE_90;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERSEG_FACE);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle+ANGLE_90;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERSEG_FACE);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERSEG_LEFT);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERSEG_RIGHT);
|
||||
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1+x2), 13*(y1+y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1-x2), 13*(y1-y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1+x2), -13*(y1+y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1-x2), -13*(y1-y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERROLLER);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2606,7 +2606,6 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
boolean loadedbm = false;
|
||||
sector_t *ss;
|
||||
boolean chase;
|
||||
|
||||
levelloading = true;
|
||||
|
||||
// This is needed. Don't touch.
|
||||
|
@ -3047,8 +3046,11 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
CONS_Printf(M_GetText("No player currently available to become IT. Awaiting available players.\n"));
|
||||
|
||||
}
|
||||
else if (gametype == GT_RACE && server && cv_usemapnumlaps.value)
|
||||
CV_StealthSetValue(&cv_numlaps, mapheaderinfo[gamemap - 1]->numlaps);
|
||||
else if (gametype == GT_RACE && server)
|
||||
CV_StealthSetValue(&cv_numlaps,
|
||||
(cv_basenumlaps.value)
|
||||
? cv_basenumlaps.value
|
||||
: mapheaderinfo[gamemap - 1]->numlaps);
|
||||
|
||||
// ===========
|
||||
// landing point for netgames.
|
||||
|
|
69
src/p_spec.c
69
src/p_spec.c
|
@ -2718,6 +2718,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
CONS_Debug(DBG_GAMELOGIC, "Line type 414 Executor: sfx number %d is invalid!\n", sfxnum);
|
||||
return;
|
||||
}
|
||||
|
||||
if (line->tag != 0) // Do special stuff only if a non-zero linedef tag is set
|
||||
{
|
||||
if (line->flags & ML_EFFECT5) // Repeat Midtexture
|
||||
|
@ -2758,30 +2759,32 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (line->flags & ML_NOCLIMB)
|
||||
else
|
||||
{
|
||||
// play the sound from nowhere, but only if display player triggered it
|
||||
if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer]))
|
||||
if (line->flags & ML_NOCLIMB)
|
||||
{
|
||||
// play the sound from nowhere, but only if display player triggered it
|
||||
if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer]))
|
||||
S_StartSound(NULL, sfxnum);
|
||||
}
|
||||
else if (line->flags & ML_EFFECT4)
|
||||
{
|
||||
// play the sound from nowhere
|
||||
S_StartSound(NULL, sfxnum);
|
||||
}
|
||||
else if (line->flags & ML_EFFECT4)
|
||||
{
|
||||
// play the sound from nowhere
|
||||
S_StartSound(NULL, sfxnum);
|
||||
}
|
||||
else if (line->flags & ML_BLOCKMONSTERS)
|
||||
{
|
||||
// play the sound from calling sector's soundorg
|
||||
if (callsec)
|
||||
S_StartSound(&callsec->soundorg, sfxnum);
|
||||
}
|
||||
else if (line->flags & ML_BLOCKMONSTERS)
|
||||
{
|
||||
// play the sound from calling sector's soundorg
|
||||
if (callsec)
|
||||
S_StartSound(&callsec->soundorg, sfxnum);
|
||||
else if (mo)
|
||||
S_StartSound(&mo->subsector->sector->soundorg, sfxnum);
|
||||
}
|
||||
else if (mo)
|
||||
S_StartSound(&mo->subsector->sector->soundorg, sfxnum);
|
||||
}
|
||||
else if (mo)
|
||||
{
|
||||
// play the sound from mobj that triggered it
|
||||
S_StartSound(mo, sfxnum);
|
||||
{
|
||||
// play the sound from mobj that triggered it
|
||||
S_StartSound(mo, sfxnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -5984,8 +5987,6 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline)
|
|||
* to the lowest nearby height if not
|
||||
* there already.
|
||||
*
|
||||
* Replaces the old "AirBob".
|
||||
*
|
||||
* \param sec Control sector.
|
||||
* \param actionsector Target sector.
|
||||
* \param sourceline Control linedef.
|
||||
|
@ -6030,8 +6031,7 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline)
|
|||
raise->sourceline = sourceline;
|
||||
}
|
||||
|
||||
// Function to maintain backwards compatibility
|
||||
static void P_AddOldAirbob(sector_t *sec, line_t *sourceline, boolean noadjust)
|
||||
static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boolean dynamic)
|
||||
{
|
||||
levelspecthink_t *airbob;
|
||||
|
||||
|
@ -6068,6 +6068,8 @@ static void P_AddOldAirbob(sector_t *sec, line_t *sourceline, boolean noadjust)
|
|||
airbob->vars[5] = sec->ceilingheight;
|
||||
airbob->vars[4] = airbob->vars[5]
|
||||
- (sec->ceilingheight - sec->floorheight);
|
||||
|
||||
airbob->vars[9] = dynamic ? 1 : 0;
|
||||
|
||||
airbob->sourceline = sourceline;
|
||||
}
|
||||
|
@ -6891,11 +6893,16 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
case 151: // Adjustable air bobbing platform
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
||||
P_AddOldAirbob(lines[i].frontsector, lines + i, (lines[i].special != 151));
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, (lines[i].special != 151), false);
|
||||
break;
|
||||
case 152: // Adjustable air bobbing platform in reverse
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||
P_AddOldAirbob(lines[i].frontsector, lines + i, true);
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
||||
break;
|
||||
case 153: // Dynamic Sinking Platform
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, false, true);
|
||||
break;
|
||||
|
||||
case 160: // Float/bob platform
|
||||
|
@ -6946,14 +6953,14 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers);
|
||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
||||
P_AddOldAirbob(lines[i].frontsector, lines + i, true);
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
||||
break;
|
||||
|
||||
case 177: // Air bobbing platform that will crumble and bob on
|
||||
// the water when it falls and hits, then never return
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB|FF_CRUMBLE|FF_NORETURN, secthinkers);
|
||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
||||
P_AddOldAirbob(lines[i].frontsector, lines + i, true);
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
||||
break;
|
||||
|
||||
case 178: // Crumbling platform that will float when it hits water
|
||||
|
@ -6967,7 +6974,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
case 180: // Air bobbing platform that will crumble
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers);
|
||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
||||
P_AddOldAirbob(lines[i].frontsector, lines + i, true);
|
||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
||||
break;
|
||||
|
||||
case 190: // Rising Platform FOF (solid, opaque, shadows)
|
||||
|
@ -7089,7 +7096,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
case 254: // Bustable block
|
||||
ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP;
|
||||
if (lines[i].flags & ML_NOCLIMB)
|
||||
ffloorflags |= FF_ONLYKNUX;
|
||||
ffloorflags |= FF_STRONGBUST;
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
break;
|
||||
|
|
114
src/p_user.c
114
src/p_user.c
|
@ -191,7 +191,7 @@ boolean P_AutoPause(void)
|
|||
if (netgame || modeattacking || gamestate == GS_TITLESCREEN)
|
||||
return false;
|
||||
|
||||
return (menuactive || window_notinfocus);
|
||||
return (menuactive || ( window_notinfocus && cv_pauseifunfocused.value ));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2263,7 +2263,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
|||
else if (!player->skidtime)
|
||||
player->pflags &= ~PF_GLIDING;
|
||||
}
|
||||
else if (player->charability2 == CA2_MELEE && ((player->panim == PA_ABILITY2) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|
||||
else if (player->charability2 == CA2_MELEE
|
||||
&& ((player->panim == PA_ABILITY2) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY && player->cmd.buttons & (BT_JUMP|BT_USE))))
|
||||
{
|
||||
if (player->mo->state-states != S_PLAY_MELEE_LANDING)
|
||||
{
|
||||
|
@ -2459,39 +2460,42 @@ static void P_CheckBustableBlocks(player_t *player)
|
|||
|
||||
if ((rover->flags & FF_BUSTUP)/* && !rover->master->frontsector->crumblestate*/)
|
||||
{
|
||||
// If it's an FF_SPINBUST, you have to either be jumping, or coming down
|
||||
// onto the top from a spin.
|
||||
if (rover->flags & FF_SPINBUST && ((!(player->pflags & PF_JUMPED) && !(player->pflags & PF_SPINNING) && !(player->pflags & PF_BOUNCING)) || (player->pflags & PF_STARTDASH)))
|
||||
// If it's an FF_SHATTER, you can break it just by touching it.
|
||||
if (rover->flags & FF_SHATTER)
|
||||
goto bust;
|
||||
|
||||
// If it's an FF_SPINBUST, you can break it if you are in your spinning frames
|
||||
// (either from jumping or spindashing).
|
||||
if (rover->flags & FF_SPINBUST
|
||||
&& (((player->pflags & PF_SPINNING) && !(player->pflags & PF_STARTDASH))
|
||||
|| (player->pflags & PF_JUMPED && !(player->pflags & PF_NOJUMPDAMAGE))))
|
||||
goto bust;
|
||||
|
||||
// You can always break it if you have CA_GLIDEANDCLIMB
|
||||
// or if you are bouncing on it
|
||||
// or you are using CA_TWINSPIN/CA2_MELEE.
|
||||
if (player->charability == CA_GLIDEANDCLIMB
|
||||
|| (player->pflags & PF_BOUNCING)
|
||||
|| ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY))
|
||||
|| (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
|
||||
goto bust;
|
||||
|
||||
if (rover->flags & FF_STRONGBUST)
|
||||
continue;
|
||||
|
||||
// if it's not an FF_SHATTER, you must be spinning (and not jumping)
|
||||
// or be super
|
||||
// or have CA_GLIDEANDCLIMB
|
||||
// or be in dashmode with SF_DASHMODE
|
||||
// or be using CA_TWINSPIN
|
||||
// or be using CA2_MELEE
|
||||
// or are drilling in NiGHTS
|
||||
// or are recording for Metal Sonic
|
||||
if (!(rover->flags & FF_SHATTER) && !(rover->flags & FF_SPINBUST)
|
||||
&& !((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED))
|
||||
// If it's not an FF_STRONGBUST, you can break if you are spinning (and not jumping)
|
||||
// or you are super
|
||||
// or you are in dashmode with SF_DASHMODE
|
||||
// or you are drilling in NiGHTS
|
||||
// or you are recording for Metal Sonic
|
||||
if (!((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED))
|
||||
&& !(player->powers[pw_super])
|
||||
&& !(player->charability == CA_GLIDEANDCLIMB)
|
||||
&& !(player->pflags & PF_BOUNCING)
|
||||
&& !(((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) && (player->dashmode >= DASHMODE_THRESHOLD))
|
||||
&& !((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY))
|
||||
&& !(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
|
||||
&& !(player->pflags & PF_DRILLING)
|
||||
&& !metalrecording)
|
||||
continue;
|
||||
|
||||
// Only players with CA_GLIDEANDCLIMB, or CA_TWINSPIN/CA2_MELEE users can break this rock...
|
||||
if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX)
|
||||
&& !(player->charability == CA_GLIDEANDCLIMB
|
||||
|| (player->pflags & PF_BOUNCING)
|
||||
|| ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY))
|
||||
|| (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)))
|
||||
continue;
|
||||
|
||||
bust:
|
||||
topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
|
||||
bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
|
||||
|
||||
|
@ -4156,8 +4160,11 @@ static void P_DoSuperStuff(player_t *player)
|
|||
{
|
||||
player->powers[pw_super] = 0;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||
music_stack_noposition = true; // HACK: Do not reposition next music
|
||||
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
|
||||
if (P_IsLocalPlayer(player))
|
||||
{
|
||||
music_stack_noposition = true; // HACK: Do not reposition next music
|
||||
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
|
||||
}
|
||||
P_RestoreMusic(player);
|
||||
P_SpawnShieldOrb(player);
|
||||
|
||||
|
@ -4226,7 +4233,7 @@ static void P_DoSuperStuff(player_t *player)
|
|||
if (gametype != GT_COOP)
|
||||
player->powers[pw_flashing] = flashingtics-1;
|
||||
|
||||
if ((player->mo->health > 0) && (player->mo->sprite2 & FF_SPR2SUPER))
|
||||
if (player->mo->sprite2 & FF_SPR2SUPER)
|
||||
P_SetPlayerMobjState(player->mo, player->mo->state-states);
|
||||
|
||||
// Inform the netgame that the champion has fallen in the heat of battle.
|
||||
|
@ -4239,8 +4246,11 @@ static void P_DoSuperStuff(player_t *player)
|
|||
}
|
||||
|
||||
// Resume normal music if you're the console player
|
||||
music_stack_noposition = true; // HACK: Do not reposition next music
|
||||
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
|
||||
if (P_IsLocalPlayer(player))
|
||||
{
|
||||
music_stack_noposition = true; // HACK: Do not reposition next music
|
||||
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
|
||||
}
|
||||
P_RestoreMusic(player);
|
||||
|
||||
// If you had a shield, restore its visual significance.
|
||||
|
@ -4348,7 +4358,6 @@ void P_DoJump(player_t *player, boolean soundandstate)
|
|||
{
|
||||
player->mo->momz = 9*FRACUNIT;
|
||||
player->powers[pw_carry] = CR_NONE;
|
||||
player->mo->tracer->flags |= MF_PUSHABLE;
|
||||
P_SetTarget(&player->mo->tracer->target, NULL);
|
||||
P_SetTarget(&player->mo->tracer, NULL);
|
||||
}
|
||||
|
@ -10460,7 +10469,7 @@ static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t target
|
|||
//Axes must be directly parallel or antiparallel, give or take 5 degrees.
|
||||
if (angdiff < ANG10)
|
||||
{
|
||||
mark = P_SpawnMobj(nx, ny, nz, mobj->info->raisestate);
|
||||
mark = P_SpawnMobj(nx, ny, nz, (mobjtype_t)mobj->info->raisestate);
|
||||
return mark;
|
||||
}
|
||||
}
|
||||
|
@ -10675,7 +10684,11 @@ static void P_MinecartThink(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||
if (player->mo->state-states != S_PLAY_STND)
|
||||
{
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||
player->mo->tics = -1;
|
||||
}
|
||||
|
||||
// Move player to minecart.
|
||||
P_TeleportMove(player->mo, minecart->x - minecart->momx, minecart->y - minecart->momy, minecart->z + max(minecart->momz, 0) + 8*FRACUNIT);
|
||||
|
@ -11442,6 +11455,13 @@ void P_PlayerThink(player_t *player)
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (player->powers[pw_justsprung])
|
||||
{
|
||||
#ifdef SPRINGSPIN
|
||||
if (player->powers[pw_justsprung] & (1<<15))
|
||||
player->drawangle += (player->powers[pw_justsprung] & ~(1<<15))*(ANG2+ANG1);
|
||||
#endif
|
||||
}
|
||||
else if ((player->skidtime > (TICRATE/2 - 2) || ((player->pflags & (PF_SPINNING|PF_STARTDASH)) == PF_SPINNING)) && (abs(player->rmomx) > 5*player->mo->scale || abs(player->rmomy) > 5*player->mo->scale)) // spin/skid force
|
||||
player->drawangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy);
|
||||
else if (((player->charability2 == CA2_GUNSLINGER || player->charability2 == CA2_MELEE) && player->panim == PA_ABILITY2) || player->pflags & PF_STASIS || player->skidtime)
|
||||
|
@ -11454,7 +11474,7 @@ void P_PlayerThink(player_t *player)
|
|||
if (player->mo->eflags & MFE_TOUCHWATER || player->powers[pw_flashing] > (flashingtics/4)*3)
|
||||
{
|
||||
diff = (player->mo->angle - player->drawangle);
|
||||
factor = 4;
|
||||
factor = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -11463,7 +11483,7 @@ void P_PlayerThink(player_t *player)
|
|||
}
|
||||
#else
|
||||
diff = (player->mo->angle - player->drawangle);
|
||||
factor = 4;
|
||||
factor = 16;
|
||||
#endif
|
||||
}
|
||||
else if (player->pflags & PF_STARTDASH)
|
||||
|
@ -11498,7 +11518,9 @@ void P_PlayerThink(player_t *player)
|
|||
{
|
||||
boolean currentlyonground = P_IsObjectOnGround(player->mo);
|
||||
|
||||
if (!player->powers[pw_carry] && !player->powers[pw_nocontrol]
|
||||
if (player->powers[pw_noautobrake])
|
||||
;
|
||||
else if (!player->powers[pw_carry] && !player->powers[pw_nocontrol]
|
||||
&& ((player->pflags & (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE|PF_STASIS)) == (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE))
|
||||
&& !(cmd->forwardmove || cmd->sidemove)
|
||||
&& (player->rmomx || player->rmomy)
|
||||
|
@ -11540,9 +11562,6 @@ void P_PlayerThink(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
if (player->powers[pw_pushing])
|
||||
player->powers[pw_pushing]--;
|
||||
|
||||
player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame.
|
||||
|
||||
// Unset statis flags after moving.
|
||||
|
@ -11622,6 +11641,17 @@ void P_PlayerThink(player_t *player)
|
|||
if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM) // tails fly counter
|
||||
player->powers[pw_tailsfly]--;
|
||||
|
||||
if (player->powers[pw_pushing] && player->powers[pw_pushing] < UINT16_MAX)
|
||||
player->powers[pw_pushing]--;
|
||||
|
||||
if (player->powers[pw_justsprung] & ((1<<15)-1) && player->powers[pw_justsprung] < UINT16_MAX)
|
||||
player->powers[pw_justsprung]--;
|
||||
else
|
||||
player->powers[pw_justsprung] = 0;
|
||||
|
||||
if (player->powers[pw_pushing] && player->powers[pw_pushing] < UINT16_MAX)
|
||||
player->powers[pw_pushing]--;
|
||||
|
||||
if (player->powers[pw_underwater] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_PROTECTWATER)))
|
||||
{
|
||||
if (player->powers[pw_underwater] <= 12*TICRATE+1)
|
||||
|
@ -12176,7 +12206,7 @@ void P_PlayerAfterThink(player_t *player)
|
|||
mo->momx = rock->momx;
|
||||
mo->momy = rock->momy;
|
||||
mo->momz = 0;
|
||||
|
||||
|
||||
if (player->panim == PA_IDLE && (mo->momx || mo->momy))
|
||||
{
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#endif
|
||||
|
||||
// Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog
|
||||
#ifdef _WIN32_WCE
|
||||
#if 0
|
||||
#define AVOID_ERRNO
|
||||
#else
|
||||
#include <errno.h>
|
||||
|
|
|
@ -139,9 +139,9 @@ typedef enum
|
|||
FF_PLATFORM = 0x2000000, ///< You can jump up through this to the top.
|
||||
FF_REVERSEPLATFORM = 0x4000000, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
|
||||
FF_INTANGABLEFLATS = 0x6000000, ///< Both flats are intangable, but the sides are still solid.
|
||||
FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Thinks everyone's Knuckles.
|
||||
FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Jump or fall onto it while curled in a ball.
|
||||
FF_ONLYKNUX = 0x20000000, ///< Used with ::FF_BUSTUP. Only Knuckles can break this rock.
|
||||
FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Bustable on mere touch.
|
||||
FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames.
|
||||
FF_STRONGBUST = 0x20000000, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
|
||||
FF_RIPPLE = 0x40000000, ///< Ripple the flats
|
||||
FF_COLORMAPONLY = 0x80000000, ///< Only copy the colormap, not the lightlevel
|
||||
FF_GOOWATER = FF_SHATTERBOTTOM, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
// Quincunx antialiasing of flats!
|
||||
//#define QUINCUNX
|
||||
|
||||
// good night sweet prince
|
||||
#define SHITPLANESPARENCY
|
||||
|
||||
//SoM: 3/23/2000: Use Boom visplane hashing.
|
||||
|
||||
visplane_t *visplanes[MAXVISPLANES];
|
||||
|
@ -868,7 +871,11 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
else // Opaque, but allow transparent flat pixels
|
||||
spanfunc = splatfunc;
|
||||
|
||||
#ifdef SHITPLANESPARENCY
|
||||
if ((spanfunc == splatfunc) != (pl->extra_colormap && (pl->extra_colormap->fog & 4)))
|
||||
#else
|
||||
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
|
||||
#endif
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
light = LIGHTLEVELS-1;
|
||||
|
@ -922,7 +929,11 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
else // Opaque, but allow transparent flat pixels
|
||||
spanfunc = splatfunc;
|
||||
|
||||
#ifdef SHITPLANESPARENCY
|
||||
if ((spanfunc == splatfunc) != (pl->extra_colormap && (pl->extra_colormap->fog & 4)))
|
||||
#else
|
||||
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
|
||||
#endif
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
light = LIGHTLEVELS-1;
|
||||
|
@ -1102,7 +1113,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy);
|
||||
zeroheight = FIXED_TO_FLOAT(temp);
|
||||
|
||||
#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180)
|
||||
#define ANG2RAD(angle) ((float)((angle)*M_PIl)/ANGLE_180)
|
||||
|
||||
// p is the texture origin in view space
|
||||
// Don't add in the offsets at this stage, because doing so can result in
|
||||
|
|
|
@ -117,6 +117,10 @@ consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_O
|
|||
consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Window focus sound sytem toggles
|
||||
consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_YesNo};
|
||||
consvar_t cv_playsoundsifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo};
|
||||
|
||||
#ifdef HAVE_OPENMPT
|
||||
static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}};
|
||||
consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -278,6 +282,8 @@ void S_RegisterSoundStuff(void)
|
|||
CV_RegisterVar(&cv_samplerate);
|
||||
CV_RegisterVar(&cv_resetmusic);
|
||||
CV_RegisterVar(&cv_resetmusicbyheader);
|
||||
CV_RegisterVar(&cv_playsoundsifunfocused);
|
||||
CV_RegisterVar(&cv_playmusicifunfocused);
|
||||
CV_RegisterVar(&cv_gamesounds);
|
||||
CV_RegisterVar(&cv_gamedigimusic);
|
||||
CV_RegisterVar(&cv_gamemidimusic);
|
||||
|
@ -373,6 +379,18 @@ lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx)
|
|||
return W_GetNumForName("dsthok");
|
||||
}
|
||||
|
||||
//
|
||||
// Sound Status
|
||||
//
|
||||
|
||||
boolean S_SoundDisabled(void)
|
||||
{
|
||||
return (
|
||||
sound_disabled ||
|
||||
( window_notinfocus && ! cv_playsoundsifunfocused.value )
|
||||
);
|
||||
}
|
||||
|
||||
// Stop all sounds, load level info, THEN start sounds.
|
||||
void S_StopSounds(void)
|
||||
{
|
||||
|
@ -540,7 +558,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
|||
mobj_t *listenmobj = players[displayplayer].mo;
|
||||
mobj_t *listenmobj2 = NULL;
|
||||
|
||||
if (sound_disabled || !sound_started)
|
||||
if (S_SoundDisabled() || !sound_started)
|
||||
return;
|
||||
|
||||
// Don't want a sound? Okay then...
|
||||
|
@ -730,7 +748,7 @@ dontplay:
|
|||
|
||||
void S_StartSound(const void *origin, sfxenum_t sfx_id)
|
||||
{
|
||||
if (sound_disabled)
|
||||
if (S_SoundDisabled())
|
||||
return;
|
||||
|
||||
if (mariomode) // Sounds change in Mario mode!
|
||||
|
@ -1434,6 +1452,13 @@ boolean S_MusicPaused(void)
|
|||
return I_SongPaused();
|
||||
}
|
||||
|
||||
boolean S_MusicNotInFocus(void)
|
||||
{
|
||||
return (
|
||||
( window_notinfocus && ! cv_playmusicifunfocused.value )
|
||||
);
|
||||
}
|
||||
|
||||
musictype_t S_MusicType(void)
|
||||
{
|
||||
return I_SongType();
|
||||
|
@ -1867,6 +1892,10 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms)
|
|||
}
|
||||
|
||||
S_InitMusicVolume(); // switch between digi and sequence volume
|
||||
|
||||
if (S_MusicNotInFocus())
|
||||
S_PauseAudio();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2009,6 +2038,9 @@ void S_PauseAudio(void)
|
|||
|
||||
void S_ResumeAudio(void)
|
||||
{
|
||||
if (S_MusicNotInFocus())
|
||||
return;
|
||||
|
||||
if (I_SongPlaying() && I_SongPaused())
|
||||
I_ResumeSong();
|
||||
|
||||
|
@ -2202,7 +2234,7 @@ static void Command_RestartAudio_f(void)
|
|||
|
||||
void GameSounds_OnChange(void)
|
||||
{
|
||||
if (M_CheckParm("-nosound"))
|
||||
if (M_CheckParm("-nosound") || M_CheckParm("-noaudio"))
|
||||
return;
|
||||
|
||||
if (sound_disabled)
|
||||
|
@ -2220,7 +2252,7 @@ void GameSounds_OnChange(void)
|
|||
|
||||
void GameDigiMusic_OnChange(void)
|
||||
{
|
||||
if (M_CheckParm("-nomusic"))
|
||||
if (M_CheckParm("-nomusic") || M_CheckParm("-noaudio"))
|
||||
return;
|
||||
else if (M_CheckParm("-nodigmusic"))
|
||||
return;
|
||||
|
@ -2262,7 +2294,7 @@ void GameDigiMusic_OnChange(void)
|
|||
|
||||
void GameMIDIMusic_OnChange(void)
|
||||
{
|
||||
if (M_CheckParm("-nomusic"))
|
||||
if (M_CheckParm("-nomusic") || M_CheckParm("-noaudio"))
|
||||
return;
|
||||
else if (M_CheckParm("-nomidimusic"))
|
||||
return;
|
||||
|
|
|
@ -45,6 +45,9 @@ extern consvar_t cv_gamedigimusic;
|
|||
extern consvar_t cv_gamemidimusic;
|
||||
extern consvar_t cv_gamesounds;
|
||||
|
||||
extern consvar_t cv_playmusicifunfocused;
|
||||
extern consvar_t cv_playsoundsifunfocused;
|
||||
|
||||
#ifdef HAVE_OPENMPT
|
||||
extern consvar_t cv_modfilter;
|
||||
#endif
|
||||
|
@ -144,6 +147,12 @@ void S_StartEx(boolean reset);
|
|||
//
|
||||
lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx);
|
||||
|
||||
//
|
||||
// Sound Status
|
||||
//
|
||||
|
||||
boolean S_SoundDisabled(void);
|
||||
|
||||
//
|
||||
// Start sound for thing at <origin> using <sound_id> from sounds.h
|
||||
//
|
||||
|
@ -164,6 +173,7 @@ boolean S_MIDIMusicDisabled(void);
|
|||
boolean S_MusicDisabled(void);
|
||||
boolean S_MusicPlaying(void);
|
||||
boolean S_MusicPaused(void);
|
||||
boolean S_MusicNotInFocus(void);
|
||||
musictype_t S_MusicType(void);
|
||||
const char *S_MusicName(void);
|
||||
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping);
|
||||
|
|
|
@ -421,9 +421,9 @@ void SCR_DisplayTicRate(void)
|
|||
else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP;
|
||||
|
||||
V_DrawString(vid.width-(72*vid.dupx), h,
|
||||
V_YELLOWMAP|V_NOSCALESTART, "FPS:");
|
||||
V_YELLOWMAP|V_NOSCALESTART|V_HUDTRANS, "FPS:");
|
||||
V_DrawString(vid.width-(40*vid.dupx), h,
|
||||
ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE));
|
||||
ticcntcolor|V_NOSCALESTART|V_HUDTRANS, va("%02d/%02u", totaltics, TICRATE));
|
||||
|
||||
lasttic = ontic;
|
||||
}
|
||||
|
|
|
@ -39,13 +39,8 @@
|
|||
// we try to re-allocate a minimum of buffers for stability of the memory,
|
||||
// so all the small-enough tables based on screen size, are allocated once
|
||||
// and for all at the maximum size.
|
||||
#if defined (_WIN32_WCE)
|
||||
#define MAXVIDWIDTH 320
|
||||
#define MAXVIDHEIGHT 200
|
||||
#else
|
||||
#define MAXVIDWIDTH 1920 // don't set this too high because actually
|
||||
#define MAXVIDHEIGHT 1200 // lots of tables are allocated with the MAX size.
|
||||
#endif
|
||||
#define BASEVIDWIDTH 320 // NEVER CHANGE THIS! This is the original
|
||||
#define BASEVIDHEIGHT 200 // resolution of the graphics.
|
||||
|
||||
|
|
|
@ -357,6 +357,14 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void SDLdoGrabMouse(void)
|
||||
{
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
SDL_SetWindowGrab(window, SDL_TRUE);
|
||||
if (SDL_SetRelativeMouseMode(SDL_TRUE) == 0) // already warps mouse if successful
|
||||
wrapmouseok = SDL_TRUE; // TODO: is wrapmouseok or HalfWarpMouse needed anymore?
|
||||
}
|
||||
|
||||
static void SDLdoUngrabMouse(void)
|
||||
{
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
|
@ -579,12 +587,18 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
|||
if (cv_usemouse.value) I_StartupMouse();
|
||||
}
|
||||
//else firsttimeonmouse = SDL_FALSE;
|
||||
|
||||
if (USE_MOUSEINPUT)
|
||||
SDLdoGrabMouse();
|
||||
}
|
||||
else if (!mousefocus && !kbfocus)
|
||||
{
|
||||
// Tell game we lost focus, pause music
|
||||
window_notinfocus = true;
|
||||
S_PauseAudio();
|
||||
if (! cv_playmusicifunfocused.value)
|
||||
S_PauseAudio();
|
||||
if (! cv_playsoundsifunfocused.value)
|
||||
S_StopSounds();
|
||||
|
||||
if (!disable_mouse)
|
||||
{
|
||||
|
@ -655,9 +669,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt)
|
|||
// -- Monster Iestyn
|
||||
if (SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window)
|
||||
{
|
||||
SDL_SetWindowGrab(window, SDL_TRUE);
|
||||
if (SDL_SetRelativeMouseMode(SDL_TRUE) == 0) // already warps mouse if successful
|
||||
wrapmouseok = SDL_TRUE; // TODO: is wrapmouseok or HalfWarpMouse needed anymore?
|
||||
SDLdoGrabMouse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1056,7 +1068,7 @@ void I_StartupMouse(void)
|
|||
else
|
||||
firsttimeonmouse = SDL_FALSE;
|
||||
if (cv_usemouse.value)
|
||||
return;
|
||||
SDLdoGrabMouse();
|
||||
else
|
||||
SDLdoUngrabMouse();
|
||||
}
|
||||
|
@ -1164,8 +1176,11 @@ void I_FinishUpdate(void)
|
|||
if (cv_closedcaptioning.value)
|
||||
SCR_ClosedCaptions();
|
||||
|
||||
if (cv_ticrate.value)
|
||||
SCR_DisplayTicRate();
|
||||
if (st_overlay)
|
||||
{
|
||||
if (cv_ticrate.value)
|
||||
SCR_DisplayTicRate();
|
||||
}
|
||||
|
||||
if (rendermode == render_soft && screens[0])
|
||||
{
|
||||
|
|
|
@ -715,7 +715,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"cdfm59", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm60", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Speed boost"},
|
||||
{"cdfm63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm64", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm65", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
|
|
@ -351,7 +351,7 @@ void ST_LoadFaceGraphics(INT32 skinnum)
|
|||
if (skins[skinnum].sprites[SPR2_XTRA].numframes)
|
||||
{
|
||||
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[0];
|
||||
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)
|
||||
{
|
||||
|
|
211
src/v_video.c
211
src/v_video.c
|
@ -1074,7 +1074,7 @@ void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skin
|
|||
if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes >= 4)
|
||||
{
|
||||
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[3];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CONTINUE];
|
||||
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
|
||||
const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);
|
||||
|
||||
|
@ -2192,7 +2192,7 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
|
|||
w = SHORT(hu_font[c]->width) * dupx;
|
||||
|
||||
if (cx > scrwidth)
|
||||
break;
|
||||
continue;
|
||||
if (cx+left + w < 0) //left boundary check
|
||||
{
|
||||
cx += w;
|
||||
|
@ -2306,7 +2306,7 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string)
|
|||
w = SHORT(hu_font[c]->width) * dupx / 2;
|
||||
|
||||
if (cx > scrwidth)
|
||||
break;
|
||||
continue;
|
||||
if (cx+left + w < 0) //left boundary check
|
||||
{
|
||||
cx += w;
|
||||
|
@ -2411,7 +2411,7 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string)
|
|||
w = (SHORT(tny_font[c]->width) * dupx);
|
||||
|
||||
if (cx > scrwidth)
|
||||
break;
|
||||
continue;
|
||||
if (cx+left + w < 0) //left boundary check
|
||||
{
|
||||
cx += w;
|
||||
|
@ -2509,7 +2509,7 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
|
|||
w = SHORT(hu_font[c]->width) * dupx;
|
||||
|
||||
if ((cx>>FRACBITS) > scrwidth)
|
||||
break;
|
||||
continue;
|
||||
if ((cx>>FRACBITS)+left + w < 0) //left boundary check
|
||||
{
|
||||
cx += w<<FRACBITS;
|
||||
|
@ -2621,13 +2621,210 @@ void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string)
|
|||
|
||||
w = SHORT(cred_font[c]->width) * dupx;
|
||||
if ((cx>>FRACBITS) > scrwidth)
|
||||
break;
|
||||
continue;
|
||||
|
||||
V_DrawSciencePatch(cx, cy, option, cred_font[c], FRACUNIT);
|
||||
cx += w<<FRACBITS;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a string using the nt_font
|
||||
// Note that the outline is a seperate font set
|
||||
static void V_DrawNameTagLine(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string)
|
||||
{
|
||||
fixed_t cx, cy, w;
|
||||
INT32 c, dupx, dupy, scrwidth, left = 0;
|
||||
const char *ch = string;
|
||||
|
||||
if (option & V_CENTERNAMETAG)
|
||||
x -= FixedInt(FixedMul((V_NameTagWidth(string)/2)*FRACUNIT, scale));
|
||||
option &= ~V_CENTERNAMETAG; // which is also shared with V_ALLOWLOWERCASE...
|
||||
|
||||
cx = x<<FRACBITS;
|
||||
cy = y<<FRACBITS;
|
||||
|
||||
if (option & V_NOSCALESTART)
|
||||
{
|
||||
dupx = vid.dupx;
|
||||
dupy = vid.dupy;
|
||||
scrwidth = vid.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
dupx = dupy = 1;
|
||||
scrwidth = vid.width/vid.dupx;
|
||||
left = (scrwidth - BASEVIDWIDTH)/2;
|
||||
scrwidth -= left;
|
||||
}
|
||||
|
||||
for (;;ch++)
|
||||
{
|
||||
if (!*ch)
|
||||
break;
|
||||
if (*ch == '\n')
|
||||
{
|
||||
cx = x<<FRACBITS;
|
||||
cy += FixedMul((21*dupy)*FRACUNIT, scale);
|
||||
continue;
|
||||
}
|
||||
|
||||
c = toupper(*ch);
|
||||
c -= NT_FONTSTART;
|
||||
|
||||
// character does not exist or is a space
|
||||
if (c < 0 || c >= NT_FONTSIZE || !ntb_font[c] || !nto_font[c])
|
||||
{
|
||||
cx += FixedMul((4 * dupx)*FRACUNIT, scale);
|
||||
continue;
|
||||
}
|
||||
|
||||
w = FixedMul((SHORT(ntb_font[c]->width)+2 * dupx) * FRACUNIT, scale);
|
||||
|
||||
if (FixedInt(cx) > scrwidth)
|
||||
continue;
|
||||
if (cx+(left*FRACUNIT) + w < 0) // left boundary check
|
||||
{
|
||||
cx += w;
|
||||
continue;
|
||||
}
|
||||
|
||||
V_DrawFixedPatch(cx, cy, scale, option, nto_font[c], outlinecolormap);
|
||||
V_DrawFixedPatch(cx, cy, scale, option, ntb_font[c], basecolormap);
|
||||
|
||||
cx += w;
|
||||
}
|
||||
}
|
||||
|
||||
// Looks familiar.
|
||||
void V_DrawNameTag(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string)
|
||||
{
|
||||
const char *text = string;
|
||||
const char *first_token = text;
|
||||
char *last_token = strchr(text, '\n');
|
||||
const INT32 lbreakheight = 21;
|
||||
INT32 ntlines;
|
||||
|
||||
if (option & V_CENTERNAMETAG)
|
||||
{
|
||||
ntlines = V_CountNameTagLines(string);
|
||||
y -= FixedInt(FixedMul(((lbreakheight/2) * (ntlines-1))*FRACUNIT, scale));
|
||||
}
|
||||
|
||||
// No line breaks?
|
||||
// Draw entire string
|
||||
if (!last_token)
|
||||
V_DrawNameTagLine(x, y, option, scale, basecolormap, outlinecolormap, string);
|
||||
// Split string by the line break character
|
||||
else
|
||||
{
|
||||
char *str = NULL;
|
||||
INT32 len;
|
||||
while (true)
|
||||
{
|
||||
// There are still lines left to draw
|
||||
if (last_token)
|
||||
{
|
||||
size_t shift = 0;
|
||||
// Free this line
|
||||
if (str)
|
||||
Z_Free(str);
|
||||
// Find string length, do a malloc...
|
||||
len = (last_token-first_token)+1;
|
||||
str = ZZ_Alloc(len);
|
||||
// Copy the line
|
||||
strncpy(str, first_token, len-1);
|
||||
str[len-1] = '\0';
|
||||
// Don't leave a line break character
|
||||
// at the start of the string!
|
||||
if ((strlen(str) >= 2) && (string[0] == '\n') && (string[1] != '\n'))
|
||||
shift++;
|
||||
// Then draw it
|
||||
V_DrawNameTagLine(x, y, option, scale, basecolormap, outlinecolormap, str+shift);
|
||||
}
|
||||
// No line break character was found
|
||||
else
|
||||
{
|
||||
// Don't leave a line break character
|
||||
// at the start of the string!
|
||||
if ((strlen(first_token) >= 2) && (first_token[0] == '\n') && (first_token[1] != '\n'))
|
||||
first_token++;
|
||||
// Then draw it
|
||||
V_DrawNameTagLine(x, y, option, scale, basecolormap, outlinecolormap, first_token);
|
||||
break;
|
||||
}
|
||||
|
||||
// Next line
|
||||
y += FixedInt(FixedMul(lbreakheight*FRACUNIT, scale));
|
||||
if ((last_token-text)+1 >= (signed)strlen(text))
|
||||
last_token = NULL;
|
||||
else
|
||||
{
|
||||
first_token = last_token;
|
||||
last_token = strchr(first_token+1, '\n');
|
||||
}
|
||||
}
|
||||
// Free this line
|
||||
if (str)
|
||||
Z_Free(str);
|
||||
}
|
||||
}
|
||||
|
||||
// Count the amount of lines in name tag string
|
||||
INT32 V_CountNameTagLines(const char *string)
|
||||
{
|
||||
INT32 ntlines = 1;
|
||||
const char *text = string;
|
||||
const char *first_token = text;
|
||||
char *last_token = strchr(text, '\n');
|
||||
|
||||
// No line breaks?
|
||||
if (!last_token)
|
||||
return ntlines;
|
||||
// Split string by the line break character
|
||||
else
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (last_token)
|
||||
ntlines++;
|
||||
// No line break character was found
|
||||
else
|
||||
break;
|
||||
|
||||
// Next line
|
||||
if ((last_token-text)+1 >= (signed)strlen(text))
|
||||
last_token = NULL;
|
||||
else
|
||||
{
|
||||
first_token = last_token;
|
||||
last_token = strchr(first_token+1, '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
return ntlines;
|
||||
}
|
||||
|
||||
INT32 V_NameTagWidth(const char *string)
|
||||
{
|
||||
INT32 c, w = 0;
|
||||
size_t i;
|
||||
|
||||
// It's possible for string to be a null pointer
|
||||
if (!string)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
c = toupper(string[i]) - NT_FONTSTART;
|
||||
if (c < 0 || c >= NT_FONTSIZE || !ntb_font[c] || !nto_font[c])
|
||||
w += 4;
|
||||
else
|
||||
w += SHORT(ntb_font[c]->width)+2;
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
// Find string width from cred_font chars
|
||||
//
|
||||
INT32 V_CreditStringWidth(const char *string)
|
||||
|
@ -2703,7 +2900,7 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string)
|
|||
w = SHORT(lt_font[c]->width) * dupx;
|
||||
|
||||
if (cx > scrwidth)
|
||||
break;
|
||||
continue;
|
||||
if (cx+left + w < 0) //left boundary check
|
||||
{
|
||||
cx += w;
|
||||
|
|
|
@ -112,6 +112,7 @@ extern RGBA_t *pMasterPalette;
|
|||
#define V_OFFSET 0x00400000 // account for offsets in patches
|
||||
#define V_ALLOWLOWERCASE 0x00800000 // (strings only) allow fonts that have lowercase letters to use them
|
||||
#define V_FLIP 0x00800000 // (patches only) Horizontal flip
|
||||
#define V_CENTERNAMETAG 0x00800000 // (nametag only) center nametag lines
|
||||
|
||||
#define V_SNAPTOTOP 0x01000000 // for centering
|
||||
#define V_SNAPTOBOTTOM 0x02000000 // for centering
|
||||
|
@ -205,6 +206,11 @@ INT32 V_LevelActNumWidth(INT32 num); // act number width
|
|||
void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
INT32 V_CreditStringWidth(const char *string);
|
||||
|
||||
// Draw a string using the nt_font
|
||||
void V_DrawNameTag(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string);
|
||||
INT32 V_CountNameTagLines(const char *string);
|
||||
INT32 V_NameTagWidth(const char *string);
|
||||
|
||||
// Find string width from hu_font chars
|
||||
INT32 V_StringWidth(const char *string, INT32 option);
|
||||
// Find string width from hu_font chars, 0.5x scale
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "p_local.h"
|
||||
|
||||
#include "m_cond.h" // condition sets
|
||||
#include "lua_hook.h" // IntermissionThinker hook
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
@ -802,6 +803,10 @@ void Y_Ticker(void)
|
|||
if (paused || P_AutoPause())
|
||||
return;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_IntermissionThinker();
|
||||
#endif
|
||||
|
||||
intertic++;
|
||||
|
||||
// Team scramble code for team match and CTF.
|
||||
|
@ -1047,6 +1052,9 @@ static void Y_UpdateRecordReplays(void)
|
|||
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';
|
||||
|
|
9
tools/flatb/Makefile
Normal file
9
tools/flatb/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
.PHONY : all clean
|
||||
|
||||
all : flatb
|
||||
|
||||
flatb.exe : flatb.c
|
||||
i686-w64-mingw32-gcc $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ $<
|
||||
|
||||
clean :
|
||||
$(RM) flatb flatb.exe
|
566
tools/flatb/flatb.c
Normal file
566
tools/flatb/flatb.c
Normal file
|
@ -0,0 +1,566 @@
|
|||
#define HELP \
|
||||
"Usage: flatb WAD-file list-file" "\n"\
|
||||
"Replace flats and textures by name in a DOOM WAD." "\n"\
|
||||
"\n"\
|
||||
"list-file may have the following format:" "\n"\
|
||||
"\n"\
|
||||
"GFZFLR01 GFZFLR02" "\n"\
|
||||
"# Comment" "\n"\
|
||||
"GFZROCK GFZBLOCK" "\n"\
|
||||
"\n"\
|
||||
"The first name and second name may be delimited by any whitespace." "\n"\
|
||||
"\n"\
|
||||
"Copyright 2019 James R." "\n"\
|
||||
"All rights reserved." "\n"
|
||||
|
||||
/*
|
||||
Copyright 2019 James R.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define cchar const char
|
||||
#define cvoid const void
|
||||
|
||||
#define LONG int32_t
|
||||
|
||||
#define va_inline( __ap,__last, ... )\
|
||||
(\
|
||||
va_start (__ap,__last),\
|
||||
__VA_ARGS__,\
|
||||
va_end (__ap)\
|
||||
)
|
||||
|
||||
#define DELIM "\t\n\r "
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FILE * fp;
|
||||
cchar * filename;
|
||||
}
|
||||
File;
|
||||
|
||||
int (*le32)(cvoid *);
|
||||
|
||||
void
|
||||
Pexit (int c, cchar *s, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_inline (ap, s,
|
||||
|
||||
vfprintf(stderr, s, ap)
|
||||
|
||||
);
|
||||
exit(c);
|
||||
}
|
||||
|
||||
void
|
||||
Prexit (cchar *pr, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_inline (ap, pr,
|
||||
|
||||
vfprintf(stderr, pr, ap)
|
||||
|
||||
);
|
||||
perror("");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
void
|
||||
Fopen (File *f, cchar *filename, const char *mode)
|
||||
{
|
||||
FILE *fp;
|
||||
if (!( fp = fopen(filename, mode) ))
|
||||
Prexit("%s", filename);
|
||||
f->filename = filename;
|
||||
f->fp = fp;
|
||||
}
|
||||
|
||||
void
|
||||
Ferr (File *f)
|
||||
{
|
||||
if (ferror(f->fp))
|
||||
Prexit("%s", f->filename);
|
||||
}
|
||||
|
||||
char *
|
||||
Fgets (File *f, int b, char *p)
|
||||
{
|
||||
if (!( p = fgets(p, b, f->fp) ))
|
||||
Ferr(f);
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
Fread (File *f, int b, void *p)
|
||||
{
|
||||
if (fread(p, 1, b, f->fp) < b)
|
||||
Ferr(f);
|
||||
}
|
||||
|
||||
void
|
||||
Fwrite (File *f, int b, cvoid *s)
|
||||
{
|
||||
if (fwrite(s, 1, b, f->fp) < b)
|
||||
Ferr(f);
|
||||
}
|
||||
|
||||
void
|
||||
Fseek (File *f, long o)
|
||||
{
|
||||
if (fseek(f->fp, o, SEEK_SET) == -1)
|
||||
Prexit("%s", f->filename);
|
||||
}
|
||||
|
||||
void *
|
||||
Malloc (int b)
|
||||
{
|
||||
void *p;
|
||||
if (!( p = malloc(b) ))
|
||||
Prexit("%d", b);
|
||||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
Calloc (int c, int b)
|
||||
{
|
||||
void *p;
|
||||
if (!( p = calloc(c, b) ))
|
||||
Prexit("(%d)%d", c, b);
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
Reallocp (void *pp, int b)
|
||||
{
|
||||
void *p;
|
||||
if (!( p = realloc((*(void **)pp), b) ))
|
||||
Prexit("%d", b);
|
||||
(*(void **)pp) = p;
|
||||
}
|
||||
|
||||
void
|
||||
strucpy (char *p, cchar *s, int n)
|
||||
{
|
||||
int c;
|
||||
int i;
|
||||
for (i = 0; i < n && ( c = s[i] ); ++i)
|
||||
p[i] = toupper(c);
|
||||
}
|
||||
|
||||
int
|
||||
e32 (cvoid *s)
|
||||
{
|
||||
unsigned int c;
|
||||
c = *(LONG *)s;
|
||||
return (
|
||||
( c >> 24 ) |
|
||||
(( c >> 8 )& 0x00FF00 )|
|
||||
(( c << 8 )& 0xFF0000 )|
|
||||
( c << 24 )
|
||||
);
|
||||
}
|
||||
|
||||
int
|
||||
n32 (cvoid *s)
|
||||
{
|
||||
return *(LONG *)s;
|
||||
}
|
||||
|
||||
void
|
||||
Ie ()
|
||||
{
|
||||
int c;
|
||||
c = 1;
|
||||
if (*(char *)&c == 1)
|
||||
le32 = n32;
|
||||
else
|
||||
le32 = e32;
|
||||
}
|
||||
|
||||
File wad_file;
|
||||
File list_file;
|
||||
|
||||
int list_c;
|
||||
char *** list_v;
|
||||
|
||||
char * directory;
|
||||
char * lump;
|
||||
int lumpsize;
|
||||
|
||||
char * sectors;
|
||||
int sectors_c;
|
||||
|
||||
char * sides;
|
||||
int sides_c;
|
||||
|
||||
int st_floors;
|
||||
int st_ceilings;
|
||||
int st_sectors;
|
||||
|
||||
int st_sides;
|
||||
int st_uppers;
|
||||
int st_mids;
|
||||
int st_lowers;
|
||||
|
||||
/* this is horseshit */
|
||||
char * old;
|
||||
char * new;
|
||||
int did;
|
||||
|
||||
void
|
||||
Itable ()
|
||||
{
|
||||
char a[1024];
|
||||
|
||||
char ***ttt;
|
||||
char ***ppp;
|
||||
|
||||
char **pp;
|
||||
|
||||
int c;
|
||||
|
||||
while (Fgets(&list_file, sizeof a, a))
|
||||
{
|
||||
c = a[0];
|
||||
if (!(
|
||||
c == '\n' ||
|
||||
c == '#'
|
||||
))
|
||||
{
|
||||
list_c++;
|
||||
}
|
||||
}
|
||||
|
||||
rewind(list_file.fp);
|
||||
|
||||
list_v = Calloc(list_c, sizeof (char **));
|
||||
for (
|
||||
ttt = ( ppp = list_v ) + list_c;
|
||||
ppp < ttt;
|
||||
++ppp
|
||||
)
|
||||
{
|
||||
(*ppp) = pp = Calloc(2, sizeof (char *));
|
||||
pp[0] = Malloc(9);
|
||||
pp[1] = Malloc(9);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Iwad ()
|
||||
{
|
||||
char buf[12];
|
||||
|
||||
char * t;
|
||||
char * p;
|
||||
int map;
|
||||
|
||||
char *sector_p;
|
||||
char * side_p;
|
||||
|
||||
int n;
|
||||
int h;
|
||||
|
||||
Fread(&wad_file, 12, buf);
|
||||
if (
|
||||
memcmp(buf, "IWAD", 4) != 0 &&
|
||||
memcmp(buf, "PWAD", 4) != 0
|
||||
)
|
||||
{
|
||||
Pexit(-1,"%s: Not a WAD\n", wad_file.filename);
|
||||
}
|
||||
|
||||
Fseek(&wad_file, (*le32)(&buf[8]));
|
||||
|
||||
n = (*le32)(&buf[4]) * 8;
|
||||
h = n / 9;
|
||||
n *= 2;
|
||||
directory = Malloc(n);
|
||||
/* minimum number of lumps for a map */
|
||||
sectors = Malloc(h);
|
||||
sides = Malloc(h);
|
||||
|
||||
Fread(&wad_file, n, directory);
|
||||
|
||||
sector_p = sectors;
|
||||
side_p = sides;
|
||||
map = 3;
|
||||
for (t = ( p = directory ) + n; p < t; p += 16)
|
||||
{
|
||||
/* looking for SECTORS? Hopefully order doesn't matter in real world. */
|
||||
/* also search for fucking SIDES MY SIDES AAAAAAAAAA */
|
||||
switch (map)
|
||||
{
|
||||
case 0:
|
||||
case 2:
|
||||
if (strncmp(&p[8], "SECTORS", 8) == 0)
|
||||
{
|
||||
/* copy file offset and size */
|
||||
memcpy(sector_p, p, 8);
|
||||
sector_p += 8;
|
||||
sectors_c++;
|
||||
map |= 1;
|
||||
}
|
||||
case 1:
|
||||
if (strncmp(&p[8], "SIDEDEFS", 8) == 0)
|
||||
{
|
||||
memcpy(side_p, p, 8);
|
||||
side_p += 8;
|
||||
sides_c++;
|
||||
map |= 2;
|
||||
}
|
||||
}
|
||||
if (map == 3)
|
||||
{
|
||||
/* MAP marker */
|
||||
if (p[13] == '\0' && strncmp(&p[8], "MAP", 3) == 0)
|
||||
map = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Fuckyou (char *p, int f, int *st)
|
||||
{
|
||||
if (strncmp(p, old, 8) == 0)
|
||||
{
|
||||
strncpy(p, new, 8);
|
||||
(*st)++;
|
||||
did |= f;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Epic (char *p, char *t)
|
||||
{
|
||||
char *top;
|
||||
char *bot;
|
||||
int i;
|
||||
/* oh hi magic number! */
|
||||
for (; p < t; p += 26)
|
||||
{
|
||||
bot = &p [4];
|
||||
top = &p[12];
|
||||
did = 0;
|
||||
for (i = 0; i < list_c; ++i)
|
||||
{
|
||||
old = list_v[i][0];
|
||||
new = list_v[i][1];
|
||||
switch (did)
|
||||
{
|
||||
case 0:
|
||||
case 2:
|
||||
Fuckyou(bot, 1, &st_floors);
|
||||
case 1:
|
||||
Fuckyou(top, 2, &st_ceilings);
|
||||
}
|
||||
if (did == 3)
|
||||
break;
|
||||
}
|
||||
if (did)
|
||||
st_sectors++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Epic2 (char *p, char *t)
|
||||
{
|
||||
char *top;
|
||||
char *mid;
|
||||
char *bot;
|
||||
int i;
|
||||
for (; p < t; p += 30)
|
||||
{
|
||||
top = &p [4];
|
||||
bot = &p[12];
|
||||
mid = &p[20];
|
||||
did = 0;
|
||||
for (i = 0; i < list_c; ++i)
|
||||
{
|
||||
old = list_v[i][0];
|
||||
new = list_v[i][1];
|
||||
switch (did)
|
||||
{
|
||||
case 0:
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
Fuckyou(top, 1, &st_uppers);
|
||||
case 1:
|
||||
case 5:
|
||||
Fuckyou(mid, 2, &st_mids);
|
||||
case 3:
|
||||
Fuckyou(bot, 4, &st_lowers);
|
||||
}
|
||||
if (did == 7)
|
||||
break;
|
||||
}
|
||||
if (did)
|
||||
st_sides++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Fuck (char *p, int c, void (*fn)(char *,char *))
|
||||
{
|
||||
char *t;
|
||||
int offs;
|
||||
int size;
|
||||
for (t = p + c * 8; p < t; p += 8)
|
||||
{
|
||||
offs = (*le32)(p);
|
||||
size = (*le32)(p + 4);
|
||||
if (lumpsize < size)
|
||||
{
|
||||
Reallocp(&lump, size);
|
||||
lumpsize = size;
|
||||
}
|
||||
Fseek(&wad_file, offs);
|
||||
Fread(&wad_file, size, lump);
|
||||
(*fn)(lump, lump + size);
|
||||
Fseek(&wad_file, offs);
|
||||
Fwrite(&wad_file, size, lump);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Awad ()
|
||||
{
|
||||
Fuck (sectors, sectors_c, Epic);
|
||||
Fuck (sides, sides_c, Epic2);
|
||||
}
|
||||
|
||||
void
|
||||
Readtable ()
|
||||
{
|
||||
char a[1024];
|
||||
|
||||
int s;
|
||||
char *old;
|
||||
char *new;
|
||||
|
||||
int c;
|
||||
|
||||
s = 0;
|
||||
|
||||
while (Fgets(&list_file, sizeof a, a))
|
||||
{
|
||||
c = a[0];
|
||||
if (!(
|
||||
c == '\n' ||
|
||||
c == '#'
|
||||
))
|
||||
{
|
||||
if (
|
||||
( old = strtok(a, DELIM) ) &&
|
||||
( new = strtok(0, DELIM) )
|
||||
)
|
||||
{
|
||||
strucpy(list_v[s][0], old, 8);
|
||||
strucpy(list_v[s][1], new, 8);
|
||||
++s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cleanup ()
|
||||
{
|
||||
char ***ttt;
|
||||
char ***ppp;
|
||||
|
||||
char **pp;
|
||||
|
||||
free(lump);
|
||||
free(sides);
|
||||
free(sectors);
|
||||
free(directory);
|
||||
|
||||
if (list_v)
|
||||
{
|
||||
for (
|
||||
ttt = ( ppp = list_v ) + list_c;
|
||||
ppp < ttt && ( pp = (*ppp) );
|
||||
++ppp
|
||||
)
|
||||
{
|
||||
free(pp[0]);
|
||||
free(pp[1]);
|
||||
free(pp);
|
||||
}
|
||||
free(list_v);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int ac, char **av)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (ac < 3)
|
||||
Pexit(0,HELP);
|
||||
|
||||
Fopen (& wad_file, av[1], "rb+");
|
||||
Fopen (&list_file, av[2], "r");
|
||||
|
||||
if (atexit(Cleanup) != 0)
|
||||
Pexit(-1,"Failed to register cleanup function.\n");
|
||||
|
||||
Itable();
|
||||
Readtable();
|
||||
|
||||
Ie();
|
||||
|
||||
Iwad();
|
||||
Awad();
|
||||
|
||||
printf(
|
||||
"%5d sectors changed.\n"
|
||||
"%5d floors.\n"
|
||||
"%5d ceilings.\n"
|
||||
"\n"
|
||||
"%5d sides.\n"
|
||||
"%5d upper textures.\n"
|
||||
"%5d mid textures.\n"
|
||||
"%5d lower textures.\n",
|
||||
|
||||
st_sectors,
|
||||
|
||||
st_floors,
|
||||
st_ceilings,
|
||||
|
||||
st_sides,
|
||||
|
||||
st_uppers,
|
||||
st_mids,
|
||||
st_lowers);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue