diff --git a/Source/Client/Entities.c b/Source/Client/Entities.c index 8a484efd..7f5e5806 100755 --- a/Source/Client/Entities.c +++ b/Source/Client/Entities.c @@ -48,7 +48,7 @@ void CSQC_Ent_Update( float flIsNew ) { self.origin_x = readcoord(); self.origin_y = readcoord(); self.origin_z = readcoord(); - self.angles_x = readcoord(); + self.subblend2frac = readcoord() / 90; self.angles_y = readcoord(); self.angles_z = readcoord(); self.velocity_x = readshort(); @@ -89,8 +89,9 @@ void CSQC_Ent_Update( float flIsNew ) { self.angles_y = readcoord(); self.angles_z = readcoord(); + // TODO: This doesn't cache them to be player specific yet, make it so! self.model = sprintf( "logos/%s.bmp" ,getplayerkeyvalue( readbyte() - 1, "logo" ) ); - shaderforname( self.model, sprintf("{\npolygonOffset\n{\nmap %s\n}\n}\n", self.model ) ); + shaderforname( self.classname, sprintf("{\npolygonOffset\n{\nmap %s\nblendfunc blendFunc add\n\nrgbgen vertex\n}\n}\n", self.model ) ); self.predraw = Effect_Spraypaint; self.drawmask = MASK_ENGINE; } diff --git a/Source/Client/Init.c b/Source/Client/Init.c index 7f03820b..d280a28e 100755 --- a/Source/Client/Init.c +++ b/Source/Client/Init.c @@ -83,6 +83,7 @@ void CSQC_Init(float apilevel, string enginename, float engineversion) { precache_pic( sprintf( "overviews/%s.bmp", mapname ) ); precache_pic( "logos/lambda.bmp" ); + precache_pic( "logos/doug.bmp" ); for ( int i = 0; i < ( CS_WEAPON_COUNT - 1 ); i++ ) { precache_model( sViewModels[ i ] ); diff --git a/Source/Client/Player.c b/Source/Client/Player.c index 45c5a0ba..7a268b91 100755 --- a/Source/Client/Player.c +++ b/Source/Client/Player.c @@ -62,6 +62,7 @@ string sPModels[ CS_WEAPON_COUNT - 1 ] = { //.float bonecontrol5; //Halflife model format bone controller. This typically affects the mouth. //.float subblendfrac; //Weird animation value specific to halflife models. On player models, this typically affects the spine's pitch. //.float basesubblendfrac; // legs part. +.float subblend2frac; // Up/Down static float Player_Gun_PreDraw (void) { self.entnum = self.owner.entnum; //so this entity gets its RF_EXTERNALMODEL flag rewritten as needed @@ -73,7 +74,7 @@ static float Player_Gun_PreDraw (void) { void Player_Draw( void ) { if ( !self.eGunModel ) { self.eGunModel = spawn(); - self.eGunModel.classname = "vwep model"; + self.eGunModel.classname = "pmodel"; self.eGunModel.owner = self; self.eGunModel.predraw = Player_Gun_PreDraw; self.eGunModel.drawmask = MASK_ENGINE; @@ -102,6 +103,8 @@ void Player_Draw( void ) { self.frame2time += frametime; self.bonecontrol5 = stof( getplayerkeyvalue( player_localnum, INFOKEY_P_VOIPLOUDNESS ) ); + //self.subblendfrac = ; + //self. = self.angles_x / 90; } /* @@ -131,6 +134,7 @@ void Player_Predict(void) { vector vOldAngles = self.angles = self.netangles; vector vOldVelocity = self.velocity = self.netvelocity; float fOldPMoveFlags = self.pmove_flags = self.netpmove_flags; + // Don't predict if we're frozen/paused FIXME: FTE doesn't have serverkey_float yet! if ( serverkey( SERVERKEY_PAUSESTATE ) == "1" || ( ( getstati( STAT_GAMESTATE ) == GAME_FREEZE ) && ( getstati( STAT_HEALTH ) > 0 ) ) ) { pSeat->vPlayerOrigin = self.origin; @@ -146,16 +150,20 @@ void Player_Predict(void) { self.movetype = MOVETYPE_NOCLIP; } - if (self.pmove_flags & 0x80000) + if (self.pmove_flags & 0x80000) { self.flags |= FL_ONGROUND; - else + } else { self.flags &~= FL_ONGROUND; + } + for ( int i = self.pmove_frame; i <= clientcommandframe; i++ ) { getinputstate( i ); runplayerphysics(); } - if (self.flags & FL_ONGROUND) + + if ( self.flags & FL_ONGROUND ) { self.pmove_flags |= 0x80000; + } } pSeat->vPlayerOriginOld = pSeat->vPlayerOrigin; @@ -196,7 +204,7 @@ We're part way through parsing new player data. Propagate our pmove state to whatever the current frame before its stomped on (so any non-networked state updates locally). ================= */ -void Player_PreUpdate(void) { +void Player_PreUpdate( void ) { self.origin = self.netorigin; self.angles = self.netangles; self.velocity = self.netvelocity; @@ -208,27 +216,30 @@ void Player_PreUpdate(void) { self.movetype = MOVETYPE_NOCLIP; } - if (self.pmove_flags & 0x80000) + if ( self.pmove_flags & 0x80000 ) { self.flags |= FL_ONGROUND; - else + } else { self.flags &~= FL_ONGROUND; + } + //we want to predict an exact copy of the data in the new packet - for ( ; self.pmove_frame <= servercommandframe; self.pmove_frame++) { - if ( getinputstate( self.pmove_frame )) + for ( ; self.pmove_frame <= servercommandframe; self.pmove_frame++ ) { + if ( getinputstate( self.pmove_frame ) ) runplayerphysics(); } - if (self.flags & FL_ONGROUND) + if ( self.flags & FL_ONGROUND ) { self.pmove_flags |= 0x80000; + } //we now have self.pmove_flags set properly... self.movetype = MOVETYPE_NONE; } -void Player_PostUpdate(void) { +void Player_PostUpdate( void ) { self.netorigin = self.origin; self.netangles = self.angles; self.netvelocity = self.velocity; self.netpmove_flags = self.pmove_flags; self.pmove_frame = servercommandframe+1; -}; \ No newline at end of file +} diff --git a/Source/Menu/MenuMultiplayer.c b/Source/Menu/MenuMultiplayer.c index ceecb61f..18bcbb9b 100755 --- a/Source/Menu/MenuMultiplayer.c +++ b/Source/Menu/MenuMultiplayer.c @@ -242,7 +242,8 @@ void Menu_Multiplayer_Create( void ) { // Options Object_Label( '196 148', _("SERVER_NAME"), '8 8' ); Object_Textfield( '196 160', strHostname, 20 ); - + Object_CvarToggle( '196 185', "Public", "sv_public" ); + // Map list Object_Label( '384 148', _("MP_MAPS"), '8 8' ); Object_Frame( '384 164', '190 288' ); @@ -363,4 +364,4 @@ void Menu_Multiplayer_IRC( void ) { Object_Label( '196 148', _("No IRC Output"), '8 8' ); Object_Button( '32 308', BTN_DONE, IRC_ButtonDone, fButtonAlpha[0] ); -} \ No newline at end of file +} diff --git a/Source/Server/ArmouryEntity.c b/Source/Server/ArmouryEntity.c index 7e6da1ad..92fdba4c 100755 --- a/Source/Server/ArmouryEntity.c +++ b/Source/Server/ArmouryEntity.c @@ -108,6 +108,11 @@ void armoury_entity( void ) { droptofloor(); } + if ( autocvar_fcs_nopickups == TRUE ) { + remove( self ); + return; + } + precache_model( sArmouryModels[ self.item ] ); setmodel( self, sArmouryModels[ self.item ] ); setsize( self, '-16 -16 0', '16 16 16' ); diff --git a/Source/Server/Damage.c b/Source/Server/Damage.c index 11d5676a..609b3378 100755 --- a/Source/Server/Damage.c +++ b/Source/Server/Damage.c @@ -152,9 +152,9 @@ void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos // Special monetary punishment for hostage murderers if ( eTarget.classname == "hostage_entity" ) { if ( eTarget.health > 0 ) { - Money_AddMoney( eAttacker, -150 ); // Pain + Money_AddMoney( eAttacker, autocvar_fcs_penalty_pain ); // Pain } else { - Money_AddMoney( eAttacker, -1500 ); // Death + Money_AddMoney( eAttacker, autocvar_fcs_penalty_kill ); // Death } } @@ -169,7 +169,7 @@ void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos // Don't encourage them to kill their own team members for $$$ if ( Damage_ShouldDamage( eTarget.team, eAttacker.team ) == TRUE ) { eAttacker.frags++; - Money_AddMoney( eAttacker, 300 ); + Money_AddMoney( eAttacker, autocvar_fcs_reward_kill ); } else { eAttacker.frags--; } @@ -243,12 +243,12 @@ Damage_Radius Even more pain and suffering, mostly used for explosives ================= */ -void Damage_Radius( vector vOrigin, entity eAttacker, float fDamage, float fRadius ) { +void Damage_Radius( vector vOrigin, entity eAttacker, float fDamage, float fRadius, int iCheckClip ) { entity eDChain = findradius( vOrigin, fRadius ); while( eDChain ) { if ( eDChain.takedamage == DAMAGE_YES ) { - if ( Damage_CheckAttack( eDChain, vOrigin ) ) { + if ( Damage_CheckAttack( eDChain, vOrigin ) || iCheckClip == FALSE ) { float fDiff = vlen( vOrigin - eDChain.origin ); fDiff = ( fRadius - fDiff ) / fRadius; diff --git a/Source/Server/Defs.h b/Source/Server/Defs.h index 52296cdc..3273b71f 100755 --- a/Source/Server/Defs.h +++ b/Source/Server/Defs.h @@ -30,10 +30,21 @@ var float autocvar_mp_roundtime = 5; var float autocvar_mp_timelimit = 60; var string autocvar_motdfile = "motd.txt"; -var int autocvar_mp_fillweapons = FALSE; -var int autocvar_mp_autoreload = FALSE; var int autocvar_sv_voxannounce = FALSE; +// Casual, or later CS variables +var int autocvar_mp_fillweapons = FALSE; // This will automatically get ammo for the weapon you buy +var int autocvar_mp_autoreload = FALSE; // When pressing fire and the gun is empty, it will reload instead + +// New, FreeCS exclusive variables +var int autocvar_fcs_knifeonly = FALSE; // Disallows buying and spawning with weps +var int autocvar_fcs_swapteams = FALSE; // Swaps spawnpoints +var int autocvar_fcs_nopickups = FALSE; // Disable weapon items +var int autocvar_fcs_reward_kill = 300; +var int autocvar_fcs_penalty_pain = -150; +var int autocvar_fcs_penalty_kill = -1500; +var int autocvar_fcs_maxmoney = 16000; + // Mapcycle features var string autocvar_mapcyclefile = "mapcycle.txt"; var int iMapCycleCount; @@ -157,7 +168,7 @@ void Effect_CreateExplosion( vector vPos ); void Effect_CreateFlash( entity eTarget ); void TraceAttack_FireBullets( int iShots, vector vPos ); -void Damage_Radius( vector vOrigin, entity eAttacker, float fDamage, float fRadius ); +void Damage_Radius( vector vOrigin, entity eAttacker, float fDamage, float fRadius, int iCheckClip ); void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos, int iSkipArmor ); void Entities_UseTargets( void ); diff --git a/Source/Server/EnvObjects.c b/Source/Server/EnvObjects.c index af7d4f0c..e51281c9 100755 --- a/Source/Server/EnvObjects.c +++ b/Source/Server/EnvObjects.c @@ -180,7 +180,7 @@ void env_explosion( void ) { Effect_CreateExplosion( self.origin ); if ( !( self.spawnflags & ENVEXPLO_NODAMAGE ) ) { - Damage_Radius( self.origin, self, 500, self.iMagnitude ); + Damage_Radius( self.origin, self, 500, self.iMagnitude, TRUE ); } if ( !( self.spawnflags & ENVEXPLO_REPEATABLE ) ) { self.vUse = __NULL__; diff --git a/Source/Server/FuncBuyZone.c b/Source/Server/FuncBuyZone.c index 73806f49..962025dc 100755 --- a/Source/Server/FuncBuyZone.c +++ b/Source/Server/FuncBuyZone.c @@ -37,6 +37,11 @@ Entry function for the buyzone area-markings. ================= */ void func_buyzone( void ) { + if ( autocvar_fcs_knifeonly == TRUE ) { + remove( self ); + return; + } + self.angles = '0 0 0'; self.movetype = MOVETYPE_NONE; self.solid = SOLID_TRIGGER; @@ -65,6 +70,10 @@ void Game_CreateBuyZones( void ) { entity eFind; entity eOld; + if ( autocvar_fcs_knifeonly == TRUE ) { + return; + } + if ( iBuyRestriction == BUY_T || iBuyRestriction == BUY_BOTH ) { eFind = findchain( classname, "info_player_deathmatch" ); eOld = self; diff --git a/Source/Server/Input.c b/Source/Server/Input.c index 21b8f2b8..a9dc360f 100755 --- a/Source/Server/Input.c +++ b/Source/Server/Input.c @@ -26,7 +26,15 @@ Handles impulse and whatnot ================= */ void Input_Handle( void ) { + // Dead, specatator if ( self.health <= 0 ) { + /*if ( self.button2 ) { + if ( infokey( self, "*spectator" ) == "0" ) { + forceinfokey( self, "*spectator", "1" ); + } else { + forceinfokey( self, "*spectator", "1" ); + } + }*/ return; } diff --git a/Source/Server/Money.c b/Source/Server/Money.c index ad6d7584..4ffb03e7 100755 --- a/Source/Server/Money.c +++ b/Source/Server/Money.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define CS_MAX_MONEY 16000 - int iMoneyReward_CT; int iMoneyReward_T; @@ -35,8 +33,8 @@ void Money_AddMoney( entity ePlayer, int iMoneyValue ) { dprint( sprintf( "[DEBUG]: Giving %s %i in cash\n", ePlayer.netname, iMoneyValue ) ); ePlayer.fMoney += (float)iMoneyValue; - if ( ePlayer.fMoney > CS_MAX_MONEY ) { - ePlayer.fMoney = CS_MAX_MONEY; + if ( ePlayer.fMoney > autocvar_fcs_maxmoney ) { + ePlayer.fMoney = autocvar_fcs_maxmoney; } // Because people do tend to kill hostages... diff --git a/Source/Server/Player.c b/Source/Server/Player.c index 75c5d842..3f0bffc0 100755 --- a/Source/Server/Player.c +++ b/Source/Server/Player.c @@ -41,7 +41,7 @@ float Player_SendEntity( entity ePEnt, float fChanged ) { WriteCoord( MSG_ENTITY, self.origin_x ); WriteCoord( MSG_ENTITY, self.origin_y ); WriteCoord( MSG_ENTITY, self.origin_z ); - WriteCoord( MSG_ENTITY, self.angles_x ); + WriteCoord( MSG_ENTITY, self.v_angle_x ); WriteCoord( MSG_ENTITY, self.angles_y ); WriteCoord( MSG_ENTITY, self.angles_z ); WriteShort( MSG_ENTITY, self.velocity_x ); diff --git a/Source/Server/Spawn.c b/Source/Server/Spawn.c index 3fa09988..544b9d85 100755 --- a/Source/Server/Spawn.c +++ b/Source/Server/Spawn.c @@ -178,17 +178,25 @@ void Spawn_CreateClient( float fCharModel ) { iAlivePlayers_T++; Weapon_AddItem( WEAPON_KNIFE ); - Weapon_AddItem( WEAPON_GLOCK18 ); - Weapon_GiveAmmo( WEAPON_GLOCK18, 40 ); - Weapon_Draw( WEAPON_GLOCK18 ); + if ( autocvar_fcs_knifeonly == FALSE ) { + Weapon_AddItem( WEAPON_GLOCK18 ); + Weapon_GiveAmmo( WEAPON_GLOCK18, 40 ); + Weapon_Draw( WEAPON_GLOCK18 ); + } else { + Weapon_Draw( WEAPON_KNIFE ); + } } else { self.team = TEAM_CT; iAlivePlayers_CT++; Weapon_AddItem( WEAPON_KNIFE ); - Weapon_AddItem( WEAPON_USP45 ); - Weapon_GiveAmmo( WEAPON_USP45, 24 ); - Weapon_Draw( WEAPON_USP45 ); + if ( autocvar_fcs_knifeonly == FALSE ) { + Weapon_AddItem( WEAPON_USP45 ); + Weapon_GiveAmmo( WEAPON_USP45, 24 ); + Weapon_Draw( WEAPON_USP45 ); + } else { + Weapon_Draw( WEAPON_KNIFE ); + } } if( self.iInGame == FALSE ) { @@ -321,6 +329,9 @@ Counter-Terrorist Spawnpoints ================= */ void info_player_start( void ) { + if ( autocvar_fcs_swapteams == TRUE ) { + self.classname = "info_player_deathmatch"; + } } /* @@ -331,6 +342,9 @@ Terrorist Spawnpoints ================= */ void info_player_deathmatch( void ) { + if ( autocvar_fcs_swapteams == TRUE ) { + self.classname = "info_player_start"; + } } /* diff --git a/Source/Shared/Effects.c b/Source/Shared/Effects.c index 844b3bae..f92f3250 100755 --- a/Source/Shared/Effects.c +++ b/Source/Shared/Effects.c @@ -63,10 +63,18 @@ void Effect_Spraypaint( void ) { setorigin( eSpray, trace_endpos ); // Align it - vector vSprayAngles = self.angles; + vector vSprayAngles = self.v_angle; vSprayAngles_x *= -1; makevectors( vSprayAngles ); + vector vCoplanar = v_forward - ( v_forward * trace_plane_normal ) * trace_plane_normal; + + centerprint( self, sprintf( "Coplanar: %f %f %f\n", vCoplanar_x, vCoplanar_y, vCoplanar_z ) ); + + if ( trace_plane_normal_z == 0 ) { + vCoplanar = '0 0 1'; + } + eSpray.angles = vectoangles( vCoplanar, trace_plane_normal ); eSpray.SendEntity = Effect_Spraypaint_Send; @@ -77,7 +85,7 @@ void Effect_Spraypaint( void ) { float Effect_Spraypaint( void ) { makevectors( self.angles ); // Temporary string, will getinfo from player later - adddecal( self.model, self.origin, v_up / 64, v_right / 64, '1 1 1', 1.0f ); + adddecal( self.classname, self.origin, v_up / 32, v_forward / 32, '1 0 0', 1.0f ); addentity( self ); return PREDRAW_NEXT; #endif diff --git a/Source/Shared/WeaponC4Bomb.c b/Source/Shared/WeaponC4Bomb.c index 7243f682..e075d7c0 100755 --- a/Source/Shared/WeaponC4Bomb.c +++ b/Source/Shared/WeaponC4Bomb.c @@ -116,7 +116,7 @@ static void WeaponC4BOMB_Think( void ) { Rules_RoundOver( TEAM_T, 3500, FALSE ); // Make it explode and hurt things - Damage_Radius( self.origin, self, 500, 1024 ); + Damage_Radius( self.origin, self, 500, 1024, FALSE ); sound( self, CHAN_VOICE, "weapons/c4_explode1.wav", 1.0, ATTN_NONE ); // Trigger all targets diff --git a/Source/Shared/WeaponHEGrenade.c b/Source/Shared/WeaponHEGrenade.c index dc9cdc27..d8a8ef95 100755 --- a/Source/Shared/WeaponHEGrenade.c +++ b/Source/Shared/WeaponHEGrenade.c @@ -97,7 +97,7 @@ void WeaponHEGRENADE_PrimaryFire( void ) { void WeaponHEGRENADE_Throw( void ) { static void WeaponHEGRENADE_Explode( void ) { Effect_CreateExplosion( self.origin ); - Damage_Radius( self.origin, self, 100, 512 ); + Damage_Radius( self.origin, self, 100, 512, TRUE ); sound( self, CHAN_WEAPON, sprintf( "weapons/explode%d.wav", floor( random() * 2 ) + 3 ), 1, ATTN_NORM ); remove( self ); } diff --git a/freecs/csprogs.dat b/freecs/csprogs.dat old mode 100644 new mode 100755 index 0b46c22a..357de998 Binary files a/freecs/csprogs.dat and b/freecs/csprogs.dat differ diff --git a/freecs/default.cfg b/freecs/default.cfg index 34d776c3..785c1677 100755 --- a/freecs/default.cfg +++ b/freecs/default.cfg @@ -77,4 +77,5 @@ seta scr_conalpha "1" seta con_notifylines "0" seta maxplayers "8" seta lang "en_us" -seta cfg_save_auto "1" \ No newline at end of file +seta cfg_save_auto "1" +seta r_meshpitch "1" diff --git a/freecs/ftesrv.cfg b/freecs/ftesrv.cfg index 6ea7cf10..37b96e69 100755 --- a/freecs/ftesrv.cfg +++ b/freecs/ftesrv.cfg @@ -9,7 +9,6 @@ seta mp_freezetime 6 seta mp_c4timer 45 seta mp_roundtime 5 seta mp_fillweapons 0 -seta motdfile "motd.txt" // In case you want to use a different Message Of The Day // Physics seta pm_bunnyspeedcap "1" diff --git a/freecs/menu.dat b/freecs/menu.dat index 82f70202..693e2ebf 100755 Binary files a/freecs/menu.dat and b/freecs/menu.dat differ diff --git a/freecs/progs.dat b/freecs/progs.dat old mode 100644 new mode 100755 index 068601b4..908a0fed Binary files a/freecs/progs.dat and b/freecs/progs.dat differ