Improved pathfinding, early breakable model stuff

This commit is contained in:
Marco Hladik 2016-12-03 20:25:03 +01:00
parent d144d3e998
commit a75b6d1dda
11 changed files with 2441 additions and 26 deletions

View file

@ -53,6 +53,19 @@ void CSQC_Parse_Event( void ) {
Weapon_SecondaryAttack( getstatf( STAT_ACTIVEWEAPON ) );
} else if ( fHeader == EV_WEAPON_RELOAD ) {
Weapon_Reload( getstatf( STAT_ACTIVEWEAPON ) );
} else if ( fHeader == EV_MODELGIB ) {
vector vPos;
vPos_x = readcoord();
vPos_y = readcoord();
vPos_z = readcoord();
vector vSize;
vSize_x = readcoord();
vSize_y = readcoord();
vSize_z = readcoord();
float fStyle = readbyte();
Effect_BreakModel( vPos, vSize, '0 0 0', fStyle );
}
}

View file

@ -34,6 +34,7 @@ Defs.h
../Shared/WeaponBase.c
../Shared/Weapons.c
../Shared/Effects.c
View.c
VGUI_Objects.c
VGUI_MOTD.c

View file

@ -151,7 +151,8 @@ enum {
EV_WEAPON_DRAW,
EV_WEAPON_PRIMARYATTACK,
EV_WEAPON_SECONDARYATTACK,
EV_WEAPON_RELOAD
EV_WEAPON_RELOAD,
EV_MODELGIB,
};
float clamp(float d, float imin, float imax) {

28
Source/Math.h Normal file
View file

@ -0,0 +1,28 @@
/*
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.
*/
float Math_LerpAngle( float fStart, float fEnd, float fAmount ) {
float shortest_angle = ( ( ( ( fEnd - fStart ) % 360 ) + 540 ) % 360 ) - 180;
return shortest_angle * fAmount;
}
float Math_CRandom( void ) {
return 2 * ( random() - 0.5 );
}

View file

@ -19,65 +19,135 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
.entity eUser;
.entity eTargetPoint;
.entity eLastCreated;
enum {
HOSTAGE_IDLE,
HOSTAGE_WALK,
HOSTAGE_RUN
};
float Client_LerpCamera( float fStart, float fEnd, float fAmount ) {
float shortest_angle = ( ( ( ( fEnd - fStart ) % 360 ) + 540 ) % 360 ) - 180;
return shortest_angle * fAmount;
// To make sure they are following us right
entity hostage_waypoint( void ) {
entity ePoint = spawn();
setorigin( ePoint, self.eUser.origin );
//setmodel( ePoint, "models/chick.mdl" ); // Visual feedback...
return ePoint;
}
// Called whenver a hostage is shot
void hostage_pain( void ) {
self.frame = 13 - ceil( random() * 5);
}
// hosdown.wav
void hostage_die( void ) {
sound( world, CHAN_VOICE, "radio/hosdown.wav", 1.0, ATTN_NONE );
self.frame = 30 + ceil( random() * 5);
self.solid = SOLID_NOT;
self.takedamage = DAMAGE_NO;
if ( other.eTargetPoint != other.eUser ) {
remove( other.eTargetPoint );
}
}
// Happens upon calling 'use'
void hostage_use( void ) {
if ( self.eUser == world ) {
sound( self, CHAN_VOICE, sprintf( "hostage/hos%d.wav", ceil( random() * 5 ) ), 1.0, ATTN_IDLE );
self.eUser = eActivator;
self.eTargetPoint = self.eUser;
} else {
self.eUser = world;
}
}
// Run every frame
void hostage_physics( void ) {
input_movevalues = '0 0 0';
input_impulse = 0;
input_buttons = 0;
input_angles = self.angles;
// Are we meant to follow someone and AREN'T dead?
if ( ( self.eUser != world ) && ( self.health > 0 ) ) {
// This is visible ingame, so this is definitely executed.
vector vEndAngle = vectoangles( self.eUser.origin - self.origin );
self.angles_y += Client_LerpCamera( self.angles_y, vEndAngle_y, 0.2 );
// Which direction we have to face
vector vEndAngle = vectoangles( self.eTargetPoint.origin - self.origin );
// Just make them move forward right now
// TODO: trace the dist to determine whether or not we should back off
float fDist = vlen( self.eUser.origin - self.origin );
// Slowly turn towards target
float fTurn = Math_LerpAngle( self.angles_y, vEndAngle_y, 0.2 );
self.angles_y += fTurn;
if ( fDist < 130 ) {
self.frame = 13;
input_movevalues = '0 0 0';
} else if ( fDist < 200 ) {
// Is the waypoint close? if so, remove and go set the next one!
float fDist1 = vlen( self.eTargetPoint.origin - self.origin );
if ( fDist1 < 100 && self.eTargetPoint != self.eUser ) {
entity eTemp = self.eTargetPoint;
if ( self.eTargetPoint.eTargetPoint ) {
self.eTargetPoint = self.eTargetPoint.eTargetPoint;
} else {
self.eTargetPoint = self.eUser;
}
remove( eTemp ); // Delete the old waypoint
}
// Don't switch states so often
if( self.fAttackFinished < time ) {
// Here we check the distance of us and the player, then choosing if we should walk/run etc.
float fDist = vlen( self.eUser.origin - self.origin );
if ( fDist < 130 ) {
self.style = HOSTAGE_IDLE;
self.fAttackFinished = time + 0.1;
} else if ( fDist < 200 ) {
self.style = HOSTAGE_WALK;
self.fAttackFinished = time + 0.4;
} else {
self.style = HOSTAGE_RUN;
self.fAttackFinished = time + 0.1;
// We only ever need to create waypoints when we run
if ( self.fStepTime < time ) {
if ( self.eTargetPoint == self.eUser ) {
// Create the first waypoint
self.eTargetPoint = hostage_waypoint();
self.eLastCreated = self.eTargetPoint;
} else {
// Create the next one and link
self.eLastCreated.eTargetPoint = hostage_waypoint();
self.eLastCreated = self.eLastCreated.eTargetPoint;
}
self.fStepTime = time + 0.2;
}
}
}
// Decide speed and stuff
if ( self.style == HOSTAGE_WALK ) {
self.frame = 0;
input_movevalues = '110 0 0';
} else {
self.frame = 2;
} else if ( self.style == HOSTAGE_RUN ) {
input_movevalues = '220 0 0';
self.frame = 2;
} else {
input_movevalues = '0 0 0';
if ( fTurn > 0 ) {
self.frame = 5;
} else if ( fTurn < 0 ){
self.frame = 6;
} else {
self.frame = 13;
}
}
} else {
}
// Tricking the engine
self.movetype = MOVETYPE_WALK;
// Calculate physstuff
runstandardplayerphysics( self );
self.customphysics = hostage_physics;
}
/*
@ -97,12 +167,14 @@ void hostage_entity( void ) {
self.customphysics = hostage_physics;
self.eUser = world;
self.eTargetPoint = world;
self.iUsable = TRUE;
self.iBleeds = TRUE;
self.takedamage = DAMAGE_YES;
self.vUse = hostage_use;
self.vPain = hostage_pain;
self.vDeath = hostage_die;
self.style = HOSTAGE_IDLE;
self.frame = 13; // Idle frame
self.health = 100;

View file

@ -111,6 +111,8 @@ void func_breakable_die( void ) {
sound( self, CHAN_VOICE, sprintf( "%s%d.wav", sTypeSample, ceil( random() * iTypeCount ) ), 1.0, ATTN_NORM );
}
Effect_BreakModel( self.origin, self.size, self.velocity, self.style );
remove( self );
}

View file

@ -32,6 +32,9 @@ void func_hostage_rescue_touch( void ) {
iHostagesRescued++;
other.eUser.fMoney += 1000;
if ( other.eTargetPoint != other.eUser ) {
remove( other.eTargetPoint );
}
remove( other );
}
}

View file

@ -18,10 +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.
*/
float Math_CRandom( void ) {
return 2 * ( random() - 0.5 );
}
void TraceAttack_FireBullets( int iShots ) {
vector vSrc, vDir;

2244
Source/Server/fteqcc.log Normal file

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,7 @@
#includelist
../Builtins.h
../Globals.h
../Math.h
Defs.h
../Shared/WeaponAK47.c
@ -32,6 +33,7 @@ Defs.h
../Shared/WeaponBase.c
../Shared/Weapons.c
../Shared/Effects.c
Damage.c
TraceAttack.c
Timer.c

53
Source/Shared/Effects.c Normal file
View file

@ -0,0 +1,53 @@
/*
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.
*/
void Effect_BreakModel( vector vPos, vector vSize, vector vVel, float fStyle ) {
#ifdef SSQC
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_MODELGIB );
WriteCoord( MSG_MULTICAST, vPos_x);
WriteCoord( MSG_MULTICAST, vPos_y);
WriteCoord( MSG_MULTICAST, vPos_z);
WriteCoord( MSG_MULTICAST, vSize_x);
WriteCoord( MSG_MULTICAST, vSize_y);
WriteCoord( MSG_MULTICAST, vSize_z);
WriteByte( MSG_MULTICAST, fStyle );
msg_entity = self;
multicast( '0 0 0', MULTICAST_PVS );
#else
float fCount = 20; // TODO: Generate gibcount based around size.
vector vRandPos;
while ( fCount > 0 ) {
entity eGib = spawn();
vRandPos_x = random() * vSize_x;
vRandPos_y = random() * vSize_y;
vRandPos_z = random() * vSize_z;
vRandPos = vRandPos - ( vSize / 2 );
setorigin( eGib, vPos + vRandPos );
setmodel( eGib, "models/head.mdl" ); // Placeholder
fCount--;
eGib.drawmask = MASK_ENGINE;
}
#endif
}