mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +00:00
Rednukem: implement WW2GI weapons
# Conflicts: # source/rr/src/actors.cpp # source/rr/src/gamevars.cpp # source/rr/src/sbar.cpp
This commit is contained in:
parent
972f2c4f0d
commit
365b7bfe79
7 changed files with 1561 additions and 53 deletions
|
@ -1184,7 +1184,7 @@ ACTOR_STATIC void G_MovePlayers(void)
|
|||
{
|
||||
pSprite->extra = pPlayer->max_player_health;
|
||||
pSprite->cstat = 257;
|
||||
if (!RR)
|
||||
if (!RR && !WW2GI)
|
||||
pPlayer->inv_amount[GET_JETPACK] = 1599;
|
||||
}
|
||||
|
||||
|
@ -1801,6 +1801,20 @@ ACTOR_STATIC void G_MoveStandables(void)
|
|||
}
|
||||
else if (!RR && pSprite->picnum == TRIPBOMB)
|
||||
{
|
||||
int const tripBombMode = Gv_GetVarByLabel("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, -1, -1);
|
||||
if(tripBombMode & TRIPBOMB_TIMER)
|
||||
{
|
||||
// we're on a timer....
|
||||
if (pSprite->extra >= 0)
|
||||
{
|
||||
pSprite->extra--;
|
||||
if (pSprite->extra == 0)
|
||||
{
|
||||
T3(spriteNum) = 16;
|
||||
A_PlaySound(LASERTRIP_ARMING,spriteNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (T3(spriteNum) > 0)
|
||||
{
|
||||
T3(spriteNum)--;
|
||||
|
@ -1871,6 +1885,8 @@ ACTOR_STATIC void G_MoveStandables(void)
|
|||
actor[spriteNum].lastv.x = hitDist;
|
||||
pSprite->ang = oldAng;
|
||||
|
||||
if (tripBombMode & TRIPBOMB_TRIPWIRE)
|
||||
{
|
||||
// we're on a trip wire
|
||||
//int16_t cursectnum;
|
||||
|
||||
|
@ -1896,6 +1912,7 @@ ACTOR_STATIC void G_MoveStandables(void)
|
|||
//if (cursectnum < 0)
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
T1(spriteNum)++;
|
||||
|
||||
|
@ -1906,7 +1923,7 @@ ACTOR_STATIC void G_MoveStandables(void)
|
|||
setsprite(spriteNum,(vec3_t *)pSprite);
|
||||
T4(spriteNum) = T3(spriteNum) = 0;
|
||||
|
||||
if (hitSprite >= 0)
|
||||
if (hitSprite >= 0 && (tripBombMode & TRIPBOMB_TRIPWIRE))
|
||||
{
|
||||
T3(spriteNum) = 13;
|
||||
A_PlaySound(LASERTRIP_ARMING,spriteNum);
|
||||
|
@ -1934,7 +1951,7 @@ ACTOR_STATIC void G_MoveStandables(void)
|
|||
setsprite(spriteNum, (vec3_t *) pSprite);
|
||||
|
||||
// if( Actor[i].lastvx != x && lTripBombControl & TRIPBOMB_TRIPWIRE)
|
||||
if (actor[spriteNum].lastv.x != hitDist)
|
||||
if (actor[spriteNum].lastv.x != hitDist && (tripBombMode & TRIPBOMB_TRIPWIRE))
|
||||
{
|
||||
T3(spriteNum) = 13;
|
||||
A_PlaySound(LASERTRIP_ARMING, spriteNum);
|
||||
|
|
|
@ -185,6 +185,43 @@ void G_SetupCheats(void)
|
|||
Bstrcpy(CheatStrings[39], "van");
|
||||
}
|
||||
}
|
||||
if (WW2GI)
|
||||
{
|
||||
#if 0
|
||||
// WWII GI's original cheat prefix temporarily disabled because W conflicts with WSAD movement
|
||||
CheatKeys[0] = CheatKeys[1] = sc_W;
|
||||
#else
|
||||
CheatKeys[0] = sc_G;
|
||||
CheatKeys[1] = sc_I;
|
||||
#endif
|
||||
|
||||
Bstrcpy(CheatStrings[0], "2god");
|
||||
Bstrcpy(CheatStrings[1], "2blood");
|
||||
Bstrcpy(CheatStrings[2], "2level###");
|
||||
Bstrcpy(CheatStrings[3], "2coords");
|
||||
Bstrcpy(CheatStrings[4], "2view");
|
||||
Bstrcpy(CheatStrings[5], "<RESERVED>");
|
||||
Bstrcpy(CheatStrings[7], "<RESERVED>");
|
||||
Bstrcpy(CheatStrings[8], "<RESERVED>");
|
||||
Bstrcpy(CheatStrings[9], "2rate");
|
||||
Bstrcpy(CheatStrings[10], "2skill");
|
||||
Bstrcpy(CheatStrings[11], "<RESERVED>");
|
||||
Bstrcpy(CheatStrings[12], "<RESERVED>");
|
||||
Bstrcpy(CheatStrings[13], "<RESERVED>");
|
||||
Bstrcpy(CheatStrings[16], "2matt");
|
||||
Bstrcpy(CheatStrings[17], "2showmap");
|
||||
Bstrcpy(CheatStrings[18], "2ryan");
|
||||
Bstrcpy(CheatStrings[19], "<RESERVED>");
|
||||
Bstrcpy(CheatStrings[20], "2clip");
|
||||
Bstrcpy(CheatStrings[21], "2weapons");
|
||||
Bstrcpy(CheatStrings[22], "2inventory");
|
||||
Bstrcpy(CheatStrings[23], "<RESERVED>");
|
||||
Bstrcpy(CheatStrings[24], "2debug");
|
||||
Bstrcpy(CheatStrings[26], "2cgs");
|
||||
|
||||
Bstrcpy(g_gametypeNames[0], "GI Match (Spawn)");
|
||||
Bstrcpy(g_gametypeNames[2], "GI Match (No Spawn)");
|
||||
}
|
||||
else if (NAM)
|
||||
{
|
||||
CheatKeys[0] = sc_N;
|
||||
|
|
852
source/rr/src/gamevars.cpp
Normal file
852
source/rr/src/gamevars.cpp
Normal file
|
@ -0,0 +1,852 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2016 EDuke32 developers and contributors
|
||||
|
||||
This file is part of EDuke32.
|
||||
|
||||
EDuke32 is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#include "duke3d.h"
|
||||
#include "menus.h"
|
||||
#include "savegame.h"
|
||||
|
||||
#include "vfs.h"
|
||||
|
||||
#define gamevars_c_
|
||||
|
||||
gamevar_t aGameVars[MAXGAMEVARS];
|
||||
int32_t g_gameVarCount = 0;
|
||||
|
||||
// pointers to weapon gamevar data
|
||||
intptr_t *aplWeaponClip[MAX_WEAPONS]; // number of items in magazine
|
||||
intptr_t *aplWeaponFireDelay[MAX_WEAPONS]; // delay to fire
|
||||
intptr_t *aplWeaponFireSound[MAX_WEAPONS]; // Sound made when firing (each time for automatic)
|
||||
intptr_t *aplWeaponFlags[MAX_WEAPONS]; // Flags for weapon
|
||||
intptr_t *aplWeaponFlashColor[MAX_WEAPONS]; // Muzzle flash color
|
||||
intptr_t *aplWeaponHoldDelay[MAX_WEAPONS]; // delay after release fire button to fire (0 for none)
|
||||
intptr_t *aplWeaponInitialSound[MAX_WEAPONS]; // Sound made when weapon starts firing. zero for no sound
|
||||
intptr_t *aplWeaponReload[MAX_WEAPONS]; // delay to reload (include fire)
|
||||
intptr_t *aplWeaponShoots[MAX_WEAPONS]; // what the weapon shoots
|
||||
intptr_t *aplWeaponShotsPerBurst[MAX_WEAPONS]; // number of shots per 'burst' (one ammo per 'burst')
|
||||
intptr_t *aplWeaponSound2Sound[MAX_WEAPONS]; // Alternate sound sound ID
|
||||
intptr_t *aplWeaponSound2Time[MAX_WEAPONS]; // Alternate sound time
|
||||
intptr_t *aplWeaponSpawn[MAX_WEAPONS]; // the item to spawn
|
||||
intptr_t *aplWeaponSpawnTime[MAX_WEAPONS]; // the frame at which to spawn an item
|
||||
intptr_t *aplWeaponTotalTime[MAX_WEAPONS]; // The total time the weapon is cycling before next fire.
|
||||
intptr_t *aplWeaponWorksLike[MAX_WEAPONS]; // What original the weapon works like
|
||||
|
||||
|
||||
// Frees the memory for the *values* of game variables and arrays. Resets their
|
||||
// counts to zero. Call this function as many times as needed.
|
||||
//
|
||||
// Returns: old g_gameVarCount | (g_gameArrayCount<<16).
|
||||
int Gv_Free(void)
|
||||
{
|
||||
for (auto &gameVar : aGameVars)
|
||||
{
|
||||
if (gameVar.flags & GAMEVAR_USER_MASK)
|
||||
ALIGNED_FREE_AND_NULL(gameVar.pValues);
|
||||
gameVar.flags |= GAMEVAR_RESET;
|
||||
}
|
||||
|
||||
EDUKE32_STATIC_ASSERT(MAXGAMEVARS < 32768);
|
||||
int const varCount = g_gameVarCount;
|
||||
g_gameVarCount = 0;
|
||||
|
||||
hash_init(&h_gamevars);
|
||||
|
||||
return varCount;
|
||||
}
|
||||
|
||||
// Calls Gv_Free() and in addition frees the labels of all game variables and
|
||||
// arrays.
|
||||
// Only call this function at exit
|
||||
void Gv_Clear(void)
|
||||
{
|
||||
Gv_Free();
|
||||
|
||||
// Now, only do work that Gv_Free() hasn't done.
|
||||
for (auto & gameVar : aGameVars)
|
||||
DO_FREE_AND_NULL(gameVar.szLabel);
|
||||
}
|
||||
|
||||
int Gv_ReadSave(buildvfs_kfd kFile)
|
||||
{
|
||||
char tbuf[12];
|
||||
|
||||
if (kread(kFile, tbuf, 12)!=12) goto corrupt;
|
||||
if (Bmemcmp(tbuf, "BEG: EDuke32", 12)) { OSD_Printf("BEG ERR\n"); return 2; }
|
||||
|
||||
Gv_Free(); // nuke 'em from orbit, it's the only way to be sure...
|
||||
|
||||
if (kdfread_LZ4(&g_gameVarCount,sizeof(g_gameVarCount),1,kFile) != 1) goto corrupt;
|
||||
for (bssize_t i=0; i<g_gameVarCount; i++)
|
||||
{
|
||||
char *const olabel = aGameVars[i].szLabel;
|
||||
|
||||
if (kdfread_LZ4(&aGameVars[i], sizeof(gamevar_t), 1, kFile) != 1)
|
||||
goto corrupt;
|
||||
|
||||
aGameVars[i].szLabel = (char *)Xrealloc(olabel, MAXVARLABEL * sizeof(uint8_t));
|
||||
|
||||
if (kdfread_LZ4(aGameVars[i].szLabel, MAXVARLABEL, 1, kFile) != 1)
|
||||
goto corrupt;
|
||||
hash_add(&h_gamevars, aGameVars[i].szLabel,i, 1);
|
||||
|
||||
if (aGameVars[i].flags & GAMEVAR_PERPLAYER)
|
||||
{
|
||||
aGameVars[i].pValues = (intptr_t*)Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
|
||||
if (kdfread_LZ4(aGameVars[i].pValues,sizeof(intptr_t) * MAXPLAYERS, 1, kFile) != 1) goto corrupt;
|
||||
}
|
||||
else if (aGameVars[i].flags & GAMEVAR_PERACTOR)
|
||||
{
|
||||
aGameVars[i].pValues = (intptr_t*)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
|
||||
if (kdfread_LZ4(aGameVars[i].pValues,sizeof(intptr_t) * MAXSPRITES, 1, kFile) != 1) goto corrupt;
|
||||
}
|
||||
}
|
||||
|
||||
Gv_InitWeaponPointers();
|
||||
|
||||
// Gv_RefreshPointers();
|
||||
|
||||
uint8_t savedstate[MAXVOLUMES*MAXLEVELS];
|
||||
Bmemset(savedstate, 0, sizeof(savedstate));
|
||||
|
||||
if (kdfread_LZ4(savedstate, sizeof(savedstate), 1, kFile) != 1) goto corrupt;
|
||||
|
||||
for (bssize_t i = 0; i < (MAXVOLUMES * MAXLEVELS); i++)
|
||||
{
|
||||
G_FreeMapState(i);
|
||||
|
||||
if (!savedstate[i])
|
||||
continue;
|
||||
|
||||
g_mapInfo[i].savedstate = (mapstate_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, sizeof(mapstate_t));
|
||||
if (kdfread_LZ4(g_mapInfo[i].savedstate, sizeof(mapstate_t), 1, kFile) != 1) return -8;
|
||||
|
||||
mapstate_t &sv = *g_mapInfo[i].savedstate;
|
||||
|
||||
for (bssize_t j = 0; j < g_gameVarCount; j++)
|
||||
{
|
||||
if (aGameVars[j].flags & GAMEVAR_NORESET) continue;
|
||||
if (aGameVars[j].flags & GAMEVAR_PERPLAYER)
|
||||
{
|
||||
sv.vars[j] = (intptr_t *) Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
|
||||
if (kdfread_LZ4(sv.vars[j], sizeof(intptr_t) * MAXPLAYERS, 1, kFile) != 1) return -9;
|
||||
}
|
||||
else if (aGameVars[j].flags & GAMEVAR_PERACTOR)
|
||||
{
|
||||
sv.vars[j] = (intptr_t *) Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
|
||||
if (kdfread_LZ4(sv.vars[j], sizeof(intptr_t) * MAXSPRITES, 1, kFile) != 1) return -10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kread(kFile, tbuf, 12) != 12) return -13;
|
||||
if (Bmemcmp(tbuf, "EOF: EDuke32", 12)) { OSD_Printf("EOF ERR\n"); return 2; }
|
||||
|
||||
return 0;
|
||||
|
||||
corrupt:
|
||||
return -7;
|
||||
}
|
||||
|
||||
void Gv_WriteSave(buildvfs_FILE fil)
|
||||
{
|
||||
// AddLog("Saving Game Vars to File");
|
||||
buildvfs_fwrite("BEG: EDuke32", 12, 1, fil);
|
||||
|
||||
dfwrite_LZ4(&g_gameVarCount,sizeof(g_gameVarCount),1,fil);
|
||||
|
||||
for (bssize_t i = 0; i < g_gameVarCount; i++)
|
||||
{
|
||||
dfwrite_LZ4(&(aGameVars[i]), sizeof(gamevar_t), 1, fil);
|
||||
dfwrite_LZ4(aGameVars[i].szLabel, sizeof(uint8_t) * MAXVARLABEL, 1, fil);
|
||||
|
||||
if (aGameVars[i].flags & GAMEVAR_PERPLAYER)
|
||||
dfwrite_LZ4(aGameVars[i].pValues, sizeof(intptr_t) * MAXPLAYERS, 1, fil);
|
||||
else if (aGameVars[i].flags & GAMEVAR_PERACTOR)
|
||||
dfwrite_LZ4(aGameVars[i].pValues, sizeof(intptr_t) * MAXSPRITES, 1, fil);
|
||||
}
|
||||
|
||||
uint8_t savedstate[MAXVOLUMES * MAXLEVELS];
|
||||
Bmemset(savedstate, 0, sizeof(savedstate));
|
||||
|
||||
for (bssize_t i = 0; i < (MAXVOLUMES * MAXLEVELS); i++)
|
||||
if (g_mapInfo[i].savedstate != NULL)
|
||||
savedstate[i] = 1;
|
||||
|
||||
dfwrite_LZ4(savedstate, sizeof(savedstate), 1, fil);
|
||||
|
||||
for (bssize_t i = 0; i < (MAXVOLUMES * MAXLEVELS); i++)
|
||||
{
|
||||
if (!savedstate[i]) continue;
|
||||
|
||||
mapstate_t &sv = *g_mapInfo[i].savedstate;
|
||||
|
||||
dfwrite_LZ4(g_mapInfo[i].savedstate, sizeof(mapstate_t), 1, fil);
|
||||
|
||||
for (bssize_t j = 0; j < g_gameVarCount; j++)
|
||||
{
|
||||
if (aGameVars[j].flags & GAMEVAR_NORESET) continue;
|
||||
if (aGameVars[j].flags & GAMEVAR_PERPLAYER)
|
||||
dfwrite_LZ4(sv.vars[j], sizeof(intptr_t) * MAXPLAYERS, 1, fil);
|
||||
else if (aGameVars[j].flags & GAMEVAR_PERACTOR)
|
||||
dfwrite_LZ4(sv.vars[j], sizeof(intptr_t) * MAXSPRITES, 1, fil);
|
||||
}
|
||||
}
|
||||
|
||||
buildvfs_fwrite("EOF: EDuke32", 12, 1, fil);
|
||||
}
|
||||
|
||||
void Gv_DumpValues(void)
|
||||
{
|
||||
buildprint("// Current Game Definitions\n\n");
|
||||
|
||||
for (bssize_t i=0; i<g_gameVarCount; i++)
|
||||
{
|
||||
buildprint("gamevar ", aGameVars[i].szLabel, " ");
|
||||
|
||||
if (aGameVars[i].flags & (GAMEVAR_INT32PTR))
|
||||
buildprint(*(int32_t *)aGameVars[i].global);
|
||||
else if (aGameVars[i].flags & (GAMEVAR_INT16PTR))
|
||||
buildprint(*(int16_t *)aGameVars[i].global);
|
||||
else
|
||||
buildprint(aGameVars[i].global);
|
||||
|
||||
if (aGameVars[i].flags & (GAMEVAR_PERPLAYER))
|
||||
buildprint(" GAMEVAR_PERPLAYER");
|
||||
else if (aGameVars[i].flags & (GAMEVAR_PERACTOR))
|
||||
buildprint(" GAMEVAR_PERACTOR");
|
||||
else
|
||||
buildprint(" ", aGameVars[i].flags/* & (GAMEVAR_USER_MASK)*/);
|
||||
|
||||
buildprint(" // ");
|
||||
if (aGameVars[i].flags & (GAMEVAR_SYSTEM))
|
||||
buildprint(" (system)");
|
||||
if (aGameVars[i].flags & (GAMEVAR_PTR_MASK))
|
||||
buildprint(" (pointer)");
|
||||
if (aGameVars[i].flags & (GAMEVAR_READONLY))
|
||||
buildprint(" (read only)");
|
||||
if (aGameVars[i].flags & (GAMEVAR_SPECIAL))
|
||||
buildprint(" (special)");
|
||||
buildprint("\n");
|
||||
}
|
||||
buildprint("\n// end of game definitions\n");
|
||||
}
|
||||
|
||||
// XXX: This function is very strange.
|
||||
void Gv_ResetVars(void) /* this is called during a new game and nowhere else */
|
||||
{
|
||||
Gv_Free();
|
||||
|
||||
for (auto &aGameVar : aGameVars)
|
||||
{
|
||||
if (aGameVar.szLabel != NULL)
|
||||
Gv_NewVar(aGameVar.szLabel, (aGameVar.flags & GAMEVAR_NODEFAULT) ? aGameVar.global : aGameVar.defaultValue, aGameVar.flags);
|
||||
}
|
||||
}
|
||||
|
||||
void Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags)
|
||||
{
|
||||
if (EDUKE32_PREDICT_FALSE(g_gameVarCount >= MAXGAMEVARS))
|
||||
{
|
||||
g_errorCnt++;
|
||||
C_ReportError(-1);
|
||||
initprintf("%s:%d: error: too many gamevars!\n",g_scriptFileName,g_lineNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
if (EDUKE32_PREDICT_FALSE(Bstrlen(pszLabel) > (MAXVARLABEL-1)))
|
||||
{
|
||||
g_errorCnt++;
|
||||
C_ReportError(-1);
|
||||
initprintf("%s:%d: error: variable name `%s' exceeds limit of %d characters.\n",g_scriptFileName,g_lineNumber,pszLabel, MAXVARLABEL);
|
||||
return;
|
||||
}
|
||||
|
||||
int gV = hash_find(&h_gamevars,pszLabel);
|
||||
|
||||
if (gV >= 0 && !(aGameVars[gV].flags & GAMEVAR_RESET))
|
||||
{
|
||||
// found it...
|
||||
if (EDUKE32_PREDICT_FALSE(aGameVars[gV].flags & (GAMEVAR_PTR_MASK)))
|
||||
{
|
||||
C_ReportError(-1);
|
||||
initprintf("%s:%d: warning: cannot redefine internal gamevar `%s'.\n",g_scriptFileName,g_lineNumber,label+(g_labelCnt<<6));
|
||||
return;
|
||||
}
|
||||
else if (EDUKE32_PREDICT_FALSE(!(aGameVars[gV].flags & GAMEVAR_SYSTEM)))
|
||||
{
|
||||
// it's a duplicate in error
|
||||
g_warningCnt++;
|
||||
C_ReportError(WARNING_DUPLICATEDEFINITION);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (gV == -1)
|
||||
gV = g_gameVarCount;
|
||||
|
||||
// If it's a user gamevar...
|
||||
if ((aGameVars[gV].flags & GAMEVAR_SYSTEM) == 0)
|
||||
{
|
||||
// Allocate and set its label
|
||||
if (aGameVars[gV].szLabel == NULL)
|
||||
aGameVars[gV].szLabel = (char *)Xcalloc(MAXVARLABEL,sizeof(uint8_t));
|
||||
|
||||
if (aGameVars[gV].szLabel != pszLabel)
|
||||
Bstrcpy(aGameVars[gV].szLabel,pszLabel);
|
||||
|
||||
// and the flags
|
||||
aGameVars[gV].flags=dwFlags;
|
||||
|
||||
// only free if per-{actor,player}
|
||||
if (aGameVars[gV].flags & GAMEVAR_USER_MASK)
|
||||
ALIGNED_FREE_AND_NULL(aGameVars[gV].pValues);
|
||||
}
|
||||
|
||||
// if existing is system, they only get to change default value....
|
||||
aGameVars[gV].defaultValue = lValue;
|
||||
aGameVars[gV].flags &= ~GAMEVAR_RESET;
|
||||
|
||||
if (gV == g_gameVarCount)
|
||||
{
|
||||
// we're adding a new one.
|
||||
hash_add(&h_gamevars, aGameVars[gV].szLabel, g_gameVarCount++, 0);
|
||||
}
|
||||
|
||||
// Set initial values. (Or, override values for system gamevars.)
|
||||
if (aGameVars[gV].flags & GAMEVAR_PERPLAYER)
|
||||
{
|
||||
if (!aGameVars[gV].pValues)
|
||||
{
|
||||
aGameVars[gV].pValues = (intptr_t *) Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
|
||||
Bmemset(aGameVars[gV].pValues, 0, MAXPLAYERS * sizeof(intptr_t));
|
||||
}
|
||||
for (bssize_t j=MAXPLAYERS-1; j>=0; --j)
|
||||
aGameVars[gV].pValues[j]=lValue;
|
||||
}
|
||||
else if (aGameVars[gV].flags & GAMEVAR_PERACTOR)
|
||||
{
|
||||
if (!aGameVars[gV].pValues)
|
||||
{
|
||||
aGameVars[gV].pValues = (intptr_t *) Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
|
||||
Bmemset(aGameVars[gV].pValues, 0, MAXSPRITES * sizeof(intptr_t));
|
||||
}
|
||||
for (bssize_t j=MAXSPRITES-1; j>=0; --j)
|
||||
aGameVars[gV].pValues[j]=lValue;
|
||||
}
|
||||
else aGameVars[gV].global = lValue;
|
||||
}
|
||||
|
||||
static int Gv_GetVarIndex(const char *szGameLabel)
|
||||
{
|
||||
int const gameVar = hash_find(&h_gamevars,szGameLabel);
|
||||
|
||||
if (EDUKE32_PREDICT_FALSE((unsigned)gameVar >= MAXGAMEVARS))
|
||||
{
|
||||
OSD_Printf(OSD_ERROR "Gv_GetVarIndex(): INTERNAL ERROR: couldn't find gamevar %s!\n", szGameLabel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return gameVar;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int __fastcall getvar__(int const gameVar, int const spriteNum, int const playerNum)
|
||||
{
|
||||
auto const &var = aGameVars[gameVar & (MAXGAMEVARS-1)];
|
||||
|
||||
int returnValue = 0;
|
||||
int const varFlags = var.flags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
|
||||
|
||||
if (!varFlags) returnValue = var.global;
|
||||
else if (varFlags == GAMEVAR_PERACTOR)
|
||||
returnValue = var.pValues[spriteNum & (MAXSPRITES-1)];
|
||||
else if (varFlags == GAMEVAR_PERPLAYER)
|
||||
returnValue = var.pValues[playerNum & (MAXPLAYERS-1)];
|
||||
else switch (varFlags & GAMEVAR_PTR_MASK)
|
||||
{
|
||||
case GAMEVAR_RAWQ16PTR:
|
||||
case GAMEVAR_INT32PTR: returnValue = *(int32_t *)var.global; break;
|
||||
case GAMEVAR_INT16PTR: returnValue = *(int16_t *)var.global; break;
|
||||
case GAMEVAR_Q16PTR: returnValue = fix16_to_int(*(fix16_t *)var.global); break;
|
||||
}
|
||||
|
||||
return NEGATE_ON_CONDITION(returnValue, gameVar & GV_FLAG_NEGATIVE);
|
||||
}
|
||||
|
||||
int __fastcall Gv_GetVar(int const gameVar, int const spriteNum, int const playerNum) { return getvar__(gameVar, spriteNum, playerNum); }
|
||||
int __fastcall Gv_GetVar(int const gameVar) { return getvar__(gameVar, vm.spriteNum, vm.playerNum); }
|
||||
|
||||
void __fastcall Gv_GetManyVars(int const numVars, int32_t * const outBuf)
|
||||
{
|
||||
for (native_t j = 0; j < numVars; ++j)
|
||||
outBuf[j] = getvar__(*insptr++, vm.spriteNum, vm.playerNum);
|
||||
}
|
||||
|
||||
static FORCE_INLINE void __fastcall setvar__(int const gameVar, int const newValue, int const spriteNum, int const playerNum)
|
||||
{
|
||||
gamevar_t &var = aGameVars[gameVar];
|
||||
int const varFlags = var.flags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
|
||||
|
||||
if (!varFlags) var.global=newValue;
|
||||
else if (varFlags == GAMEVAR_PERACTOR)
|
||||
var.pValues[spriteNum & (MAXSPRITES-1)] = newValue;
|
||||
else if (varFlags == GAMEVAR_PERPLAYER)
|
||||
var.pValues[playerNum & (MAXPLAYERS-1)] = newValue;
|
||||
else switch (varFlags & GAMEVAR_PTR_MASK)
|
||||
{
|
||||
case GAMEVAR_RAWQ16PTR:
|
||||
case GAMEVAR_INT32PTR: *((int32_t *)var.global) = (int32_t)newValue; break;
|
||||
case GAMEVAR_INT16PTR: *((int16_t *)var.global) = (int16_t)newValue; break;
|
||||
case GAMEVAR_Q16PTR: *(fix16_t *)var.global = fix16_from_int((int16_t)newValue); break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void __fastcall Gv_SetVar(int const gameVar, int const newValue) { setvar__(gameVar, newValue, vm.spriteNum, vm.playerNum); }
|
||||
void __fastcall Gv_SetVar(int const gameVar, int const newValue, int const spriteNum, int const playerNum)
|
||||
{
|
||||
setvar__(gameVar, newValue, spriteNum, playerNum);
|
||||
}
|
||||
|
||||
int Gv_GetVarByLabel(const char *szGameLabel, int const defaultValue, int const spriteNum, int const playerNum)
|
||||
{
|
||||
int const gameVar = hash_find(&h_gamevars, szGameLabel);
|
||||
return EDUKE32_PREDICT_TRUE(gameVar >= 0) ? Gv_GetVar(gameVar, spriteNum, playerNum) : defaultValue;
|
||||
}
|
||||
|
||||
static intptr_t *Gv_GetVarDataPtr(const char *szGameLabel)
|
||||
{
|
||||
int const gameVar = hash_find(&h_gamevars, szGameLabel);
|
||||
|
||||
if (EDUKE32_PREDICT_FALSE((unsigned)gameVar >= MAXGAMEVARS))
|
||||
return NULL;
|
||||
|
||||
gamevar_t &var = aGameVars[gameVar];
|
||||
|
||||
if (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK))
|
||||
return var.pValues;
|
||||
|
||||
return &(var.global);
|
||||
}
|
||||
|
||||
void Gv_ResetSystemDefaults(void)
|
||||
{
|
||||
// call many times...
|
||||
char aszBuf[64];
|
||||
|
||||
//AddLog("ResetWeaponDefaults");
|
||||
|
||||
for (int weaponNum = 0; weaponNum < MAX_WEAPONS; ++weaponNum)
|
||||
{
|
||||
for (int playerNum = 0; playerNum < MAXPLAYERS; ++playerNum)
|
||||
{
|
||||
Bsprintf(aszBuf, "WEAPON%d_CLIP", weaponNum);
|
||||
aplWeaponClip[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_RELOAD", weaponNum);
|
||||
aplWeaponReload[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_FIREDELAY", weaponNum);
|
||||
aplWeaponFireDelay[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_TOTALTIME", weaponNum);
|
||||
aplWeaponTotalTime[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_HOLDDELAY", weaponNum);
|
||||
aplWeaponHoldDelay[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_FLAGS", weaponNum);
|
||||
aplWeaponFlags[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_SHOOTS", weaponNum);
|
||||
aplWeaponShoots[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
if ((unsigned)aplWeaponShoots[weaponNum][playerNum] >= MAXTILES)
|
||||
aplWeaponShoots[weaponNum][playerNum] = 0;
|
||||
Bsprintf(aszBuf, "WEAPON%d_SPAWNTIME", weaponNum);
|
||||
aplWeaponSpawnTime[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_SPAWN", weaponNum);
|
||||
aplWeaponSpawn[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_SHOTSPERBURST", weaponNum);
|
||||
aplWeaponShotsPerBurst[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_WORKSLIKE", weaponNum);
|
||||
aplWeaponWorksLike[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_INITIALSOUND", weaponNum);
|
||||
aplWeaponInitialSound[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_FIRESOUND", weaponNum);
|
||||
aplWeaponFireSound[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_SOUND2TIME", weaponNum);
|
||||
aplWeaponSound2Time[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_SOUND2SOUND", weaponNum);
|
||||
aplWeaponSound2Sound[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
Bsprintf(aszBuf, "WEAPON%d_FLASHCOLOR", weaponNum);
|
||||
aplWeaponFlashColor[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
|
||||
}
|
||||
}
|
||||
|
||||
g_aimAngleVarID = Gv_GetVarIndex("AUTOAIMANGLE");
|
||||
g_angRangeVarID = Gv_GetVarIndex("ANGRANGE");
|
||||
g_returnVarID = Gv_GetVarIndex("RETURN");
|
||||
g_weaponVarID = Gv_GetVarIndex("WEAPON");
|
||||
g_worksLikeVarID = Gv_GetVarIndex("WORKSLIKE");
|
||||
g_zRangeVarID = Gv_GetVarIndex("ZRANGE");
|
||||
|
||||
//AddLog("EOF:ResetWeaponDefaults");
|
||||
}
|
||||
|
||||
// Will set members that were overridden at CON translation time to 1.
|
||||
// For example, if
|
||||
// gamevar WEAPON1_SHOOTS 2200 GAMEVAR_PERPLAYER
|
||||
// was specified at file scope, g_weaponOverridden[1].Shoots will be 1.
|
||||
weapondata_t g_weaponOverridden[MAX_WEAPONS];
|
||||
|
||||
static weapondata_t weapondefaults[MAX_WEAPONS] = {
|
||||
/*
|
||||
WorksLike, Clip, Reload, FireDelay, TotalTime, HoldDelay,
|
||||
Flags,
|
||||
Shoots, SpawnTime, Spawn, ShotsPerBurst, InitialSound, FireSound, Sound2Time, Sound2Sound,
|
||||
FlashColor
|
||||
*/
|
||||
{
|
||||
KNEE_WEAPON__STATIC, 0, 30, 7, 14, 14,
|
||||
WEAPON_RANDOMRESTART | WEAPON_AUTOMATIC,
|
||||
KNEE__STATIC, 0, 0, 0, 0, 0, 0,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
PISTOL_WEAPON, 20, 50, 2, 5, 0,
|
||||
WEAPON_AUTOMATIC | WEAPON_HOLSTER_CLEARS_CLIP,
|
||||
SHOTSPARK1__STATIC, 2, SHELL__STATIC, 0, 0, PISTOL_FIRE__STATIC, 0, 0,
|
||||
255+(95<<8)
|
||||
},
|
||||
|
||||
{
|
||||
SHOTGUN_WEAPON__STATIC, 0, 13, 4, 31, 0,
|
||||
WEAPON_CHECKATRELOAD,
|
||||
SHOTGUN__STATIC, 24, SHOTGUNSHELL__STATIC, 7, 0, SHOTGUN_FIRE__STATIC, 15, SHOTGUN_COCK__STATIC,
|
||||
255+(95<<8)
|
||||
},
|
||||
|
||||
{
|
||||
CHAINGUN_WEAPON__STATIC, 0, 30, 1, 12, 10,
|
||||
WEAPON_AUTOMATIC | WEAPON_FIREEVERYTHIRD | WEAPON_AMMOPERSHOT,
|
||||
CHAINGUN__STATIC, 0, SHELL__STATIC, 0, 0, CHAINGUN_FIRE__STATIC, 0, 0,
|
||||
255+(95<<8)
|
||||
},
|
||||
|
||||
{
|
||||
RPG_WEAPON__STATIC, 0, 30, 4, 20, 0,
|
||||
0,
|
||||
RPG__STATIC, 0, 0, 0, 0, 0, 0, 0,
|
||||
255+(95<<8)
|
||||
},
|
||||
|
||||
{
|
||||
HANDBOMB_WEAPON__STATIC, 0, 30, 6, 19, 12,
|
||||
WEAPON_THROWIT,
|
||||
HEAVYHBOMB__STATIC, 0, 0, 0, 0, 0, 0,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
SHRINKER_WEAPON__STATIC, 0, 0, 10, 30, 0,
|
||||
WEAPON_GLOWS,
|
||||
SHRINKER__STATIC, 0, 0, 0, SHRINKER_FIRE__STATIC, 0, 0, 0,
|
||||
176+(252<<8)+(120<<16)
|
||||
},
|
||||
|
||||
{
|
||||
DEVISTATOR_WEAPON__STATIC, 0, 30, 2, 5, 5,
|
||||
WEAPON_FIREEVERYOTHER,
|
||||
RPG__STATIC, 0, 0, 2, CAT_FIRE__STATIC, 0, 0, 0,
|
||||
255+(95<<8)
|
||||
},
|
||||
|
||||
{
|
||||
TRIPBOMB_WEAPON__STATIC, 0, 30, 3, 16, 0,
|
||||
WEAPON_STANDSTILL,
|
||||
HANDHOLDINGLASER__STATIC, 0, 0, 0, 0, 0, 0,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
FREEZE_WEAPON__STATIC, 0, 0, 3, 5, 0,
|
||||
WEAPON_FIREEVERYOTHER,
|
||||
FREEZEBLAST__STATIC, 0, 0, 0, CAT_FIRE__STATIC, CAT_FIRE__STATIC, 0, 0,
|
||||
72+(88<<8)+(140<<16)
|
||||
},
|
||||
|
||||
{
|
||||
HANDREMOTE_WEAPON__STATIC, 0, 30, 2, 10, 0,
|
||||
WEAPON_BOMB_TRIGGER | WEAPON_NOVISIBLE,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
GROW_WEAPON__STATIC, 0, 0, 3, 30, 0,
|
||||
WEAPON_GLOWS,
|
||||
GROWSPARK__STATIC, 0, 0, 0, EXPANDERSHOOT__STATIC, EXPANDERSHOOT__STATIC, 0, 0,
|
||||
216+(52<<8)+(20<<16)
|
||||
},
|
||||
};
|
||||
|
||||
// KEEPINSYNC with what is contained above
|
||||
// XXX: ugly
|
||||
static int32_t G_StaticToDynamicTile(int32_t const tile)
|
||||
{
|
||||
switch (tile)
|
||||
{
|
||||
#ifndef EDUKE32_STANDALONE
|
||||
case CHAINGUN__STATIC: return CHAINGUN;
|
||||
case FREEZEBLAST__STATIC: return FREEZEBLAST;
|
||||
case GROWSPARK__STATIC: return GROWSPARK;
|
||||
case HANDHOLDINGLASER__STATIC: return HANDHOLDINGLASER;
|
||||
case HEAVYHBOMB__STATIC: return HEAVYHBOMB;
|
||||
case KNEE__STATIC: return KNEE;
|
||||
case RPG__STATIC: return RPG;
|
||||
case SHELL__STATIC: return SHELL;
|
||||
case SHOTGUNSHELL__STATIC: return SHOTGUNSHELL;
|
||||
case SHOTGUN__STATIC: return SHOTGUN;
|
||||
case SHOTSPARK1__STATIC: return SHOTSPARK1;
|
||||
case SHRINKER__STATIC: return SHRINKER;
|
||||
#endif
|
||||
default: return tile;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t G_StaticToDynamicSound(int32_t const sound)
|
||||
{
|
||||
switch (sound)
|
||||
{
|
||||
#ifndef EDUKE32_STANDALONE
|
||||
case CAT_FIRE__STATIC: return CAT_FIRE;
|
||||
case CHAINGUN_FIRE__STATIC: return CHAINGUN_FIRE;
|
||||
case EJECT_CLIP__STATIC: return EJECT_CLIP;
|
||||
case EXPANDERSHOOT__STATIC: return EXPANDERSHOOT;
|
||||
case INSERT_CLIP__STATIC: return INSERT_CLIP;
|
||||
case PISTOL_FIRE__STATIC: return PISTOL_FIRE;
|
||||
case SELECT_WEAPON__STATIC: return SELECT_WEAPON;
|
||||
case SHOTGUN_FIRE__STATIC: return SHOTGUN_FIRE;
|
||||
case SHOTGUN_COCK__STATIC: return SHOTGUN_COCK;
|
||||
case SHRINKER_FIRE__STATIC: return SHRINKER_FIRE;
|
||||
#endif
|
||||
default: return sound;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize WEAPONx_* gamevars. Since for Lunatic, they reside on the C side,
|
||||
// they're set directly. In C-CON, a new CON variable is defined together with
|
||||
// its initial value.
|
||||
#ifdef LUNATIC
|
||||
# define ADDWEAPONVAR(Weapidx, Membname) do { \
|
||||
int32_t j; \
|
||||
for (j=0; j<MAXPLAYERS; j++) \
|
||||
g_playerWeapon[j][Weapidx].Membname = weapondefaults[Weapidx].Membname; \
|
||||
} while (0)
|
||||
#else
|
||||
# define ADDWEAPONVAR(Weapidx, Membname) do { \
|
||||
Bsprintf(aszBuf, "WEAPON%d_" #Membname, Weapidx); \
|
||||
Bstrupr(aszBuf); \
|
||||
Gv_NewVar(aszBuf, weapondefaults[Weapidx].Membname, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
// After CON translation, get not-overridden members from weapondefaults[] back
|
||||
// into the live arrays! (That is, g_playerWeapon[][] for Lunatic, WEAPONx_*
|
||||
// gamevars on the CON side in C-CON.)
|
||||
#ifdef LUNATIC
|
||||
# define POSTADDWEAPONVAR(Weapidx, Membname) ADDWEAPONVAR(Weapidx, Membname)
|
||||
#else
|
||||
// NYI
|
||||
# define POSTADDWEAPONVAR(Weapidx, Membname) do {} while (0)
|
||||
#endif
|
||||
|
||||
// Finish a default weapon member after CON translation. If it was not
|
||||
// overridden from CON itself (see example at g_weaponOverridden[]), we set
|
||||
// both the weapondefaults[] entry (probably dead by now) and the live value.
|
||||
#define FINISH_WEAPON_DEFAULT_X(What, i, Membname) do { \
|
||||
if (!g_weaponOverridden[i].Membname) \
|
||||
{ \
|
||||
weapondefaults[i].Membname = G_StaticToDynamic##What(weapondefaults[i].Membname); \
|
||||
POSTADDWEAPONVAR(i, Membname); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FINISH_WEAPON_DEFAULT_TILE(i, Membname) FINISH_WEAPON_DEFAULT_X(Tile, i, Membname)
|
||||
#define FINISH_WEAPON_DEFAULT_SOUND(i, Membname) FINISH_WEAPON_DEFAULT_X(Sound, i, Membname)
|
||||
|
||||
// Process the dynamic {tile,sound} mappings after CON has been translated.
|
||||
// We cannot do this before, because the dynamic maps are not yet set up then.
|
||||
void Gv_FinalizeWeaponDefaults(void)
|
||||
{
|
||||
for (int i=0; i<MAX_WEAPONS; i++)
|
||||
{
|
||||
FINISH_WEAPON_DEFAULT_TILE(i, Shoots);
|
||||
FINISH_WEAPON_DEFAULT_TILE(i, Spawn);
|
||||
|
||||
FINISH_WEAPON_DEFAULT_SOUND(i, InitialSound);
|
||||
FINISH_WEAPON_DEFAULT_SOUND(i, FireSound);
|
||||
FINISH_WEAPON_DEFAULT_SOUND(i, Sound2Sound);
|
||||
}
|
||||
}
|
||||
#undef FINISH_WEAPON_DEFAULT_SOUND
|
||||
#undef FINISH_WEAPON_DEFAULT_TILE
|
||||
#undef FINISH_WEAPON_DEFAULT_X
|
||||
#undef POSTADDWEAPONVAR
|
||||
|
||||
#if !defined LUNATIC
|
||||
static int32_t lastvisinc;
|
||||
#endif
|
||||
|
||||
static void Gv_AddSystemVars(void)
|
||||
{
|
||||
// only call ONCE
|
||||
|
||||
char aszBuf[64];
|
||||
|
||||
for (int i=0; i<MAX_WEAPONS; i++)
|
||||
{
|
||||
ADDWEAPONVAR(i, Clip);
|
||||
ADDWEAPONVAR(i, FireDelay);
|
||||
ADDWEAPONVAR(i, FireSound);
|
||||
ADDWEAPONVAR(i, Flags);
|
||||
ADDWEAPONVAR(i, FlashColor);
|
||||
ADDWEAPONVAR(i, HoldDelay);
|
||||
ADDWEAPONVAR(i, InitialSound);
|
||||
ADDWEAPONVAR(i, Reload);
|
||||
ADDWEAPONVAR(i, Shoots);
|
||||
ADDWEAPONVAR(i, ShotsPerBurst);
|
||||
ADDWEAPONVAR(i, Sound2Sound);
|
||||
ADDWEAPONVAR(i, Sound2Time);
|
||||
ADDWEAPONVAR(i, Spawn);
|
||||
ADDWEAPONVAR(i, SpawnTime);
|
||||
ADDWEAPONVAR(i, TotalTime);
|
||||
ADDWEAPONVAR(i, WorksLike);
|
||||
}
|
||||
|
||||
Gv_NewVar("GRENADE_LIFETIME", NAM_GRENADE_LIFETIME, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
|
||||
Gv_NewVar("GRENADE_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
|
||||
Gv_NewVar("STICKYBOMB_LIFETIME", NAM_GRENADE_LIFETIME, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
|
||||
Gv_NewVar("STICKYBOMB_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
|
||||
Gv_NewVar("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
|
||||
|
||||
Gv_NewVar("ANGRANGE", 18, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
|
||||
Gv_NewVar("AUTOAIMANGLE", 0, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
|
||||
Gv_NewVar("COOP", (intptr_t)&ud.coop, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||
Gv_NewVar("FFIRE", (intptr_t)&ud.ffire, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||
Gv_NewVar("LEVEL", (intptr_t)&ud.level_number, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR | GAMEVAR_READONLY);
|
||||
Gv_NewVar("MARKER", (intptr_t)&ud.marker, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||
Gv_NewVar("MONSTERS_OFF", (intptr_t)&ud.monsters_off, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||
Gv_NewVar("MULTIMODE", (intptr_t)&ud.multimode, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||
Gv_NewVar("RESPAWN_INVENTORY", (intptr_t)&ud.respawn_inventory, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||
Gv_NewVar("RESPAWN_ITEMS", (intptr_t)&ud.respawn_items, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||
Gv_NewVar("RESPAWN_MONSTERS", (intptr_t)&ud.respawn_monsters, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||
Gv_NewVar("RETURN", 0, GAMEVAR_SYSTEM);
|
||||
Gv_NewVar("VOLUME", (intptr_t)&ud.volume_number, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR | GAMEVAR_READONLY);
|
||||
Gv_NewVar("WEAPON", 0, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER | GAMEVAR_READONLY);
|
||||
Gv_NewVar("WORKSLIKE", 0, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER | GAMEVAR_READONLY);
|
||||
Gv_NewVar("ZRANGE", 4, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
|
||||
}
|
||||
|
||||
#undef ADDWEAPONVAR
|
||||
|
||||
void Gv_Init(void)
|
||||
{
|
||||
#if !defined LUNATIC
|
||||
// already initialized
|
||||
if (aGameVars[0].flags)
|
||||
return;
|
||||
#else
|
||||
static int32_t inited=0;
|
||||
if (inited)
|
||||
return;
|
||||
inited = 1;
|
||||
#endif
|
||||
|
||||
// Set up weapon defaults, g_playerWeapon[][].
|
||||
Gv_AddSystemVars();
|
||||
#if !defined LUNATIC
|
||||
Gv_InitWeaponPointers();
|
||||
#endif
|
||||
Gv_ResetSystemDefaults();
|
||||
}
|
||||
|
||||
#if !defined LUNATIC
|
||||
void Gv_InitWeaponPointers(void)
|
||||
{
|
||||
char aszBuf[64];
|
||||
// called from game Init AND when level is loaded...
|
||||
|
||||
//AddLog("Gv_InitWeaponPointers");
|
||||
|
||||
for (int i=(MAX_WEAPONS-1); i>=0; i--)
|
||||
{
|
||||
Bsprintf(aszBuf, "WEAPON%d_CLIP", i);
|
||||
aplWeaponClip[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
|
||||
if (!aplWeaponClip[i])
|
||||
{
|
||||
initprintf("ERROR: NULL weapon! WTF?! %s\n", aszBuf);
|
||||
// Bexit(EXIT_SUCCESS);
|
||||
G_Shutdown();
|
||||
}
|
||||
|
||||
Bsprintf(aszBuf, "WEAPON%d_RELOAD", i);
|
||||
aplWeaponReload[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_FIREDELAY", i);
|
||||
aplWeaponFireDelay[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_TOTALTIME", i);
|
||||
aplWeaponTotalTime[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_HOLDDELAY", i);
|
||||
aplWeaponHoldDelay[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_FLAGS", i);
|
||||
aplWeaponFlags[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_SHOOTS", i);
|
||||
aplWeaponShoots[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_SPAWNTIME", i);
|
||||
aplWeaponSpawnTime[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_SPAWN", i);
|
||||
aplWeaponSpawn[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_SHOTSPERBURST", i);
|
||||
aplWeaponShotsPerBurst[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_WORKSLIKE", i);
|
||||
aplWeaponWorksLike[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_INITIALSOUND", i);
|
||||
aplWeaponInitialSound[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_FIRESOUND", i);
|
||||
aplWeaponFireSound[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_SOUND2TIME", i);
|
||||
aplWeaponSound2Time[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_SOUND2SOUND", i);
|
||||
aplWeaponSound2Sound[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
Bsprintf(aszBuf, "WEAPON%d_FLASHCOLOR", i);
|
||||
aplWeaponFlashColor[i] = Gv_GetVarDataPtr(aszBuf);
|
||||
}
|
||||
}
|
||||
|
||||
void Gv_RefreshPointers(void)
|
||||
{
|
||||
aGameVars[Gv_GetVarIndex("COOP")].global = (intptr_t)&ud.coop;
|
||||
aGameVars[Gv_GetVarIndex("FFIRE")].global = (intptr_t)&ud.ffire;
|
||||
aGameVars[Gv_GetVarIndex("LEVEL")].global = (intptr_t)&ud.level_number;
|
||||
aGameVars[Gv_GetVarIndex("MARKER")].global = (intptr_t)&ud.marker;
|
||||
aGameVars[Gv_GetVarIndex("MONSTERS_OFF")].global = (intptr_t)&ud.monsters_off;
|
||||
aGameVars[Gv_GetVarIndex("MULTIMODE")].global = (intptr_t)&ud.multimode;
|
||||
aGameVars[Gv_GetVarIndex("RESPAWN_INVENTORY")].global = (intptr_t)&ud.respawn_inventory;
|
||||
aGameVars[Gv_GetVarIndex("RESPAWN_ITEMS")].global = (intptr_t)&ud.respawn_items;
|
||||
aGameVars[Gv_GetVarIndex("RESPAWN_MONSTERS")].global = (intptr_t)&ud.respawn_monsters;
|
||||
aGameVars[Gv_GetVarIndex("VOLUME")].global = (intptr_t)&ud.volume_number;
|
||||
}
|
||||
#endif
|
|
@ -211,8 +211,14 @@ static int A_FindTargetSprite(const spritetype *pSprite, int projAng, int projec
|
|||
|
||||
int const spriteAng = pSprite->ang;
|
||||
|
||||
int const isShrinker = (!RR && pSprite->picnum == APLAYER && g_player[playerNum].ps->curr_weapon == SHRINKER_WEAPON);
|
||||
int const isFreezer = (!RR && pSprite->picnum == APLAYER && g_player[playerNum].ps->curr_weapon == FREEZE_WEAPON);
|
||||
int isShrinker = (!RR && pSprite->picnum == APLAYER && g_player[playerNum].ps->curr_weapon == SHRINKER_WEAPON);
|
||||
int isFreezer = (!RR && pSprite->picnum == APLAYER && g_player[playerNum].ps->curr_weapon == FREEZE_WEAPON);
|
||||
|
||||
if (WW2GI)
|
||||
{
|
||||
isShrinker = (pSprite->picnum == APLAYER && PWEAPON(playerNum, g_player[playerNum].ps->curr_weapon, WorksLike) == SHRINKER_WEAPON);
|
||||
isFreezer = (pSprite->picnum == APLAYER && PWEAPON(playerNum, g_player[playerNum].ps->curr_weapon, WorksLike) == FREEZE_WEAPON);
|
||||
}
|
||||
|
||||
vec2_t const d1 = { sintable[(spriteAng + 512 - projAng) & 2047], sintable[(spriteAng - projAng) & 2047] };
|
||||
vec2_t const d2 = { sintable[(spriteAng + 512 + projAng) & 2047], sintable[(spriteAng + projAng) & 2047] };
|
||||
|
@ -1212,7 +1218,7 @@ growspark_rr:
|
|||
pReturn->extra >>= 2;
|
||||
}
|
||||
}
|
||||
else if (g_player[playerNum].ps->curr_weapon == DEVISTATOR_WEAPON)
|
||||
else if ((WW2GI ? PWEAPON(playerNum, g_player[playerNum].ps->curr_weapon, WorksLike) : g_player[playerNum].ps->curr_weapon) == DEVISTATOR_WEAPON)
|
||||
{
|
||||
pReturn->extra >>= 2;
|
||||
pReturn->ang += 16 - (krand2() & 31);
|
||||
|
@ -1272,8 +1278,17 @@ growspark_rr:
|
|||
|
||||
if (placeMine == 1)
|
||||
{
|
||||
int const tripBombMode = Gv_GetVarByLabel("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, -1, -1);
|
||||
int const spawnedSprite = A_InsertSprite(hitData.sect, hitData.pos.x, hitData.pos.y, hitData.pos.z, TRIPBOMB, -16, 4, 5,
|
||||
shootAng, 0, 0, spriteNum, 6);
|
||||
if (tripBombMode & TRIPBOMB_TIMER)
|
||||
{
|
||||
int32_t lLifetime = Gv_GetVarByLabel("STICKYBOMB_LIFETIME", NAM_GRENADE_LIFETIME, -1, playerNum);
|
||||
int32_t lLifetimeVar
|
||||
= Gv_GetVarByLabel("STICKYBOMB_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, -1, playerNum);
|
||||
// set timer. blows up when at zero....
|
||||
sprite[spawnedSprite].extra = lLifetime + mulscale14(krand2(), lLifetimeVar) - lLifetimeVar;
|
||||
}
|
||||
sprite[spawnedSprite].hitag = spawnedSprite;
|
||||
A_PlaySound(LASERTRIP_ONWALL, spawnedSprite);
|
||||
sprite[spawnedSprite].xvel = -20;
|
||||
|
@ -1285,7 +1300,7 @@ growspark_rr:
|
|||
|
||||
actor[spawnedSprite].t_data[5] = sprite[spawnedSprite].ang = wallAng;
|
||||
|
||||
if (playerNum >= 0)
|
||||
if (!WW2GI && playerNum >= 0)
|
||||
pPlayer->ammo_amount[TRIPBOMB_WEAPON]--;
|
||||
|
||||
return spawnedSprite;
|
||||
|
@ -1585,6 +1600,8 @@ static int P_DisplayKnee(int kneeShade)
|
|||
|
||||
static int P_DisplayKnuckles(int knuckleShade)
|
||||
{
|
||||
if (WW2GI)
|
||||
return 0;
|
||||
const DukePlayer_t *const pPlayer = g_player[screenpeek].ps;
|
||||
|
||||
if (pPlayer->knuckle_incs == 0)
|
||||
|
@ -1606,6 +1623,99 @@ static int P_DisplayKnuckles(int knuckleShade)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Set C-CON's WEAPON and WORKSLIKE gamevars.
|
||||
void P_SetWeaponGamevars(int playerNum, const DukePlayer_t * const pPlayer)
|
||||
{
|
||||
if (!WW2GI)
|
||||
return;
|
||||
Gv_SetVar(g_weaponVarID, pPlayer->curr_weapon, pPlayer->i, playerNum);
|
||||
Gv_SetVar(g_worksLikeVarID,
|
||||
((unsigned)pPlayer->curr_weapon < MAX_WEAPONS) ? PWEAPON(playerNum, pPlayer->curr_weapon, WorksLike) : -1,
|
||||
pPlayer->i, playerNum);
|
||||
}
|
||||
|
||||
static void P_FireWeapon(int playerNum)
|
||||
{
|
||||
auto const pPlayer = g_player[playerNum].ps;
|
||||
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, WorksLike) != KNEE_WEAPON)
|
||||
pPlayer->ammo_amount[pPlayer->curr_weapon]--;
|
||||
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, FireSound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, FireSound), pPlayer->i);
|
||||
|
||||
P_SetWeaponGamevars(playerNum, pPlayer);
|
||||
// OSD_Printf("doing %d %d %d\n",PWEAPON(snum, p->curr_weapon, Shoots),p->curr_weapon,snum);
|
||||
A_Shoot(pPlayer->i, PWEAPON(playerNum, pPlayer->curr_weapon, Shoots));
|
||||
|
||||
for (bssize_t burstFire = PWEAPON(playerNum, pPlayer->curr_weapon, ShotsPerBurst) - 1; burstFire > 0; --burstFire)
|
||||
{
|
||||
A_Shoot(pPlayer->i, PWEAPON(playerNum, pPlayer->curr_weapon, Shoots));
|
||||
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_AMMOPERSHOT)
|
||||
{
|
||||
pPlayer->ammo_amount[pPlayer->curr_weapon]--;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_NOVISIBLE))
|
||||
{
|
||||
#ifdef POLYMER
|
||||
spritetype *s = &sprite[pPlayer->i];
|
||||
int32_t x = ((sintable[(s->ang + 512) & 2047]) >> 7), y = ((sintable[(s->ang) & 2047]) >> 7);
|
||||
|
||||
s->x += x;
|
||||
s->y += y;
|
||||
G_AddGameLight(0, pPlayer->i, PHEIGHT, 8192, PWEAPON(playerNum, pPlayer->curr_weapon, FlashColor),
|
||||
PR_LIGHT_PRIO_MAX_GAME);
|
||||
actor[pPlayer->i].lightcount = 2;
|
||||
s->x -= x;
|
||||
s->y -= y;
|
||||
#endif // POLYMER
|
||||
pPlayer->visibility = 0;
|
||||
}
|
||||
|
||||
if (/*!(PWEAPON(playerNum, p->curr_weapon, Flags) & WEAPON_CHECKATRELOAD) && */
|
||||
PWEAPON(playerNum, pPlayer->curr_weapon, Reload) > PWEAPON(playerNum, pPlayer->curr_weapon, TotalTime) && pPlayer->ammo_amount[pPlayer->curr_weapon] > 0
|
||||
&& (PWEAPON(playerNum, pPlayer->curr_weapon, Clip)) && (((pPlayer->ammo_amount[pPlayer->curr_weapon]%(PWEAPON(playerNum, pPlayer->curr_weapon, Clip)))==0)))
|
||||
{
|
||||
pPlayer->kickback_pic = PWEAPON(playerNum, pPlayer->curr_weapon, TotalTime);
|
||||
}
|
||||
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, WorksLike) != KNEE_WEAPON)
|
||||
P_CheckWeapon(pPlayer);
|
||||
}
|
||||
|
||||
static void P_DoWeaponSpawn(int playerNum)
|
||||
{
|
||||
auto const pPlayer = g_player[playerNum].ps;
|
||||
|
||||
// NOTE: For the 'Spawn' member, 0 means 'none', too (originally so,
|
||||
// i.e. legacy). The check for <0 was added to the check because mod
|
||||
// authors (rightly) assumed that -1 is the no-op value.
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Spawn) <= 0) // <=0 : AMC TC beta/RC2 has WEAPONx_SPAWN -1
|
||||
return;
|
||||
|
||||
int newSprite = A_Spawn(pPlayer->i, PWEAPON(playerNum, pPlayer->curr_weapon, Spawn));
|
||||
|
||||
if ((PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_SPAWNTYPE2))
|
||||
{
|
||||
// like shotgun shells
|
||||
sprite[newSprite].ang += 1024;
|
||||
A_SetSprite(newSprite,CLIPMASK0);
|
||||
sprite[newSprite].ang += 1024;
|
||||
}
|
||||
else if ((PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_SPAWNTYPE3))
|
||||
{
|
||||
// like chaingun shells
|
||||
sprite[newSprite].ang += 1024;
|
||||
sprite[newSprite].ang &= 2047;
|
||||
sprite[newSprite].xvel += 32;
|
||||
sprite[newSprite].z += (3<<8);
|
||||
A_SetSprite(newSprite,CLIPMASK0);
|
||||
}
|
||||
}
|
||||
|
||||
void P_DisplayScuba(void)
|
||||
{
|
||||
if (g_player[screenpeek].ps->scuba_on)
|
||||
|
@ -1762,6 +1872,9 @@ void P_DisplayWeapon(void)
|
|||
weaponX -= 58 + pPlayer->weapon_ang;
|
||||
weaponYOffset -= (pPlayer->hard_landing << 3);
|
||||
|
||||
if (WW2GI)
|
||||
currentWeapon = PWEAPON(screenpeek, (pPlayer->last_weapon >= 0) ? pPlayer->last_weapon : pPlayer->curr_weapon, WorksLike);
|
||||
else
|
||||
currentWeapon = (pPlayer->last_weapon >= 0) ? pPlayer->last_weapon : pPlayer->curr_weapon;
|
||||
hudweap.gunposy = weaponYOffset;
|
||||
hudweap.lookhoriz = weaponY;
|
||||
|
@ -2415,9 +2528,19 @@ void P_DisplayWeapon(void)
|
|||
|
||||
if (*weaponFrame > 0)
|
||||
{
|
||||
if (*weaponFrame < 8)
|
||||
int totalTime;
|
||||
if (*weaponFrame < (WW2GI ? (totalTime = PWEAPON(screenpeek, pPlayer->curr_weapon, TotalTime)) : 8))
|
||||
G_DrawWeaponTileWithID(currentWeapon << 1, weaponX + 164, (weaponY << 1) + 176 - weaponYOffset,
|
||||
RPGGUN + ((*weaponFrame) >> 1), weaponShade, weaponBits, weaponPal);
|
||||
else if (WW2GI)
|
||||
{
|
||||
totalTime = PWEAPON(screenpeek, pPlayer->curr_weapon, TotalTime);
|
||||
int const reloadTime = PWEAPON(screenpeek, pPlayer->curr_weapon, Reload);
|
||||
|
||||
weaponYOffset -= (*weaponFrame < ((reloadTime - totalTime) / 2 + totalTime))
|
||||
? 10 * ((*weaponFrame) - totalTime) // down
|
||||
: 10 * (reloadTime - (*weaponFrame)); // up
|
||||
}
|
||||
}
|
||||
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 164, (weaponY << 1) + 176 - weaponYOffset, RPGGUN, weaponShade,
|
||||
|
@ -2427,6 +2550,41 @@ void P_DisplayWeapon(void)
|
|||
case SHOTGUN_WEAPON__STATIC:
|
||||
weaponX -= 8;
|
||||
|
||||
if (WW2GI)
|
||||
{
|
||||
int const totalTime = PWEAPON(screenpeek, pPlayer->curr_weapon, TotalTime);
|
||||
int const reloadTime = PWEAPON(screenpeek, pPlayer->curr_weapon, Reload);
|
||||
|
||||
if (*weaponFrame > 0)
|
||||
weaponYOffset -= sintable[(*weaponFrame)<<7]>>12;
|
||||
|
||||
if (*weaponFrame > 0 && doAnim)
|
||||
weaponX += 1-(rand()&3);
|
||||
|
||||
if (*weaponFrame == 0)
|
||||
{
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 146 - halfLookAng, weaponY + 202 - weaponYOffset,
|
||||
SHOTGUN, weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
else if (*weaponFrame <= totalTime)
|
||||
{
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 146 - halfLookAng, weaponY + 202 - weaponYOffset,
|
||||
SHOTGUN + 1, weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
// else we are in 'reload time'
|
||||
else
|
||||
{
|
||||
weaponYOffset -= (*weaponFrame < ((reloadTime - totalTime) / 2 + totalTime))
|
||||
? 10 * ((*weaponFrame) - totalTime) // D
|
||||
: 10 * (reloadTime - (*weaponFrame)); // U
|
||||
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 146 - halfLookAng, weaponY + 202 - weaponYOffset,
|
||||
SHOTGUN, weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch (*weaponFrame)
|
||||
{
|
||||
case 1:
|
||||
|
@ -2505,6 +2663,83 @@ void P_DisplayWeapon(void)
|
|||
weaponX += 1-(rand()&3);
|
||||
}
|
||||
|
||||
if (WW2GI)
|
||||
{
|
||||
int const totalTime = PWEAPON(screenpeek, pPlayer->curr_weapon, TotalTime);
|
||||
int const reloadTime = PWEAPON(screenpeek, pPlayer->curr_weapon, Reload);
|
||||
|
||||
if (*weaponFrame == 0)
|
||||
{
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 178 - halfLookAng,weaponY+233-weaponYOffset,
|
||||
CHAINGUN+1,weaponShade,weaponBits,weaponPal);
|
||||
}
|
||||
else if (*weaponFrame <= totalTime)
|
||||
{
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 188 - halfLookAng,weaponY+243-weaponYOffset,
|
||||
CHAINGUN+2,weaponShade,weaponBits,weaponPal);
|
||||
}
|
||||
// else we are in 'reload time'
|
||||
// divide reload time into fifths..
|
||||
// 1) move weapon up/right, hand on clip (CHAINGUN - 17)
|
||||
// 2) move weapon up/right, hand removing clip (CHAINGUN - 18)
|
||||
// 3) hold weapon up/right, hand removed clip (CHAINGUN - 19)
|
||||
// 4) hold weapon up/right, hand inserting clip (CHAINGUN - 18)
|
||||
// 5) move weapon down/left, clip inserted (CHAINGUN - 17)
|
||||
else
|
||||
{
|
||||
int iFifths = (reloadTime - totalTime) / 5;
|
||||
if (iFifths < 1)
|
||||
iFifths = 1;
|
||||
|
||||
if (*weaponFrame < iFifths + totalTime)
|
||||
{
|
||||
// first segment
|
||||
int const weaponOffset = 80 - 10 * (totalTime + iFifths - (*weaponFrame));
|
||||
weaponYOffset += weaponOffset;
|
||||
weaponX += weaponOffset;
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 168 - halfLookAng, weaponY + 260 - weaponYOffset, CHAINGUN - 17,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
else if (*weaponFrame < (iFifths * 2 + totalTime))
|
||||
{
|
||||
// second segment
|
||||
weaponYOffset += 80; // D
|
||||
weaponX += 80;
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 168 - halfLookAng, weaponY + 260 - weaponYOffset, CHAINGUN - 18,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
else if (*weaponFrame < (iFifths * 3 + totalTime))
|
||||
{
|
||||
// third segment
|
||||
// up
|
||||
weaponYOffset += 80;
|
||||
weaponX += 80;
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 168 - halfLookAng, weaponY + 260 - weaponYOffset, CHAINGUN - 19,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
else if (*weaponFrame < (iFifths * 4 + totalTime))
|
||||
{
|
||||
// fourth segment
|
||||
// down
|
||||
weaponYOffset += 80; // D
|
||||
weaponX += 80;
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 168 - halfLookAng, weaponY + 260 - weaponYOffset, CHAINGUN - 18,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
else
|
||||
{
|
||||
// up and left
|
||||
int const weaponOffset = 10 * (reloadTime - (*weaponFrame));
|
||||
weaponYOffset += weaponOffset; // U
|
||||
weaponX += weaponOffset;
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 168 - halfLookAng, weaponY + 260 - weaponYOffset, CHAINGUN - 17,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch (*weaponFrame)
|
||||
{
|
||||
case 0:
|
||||
|
@ -2584,21 +2819,21 @@ void P_DisplayWeapon(void)
|
|||
weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
|
||||
else if ((*weaponFrame) < (NAM ? 38 : 23))
|
||||
else if ((*weaponFrame) < (WW2GI ? PWEAPON(screenpeek, PISTOL_WEAPON, Reload) - 12 : (NAM ? 38 : 23)))
|
||||
{
|
||||
G_DrawWeaponTileWithID(currentWeapon << 2, 184 - (pPlayer->look_ang >> 1), weaponY + 235 - weaponYOffset,
|
||||
FIRSTGUN + 8, weaponShade, weaponBits, weaponPal);
|
||||
G_DrawWeaponTileWithID(currentWeapon, 224 - (pPlayer->look_ang >> 1), weaponY + 210 - weaponYOffset, FIRSTGUN + 5,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
else if ((*weaponFrame) < (NAM ? 44 : 25))
|
||||
else if ((*weaponFrame) < (WW2GI ? PWEAPON(screenpeek, PISTOL_WEAPON, Reload) - 6 : (NAM ? 44 : 25)))
|
||||
{
|
||||
G_DrawWeaponTileWithID(currentWeapon << 2, 164 - (pPlayer->look_ang >> 1), weaponY + 245 - weaponYOffset,
|
||||
FIRSTGUN + 8, weaponShade, weaponBits, weaponPal);
|
||||
G_DrawWeaponTileWithID(currentWeapon, 224 - (pPlayer->look_ang >> 1), weaponY + 220 - weaponYOffset, FIRSTGUN + 5,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
else if ((*weaponFrame) < (NAM ? 50 : 27))
|
||||
else if ((*weaponFrame) < (WW2GI ? PWEAPON(screenpeek, PISTOL_WEAPON, Reload) : (NAM ? 50 : 27)))
|
||||
G_DrawWeaponTileWithID(currentWeapon, 194 - (pPlayer->look_ang >> 1), weaponY + 235 - weaponYOffset, FIRSTGUN + 5,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
|
||||
|
@ -2611,7 +2846,38 @@ void P_DisplayWeapon(void)
|
|||
if (*weaponFrame >= ARRAY_SIZE(pipebombFrames))
|
||||
break;
|
||||
|
||||
if (WW2GI && *weaponFrame >= PWEAPON(screenpeek, pPlayer->curr_weapon, TotalTime))
|
||||
break;
|
||||
|
||||
if (*weaponFrame)
|
||||
{
|
||||
if (WW2GI)
|
||||
{
|
||||
int const fireDelay = PWEAPON(screenpeek, pPlayer->curr_weapon, FireDelay);
|
||||
int const totalTime = PWEAPON(screenpeek, pPlayer->curr_weapon, TotalTime);
|
||||
|
||||
if (*weaponFrame <= fireDelay)
|
||||
{
|
||||
// it holds here
|
||||
weaponYOffset -= 5 * (*weaponFrame); // D
|
||||
}
|
||||
else if (*weaponFrame < ((totalTime - fireDelay) / 2 + fireDelay))
|
||||
{
|
||||
// up and left
|
||||
int const weaponOffset = (*weaponFrame) - fireDelay;
|
||||
weaponYOffset += 10 * weaponOffset; // U
|
||||
weaponX += 80 * weaponOffset;
|
||||
}
|
||||
else if (*weaponFrame < totalTime)
|
||||
{
|
||||
// start high
|
||||
weaponYOffset += 240;
|
||||
weaponYOffset -= 12 * ((*weaponFrame) - fireDelay); // D
|
||||
// move left
|
||||
weaponX += 90 - 5 * (totalTime - (*weaponFrame));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*weaponFrame < 7) weaponYOffset -= 10 * (*weaponFrame); // D
|
||||
else if (*weaponFrame < 12) weaponYOffset += 20 * ((*weaponFrame) - 10); // U
|
||||
|
@ -2619,6 +2885,7 @@ void P_DisplayWeapon(void)
|
|||
|
||||
weaponYOffset += 10;
|
||||
}
|
||||
}
|
||||
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 190 - halfLookAng, weaponY + 260 - weaponYOffset,
|
||||
HANDTHROW + pipebombFrames[(*weaponFrame)], weaponShade, weaponBits, weaponPal);
|
||||
|
@ -2639,6 +2906,55 @@ void P_DisplayWeapon(void)
|
|||
break;
|
||||
|
||||
case DEVISTATOR_WEAPON__STATIC:
|
||||
if (WW2GI)
|
||||
{
|
||||
if (*weaponFrame)
|
||||
{
|
||||
int32_t const totalTime = PWEAPON(screenpeek, pPlayer->curr_weapon, TotalTime);
|
||||
int32_t const reloadTime = PWEAPON(screenpeek, pPlayer->curr_weapon, Reload);
|
||||
|
||||
if (*weaponFrame < totalTime)
|
||||
{
|
||||
int const tileOffset = ksgn((*weaponFrame) >> 2);
|
||||
|
||||
if (pPlayer->ammo_amount[pPlayer->curr_weapon] & 1)
|
||||
{
|
||||
G_DrawWeaponTileWithID(currentWeapon << 1, weaponX + 30 - halfLookAng, weaponY + 240 - weaponYOffset,
|
||||
DEVISTATOR, weaponShade, weaponBits | 4, weaponPal);
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 268 - halfLookAng, weaponY + 238 - weaponYOffset,
|
||||
DEVISTATOR + tileOffset, -32, weaponBits, weaponPal);
|
||||
}
|
||||
else
|
||||
{
|
||||
G_DrawWeaponTileWithID(currentWeapon << 1, weaponX + 30 - halfLookAng, weaponY + 240 - weaponYOffset,
|
||||
DEVISTATOR + tileOffset, -32, weaponBits | 4, weaponPal);
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 268 - halfLookAng, weaponY + 238 - weaponYOffset, DEVISTATOR,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
}
|
||||
}
|
||||
// else we are in 'reload time'
|
||||
else
|
||||
{
|
||||
weaponYOffset -= (*weaponFrame < ((reloadTime - totalTime) / 2 + totalTime))
|
||||
? 10 * ((*weaponFrame) - totalTime)
|
||||
: 10 * (reloadTime - (*weaponFrame));
|
||||
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 268 - halfLookAng, weaponY + 238 - weaponYOffset, DEVISTATOR,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
G_DrawWeaponTileWithID(currentWeapon << 1, weaponX + 30 - halfLookAng, weaponY + 240 - weaponYOffset, DEVISTATOR,
|
||||
weaponShade, weaponBits | 4, weaponPal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 268 - halfLookAng, weaponY + 238 - weaponYOffset, DEVISTATOR,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
G_DrawWeaponTileWithID(currentWeapon << 1, weaponX + 30 - halfLookAng, weaponY + 240 - weaponYOffset, DEVISTATOR,
|
||||
weaponShade, weaponBits | 4, weaponPal);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (*weaponFrame > 0)
|
||||
{
|
||||
static uint8_t const devastatorFrames[] = { 0, 4, 12, 24, 12, 4, 0 };
|
||||
|
@ -2706,6 +3022,65 @@ void P_DisplayWeapon(void)
|
|||
weaponX += 28;
|
||||
weaponY += 18;
|
||||
|
||||
if (WW2GI)
|
||||
{
|
||||
if (*weaponFrame == 0)
|
||||
{
|
||||
// the 'at rest' display
|
||||
if (currentWeapon == GROW_WEAPON)
|
||||
{
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 188 - halfLookAng, weaponY + 240 - weaponYOffset, SHRINKER - 2,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
break;
|
||||
}
|
||||
else if (pPlayer->ammo_amount[currentWeapon] > 0)
|
||||
{
|
||||
G_DrawWeaponTileUnfadedWithID(currentWeapon << 1, weaponX + 184 - halfLookAng, weaponY + 240 - weaponYOffset, SHRINKER + 2,
|
||||
16 - (sintable[pPlayer->random_club_frame & 2047] >> 10), weaponBits, 0);
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 188 - halfLookAng, weaponY + 240 - weaponYOffset, SHRINKER,
|
||||
weaponShade, weaponBits, weaponPal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// the 'active' display.
|
||||
if (doAnim)
|
||||
{
|
||||
weaponX += rand() & 3;
|
||||
weaponYOffset += rand() & 3;
|
||||
}
|
||||
|
||||
int const totalTime = PWEAPON(screenpeek, pPlayer->curr_weapon, TotalTime);
|
||||
int const reloadTime = PWEAPON(screenpeek, pPlayer->curr_weapon, Reload);
|
||||
|
||||
if (*weaponFrame < totalTime)
|
||||
{
|
||||
if (*weaponFrame >= PWEAPON(screenpeek, pPlayer->curr_weapon, FireDelay))
|
||||
{
|
||||
// after fire time.
|
||||
// lower weapon to reload cartridge (not clip)
|
||||
weaponYOffset -= (currentWeapon == GROW_WEAPON ? 15 : 10) * (totalTime - (*weaponFrame));
|
||||
}
|
||||
}
|
||||
// else we are in 'reload time'
|
||||
else
|
||||
{
|
||||
weaponYOffset -= (*weaponFrame < ((reloadTime - totalTime) / 2 + totalTime))
|
||||
? (currentWeapon == GROW_WEAPON ? 5 : 10) * ((*weaponFrame) - totalTime) // D
|
||||
: 10 * (reloadTime - (*weaponFrame)); // U
|
||||
}
|
||||
}
|
||||
|
||||
G_DrawWeaponTileUnfadedWithID(currentWeapon << 1, weaponX + 184 - halfLookAng, weaponY + 240 - weaponYOffset,
|
||||
SHRINKER + 3 + ((*weaponFrame) & 3), -32, weaponBits, currentWeapon == GROW_WEAPON ? 2 : 0);
|
||||
|
||||
G_DrawWeaponTileWithID(currentWeapon, weaponX + 188 - halfLookAng, weaponY + 240 - weaponYOffset,
|
||||
SHRINKER + (currentWeapon == GROW_WEAPON ? -1 : 1), weaponShade, weaponBits, weaponPal);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ((*weaponFrame) > 0)
|
||||
{
|
||||
if (doAnim)
|
||||
|
@ -3924,7 +4299,9 @@ static int32_t P_DoCounters(int playerNum)
|
|||
}
|
||||
A_PlaySound(soundId, pPlayer->i);
|
||||
}
|
||||
else if (totalclock > 1024)
|
||||
else if (!WW2GI)
|
||||
{
|
||||
if (totalclock > 1024)
|
||||
if (playerNum == screenpeek || GTFLAGS(GAMETYPE_COOPSOUND))
|
||||
{
|
||||
if (rand()&1)
|
||||
|
@ -3932,9 +4309,9 @@ static int32_t P_DoCounters(int playerNum)
|
|||
else A_PlaySound(DUKE_CRACK2,pPlayer->i);
|
||||
}
|
||||
|
||||
if (!RR)
|
||||
A_PlaySound(DUKE_CRACK_FIRST, pPlayer->i);
|
||||
}
|
||||
}
|
||||
else if (pPlayer->knuckle_incs == 22 || TEST_SYNC_KEY(g_player[playerNum].inputBits->bits, SK_FIRE))
|
||||
pPlayer->knuckle_incs=0;
|
||||
|
||||
|
@ -3952,7 +4329,7 @@ int16_t WeaponPickupSprites[MAX_WEAPONS] = { KNEE__STATIC, FIRSTGUNSPRITE__STATI
|
|||
void P_DropWeapon(int const playerNum)
|
||||
{
|
||||
DukePlayer_t *const pPlayer = g_player[playerNum].ps;
|
||||
int const currentWeapon = pPlayer->curr_weapon;
|
||||
int const currentWeapon = WW2GI ? PWEAPON(playerNum, pPlayer->curr_weapon, WorksLike) : pPlayer->curr_weapon;
|
||||
|
||||
if (RRRA && (g_netServer || numplayers > 1))
|
||||
{
|
||||
|
@ -3990,7 +4367,7 @@ void P_DropWeapon(int const playerNum)
|
|||
}
|
||||
}
|
||||
|
||||
if ((unsigned)currentWeapon >= MAX_WEAPONS)
|
||||
if (currentWeapon == KNEE_WEAPON || (unsigned)currentWeapon >= MAX_WEAPONS)
|
||||
return;
|
||||
|
||||
if (krand2() & 1)
|
||||
|
@ -4137,15 +4514,6 @@ void P_SelectNextInvItem(DukePlayer_t *pPlayer)
|
|||
pPlayer->inven_icon = ICON_NONE;
|
||||
}
|
||||
|
||||
// Set C-CON's WEAPON and WORKSLIKE gamevars.
|
||||
void P_SetWeaponGamevars(int playerNum, const DukePlayer_t * const pPlayer)
|
||||
{
|
||||
Gv_SetVar(g_weaponVarID, pPlayer->curr_weapon, pPlayer->i, playerNum);
|
||||
Gv_SetVar(g_worksLikeVarID,
|
||||
((unsigned)pPlayer->curr_weapon < MAX_WEAPONS) ? PWEAPON(playerNum, pPlayer->curr_weapon, WorksLike) : -1,
|
||||
pPlayer->i, playerNum);
|
||||
}
|
||||
|
||||
void P_CheckWeapon(DukePlayer_t *pPlayer)
|
||||
{
|
||||
int playerNum;
|
||||
|
@ -4571,9 +4939,10 @@ static void P_ProcessWeapon(int playerNum)
|
|||
}
|
||||
}
|
||||
#undef WEAPON2_CLIP
|
||||
if (pPlayer->curr_weapon == SHRINKER_WEAPON || pPlayer->curr_weapon == GROW_WEAPON
|
||||
if (WW2GI ? PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_GLOWS :
|
||||
(pPlayer->curr_weapon == SHRINKER_WEAPON || pPlayer->curr_weapon == GROW_WEAPON
|
||||
|| (RR && (pPlayer->curr_weapon == TRIPBOMB_WEAPON || pPlayer->curr_weapon == BOWLINGBALL_WEAPON))
|
||||
|| (RRRA && (pPlayer->curr_weapon == KNEE_WEAPON || pPlayer->curr_weapon == SLINGBLADE_WEAPON)))
|
||||
|| (RRRA && (pPlayer->curr_weapon == KNEE_WEAPON || pPlayer->curr_weapon == SLINGBLADE_WEAPON))))
|
||||
{
|
||||
pPlayer->random_club_frame += 64; // Glowing
|
||||
|
||||
|
@ -4627,19 +4996,23 @@ static void P_ProcessWeapon(int playerNum)
|
|||
P_SetWeaponGamevars(playerNum, pPlayer);
|
||||
if (VM_OnEvent(EVENT_FIRE, pPlayer->i, playerNum) == 0)
|
||||
{
|
||||
switch (DYNAMICWEAPONMAP(pPlayer->curr_weapon))
|
||||
switch (DYNAMICWEAPONMAP(WW2GI ? PWEAPON(playerNum, pPlayer->curr_weapon, WorksLike) : pPlayer->curr_weapon))
|
||||
{
|
||||
case HANDBOMB_WEAPON__STATIC:
|
||||
pPlayer->hbomb_hold_delay = 0;
|
||||
if (pPlayer->ammo_amount[pPlayer->curr_weapon] > 0)
|
||||
{
|
||||
(*weaponFrame) = 1;
|
||||
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
|
||||
}
|
||||
break;
|
||||
|
||||
case HANDREMOTE_WEAPON__STATIC:
|
||||
pPlayer->hbomb_hold_delay = 0;
|
||||
(*weaponFrame) = 1;
|
||||
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
|
||||
break;
|
||||
|
||||
case PISTOL_WEAPON__STATIC:
|
||||
|
@ -4647,6 +5020,8 @@ static void P_ProcessWeapon(int playerNum)
|
|||
{
|
||||
pPlayer->ammo_amount[PISTOL_WEAPON]--;
|
||||
(*weaponFrame) = 1;
|
||||
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4654,6 +5029,8 @@ static void P_ProcessWeapon(int playerNum)
|
|||
if (pPlayer->ammo_amount[SHOTGUN_WEAPON] > 0 && pPlayer->random_club_frame == 0)
|
||||
{
|
||||
(*weaponFrame) = 1;
|
||||
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4706,6 +5083,10 @@ static void P_ProcessWeapon(int playerNum)
|
|||
pPlayer->pos.z = pPlayer->opos.z;
|
||||
pPlayer->vel.z = 0;
|
||||
(*weaponFrame) = 1;
|
||||
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
|
||||
{
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -4714,7 +5095,10 @@ static void P_ProcessWeapon(int playerNum)
|
|||
if (pPlayer->ammo_amount[SHRINKER_WEAPON] > 0)
|
||||
{
|
||||
(*weaponFrame) = 1;
|
||||
if (!WW2GI)
|
||||
A_PlaySound(SHRINKER_FIRE, pPlayer->i);
|
||||
else if (PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4722,16 +5106,24 @@ static void P_ProcessWeapon(int playerNum)
|
|||
if (pPlayer->ammo_amount[GROW_WEAPON] > 0)
|
||||
{
|
||||
(*weaponFrame) = 1;
|
||||
if (!WW2GI)
|
||||
A_PlaySound(RR ? 431 : EXPANDERSHOOT, pPlayer->i);
|
||||
else if (PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
|
||||
}
|
||||
break;
|
||||
|
||||
case FREEZE_WEAPON__STATIC:
|
||||
if (pPlayer->ammo_amount[FREEZE_WEAPON] > 0)
|
||||
if (pPlayer->ammo_amount[pPlayer->curr_weapon] > 0)
|
||||
{
|
||||
(*weaponFrame) = 1;
|
||||
if (!RR)
|
||||
{
|
||||
if (!WW2GI)
|
||||
A_PlaySound(CAT_FIRE, pPlayer->i);
|
||||
else if (PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4740,6 +5132,8 @@ static void P_ProcessWeapon(int playerNum)
|
|||
if (pPlayer->ammo_amount[pPlayer->curr_weapon] > 0)
|
||||
{
|
||||
(*weaponFrame) = 1;
|
||||
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4749,7 +5143,12 @@ static void P_ProcessWeapon(int playerNum)
|
|||
(*weaponFrame) = 1;
|
||||
pPlayer->hbomb_hold_delay = !pPlayer->hbomb_hold_delay;
|
||||
if (!RR)
|
||||
{
|
||||
if (!WW2GI)
|
||||
A_PlaySound(CAT_FIRE, pPlayer->i);
|
||||
else if (PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4765,6 +5164,8 @@ static void P_ProcessWeapon(int playerNum)
|
|||
if (pPlayer->quick_kick == 0)
|
||||
{
|
||||
(*weaponFrame) = 1;
|
||||
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -5375,6 +5776,186 @@ static void P_ProcessWeapon(int playerNum)
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (WW2GI)
|
||||
{
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, WorksLike) == HANDBOMB_WEAPON)
|
||||
{
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, HoldDelay) && ((*weaponFrame) == PWEAPON(playerNum, pPlayer->curr_weapon, FireDelay)) && TEST_SYNC_KEY(playerBits, SK_FIRE))
|
||||
{
|
||||
pPlayer->rapid_fire_hold = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (++(*weaponFrame) == PWEAPON(playerNum, pPlayer->curr_weapon, HoldDelay))
|
||||
{
|
||||
pPlayer->ammo_amount[pPlayer->curr_weapon]--;
|
||||
|
||||
int pipeBombType;
|
||||
int pipeBombZvel;
|
||||
int pipeBombFwdVel;
|
||||
|
||||
if (pPlayer->on_ground && TEST_SYNC_KEY(playerBits, SK_CROUCH))
|
||||
{
|
||||
pipeBombFwdVel = 15;
|
||||
pipeBombZvel = (fix16_to_int(pPlayer->q16horiz + pPlayer->q16horizoff - F16(100)) * 20);
|
||||
}
|
||||
else
|
||||
{
|
||||
pipeBombFwdVel = 140;
|
||||
pipeBombZvel = -512 - (fix16_to_int(pPlayer->q16horiz + pPlayer->q16horizoff - F16(100)) * 20);
|
||||
}
|
||||
|
||||
int pipeSpriteNum = A_InsertSprite(pPlayer->cursectnum,
|
||||
pPlayer->pos.x+(sintable[(fix16_to_int(pPlayer->q16ang)+512)&2047]>>6),
|
||||
pPlayer->pos.y+(sintable[fix16_to_int(pPlayer->q16ang)&2047]>>6),
|
||||
pPlayer->pos.z,PWEAPON(playerNum, pPlayer->curr_weapon, Shoots),-16,9,9,
|
||||
fix16_to_int(pPlayer->q16ang),(pipeBombFwdVel+(pPlayer->hbomb_hold_delay<<5)),pipeBombZvel,pPlayer->i,1);
|
||||
|
||||
int pipeLifeTime = Gv_GetVarByLabel("GRENADE_LIFETIME", NAM_GRENADE_LIFETIME, -1, playerNum);
|
||||
int pipeLifeVariance = Gv_GetVarByLabel("GRENADE_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, -1, playerNum);
|
||||
sprite[pipeSpriteNum].extra = pipeLifeTime
|
||||
+ mulscale14(krand2(), pipeLifeVariance)
|
||||
- pipeLifeVariance;
|
||||
|
||||
if (pipeBombFwdVel == 15)
|
||||
{
|
||||
sprite[pipeSpriteNum].yvel = 3;
|
||||
sprite[pipeSpriteNum].z += ZOFFSET3;
|
||||
}
|
||||
|
||||
if (A_GetHitscanRange(pPlayer->i) < 512)
|
||||
{
|
||||
sprite[pipeSpriteNum].ang += 1024;
|
||||
sprite[pipeSpriteNum].zvel /= 3;
|
||||
sprite[pipeSpriteNum].xvel /= 3;
|
||||
}
|
||||
|
||||
pPlayer->hbomb_on = 1;
|
||||
}
|
||||
else if ((*weaponFrame) < PWEAPON(playerNum, pPlayer->curr_weapon, HoldDelay) && TEST_SYNC_KEY(playerBits, SK_FIRE))
|
||||
pPlayer->hbomb_hold_delay++;
|
||||
else if ((*weaponFrame) > PWEAPON(playerNum, pPlayer->curr_weapon, TotalTime))
|
||||
{
|
||||
(*weaponFrame) = 0;
|
||||
P_CheckWeapon(pPlayer);
|
||||
}
|
||||
}
|
||||
else if (PWEAPON(playerNum, pPlayer->curr_weapon, WorksLike) == HANDREMOTE_WEAPON)
|
||||
{
|
||||
if (++(*weaponFrame) == PWEAPON(playerNum, pPlayer->curr_weapon, FireDelay))
|
||||
{
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_BOMB_TRIGGER)
|
||||
pPlayer->hbomb_on = 0;
|
||||
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Shoots) != 0)
|
||||
{
|
||||
if (!(PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_NOVISIBLE))
|
||||
{
|
||||
lastvisinc = (int32_t) totalclock+32;
|
||||
pPlayer->visibility = 0;
|
||||
}
|
||||
|
||||
P_SetWeaponGamevars(playerNum, pPlayer);
|
||||
A_Shoot(pPlayer->i, PWEAPON(playerNum, pPlayer->curr_weapon, Shoots));
|
||||
}
|
||||
}
|
||||
|
||||
if ((*weaponFrame) >= PWEAPON(playerNum, pPlayer->curr_weapon, TotalTime))
|
||||
{
|
||||
(*weaponFrame) = 0;
|
||||
if (pPlayer->ammo_amount[HANDBOMB_WEAPON] > 0)
|
||||
P_AddWeapon(pPlayer, HANDBOMB_WEAPON);
|
||||
else P_CheckWeapon(pPlayer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// the basic weapon...
|
||||
(*weaponFrame)++;
|
||||
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_CHECKATRELOAD)
|
||||
{
|
||||
if (*weaponFrame >= PWEAPON(playerNum, pPlayer->curr_weapon, Reload))
|
||||
P_CheckWeapon(pPlayer);
|
||||
}
|
||||
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_STANDSTILL
|
||||
&& *weaponFrame < (PWEAPON(playerNum, pPlayer->curr_weapon, FireDelay)+1))
|
||||
{
|
||||
pPlayer->pos.z = pPlayer->opos.z;
|
||||
pPlayer->vel.z = 0;
|
||||
}
|
||||
|
||||
if (*weaponFrame == PWEAPON(playerNum, pPlayer->curr_weapon, Sound2Time))
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Sound2Sound) > 0)
|
||||
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, Sound2Sound),pPlayer->i);
|
||||
|
||||
if (*weaponFrame == PWEAPON(playerNum, pPlayer->curr_weapon, SpawnTime))
|
||||
P_DoWeaponSpawn(playerNum);
|
||||
|
||||
if (*weaponFrame == PWEAPON(playerNum, pPlayer->curr_weapon, FireDelay))
|
||||
P_FireWeapon(playerNum);
|
||||
|
||||
if (*weaponFrame > PWEAPON(playerNum, pPlayer->curr_weapon, FireDelay)
|
||||
&& *weaponFrame < PWEAPON(playerNum, pPlayer->curr_weapon, TotalTime))
|
||||
{
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_AUTOMATIC)
|
||||
{
|
||||
if (TEST_SYNC_KEY(playerBits, SK_FIRE) == 0)
|
||||
*weaponFrame = PWEAPON(playerNum, pPlayer->curr_weapon, TotalTime);
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_FIREEVERYTHIRD)
|
||||
{
|
||||
if (((*(weaponFrame))%3) == 0)
|
||||
{
|
||||
P_FireWeapon(playerNum);
|
||||
P_DoWeaponSpawn(playerNum);
|
||||
}
|
||||
}
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_FIREEVERYOTHER)
|
||||
{
|
||||
P_FireWeapon(playerNum);
|
||||
P_DoWeaponSpawn(playerNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*weaponFrame >= PWEAPON(playerNum, pPlayer->curr_weapon, TotalTime))
|
||||
{
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Reload) > PWEAPON(playerNum, pPlayer->curr_weapon, TotalTime) && pPlayer->ammo_amount[pPlayer->curr_weapon] > 0
|
||||
&& PWEAPON(playerNum, pPlayer->curr_weapon, Clip) && pPlayer->ammo_amount[pPlayer->curr_weapon] % PWEAPON(playerNum, pPlayer->curr_weapon, Clip) == 0)
|
||||
{
|
||||
int const weaponReloadTime = PWEAPON(playerNum, pPlayer->curr_weapon, Reload)
|
||||
- PWEAPON(playerNum, pPlayer->curr_weapon, TotalTime);
|
||||
|
||||
if ((*weaponFrame) == (PWEAPON(playerNum, pPlayer->curr_weapon, TotalTime)+1))
|
||||
{
|
||||
A_PlaySound(EJECT_CLIP, pPlayer->i);
|
||||
}
|
||||
else if ((*weaponFrame) ==
|
||||
(PWEAPON(playerNum, pPlayer->curr_weapon, Reload) - (weaponReloadTime / 3)))
|
||||
{
|
||||
A_PlaySound(INSERT_CLIP, pPlayer->i);
|
||||
}
|
||||
if ((*weaponFrame) >= (PWEAPON(playerNum, pPlayer->curr_weapon, Reload)))
|
||||
{
|
||||
*weaponFrame = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_AUTOMATIC)
|
||||
{
|
||||
if (TEST_SYNC_KEY(playerBits, SK_FIRE))
|
||||
{
|
||||
*weaponFrame =
|
||||
(PWEAPON(playerNum, pPlayer->curr_weapon, Flags) & WEAPON_RANDOMRESTART) ? 1 + (krand2() & 3) : 1;
|
||||
}
|
||||
else *weaponFrame = 0;
|
||||
}
|
||||
else *weaponFrame = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (DYNAMICWEAPONMAP(pPlayer->curr_weapon))
|
||||
|
@ -6932,7 +7513,7 @@ check_enemy_sprite:
|
|||
P_UpdatePosWhenViewingCam(pPlayer);
|
||||
P_DoCounters(playerNum);
|
||||
|
||||
if (pPlayer->curr_weapon == HANDREMOTE_WEAPON)
|
||||
if ((WW2GI ? PWEAPON(playerNum, pPlayer->curr_weapon, WorksLike) : pPlayer->curr_weapon) == HANDREMOTE_WEAPON)
|
||||
P_ProcessWeapon(playerNum);
|
||||
|
||||
return;
|
||||
|
|
|
@ -1956,13 +1956,14 @@ end_vol4a:
|
|||
{
|
||||
for (bssize_t weaponNum = 0; weaponNum < MAX_WEAPONS; weaponNum++)
|
||||
{
|
||||
if (weaponNum == PISTOL_WEAPON)
|
||||
auto const worksLike = WW2GI ? PWEAPON(0, weaponNum, WorksLike) : weaponNum;
|
||||
if (worksLike == PISTOL_WEAPON)
|
||||
{
|
||||
pPlayer->curr_weapon = weaponNum;
|
||||
pPlayer->gotweapon |= (1 << weaponNum);
|
||||
pPlayer->ammo_amount[weaponNum] = min<int16_t>(pPlayer->max_ammo_amount[weaponNum], 48);
|
||||
}
|
||||
else if (weaponNum == KNEE_WEAPON || (!RR && weaponNum == HANDREMOTE_WEAPON) || (RRRA && weaponNum == SLINGBLADE_WEAPON))
|
||||
else if (worksLike == KNEE_WEAPON || (!RR && worksLike == HANDREMOTE_WEAPON) || (RRRA && worksLike == SLINGBLADE_WEAPON))
|
||||
{
|
||||
pPlayer->gotweapon |= (1 << weaponNum);
|
||||
if (RRRA)
|
||||
|
|
|
@ -604,8 +604,12 @@ static int32_t G_GetInvOn(const DukePlayer_t *p)
|
|||
return 0x80000000;
|
||||
}
|
||||
|
||||
static inline void rotatesprite_althud(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat)
|
||||
static int32_t G_GetMorale(int32_t p_i, int32_t snum)
|
||||
{
|
||||
return Gv_GetVarByLabel("PLR_MORALE", -1, p_i, snum);
|
||||
}
|
||||
|
||||
static inline void rotatesprite_althud(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat){
|
||||
if (videoGetRenderMode() >= REND_POLYMOST && althud_shadows)
|
||||
rotatesprite_(sbarx(sx+1), sbary(sy+1), z, a, picnum, 127, 4, dastat + POLYMOSTTRANS2, 0, 0, 0, 0, xdim - 1, ydim - 1);
|
||||
rotatesprite_(sbarx(sx), sbary(sy), z, a, picnum, dashade, dapalnum, dastat, 0, 0, 0, 0, xdim - 1, ydim - 1);
|
||||
|
@ -808,7 +812,13 @@ void G_DrawStatusBar(int32_t snum)
|
|||
}
|
||||
|
||||
rotatesprite_althud(62, hudoffset-25, sb15h, 0, SHIELD, 0, 0, 10+16+256);
|
||||
G_DrawAltDigiNum(105, -(hudoffset-22), p->inv_amount[GET_SHIELD], -16, 10+16+256);
|
||||
|
||||
{
|
||||
int32_t lAmount = G_GetMorale(p->i, snum);
|
||||
if (lAmount == -1)
|
||||
lAmount = p->inv_amount[GET_SHIELD];
|
||||
G_DrawAltDigiNum(105, -(hudoffset-22), lAmount, -16, 10+16+256);
|
||||
}
|
||||
|
||||
if (ammo_sprites[p->curr_weapon] >= 0)
|
||||
{
|
||||
|
@ -844,6 +854,8 @@ void G_DrawStatusBar(int32_t snum)
|
|||
|
||||
G_DrawInvNum(-(284-30-o), 0, hudoffset-6-3, (uint8_t) i, 0, 10+permbit+256);
|
||||
|
||||
if (!WW2GI)
|
||||
{
|
||||
if (j > 0)
|
||||
{
|
||||
if (videoGetRenderMode() >= REND_POLYMOST && althud_shadows)
|
||||
|
@ -856,6 +868,7 @@ void G_DrawStatusBar(int32_t snum)
|
|||
minitextshade(284-30-o+1, hudoffset-20-3+1, "Off", 127, 4, POLYMOSTTRANS+orient+ROTATESPRITE_MAX);
|
||||
minitext(284-30-o, hudoffset-20-3, "Off", 2, orient+ROTATESPRITE_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
if (p->inven_icon >= ICON_SCUBA)
|
||||
{
|
||||
|
@ -981,10 +994,13 @@ void G_DrawStatusBar(int32_t snum)
|
|||
|
||||
G_DrawInvNum(284-30-o, yofssh, 200-6, (uint8_t) i, 0, orient&~16);
|
||||
|
||||
if (!WW2GI)
|
||||
{
|
||||
if (j > 0)
|
||||
minitext(288-30-o, 180, GStrings("OPTVAL_ON"), 0, orient);
|
||||
else if ((uint32_t) j != 0x80000000)
|
||||
minitext(284-30-o, 180, GStrings("OPTVAL_OFF"), 2, orient);
|
||||
}
|
||||
|
||||
if (p->inven_icon >= ICON_SCUBA)
|
||||
minitext(284-35-o, 180, GStrings("OPTVAL_AUTO"), 2, orient);
|
||||
|
@ -1024,7 +1040,9 @@ void G_DrawStatusBar(int32_t snum)
|
|||
}
|
||||
|
||||
{
|
||||
int32_t lAmount = p->inv_amount[GET_SHIELD];
|
||||
int32_t lAmount = G_GetMorale(p->i, snum);
|
||||
if (lAmount == -1)
|
||||
lAmount = p->inv_amount[GET_SHIELD];
|
||||
if (sbar.inv_amount[GET_SHIELD] != lAmount)
|
||||
{
|
||||
sbar.inv_amount[GET_SHIELD] = lAmount;
|
||||
|
@ -1045,6 +1063,8 @@ void G_DrawStatusBar(int32_t snum)
|
|||
sbar.ammo_amount[i] = p->ammo_amount[i];
|
||||
if (i < 9)
|
||||
u |= ((2<<i)+1024);
|
||||
else if (WW2GI && i == 11)
|
||||
u |= 1024 + 128;
|
||||
else
|
||||
u |= 65536L+1024;
|
||||
}
|
||||
|
@ -1280,7 +1300,7 @@ void G_DrawStatusBar(int32_t snum)
|
|||
}
|
||||
}
|
||||
|
||||
if (u&(2048+4096))
|
||||
if (u&(2048+4096) && !WW2GI)
|
||||
{
|
||||
j = G_GetInvOn(p);
|
||||
|
||||
|
|
|
@ -3722,10 +3722,10 @@ void P_HandleSharedKeys(int playerNum)
|
|||
}
|
||||
return; // is there significance to returning?
|
||||
}
|
||||
if (pPlayer->refresh_inventory)
|
||||
if (WW2GI && pPlayer->refresh_inventory)
|
||||
playerBits |= BIT(SK_INV_LEFT); // emulate move left...
|
||||
|
||||
if (pPlayer->newowner == -1 && (TEST_SYNC_KEY(playerBits, SK_INV_LEFT) || TEST_SYNC_KEY(playerBits, SK_INV_RIGHT)))
|
||||
if (pPlayer->newowner == -1 && (TEST_SYNC_KEY(playerBits, SK_INV_LEFT) || TEST_SYNC_KEY(playerBits, SK_INV_RIGHT)) || (!WW2GI && pPlayer->refresh_inventory))
|
||||
{
|
||||
pPlayer->invdisptime = GAMETICSPERSEC*2;
|
||||
|
||||
|
|
Loading…
Reference in a new issue