From 4f7defcb98aeb9e893e404fa1718792a3c5711d3 Mon Sep 17 00:00:00 2001 From: Marco Hladik Date: Wed, 7 Dec 2016 01:05:06 +0100 Subject: [PATCH] Added info_map_parameters (setting buyrestrictions) Added trigger_camera Added ammo-buying restrictions (money wasn't taken into account) Added spawning of buyzones when there aren't any Added sound when buying ammo Added Client_TriggerCamera as part of EV_CAMERATRIGGER Fixed the Knife not showing/animating --- Source/Client/Defs.h | 5 ++ Source/Client/Draw.c | 9 +++- Source/Client/Event.c | 19 +++++-- Source/Client/progs.src | 1 + Source/Globals.h | 1 + Source/Server/Ammo.c | 5 ++ Source/Server/Client.c | 35 +++++++------ Source/Server/Defs.h | 10 ++-- Source/Server/Entities.c | 2 +- Source/Server/FuncBombTarget.c | 4 +- Source/Server/FuncBuyZone.c | 54 +++++++++++++++++++- Source/Server/Main.c | 9 +++- Source/Server/Player.c | 2 + Source/Server/Rules.c | 38 ++++++++++++++ Source/Server/Spawn.c | 21 ++++++-- Source/Server/Triggers.c | 20 ++++++++ Source/Server/progs.src | 1 + Source/Shared/WeaponBase.c | 2 +- Source/Shared/WeaponKnife.c | 92 ++++++++++++++++++++++++++++++++++ Source/Shared/Weapons.c | 2 +- 20 files changed, 293 insertions(+), 39 deletions(-) create mode 100644 Source/Shared/WeaponKnife.c diff --git a/Source/Client/Defs.h b/Source/Client/Defs.h index 394673c1..273b9d57 100644 --- a/Source/Client/Defs.h +++ b/Source/Client/Defs.h @@ -41,5 +41,10 @@ vector vMousePos; .string sSoundSample; .float fVolume; +// Camera Fields +vector vCameraPos; +vector vCameraAngle; +float fCameraTime; + void View_PlayAnimation( int iSequence ); void Sound_Delayed( string sSample, float fVol, float fDelay ); diff --git a/Source/Client/Draw.c b/Source/Client/Draw.c index 341ef204..7f293948 100644 --- a/Source/Client/Draw.c +++ b/Source/Client/Draw.c @@ -34,7 +34,14 @@ void CSQC_UpdateView( float fWinWidth, float fWinHeight, float fGameFocus ) { setproperty( VF_DRAWCROSSHAIR, 0 ); addentities( MASK_ENGINE ); - View_DrawViewModel(); + + // When Cameratime is active, draw on the forced coords instead + if ( fCameraTime > time ) { + setproperty( VF_ORIGIN, vCameraPos) ; + setproperty( VF_ANGLES, vCameraAngle ); + } else { + View_DrawViewModel(); + } renderscene(); if( fGameFocus == TRUE ) { diff --git a/Source/Client/Event.c b/Source/Client/Event.c index 163dbaba..d23d2275 100644 --- a/Source/Client/Event.c +++ b/Source/Client/Event.c @@ -26,8 +26,8 @@ Init all the cmds in one place ================= */ void CSQC_ConsoleCommand_Init( void ) { - registercommand( "vgui_buymenu" ); - registercommand( "vgui_teammenu" ); + registercommand( "buy" ); + registercommand( "chooseteam" ); registercommand( "use" ); } @@ -42,13 +42,13 @@ float CSQC_ConsoleCommand( string sCMD ) { tokenize( sCMD ); switch ( argv(0) ) { - case "vgui_buymenu": + case "buy": if( getstatf( STAT_BUYZONE ) == TRUE ) { fVGUI_Display = VGUI_BM_MAIN; } return TRUE; break; - case "vgui_teammenu": + case "chooseteam": if( getstatf( STAT_TEAM ) == 0 ) { fVGUI_Display = VGUI_TEAMSELECT; } @@ -94,6 +94,17 @@ void CSQC_Parse_Event( void ) { float fStyle = readbyte(); Effect_BreakModel( vPos, vSize, '0 0 0', fStyle ); + } else if ( fHeader == EV_CAMERATRIGGER ) { + + vCameraPos_x = readcoord(); + vCameraPos_y = readcoord(); + vCameraPos_z = readcoord(); + + vCameraAngle_x = readcoord(); + vCameraAngle_y = readcoord(); + vCameraAngle_z = readcoord(); + + fCameraTime = time + readfloat(); } } diff --git a/Source/Client/progs.src b/Source/Client/progs.src index 443872e2..51749493 100644 --- a/Source/Client/progs.src +++ b/Source/Client/progs.src @@ -18,6 +18,7 @@ Defs.h ../Shared/WeaponFiveSeven.c ../Shared/WeaponG3SG1.c ../Shared/WeaponGlock18.c +../Shared/WeaponKnife.c ../Shared/WeaponM3.c ../Shared/WeaponM4A1.c ../Shared/WeaponMac10.c diff --git a/Source/Globals.h b/Source/Globals.h index aa32e1d4..dcf11c51 100644 --- a/Source/Globals.h +++ b/Source/Globals.h @@ -166,6 +166,7 @@ enum { EV_WEAPON_SECONDARYATTACK, EV_WEAPON_RELOAD, EV_MODELGIB, + EV_CAMERATRIGGER }; // Submodel materials diff --git a/Source/Server/Ammo.c b/Source/Server/Ammo.c index f79426b2..f236cf43 100644 --- a/Source/Server/Ammo.c +++ b/Source/Server/Ammo.c @@ -59,6 +59,10 @@ void Ammo_BuySecondary( void ) { float fNew = ceil( ( (float)iRequiredAmmo / (float)ammoTable[ wptTable[ self.iSlotSecondary ].iCaliber ].iSize ) ); for ( int i = 0; i < fNew; i++ ) { + if ( self.fMoney - ammoTable[ wptTable[ self.iSlotSecondary ].iCaliber ].iPrice < 0 ) { + break; + } + self.(wptTable[ self.iSlotSecondary ].iCaliberfld) += ammoTable[ wptTable[ self.iSlotSecondary ].iCaliber ].iSize; self.fMoney -= ammoTable[ wptTable[ self.iSlotSecondary ].iCaliber ].iPrice; @@ -79,6 +83,7 @@ void CSEv_GamePlayerBuyAmmo_f( float fType ) { Ammo_BuySecondary(); } + sound( self, CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM ); Weapon_UpdateCurrents(); self.fAttackFinished = time + 1.0; } diff --git a/Source/Server/Client.c b/Source/Server/Client.c index b1b7ea48..f51878d6 100644 --- a/Source/Server/Client.c +++ b/Source/Server/Client.c @@ -47,23 +47,8 @@ void PlayerPostThink( void ) { } void PutClientInServer( void ) { - entity eSpawn; entity eTarget = world; - eSpawn = find (world, classname, "trigger_camera"); - - self.origin = eSpawn.origin + '0 0 1'; - - // Rotate camera towards a target - if( eSpawn.target ) { - eTarget = find( eTarget, targetname, eSpawn.target ); - self.angles = vectoangles( eTarget.origin - eSpawn.origin ); - self.angles_x *= -1; - } else { - self.angles = eSpawn.angles; - } - - self.fixangle = TRUE; - self.classname = "spectator"; + Spawn_MakeSpectator(); // Because we don't want to reset these when we die @@ -96,3 +81,21 @@ void Client_SendEvent( entity eClient, float fEVType ) { msg_entity = eClient; multicast( '0 0 0', MULTICAST_ONE ); } + +void Client_TriggerCamera( entity eTarget, vector vPos, vector vEndPos, float fResetTime ) { + WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET ); + + WriteByte( MSG_MULTICAST, EV_CAMERATRIGGER ); + + WriteCoord( MSG_MULTICAST, vPos_x ); + WriteCoord( MSG_MULTICAST, vPos_y ); + WriteCoord( MSG_MULTICAST, vPos_z ); + + WriteCoord( MSG_MULTICAST, vEndPos_x ); + WriteCoord( MSG_MULTICAST, vEndPos_y ); + WriteCoord( MSG_MULTICAST, vEndPos_z ); + + WriteFloat( MSG_MULTICAST, fResetTime ); + msg_entity = eTarget; + multicast( '0 0 0', MULTICAST_ONE ); +} diff --git a/Source/Server/Defs.h b/Source/Server/Defs.h index 6f7e0941..9fc9f5e3 100644 --- a/Source/Server/Defs.h +++ b/Source/Server/Defs.h @@ -46,29 +46,26 @@ float EFFECT_BLOOD; // Match specific fields int iWon_T; int iWon_CT; - int iAlivePlayers_T; int iAlivePlayers_CT; int fOldInGamePlayers; - float fGameState; float fGameTime; +// Weapon specific fields .int iCurrentClip; .int iCurrentCaliber; - .int iSlotMelee, iSlotPrimary, iSlotSecondary, iSlotGrenade; - .float fAttackFinished; - .float fAccuracy; // Game specific fields int iHostagesMax; int iHostagesRescued; - int iBombZones; int iRescueZones; +int iBuyZones; +int iBuyRestriction; // For info_map_parameters // Generic entity fields .int iUsable; @@ -105,6 +102,7 @@ void Spawn_RespawnClient( float fTeam ); void Spawn_CreateClient( float fTeam ); void Spawn_MakeSpectator( void ); void Client_SendEvent( entity eClient, float fEVType ); +void Client_TriggerCamera( entity eTarget, vector vPos, vector vEndPos, float fResetTime ); void Weapon_SwitchBest( void ); void OpenCSGunBase_AccuracyCalc( void ); diff --git a/Source/Server/Entities.c b/Source/Server/Entities.c index d83783a5..840afaec 100644 --- a/Source/Server/Entities.c +++ b/Source/Server/Entities.c @@ -216,7 +216,7 @@ void Entities_RenderSetup( void ) { if ( self.rendermode == RENDERMODE_ADDITIVE ) { self.effects = EF_ADDITIVE; } else if ( self.rendermode == RENDERMODE_GLOW ) { - self.effects = EF_FULLBRIGHT; + self.effects = EF_ADDITIVE | EF_FULLBRIGHT; } } } diff --git a/Source/Server/FuncBombTarget.c b/Source/Server/FuncBombTarget.c index 858db0fb..21aa4aae 100644 --- a/Source/Server/FuncBombTarget.c +++ b/Source/Server/FuncBombTarget.c @@ -31,9 +31,7 @@ void func_bomb_target_touch( void ) { /* ================= -SPAWN: func_hostage_rescue - -Entry function for the rescue area-markings. +SPAWN: func_bomb_target ================= */ void func_bomb_target( void ) { diff --git a/Source/Server/FuncBuyZone.c b/Source/Server/FuncBuyZone.c index 70c4a9ea..7c290885 100644 --- a/Source/Server/FuncBuyZone.c +++ b/Source/Server/FuncBuyZone.c @@ -40,7 +40,59 @@ void func_buyzone( void ) { self.angles = '0 0 0'; self.movetype = MOVETYPE_NONE; self.solid = SOLID_TRIGGER; - setmodel (self, self.model); + + if ( self.model ) { + setmodel( self, self.model ); + } else { + self.mins = '-128 -128 -36'; + self.maxs = '128 128 36'; + setsize( self, self.mins, self.maxs ); + } + self.model = 0; self.touch = func_buyzone_touch; + iBuyZones++; +} + +/* +================= +Game_CreateBuyZones + +Called by StartFrame if we somehow got no buy zones +================= +*/ +void Game_CreateBuyZones( void ) { + entity eOldSelf; + entity eFind; + + if ( iBuyRestriction == BUY_T || iBuyRestriction == BUY_BOTH ) { + eFind = findchain( classname, "info_player_start" ); + + while ( eFind ) { + entity eBuyZoneT = spawn(); + setorigin( eBuyZoneT, eFind.origin ); + eOldSelf = self; + self = eBuyZoneT; + func_buyzone(); + self.team = TEAM_T; + self = eOldSelf; + eFind = eFind.chain; + } + } + + if ( iBuyRestriction == BUY_CT || iBuyRestriction == BUY_BOTH ) { + eFind = findchain( classname, "info_player_start" ); + + while ( eFind ) { + entity eBuyZoneCT = spawn(); + setorigin( eBuyZoneCT, eFind.origin ); + + eOldSelf = self; + self = eBuyZoneCT; + func_buyzone(); + self.team = TEAM_CT; + self = eOldSelf; + eFind = eFind.chain; + } + } } diff --git a/Source/Server/Main.c b/Source/Server/Main.c index cbab1231..6e02520b 100644 --- a/Source/Server/Main.c +++ b/Source/Server/Main.c @@ -25,11 +25,16 @@ void SetChangeParms( void ) {} // Run every frame... by world? void StartFrame( void ) { + // We've got hostages, but no rescue zones, create some if ( !iRescueZones && iHostagesMax > 0 ) { Game_CreateRescueZones(); } - + + if ( iBuyZones == 0 ) { + Game_CreateBuyZones(); + } + int iInGamePlayers; // Sigh, check if clients are in the game if ( find( world, classname , "player" ) != world ) { @@ -85,6 +90,8 @@ void worldspawn( void ) { precache_sound( "hostage/hos4.wav" ); precache_sound( "hostage/hos5.wav" ); + precache_sound( "items/9mmclip1.wav" ); + precache_sound( "weapons/ak47-1.wav" ); precache_sound( "weapons/ak47-2.wav" ); precache_sound( "weapons/ak47_boltpull.wav" ); diff --git a/Source/Server/Player.c b/Source/Server/Player.c index 3129432b..360e0a79 100644 --- a/Source/Server/Player.c +++ b/Source/Server/Player.c @@ -32,6 +32,8 @@ void Player_Death( void ) { eCorpse.frame = 93; // TODO: Pick the right frame Spawn_MakeSpectator(); + self.classname = "player"; + self.health = 0; if ( self.team == TEAM_T ) { iAlivePlayers_T--; diff --git a/Source/Server/Rules.c b/Source/Server/Rules.c index bb86a6cb..12676c45 100644 --- a/Source/Server/Rules.c +++ b/Source/Server/Rules.c @@ -18,6 +18,13 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +enum { + BUY_BOTH, + BUY_CT, + BUY_T, + BUY_NEITHER +}; + // Checks if it is possible for players to buy anything float Rules_BuyingPossible( void ) { if ( fGameState == GAME_ACTIVE ) { @@ -28,6 +35,24 @@ float Rules_BuyingPossible( void ) { } } + if ( iBuyRestriction == BUY_NEITHER ) { + centerprint( self, "Sorry, you aren't meant to be buying anything.\n" ); + self.fAttackFinished = time + 1.0; + return FALSE; + } + + if ( iBuyRestriction != BUY_BOTH ) { + if ( iBuyRestriction == BUY_CT && self.team == TEAM_T ) { + centerprint( self, "Terrorists aren't allowed to buy anything!\n" ); + self.fAttackFinished = time + 1.0; + return FALSE; + } else if ( iBuyRestriction == BUY_T && self.team == TEAM_CT ) { + centerprint( self, "Counter-Terrorists aren't allowed to buy anything!\n" ); + self.fAttackFinished = time + 1.0; + return FALSE; + } + } + return TRUE; } @@ -80,3 +105,16 @@ void Rules_TimeOver( void ) { Rules_RoundOver( 0 ); } } + +/* +================= +SPAWN: info_map_parameters + +Let's map authors decide who can buy stuff and who CAN'T. +Also allows people to set the bomb placing radius incase you want to use info_bomb_target. +================= +*/ +.float buying; +void info_map_parameters( void ) { + iBuyRestriction = self.buying; +} diff --git a/Source/Server/Spawn.c b/Source/Server/Spawn.c index 87f208a3..4589aa31 100644 --- a/Source/Server/Spawn.c +++ b/Source/Server/Spawn.c @@ -95,6 +95,7 @@ void Spawn_CreateClient( float fCharModel ) { self.team = TEAM_T; iAlivePlayers_T++; + Weapon_AddItem( WEAPON_KNIFE ); Weapon_AddItem( WEAPON_GLOCK18 ); Weapon_GiveAmmo( WEAPON_GLOCK18, 40 ); //Weapon_AddItem( WEAPON_C4BOMB ); @@ -102,6 +103,7 @@ void Spawn_CreateClient( float fCharModel ) { self.team = TEAM_CT; iAlivePlayers_CT++; + Weapon_AddItem( WEAPON_KNIFE ); Weapon_AddItem( WEAPON_USP45 ); Weapon_GiveAmmo( WEAPON_USP45, 24 ); } @@ -116,6 +118,9 @@ void Spawn_CreateClient( float fCharModel ) { // This is called on connect and whenever a player dies void Spawn_MakeSpectator( void ) { + entity eSpawn; + self.classname = "spectator"; + self.health = 0; self.takedamage = DAMAGE_NO; self.solid = SOLID_NOT; @@ -130,6 +135,17 @@ void Spawn_MakeSpectator( void ) { forceinfokey( self, "*spectator", "1" ); // Make sure we are known as a spectator + // Go find a camera if we aren't dead + eSpawn = find (world, classname, "trigger_camera"); + + if ( eSpawn ) { + self.origin = eSpawn.origin + '0 0 1'; + self.angles = eSpawn.angles; + //self.angles_x = eSpawn.angles_x * -1; + } + + self.fixangle = TRUE; + // Clear all the ammo stuff for ( int i = 0; i < CS_WEAPON_COUNT; i++ ) { self.(wptTable[ i ].iClipfld) = 0; @@ -157,10 +173,10 @@ void CSEv_GamePlayerSpawn_f( float fChar ) { self.team = TEAM_CT; } + Spawn_MakeSpectator(); self.classname = "player"; self.fCharModel = fChar; self.health = 0; - Spawn_MakeSpectator(); break; default: self.fCharModel = fChar; @@ -178,7 +194,4 @@ void info_player_start( void ) { void info_player_deathmatch( void ) { } -// Spectator Spawnpoints -void trigger_camera( void ) { -} void info_target( void ) { } diff --git a/Source/Server/Triggers.c b/Source/Server/Triggers.c index f0f2fb36..c74dad2e 100644 --- a/Source/Server/Triggers.c +++ b/Source/Server/Triggers.c @@ -70,6 +70,26 @@ void trigger_multiple( void ) { self.touch = trigger_multiple_touch; } +/* +================= +trigger_camera +================= +*/ +void trigger_camera( void ) { + static void trigger_camera_use( void ) { + Client_TriggerCamera( eActivator, self.origin, self.angles, self.wait ); + } + + entity eTarget; + eTarget = find( world, targetname, self.target ); + if( self.target ) { + self.angles = vectoangles( eTarget.origin - self.origin ); + self.angles_x *= -1; + } + + self.vUse = trigger_camera_use; +} + /* ================= multi_manager diff --git a/Source/Server/progs.src b/Source/Server/progs.src index 1f906d1f..4575867d 100644 --- a/Source/Server/progs.src +++ b/Source/Server/progs.src @@ -17,6 +17,7 @@ Defs.h ../Shared/WeaponFiveSeven.c ../Shared/WeaponG3SG1.c ../Shared/WeaponGlock18.c +../Shared/WeaponKnife.c ../Shared/WeaponM3.c ../Shared/WeaponM4A1.c ../Shared/WeaponMac10.c diff --git a/Source/Shared/WeaponBase.c b/Source/Shared/WeaponBase.c index c3a7329f..d8b1c165 100644 --- a/Source/Shared/WeaponBase.c +++ b/Source/Shared/WeaponBase.c @@ -23,7 +23,7 @@ weaponinfo_t wptDEFAULT = { 0, 0, 0, 0, 240, 0, 0, 0, 0, 0.0, 0.0, 0, 0.0, 0.0, weaponinfo_t wptTable[ CS_WEAPON_COUNT ] = { wptDEFAULT, - wptDEFAULT, + wptKNIFE, wptUSP45, wptGLOCK18, wptDEAGLE, diff --git a/Source/Shared/WeaponKnife.c b/Source/Shared/WeaponKnife.c new file mode 100644 index 00000000..2d88396d --- /dev/null +++ b/Source/Shared/WeaponKnife.c @@ -0,0 +1,92 @@ +/* +OpenCS Project +Copyright (C) 2015 Marco "eukara" Hladik + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +.int iClip_GLOCK18; + +#ifdef SSQC +.int iMode_GLOCK18; +#else +int iWeaponMode_GLOCK18; +#endif + +// Weapon Info +weaponinfo_t wptKNIFE = { + WEAPON_KNIFE, // Identifier + SLOT_MELEE, + 0, // Price + 0, // Caliber ID + 1.0, // Max Player Speed + 1, // Bullets Per Shot + 1, // Clip/MagSize + 15, // Damage Per Bullet + 1, // Penetration Multiplier + 64, // Bullet Range + 0.75, // Range Modifier + TYPE_SEMI, + 0.15, // Attack-Delay + 1.0, // Reload-Delay + iAmmo_9MM, // Caliber Pointer + iClip_GLOCK18, // Clip Pointer + 1, // Accuracy Divisor + 1.0, // Accuracy Offset + 1.0 // Max Inaccuracyy +}; + +// Anim Table +enum { + ANIM_KNIFE_IDLE1, + ANIM_KNIFE_SLASH1, + ANIM_KNIFE_SLASH2, + ANIM_KNIFE_DRAW, + ANIM_KNIFE_STAB, + ANIM_KNIFE_STAB_MISS, + ANIM_KNIFE_MIDSLASH1, + ANIM_KNIFE_MIDSLASH2 +}; + +void WeaponKNIFE_Draw( void ) { +#ifdef SSQC + Client_SendEvent( self, EV_WEAPON_DRAW ); +#else + View_PlayAnimation( ANIM_KNIFE_DRAW ); +#endif +} + +void WeaponKNIFE_PrimaryFire( void ) { +#ifdef SSQC + Client_SendEvent( self, EV_WEAPON_PRIMARYATTACK ); + self.fAttackFinished = time + wptKNIFE.fAttackFinished; +#else + if ( random() <= 0.5 ) { + View_PlayAnimation( ANIM_KNIFE_SLASH1 ); + } else { + View_PlayAnimation( ANIM_KNIFE_SLASH2 ); + } +#endif +} + +void WeaponKNIFE_Secondary( void ) { +#ifdef SSQC + Client_SendEvent( self, EV_WEAPON_SECONDARYATTACK ); + self.fAttackFinished = time + wptKNIFE.fAttackFinished; +#else + View_PlayAnimation( ANIM_KNIFE_STAB ); +#endif +} diff --git a/Source/Shared/Weapons.c b/Source/Shared/Weapons.c index 76d230dc..ff409674 100644 --- a/Source/Shared/Weapons.c +++ b/Source/Shared/Weapons.c @@ -22,7 +22,7 @@ void Temp_Nothing( void ) { } weaponfunc_t wpnFuncTable[ CS_WEAPON_COUNT ] = { { Temp_Nothing, Temp_Nothing, Temp_Nothing, Temp_Nothing }, - { Temp_Nothing, Temp_Nothing, Temp_Nothing, Temp_Nothing }, + { WeaponKNIFE_Draw, WeaponKNIFE_PrimaryFire, WeaponKNIFE_Secondary, Temp_Nothing }, { WeaponUSP45_Draw, WeaponUSP45_PrimaryFire, WeaponUSP45_Secondary, WeaponUSP45_Reload }, { WeaponGLOCK18_Draw, WeaponGLOCK18_PrimaryFire, WeaponGLOCK18_Secondary, WeaponGLOCK18_Reload }, { WeaponDEAGLE_Draw, WeaponDEAGLE_PrimaryFire, Temp_Nothing, WeaponDEAGLE_Reload },