shotgun with packet delays
This commit is contained in:
parent
7753285cfb
commit
d3a620bb55
16 changed files with 487 additions and 178 deletions
|
@ -231,7 +231,7 @@ TS_HUD_DrawWeaponSelect(void)
|
|||
return;
|
||||
}
|
||||
|
||||
drawPlayerInventory_buy(FALSE);
|
||||
drawPlayerInventory(FALSE);
|
||||
drawPlayerInventory_TopBar(-1, FALSE);
|
||||
|
||||
}//HUD_DrawWeaponSelect
|
||||
|
|
|
@ -57,7 +57,7 @@ imageCropBounds_t ary_LCD_numberSet[] = {
|
|||
|
||||
void drawWeaponOptionBar(vector arg_vDrawOrigin, string arg_sOptionName, BOOLEAN arg_fBrightLight, float arg_opac);
|
||||
void drawPlayerInventory_TopBar(int arg_iSlotSelected, BOOL arg_fBuyMode);
|
||||
void drawPlayerInventory_buy(BOOL arg_fBuyMode);
|
||||
void drawPlayerInventory(BOOL arg_fBuyMode);
|
||||
|
||||
void drawPlayerInventory_place(int arg_iSlot, int arg_iRow, string arg_sWeaponSpritePath, string arg_sSelectedWeaponDisplayName, BOOL arg_fBuyMode, optional int ammoCount, optional BOOL hasAnyAmmo, optional int bitsUpgradeOpts);
|
||||
|
||||
|
|
|
@ -70,11 +70,13 @@ drawPlayerInventory_TopBar(int arg_iSlotSelected, BOOL arg_fBuyMode)
|
|||
|
||||
}//drawPlayerInventory_TopBar
|
||||
|
||||
|
||||
// While in the buy screen, draw each slot according to the current temp config.
|
||||
// This includes using the #1 slot for the text
|
||||
// ...We're going to take advantage of the fact that weaponconfig_weapon_t
|
||||
// This includes using the #1 slot for the text.
|
||||
// For buymode, we're displaying the tempconfig (what things to buy at spawntime).
|
||||
// Otherwise, this is the player's ingame inventory being drawn.
|
||||
void
|
||||
drawPlayerInventory_buy(BOOL arg_fBuyMode)
|
||||
drawPlayerInventory(BOOL arg_fBuyMode)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
|
||||
|
|
|
@ -41,11 +41,7 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(CSQC) || defined(MENU)
|
||||
#if defined(CLIENT) || defined(MENU)
|
||||
|
||||
//TAGGG - just give those bits names
|
||||
#define DRAWTEXTFIELD_ALIGN_LEFT 1
|
||||
|
@ -68,11 +64,6 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct{
|
||||
string sFilePath;
|
||||
float w;
|
||||
|
|
|
@ -1438,6 +1438,7 @@ void
|
|||
VGUI_BuySideMenu_Update(player arg_player, vector vPos, vector vWindowSiz, float fFontSizeMulti)
|
||||
{
|
||||
// If we leave spectator view (spawned and walking/aiming), disallow the buy menu.
|
||||
// (could also check for "player.iState == PLAYER_STATE::SPAWNED" )
|
||||
if(getplayerkeyvalue(player_localnum, "*spec") == "0"){
|
||||
|
||||
VGUI_ChangeScreen(VGUI_SCREEN::NONE);
|
||||
|
@ -1472,7 +1473,7 @@ VGUI_BuySideMenu_Update(player arg_player, vector vPos, vector vWindowSiz, float
|
|||
|
||||
BuySideMenu_onInputEvent();
|
||||
|
||||
drawPlayerInventory_buy(TRUE);
|
||||
drawPlayerInventory(TRUE);
|
||||
|
||||
for(int i = 0i; i <= iActiveLayer; i = i + 1i){
|
||||
//Adjust these as needed. These also show where to draw the "0 Cancel" button
|
||||
|
|
|
@ -426,11 +426,20 @@ CSEv_TS_playerDropWeapon_(){
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SERVER
|
||||
// Server receives the message
|
||||
void
|
||||
CSEv_TS_playerChangeFiremode_(void){
|
||||
player pl = (player)self;
|
||||
|
||||
#ifdef FIREMODE_PREDICTION_TEST
|
||||
pl.doFiremodeChange = TRUE;
|
||||
#else
|
||||
_TS_playerChangeFiremode();
|
||||
#endif//FIREMODE_PREDICTION_TEST
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -443,10 +452,18 @@ TS_playerChangeFiremode(void){
|
|||
if(pl.inventoryEquippedIndex == -1){
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CLIENT
|
||||
sendevent("TS_playerChangeFiremode", "");
|
||||
// and do it my side too?
|
||||
|
||||
#ifdef FIREMODE_PREDICTION_TEST
|
||||
pl.ignoreFiremodeReceiveTime = time + 0.4f;
|
||||
pl.doFiremodeChange = TRUE;
|
||||
#else
|
||||
// do it for the client too?
|
||||
_TS_playerChangeFiremode();
|
||||
#endif//FIREMODE_PREDICTION_TEST
|
||||
|
||||
#else
|
||||
// SHOULD NOT HAPPEN, should call the CSEv_ version instead
|
||||
#endif
|
||||
|
@ -458,6 +475,12 @@ _TS_playerChangeFiremode(void ) {
|
|||
player pl = (player)self;
|
||||
weapondynamic_t dynaRef = pl.ary_myWeapons[pl.inventoryEquippedIndex];
|
||||
|
||||
|
||||
#if defined(CLIENT_CMD_SAFEMODE) && defined(CLIENT)
|
||||
// nope!
|
||||
return;
|
||||
#endif
|
||||
|
||||
if(dynaRef.weaponTypeID == WEAPONDATA_TYPEID_GUN || dynaRef.weaponTypeID == WEAPONDATA_TYPEID_IRONSIGHT){
|
||||
weapondata_gun_t* basicPointer = (weapondata_gun_t*) pl.getEquippedWeaponData();
|
||||
weapondata_gun_t basicRef = *(basicPointer);
|
||||
|
@ -470,10 +493,13 @@ _TS_playerChangeFiremode(void ) {
|
|||
}
|
||||
|
||||
int* fireModeVar;
|
||||
int* fireModeVar_net;
|
||||
if(!pl.weaponEquippedAkimbo){
|
||||
fireModeVar = &dynaRef.iFireMode;
|
||||
fireModeVar_net = &dynaRef.iFireMode_net;
|
||||
}else{
|
||||
fireModeVar = &dynaRef.iFireModeAkimbo;
|
||||
fireModeVar_net = &dynaRef.iFireModeAkimbo_net;
|
||||
}
|
||||
|
||||
if( (*fireModeVar) == basicRef.iBitsFireModes){
|
||||
|
@ -506,6 +532,12 @@ _TS_playerChangeFiremode(void ) {
|
|||
if(basicRef.iBitsFireModes & currentChoice){
|
||||
//this power of 2 is a valid fireMode? pick it
|
||||
(*fireModeVar) = currentChoice;
|
||||
|
||||
#ifdef CLIENT
|
||||
// effectively SAVE_STATE on whatever choice
|
||||
(*fireModeVar_net) = currentChoice;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -551,6 +583,8 @@ void
|
|||
_TS_playerUseItems(void){
|
||||
player pl = (player)self;
|
||||
|
||||
|
||||
|
||||
if(pl.inventoryEquippedIndex != -1){
|
||||
|
||||
weapondynamic_t dynaRef = pl.ary_myWeapons[pl.inventoryEquippedIndex];
|
||||
|
@ -573,6 +607,16 @@ _TS_playerUseItems(void){
|
|||
//no togglable buyopts at all? I guess that's it.
|
||||
}else{
|
||||
|
||||
|
||||
#if defined(CLIENT_CMD_SAFEMODE) && defined(CLIENT)
|
||||
// Have a much simpler version instead
|
||||
#ifdef CLIENT
|
||||
localsound("weapons/switch.wav", CHAN_AUTO, 1.0f);
|
||||
#endif
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
||||
if(bitCount == 1){
|
||||
//one bit available? just toggle on/off then.
|
||||
if(bitCount_on){
|
||||
|
|
|
@ -85,6 +85,64 @@ Game_Input(void)
|
|||
self.impulse = 0;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
// FreeHL's way
|
||||
|
||||
if (input_buttons & INPUT_BUTTON0)
|
||||
Weapons_Primary();
|
||||
else if (input_buttons & INPUT_BUTTON4)
|
||||
Weapons_Reload();
|
||||
else if (input_buttons & INPUT_BUTTON3)
|
||||
Weapons_Secondary();
|
||||
//else
|
||||
pl.callWeaponThink(); //Weapons_Release();
|
||||
|
||||
// Added portion to that.
|
||||
if(input_buttons & INPUT_BUTTON0){
|
||||
pl.gflags |= GF_SEMI_TOGGLED;
|
||||
}else{
|
||||
// held down the previous frame, but not now? That's a release.
|
||||
if(pl.gflags & GF_SEMI_TOGGLED){
|
||||
TS_Weapon_PrimaryAttackRelease(pl, TRUE);
|
||||
pl.gflags &= ~GF_SEMI_TOGGLED;
|
||||
}
|
||||
}
|
||||
if(input_buttons & INPUT_BUTTON3){
|
||||
pl.gflags |= GF_SEMI_SECONDARY_TOGGLED;
|
||||
}else{
|
||||
if(pl.gflags & GF_SEMI_SECONDARY_TOGGLED){
|
||||
TS_Weapon_SecondaryAttackRelease(pl, TRUE);
|
||||
pl.gflags &= ~GF_SEMI_SECONDARY_TOGGLED;
|
||||
}
|
||||
}
|
||||
// it's this way or the much more modified way further down
|
||||
return;
|
||||
*/
|
||||
|
||||
|
||||
#ifdef FIREMODE_PREDICTION_TEST
|
||||
if(pl.doFiremodeChange){
|
||||
|
||||
// so they say?
|
||||
#ifdef CLIENT
|
||||
//sendevent("TS_playerChangeFiremode", "");
|
||||
#endif
|
||||
int iOldFiremode = pl.ary_myWeapons[pl.inventoryEquippedIndex].iFireMode;
|
||||
_TS_playerChangeFiremode();
|
||||
pl.doFiremodeChange = FALSE;
|
||||
int iNewFiremode = pl.ary_myWeapons[pl.inventoryEquippedIndex].iFireMode;
|
||||
printfline("!!! pl.doFiremodeChange seen! Firemode, old:%i new:%i", iOldFiremode, iNewFiremode);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// better TS way, weapon thinks happen alongside checking inputs
|
||||
pl.callWeaponThink();
|
||||
|
||||
|
@ -102,8 +160,6 @@ Game_Input(void)
|
|||
// to give some tolerance to ease some slight frame desyncs between the client/server.
|
||||
BOOL wasPassingFrame = (pl.w_attack_next <= 0);
|
||||
|
||||
|
||||
|
||||
#if INPUT_TAP_DETECT_CHOICE == 1
|
||||
|
||||
processInputs();
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#define PLAYER_INVENTORY_GENERIC pl.ary_myWeapons
|
||||
#define PLAYER_INVENTORY_GENERIC_MAX pl.ary_myWeapons_softMax
|
||||
//The server has the player's physical money for use anytime.
|
||||
//Can make changes to it as needed. Just use the usual "ifdef SSQC" check first.
|
||||
//Can make changes to it as needed. Just use the usual "ifdef SERVER" check first.
|
||||
//...actually, we're using CHANGE_PLAYER_MONEY instead. It includes instructions for changing the player's own memory of total amount
|
||||
//spent (useless for the server?), and actually changes the money count.
|
||||
#define PLAYER_MONEY pl.money
|
||||
|
|
|
@ -27,8 +27,19 @@ enum PLAYER_STATE{
|
|||
};
|
||||
|
||||
|
||||
#define PREDICTED_CUSTOM(arg_t, x) arg_t x; arg_t x ##_net
|
||||
|
||||
#define ATTR_CHANGED_ARY(ary, i) (ary ##_net[i] != ary[i])
|
||||
|
||||
#define PREDICTED_ARY_INT(ary, size) int ary[size]; int ary ##_net[size]
|
||||
|
||||
#define ROLL_BACK_ARY(ary, i) ary[i] = ary ##_net[i]
|
||||
#define SAVE_STATE_ARY(ary, i) ary ##_net[i] = ary[i]
|
||||
|
||||
#define PREDICTED_CUSTOM(arg_t, x) arg_t x; arg_t x ##_net
|
||||
/*
|
||||
#define ROLL_BACK_ARRAY_MEMBER(ary, i, sub) ary[i].sub = ary ##_net[i].sub
|
||||
#define SAVE_STATE_ARRAY_MEMBER(ary, i, sub) x ##_net = x // did not do
|
||||
*/
|
||||
|
||||
noref int input_sequence;
|
||||
class player:base_player
|
||||
|
@ -296,17 +307,17 @@ class player:base_player
|
|||
// When do I want to move on to the next phase?
|
||||
// For reload2 without a changed shotgunReloadIndexQueued or seeing the shotgun is full,
|
||||
// it wants to repeat to put more bullets in.
|
||||
float shotgunAddAmmoTime;
|
||||
float shotgunAddAmmoSoundTime;
|
||||
|
||||
|
||||
PREDICTED_FLOAT(shotgunAddAmmoTime);
|
||||
PREDICTED_FLOAT(shotgunAddAmmoSoundTime);
|
||||
|
||||
#ifdef CLIENT
|
||||
|
||||
|
||||
#else
|
||||
|
||||
// This time must pass before re-setting the shotgunAddAmmoTime/shotgunAddAmmoSoundTime counters is allowed.
|
||||
// Why do we need to do this? Ask FTE.
|
||||
float shotgunAddAmmoTime_cooldownSetTime;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// shared
|
||||
|
||||
// length of time for the start, intermediate (ammo loading) and end animations.
|
||||
|
@ -318,6 +329,11 @@ class player:base_player
|
|||
int shotgunReload3_seq;
|
||||
float shotgunReload3_Duration;
|
||||
|
||||
|
||||
// was BOOL
|
||||
PREDICTED_FLOAT(doFiremodeChange);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//Grenade stuff
|
||||
|
@ -401,15 +417,14 @@ class player:base_player
|
|||
|
||||
|
||||
//This will tell us whether we intend to equip the akimbo version of hte currently
|
||||
// equipped weapon. This is done since akimso variants, although selected separately in
|
||||
// equipped weapon. This is done since akimso variants, although selected separately in222222222222
|
||||
// weapon select, are still tied to the exact same element in ary_myWeapons.
|
||||
|
||||
// was BOOL.
|
||||
PREDICTED_FLOAT(weaponEquippedAkimbo);
|
||||
|
||||
//TAGGG - you're the man now, dog!
|
||||
weapondynamic_t ary_myWeapons[ary_myWeapons_length];
|
||||
int ary_myWeapons_softMax;
|
||||
PREDICTED_INT(ary_myWeapons_softMax);
|
||||
|
||||
// Have one space for each type of ammo available.
|
||||
// If there were a large number of ammunitions and a low likelihood that all/most were
|
||||
|
@ -417,7 +432,8 @@ class player:base_player
|
|||
// of ammunitions expected and keep track of which one an index (0, 1, 2, 3, etc.) refers
|
||||
// to. Sounds like a lot of extra work for a single ammo counter per type of ammo which
|
||||
// is all this is.
|
||||
int ary_ammoTotal[AMMO_ID::LAST_ID];
|
||||
//int ary_ammoTotal[AMMO_ID::LAST_ID];
|
||||
PREDICTED_ARY_INT(ary_ammoTotal,AMMO_ID::LAST_ID);
|
||||
|
||||
// Provided for quick reference. How many slots does the current loadout take?
|
||||
// There is a record of how much money has been spent, similar to config, but that isn't
|
||||
|
@ -443,6 +459,9 @@ class player:base_player
|
|||
//float lastweapon;
|
||||
#endif
|
||||
|
||||
#ifdef FIREMODE_PREDICTION_TEST
|
||||
float ignoreFiremodeReceiveTime;
|
||||
#endif
|
||||
|
||||
//TAGGG - NEW, constructor
|
||||
void(void) player;
|
||||
|
@ -474,6 +493,11 @@ class player:base_player
|
|||
|
||||
virtual void(void) callWeaponThink;
|
||||
|
||||
/*
|
||||
virtual BOOL(void) shotgunAddAmmoTime_canSet;
|
||||
virtual void(void) shotgunAddAmmoTime_setCooldownSetTime;
|
||||
*/
|
||||
|
||||
//TAGGG - CRITICAL.
|
||||
// overriding Nuclide player physics method!
|
||||
// If any ever get renamed, this needs to be kept up-to-date with that!
|
||||
|
@ -508,7 +532,6 @@ class player:base_player
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
|
@ -73,7 +73,8 @@ player::ReceiveEntity(float new, float fl)
|
|||
anim_bottom = readbyte();
|
||||
anim_bottom_time = readfloat();
|
||||
}
|
||||
|
||||
|
||||
int i;
|
||||
float temp_flViewModelFrame;
|
||||
|
||||
temp_flViewModelFrame = readfloat();
|
||||
|
@ -200,14 +201,18 @@ player::ReceiveEntity(float new, float fl)
|
|||
shotgunReloadIndexQueued = readbyte();
|
||||
shotgunWaitingForPump = readbyte();
|
||||
//shotgunReload2_ammoLoadDelay = readbyte();
|
||||
//shotgunAddAmmoTime = readbyte();
|
||||
//shotgunAddAmmoSoundTime = readbyte();
|
||||
shotgunAddAmmoTime = readfloat();
|
||||
shotgunAddAmmoSoundTime = readfloat();
|
||||
|
||||
//doFiremodeChange = readbyte();
|
||||
|
||||
currentZoomChoice = readbyte() - 1;
|
||||
|
||||
// TODO: IDEA. Only send updates for the currently equipped weapon, maybe the previously equipped one
|
||||
// a few frames too? Unsure.
|
||||
ary_myWeapons_softMax = readbyte();
|
||||
for(int i = 0; i < ary_myWeapons_softMax; i++){
|
||||
for(i = 0; i < ary_myWeapons_softMax; i++){
|
||||
ary_myWeapons[i].weaponID = readbyte();
|
||||
//printfline("ERE I GO %i - %i\n", i, ary_myWeapons[i].weaponID);
|
||||
ary_myWeapons[i].weaponTypeID = readbyte();
|
||||
ary_myWeapons[i].iBitsUpgrade = readbyte();
|
||||
ary_myWeapons[i].iCount = readbyte();
|
||||
|
@ -216,7 +221,21 @@ player::ReceiveEntity(float new, float fl)
|
|||
ary_myWeapons[i].iClipLeft = readbyte();
|
||||
ary_myWeapons[i].iClipAkimboLeft = readbyte();
|
||||
ary_myWeapons[i].iBitsUpgrade_on = readbyte();
|
||||
ary_myWeapons[i].iFireMode = readbyte();
|
||||
|
||||
int newFir = readbyte();
|
||||
|
||||
#if defined(FIREMODE_PREDICTION_TEST)
|
||||
if(i == this.inventoryEquippedIndex && ary_myWeapons[i].iFireMode != newFir){
|
||||
printfline("!!! player::ReceiveEntity, iFireMode update, changed firemode, WAS: %i NOW: %i", ary_myWeapons[i].iFireMode, newFir);
|
||||
}
|
||||
if(time >= this.ignoreFiremodeReceiveTime){
|
||||
printfline("X Change blocked, too soon");
|
||||
ary_myWeapons[i].iFireMode = newFir;
|
||||
}
|
||||
#else
|
||||
ary_myWeapons[i].iFireMode = newFir;
|
||||
#endif
|
||||
|
||||
ary_myWeapons[i].iFireModeAkimbo = readbyte();
|
||||
ary_myWeapons[i].iIronSight = readbyte();
|
||||
ary_myWeapons[i].forceBodygroup1Submodel = readbyte();
|
||||
|
@ -224,7 +243,7 @@ player::ReceiveEntity(float new, float fl)
|
|||
|
||||
//UNNECESSARY. This array is of fixed length, so known at all times.
|
||||
//WriteByte(MSG_ENTITY, ary_ammoTotal_softMax);
|
||||
for(int i = 0; i < AMMO_ID::LAST_ID; i++){
|
||||
for(i = 0; i < AMMO_ID::LAST_ID; i++){
|
||||
// See serverside equivalent, too much info was lost from some pools being over 255
|
||||
// (well I guess that's all there is to it)
|
||||
ary_ammoTotal[i] = readlong();
|
||||
|
@ -232,8 +251,6 @@ player::ReceiveEntity(float new, float fl)
|
|||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
currentZoomChoice = readbyte() - 1;
|
||||
|
||||
|
||||
|
||||
// TODO! Check for any change in ammo values like this:
|
||||
|
@ -312,6 +329,37 @@ player::PredictPreFrame(void)
|
|||
SAVE_STATE(shotgunReloadIndexQueued);
|
||||
SAVE_STATE(shotgunWaitingForPump);
|
||||
|
||||
SAVE_STATE(shotgunAddAmmoTime);
|
||||
SAVE_STATE(shotgunAddAmmoSoundTime);
|
||||
|
||||
//SAVE_STATE(doFiremodeChange);
|
||||
|
||||
|
||||
SAVE_STATE(ary_myWeapons_softMax);
|
||||
for(int i = 0; i < ary_myWeapons_softMax; i++){
|
||||
SAVE_STATE(ary_myWeapons[i].weaponID);
|
||||
SAVE_STATE(ary_myWeapons[i].weaponTypeID);
|
||||
SAVE_STATE(ary_myWeapons[i].iBitsUpgrade);
|
||||
SAVE_STATE(ary_myWeapons[i].iCount);
|
||||
//SAVE_STATE(ary_myWeapons[i].iPrice);
|
||||
//SAVE_STATE(ary_myWeapons[i].iSlots);
|
||||
SAVE_STATE(ary_myWeapons[i].iClipLeft);
|
||||
SAVE_STATE(ary_myWeapons[i].iClipAkimboLeft);
|
||||
SAVE_STATE(ary_myWeapons[i].iBitsUpgrade_on);
|
||||
SAVE_STATE(ary_myWeapons[i].iFireMode);
|
||||
SAVE_STATE(ary_myWeapons[i].iFireModeAkimbo);
|
||||
SAVE_STATE(ary_myWeapons[i].iIronSight);
|
||||
SAVE_STATE(ary_myWeapons[i].forceBodygroup1Submodel);
|
||||
}
|
||||
|
||||
//UNNECESSARY. This array is of fixed length, so known at all times.
|
||||
//WriteByte(MSG_ENTITY, ary_ammoTotal_softMax);
|
||||
for(int i = 0; i < AMMO_ID::LAST_ID; i++){
|
||||
// See serverside equivalent, too much info was lost from some pools being over 255
|
||||
// (well I guess that's all there is to it)
|
||||
SAVE_STATE_ARY(ary_ammoTotal, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -381,6 +429,35 @@ player::PredictPostFrame(void)
|
|||
ROLL_BACK(shotgunReloadIndexQueued);
|
||||
ROLL_BACK(shotgunWaitingForPump);
|
||||
|
||||
ROLL_BACK(shotgunAddAmmoTime);
|
||||
ROLL_BACK(shotgunAddAmmoSoundTime);
|
||||
|
||||
//ROLL_BACK(doFiremodeChange);
|
||||
|
||||
ROLL_BACK(ary_myWeapons_softMax);
|
||||
for(int i = 0; i < ary_myWeapons_softMax; i++){
|
||||
ROLL_BACK(ary_myWeapons[i].weaponID);
|
||||
ROLL_BACK(ary_myWeapons[i].weaponTypeID);
|
||||
ROLL_BACK(ary_myWeapons[i].iBitsUpgrade);
|
||||
ROLL_BACK(ary_myWeapons[i].iCount);
|
||||
//ROLL_BACK(ary_myWeapons[i].iPrice);
|
||||
//ROLL_BACK(ary_myWeapons[i].iSlots);
|
||||
ROLL_BACK(ary_myWeapons[i].iClipLeft);
|
||||
ROLL_BACK(ary_myWeapons[i].iClipAkimboLeft);
|
||||
ROLL_BACK(ary_myWeapons[i].iBitsUpgrade_on);
|
||||
ROLL_BACK(ary_myWeapons[i].iFireMode);
|
||||
ROLL_BACK(ary_myWeapons[i].iFireModeAkimbo);
|
||||
ROLL_BACK(ary_myWeapons[i].iIronSight);
|
||||
ROLL_BACK(ary_myWeapons[i].forceBodygroup1Submodel);
|
||||
}
|
||||
|
||||
//UNNECESSARY. This array is of fixed length, so known at all times.
|
||||
//WriteByte(MSG_ENTITY, ary_ammoTotal_softMax);
|
||||
for(int i = 0; i < AMMO_ID::LAST_ID; i++){
|
||||
// See serverside equivalent, too much info was lost from some pools being over 255
|
||||
// (well I guess that's all there is to it)
|
||||
ROLL_BACK_ARY(ary_ammoTotal, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -497,6 +574,37 @@ player::EvaluateEntity(void)
|
|||
SAVE_STATE(shotgunReloadIndexQueued);
|
||||
SAVE_STATE(shotgunWaitingForPump);
|
||||
|
||||
SAVE_STATE(shotgunAddAmmoTime);
|
||||
SAVE_STATE(shotgunAddAmmoSoundTime);
|
||||
|
||||
//SAVE_STATE(doFiremodeChange);
|
||||
|
||||
|
||||
SAVE_STATE(ary_myWeapons_softMax);
|
||||
for(int i = 0; i < ary_myWeapons_softMax; i++){
|
||||
SAVE_STATE(ary_myWeapons[i].weaponID);
|
||||
SAVE_STATE(ary_myWeapons[i].weaponTypeID);
|
||||
SAVE_STATE(ary_myWeapons[i].iBitsUpgrade);
|
||||
SAVE_STATE(ary_myWeapons[i].iCount);
|
||||
//SAVE_STATE(ary_myWeapons[i].iPrice);
|
||||
//SAVE_STATE(ary_myWeapons[i].iSlots);
|
||||
SAVE_STATE(ary_myWeapons[i].iClipLeft);
|
||||
SAVE_STATE(ary_myWeapons[i].iClipAkimboLeft);
|
||||
SAVE_STATE(ary_myWeapons[i].iBitsUpgrade_on);
|
||||
SAVE_STATE(ary_myWeapons[i].iFireMode);
|
||||
SAVE_STATE(ary_myWeapons[i].iFireModeAkimbo);
|
||||
SAVE_STATE(ary_myWeapons[i].iIronSight);
|
||||
SAVE_STATE(ary_myWeapons[i].forceBodygroup1Submodel);
|
||||
}
|
||||
|
||||
//UNNECESSARY. This array is of fixed length, so known at all times.
|
||||
//WriteByte(MSG_ENTITY, ary_ammoTotal_softMax);
|
||||
for(int i = 0; i < AMMO_ID::LAST_ID; i++){
|
||||
// See serverside equivalent, too much info was lost from some pools being over 255
|
||||
// (well I guess that's all there is to it)
|
||||
SAVE_STATE_ARY(ary_ammoTotal, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -517,9 +625,6 @@ player::SendEntity(entity ePEnt, float fChanged)
|
|||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//TAGGG - REPLACED.
|
||||
/*
|
||||
// other players don't need to know about these attributes
|
||||
|
@ -539,6 +644,9 @@ player::SendEntity(entity ePEnt, float fChanged)
|
|||
|
||||
/* the generic client attributes */
|
||||
base_player::SendEntity(ePEnt, fChanged);
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
if (fChanged & PLAYER_TOPFRAME) {
|
||||
WriteByte(MSG_ENTITY, anim_top);
|
||||
|
@ -630,13 +738,17 @@ player::SendEntity(entity ePEnt, float fChanged)
|
|||
WriteByte(MSG_ENTITY, shotgunReloadIndexQueued );
|
||||
WriteByte(MSG_ENTITY, shotgunWaitingForPump );
|
||||
//WriteByte(MSG_ENTITY, shotgunReload2_ammoLoadDelay );
|
||||
//WriteByte(MSG_ENTITY, shotgunAddAmmoTime );
|
||||
//WriteByte(MSG_ENTITY, shotgunAddAmmoSoundTime );
|
||||
WriteFloat(MSG_ENTITY, shotgunAddAmmoTime );
|
||||
WriteFloat(MSG_ENTITY, shotgunAddAmmoSoundTime );
|
||||
|
||||
//WriteByte(MSG_ENTITY, doFiremodeChange);
|
||||
|
||||
WriteByte(MSG_ENTITY, currentZoomChoice + 1 );
|
||||
|
||||
|
||||
//weapondynamic_t ary_myWeapons[ary_myWeapons_length];
|
||||
WriteByte(MSG_ENTITY, ary_myWeapons_softMax );
|
||||
for(int i = 0; i < ary_myWeapons_softMax; i++){
|
||||
for(i = 0; i < ary_myWeapons_softMax; i++){
|
||||
WriteByte(MSG_ENTITY, ary_myWeapons[i].weaponID );
|
||||
WriteByte(MSG_ENTITY, ary_myWeapons[i].weaponTypeID );
|
||||
WriteByte(MSG_ENTITY, ary_myWeapons[i].iBitsUpgrade );
|
||||
|
@ -654,14 +766,12 @@ player::SendEntity(entity ePEnt, float fChanged)
|
|||
|
||||
//UNNECESSARY. This array is of fixed length, so known at all times.
|
||||
//WriteByte(MSG_ENTITY, ary_ammoTotal_softMax);
|
||||
for(int i = 0; i < AMMO_ID::LAST_ID; i++){
|
||||
for(i = 0; i < AMMO_ID::LAST_ID; i++){
|
||||
// using 'WriteLong' instead of 'WriteByte', because SOME AMMO POOL just had to
|
||||
// exceed 255, didn't it.
|
||||
WriteLong(MSG_ENTITY, ary_ammoTotal[i] );
|
||||
}
|
||||
|
||||
WriteByte(MSG_ENTITY, currentZoomChoice + 1 );
|
||||
|
||||
|
||||
|
||||
return (1);
|
||||
|
@ -680,6 +790,10 @@ player::player(void){
|
|||
// reasonable default?
|
||||
iState = PLAYER_STATE::NOCLIP;
|
||||
|
||||
#ifdef FIREMODE_PREDICTION_TEST
|
||||
ignoreFiremodeReceiveTime = -1;
|
||||
#endif
|
||||
|
||||
#ifdef SERVER
|
||||
money = 0; //safety?
|
||||
|
||||
|
@ -872,7 +986,9 @@ player::reset(BOOL resetInventory){
|
|||
shotgunReload2_ammoLoadDelay = -1;
|
||||
shotgunAddAmmoTime = -1;
|
||||
shotgunAddAmmoSoundTime = -1;
|
||||
|
||||
#ifdef CLIENT
|
||||
shotgunAddAmmoTime_cooldownSetTime = -1;
|
||||
#endif
|
||||
shotgunReload1_seq = -1;
|
||||
shotgunReload1_Duration = -1;
|
||||
shotgunReload2_seq = -1;
|
||||
|
@ -880,6 +996,8 @@ player::reset(BOOL resetInventory){
|
|||
shotgunReload3_seq = -1;
|
||||
shotgunReload3_Duration = -1;
|
||||
|
||||
doFiremodeChange = FALSE;
|
||||
|
||||
//Grenade stuff
|
||||
printfline("I set grenadeFireIndex to -1, D!");
|
||||
grenadeFireIndex = -1;
|
||||
|
@ -1192,6 +1310,30 @@ player::callWeaponThink(void){
|
|||
}
|
||||
|
||||
|
||||
// well that didn't work.
|
||||
/*
|
||||
BOOL
|
||||
player::shotgunAddAmmoTime_canSet(void){
|
||||
#ifdef CLIENT
|
||||
// require the cooldown
|
||||
// is cltime better? Unsure
|
||||
return (time >= shotgunAddAmmoTime_cooldownSetTime);
|
||||
#else
|
||||
// Server? Always
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
void
|
||||
player::shotgunAddAmmoTime_setCooldownSetTime(void){
|
||||
#ifdef CLIENT
|
||||
// do it
|
||||
shotgunAddAmmoTime_cooldownSetTime = time + 0.02f;
|
||||
#else
|
||||
// Server? I don't.
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef SERVER
|
||||
// runs every frame server-side. postthink, oddly enough, does not.
|
||||
|
|
|
@ -12,6 +12,31 @@
|
|||
|
||||
|
||||
|
||||
// Few config macros:
|
||||
|
||||
// If this is on, what's done for clientside on some commands (change firemode, change
|
||||
// buyoption toggleables) will be dummied or much simpler to avoid a slight flicker
|
||||
// seen in realistic packet delays (typical multiplayer).
|
||||
// Why doesn't the chage made just stay until server update? I have no idea.
|
||||
//#define CLIENT_CMD_SAFEMODE
|
||||
|
||||
|
||||
// Do testing to see my attempt to get prediction with firemodes working (default control:
|
||||
// F-key).
|
||||
// Or, obvious with a high cl_delay_packets choice (1000), the firemode flickers to the
|
||||
// new value and back to the old one, the full second has to pass for a delay_packets choice
|
||||
// of 1000, and then it stays at the new version. ...?
|
||||
// Why do messages keep coming back from the server to revert the firemode until the server
|
||||
// message comes back? Shouldn't it be the case that nothing happens to it until then?
|
||||
//#define FIREMODE_PREDICTION_TEST
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define NULL __NULL__
|
||||
|
||||
#define BOOL float
|
||||
|
@ -32,6 +57,12 @@
|
|||
// That means Nuclide's printf is only a shortener of print + sprintf for calls
|
||||
// without any other fill-ins (%d, etc.).
|
||||
// Undoing that here for now, compatible with original calls anytime.
|
||||
|
||||
// And do we care about bprint (broadcast-print)? Example:
|
||||
// bprint(PRINT_HIGH, sprintf("SSQC: %s", sWow) );
|
||||
// Probably not for debugging as printf is working fine for the typical rapid-fire
|
||||
// single player debug.
|
||||
|
||||
#ifdef printf
|
||||
#undef printf
|
||||
#endif
|
||||
|
|
|
@ -325,12 +325,12 @@ typedef struct{
|
|||
// TODO. make this a struct instead? should be feasible.
|
||||
// yes this is a class... hm. fix later.
|
||||
class weapondynamic_t{
|
||||
int weaponID; //what weapon is this referring to in the array of weapon data (glock, SOCOM, SMG, M4A1, etc.)
|
||||
int weaponTypeID; //what type of struct does the weapon use for convenient casting in lookups (gun, ironsight, melee, throwable)?
|
||||
PREDICTED_INT(weaponID); //what weapon is this referring to in the array of weapon data (glock, SOCOM, SMG, M4A1, etc.)
|
||||
PREDICTED_INT(weaponTypeID); //what type of struct does the weapon use for convenient casting in lookups (gun, ironsight, melee, throwable)?
|
||||
|
||||
// what did the player actually buy?
|
||||
// Also set this even for forced buyopts, such as the ruger's silencer.
|
||||
int iBitsUpgrade;
|
||||
PREDICTED_INT(iBitsUpgrade);
|
||||
|
||||
// How many of this weapon are equipped? The Akimbo BuyOpt makes this potentially 2.
|
||||
// Weapons that come akimbo (golden colts) will still treat this as "1".
|
||||
|
@ -338,39 +338,39 @@ class weapondynamic_t{
|
|||
// This is for whether the current weapon should be treated as one (golden colts drop together in one
|
||||
// model) or whether dropping just removes the akimbo version.
|
||||
// Throwing knives can also use this iCount to stack instead.
|
||||
int iCount;
|
||||
PREDICTED_INT(iCount);
|
||||
|
||||
//Does keeping track of these things on an actual inventory'd weapon even makes sense?
|
||||
//Ah well, lazy client-server logic compatability for now.
|
||||
int iPrice;
|
||||
int iSlots;
|
||||
PREDICTED_INT(iPrice);
|
||||
PREDICTED_INT(iSlots);
|
||||
|
||||
|
||||
int iClipLeft;
|
||||
int iClipAkimboLeft; //ammo left of the 2nd weapon if the akimbo option is present.
|
||||
PREDICTED_INT(iClipLeft);
|
||||
PREDICTED_INT(iClipAkimboLeft); //ammo left of the 2nd weapon if the akimbo option is present.
|
||||
|
||||
// Buyopts flashlight and lasersight can be toggled on/off. The rest don't need
|
||||
// to be part of this bitmask to be on at all times.
|
||||
int iBitsUpgrade_on;
|
||||
PREDICTED_INT(iBitsUpgrade_on);
|
||||
|
||||
|
||||
|
||||
// What firemode is the player using for this weapon now?
|
||||
int iFireMode;
|
||||
int iFireModeAkimbo;
|
||||
PREDICTED_INT(iFireMode);
|
||||
PREDICTED_INT(iFireModeAkimbo);
|
||||
|
||||
// Is the player using ironsight (right-click)? Also include checks for scoping / drawing overlays
|
||||
// in logic later if needed.
|
||||
// This is usually a boolean (0 or 1... off or on), but weapons with multiple magnifications can use
|
||||
// this to count too, such as for 2times or 10times. 0(off), 1(2x), 2(10x).
|
||||
int iIronSight;
|
||||
PREDICTED_INT(iIronSight);
|
||||
|
||||
// Do I force the first bodygroup's submodel to a certain choice?
|
||||
// NOTE - do not set to 0 during intended use! That is only a lazy default to say, don't do anything
|
||||
// to the submodel on drawing this weapon. Submodels actually start at 1, even if the only one.
|
||||
// If set to 0, the change will only be noticed on undrawing/drawing the weapon as the submodel will
|
||||
// not be applied then. Set to 1 to change in real time (likely the intention).
|
||||
int forceBodygroup1Submodel;
|
||||
PREDICTED_INT(forceBodygroup1Submodel);
|
||||
|
||||
|
||||
void(void) weapondynamic_t;
|
||||
|
@ -718,7 +718,6 @@ typedef struct{
|
|||
string sWorldModelPath;
|
||||
string sIconFilePath;
|
||||
|
||||
//!!!!!!!!!
|
||||
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttack;
|
||||
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnPrimaryAttackRelease;
|
||||
BOOL(player pl, weapondynamic_t arg_thisWeapon, BOOL hasAmmo) vOnSecondaryAttack;
|
||||
|
@ -732,7 +731,6 @@ typedef struct{
|
|||
void(player pl, weapondynamic_t arg_thisWeapon) vOnColdCock;
|
||||
|
||||
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
int iAnim_Idle_Index;
|
||||
|
||||
int iAnim_Deploy_Index;
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
weapon_t w_null = {};
|
||||
|
||||
// Populate each slot with a member of the enum early on in runtime instead.
|
||||
|
@ -35,9 +44,7 @@ weapon_base_setWholeAttackDelay(player pl, float amount){
|
|||
pl.w_attack_next = amount;
|
||||
pl.w_attack_akimbo_next = amount;
|
||||
|
||||
// I think this is a good idea, right?
|
||||
// or, is only for the client better? Turned out to be the case somewhere else...
|
||||
//#ifdef SERVER
|
||||
//#ifdef CLIENT
|
||||
//SAVE_STATE(pl.w_attack_next);
|
||||
//SAVE_STATE(pl.w_attack_akimbo_next);
|
||||
//#endif
|
||||
|
@ -421,6 +428,18 @@ BOOL
|
|||
weapon_shotgun_onInterrupt(
|
||||
player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon
|
||||
){
|
||||
if(pl.shotgunReloadIndex == 0){
|
||||
// not reloading, nothing to interrupt.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(pl.shotgunReloadIndex == 1 || pl.shotgunReloadIndex == 2){
|
||||
// pre-reload or shell-load sequences? Going to the end instead next time.
|
||||
pl.shotgunReloadIndex = 3;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if(pl.shotgunReloadIndex == 0){
|
||||
// nothing to interrupt.
|
||||
return FALSE;
|
||||
|
@ -436,6 +455,7 @@ weapon_shotgun_onInterrupt(
|
|||
pl.shotgunReloadIndexQueued = 3;
|
||||
}
|
||||
//}
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}// weapon_shotgun_onInterrupt
|
||||
|
@ -492,7 +512,6 @@ weapon_shotgun_reload(
|
|||
}
|
||||
|
||||
pl.isChangingIronsight = FALSE;
|
||||
SAVE_STATE(pl.isChangingIronsight);
|
||||
pl.currentZoomChoice = -1;
|
||||
pl.setZoom(1.00f);
|
||||
pl.aryNextBurstShotTime_softLength = 0;
|
||||
|
@ -503,7 +522,6 @@ weapon_shotgun_reload(
|
|||
//printfline("weapon_shotgun_reload %i %d", pl.shotgunReloadIndex, pl.shotgunPumpEndTime);
|
||||
pl.isReloading = TRUE;
|
||||
|
||||
pl.shotgunReloadIndex = 1;
|
||||
|
||||
//printfline("HERES THAT shotgunReload1_Duration %.2f", pl.shotgunReload1_Duration);
|
||||
weapon_base_setWholeAttackDelay(pl, pl.shotgunReload1_Duration);
|
||||
|
@ -511,11 +529,21 @@ weapon_shotgun_reload(
|
|||
pl.shotgunReloadIndexQueued = 2;
|
||||
|
||||
TS_Weapons_ViewAnimation(pl.shotgunReload1_seq, pl.shotgunReload1_Duration );
|
||||
pl.shotgunReloadIndex = 1;
|
||||
|
||||
}//weapon_shotgun_reload
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef CLIENT
|
||||
void viewEv_playShotgunInsertShellSound(void){
|
||||
player pl = (player)self;
|
||||
sound(pl, CHAN_AUTO, "weapons/insert-shell.wav", 1, ATTN_NONE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// NOTICE - shotguns with typical shotgun reload logic should use this method at all
|
||||
// times. It includes checks for whether the shotgun is actually reloading or not
|
||||
// (don't do anything if not of course)
|
||||
|
@ -525,103 +553,99 @@ weapon_shotgun_onThink_reloadLogic(player pl, weapondata_gun_t* basePRef, weapon
|
|||
|
||||
//printfline("FRAME att: %.2f", pl.w_attack_next);
|
||||
|
||||
if(pl.shotgunReloadIndex > 0){
|
||||
//reloading at all only.
|
||||
|
||||
if(pl.shotgunAddAmmoTime != -1 && pl.w_attack_next <= pl.shotgunAddAmmoTime){
|
||||
// add the ammo!!
|
||||
arg_thisWeapon.iClipLeft++;
|
||||
pl.ary_ammoTotal[baseRef.iAmmoDataID] -= 1;
|
||||
|
||||
if(pl.w_attack_next <= 0){
|
||||
//time has surpassed the time to the next phase? Check the pl.shotgunReloadIndexQueued.
|
||||
|
||||
pl.shotgunReloadIndex = pl.shotgunReloadIndexQueued;
|
||||
|
||||
|
||||
|
||||
//printfline("ack: %i", pl.shotgunReloadIndex);
|
||||
if(pl.shotgunReloadIndex == 0){
|
||||
//little bit of cleanup, since we're done reloading.
|
||||
pl.isReloading = FALSE;
|
||||
|
||||
|
||||
//printfline("shotgunWaitingForPump go BYEBYE 1");
|
||||
//if we were waiting for a pump, stop now. the anim did a pump by this point.
|
||||
pl.shotgunWaitingForPump = FALSE;
|
||||
|
||||
//NOTICE - an index of 0 should not be possible, we move away from it always.
|
||||
}else if(pl.shotgunReloadIndex == 2){
|
||||
//time to plug the bullets in
|
||||
|
||||
|
||||
if( arg_thisWeapon.iClipLeft >= baseRef.iClipMax || pl.ary_ammoTotal[baseRef.iAmmoDataID] <= 0 ){
|
||||
|
||||
pl.shotgunReloadIndex = 3;
|
||||
TS_Weapons_ViewAnimation(pl.shotgunReload3_seq, pl.shotgunReload3_Duration);
|
||||
weapon_base_setWholeAttackDelay(pl, pl.shotgunReload3_Duration);
|
||||
|
||||
|
||||
pl.shotgunReloadIndexQueued = 0;
|
||||
}else{
|
||||
// if we still have ammo left in the reserve,
|
||||
// AND the clip is not full, repeat, going to reload again.
|
||||
|
||||
TS_Weapons_ViewAnimation(pl.shotgunReload2_seq, pl.shotgunReload2_Duration);
|
||||
|
||||
pl.shotgunReloadIndex = 2;
|
||||
weapon_base_setWholeAttackDelay(pl, pl.shotgunReload2_Duration);
|
||||
|
||||
pl.shotgunReloadIndexQueued = 2;
|
||||
|
||||
// 2.0 - 0.3 = 1.7
|
||||
// idea: set shotgunAddAmmoTime to the w_attack_next (total duration of the anim) minus ammoLoadDelay,
|
||||
// since w_attack_next counts down. When w_attack_next goes below shotgunAddAmmoTime, that means
|
||||
// the "shotgunReload2_ammoLoadDelay" amount of time has passed, same thing, better for networking.
|
||||
//// pl.shotgunAddAmmoTime = time + pl.shotgunReload2_ammoLoadDelay;
|
||||
pl.shotgunAddAmmoTime = pl.w_attack_next - pl.shotgunReload2_ammoLoadDelay;
|
||||
|
||||
|
||||
pl.shotgunAddAmmoSoundTime = time + pl.shotgunReload2_ammoLoadDelay - 0.03f;
|
||||
}
|
||||
|
||||
|
||||
}else if(pl.shotgunReloadIndex == 3){
|
||||
//end anim
|
||||
|
||||
TS_Weapons_ViewAnimation(pl.shotgunReload3_seq, pl.shotgunReload3_Duration);
|
||||
weapon_base_setWholeAttackDelay(pl, pl.shotgunReload3_Duration);
|
||||
|
||||
pl.shotgunReloadIndexQueued = 0;
|
||||
}
|
||||
|
||||
}// w_attack_next <= 0
|
||||
printfline("I ADDED AMMO TO SHOTGUN. %i - %i", arg_thisWeapon.iClipLeft, pl.ary_ammoTotal[baseRef.iAmmoDataID]);
|
||||
|
||||
|
||||
if(pl.shotgunReloadIndex == 2){
|
||||
|
||||
////if(pl.shotgunAddAmmoTime != -1 && time >= pl.shotgunAddAmmoTime){
|
||||
if(pl.shotgunAddAmmoTime != -1 && pl.w_attack_next <= pl.shotgunAddAmmoTime){
|
||||
//add the ammo!!
|
||||
|
||||
arg_thisWeapon.iClipLeft++;
|
||||
pl.ary_ammoTotal[baseRef.iAmmoDataID] -= 1;
|
||||
|
||||
#ifdef CLIENT
|
||||
sound(pl, CHAN_ITEM, "weapons/insert-shell.wav", 1, ATTN_NONE);
|
||||
#endif
|
||||
|
||||
pl.shotgunAddAmmoTime = -1; //don't keep doing it.
|
||||
}
|
||||
if(pl.shotgunAddAmmoSoundTime != -1 && time >= pl.shotgunAddAmmoSoundTime){
|
||||
//TS_PlayInsertShellSound(pl);
|
||||
pl.shotgunAddAmmoSoundTime = -1;
|
||||
}
|
||||
|
||||
}
|
||||
pl.shotgunAddAmmoTime = -1; //don't keep doing it.
|
||||
}
|
||||
|
||||
if(pl.w_attack_next <= 0){
|
||||
// little copy from base think logic, since we're replacing it for shotguns.
|
||||
if(pl.isChangingIronsight){
|
||||
weapon_gun_endOfIronSight(pl, basePRef, arg_thisWeapon);
|
||||
}
|
||||
if(pl.shotgunAddAmmoSoundTime != -1 && pl.w_attack_next <= pl.shotgunAddAmmoSoundTime){
|
||||
|
||||
//TS_PlayInsertShellSound(pl);
|
||||
//TS_Weapons_PlaySoundChannelDirect(pl, "weapons/insert-shell.wav", CHAN_AUTO);
|
||||
|
||||
// TODO: if you want other players to hear this, the server should play it for all players
|
||||
// except the localone here because it already played clientside, again with a delay would be
|
||||
// pointless for the one that already heard it.
|
||||
/*
|
||||
#ifdef CLIENT
|
||||
sound(pl, CHAN_AUTO, "weapons/insert-shell.wav", 1, ATTN_NONE);
|
||||
#endif
|
||||
*/
|
||||
|
||||
pl.shotgunAddAmmoSoundTime = -1;
|
||||
}
|
||||
|
||||
|
||||
if(pl.w_attack_next > 0.0){
|
||||
return;
|
||||
}
|
||||
|
||||
// in case this weapon is ironsight.
|
||||
if(pl.isChangingIronsight){
|
||||
weapon_gun_endOfIronSight(pl, basePRef, arg_thisWeapon);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pl.shotgunReloadIndex == 0){
|
||||
// nothing to do here
|
||||
}else if(pl.shotgunReloadIndex == 1 || pl.shotgunReloadIndex == 2){
|
||||
// end of pre-reload anim (bringing the shotgun into place) or a shell-load anim.
|
||||
// Same thing wanted in either case: start another shell-load anim
|
||||
|
||||
printfline("w_attack_next pass!!!");
|
||||
|
||||
|
||||
if (pl.ary_ammoTotal[baseRef.iAmmoDataID] <= 0 || arg_thisWeapon.iClipLeft >= baseRef.iClipMax) {
|
||||
//pl.shotgunReloadIndex = 3;
|
||||
|
||||
//if(pl.shotgunAddAmmoTime_canSet()){
|
||||
// pl.shotgunAddAmmoTime_setCooldownSetTime();
|
||||
TS_Weapons_ViewAnimation(pl.shotgunReload3_seq, pl.shotgunReload3_Duration);
|
||||
weapon_base_setWholeAttackDelay(pl, pl.shotgunReload3_Duration);
|
||||
pl.shotgunReloadIndex = 0;
|
||||
pl.isReloading = FALSE;
|
||||
//}
|
||||
}else{
|
||||
TS_Weapons_ViewAnimation(pl.shotgunReload2_seq, pl.shotgunReload2_Duration);
|
||||
weapon_base_setWholeAttackDelay(pl, pl.shotgunReload2_Duration);
|
||||
pl.shotgunReloadIndex = 2;
|
||||
|
||||
|
||||
|
||||
//if(pl.shotgunAddAmmoTime_canSet()){
|
||||
// pl.shotgunAddAmmoTime_setCooldownSetTime();
|
||||
printfline("I SET shotgunAddAmmoTime!");
|
||||
|
||||
//View_AddEvent(w_ejectshell_pistol, pl.w_attack_next - pl.shotgunReload2_ammoLoadDelay);
|
||||
#ifdef CLIENT
|
||||
View_AddEvent(viewEv_playShotgunInsertShellSound, pl.shotgunReload2_Duration - (pl.shotgunReload2_ammoLoadDelay - 0.03f));
|
||||
#endif
|
||||
pl.shotgunAddAmmoTime = pl.shotgunReload2_Duration - pl.shotgunReload2_ammoLoadDelay;
|
||||
//pl.shotgunAddAmmoSoundTime = pl.shotgunReload2_Duration - (pl.shotgunReload2_ammoLoadDelay - 0.03f);
|
||||
//}
|
||||
|
||||
|
||||
//arg_thisWeapon.iClipLeft++;
|
||||
//pl.ary_ammoTotal[baseRef.iAmmoDataID]--;
|
||||
|
||||
}
|
||||
|
||||
}else if(pl.shotgunReloadIndex == 3){
|
||||
// end of reload anim wanted!
|
||||
TS_Weapons_ViewAnimation(pl.shotgunReload3_seq, pl.shotgunReload3_Duration);
|
||||
weapon_base_setWholeAttackDelay(pl, pl.shotgunReload3_Duration);
|
||||
pl.shotgunReloadIndex = 0;
|
||||
// this will be true when the fire delay expires, but doesn't hurt happening earlier.
|
||||
pl.isReloading = FALSE;
|
||||
}
|
||||
|
||||
|
||||
}//weapon_shotgun_onThink_reloadLogic
|
||||
|
||||
|
||||
|
@ -1143,7 +1167,6 @@ weapon_ironsight_ToggleIronsight(
|
|||
printfline("time: %.2f weapon_ironsight_ToggleIronsight PASS. CURRENT:%i", time, arg_thisWeapon.iIronSight);
|
||||
|
||||
pl.isChangingIronsight = TRUE;
|
||||
SAVE_STATE(pl.isChangingIronsight);
|
||||
|
||||
//TAGGG - QUESTION.
|
||||
// Why does only from ironSight == 0, going towards 1, use the "_EndIdle" version, but
|
||||
|
@ -1202,7 +1225,6 @@ weapon_gun_Reload(
|
|||
}
|
||||
|
||||
pl.isChangingIronsight = FALSE;
|
||||
SAVE_STATE(pl.isChangingIronsight);
|
||||
pl.currentZoomChoice = -1;
|
||||
pl.setZoom(1.00f);
|
||||
pl.aryNextBurstShotTime_softLength = 0;
|
||||
|
@ -1247,7 +1269,6 @@ weapon_gun_Reload_CustomSequence(
|
|||
}
|
||||
|
||||
pl.isChangingIronsight = FALSE;
|
||||
SAVE_STATE(pl.isChangingIronsight);
|
||||
pl.currentZoomChoice = -1;
|
||||
pl.setZoom(1.00f);
|
||||
pl.aryNextBurstShotTime_softLength = 0;
|
||||
|
@ -1295,7 +1316,6 @@ weapon_ironsight_Reload(
|
|||
}
|
||||
|
||||
pl.isChangingIronsight = FALSE;
|
||||
SAVE_STATE(pl.isChangingIronsight);
|
||||
pl.currentZoomChoice = -1;
|
||||
pl.setZoom(1.00f);
|
||||
pl.aryNextBurstShotTime_softLength = 0;
|
||||
|
@ -1377,7 +1397,6 @@ weapon_gun_endOfIronSight(
|
|||
}
|
||||
|
||||
pl.isChangingIronsight = FALSE;
|
||||
SAVE_STATE(pl.isChangingIronsight);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -167,7 +167,6 @@ w_benellim3_holster(void)
|
|||
void
|
||||
w_benellim3_primary(void)
|
||||
{
|
||||
float randomChoice;
|
||||
player pl = (player)self;
|
||||
weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex];
|
||||
|
||||
|
@ -178,11 +177,13 @@ w_benellim3_primary(void)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
// good place? should this go above onInterrupt above?
|
||||
if (pl.w_attack_next > 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(arg_thisWeapon.iFireMode == BITS_FIREMODE_SEMI){
|
||||
INPUT_PRIMARY_TAP_GATE
|
||||
}
|
||||
|
@ -200,8 +201,10 @@ w_benellim3_primary(void)
|
|||
View_AddEvent(w_ejectshell_pistol, 0.0f);
|
||||
#endif
|
||||
|
||||
randomChoice = random();
|
||||
if(randomChoice > 0.5){
|
||||
// float randomChoice = random();
|
||||
// why the cast to float here? No idea
|
||||
int r = (float)input_sequence % 2;
|
||||
if(r == 0){
|
||||
TS_Weapons_ViewAnimation(weaponseq_benellim3::pump, 29.0f/35.0f);
|
||||
}else{
|
||||
TS_Weapons_ViewAnimation(weaponseq_benellim3::pump2, 25.0f/35.0f);
|
||||
|
|
|
@ -180,7 +180,6 @@ w_mossberg500_holster(void)
|
|||
void
|
||||
w_mossberg500_primary(void)
|
||||
{
|
||||
float randomChoice;
|
||||
player pl = (player)self;
|
||||
weapondynamic_t arg_thisWeapon = pl.ary_myWeapons[pl.inventoryEquippedIndex];
|
||||
|
||||
|
@ -219,8 +218,8 @@ w_mossberg500_primary(void)
|
|||
if(!arg_thisWeapon.iIronSight){
|
||||
TS_Weapons_ViewAnimation(weaponseq_mossberg500::pump, 31.0f/35.0f);
|
||||
}else{
|
||||
randomChoice = random();
|
||||
if(randomChoice > 0.5){
|
||||
int r = (float)input_sequence % 2;
|
||||
if(r == 0){
|
||||
TS_Weapons_ViewAnimation(weaponseq_mossberg500::pumpb, 31.0f/35.0f);
|
||||
}else{
|
||||
TS_Weapons_ViewAnimation(weaponseq_mossberg500::pumpb2, 31.0f/35.0f);
|
||||
|
|
|
@ -203,8 +203,8 @@ w_spas12_primary(void)
|
|||
View_AddEvent(w_ejectshell_pistol, 0.0f);
|
||||
#endif
|
||||
|
||||
randomChoice = random();
|
||||
if(randomChoice > 0.5){
|
||||
int r = (float)input_sequence % 2;
|
||||
if(r == 0){
|
||||
TS_Weapons_ViewAnimation(weaponseq_spas12::pump, 31.0f/35.0f);
|
||||
}else{
|
||||
TS_Weapons_ViewAnimation(weaponseq_spas12::pump2, 31.0f/35.0f);
|
||||
|
|
Loading…
Reference in a new issue