Merge branch 'superbutton' into 'next'

Dedicated Shield / Super Transformation Button

See merge request STJr/SRB2!2096
This commit is contained in:
Monster Iestyn 2023-11-26 20:38:49 +00:00
commit 4706e80df1
12 changed files with 227 additions and 213 deletions

View file

@ -158,6 +158,10 @@ typedef enum
PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs
PF_CANCARRY = 1<<29, // Can carry another player? PF_CANCARRY = 1<<29, // Can carry another player?
PF_FINISHED = 1<<30, // The player finished the level. NOT the same as exiting PF_FINISHED = 1<<30, // The player finished the level. NOT the same as exiting
// True if shield button down last tic
// This may be the final flag, but 2.3 could free up the others
PF_SHIELDDOWN = 1<<31,
// up to 1<<31 is free // up to 1<<31 is free
} pflags_t; } pflags_t;

View file

@ -26,20 +26,23 @@
// Button/action code definitions. // Button/action code definitions.
typedef enum typedef enum
{ {
// First 4 bits are weapon change info, DO NOT USE! // First 3 bits are weapon change info, DO NOT USE!
BT_WEAPONMASK = 0x0F, //our first four bits. BT_WEAPONMASK = 0x07, //our first three bits.
BT_SHIELD = 1<<3, // shield or super action
BT_WEAPONNEXT = 1<<4, BT_WEAPONNEXT = 1<<4, // select next weapon
BT_WEAPONPREV = 1<<5, BT_WEAPONPREV = 1<<5, // select previous weapon
BT_ATTACK = 1<<6, // shoot rings
BT_SPIN = 1<<7,
BT_CAMLEFT = 1<<8, // turn camera left
BT_CAMRIGHT = 1<<9, // turn camera right
BT_TOSSFLAG = 1<<10,
BT_JUMP = 1<<11,
BT_FIRENORMAL = 1<<12, // Fire a normal ring no matter what
BT_ATTACK = 1<<6, // shoot rings
BT_SPIN = 1<<7, // spin action
BT_CAMLEFT = 1<<8, // turn camera left
BT_CAMRIGHT = 1<<9, // turn camera right
BT_TOSSFLAG = 1<<10, // toss flag or emeralds
BT_JUMP = 1<<11, // jump action
BT_FIRENORMAL = 1<<12, // fire a normal ring no matter what
// custom lua buttons
BT_CUSTOM1 = 1<<13, BT_CUSTOM1 = 1<<13,
BT_CUSTOM2 = 1<<14, BT_CUSTOM2 = 1<<14,
BT_CUSTOM3 = 1<<15, BT_CUSTOM3 = 1<<15,

View file

@ -589,7 +589,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
{ {
CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN); CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN);
return 1; return 1;
} }
for (i = 0; INT_CONST[i].n; i++) for (i = 0; INT_CONST[i].n; i++)
if (fastcmp(word,INT_CONST[i].n)) { if (fastcmp(word,INT_CONST[i].n)) {

View file

@ -5576,7 +5576,8 @@ struct int_const_s const INT_CONST[] = {
{"ROTAXIS_Z",ROTAXIS_Z}, {"ROTAXIS_Z",ROTAXIS_Z},
// Buttons (ticcmd_t) // Buttons (ticcmd_t)
{"BT_WEAPONMASK",BT_WEAPONMASK}, //our first four bits. {"BT_WEAPONMASK",BT_WEAPONMASK}, //our first three bits.
{"BT_SHIELD",BT_SHIELD},
{"BT_WEAPONNEXT",BT_WEAPONNEXT}, {"BT_WEAPONNEXT",BT_WEAPONNEXT},
{"BT_WEAPONPREV",BT_WEAPONPREV}, {"BT_WEAPONPREV",BT_WEAPONPREV},
{"BT_ATTACK",BT_ATTACK}, // shoot rings {"BT_ATTACK",BT_ATTACK}, // shoot rings
@ -5756,9 +5757,7 @@ struct int_const_s const INT_CONST[] = {
{"GC_WEPSLOT5",GC_WEPSLOT5}, {"GC_WEPSLOT5",GC_WEPSLOT5},
{"GC_WEPSLOT6",GC_WEPSLOT6}, {"GC_WEPSLOT6",GC_WEPSLOT6},
{"GC_WEPSLOT7",GC_WEPSLOT7}, {"GC_WEPSLOT7",GC_WEPSLOT7},
{"GC_WEPSLOT8",GC_WEPSLOT8}, {"GC_SHIELD",GC_SHIELD},
{"GC_WEPSLOT9",GC_WEPSLOT9},
{"GC_WEPSLOT10",GC_WEPSLOT10},
{"GC_FIRE",GC_FIRE}, {"GC_FIRE",GC_FIRE},
{"GC_FIRENORMAL",GC_FIRENORMAL}, {"GC_FIRENORMAL",GC_FIRENORMAL},
{"GC_TOSSFLAG",GC_TOSSFLAG}, {"GC_TOSSFLAG",GC_TOSSFLAG},

View file

@ -1335,7 +1335,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
#if NUM_WEAPONS > 10 #if NUM_WEAPONS > 10
"Add extra inputs to g_input.h/gamecontrols_e" "Add extra inputs to g_input.h/gamecontrols_e"
#endif #endif
//use the four avaliable bits to determine the weapon. //use the three avaliable bits to determine the weapon.
cmd->buttons &= ~BT_WEAPONMASK; cmd->buttons &= ~BT_WEAPONMASK;
for (i = 0; i < NUM_WEAPONS; ++i) for (i = 0; i < NUM_WEAPONS; ++i)
if (PLAYERINPUTDOWN(ssplayer, GC_WEPSLOT1 + i)) if (PLAYERINPUTDOWN(ssplayer, GC_WEPSLOT1 + i))
@ -1353,9 +1353,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL); axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL);
if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0)) if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0))
cmd->buttons |= BT_FIRENORMAL; cmd->buttons |= BT_FIRENORMAL;
// Toss flag button
if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG)) if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG))
cmd->buttons |= BT_TOSSFLAG; cmd->buttons |= BT_TOSSFLAG;
// Shield button
if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD))
cmd->buttons |= BT_SHIELD;
// Lua scriptable buttons // Lua scriptable buttons
if (PLAYERINPUTDOWN(ssplayer, GC_CUSTOM1)) if (PLAYERINPUTDOWN(ssplayer, GC_CUSTOM1))
@ -2748,6 +2753,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->pflags |= PF_SPINDOWN; p->pflags |= PF_SPINDOWN;
p->pflags |= PF_ATTACKDOWN; p->pflags |= PF_ATTACKDOWN;
p->pflags |= PF_JUMPDOWN; p->pflags |= PF_JUMPDOWN;
p->pflags |= PF_SHIELDDOWN;
p->playerstate = PST_LIVE; p->playerstate = PST_LIVE;
p->panim = PA_IDLE; // standing animation p->panim = PA_IDLE; // standing animation

