Added some new cvars, such as fcs_knifeonly, fcs_swapteams, fcs_nopickups, fcs_reward_kill, fcs_penalty_pain, fcs_penalty_kill, fcs_maxmoney. Also fixed that exploding C4 does traceline collision checks against its targets. Sprays are sort-of in, but not fully.

This commit is contained in:
Marco Cawthorne 2017-12-01 13:02:58 -06:00
parent 5969fc35c9
commit 057420ed4c
21 changed files with 109 additions and 42 deletions

View file

@ -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;
}

View file

@ -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 ] );

View file

@ -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;
};
}

View file

@ -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] );
}
}

View file

@ -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' );

View file

@ -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;

View file

@ -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 );

View file

@ -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__;

View file

@ -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;

View file

@ -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;
}

View file

@ -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...

View file

@ -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 );

View file

@ -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";
}
}
/*

View file

@ -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

View file

@ -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

View file

@ -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 );
}

BIN
freecs/csprogs.dat Normal file → Executable file

Binary file not shown.

View file

@ -77,4 +77,5 @@ seta scr_conalpha "1"
seta con_notifylines "0"
seta maxplayers "8"
seta lang "en_us"
seta cfg_save_auto "1"
seta cfg_save_auto "1"
seta r_meshpitch "1"

View file

@ -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"

Binary file not shown.

BIN
freecs/progs.dat Normal file → Executable file

Binary file not shown.