diff --git a/Source/Builtins.h b/Source/Builtins.h index 8c48eff4..a604ea58 100755 --- a/Source/Builtins.h +++ b/Source/Builtins.h @@ -1992,7 +1992,7 @@ float(float modidx, float framenum, int eventidx, __out float timestamp, __out i Reports an indexed event within a model's animation. Writes to timestamp,code,data arguments on success. Returns false if the animation/event/model was out of range/invalid. Does not consider looping animations (retry from index 0 if it fails and you know that its a looping animation). This builtin is more annoying to use than getnextmodelevent, but can be made to deal with multiple events with the exact same timestamp. */ #endif -#define dotproduct(v1,v2) ((vector)(v1)*(vector)(v2)) +#define dotproduct(a,b) ((vector)(a)*(vector)(b)) vector(vector v1, vector v2) crossproduct = #0:crossproduct; /* Part of FTE_QC_CROSSPRODUCT Small helper function to calculate the crossproduct of two vectors. */ diff --git a/Source/Client/View.c b/Source/Client/View.c index 737fda75..0e8fd9e6 100755 --- a/Source/Client/View.c +++ b/Source/Client/View.c @@ -181,7 +181,7 @@ void View_DrawViewModel( void ) { makevectors( getproperty( VF_ANGLES ) ); eViewModel.origin = getproperty( VF_ORIGIN ) + '0 0 -1' + ( v_forward * ( fBob * 0.4 ) ); - eViewModel.angles = getproperty( VF_ANGLES ); + eViewModel.angles = getproperty( VF_ANGLES ) + vPunchAngle; // Left-handed weapons if ( autocvar_v_lefthanded ) { diff --git a/Source/Menu/Defs.h b/Source/Menu/Defs.h index 61f0dd0b..1ac63983 100644 --- a/Source/Menu/Defs.h +++ b/Source/Menu/Defs.h @@ -39,6 +39,7 @@ var float fInputKeyDown; var float fMouseClick; var float fButtonAlpha[8]; var float fScrollWheel; +var int iHLContent = 0; var vector vMenuButtonsSize; diff --git a/Source/Menu/Init.c b/Source/Menu/Init.c index 239c1891..27740504 100644 --- a/Source/Menu/Init.c +++ b/Source/Menu/Init.c @@ -45,6 +45,11 @@ void m_init( void ) { FONT_MENU = loadfont( "menu", "gfx/menuchars", "32", -1 ); vMenuButtonsSize = drawgetimagesize( "gfx/shell/btns_main" ); + + // For those peeps who don't read or don't want to follow the instructions + if ( whichpack( "sound/items/9mmclip1.wav" ) ) { + iHLContent = TRUE; + } } /* diff --git a/Source/Menu/MenuMain.c b/Source/Menu/MenuMain.c index 22ab3b41..1b00fdf0 100644 --- a/Source/Menu/MenuMain.c +++ b/Source/Menu/MenuMain.c @@ -39,6 +39,14 @@ void Menu_Main( void ) { iMenu = MENU_QUIT; } + if ( iHLContent == FALSE ) { + Object_Frame( '232 200', '400 96' ); + Object_Label( '244 212', "Warning", '16 16' ); + Object_Label( '244 248', "You have not copied over your 'valve' directory", '8 8' ); + Object_Label( '244 258', "from Half-Life. This will cause missing models,", '8 8' ); + Object_Label( '244 268', "sounds and textures. Be warned!", '8 8' ); + } + Object_Button( '72 188', BTN_CONSOLE, Main_ButtonConsole, fButtonAlpha[0] ); Object_Button( '72 272', BTN_CONFIG, Main_ButtonConfiguration, fButtonAlpha[1] ); diff --git a/Source/Server/Damage.c b/Source/Server/Damage.c index 7566c7c8..47f97b72 100644 --- a/Source/Server/Damage.c +++ b/Source/Server/Damage.c @@ -98,7 +98,8 @@ void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos // Modify the damage based on the location if ( trace_surface_id == BODY_HEAD ) { if ( eTarget.iEquipment & EQUIPMENT_HELMET ) { - iDamage *= 0.5; + sound( self, CHAN_ITEM, "weapons/ric_metal-2.wav", 1, ATTN_IDLE ); + iDamage = 0; eTarget.iEquipment -= EQUIPMENT_HELMET; } else { iDamage *= 4; diff --git a/Source/Server/Defs.h b/Source/Server/Defs.h index 19a95e75..3a8e8c7c 100755 --- a/Source/Server/Defs.h +++ b/Source/Server/Defs.h @@ -28,8 +28,15 @@ var float autocvar_mp_freezetime = 6; var float autocvar_mp_c4timer = 45; var float autocvar_mp_roundtime = 5; var float autocvar_mp_fillweapons = 0; +var float autocvar_mp_timelimit = 60; var string autocvar_motdfile = "motd.txt"; + +// Mapcycle features +var string autocvar_mapcyclefile = "mapcycle.txt"; +var int iMapCycleCount; +string *sMapCycle; + // Hit Group standards enum { BODY_DEFAULT, diff --git a/Source/Server/Main.c b/Source/Server/Main.c index c55728d4..a6a1d575 100755 --- a/Source/Server/Main.c +++ b/Source/Server/Main.c @@ -19,7 +19,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ void main( void ) {} + void SetNewParms( void ) {} + void SetChangeParms( void ) {} void SV_SendChat( entity eSender, string sMessage, entity eEnt, float fType ) { @@ -141,6 +143,7 @@ It's the map entity, literally */ void worldspawn( void ) { int iMOTDLines = 0; + // Let's load materials.txt because someone thought this was the best idea string sTemp; filestream fileMaterial = fopen( "sound/materials.txt", FILE_READ ); @@ -157,6 +160,7 @@ void worldspawn( void ) { } // The message of the day. + localcmd( sprintf( "echo [MOTD] Loading %s.\n", autocvar_motdfile ) ); filestream fmMOTD = fopen( autocvar_motdfile, FILE_READ ); for ( int i = 0; i < 25; i++ ) { sTemp = fgets( fmMOTD ); @@ -174,8 +178,45 @@ void worldspawn( void ) { localcmd( sprintf( "serverinfo motdlength %i\n", iMOTDLines ) ); fclose( fmMOTD ); + // The mapcycle information. + localcmd( sprintf( "echo [MAPCYCLE] Loading %s.\n", autocvar_mapcyclefile ) ); + filestream fmMapcycle = fopen( autocvar_mapcyclefile, FILE_READ ); + for ( int i = 0;; i++ ) { + sTemp = fgets( fmMapcycle ); + if not ( sTemp ) { + break; + } + + if ( sTemp != __NULL__ ) { + iMapCycleCount++; + } + } + + fseek( fmMapcycle, 0 ); + localcmd( sprintf( "echo [MAPCYCLE] List has %i maps.\n", iMapCycleCount ) ); + sMapCycle = memalloc( sizeof( string ) * iMapCycleCount ); + for ( int i = 0; i < iMapCycleCount; i++ ) { + sMapCycle[ i ] = fgets( fmMapcycle ); + } + fclose( fmMapcycle ); + + for ( int i = 0; i < iMapCycleCount; i++ ) { + if ( sMapCycle[ i ] == mapname ) { + if ( ( i + 1 ) < iMapCycleCount ) { + localcmd( sprintf( "echo [MAPCYCLE] Next map: %s\n", sMapCycle[ i + 1 ] ) ); + } else { + break; + } + } + } + + // Let's make our version information clear localcmd( sprintf( "serverinfo fcs_ver %s\n", __DATE__ ) ); + // Tell em the next map in the list we should load. + localcmd( sprintf( "serverinfo maplist %s\n", iMapCycleCount ) ); + + // All the important precaches for ( int i = 1; i < CS_WEAPON_COUNT; i++ ) { precache_model( sWeaponModels[ i ] ); } diff --git a/Source/Server/Rules.c b/Source/Server/Rules.c index 1ab9bf8b..e46166e2 100755 --- a/Source/Server/Rules.c +++ b/Source/Server/Rules.c @@ -191,6 +191,8 @@ void Rules_RoundOver( int iTeamWon, int iMoneyReward, float fSilent ) { } Money_QueTeamReward( iTeamWon, iMoneyReward ); Timer_Begin( 5, GAME_END); // Round is over, 5 seconds til a new round starts + + iBombPlanted = 0; } /* diff --git a/Source/Server/Spawn.c b/Source/Server/Spawn.c index 5987097f..e6d827dd 100755 --- a/Source/Server/Spawn.c +++ b/Source/Server/Spawn.c @@ -257,6 +257,11 @@ void CSEv_GamePlayerSpawn_f( float fChar ) { self.fSlotPrimary = 0; self.fSlotSecondary = 0; self.fSlotGrenade = 0; + self.iEquipment = 0; + + if ( iAlivePlayers_T + iAlivePlayers_CT == 1 ) { + Rules_RoundOver( 0, 0, FALSE ); + } // Spawn the players immediately when its in the freeze state switch ( fGameState ) { @@ -270,32 +275,8 @@ void CSEv_GamePlayerSpawn_f( float fChar ) { return; } else if( fChar < 5 ) { self.team = TEAM_T; - - if ( fGameState == GAME_ACTIVE && iAlivePlayers_T == 0 ) { - self.fCharModel = fChar; - Spawn_CreateClient( fChar ); - - if ( iBombZones > 0 ) { - Weapon_AddItem( WEAPON_C4BOMB ); - centerprint( self, "You have the bomb!\nFind the target zone or DROP\nthe bomb for another Terrorist." ); - } - break; - } } else { self.team = TEAM_CT; - - if ( fGameState == GAME_ACTIVE && iAlivePlayers_CT == 0 ) { - self.fCharModel = fChar; - Spawn_CreateClient( fChar ); - - if ( iVIPZones > 0 ) { - self.team = TEAM_VIP; - Spawn_RespawnClient( self.team ); - centerprint( self, "You are the VIP\nMake your way to the safety zones!" ); - forceinfokey( self, "*dead", "2" ); - } - break; - } } Spawn_MakeSpectator(); diff --git a/Source/Server/Timer.c b/Source/Server/Timer.c index 425e90a7..a8024fa4 100755 --- a/Source/Server/Timer.c +++ b/Source/Server/Timer.c @@ -47,6 +47,20 @@ Called once every frame to check the status of things ================= */ void Timer_Update( void ) { + // This map has been played enough we think + if ( time >= ( cvar( "mp_timelimit" ) * 60 ) ) { + for ( int i = 0; i < iMapCycleCount; i++ ) { + if ( sMapCycle[ i ] == mapname ) { + if ( ( i + 1 ) < iMapCycleCount ) { + localcmd( sprintf( "changelevel %s\n", sMapCycle[ i + 1 ] ) ); + return; + } else { + localcmd( sprintf( "changelevel %s\n", sMapCycle[ 0 ] ) ); + } + } + } + } + if ( fGameState == GAME_INACTIVE ) { return; } diff --git a/Source/Shared/Equipment.c b/Source/Shared/Equipment.c index 79f964b1..cefb2e28 100755 --- a/Source/Shared/Equipment.c +++ b/Source/Shared/Equipment.c @@ -35,10 +35,27 @@ void CSEv_PlayerBuyEquipment_f( float fID ) { } if ( ( self.fMoney - eqptTable[ fID ].iPrice ) >= 0 ) { - if ( eqptTable[ fID ].iID == WEAPON_HEGRENADE ) { + if ( eqptTable[ fID ].iID == EQUIPMENT_DEFUSALKIT ) { + if ( !( self.iEquipment & EQUIPMENT_DEFUSALKIT ) ) { + self.iEquipment |= EQUIPMENT_DEFUSALKIT; + Money_AddMoney( self, -200 ); + sound( self, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE ); + } else { + centerprint( self, "You already have a defusal kit!" ); + } + } else if ( eqptTable[ fID ].iID == EQUIPMENT_NIGHTVISION ) { + if ( !( self.iEquipment & EQUIPMENT_NIGHTVISION ) ) { + self.iEquipment |= EQUIPMENT_NIGHTVISION; + Money_AddMoney( self, -1250 ); + sound( self, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE ); + } else { + centerprint( self, "You already have nightvision goggles!" ); + } + } else if ( eqptTable[ fID ].iID == WEAPON_HEGRENADE ) { if ( self.iAmmo_HEGRENADE < 2 ) { self.iAmmo_HEGRENADE++; Money_AddMoney( self, -300 ); + sound( self, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE ); } else { centerprint( self, "You can't carry any more!" ); } @@ -46,6 +63,7 @@ void CSEv_PlayerBuyEquipment_f( float fID ) { if ( self.iAmmo_FLASHBANG < 2 ) { self.iAmmo_FLASHBANG++; Money_AddMoney( self, -300 ); + sound( self, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE ); } else { centerprint( self, "You can't carry any more!" ); } @@ -53,6 +71,7 @@ void CSEv_PlayerBuyEquipment_f( float fID ) { if ( self.iAmmo_SMOKEGRENADE < 2 ) { self.iAmmo_SMOKEGRENADE++; Money_AddMoney( self, -300 ); + sound( self, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE ); } else { centerprint( self, "You can't carry any more!" ); } diff --git a/Source/Shared/WeaponFlashbang.c b/Source/Shared/WeaponFlashbang.c index 6471c5be..48287387 100755 --- a/Source/Shared/WeaponFlashbang.c +++ b/Source/Shared/WeaponFlashbang.c @@ -126,7 +126,7 @@ void WeaponFLASHBANG_Throw( void ) { return; } if ( other.classname == "func_breakable" ) { - Damage_Apply( other, self, 10, self.origin, FALSE ); + Damage_Apply( other, self, 50, self.origin, FALSE ); } sound( self, CHAN_WEAPON, sprintf( "weapons/grenade_hit%d.wav", floor( random() * 3 ) + 1 ), 1, ATTN_NORM ); } diff --git a/Source/Shared/WeaponHEGrenade.c b/Source/Shared/WeaponHEGrenade.c index 87edc3a0..92f43678 100755 --- a/Source/Shared/WeaponHEGrenade.c +++ b/Source/Shared/WeaponHEGrenade.c @@ -108,7 +108,7 @@ void WeaponHEGRENADE_Throw( void ) { return; } if ( other.classname == "func_breakable" && other.material == MATERIAL_GLASS ) { - Damage_Apply( other, self, 10, self.origin, FALSE ); + Damage_Apply( other, self, 50, self.origin, FALSE ); } sound( self, CHAN_WEAPON, "weapons/he_bounce-1.wav", 1, ATTN_NORM ); diff --git a/Source/Shared/WeaponSmokeGrenade.c b/Source/Shared/WeaponSmokeGrenade.c index 546d1f44..e470ac57 100755 --- a/Source/Shared/WeaponSmokeGrenade.c +++ b/Source/Shared/WeaponSmokeGrenade.c @@ -97,6 +97,9 @@ void WeaponSMOKEGRENADE_Throw( void ) { static void WeaponSMOKEGRENADE_Die( void ) { remove( self ); } + static vector Caliber_Reflect( vector v1, vector v2 ) { + return v1 - 2 * dotproduct( v1, v2 ) * v2; + } static void WeaponSMOKEGRENADE_Explode( void ) { Effect_CreateSmoke( self.origin ); @@ -114,7 +117,8 @@ void WeaponSMOKEGRENADE_Throw( void ) { return; } if ( other.classname == "func_breakable" ) { - Damage_Apply( other, self, 10, self.origin, FALSE ); + Damage_Apply( other, self, 50, self.origin, FALSE ); + self.velocity = Caliber_Reflect( self.velocity, trace_plane_normal ); } sound( self, CHAN_WEAPON, sprintf( "weapons/grenade_hit%d.wav", floor( random() * 3 ) + 1 ), 1, ATTN_NORM ); } diff --git a/freecs/csprogs.dat b/freecs/csprogs.dat index bf6c6cff..c435eddf 100644 Binary files a/freecs/csprogs.dat and b/freecs/csprogs.dat differ diff --git a/freecs/menu.dat b/freecs/menu.dat index a69d3e41..3d0a8dec 100755 Binary files a/freecs/menu.dat and b/freecs/menu.dat differ diff --git a/freecs/progs.dat b/freecs/progs.dat index da233e4c..a83abbc8 100644 Binary files a/freecs/progs.dat and b/freecs/progs.dat differ