View file

@ -576,9 +576,7 @@ static const char *gamecontrolname[NUM_GAMECONTROLS] =
"weapon5", "weapon5",
"weapon6", "weapon6",
"weapon7", "weapon7",
"weapon8", "shield",
"weapon9",
"weapon10",
"fire", "fire",
"firenormal", "firenormal",
"tossflag", "tossflag",
@ -693,6 +691,7 @@ void G_DefineDefaultControls(void)
gamecontroldefault[gcs_fps][GC_CENTERVIEW ][0] = KEY_LCTRL; gamecontroldefault[gcs_fps][GC_CENTERVIEW ][0] = KEY_LCTRL;
gamecontroldefault[gcs_fps][GC_JUMP ][0] = KEY_SPACE; gamecontroldefault[gcs_fps][GC_JUMP ][0] = KEY_SPACE;
gamecontroldefault[gcs_fps][GC_SPIN ][0] = KEY_LSHIFT; gamecontroldefault[gcs_fps][GC_SPIN ][0] = KEY_LSHIFT;
gamecontroldefault[gcs_fps][GC_SHIELD ][0] = KEY_LALT;
gamecontroldefault[gcs_fps][GC_FIRE ][0] = KEY_RCTRL; gamecontroldefault[gcs_fps][GC_FIRE ][0] = KEY_RCTRL;
gamecontroldefault[gcs_fps][GC_FIRE ][1] = KEY_MOUSE1+0; gamecontroldefault[gcs_fps][GC_FIRE ][1] = KEY_MOUSE1+0;
gamecontroldefault[gcs_fps][GC_FIRENORMAL ][0] = KEY_RALT; gamecontroldefault[gcs_fps][GC_FIRENORMAL ][0] = KEY_RALT;
@ -713,6 +712,7 @@ void G_DefineDefaultControls(void)
gamecontroldefault[gcs_platform][GC_CENTERVIEW ][0] = KEY_END; gamecontroldefault[gcs_platform][GC_CENTERVIEW ][0] = KEY_END;
gamecontroldefault[gcs_platform][GC_JUMP ][0] = KEY_SPACE; gamecontroldefault[gcs_platform][GC_JUMP ][0] = KEY_SPACE;
gamecontroldefault[gcs_platform][GC_SPIN ][0] = KEY_LSHIFT; gamecontroldefault[gcs_platform][GC_SPIN ][0] = KEY_LSHIFT;
gamecontroldefault[gcs_platform][GC_SHIELD ][0] = KEY_LALT;
gamecontroldefault[gcs_platform][GC_FIRE ][0] = 's'; gamecontroldefault[gcs_platform][GC_FIRE ][0] = 's';
gamecontroldefault[gcs_platform][GC_FIRE ][1] = KEY_MOUSE1+0; gamecontroldefault[gcs_platform][GC_FIRE ][1] = KEY_MOUSE1+0;
gamecontroldefault[gcs_platform][GC_FIRENORMAL ][0] = 'w'; gamecontroldefault[gcs_platform][GC_FIRENORMAL ][0] = 'w';
@ -728,9 +728,6 @@ void G_DefineDefaultControls(void)
gamecontroldefault[i][GC_WEPSLOT5 ][0] = '5'; gamecontroldefault[i][GC_WEPSLOT5 ][0] = '5';
gamecontroldefault[i][GC_WEPSLOT6 ][0] = '6'; gamecontroldefault[i][GC_WEPSLOT6 ][0] = '6';
gamecontroldefault[i][GC_WEPSLOT7 ][0] = '7'; gamecontroldefault[i][GC_WEPSLOT7 ][0] = '7';
gamecontroldefault[i][GC_WEPSLOT8 ][0] = '8';
gamecontroldefault[i][GC_WEPSLOT9 ][0] = '9';
gamecontroldefault[i][GC_WEPSLOT10 ][0] = '0';
gamecontroldefault[i][GC_TOSSFLAG ][0] = '\''; gamecontroldefault[i][GC_TOSSFLAG ][0] = '\'';
gamecontroldefault[i][GC_CAMTOGGLE ][0] = 'v'; gamecontroldefault[i][GC_CAMTOGGLE ][0] = 'v';
gamecontroldefault[i][GC_CAMRESET ][0] = 'r'; gamecontroldefault[i][GC_CAMRESET ][0] = 'r';
@ -749,15 +746,15 @@ void G_DefineDefaultControls(void)
gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+1; // B gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+1; // B
gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+3; // Y gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+3; // Y
gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick
gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_JOY1+4; // LB gamecontroldefault[i][GC_SHIELD ][1] = KEY_JOY1+4; // LB
gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB
gamecontroldefault[i][GC_SCREENSHOT ][1] = KEY_JOY1+6; // Back gamecontroldefault[i][GC_SCORES ][1] = KEY_JOY1+6; // Back
gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start
gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left
gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right
gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_JOY1+9; // Right Stick gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_JOY1+9; // Right Stick
gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+0; // D-Pad Up gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+0; // D-Pad Up
gamecontroldefault[i][GC_SCORES ][1] = KEY_HAT1+1; // D-Pad Down gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_HAT1+1; // D-Pad Down
// Second player controls only have joypad defaults // Second player controls only have joypad defaults
gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A
@ -765,15 +762,15 @@ void G_DefineDefaultControls(void)
gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+1; // B gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+1; // B
gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+3; // Y gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+3; // Y
gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick
gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2JOY1+4; // LB gamecontrolbisdefault[i][GC_SHIELD ][1] = KEY_2JOY1+4; // LB
gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB
gamecontrolbisdefault[i][GC_SCREENSHOT ][1] = KEY_2JOY1+6; // Back //gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2JOY1+6; // Back
//gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start //gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start
gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left
gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right
gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2JOY1+9; // Right Stick gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2JOY1+9; // Right Stick
gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+0; // D-Pad Up gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+0; // D-Pad Up
//gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2HAT1+1; // D-Pad Down gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2HAT1+1; // D-Pad Down
} }
} }
@ -1004,6 +1001,7 @@ static void setcontrol(INT32 (*gc)[2])
// TODO: 2.3: Delete the "use" alias // TODO: 2.3: Delete the "use" alias
namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin"; namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin";
for (numctrl = 0; numctrl < NUM_GAMECONTROLS && stricmp(namectrl, gamecontrolname[numctrl]); for (numctrl = 0; numctrl < NUM_GAMECONTROLS && stricmp(namectrl, gamecontrolname[numctrl]);
numctrl++) numctrl++)

