diff --git a/src/client/cmds.qc b/src/client/cmds.qc index b0a3d24..0f2af63 100644 --- a/src/client/cmds.qc +++ b/src/client/cmds.qc @@ -37,14 +37,12 @@ ClientGame_ConsoleCommand(void) case "getangle": sendevent("TS_Debug_getAngle", ""); break; - case "firemode": - TS_playerChangeFiremode(); - //pSeatLocal->m_bFireModeFreshPress = TRUE; + case "+firemode": + Input_firemode_press(); + break; + case "-firemode": + Input_firemode_release(); break; - - //case "useitems" - // TS_playerUseItems(); - // break; case "+useitems": Input_useItems_press(); break; @@ -124,7 +122,6 @@ ClientGame_ConsoleCommand(void) TS_playerDropWeapon(); //I do it fine. break; - default: return (0); } diff --git a/src/client/draw.qc b/src/client/draw.qc index 33dce72..cd4b0d2 100644 --- a/src/client/draw.qc +++ b/src/client/draw.qc @@ -34,11 +34,8 @@ void ClientGame_PreDraw(void) { player pl = (player)pSeat->m_ePlayer; - // TODO: may as well make TS_View_HandleZoom a player method at this point, - // do the state check inside player then - if(pl.iState == PLAYER_STATE::SPAWNED){ - TS_View_HandleZoom(); - } + + pl.handleZoom(); pl.viewzoom = pl.flZoomCurrent; @@ -60,6 +57,12 @@ ClientGame_PreDraw(void) } //////////////////////////////////////////////////////////////////// + + // save the view_angles before adding in the predicted frame-total view kickback + // from pl.vViewAngleOffset. + view_angles_unmodified = view_angles; + view_angles += pl.vViewAngleOffsetTotalChange; + }//ClientGame_PreDraw @@ -77,6 +80,8 @@ Custom_LatePreDraw(void) int thirdperson = (autocvar_cl_thirdperson == TRUE || pl.entnum != player_localentnum); TS_View_DrawExtraEffects(pl, thirdperson); + // restore. + view_angles = view_angles_unmodified; } @@ -141,7 +146,7 @@ TS_HUD_drawPainArrows(void) drawpic(center + [-102,-64], g_damage_spr_l, [48,128], [1,1,1], rt_alpha, DRAWFLAG_ADDITIVE); } - + } diff --git a/src/client/game_event.qc b/src/client/game_event.qc index 2ce8b38..e388b4f 100644 --- a/src/client/game_event.qc +++ b/src/client/game_event.qc @@ -212,6 +212,12 @@ ClientGame_EventParse(float fHeader) Custom_Prediction_Server_Callback(pl); }break; #endif + + case EVENT_TS::VIEWANGLES_REQUEST:{ + + sendevent("ViewAnglesR", "fff", view_angles.x, view_angles.y, view_angles.z); + }break; + case EVENT_TS::TEST:{ //printfline("EVENT_TS::TEST HAPPENED"); diff --git a/src/client/seatlocal.h b/src/client/seatlocal.h index 9f214e0..ac9325d 100644 --- a/src/client/seatlocal.h +++ b/src/client/seatlocal.h @@ -45,12 +45,8 @@ struct float m_flBlockSpawnInputTime; - BOOL m_bUseItemsFreshPress; - // How many times has the use button been pressed before getting a server callback? - // Also need to handle determining what in a server callback lets this be reduced - int m_iUseItemsLatencyPresses; - BOOL m_bUseItems; + BOOL m_bChangeFiremode; } g_seatslocal[4], *pSeatLocal; diff --git a/src/client/view.h b/src/client/view.h index 5592885..2f61057 100644 --- a/src/client/view.h +++ b/src/client/view.h @@ -10,5 +10,3 @@ void TS_View_ResetViewModel(void); void TS_View_DrawCustom(player pl); void TS_View_DrawExtraEffects(player pl, int thirdperson); void TS_View_ShowMuzzleflash(int index, int akimboChoice); - -void TS_View_HandleZoom(void); diff --git a/src/client/view.qc b/src/client/view.qc index 2f2cd9e..2aaf31f 100644 --- a/src/client/view.qc +++ b/src/client/view.qc @@ -571,8 +571,6 @@ TS_View_DrawExtraEffects(player pl, int thirdperson) posView = pSeat->m_vecPredictedOrigin + pl.view_ofs; angView = view_angles; - angView = view_angles; - // CHECK: is "getproperty(VF_CL_VIEWANGLES)" always the same as "view_angles"? if(!pl.weaponEquippedAkimbo){ @@ -743,84 +741,3 @@ TS_View_ShowMuzzleflash(int index, int akimboChoice) } } - - -//TAGGG - loaned from The Wastes. -void TS_View_HandleZoom(void) -{ - player pl = (player)pSeat->m_ePlayer; - - if(pl == NULL){ - return; - } - - // test - /* - pl.flZoomCurrent = pl.flZoomTarget; - pl.viewzoom = pl.flZoomTarget; - printfline("flZoomTarget: %.2f", pl.flZoomTarget); - return; - */ - - //printfline("WHATS GOING ON %.2f %.2f %.2f %.2f %.2f", pl.flZoomEnd, pl.flZoomTarget, pl.flZoomStart, pl.flZoomLerp, pl.flZoomCurrent); - - // - No other codebase refers to STAT_VIEWZOOM, best to replace anything - // involving that. - - // in case of some unexpected change. - // TODO: this might have an issue if the player were to change weapons and end up - // on the same zoom level as a previous weapon, despite the two weapons having - // different target values (like 0.4 vs. 0.6) at their own zoom level #1's. - // A check for being a different equipped weapon type - // (pl.activeweapon vs. pl.activeweapon_zoomprev, set only by setZoomLevel) - // ought to work. But that would be a very strange case anyway - if(pl.iZoomLevel != pl.iZoomLevelPrev){ - pl.setZoomLevel(pl.iZoomLevel); - } - - if (pl.flZoomEnd != pl.flZoomTarget ) { - //printfline("NEW ZOOM DETECTED: %.2f -> %.2f (zoomlev: %i)", pl.flZoomEnd, pl.flZoomTarget, pl.iZoomLevel); - - // is setting flZoomStart to flZoomEnd or flZoomCurrent a better idea? - // at flZoomEnd means, on changing before the current lerp has finished, it jumps to beginning - // at the end point of the lerp in progress. But starting at flZoomCurrent might be smoother? - // if it isn't glitchy that could be nice. Trying that out. - - pl.flZoomStart = pl.flZoomCurrent; - //pl.flZoomStart = pl.flZoomEnd; - - pl.flZoomEnd = pl.flZoomTarget; - pl.flZoomLerp = 0.0f; - } - - if (pl.flZoomLerp < 1.0f) { - // Slow this down for debugging purposes, this is meant to be fast. - // 0.8 can be safe. - // The Wastes default was 4. - - // !!! clframetime, frametime, or input_timelength ? - pl.flZoomLerp += clframetime * 5.7; - - if(pl.flZoomLerp >= 1.0){ - //enforce the cap. - pl.flZoomLerp = 1.0; - } - - //pl.flZoomCurrent = getstatf(STAT_VIEWZOOM); - pl.flZoomCurrent = Math_Lerp(pl.flZoomStart, pl.flZoomEnd, pl.flZoomLerp); - } - - // Set this, since Nuclide will read it in and apply instantly. - // So same effect without having to edit Nuclide, this pipes it over for it - // to do the setproperty thing below to apply - //pl.viewzoom = pl.flZoomCurrent; - - ////setproperty(VF_AFOV, DEFAULT_FOV * pl.flZoomCurrent); - ////setsensitivityscaler(pl.flZoomCurrent); - - // here's the way old FreeCS did it - //setproperty(VF_AFOV, cvar("fov") * pl.viewzoom); - //setsensitivityscaler(pl.viewzoom); -} - - diff --git a/src/shared/defs.h b/src/shared/defs.h index de8d28e..3273d2b 100644 --- a/src/shared/defs.h +++ b/src/shared/defs.h @@ -90,10 +90,6 @@ enum { var float autocvar_movemodmulti = 1; -//float Game_GetFriction(entity eTarget); -//float Game_GetMaxSpeed( entity eTarget ); - - // Prototype for weapons_common.qc method(s)! // For things here to be aware of these earlier void Weapons_Draw(void); @@ -101,22 +97,26 @@ void Weapons_Holster(void); -#if OTHER_PREDICTION_TEST == 1 #ifdef CLIENT -// test -void Custom_Prediction_Server_Callback(player pl); -void Custom_Predict_EntityUpdate(player pl); -void Custom_Predict_PlayerPreFrame(player pl); -void Custom_Predict_PlayerPostFrame(player pl); -var float custom_input_sequence = 0; -var float custom_clientcommandframe = 0; -var float custom_servercommandframe = 0; -#else -var float custom_servercommandframe = 0; -void Custom_EvaluateEntity(player pl); +var BOOL canPlaySwitchSound = FALSE; +var vector view_angles_unmodified; #endif -#elif OTHER_PREDICTION_TEST == 2 -//var BOOL isFreshInput = FALSE; + +#if OTHER_PREDICTION_TEST == 1 +#ifdef CLIENT + // test + void Custom_Prediction_Server_Callback(player pl); + void Custom_Predict_EntityUpdate(player pl); + void Custom_Predict_PlayerPreFrame(player pl); + void Custom_Predict_PlayerPostFrame(player pl); + var float custom_input_sequence = 0; + var float custom_clientcommandframe = 0; + var float custom_servercommandframe = 0; +#else + var float custom_servercommandframe = 0; + void Custom_EvaluateEntity(player pl); +#endif #endif//OTHER_PREDICTION_TEST + diff --git a/src/shared/event_custom.h b/src/shared/event_custom.h index a371a9c..0793904 100644 --- a/src/shared/event_custom.h +++ b/src/shared/event_custom.h @@ -64,14 +64,10 @@ void CSEv_TS_playerDropWeapon_(void); #ifdef SERVER -void CSEv_TS_playerChangeFiremode_(void); #endif void TS_playerChangeFiremode(void); void _TS_playerChangeFiremode(void ) -#ifdef SERVER -void CSEv_TS_playerUseItems_(void); -#endif void TS_playerUseItems(void); void _TS_playerUseItems(void); diff --git a/src/shared/event_custom.qc b/src/shared/event_custom.qc index 8ac9877..71ccefa 100644 --- a/src/shared/event_custom.qc +++ b/src/shared/event_custom.qc @@ -475,21 +475,6 @@ 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 - // For now, only the client will expect direct calls to these. // Client sends the input, server receives a message in response to perform things on // its end too. @@ -500,20 +485,9 @@ TS_playerChangeFiremode(void){ return; } -#ifdef CLIENT - sendevent("TS_playerChangeFiremode", ""); - -#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 + // always now + _TS_playerChangeFiremode(); + } @@ -523,11 +497,6 @@ _TS_playerChangeFiremode(void ) { 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); @@ -540,13 +509,10 @@ _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){ @@ -580,11 +546,6 @@ _TS_playerChangeFiremode(void ) { //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; } @@ -598,21 +559,6 @@ _TS_playerChangeFiremode(void ) { -#ifdef SERVER -// Server receives the message -void -CSEv_TS_playerUseItems_(void){ - player pl = (player)self; - _TS_playerUseItems(); - - // Send a message back too! - WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET ); - WriteByte( MSG_MULTICAST, EVENT_TS::USEITEMS_CHANGE_CALLBACK ); - msg_entity = pl; - multicast( [0,0,0], MULTICAST_ONE ); - -} -#endif // For now, only the client will expect direct calls to these. // Client sends the input, server receives a message in response to perform things on its end too. @@ -648,77 +594,62 @@ void _TS_playerUseItems(void){ player pl = (player)self; + + weapondynamic_t dynaRef = pl.ary_myWeapons[pl.inventoryEquippedIndex]; - - if(pl.inventoryEquippedIndex != -1){ - - weapondynamic_t dynaRef = pl.ary_myWeapons[pl.inventoryEquippedIndex]; + if(dynaRef.weaponTypeID == WEAPONDATA_TYPEID_GUN || dynaRef.weaponTypeID == WEAPONDATA_TYPEID_IRONSIGHT){ + weapondata_basic_t* basicP = pl.getEquippedWeaponData(); - if(dynaRef.weaponTypeID == WEAPONDATA_TYPEID_GUN || dynaRef.weaponTypeID == WEAPONDATA_TYPEID_IRONSIGHT){ - weapondata_basic_t* basicP = pl.getEquippedWeaponData(); - - int legalBuyOpts = (dynaRef.iBitsUpgrade & (*basicP).iBitsUpgrade) & (BITMASK_WEAPONOPT_TOGGLEABLE); - // We must have the flashlight bit on, AND support it on our weapon, AND it be a possibility according to weapon data. - int legalBuyOpts_on = (dynaRef.iBitsUpgrade_on & legalBuyOpts); + int legalBuyOpts = (dynaRef.iBitsUpgrade & (*basicP).iBitsUpgrade) & (BITMASK_WEAPONOPT_TOGGLEABLE); + // We must have the flashlight bit on, AND support it on our weapon, AND it be a possibility according to weapon data. + int legalBuyOpts_on = (dynaRef.iBitsUpgrade_on & legalBuyOpts); + + + int bitCount = count1Bits(legalBuyOpts, BITMASK_WEAPONOPT_TOGGLEABLE_MIN, BITMASK_WEAPONOPT_TOGGLEABLE_MAX); + int bitCount_on = count1Bits(legalBuyOpts_on, BITMASK_WEAPONOPT_TOGGLEABLE_MIN, BITMASK_WEAPONOPT_TOGGLEABLE_MAX); + + int firstBit; + int firstBit_on; + + if(bitCount == 0){ + //no togglable buyopts at all? I guess that's it. + }else{ - int bitCount = count1Bits(legalBuyOpts, BITMASK_WEAPONOPT_TOGGLEABLE_MIN, BITMASK_WEAPONOPT_TOGGLEABLE_MAX); - int bitCount_on = count1Bits(legalBuyOpts_on, BITMASK_WEAPONOPT_TOGGLEABLE_MIN, BITMASK_WEAPONOPT_TOGGLEABLE_MAX); - - int firstBit; - int firstBit_on; - - if(bitCount == 0){ - //no togglable buyopts at all? I guess that's it. - }else{ - - - -#if defined(CLIENT_CMD_SAFEMODE) - // 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){ - dynaRef.iBitsUpgrade_on = 0; - }else{ - dynaRef.iBitsUpgrade_on = legalBuyOpts; - } - + if(bitCount == 1){ + //one bit available? just toggle on/off then. + if(bitCount_on){ + dynaRef.iBitsUpgrade_on = 0; }else{ - //variable number of bits? See how many bits are on right now. - if(bitCount_on == 0){ - // No bits on? - // Turn the first one on. - firstBit = findFirst1Bit(legalBuyOpts, BITMASK_WEAPONOPT_TOGGLEABLE_MIN, BITMASK_WEAPONOPT_TOGGLEABLE_MAX); - dynaRef.iBitsUpgrade_on |= firstBit; - }else if(bitCount_on == 1){ - // If we're not the last bit, turn the next one on. - // Start by looking at the next bit (bit << 1) - firstBit_on = findFirst1Bit(legalBuyOpts, legalBuyOpts_on << 1, BITMASK_WEAPONOPT_TOGGLEABLE_MAX); - - if(firstBit_on != 0){ - //we'll take it! - dynaRef.iBitsUpgrade_on = firstBit_on; - }else{ - //ran out of available bits? Take them all. - dynaRef.iBitsUpgrade_on = legalBuyOpts; - } - }else{ - //more than 1? Turn them all off then. - dynaRef.iBitsUpgrade_on = 0; - } + dynaRef.iBitsUpgrade_on = legalBuyOpts; } - - - // Let's be a clientside sound only. + }else{ + //variable number of bits? See how many bits are on right now. + if(bitCount_on == 0){ + // No bits on? + // Turn the first one on. + firstBit = findFirst1Bit(legalBuyOpts, BITMASK_WEAPONOPT_TOGGLEABLE_MIN, BITMASK_WEAPONOPT_TOGGLEABLE_MAX); + dynaRef.iBitsUpgrade_on |= firstBit; + }else if(bitCount_on == 1){ + // If we're not the last bit, turn the next one on. + // Start by looking at the next bit (bit << 1) + firstBit_on = findFirst1Bit(legalBuyOpts, legalBuyOpts_on << 1, BITMASK_WEAPONOPT_TOGGLEABLE_MAX); + + if(firstBit_on != 0){ + //we'll take it! + dynaRef.iBitsUpgrade_on = firstBit_on; + }else{ + //ran out of available bits? Take them all. + dynaRef.iBitsUpgrade_on = legalBuyOpts; + } + }else{ + //more than 1? Turn them all off then. + dynaRef.iBitsUpgrade_on = 0; + } + } + + // Let's be a clientside sound only. #ifdef CLIENT @@ -726,79 +657,42 @@ _TS_playerUseItems(void){ // enforce a check that this is the first inputframe, not repeats, to avoid sound spam if(custom_input_sequence==custom_clientcommandframe){ #elif OTHER_PREDICTION_TEST == 2 -//if(input_sequence==clientcommandframe){ -//if(isFreshInput){ -if(0){ // never do it here, elsewhere instead + +if(canPlaySwitchSound){ +// only happens once, not during prediction rewinds. +// that would get spammy +canPlaySwitchSound = FALSE; #else // nothing special if(1){ #endif - localsound("weapons/switch.wav", CHAN_AUTO, 1.0f); + localsound("weapons/switch.wav", CHAN_AUTO, 1.0f); } #endif - - - // (METHOD MADE SINCE: TS_Weapons_PlaySoundChannelDirect) - - // Any bits? Play this sound, some change happened - //sound(pl, CHAN_ITEM, "weapons/switch.wav", 1, ATTN_NONE, 100.0f, SOUNDFLAG_PLAYER_SHARED, 0); - - /* - // unicast demo . Why does the sound play clientside the first few times anyway? - // It shouldn't ever, with the clientside-call here disabled. + + + // (METHOD MADE SINCE: TS_Weapons_PlaySoundChannelDirect) + + // Any bits? Play this sound, some change happened + //sound(pl, CHAN_ITEM, "weapons/switch.wav", 1, ATTN_NONE, 100.0f, SOUNDFLAG_PLAYER_SHARED, 0); + + /* + // unicast demo . Why does the sound play clientside the first few times anyway? + // It shouldn't ever, with the clientside-call here disabled. #ifdef CLIENT - //sound(pl, CHAN_ITEM, "weapons/switch.wav", 1, ATTN_NONE, 100.0f, SOUNDFLAG_NONE, 0); + //sound(pl, CHAN_ITEM, "weapons/switch.wav", 1, ATTN_NONE, 100.0f, SOUNDFLAG_NONE, 0); #else - sound(pl, CHAN_ITEM, "weapons/switch.wav", 1, ATTN_NONE, 100.0f, SOUNDFLAG_UNICAST, 0); + sound(pl, CHAN_ITEM, "weapons/switch.wav", 1, ATTN_NONE, 100.0f, SOUNDFLAG_UNICAST, 0); #endif - */ - }// bitcount checks - - - }// _GUN or _IRONSIGHT type checks - }// weaponEquippedID check - - -} - - - -// TEST, might get abandoned -#ifdef CLIENT -void -_TS_FRESH_playerUseItems(void){ - player pl = (player)self; - - printfline("CSEv_TS_playerUseItems_"); - - sendevent("TS_playerUseItems", ""); - - - if(pl.inventoryEquippedIndex != -1){ - - weapondynamic_t dynaRef = pl.ary_myWeapons[pl.inventoryEquippedIndex]; + */ + }// bitcount checks - if(dynaRef.weaponTypeID == WEAPONDATA_TYPEID_GUN || dynaRef.weaponTypeID == WEAPONDATA_TYPEID_IRONSIGHT){ - weapondata_basic_t* basicP = pl.getEquippedWeaponData(); - - - int legalBuyOpts = (dynaRef.iBitsUpgrade & (*basicP).iBitsUpgrade) & (BITMASK_WEAPONOPT_TOGGLEABLE); - int bitCount = count1Bits(legalBuyOpts, BITMASK_WEAPONOPT_TOGGLEABLE_MIN, BITMASK_WEAPONOPT_TOGGLEABLE_MAX); - - if(bitCount == 0){ - - }else{ - // Let's be a clientside sound only. -//#ifdef CLIENT - localsound("weapons/switch.wav", CHAN_AUTO, 1.0f); -//#endif - } - - }// _GUN or _IRONSIGHT type checks - }// weaponEquippedID check + + }// _GUN or _IRONSIGHT type checks + } -#endif + diff --git a/src/shared/event_enum.h b/src/shared/event_enum.h index 67a3fd2..d692d2e 100644 --- a/src/shared/event_enum.h +++ b/src/shared/event_enum.h @@ -17,6 +17,8 @@ enum EVENT_TS{ USEITEMS_CHANGE_CALLBACK, CUSTOM_PREDICTION_CALLBACK, + + VIEWANGLES_REQUEST, TEST, }; diff --git a/src/shared/input.qc b/src/shared/input.qc index fd4b4e5..ad09b29 100644 --- a/src/shared/input.qc +++ b/src/shared/input.qc @@ -157,30 +157,10 @@ Game_Input(void) */ -#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 - // TS way, weapon thinks happen alongside checking inputs pl.callWeaponThink(); - /* - if(pl.w_attack_next > 0){ - printfline("w_attack_next > 0 at:%.2f - t:%.2f", pl.w_attack_next, time); - } - */ // HACK: If, this frame, w_attack_next was 0, for most weapons to allow firing, // make that a signal to reset inputPrimaryTapFrameCount. @@ -330,36 +310,31 @@ Game_Input(void) //pl.callWeaponThink(); - /* - // primary fire. - if (input_buttons & INPUT_BUTTON0){ - // mark as held down for future frames. - pl.gflags |= GF_SEMI_TOGGLED; - pl.gflags_net |= GF_SEMI_TOGGLED; - }else{ - // mark as not held down (for the next time held down to be a fresh press) - pl.gflags &= ~GF_SEMI_TOGGLED; - pl.gflags_net &= ~GF_SEMI_TOGGLED; - } - - // And for secondary fire. - if (input_buttons & INPUT_BUTTON3){ - pl.gflags |= GF_SEMI_SECONDARY_TOGGLED; - pl.gflags_net |= GF_SEMI_SECONDARY_TOGGLED; - }else{ - pl.gflags &= ~GF_SEMI_SECONDARY_TOGGLED; - pl.gflags_net &= ~GF_SEMI_SECONDARY_TOGGLED; - } - */ #if OTHER_PREDICTION_TEST == 2 + + /* if(input_impulse == 115){ TS_playerUseItems(); } - // great. So that won't even work. - //isFreshInput = FALSE; + */ + if(input_impulse == 115){ + if( !(pl.gflags & GF_UNUSED4)){ + TS_playerUseItems(); + } + pl.gflags |= GF_UNUSED4; + }else{ + pl.gflags &= ~GF_UNUSED4; + } #endif - + if(input_impulse == 116){ + if( !(pl.gflags & GF_UNUSED5)){ + TS_playerChangeFiremode(); + } + pl.gflags |= GF_UNUSED5; + }else{ + pl.gflags &= ~GF_UNUSED5; + } }//Game_Input @@ -479,12 +454,14 @@ void Input_useItems_press(void){ #elif OTHER_PREDICTION_TEST == 1 pSeatLocal->m_bUseItems = TRUE; #elif OTHER_PREDICTION_TEST == 2 - pSeatLocal->m_bUseItems = TRUE; - //TAGGG - play the click only this once + if( !(pl.gflags & GF_UNUSED3)){ - localsound("weapons/switch.wav", CHAN_AUTO, 1.0f); + canPlaySwitchSound = TRUE; + }else{ + pl.gflags |= GF_UNUSED3; } - pl.gflags |= GF_UNUSED3; + + pSeatLocal->m_bUseItems = TRUE; #endif }//Input_useItems_press @@ -498,6 +475,7 @@ void Input_useItems_release(void){ pSeatLocal->m_bUseItems = FALSE; #elif OTHER_PREDICTION_TEST == 2 pSeatLocal->m_bUseItems = FALSE; + pl.gflags &= ~GF_UNUSED3; #endif }//Input_useItems_release @@ -507,7 +485,13 @@ void Input_useItems_release(void){ +void Input_firemode_press(void){ + pSeatLocal->m_bChangeFiremode = TRUE; +} +void Input_firemode_release(void){ + pSeatLocal->m_bChangeFiremode = FALSE; +} @@ -540,6 +524,16 @@ void ClientGame_Input_Frame(void){ if(pl == NULL)return; // ??? + + /* + // does... funky things, not cumulative, only an offset forced this frame. + // Don't do that. + input_angles[0] += 36; + input_angles[1] += 36; + input_angles[2] += 36; + */ + + if(pl.iState != PLAYER_STATE::SPAWNED && pSeatLocal->m_flUI_Display != UI_SCREEN::NONE){ // If buying, don't allow any movement inputs. // The above is a similar check as "g_vguiWidgetCount > 0", but the buymenu does not @@ -577,24 +571,31 @@ void ClientGame_Input_Frame(void){ //printfline("input_buttons: %d", (INPUT_BUTTON7 & input_buttons) ); - // NOTE - GF_UNUSED3 is being used for playing the toggle-switch sound in - // #if OTHER_PREDICTION_TEST == 2 - // using GF_UNUSED4 instead of GF_UNUSED3 because that one is - // being used to play the click-noise on toggling instead. - // Yes, really. + + if(pSeatLocal->m_bUseItems){ + input_impulse = 115; + } + +/* if(pSeatLocal->m_bUseItems){ if( !(pl.gflags & GF_UNUSED4)){ input_impulse = 115; - //isFreshInput = TRUE; } pl.gflags |= GF_UNUSED4; }else{ pl.gflags &= ~GF_UNUSED4; } + */ #endif - - + + + if(pSeatLocal->m_bChangeFiremode){ + input_impulse = 116; + } + + + }// ClientGame_InputFrame diff --git a/src/shared/player.h b/src/shared/player.h index f98d835..2ce2921 100644 --- a/src/shared/player.h +++ b/src/shared/player.h @@ -224,8 +224,37 @@ class player:base_player PREDICTED_INT(iMeleeCycler); + // SHARED + // PREDICTED_whatever(...); + //vector vViewAngleOffsetTarget; + + /* + vector vViewAngleOffsetEnd; + vector vViewAngleOffsetStart; + float flViewAngleOffsetLerp; + vector vViewAngleOffsetCurrent; vector vViewAngleOffsetTarget; + vector vViewAngleMemory; + */ + //vector vViewAngleOffsetEnd; + //vector vViewAngleOffsetStart; + //float flViewAngleOffsetLerp; + //vector vViewAngleOffsetCurrent; + PREDICTED_FLOAT(flViewAngleOffsetTarget); + PREDICTED_VECTOR(vViewAngleOffsetTargetDir); + //vector vViewAngleMemory; + + //vector vViewAngleOffsetTotalChange; + PREDICTED_VECTOR(vViewAngleOffsetTotalChange); + vector vViewAngleOffsetTotalChangeAlt; + + vector receivedViewAngles; + vector oldViewAngles; + + + + PREDICTED_FLOAT(fAccuracyKickback); PREDICTED_FLOAT(fAccuracyKickbackStartCooldown); @@ -350,9 +379,6 @@ class player:base_player int iShotgunExtraDataID; - // was BOOL (a test, not even networked though) - PREDICTED_FLOAT(doFiremodeChange); - ////////////////////////////////////////////////////////////////////////////// @@ -473,10 +499,6 @@ class player:base_player // nothing uses this? Whoops //float lastweapon; #endif - -#ifdef FIREMODE_PREDICTION_TEST - float ignoreFiremodeReceiveTime; -#endif void(void) player; @@ -489,8 +511,8 @@ class player:base_player virtual void(BOOL resetInventory) reset; - virtual vector(vector vecInputAngles)View_approachAngleOffsetTarget; virtual void (void)updateTimers; + virtual void (float arg_ang, float arg_len)addViewAngleOffset; virtual void(int arg_iZoomLevel) setZoomLevel; virtual void(void) resetZoom; @@ -510,11 +532,6 @@ 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! @@ -550,6 +567,7 @@ class player:base_player virtual void(void) clientInputUpdate; virtual void(void) clientUseItemsCallback; + virtual void(void) handleZoom; #endif diff --git a/src/shared/player.qc b/src/shared/player.qc index f2a430f..b274200 100644 --- a/src/shared/player.qc +++ b/src/shared/player.qc @@ -18,7 +18,7 @@ // little test //var float otherTimer = 0; -#define FORCE_NETWORK_ALL_INVENTORY +//#define FORCE_NETWORK_ALL_INVENTORY /* all potential SendFlags bits we can possibly send */ @@ -228,9 +228,28 @@ player::ReceiveEntity(float new, float fl) //flKarateBlockCooldown iMeleeCycler = readbyte(); - //vViewAngleOffsetTarget[0] = readcoord(); - //vViewAngleOffsetTarget[1] = readcoord(); - //vViewAngleOffsetTarget[2] = readcoord(); + + /* + vViewAngleOffsetTargetDir[0] = readcoord(); + vViewAngleOffsetTargetDir[1] = readcoord(); + vViewAngleOffsetTargetDir[2] = readcoord(); + */ + + + + + vViewAngleOffsetTotalChange[0] = readcoord(); + vViewAngleOffsetTotalChange[1] = readcoord(); + vViewAngleOffsetTotalChange[2] = readcoord(); + + + //TAGGG - vital to the viewangle-modifying kickback looking right + // with prediction! + setproperty(VF_CL_VIEWANGLES, GET_MY_VIEW_ANGLES + vViewAngleOffsetTotalChange); + vViewAngleOffsetTotalChange = [0,0,0]; + + + fAccuracyKickback = readfloat(); fAccuracyKickbackStartCooldown = readfloat(); @@ -251,9 +270,7 @@ player::ReceiveEntity(float new, float fl) shotgunReloadIndex = readbyte(); shotgunAddAmmoTime = readfloat(); shotgunAddAmmoSoundTime = readfloat(); - - //doFiremodeChange = readbyte(); - + ary_myWeapons_softMax = readbyte(); @@ -274,11 +291,13 @@ player::ReceiveEntity(float new, float fl) } }else if(fl & PLAYER_UNUSED1){ - i = inventoryEquippedIndex; + //i = inventoryEquippedIndex; + i = readbyte() - 1; + /// could this ever be -1? if(i != -1){ ReceiveEntity_ary_myWeapons(i); - + //int myAmmoType = getAmmoTypeOfWeapon(this.activeweapon); int betterID = ary_myWeapons[inventoryEquippedIndex].weaponID; @@ -303,6 +322,11 @@ player::ReceiveEntity(float new, float fl) ///////////////////////////////////////////////////// + // safe? + receivedViewAngles = this.v_angle; + + + // TODO! Check for any change in ammo values like this: // Or maybe not, looks like Weapons_AmmoUpdate isn't needed for FreeTS, HUD draw methods @@ -330,19 +354,7 @@ void player::ReceiveEntity_ary_myWeapons(int i){ ary_myWeapons[i].iBitsUpgrade_on = readbyte(); #endif - 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].iFireMode = readbyte(); ary_myWeapons[i].iFireModeAkimbo = readbyte(); ary_myWeapons[i].iIronSight = readbyte(); @@ -368,6 +380,9 @@ player::PredictPreFrame(void) { //printfline("---PREDICT PRE FRAME"); + //sendevent("ViewOffsetR", "fff", vViewAngleOffsetTotalChange[0], vViewAngleOffsetTotalChange[1], vViewAngleOffsetTotalChange[2]); + + /* the generic client attributes */ base_player::PredictPreFrame(); @@ -381,34 +396,6 @@ player::PredictPreFrame(void) SAVE_STATE(anim_bottom); SAVE_STATE(anim_bottom_time); - -/* - SAVE_STATE(glock_mag); - SAVE_STATE(mp5_mag); - SAVE_STATE(python_mag); - SAVE_STATE(shotgun_mag); - SAVE_STATE(crossbow_mag); - SAVE_STATE(rpg_mag); - SAVE_STATE(satchel_chg); - - SAVE_STATE(ammo_9mm); - SAVE_STATE(ammo_357); - SAVE_STATE(ammo_buckshot); - SAVE_STATE(ammo_bolt); - SAVE_STATE(ammo_rocket); - SAVE_STATE(ammo_uranium); - SAVE_STATE(ammo_handgrenade); - SAVE_STATE(ammo_satchel); - SAVE_STATE(ammo_tripmine); - SAVE_STATE(ammo_snark); - SAVE_STATE(ammo_hornet); - - SAVE_STATE(ammo_m203_grenade); - SAVE_STATE(ammo_gauss_volume); - SAVE_STATE(ammo_rpg_state); - SAVE_STATE(mode_tempstate); - */ - SAVE_STATE(iState); SAVE_STATE(inventoryEquippedIndex); SAVE_STATE(weaponEquippedAkimbo); @@ -425,9 +412,13 @@ player::PredictPreFrame(void) //flKarateBlockCooldown SAVE_STATE(iMeleeCycler); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[0] ); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[1] ); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[2] ); + + + SAVE_STATE(vViewAngleOffsetTargetDir); + SAVE_STATE(vViewAngleOffsetTotalChange); + SAVE_STATE(flViewAngleOffsetTarget); + + SAVE_STATE(fAccuracyKickback); SAVE_STATE(fAccuracyKickbackStartCooldown); @@ -441,9 +432,7 @@ player::PredictPreFrame(void) SAVE_STATE(shotgunAddAmmoTime); SAVE_STATE(shotgunAddAmmoSoundTime); - - //SAVE_STATE(doFiremodeChange); - + SAVE_STATE(ary_myWeapons_softMax); for(int i = 0; i < ary_myWeapons_softMax; i++){ @@ -476,7 +465,6 @@ player::PredictPreFrame(void) // No need here now I think? //this.viewzoom = this.flZoomCurrent; - #if OTHER_PREDICTION_TEST == 1 Custom_Predict_PlayerPreFrame(this); #endif @@ -495,17 +483,11 @@ player::PredictPostFrame(void) { //printfline("---PREDICT POST FRAME"); - /* -#ifdef CLIENT - if(iState == PLAYER_STATE::SPAWNED){ - TS_View_HandleZoom(); - } -#endif - */ + sendevent("ViewOffsetR", "fff", vViewAngleOffsetTotalChange[0], vViewAngleOffsetTotalChange[1], vViewAngleOffsetTotalChange[2]); + /* the generic client attributes */ base_player::PredictPostFrame(); - // client's way of calling postthink postThink(); @@ -515,34 +497,6 @@ player::PredictPostFrame(void) ROLL_BACK(anim_top_time); ROLL_BACK(anim_bottom); ROLL_BACK(anim_bottom_time); - - /* - ROLL_BACK(glock_mag); - ROLL_BACK(mp5_mag); - ROLL_BACK(python_mag); - ROLL_BACK(shotgun_mag); - ROLL_BACK(crossbow_mag); - ROLL_BACK(rpg_mag); - ROLL_BACK(satchel_chg); - - ROLL_BACK(ammo_9mm); - ROLL_BACK(ammo_357); - ROLL_BACK(ammo_buckshot); - ROLL_BACK(ammo_m203_grenade); - ROLL_BACK(ammo_bolt); - ROLL_BACK(ammo_rocket); - ROLL_BACK(ammo_uranium); - ROLL_BACK(ammo_handgrenade); - ROLL_BACK(ammo_satchel); - ROLL_BACK(ammo_tripmine); - ROLL_BACK(ammo_snark); - ROLL_BACK(ammo_hornet); - - ROLL_BACK(ammo_m203_grenade); - ROLL_BACK(ammo_gauss_volume); - ROLL_BACK(ammo_rpg_state); - ROLL_BACK(mode_tempstate); - */ ROLL_BACK(iState); ROLL_BACK(inventoryEquippedIndex); @@ -552,11 +506,6 @@ player::PredictPostFrame(void) ROLL_BACK(isChangingIronsight); //ROLL_BACK(flZoomTarget); - /* - if(iZoomLevel != iZoomLevel_net){ - printfline("!!! ZoomLevel change B. %i -> %i (%.2f)", iZoomLevel, iZoomLevel_net, time); - } - */ ROLL_BACK(iZoomLevel); @@ -568,9 +517,13 @@ player::PredictPostFrame(void) //flKarateBlockCooldown ROLL_BACK(iMeleeCycler); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[0] ); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[1] ); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[2] ); + + + ROLL_BACK(vViewAngleOffsetTargetDir); + ROLL_BACK(vViewAngleOffsetTotalChange); + ROLL_BACK(flViewAngleOffsetTarget); + + ROLL_BACK(fAccuracyKickback); ROLL_BACK(fAccuracyKickbackStartCooldown); @@ -584,7 +537,6 @@ player::PredictPostFrame(void) ROLL_BACK(shotgunAddAmmoTime); ROLL_BACK(shotgunAddAmmoSoundTime); - //ROLL_BACK(doFiremodeChange); ROLL_BACK(ary_myWeapons_softMax); for(int i = 0; i < ary_myWeapons_softMax; i++){ @@ -604,7 +556,7 @@ player::PredictPostFrame(void) ROLL_BACK(ary_myWeapons[i].bNeedsPump); } - //UNNECESSARY. This array is of fixed length, so known at all times. + // 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 @@ -612,6 +564,7 @@ player::PredictPostFrame(void) ROLL_BACK_ARY(ary_ammoTotal, i); } + #if OTHER_PREDICTION_TEST == 1 Custom_Predict_PlayerPostFrame(this); #endif @@ -637,83 +590,6 @@ player::EvaluateEntity(void) if (ATTR_CHANGED(anim_top) || ATTR_CHANGED(anim_top_time) || ATTR_CHANGED(anim_top_delay)) SendFlags |= PLAYER_TOPFRAME; - -/* - // ammo 1 type updates - if (ATTR_CHANGED(glock_mag)) - SendFlags |= PLAYER_AMMO1; - if (ATTR_CHANGED(mp5_mag)) - SendFlags |= PLAYER_AMMO1; - if (ATTR_CHANGED(python_mag)) - SendFlags |= PLAYER_AMMO1; - if (ATTR_CHANGED(shotgun_mag)) - SendFlags |= PLAYER_AMMO1; - if (ATTR_CHANGED(crossbow_mag)) - SendFlags |= PLAYER_AMMO1; - if (ATTR_CHANGED(rpg_mag)) - SendFlags |= PLAYER_AMMO1; - if (ATTR_CHANGED(satchel_chg)) - SendFlags |= PLAYER_AMMO1; - - // ammo 2 type updates - if (ATTR_CHANGED(ammo_9mm)) - SendFlags |= PLAYER_AMMO2; - if (ATTR_CHANGED(ammo_357)) - SendFlags |= PLAYER_AMMO2; - if (ATTR_CHANGED(ammo_buckshot)) - SendFlags |= PLAYER_AMMO2; - if (ATTR_CHANGED(ammo_bolt)) - SendFlags |= PLAYER_AMMO2; - if (ATTR_CHANGED(ammo_rocket)) - SendFlags |= PLAYER_AMMO2; - if (ATTR_CHANGED(ammo_uranium)) - SendFlags |= PLAYER_AMMO2; - if (ATTR_CHANGED(ammo_handgrenade)) - SendFlags |= PLAYER_AMMO2; - if (ATTR_CHANGED(ammo_satchel)) - SendFlags |= PLAYER_AMMO2; - if (ATTR_CHANGED(ammo_tripmine)) - SendFlags |= PLAYER_AMMO2; - if (ATTR_CHANGED(ammo_snark)) - SendFlags |= PLAYER_AMMO2; - if (ATTR_CHANGED(ammo_hornet)) - SendFlags |= PLAYER_AMMO2; - - if (ATTR_CHANGED(ammo_m203_grenade)) - SendFlags |= PLAYER_AMMO3; - if (ATTR_CHANGED(ammo_gauss_volume)) - SendFlags |= PLAYER_AMMO3; - if (ATTR_CHANGED(ammo_rpg_state)) - SendFlags |= PLAYER_AMMO3; - if (ATTR_CHANGED(mode_tempstate)) - SendFlags |= PLAYER_AMMO3; - - SAVE_STATE(glock_mag); - SAVE_STATE(mp5_mag); - SAVE_STATE(python_mag); - SAVE_STATE(shotgun_mag); - SAVE_STATE(crossbow_mag); - SAVE_STATE(rpg_mag); - SAVE_STATE(satchel_chg); - SAVE_STATE(ammo_9mm); - SAVE_STATE(ammo_357); - SAVE_STATE(ammo_buckshot); - SAVE_STATE(ammo_bolt); - SAVE_STATE(ammo_rocket); - SAVE_STATE(ammo_uranium); - SAVE_STATE(ammo_handgrenade); - SAVE_STATE(ammo_satchel); - SAVE_STATE(ammo_tripmine); - SAVE_STATE(ammo_snark); - SAVE_STATE(ammo_hornet); - - SAVE_STATE(ammo_m203_grenade); - SAVE_STATE(ammo_gauss_volume); - SAVE_STATE(ammo_rpg_state); - SAVE_STATE(mode_tempstate); -*/ - - // IDEA: do a full-send, all weapons stats on executing a buyconfig order? // set some flag to convey that? @@ -787,9 +663,13 @@ player::EvaluateEntity(void) //flKarateBlockCooldown SAVE_STATE(iMeleeCycler); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[0] ); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[1] ); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[2] ); + + + SAVE_STATE(vViewAngleOffsetTargetDir); + SAVE_STATE(vViewAngleOffsetTotalChange); + SAVE_STATE(flViewAngleOffsetTarget); + + SAVE_STATE(fAccuracyKickback); SAVE_STATE(fAccuracyKickbackStartCooldown); @@ -802,9 +682,7 @@ player::EvaluateEntity(void) SAVE_STATE(shotgunAddAmmoTime); SAVE_STATE(shotgunAddAmmoSoundTime); - - //SAVE_STATE(doFiremodeChange); - + SAVE_STATE(ary_myWeapons_softMax); @@ -851,6 +729,24 @@ player::EvaluateEntity(void) } + + +void CSEv_ViewAnglesR_fff(float arg_x, float arg_y, float arg_z){ + player pl = (player)self; + pl.v_angle.x = arg_x; + pl.v_angle.y = arg_y; + pl.v_angle.z = arg_z; + pl.vViewAngleOffsetTotalChangeAlt = [0,0,0]; +} +void CSEv_ViewOffsetR_fff(float arg_x, float arg_y, float arg_z){ + player pl = (player)self; + pl.vViewAngleOffsetTotalChangeAlt.x = arg_x; + pl.vViewAngleOffsetTotalChangeAlt.y = arg_y; + pl.vViewAngleOffsetTotalChangeAlt.z = arg_z; + //pl.vViewAngleOffsetTotalChangeAlt = [0,0,0]; +} + + /* ================= player::SendEntity @@ -869,20 +765,6 @@ player::SendEntity(entity ePEnt, float fChanged) return (0); } - //TAGGG - REPLACED. - /* - // other players don't need to know about these attributes - if (ePEnt != self) { - fChanged &= ~PLAYER_ITEMS; - fChanged &= ~PLAYER_HEALTH; - fChanged &= ~PLAYER_ARMOR; - fChanged &= ~PLAYER_VIEWOFS; - fChanged &= ~PLAYER_AMMO1; - fChanged &= ~PLAYER_AMMO2; - fChanged &= ~PLAYER_AMMO3; - } - */ - WriteByte(MSG_ENTITY, ENT_PLAYER); WriteFloat(MSG_ENTITY, fChanged); @@ -905,42 +787,6 @@ player::SendEntity(entity ePEnt, float fChanged) WriteFloat(MSG_ENTITY, flViewModelFrame); - - //TAGGG - REPLACED. - /* - if (fChanged & PLAYER_AMMO1) { - WriteByte(MSG_ENTITY, glock_mag); - WriteByte(MSG_ENTITY, mp5_mag); - WriteByte(MSG_ENTITY, python_mag); - WriteByte(MSG_ENTITY, shotgun_mag); - WriteByte(MSG_ENTITY, crossbow_mag); - WriteByte(MSG_ENTITY, rpg_mag); - WriteByte(MSG_ENTITY, satchel_chg); - } - - if (fChanged & PLAYER_AMMO2) { - WriteByte(MSG_ENTITY, ammo_9mm); - WriteByte(MSG_ENTITY, ammo_357); - WriteByte(MSG_ENTITY, ammo_buckshot); - WriteByte(MSG_ENTITY, ammo_bolt); - WriteByte(MSG_ENTITY, ammo_rocket); - WriteByte(MSG_ENTITY, ammo_uranium); - WriteByte(MSG_ENTITY, ammo_handgrenade); - WriteByte(MSG_ENTITY, ammo_satchel); - WriteByte(MSG_ENTITY, ammo_tripmine); - WriteByte(MSG_ENTITY, ammo_snark); - WriteByte(MSG_ENTITY, ammo_hornet); - } - - if (fChanged & PLAYER_AMMO3) { - WriteByte(MSG_ENTITY, ammo_m203_grenade); - WriteByte(MSG_ENTITY, ammo_gauss_volume); - WriteByte(MSG_ENTITY, ammo_rpg_state); - WriteByte(MSG_ENTITY, mode_tempstate); - } - */ - - // TODO MAJOR!!! // Only send updates if we shuffled the weapons around (update everything, all weapons), // OR if a particular weapon states to update its features, perhaps sending itself @@ -966,9 +812,14 @@ player::SendEntity(entity ePEnt, float fChanged) //flKarateBlockCooldown WriteByte(MSG_ENTITY, iMeleeCycler); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[0] ); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[1] ); - //WriteCoord(MSG_ENTITY, vViewAngleOffsetTarget[2] ); + + + WriteCoord(MSG_ENTITY, vViewAngleOffsetTotalChange[0] ); + WriteCoord(MSG_ENTITY, vViewAngleOffsetTotalChange[1] ); + WriteCoord(MSG_ENTITY, vViewAngleOffsetTotalChange[2] ); + + vViewAngleOffsetTotalChange = [0,0,0]; + WriteFloat(MSG_ENTITY, fAccuracyKickback); WriteFloat(MSG_ENTITY, fAccuracyKickbackStartCooldown); @@ -981,9 +832,7 @@ player::SendEntity(entity ePEnt, float fChanged) WriteByte(MSG_ENTITY, shotgunReloadIndex ); WriteFloat(MSG_ENTITY, shotgunAddAmmoTime ); WriteFloat(MSG_ENTITY, shotgunAddAmmoSoundTime ); - - //WriteByte(MSG_ENTITY, doFiremodeChange); - + //weapondynamic_t ary_myWeapons[ary_myWeapons_length]; @@ -1006,7 +855,9 @@ player::SendEntity(entity ePEnt, float fChanged) } }else if(fChanged & PLAYER_UNUSED1){ - i = inventoryEquippedIndex; + i = (int)inventoryEquippedIndex; + WriteByte(MSG_ENTITY, i + 1); + /// could this ever be -1? if(i != -1){ SendEntity_ary_myWeapons(i); @@ -1069,9 +920,6 @@ player::player(void){ iState = PLAYER_STATE::NOCLIP; completeInventorySend = FALSE; -#ifdef FIREMODE_PREDICTION_TEST - ignoreFiremodeReceiveTime = -1; -#endif #ifdef SERVER money = 0; //safety? @@ -1108,51 +956,6 @@ player::player(void){ reset(TRUE); //cover anything specified in here too - /* -#ifdef SERVER - - player someThingy = this; - printfline("***CHECKPOINT player2***"); - printfline("CBaseEntity: %i", someThingy.CBaseEntity); - printfline("Respawn: %i", someThingy.Respawn); - printfline("Hide: %i", someThingy.Hide); - printfline("ParentUpdate: %i", someThingy.ParentUpdate); - printfline("SendEntity: %i", someThingy.SendEntity); - printfline("Pain: %i", someThingy.Pain); - printfline("Death: %i", someThingy.Death); - printfline("SetEffects: %i", someThingy.SetEffects); - printfline("SetFrame: %i", someThingy.SetFrame); - printfline("SetModel: %i", someThingy.SetModel); - printfline("SetModelindex: %i", someThingy.SetModelindex); - printfline("SetMovetype: %i", someThingy.SetMovetype); - printfline("SetSkin: %i", someThingy.SetSkin); - printfline("SetSolid: %i", someThingy.SetSolid); - printfline("SetBody: %i", someThingy.SetBody); - printfline("SetAngles: %i", someThingy.SetAngles); - printfline("SetOrigin: %i", someThingy.SetOrigin); - printfline("SetSize: %i", someThingy.SetSize); - printfline("SetRenderFX: %i", someThingy.SetRenderFX); - printfline("SetRenderMode: %i", someThingy.SetRenderMode); - printfline("SetRenderAmt: %i", someThingy.SetRenderAmt); - printfline("SetRenderColor: %i", someThingy.SetRenderColor); - - printfline("player: %i", someThingy.player); - printfline("reset: %i", someThingy.reset); - printfline("View_approachAngleOffsetTarget: %i", someThingy.View_approachAngleOffsetTarget); - printfline("updateTimers: %i", someThingy.updateTimers); - printfline("frameThink: %i", someThingy.frameThink); - printfline("frameThink_fromServer: %i", someThingy.frameThink_fromServer); - printfline("preThink: %i", someThingy.preThink); - printfline("postThink: %i", someThingy.postThink); - printfline("attemptAddWeaponFromPickup: %i", someThingy.attemptAddWeaponFromPickup); - printfline("dropWeapon: %i", someThingy.dropWeapon); - printfline("anyAmmoPoolNonEmpty: %i", someThingy.anyAmmoPoolNonEmpty); - printfline("dropAmmo: %i", someThingy.dropAmmo); - printfline("***END***"); - -#endif - */ - }// player constructor @@ -1171,6 +974,8 @@ player::reset(BOOL resetInventory){ resetZoom(); + //this.flViewAngleOffsetLerp = 1.0f; + #ifdef CLIENT // For safety, doing this. // If anywhere that ever calls for this method clientside has this set @@ -1221,9 +1026,7 @@ player::reset(BOOL resetInventory){ shotgunReloadIndex = 0; shotgunAddAmmoTime = -1; shotgunAddAmmoSoundTime = -1; - - doFiremodeChange = FALSE; - + //Grenade stuff grenadeFireIndex = -1; grenadeHeldDuration = -1; @@ -1257,7 +1060,10 @@ player::reset(BOOL resetInventory){ #endif // do this at spawn too. oh right, this 'reset' method is called from there. - vViewAngleOffsetTarget = [0, 0, 0]; + + //vViewAngleOffsetTarget = [0, 0, 0]; + flViewAngleOffsetTarget = 0; + fAccuracyKickback = 0; fAccuracyKickbackStartCooldown = -1; @@ -1317,46 +1123,6 @@ player::reset(BOOL resetInventory){ -vector -player::View_approachAngleOffsetTarget(vector vecInputAngles) -{ - float frametimeUse; - - // is this wise? -#ifdef CLIENT - frametimeUse = clframetime; -#else - frametimeUse = frametime; -#endif - - // !!! Not involving frametimeUse yet? Whoops. - - - // do we have an offset at all? - if( vlen(vViewAngleOffsetTarget) != 0){ - - //shift our view to get closer to looking in the direction suggested by it. - vector vecToMove; - - vecToMove = vViewAngleOffsetTarget * 0.22; - float vecToMoveLen = vlen(vecToMove); - - if(vecToMoveLen < 0.001 || vecToMoveLen >= vlen(vViewAngleOffsetTarget) ){ - //nah nevermind, just move to the target already. - //printfline("View_approachAngleOffsetTarget: LAST ONE"); - vecToMove = vViewAngleOffsetTarget; - }else{ - - } - - vecInputAngles += vecToMove * 1.28; - vViewAngleOffsetTarget -= vecToMove; - - } - - return vecInputAngles; -}//View_approachAngleOffsetTarget - // little test @@ -1369,7 +1135,6 @@ void player::updateTimers(void){ - // good place for this? Cloned from w_attack_next as a separate counter // for akimbo firing to use. w_attack_akimbo_next = max(0, w_attack_akimbo_next - input_timelength); @@ -1395,6 +1160,9 @@ player::updateTimers(void){ //fKarateStamina = bound(0, fKarateStamina + frametime * 0.1667, 1); fKarateStamina = bound(0, fKarateStamina + input_timelength * 0.1667, 1); } + + //printfline("KARATE STAMINA? %.2f", fKarateStamina); + if(fAccuracyKickbackStartCooldown != -1){ if(fAccuracyKickbackStartCooldown <= 0){ // begin reducing @@ -1409,49 +1177,225 @@ player::updateTimers(void){ }//kickbackStartCooldown check + /* + #ifdef CLIENT + #define my_frametime clframetime + #else + #define my_frametime frametime + #endif + */ + + #define my_frametime input_timelength + + //vector viewChange; + float flViewChange; + vector vViewChangeDir; + + + if(flViewAngleOffsetTarget <= 0.02){ + flViewChange = this.flViewAngleOffsetTarget; + vViewChangeDir = this.vViewAngleOffsetTargetDir; + this.flViewAngleOffsetTarget = 0; + }else{ + float lenOfVAOT = this.flViewAngleOffsetTarget; + float amountToChangeBy = this.flViewAngleOffsetTarget * 36 * my_frametime; + float amountToReduceBy = this.flViewAngleOffsetTarget * 18 * my_frametime; + + //printfline("COMPARISON? cb:%.2f rb:%.2f - total:%.2f", amountToChangeBy, amountToReduceBy, lenOfVAOT); + + // if changing the vViewOffsetTarget by this much would + // go past the offset into pushing it past what was intended, + // don't allow that! Might not even be possible + if(amountToReduceBy >= lenOfVAOT){ + flViewChange = this.flViewAngleOffsetTarget; + vViewChangeDir = this.vViewAngleOffsetTargetDir; + this.flViewAngleOffsetTarget = 0; + }else{ + this.flViewAngleOffsetTarget -= amountToReduceBy; + + flViewChange = amountToChangeBy; + vViewChangeDir = this.vViewAngleOffsetTargetDir; + } + } + + + vector finalChange = flViewChange * vViewChangeDir; + + + this.vViewAngleOffsetTotalChange += finalChange; + this.vViewAngleOffsetTotalChangeAlt += finalChange; + + // test? main one + #ifndef CLIENT + GET_MY_VIEW_ANGLES = GET_MY_VIEW_ANGLES + finalChange; + #else + + #endif + + }//updateTimers +// add kickback that pushes the camera by some angle. +// Cumulative with existing kickback not yet finished being applied. +void player::addViewAngleOffset(float arg_ang, float arg_len){ + + + /* + #ifdef CLIENT + + printfline("--- %d - %d", input_sequence, tempQueue2[input_sequence % 512]); + + if(!tempQueue2[input_sequence % 512]){ + return; + }else{ + tempQueue2[input_sequence % 512] = FALSE; + } + + printfline("!!! addViewAngleOffset !!! %d", input_sequence); + #endif + */ + + + + if(flViewAngleOffsetTarget == 0){ + // easy, replace completely + flViewAngleOffsetTarget = arg_len; + vViewAngleOffsetTargetDir = [-sin(arg_ang), cos(arg_ang), 0]; + }else{ + // Have to unpack the vector, add it, and re-do the split value/dir way. + // Might be a smarter way to do that math-wise but this works for now + vector tempVec = flViewAngleOffsetTarget * vViewAngleOffsetTargetDir; + vector newVec = arg_len * [-sin(arg_ang), cos(arg_ang), 0]; + tempVec = tempVec + newVec; + flViewAngleOffsetTarget = vlen(tempVec); + if(flViewAngleOffsetTarget != 0){ + vViewAngleOffsetTargetDir = tempVec / flViewAngleOffsetTarget; + }else{ + // what. + // Nothing to do, leave flViewAngleOffsetTarget at 0 to be ignored + } + } +} + + #ifdef CLIENT -void -_TS_FRESH_playerUseItems(void); - // client only, check some other input-related CVars. void player::clientInputUpdate(void){ //printfline("---clientInputUpdate"); - /* - if(pSeatLocal->m_bUseItemsFreshPress){ - pSeatLocal->m_bUseItemsFreshPress = FALSE; - pSeatLocal->m_iUseItemsLatencyPresses++; - _TS_FRESH_playerUseItems(); - } - - int i; - for(i = 0; i < pSeatLocal->m_iUseItemsLatencyPresses; i++){ - TS_playerUseItems(); - } - */ } void player::clientUseItemsCallback(void){ - //pSeatLocal->m_iUseItemsLatencyPresses--; + } + + + + + +// - initially from The Wastes. +void player::handleZoom(void) +{ + + if(this.iState != PLAYER_STATE::SPAWNED){ + // zoom is only allowed for ingame. + return; + } + + // test + /* + this.flZoomCurrent = this.flZoomTarget; + this.viewzoom = this.flZoomTarget; + printfline("flZoomTarget: %.2f", this.flZoomTarget); + return; + */ + + //printfline("WHATS GOING ON %.2f %.2f %.2f %.2f %.2f", this.flZoomEnd, this.flZoomTarget, this.flZoomStart, this.flZoomLerp, this.flZoomCurrent); + + // - No other codebase refers to STAT_VIEWZOOM, best to replace anything + // involving that. + + // in case of some unexpected change. + // TODO: this might have an issue if the player were to change weapons and end up + // on the same zoom level as a previous weapon, despite the two weapons having + // different target values (like 0.4 vs. 0.6) at their own zoom level #1's. + // A check for being a different equipped weapon type + // (this.activeweapon vs. this.activeweapon_zoomprev, set only by setZoomLevel) + // ought to work. But that would be a very strange case anyway + if(this.iZoomLevel != this.iZoomLevelPrev){ + this.setZoomLevel(this.iZoomLevel); + } + + if (this.flZoomEnd != this.flZoomTarget ) { + //printfline("NEW ZOOM DETECTED: %.2f -> %.2f (zoomlev: %i)", this.flZoomEnd, this.flZoomTarget, this.iZoomLevel); + + // is setting flZoomStart to flZoomEnd or flZoomCurrent a better idea? + // at flZoomEnd means, on changing before the current lerp has finished, it jumps to beginning + // at the end point of the lerp in progress. But starting at flZoomCurrent might be smoother? + // if it isn't glitchy that could be nice. Trying that out. + + this.flZoomStart = this.flZoomCurrent; + //this.flZoomStart = this.flZoomEnd; + + this.flZoomEnd = this.flZoomTarget; + this.flZoomLerp = 0.0f; + } + + if (this.flZoomLerp < 1.0f) { + // Slow this down for debugging purposes, this is meant to be fast. + // 0.8 can be safe. + // The Wastes default was 4. + + // !!! clframetime, frametime, or input_timelength ? + this.flZoomLerp += clframetime * 5.7; + + if(this.flZoomLerp >= 1.0){ + //enforce the cap. + this.flZoomLerp = 1.0; + } + + //this.flZoomCurrent = getstatf(STAT_VIEWZOOM); + this.flZoomCurrent = Math_Lerp(this.flZoomStart, this.flZoomEnd, this.flZoomLerp); + } + + // Set this, since Nuclide will read it in and apply instantly. + // So same effect without having to edit Nuclide, this pipes it over for it + // to do the setproperty thing below to apply + //this.viewzoom = this.flZoomCurrent; + + ////setproperty(VF_AFOV, DEFAULT_FOV * this.flZoomCurrent); + ////setsensitivityscaler(this.flZoomCurrent); + + // here's the way old FreeCS did it + //setproperty(VF_AFOV, cvar("fov") * this.viewzoom); + //setsensitivityscaler(this.viewzoom); + + + + +}// TS_View_HandleZoom + + + #endif + + + void player::setZoomLevel(int arg_iZoomLevel){ iZoomLevel = arg_iZoomLevel; @@ -1705,30 +1649,6 @@ 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 // (Comment may be out of date, verify if serverside postthink or setting think methods @@ -1759,7 +1679,6 @@ player::frameThink_fromServer(void){ - // preThink & postThink are supporter client and serverside. // They're not built-in methods per entity nor called by Nuclide. // For clientside, preThink/postThink are called by prediction pre/post methods. @@ -1859,7 +1778,6 @@ player::postThink(void){ // is that wise? There is also "frametime". //printfline("-------postThink %.3f - %.3f------", cltime_delta, frametime); - /* // if anything like this were ever needed? w_attack_next_nonet -= cltime_delta; @@ -1909,39 +1827,12 @@ player::postThink(void){ void player::preThinkShared(void){ + // Empty, for now. - - //TAGGG - any use for input_angles here? Shared, predicted? - - // TODO: make this view kickback properly predicted -#ifdef CLIENT - //printfline("So what is my view ang?? %.2f %.2f", view_angles[0], view_angles[1]); - // TODO - for clientside, this would need to involve the "view_angles" global - // instead! Unsure if the macro GET_VIEW_ANGLES is good enough - //v_angle = View_approachAngleOffsetTarget(v_angle); - //view_angles = View_approachAngleOffsetTarget(view_angles); -#else - //printfline("So what is my view ang?? %.2f %.2f", this.v_angle[0], this.v_angle[1]); - this.v_angle = View_approachAngleOffsetTarget(this.v_angle); -#endif - - - - // little test - //otherTimer += frametime; - - //changedWeaponRecentlyTimer = max(0, changedWeaponRecentlyTimer - frametime); - - //if(fUncrouchBlockDelay > 0){ - // printfline("WHAT IS IT %.2f", fUncrouchBlockDelay); - //} - //fMoveBlockDelay = max(0, fMoveBlockDelay - frametime); - //fUncrouchBlockDelay = max(0, fUncrouchBlockDelay - frametime); } - #ifdef SERVER BOOL diff --git a/src/shared/util.h b/src/shared/util.h index e04ff2a..3d4a9b5 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -10,26 +10,6 @@ // also, FTE needs a space after a preprocessor macro name for a slash to drop-down to the // rest of the definition, like "#define thing \". - - -// 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 - /////////////////////////////////////////////////////////////////////////// diff --git a/src/shared/weapons.h b/src/shared/weapons.h index 96e3994..1d9f16d 100644 --- a/src/shared/weapons.h +++ b/src/shared/weapons.h @@ -805,6 +805,7 @@ MELEE_HIT_RESPONSE weapon_base_onPrimaryAttack_melee(player pl, weapondata_basic MELEE_HIT_RESPONSE weapon_base_onPrimaryAttack_melee_fromCustomDirection(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, float damageToDeal, float range, vector customAngle ); void weapon_base_onAttack(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int attackTypeUsed); +void weapon_base_onAttack_individual(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount); void weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount, int attackTypeUsed); diff --git a/src/shared/weapons.qc b/src/shared/weapons.qc index ab91920..522ef21 100644 --- a/src/shared/weapons.qc +++ b/src/shared/weapons.qc @@ -304,31 +304,18 @@ weapon_base_onAttack(player pl, weapondata_basic_t* basePRef, weapondynamic_t ar }// weapon_base_onAttack -// Was considering making this client-callable, buuuuut -// the fire-viewcamera-kickback thing is going a different direciton though, so never mind that. -// In short, this is effectively serverside-only, clientside script in any weapon is never expected to call this method. -// If we ever need that changed, that would need to be edited in every single weapon.. ehhhhhh. -// TODO! Mass rename this to weapon_gun_onAttack_multi, same for above. -// Why would this ever be called for a non-gun? Melee uses a different method completely, -// and we refer to fRange here, a weapon-only attribute. -// (effectively becomes 'max number of penetrations allowed', which is still something only for guns) -// NOTE - checks for being unable to fire yet not included! + +// For firing once the left or right has been picked for firing, does not matter which as this has +// no effect on the weapon stats. Also applies kickback for firing once. void -weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount, int attackTypeUsed) -{ - +weapon_base_onAttack_individual(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount){ + weapondata_gun_t baseRef = *((weapondata_gun_t*)basePRef); - //TAGGG - shared random test - float randoAngFactor = randomInRange_f(0, 1); - //float randoAngFactor = 0.5; - - - - //float finalAng = (40 + randoAngFactor*( (90-40)*2 ) ) *(M_PI/180); - + float randoAngFactor; + float finalAng; + float finalAmount; float angleRange = 115; - float finalAng = ( 90 - (angleRange/2) + randoAngFactor*( angleRange ) ) *(M_PI/180); float baseAcc = baseRef.firestats.fAccuracy; float kickbackToApply = pl.fAccuracyKickback; @@ -341,7 +328,6 @@ weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynami // The lasersight can be turned off, so check for "_on" instead in that case. int legalBuyOpts_on = (arg_thisWeapon.iBitsUpgrade_on & legalBuyOpts); - if(legalBuyOpts_on & BITS_WEAPONOPT_LASERSIGHT){ baseAcc *= 0.72; kickbackToApply *= 0.87; @@ -352,10 +338,6 @@ weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynami } float acc = baseAcc + kickbackToApply; - - - //TODO - factor in 'fAccuracyKickback' too. - vector toGo; float miner = 0.65 * 1; float maxer = 1.00 * 1; @@ -387,32 +369,27 @@ weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynami #endif //////////////////////////////////////////////////////////////////////////////////////////////// + #ifdef SERVER + // Now, adjust the v_angle to account for the knockback I expet + // the user to have at this point, might not have completely + // accurate view angles from the client t the moment. + // BEWARE: using only a vViewAngleOffsetTotalChangeAlt given + // by the client is asking to get this modified, unsure of + // alternatives yet, see where this is received from the client + // in ts/src/shared/player.qc. + vector oldAng = pl.v_angle; + pl.v_angle += pl.vViewAngleOffsetTotalChangeAlt; + TraceAttack_FireBullets(shellCount, (pl.origin + pl.view_ofs), baseRef.fAttackDamage, [acc, acc], (int)pl.activeweapon); + pl.v_angle = oldAng; + #endif - //TAGGG - TODO! Re-picking the angle to kickback per hit may make more sense than varrying the intensity - // of the exact same direction for both shots, just a thought - if(attackTypeUsed & BITS_AKIMBOCHOICE_LEFT){ - //left -#ifdef SERVER - TraceAttack_FireBullets(shellCount, (pl.origin + pl.view_ofs), baseRef.fAttackDamage, [acc, acc], (int)pl.activeweapon); -#endif - arg_thisWeapon.iClipLeft -= 1; - //TAGGG - shared random test - toGo = [-sin(finalAng), cos(finalAng), 0] * baseRef.firestats.fViewKickback * randomInRange_f(miner, maxer); - //toGo = [-sin(finalAng), cos(finalAng), 0] * baseRef.firestats.fViewKickback * 0.7; - pl.vViewAngleOffsetTarget += toGo; - } - if(attackTypeUsed & BITS_AKIMBOCHOICE_RIGHT){ - - //right -#ifdef SERVER - TraceAttack_FireBullets(shellCount, (pl.origin + pl.view_ofs), baseRef.fAttackDamage, [acc, acc], (int)pl.activeweapon); -#endif - arg_thisWeapon.iClipAkimboLeft -= 1; - //TAGGG - shared random test - toGo = [-sin(finalAng), cos(finalAng), 0] * baseRef.firestats.fViewKickback * randomInRange_f(miner, maxer); - //toGo = [-sin(finalAng), cos(finalAng), 0] * baseRef.firestats.fViewKickback * 0.7; - pl.vViewAngleOffsetTarget += toGo; - } + //TAGGG - shared random test + //randoAngFactor = randomInRange_f(0, 1); + //finalAmount = baseRef.firestats.fViewKickback * randomInRange_f(miner, maxer); + randoAngFactor = 0.5; + finalAmount = baseRef.firestats.fViewKickback * 0.7; + finalAng = ( 90 - (angleRange/2) + randoAngFactor*( angleRange ) ) * (M_PI/180); + pl.addViewAngleOffset(finalAng, finalAmount); // TODO - be better shared later? // Syncing view kickback would need the random-ness to be handled between server/client, @@ -426,6 +403,29 @@ weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynami //cap it. pl.fAccuracyKickback = 0.1; } +}// weapon_base_onAttack_individual + + + +// Most weapons firing should call this to start, turns LEFT and RIGHT akimbo choices into their +// own "individual" calls, so twice if both are fired in the same frame. Same for view/accuracy +// kickback applied +void +weapon_base_onAttack_multi(player pl, weapondata_basic_t* basePRef, weapondynamic_t arg_thisWeapon, int shellCount, int attackTypeUsed) +{ + + //TAGGG - TODO! Re-picking the angle to kickback per hit may make more sense than varrying the intensity + // of the exact same direction for both shots, just a thought + if(attackTypeUsed & BITS_AKIMBOCHOICE_LEFT){ + //left + weapon_base_onAttack_individual(pl, basePRef, arg_thisWeapon, shellCount); + arg_thisWeapon.iClipLeft -= 1; + } + if(attackTypeUsed & BITS_AKIMBOCHOICE_RIGHT){ + weapon_base_onAttack_individual(pl, basePRef, arg_thisWeapon, shellCount); + arg_thisWeapon.iClipAkimboLeft -= 1; + } + // TODO - third person. This is mad old isn't it @@ -457,7 +457,7 @@ weapon_gun_burstFire( // and fire this very first frame. weapon_gun_fireBurstBullet(pl, basePRef, arg_thisWeapon); -}//weapon_gun_burstFire +}// weapon_gun_burstFire @@ -613,16 +613,12 @@ weapon_shotgun_onThink_reloadLogic(player pl, weapondata_gun_t* basePRef, weapon if (pl.ary_ammoTotal[baseRef.iAmmoDataID] <= 0 || arg_thisWeapon.iClipLeft >= baseRef.iClipMax) { //pl.shotgunReloadIndex = 3; - //if(pl.shotgunAddAmmoTime_canSet()){ - // pl.shotgunAddAmmoTime_setCooldownSetTime(); - - shotgunExtraRef = ary_shotgunExtra[pl.iShotgunExtraDataID]; + shotgunExtraRef = ary_shotgunExtra[pl.iShotgunExtraDataID]; - TS_Weapons_ViewAnimation((*shotgunExtraRef).shotgunReload3_seq, (*shotgunExtraRef).shotgunReload3_Duration); - weapon_base_setWholeAttackDelay(pl, (*shotgunExtraRef).shotgunReload3_Duration); - pl.shotgunReloadIndex = 0; - pl.isReloading = FALSE; - //} + TS_Weapons_ViewAnimation((*shotgunExtraRef).shotgunReload3_seq, (*shotgunExtraRef).shotgunReload3_Duration); + weapon_base_setWholeAttackDelay(pl, (*shotgunExtraRef).shotgunReload3_Duration); + pl.shotgunReloadIndex = 0; + pl.isReloading = FALSE; }else{ shotgunExtraRef = ary_shotgunExtra[pl.iShotgunExtraDataID]; @@ -630,19 +626,15 @@ weapon_shotgun_onThink_reloadLogic(player pl, weapondata_gun_t* basePRef, weapon weapon_base_setWholeAttackDelay(pl, (*shotgunExtraRef).shotgunReload2_Duration); pl.shotgunReloadIndex = 2; - //if(pl.shotgunAddAmmoTime_canSet()){ - // pl.shotgunAddAmmoTime_setCooldownSetTime(); - printfline("I SET shotgunAddAmmoTime!"); - - //pl.shotgunAddAmmoSoundTime = (*shotgunExtraRef).shotgunReload2_Duration - ((*shotgunExtraRef).shotgunReload2_ammoLoadDelay - 0.03f); - #ifdef CLIENT - View_AddEvent(viewEv_playShotgunInsertShellSound, (*shotgunExtraRef).shotgunReload2_Duration - ((*shotgunExtraRef).shotgunReload2_ammoLoadDelay - 0.03f)); - #endif - - pl.shotgunAddAmmoTime = (*shotgunExtraRef).shotgunReload2_Duration - (*shotgunExtraRef).shotgunReload2_ammoLoadDelay; - //} + printfline("I SET shotgunAddAmmoTime!"); + //pl.shotgunAddAmmoSoundTime = (*shotgunExtraRef).shotgunReload2_Duration - ((*shotgunExtraRef).shotgunReload2_ammoLoadDelay - 0.03f); + #ifdef CLIENT + View_AddEvent(viewEv_playShotgunInsertShellSound, (*shotgunExtraRef).shotgunReload2_Duration - ((*shotgunExtraRef).shotgunReload2_ammoLoadDelay - 0.03f)); + #endif + pl.shotgunAddAmmoTime = (*shotgunExtraRef).shotgunReload2_Duration - (*shotgunExtraRef).shotgunReload2_ammoLoadDelay; + //arg_thisWeapon.iClipLeft++; //pl.ary_ammoTotal[baseRef.iAmmoDataID]--; @@ -2368,8 +2360,6 @@ viewEv_weapon_ShowMuzzleFlash(void) }else if(pl.iMuzzleFlashAkimboChoice==BITS_AKIMBOCHOICE_RIGHT){ testCount2++; } - printf("Hello? %i %i\n", testCount1, testCount2); - } } diff --git a/zpak001.pk3dir/default.cfg b/zpak001.pk3dir/default.cfg index c9f36ea..2030e8f 100644 --- a/zpak001.pk3dir/default.cfg +++ b/zpak001.pk3dir/default.cfg @@ -43,7 +43,7 @@ bind "f1" "vote yes" bind "f2" "vote no" bind "m" "chooseteam" bind "b" "buy" -bind "f" "firemode" +bind "f" "+firemode" bind "n" "+useitems" // stunt-related (TODO) bind "MOUSE3" "+alt1"