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:
nukeykt 2020-02-07 22:45:27 +09:00 committed by Christoph Oelckers
parent 972f2c4f0d
commit 365b7bfe79
7 changed files with 1561 additions and 53 deletions

View file

@ -1184,7 +1184,7 @@ ACTOR_STATIC void G_MovePlayers(void)
{ {
pSprite->extra = pPlayer->max_player_health; pSprite->extra = pPlayer->max_player_health;
pSprite->cstat = 257; pSprite->cstat = 257;
if (!RR) if (!RR && !WW2GI)
pPlayer->inv_amount[GET_JETPACK] = 1599; pPlayer->inv_amount[GET_JETPACK] = 1599;
} }
@ -1801,6 +1801,20 @@ ACTOR_STATIC void G_MoveStandables(void)
} }
else if (!RR && pSprite->picnum == TRIPBOMB) 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) if (T3(spriteNum) > 0)
{ {
T3(spriteNum)--; T3(spriteNum)--;
@ -1871,6 +1885,8 @@ ACTOR_STATIC void G_MoveStandables(void)
actor[spriteNum].lastv.x = hitDist; actor[spriteNum].lastv.x = hitDist;
pSprite->ang = oldAng; pSprite->ang = oldAng;
if (tripBombMode & TRIPBOMB_TRIPWIRE)
{
// we're on a trip wire // we're on a trip wire
//int16_t cursectnum; //int16_t cursectnum;
@ -1896,6 +1912,7 @@ ACTOR_STATIC void G_MoveStandables(void)
//if (cursectnum < 0) //if (cursectnum < 0)
// break; // break;
} }
}
T1(spriteNum)++; T1(spriteNum)++;
@ -1906,7 +1923,7 @@ ACTOR_STATIC void G_MoveStandables(void)
setsprite(spriteNum,(vec3_t *)pSprite); setsprite(spriteNum,(vec3_t *)pSprite);
T4(spriteNum) = T3(spriteNum) = 0; T4(spriteNum) = T3(spriteNum) = 0;
if (hitSprite >= 0) if (hitSprite >= 0 && (tripBombMode & TRIPBOMB_TRIPWIRE))
{ {
T3(spriteNum) = 13; T3(spriteNum) = 13;
A_PlaySound(LASERTRIP_ARMING,spriteNum); A_PlaySound(LASERTRIP_ARMING,spriteNum);
@ -1934,7 +1951,7 @@ ACTOR_STATIC void G_MoveStandables(void)
setsprite(spriteNum, (vec3_t *) pSprite); setsprite(spriteNum, (vec3_t *) pSprite);
// if( Actor[i].lastvx != x && lTripBombControl & TRIPBOMB_TRIPWIRE) // 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; T3(spriteNum) = 13;
A_PlaySound(LASERTRIP_ARMING, spriteNum); A_PlaySound(LASERTRIP_ARMING, spriteNum);

View file

@ -185,6 +185,43 @@ void G_SetupCheats(void)
Bstrcpy(CheatStrings[39], "van"); 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) else if (NAM)
{ {
CheatKeys[0] = sc_N; CheatKeys[0] = sc_N;

852
source/rr/src/gamevars.cpp Normal file
View 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

View file

@ -211,8 +211,14 @@ static int A_FindTargetSprite(const spritetype *pSprite, int projAng, int projec
int const spriteAng = pSprite->ang; int const spriteAng = pSprite->ang;
int const isShrinker = (!RR && pSprite->picnum == APLAYER && g_player[playerNum].ps->curr_weapon == SHRINKER_WEAPON); int 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 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 d1 = { sintable[(spriteAng + 512 - projAng) & 2047], sintable[(spriteAng - projAng) & 2047] };
vec2_t const d2 = { 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; 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->extra >>= 2;
pReturn->ang += 16 - (krand2() & 31); pReturn->ang += 16 - (krand2() & 31);
@ -1272,8 +1278,17 @@ growspark_rr:
if (placeMine == 1) 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, 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); 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; sprite[spawnedSprite].hitag = spawnedSprite;
A_PlaySound(LASERTRIP_ONWALL, spawnedSprite); A_PlaySound(LASERTRIP_ONWALL, spawnedSprite);
sprite[spawnedSprite].xvel = -20; sprite[spawnedSprite].xvel = -20;
@ -1285,7 +1300,7 @@ growspark_rr:
actor[spawnedSprite].t_data[5] = sprite[spawnedSprite].ang = wallAng; actor[spawnedSprite].t_data[5] = sprite[spawnedSprite].ang = wallAng;
if (playerNum >= 0) if (!WW2GI && playerNum >= 0)
pPlayer->ammo_amount[TRIPBOMB_WEAPON]--; pPlayer->ammo_amount[TRIPBOMB_WEAPON]--;
return spawnedSprite; return spawnedSprite;
@ -1585,6 +1600,8 @@ static int P_DisplayKnee(int kneeShade)
static int P_DisplayKnuckles(int knuckleShade) static int P_DisplayKnuckles(int knuckleShade)
{ {
if (WW2GI)
return 0;
const DukePlayer_t *const pPlayer = g_player[screenpeek].ps; const DukePlayer_t *const pPlayer = g_player[screenpeek].ps;
if (pPlayer->knuckle_incs == 0) if (pPlayer->knuckle_incs == 0)
@ -1606,6 +1623,99 @@ static int P_DisplayKnuckles(int knuckleShade)
return 1; 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) void P_DisplayScuba(void)
{ {
if (g_player[screenpeek].ps->scuba_on) if (g_player[screenpeek].ps->scuba_on)
@ -1762,6 +1872,9 @@ void P_DisplayWeapon(void)
weaponX -= 58 + pPlayer->weapon_ang; weaponX -= 58 + pPlayer->weapon_ang;
weaponYOffset -= (pPlayer->hard_landing << 3); 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; currentWeapon = (pPlayer->last_weapon >= 0) ? pPlayer->last_weapon : pPlayer->curr_weapon;
hudweap.gunposy = weaponYOffset; hudweap.gunposy = weaponYOffset;
hudweap.lookhoriz = weaponY; hudweap.lookhoriz = weaponY;
@ -2415,9 +2528,19 @@ void P_DisplayWeapon(void)
if (*weaponFrame > 0) 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, G_DrawWeaponTileWithID(currentWeapon << 1, weaponX + 164, (weaponY << 1) + 176 - weaponYOffset,
RPGGUN + ((*weaponFrame) >> 1), weaponShade, weaponBits, weaponPal); 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, G_DrawWeaponTileWithID(currentWeapon, weaponX + 164, (weaponY << 1) + 176 - weaponYOffset, RPGGUN, weaponShade,
@ -2427,6 +2550,41 @@ void P_DisplayWeapon(void)
case SHOTGUN_WEAPON__STATIC: case SHOTGUN_WEAPON__STATIC:
weaponX -= 8; 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) switch (*weaponFrame)
{ {
case 1: case 1:
@ -2505,6 +2663,83 @@ void P_DisplayWeapon(void)
weaponX += 1-(rand()&3); 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) switch (*weaponFrame)
{ {
case 0: case 0:
@ -2584,21 +2819,21 @@ void P_DisplayWeapon(void)
weaponShade, weaponBits, weaponPal); 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, G_DrawWeaponTileWithID(currentWeapon << 2, 184 - (pPlayer->look_ang >> 1), weaponY + 235 - weaponYOffset,
FIRSTGUN + 8, weaponShade, weaponBits, weaponPal); FIRSTGUN + 8, weaponShade, weaponBits, weaponPal);
G_DrawWeaponTileWithID(currentWeapon, 224 - (pPlayer->look_ang >> 1), weaponY + 210 - weaponYOffset, FIRSTGUN + 5, G_DrawWeaponTileWithID(currentWeapon, 224 - (pPlayer->look_ang >> 1), weaponY + 210 - weaponYOffset, FIRSTGUN + 5,
weaponShade, weaponBits, weaponPal); 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, G_DrawWeaponTileWithID(currentWeapon << 2, 164 - (pPlayer->look_ang >> 1), weaponY + 245 - weaponYOffset,
FIRSTGUN + 8, weaponShade, weaponBits, weaponPal); FIRSTGUN + 8, weaponShade, weaponBits, weaponPal);
G_DrawWeaponTileWithID(currentWeapon, 224 - (pPlayer->look_ang >> 1), weaponY + 220 - weaponYOffset, FIRSTGUN + 5, G_DrawWeaponTileWithID(currentWeapon, 224 - (pPlayer->look_ang >> 1), weaponY + 220 - weaponYOffset, FIRSTGUN + 5,
weaponShade, weaponBits, weaponPal); 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, G_DrawWeaponTileWithID(currentWeapon, 194 - (pPlayer->look_ang >> 1), weaponY + 235 - weaponYOffset, FIRSTGUN + 5,
weaponShade, weaponBits, weaponPal); weaponShade, weaponBits, weaponPal);
@ -2611,7 +2846,38 @@ void P_DisplayWeapon(void)
if (*weaponFrame >= ARRAY_SIZE(pipebombFrames)) if (*weaponFrame >= ARRAY_SIZE(pipebombFrames))
break; break;
if (WW2GI && *weaponFrame >= PWEAPON(screenpeek, pPlayer->curr_weapon, TotalTime))
break;
if (*weaponFrame) 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 if (*weaponFrame < 7) weaponYOffset -= 10 * (*weaponFrame); // D
else if (*weaponFrame < 12) weaponYOffset += 20 * ((*weaponFrame) - 10); // U else if (*weaponFrame < 12) weaponYOffset += 20 * ((*weaponFrame) - 10); // U
@ -2619,6 +2885,7 @@ void P_DisplayWeapon(void)
weaponYOffset += 10; weaponYOffset += 10;
} }
}
G_DrawWeaponTileWithID(currentWeapon, weaponX + 190 - halfLookAng, weaponY + 260 - weaponYOffset, G_DrawWeaponTileWithID(currentWeapon, weaponX + 190 - halfLookAng, weaponY + 260 - weaponYOffset,
HANDTHROW + pipebombFrames[(*weaponFrame)], weaponShade, weaponBits, weaponPal); HANDTHROW + pipebombFrames[(*weaponFrame)], weaponShade, weaponBits, weaponPal);
@ -2639,6 +2906,55 @@ void P_DisplayWeapon(void)
break; break;
case DEVISTATOR_WEAPON__STATIC: 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) if (*weaponFrame > 0)
{ {
static uint8_t const devastatorFrames[] = { 0, 4, 12, 24, 12, 4, 0 }; static uint8_t const devastatorFrames[] = { 0, 4, 12, 24, 12, 4, 0 };
@ -2706,6 +3022,65 @@ void P_DisplayWeapon(void)
weaponX += 28; weaponX += 28;
weaponY += 18; 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 ((*weaponFrame) > 0)
{ {
if (doAnim) if (doAnim)
@ -3924,7 +4299,9 @@ static int32_t P_DoCounters(int playerNum)
} }
A_PlaySound(soundId, pPlayer->i); A_PlaySound(soundId, pPlayer->i);
} }
else if (totalclock > 1024) else if (!WW2GI)
{
if (totalclock > 1024)
if (playerNum == screenpeek || GTFLAGS(GAMETYPE_COOPSOUND)) if (playerNum == screenpeek || GTFLAGS(GAMETYPE_COOPSOUND))
{ {
if (rand()&1) if (rand()&1)
@ -3932,8 +4309,8 @@ static int32_t P_DoCounters(int playerNum)
else A_PlaySound(DUKE_CRACK2,pPlayer->i); else A_PlaySound(DUKE_CRACK2,pPlayer->i);
} }
if (!RR) A_PlaySound(DUKE_CRACK_FIRST, pPlayer->i);
A_PlaySound(DUKE_CRACK_FIRST,pPlayer->i); }
} }
else if (pPlayer->knuckle_incs == 22 || TEST_SYNC_KEY(g_player[playerNum].inputBits->bits, SK_FIRE)) else if (pPlayer->knuckle_incs == 22 || TEST_SYNC_KEY(g_player[playerNum].inputBits->bits, SK_FIRE))
pPlayer->knuckle_incs=0; pPlayer->knuckle_incs=0;
@ -3952,7 +4329,7 @@ int16_t WeaponPickupSprites[MAX_WEAPONS] = { KNEE__STATIC, FIRSTGUNSPRITE__STATI
void P_DropWeapon(int const playerNum) void P_DropWeapon(int const playerNum)
{ {
DukePlayer_t *const pPlayer = g_player[playerNum].ps; 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)) 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; return;
if (krand2() & 1) if (krand2() & 1)
@ -4137,15 +4514,6 @@ void P_SelectNextInvItem(DukePlayer_t *pPlayer)
pPlayer->inven_icon = ICON_NONE; 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) void P_CheckWeapon(DukePlayer_t *pPlayer)
{ {
int playerNum; int playerNum;
@ -4571,9 +4939,10 @@ static void P_ProcessWeapon(int playerNum)
} }
} }
#undef WEAPON2_CLIP #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)) || (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 pPlayer->random_club_frame += 64; // Glowing
@ -4627,19 +4996,23 @@ static void P_ProcessWeapon(int playerNum)
P_SetWeaponGamevars(playerNum, pPlayer); P_SetWeaponGamevars(playerNum, pPlayer);
if (VM_OnEvent(EVENT_FIRE, pPlayer->i, playerNum) == 0) 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: case HANDBOMB_WEAPON__STATIC:
pPlayer->hbomb_hold_delay = 0; pPlayer->hbomb_hold_delay = 0;
if (pPlayer->ammo_amount[pPlayer->curr_weapon] > 0) if (pPlayer->ammo_amount[pPlayer->curr_weapon] > 0)
{ {
(*weaponFrame) = 1; (*weaponFrame) = 1;
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
} }
break; break;
case HANDREMOTE_WEAPON__STATIC: case HANDREMOTE_WEAPON__STATIC:
pPlayer->hbomb_hold_delay = 0; pPlayer->hbomb_hold_delay = 0;
(*weaponFrame) = 1; (*weaponFrame) = 1;
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
break; break;
case PISTOL_WEAPON__STATIC: case PISTOL_WEAPON__STATIC:
@ -4647,6 +5020,8 @@ static void P_ProcessWeapon(int playerNum)
{ {
pPlayer->ammo_amount[PISTOL_WEAPON]--; pPlayer->ammo_amount[PISTOL_WEAPON]--;
(*weaponFrame) = 1; (*weaponFrame) = 1;
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
} }
break; break;
@ -4654,6 +5029,8 @@ static void P_ProcessWeapon(int playerNum)
if (pPlayer->ammo_amount[SHOTGUN_WEAPON] > 0 && pPlayer->random_club_frame == 0) if (pPlayer->ammo_amount[SHOTGUN_WEAPON] > 0 && pPlayer->random_club_frame == 0)
{ {
(*weaponFrame) = 1; (*weaponFrame) = 1;
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
} }
break; break;
@ -4706,6 +5083,10 @@ static void P_ProcessWeapon(int playerNum)
pPlayer->pos.z = pPlayer->opos.z; pPlayer->pos.z = pPlayer->opos.z;
pPlayer->vel.z = 0; pPlayer->vel.z = 0;
(*weaponFrame) = 1; (*weaponFrame) = 1;
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
{
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
}
} }
} }
break; break;
@ -4714,7 +5095,10 @@ static void P_ProcessWeapon(int playerNum)
if (pPlayer->ammo_amount[SHRINKER_WEAPON] > 0) if (pPlayer->ammo_amount[SHRINKER_WEAPON] > 0)
{ {
(*weaponFrame) = 1; (*weaponFrame) = 1;
if (!WW2GI)
A_PlaySound(SHRINKER_FIRE, pPlayer->i); 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; break;
@ -4722,16 +5106,24 @@ static void P_ProcessWeapon(int playerNum)
if (pPlayer->ammo_amount[GROW_WEAPON] > 0) if (pPlayer->ammo_amount[GROW_WEAPON] > 0)
{ {
(*weaponFrame) = 1; (*weaponFrame) = 1;
if (!WW2GI)
A_PlaySound(RR ? 431 : EXPANDERSHOOT, pPlayer->i); 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; break;
case FREEZE_WEAPON__STATIC: case FREEZE_WEAPON__STATIC:
if (pPlayer->ammo_amount[FREEZE_WEAPON] > 0) if (pPlayer->ammo_amount[pPlayer->curr_weapon] > 0)
{ {
(*weaponFrame) = 1; (*weaponFrame) = 1;
if (!RR) if (!RR)
{
if (!WW2GI)
A_PlaySound(CAT_FIRE, pPlayer->i); 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; break;
@ -4740,6 +5132,8 @@ static void P_ProcessWeapon(int playerNum)
if (pPlayer->ammo_amount[pPlayer->curr_weapon] > 0) if (pPlayer->ammo_amount[pPlayer->curr_weapon] > 0)
{ {
(*weaponFrame) = 1; (*weaponFrame) = 1;
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
} }
break; break;
@ -4749,7 +5143,12 @@ static void P_ProcessWeapon(int playerNum)
(*weaponFrame) = 1; (*weaponFrame) = 1;
pPlayer->hbomb_hold_delay = !pPlayer->hbomb_hold_delay; pPlayer->hbomb_hold_delay = !pPlayer->hbomb_hold_delay;
if (!RR) if (!RR)
{
if (!WW2GI)
A_PlaySound(CAT_FIRE, pPlayer->i); 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; break;
@ -4765,6 +5164,8 @@ static void P_ProcessWeapon(int playerNum)
if (pPlayer->quick_kick == 0) if (pPlayer->quick_kick == 0)
{ {
(*weaponFrame) = 1; (*weaponFrame) = 1;
if (WW2GI && PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound) > 0)
A_PlaySound(PWEAPON(playerNum, pPlayer->curr_weapon, InitialSound), pPlayer->i);
} }
break; break;
@ -5375,6 +5776,186 @@ static void P_ProcessWeapon(int playerNum)
break; 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 else
{ {
switch (DYNAMICWEAPONMAP(pPlayer->curr_weapon)) switch (DYNAMICWEAPONMAP(pPlayer->curr_weapon))
@ -6932,7 +7513,7 @@ check_enemy_sprite:
P_UpdatePosWhenViewingCam(pPlayer); P_UpdatePosWhenViewingCam(pPlayer);
P_DoCounters(playerNum); 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); P_ProcessWeapon(playerNum);
return; return;

View file

@ -1956,13 +1956,14 @@ end_vol4a:
{ {
for (bssize_t weaponNum = 0; weaponNum < MAX_WEAPONS; weaponNum++) 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->curr_weapon = weaponNum;
pPlayer->gotweapon |= (1 << weaponNum); pPlayer->gotweapon |= (1 << weaponNum);
pPlayer->ammo_amount[weaponNum] = min<int16_t>(pPlayer->max_ammo_amount[weaponNum], 48); 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); pPlayer->gotweapon |= (1 << weaponNum);
if (RRRA) if (RRRA)

View file

@ -604,8 +604,12 @@ static int32_t G_GetInvOn(const DukePlayer_t *p)
return 0x80000000; 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) 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+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); 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); 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) 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); G_DrawInvNum(-(284-30-o), 0, hudoffset-6-3, (uint8_t) i, 0, 10+permbit+256);
if (!WW2GI)
{
if (j > 0) if (j > 0)
{ {
if (videoGetRenderMode() >= REND_POLYMOST && althud_shadows) 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); 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); minitext(284-30-o, hudoffset-20-3, "Off", 2, orient+ROTATESPRITE_MAX);
} }
}
if (p->inven_icon >= ICON_SCUBA) 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); G_DrawInvNum(284-30-o, yofssh, 200-6, (uint8_t) i, 0, orient&~16);
if (!WW2GI)
{
if (j > 0) if (j > 0)
minitext(288-30-o, 180, GStrings("OPTVAL_ON"), 0, orient); minitext(288-30-o, 180, GStrings("OPTVAL_ON"), 0, orient);
else if ((uint32_t) j != 0x80000000) else if ((uint32_t) j != 0x80000000)
minitext(284-30-o, 180, GStrings("OPTVAL_OFF"), 2, orient); minitext(284-30-o, 180, GStrings("OPTVAL_OFF"), 2, orient);
}
if (p->inven_icon >= ICON_SCUBA) if (p->inven_icon >= ICON_SCUBA)
minitext(284-35-o, 180, GStrings("OPTVAL_AUTO"), 2, orient); 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) if (sbar.inv_amount[GET_SHIELD] != lAmount)
{ {
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]; sbar.ammo_amount[i] = p->ammo_amount[i];
if (i < 9) if (i < 9)
u |= ((2<<i)+1024); u |= ((2<<i)+1024);
else if (WW2GI && i == 11)
u |= 1024 + 128;
else else
u |= 65536L+1024; 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); j = G_GetInvOn(p);

View file

@ -3722,10 +3722,10 @@ void P_HandleSharedKeys(int playerNum)
} }
return; // is there significance to returning? return; // is there significance to returning?
} }
if (pPlayer->refresh_inventory) if (WW2GI && pPlayer->refresh_inventory)
playerBits |= BIT(SK_INV_LEFT); // emulate move left... 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; pPlayer->invdisptime = GAMETICSPERSEC*2;