View file

@ -74,9 +74,7 @@ typedef enum
GC_WEPSLOT5, GC_WEPSLOT5,
GC_WEPSLOT6, GC_WEPSLOT6,
GC_WEPSLOT7, GC_WEPSLOT7,
GC_WEPSLOT8, GC_SHIELD,
GC_WEPSLOT9,
GC_WEPSLOT10,
GC_FIRE, GC_FIRE,
GC_FIRENORMAL, GC_FIRENORMAL,
GC_TOSSFLAG, GC_TOSSFLAG,

View file

@ -1686,11 +1686,12 @@ static int lib_pHomingAttack(lua_State *L)
static int lib_pSuperReady(lua_State *L) static int lib_pSuperReady(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
boolean transform = (boolean)lua_opttrueboolean(L, 2);
//HUDSAFE //HUDSAFE
INLEVEL INLEVEL
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
lua_pushboolean(L, P_SuperReady(player)); lua_pushboolean(L, P_SuperReady(player, transform));
return 1; return 1;
} }

View file

@ -1068,6 +1068,7 @@ static menuitem_t OP_ChangeControlsMenu[] =
{IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, GC_STRAFERIGHT }, {IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, GC_STRAFERIGHT },
{IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, GC_JUMP }, {IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, GC_JUMP },
{IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, GC_SPIN }, {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, GC_SPIN },
{IT_CALL | IT_STRING2, NULL, "Shield", M_ChangeControl, GC_SHIELD },
{IT_HEADER, NULL, "Camera", NULL, 0}, {IT_HEADER, NULL, "Camera", NULL, 0},
{IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_SPACE, NULL, NULL, NULL, 0}, // padding
{IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, GC_LOOKUP }, {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, GC_LOOKUP },
@ -13167,23 +13168,23 @@ static void M_Setup1PControlsMenu(INT32 choice)
currentMenu->lastOn = itemOn; currentMenu->lastOn = itemOn;
// Unhide the nine non-P2 controls and their headers // Unhide the nine non-P2 controls and their headers
//OP_ChangeControlsMenu[18+0].status = IT_HEADER; //OP_ChangeControlsMenu[19+0].status = IT_HEADER;
//OP_ChangeControlsMenu[18+1].status = IT_SPACE; //OP_ChangeControlsMenu[19+1].status = IT_SPACE;
// ... // ...
OP_ChangeControlsMenu[18+2].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+2].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[18+3].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+3].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[18+4].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+4].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[18+5].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+5].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[18+6].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+6].status = IT_CALL|IT_STRING2;
//OP_ChangeControlsMenu[18+7].status = IT_CALL|IT_STRING2; //OP_ChangeControlsMenu[19+7].status = IT_CALL|IT_STRING2;
//OP_ChangeControlsMenu[18+8].status = IT_CALL|IT_STRING2; //OP_ChangeControlsMenu[19+8].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[18+9].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+9].status = IT_CALL|IT_STRING2;
// ... // ...
OP_ChangeControlsMenu[28+0].status = IT_HEADER; OP_ChangeControlsMenu[29+0].status = IT_HEADER;
OP_ChangeControlsMenu[28+1].status = IT_SPACE; OP_ChangeControlsMenu[29+1].status = IT_SPACE;
// ... // ...
OP_ChangeControlsMenu[28+2].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[29+2].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[28+3].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[29+3].status = IT_CALL|IT_STRING2;
OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef; OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef;
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level
@ -13199,23 +13200,23 @@ static void M_Setup2PControlsMenu(INT32 choice)
currentMenu->lastOn = itemOn; currentMenu->lastOn = itemOn;
// Hide the nine non-P2 controls and their headers // Hide the nine non-P2 controls and their headers
//OP_ChangeControlsMenu[18+0].status = IT_GRAYEDOUT2; //OP_ChangeControlsMenu[19+0].status = IT_GRAYEDOUT2;
//OP_ChangeControlsMenu[18+1].status = IT_GRAYEDOUT2; //OP_ChangeControlsMenu[19+1].status = IT_GRAYEDOUT2;
// ... // ...
OP_ChangeControlsMenu[18+2].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+2].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[18+3].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+3].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[18+4].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+4].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[18+5].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+5].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[18+6].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+6].status = IT_GRAYEDOUT2;
//OP_ChangeControlsMenu[18+7].status = IT_GRAYEDOUT2; //OP_ChangeControlsMenu[19+7].status = IT_GRAYEDOUT2;
//OP_ChangeControlsMenu[18+8].status = IT_GRAYEDOUT2; //OP_ChangeControlsMenu[19+8].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[18+9].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+9].status = IT_GRAYEDOUT2;
// ... // ...
OP_ChangeControlsMenu[28+0].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[29+0].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[28+1].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[29+1].status = IT_GRAYEDOUT2;
// ... // ...
OP_ChangeControlsMenu[28+2].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[29+2].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[28+3].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[29+3].status = IT_GRAYEDOUT2;
OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef; OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef;
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level

View file

@ -202,7 +202,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet);
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius);
void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius); void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius);
boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user
boolean P_SuperReady(player_t *player); boolean P_SuperReady(player_t *player, boolean transform);
void P_DoJump(player_t *player, boolean soundandstate); void P_DoJump(player_t *player, boolean soundandstate);
void P_DoSpinDashDust(player_t *player); void P_DoSpinDashDust(player_t *player);
#define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG) #define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG)

View file

@ -666,7 +666,7 @@ static void P_DeNightserizePlayer(player_t *player)
player->powers[pw_carry] = CR_NIGHTSFALL; player->powers[pw_carry] = CR_NIGHTSFALL;
player->powers[pw_underwater] = 0; player->powers[pw_underwater] = 0;
player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST); player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_SHIELDDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST);
player->secondjump = 0; player->secondjump = 0;
player->homing = 0; player->homing = 0;
player->climbing = 0; player->climbing = 0;
@ -794,7 +794,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
} }
} }
player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_SPINNING|PF_DRILLING); player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_SHIELDDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_SPINNING|PF_DRILLING);
player->homing = 0; player->homing = 0;
player->mo->fuse = 0; player->mo->fuse = 0;
player->speed = 0; player->speed = 0;
@ -1342,8 +1342,6 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player)) if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player))
P_PlayJingle(player, JT_SUPER); P_PlayJingle(player, JT_SUPER);
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
player->mo->momx = player->mo->momy = player->mo->momz = player->cmomx = player->cmomy = player->rmomx = player->rmomy = 0; player->mo->momx = player->mo->momy = player->mo->momz = player->cmomx = player->cmomy = player->rmomx = player->rmomy = 0;
// Transformation animation // Transformation animation
@ -1360,8 +1358,11 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
player->powers[pw_sneakers] = 0; player->powers[pw_sneakers] = 0;
} }
if (!G_CoopGametype()) if (G_CoopGametype())
S_StartSound(player->mo, sfx_supert); //only hear it near yourself in co-op
else
{ {
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
HU_SetCEchoFlags(0); HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5); HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is now super.\\\\\\\\", player_names[player-players])); HU_DoCEcho(va("%s\\is now super.\\\\\\\\", player_names[player-players]));
@ -1370,6 +1371,56 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
P_PlayerFlagBurst(player, false); P_PlayerFlagBurst(player, false);
} }
//
// P_DoSuperDetransformation
//
// Detransform into regular Sonic!
static void P_DoSuperDetransformation(player_t *player)
{
player->powers[pw_emeralds] = 0; // lost the power stones
P_SpawnGhostMobj(player->mo);
player->powers[pw_super] = 0;
// Restore color
if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER)
{
player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
}
else
{
player->mo->color = P_GetPlayerColor(player);
G_GhostAddColor(GHC_NORMAL);
}
if (!G_CoopGametype())
player->powers[pw_flashing] = flashingtics-1;
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.
if (!G_CoopGametype())
{
S_StartSound(NULL, sfx_s3k66); //let all players hear it.
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}
// Resume normal music if you're the console player
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.
P_SpawnShieldOrb(player);
}
// Adds to the player's score // Adds to the player's score
void P_AddPlayerScore(player_t *player, UINT32 amount) void P_AddPlayerScore(player_t *player, UINT32 amount)
{ {
@ -4086,6 +4137,16 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
I_Assert(player != NULL); I_Assert(player != NULL);
I_Assert(!P_MobjWasRemoved(player->mo)); I_Assert(!P_MobjWasRemoved(player->mo));
// Toss a flag
if (cmd->buttons & BT_TOSSFLAG && G_GametypeHasTeams()
&& !(player->powers[pw_super]) && !(player->tossdelay))
{
if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
P_PlayerEmeraldBurst(player, true); // Toss emeralds
else
P_PlayerFlagBurst(player, true);
}
if (!(cmd->buttons & (BT_ATTACK|BT_FIRENORMAL))) if (!(cmd->buttons & (BT_ATTACK|BT_FIRENORMAL)))
{ {
@ -4095,9 +4156,10 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
return; return;
} }
if (player->pflags & PF_ATTACKDOWN || player->climbing || (G_TagGametype() && !(player->pflags & PF_TAGIT))) if (player->pflags & PF_ATTACKDOWN || player->climbing)
return; return;
// Fire a fireball if we have the Fire Flower powerup!
if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->weapondelay)) if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->weapondelay))
{ {
player->pflags |= PF_ATTACKDOWN; player->pflags |= PF_ATTACKDOWN;
@ -4109,7 +4171,8 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
return; return;
} }
if (!G_RingSlingerGametype() || player->weapondelay) // No ringslinging outside of ringslinger!
if (!G_RingSlingerGametype() || player->weapondelay || (G_TagGametype() && !(player->pflags & PF_TAGIT)))
return; return;
player->pflags |= PF_ATTACKDOWN; player->pflags |= PF_ATTACKDOWN;
@ -4287,34 +4350,7 @@ static void P_DoSuperStuff(player_t *player)
// If you're super and not Sonic, de-superize! // If you're super and not Sonic, de-superize!
if (!(ALL7EMERALDS(emeralds) && player->charflags & SF_SUPER)) if (!(ALL7EMERALDS(emeralds) && player->charflags & SF_SUPER))
{ {
player->powers[pw_super] = 0; P_DoSuperDetransformation(player);
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
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);
// Restore color
if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER)
{
player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
}
else
{
player->mo->color = P_GetPlayerColor(player);
G_GhostAddColor(GHC_NORMAL);
}
if (!G_CoopGametype())
{
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}
return; return;
} }
@ -4341,69 +4377,37 @@ static void P_DoSuperStuff(player_t *player)
// Ran out of rings while super! // Ran out of rings while super!
if (player->rings <= 0 || player->exiting) if (player->rings <= 0 || player->exiting)
{ P_DoSuperDetransformation(player);
player->powers[pw_emeralds] = 0; // lost the power stones
P_SpawnGhostMobj(player->mo);
player->powers[pw_super] = 0;
// Restore color
if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER)
{
player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
}
else
{
player->mo->color = P_GetPlayerColor(player);
G_GhostAddColor(GHC_NORMAL);
}
if (!G_CoopGametype())
player->powers[pw_flashing] = flashingtics-1;
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.
if (!G_CoopGametype())
{
S_StartSound(NULL, sfx_s3k66); //let all players hear it.
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}
// Resume normal music if you're the console player
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.
P_SpawnShieldOrb(player);
}
} }
} }
// //
// P_SuperReady // P_SuperReady
// //
// Returns true if player is ready to turn super, duh // Returns true if player is ready to transform or detransform
// //
boolean P_SuperReady(player_t *player) boolean P_SuperReady(player_t *player, boolean transform)
{ {
if (!player->powers[pw_super] if (!transform &&
&& !player->powers[pw_invulnerability] (player->powers[pw_super] < TICRATE*3/2
|| !G_CoopGametype())) // No turning back in competitive!
return false;
else if (transform
&& (player->powers[pw_super]
|| !ALL7EMERALDS(emeralds)
|| !(player->rings >= 50)))
return false;
if (player->mo
&& !player->powers[pw_tailsfly] && !player->powers[pw_tailsfly]
&& !player->powers[pw_carry]
&& (player->charflags & SF_SUPER) && (player->charflags & SF_SUPER)
&& (player->pflags & PF_JUMPED) && !P_PlayerInPain(player)
&& !(player->powers[pw_shield] & SH_NOSTACK) && !player->climbing
&& !(maptol & TOL_NIGHTS) && !(player->pflags & (PF_FULLSTASIS|PF_THOKKED|PF_STARTDASH|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY))
&& ALL7EMERALDS(emeralds) && ((player->pflags & PF_JUMPED) || (P_IsObjectOnGround(player->mo) && (player->panim == PA_IDLE || player->panim == PA_EDGE
&& (player->rings >= 50)) || player->panim == PA_WALK || player->panim == PA_RUN || (player->charflags & SF_DASHMODE && player->panim == PA_DASH))))
&& !(maptol & TOL_NIGHTS))
return true; return true;
return false; return false;
@ -5094,7 +5098,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
{ {
mobj_t *lockonshield = NULL; mobj_t *lockonshield = NULL;
if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SPINDOWN) if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SHIELDDOWN)
&& ((!(player->pflags & PF_THOKKED) || (((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP || (player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) && player->secondjump == UINT8_MAX) ))) // thokked is optional if you're bubblewrapped / 3dblasted && ((!(player->pflags & PF_THOKKED) || (((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP || (player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) && player->secondjump == UINT8_MAX) ))) // thokked is optional if you're bubblewrapped / 3dblasted
{ {
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT && !(player->charflags & SF_NOSHIELDABILITY)) if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT && !(player->charflags & SF_NOSHIELDABILITY))
@ -5121,7 +5125,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
} }
} }
} }
if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUA_HookPlayer(player, HOOK(ShieldSpecial)))) // Spin button effects if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SHIELD && !LUA_HookPlayer(player, HOOK(ShieldSpecial)))) // Shield button effects
{ {
// Force stop // Force stop
if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE)
@ -5242,52 +5246,45 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
; ;
else if (P_PlayerShieldThink(player, cmd, lockonthok, visual)) else if (P_PlayerShieldThink(player, cmd, lockonthok, visual))
; ;
else if ((cmd->buttons & BT_SPIN)) else if ((cmd->buttons & BT_SPIN) && !LUA_HookPlayer(player, HOOK(JumpSpinSpecial)))
{ {
if (!(player->pflags & PF_SPINDOWN) && P_SuperReady(player)) switch (player->charability)
{ {
// If you can turn super and aren't already, case CA_THOK:
// and you don't have a shield, do it! if (player->powers[pw_super]) // Super Sonic float
P_DoSuperTransformation(player, false); {
} if ((player->speed > 5*player->mo->scale) // FixedMul(5<<FRACBITS, player->mo->scale), but scale is FRACUNIT-based
else if (!LUA_HookPlayer(player, HOOK(JumpSpinSpecial))) && (P_MobjFlip(player->mo)*player->mo->momz <= 0))
switch (player->charability)
{
case CA_THOK:
if (player->powers[pw_super]) // Super Sonic float
{ {
if ((player->speed > 5*player->mo->scale) // FixedMul(5<<FRACBITS, player->mo->scale), but scale is FRACUNIT-based if (player->panim != PA_RUN && player->panim != PA_WALK)
&& (P_MobjFlip(player->mo)*player->mo->momz <= 0))
{ {
if (player->panim != PA_RUN && player->panim != PA_WALK) if (player->speed >= FixedMul(player->runspeed, player->mo->scale))
{ P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN);
if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) else
P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN); P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT);
else
P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT);
}
player->mo->momz = 0;
player->pflags &= ~(PF_STARTJUMP|PF_SPINNING);
player->secondjump = 1;
} }
player->mo->momz = 0;
player->pflags &= ~(PF_STARTJUMP|PF_SPINNING);
player->secondjump = 1;
} }
break; }
case CA_TELEKINESIS: break;
if (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || (player->charflags & SF_MULTIABILITY)) case CA_TELEKINESIS:
{ if (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || (player->charflags & SF_MULTIABILITY))
P_Telekinesis(player, {
-FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player) P_Telekinesis(player,
FixedMul(384*FRACUNIT, player->mo->scale)); -FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player)
} FixedMul(384*FRACUNIT, player->mo->scale));
break; }
case CA_TWINSPIN: break;
if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || player->charflags & SF_MULTIABILITY)) case CA_TWINSPIN:
P_DoTwinSpin(player); if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || player->charflags & SF_MULTIABILITY))
break; P_DoTwinSpin(player);
default: break;
break; default:
} break;
}
} }
} }
@ -5350,12 +5347,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
} }
else if (player->pflags & PF_SLIDING || ((gametyperules & GTR_TEAMFLAGS) && player->gotflag) || player->pflags & PF_SHIELDABILITY) else if (player->pflags & PF_SLIDING || ((gametyperules & GTR_TEAMFLAGS) && player->gotflag) || player->pflags & PF_SHIELDABILITY)
; ;
/*else if (P_SuperReady(player))
{
// If you can turn super and aren't already,
// and you don't have a shield, do it!
P_DoSuperTransformation(player, false);
}*/
else if (player->pflags & PF_JUMPED) else if (player->pflags & PF_JUMPED)
{ {
if (!LUA_HookPlayer(player, HOOK(AbilitySpecial))) if (!LUA_HookPlayer(player, HOOK(AbilitySpecial)))
@ -8686,18 +8677,31 @@ void P_MovePlayer(player_t *player)
&& player->panim == PA_IDLE && !(player->powers[pw_carry])) && player->panim == PA_IDLE && !(player->powers[pw_carry]))
P_DoTeeter(player); P_DoTeeter(player);
// Toss a flag // Check for fire and shield buttons
if (G_GametypeHasTeams() && (cmd->buttons & BT_TOSSFLAG) && !(player->powers[pw_super]) && !(player->tossdelay)) if (!player->exiting && !(player->pflags & PF_STASIS))
{ {
if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) // Check for fire buttons
P_PlayerEmeraldBurst(player, true); // Toss emeralds
else
P_PlayerFlagBurst(player, true);
}
// check for fire
if (!player->exiting)
P_DoFiring(player, cmd); P_DoFiring(player, cmd);
// Release the shield button
if (!(cmd->buttons & BT_SHIELD))
player->pflags &= ~PF_SHIELDDOWN;
// Shield button behavior
// Check P_PlayerShieldThink for actual shields!
else if (!(player->pflags & PF_SHIELDDOWN))
{
// Transform into super if we can!
if (P_SuperReady(player, true))
P_DoSuperTransformation(player, false);
// Detransform from super if we can!
else if (P_SuperReady(player, false))
P_DoSuperDetransformation(player);
player->pflags |= PF_SHIELDDOWN;
}
}
{ {
boolean atspinheight = false; boolean atspinheight = false;

View file

@ -579,9 +579,9 @@ void Y_IntermissionDrawer(void)
{ {
if (LUA_HudEnabled(hud_intermissiontitletext)) if (LUA_HudEnabled(hud_intermissiontitletext))
{ {
const char *ringtext = "\x82" "50 rings, no shield"; const char *ringtext = "\x82" "get 50 rings then";
const char *tut1text = "\x82" "press " "\x80" "spin"; const char *tut1text = "\x82" "press " "\x80" "shield";
const char *tut2text = "\x82" "mid-" "\x80" "jump"; const char *tut2text = "\x82" "to " "\x80" "transform";
ttheight = 8; ttheight = 8;
V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
ttheight += V_LevelNameHeight(data.spec.passed3) + 2; ttheight += V_LevelNameHeight(data.spec.passed3) + 2;