📄 sentient.cpp
字号:
giveItem( type, amount );
if ( currentWeapon && !currentWeapon->HasAmmo() )
{
Weapon *best;
best = BestWeapon();
if ( best )
{
ChangeWeapon( best );
}
}
}
void Sentient::EventTakeArmor
(
Event *ev
)
{
int amount;
const char *type;
Armor *armor;
type = ev->GetString( 1 );
amount = ev->GetInteger( 2 );
armor = ( Armor * )FindItem( type );
if ( armor )
{
armor->Remove( amount );
}
}
void Sentient::EventGiveArmor
(
Event *ev
)
{
int amount;
const char *type;
Armor *armor;
type = ev->GetString( 1 );
amount = ev->GetInteger( 2 );
if ( !checkInheritance( &Armor::ClassInfo, type ) )
{
gi.dprintf( "%s is not usable as armor\n", type );
return;
}
armor = ( Armor * )FindItem( type );
if ( armor )
{
armor->Set( amount );
}
else
{
giveItem( type, amount );
}
}
void Sentient::EventGiveItem
(
Event *ev
)
{
const char *type;
float amount;
type = ev->GetString( 1 );
amount = ev->GetInteger( 2 );
giveItem( type, amount );
}
void Sentient::EventGiveInventoryItem
(
Event *ev
)
{
const char *type;
int amount;
type = ev->GetString( 1 );
amount = ev->GetInteger( 2 );
if ( !checkInheritance( &InventoryItem::ClassInfo, type ) )
{
gi.dprintf( "item '%s' is not a InventoryItem\n", type );
return;
}
giveItem( type, amount );
}
void Sentient::WeaponPutAway
(
Event *ev
)
{
SetCurrentWeapon( newWeapon );
}
void Sentient::WeaponReady
(
Event *ev
)
{
if ( newWeapon )
{
ChangeWeapon( newWeapon );
}
}
void Sentient::WeaponDoneFiring
(
Event *ev
)
{
Weapon *best;
if ( newWeapon )
{
ChangeWeapon( newWeapon );
}
else if ( !currentWeapon || !currentWeapon->HasAmmo() || !currentWeapon->ReadyToUse() )
{
best = BestWeapon();
if ( best )
{
ChangeWeapon( best );
}
}
}
EXPORT_FROM_DLL void Sentient::AnimLoop
(
Event *ev
)
{
Event *t;
animOverride = false;
if ( deadflag )
{
StopAnimating();
}
else if ( animating )
{
RandomAnimate( currentAnim.c_str(), NULL );
}
else
{
stopanimating_tillchange = true;
}
if ( tempAnimEvent )
{
t = tempAnimEvent;
tempAnimEvent = NULL;
ProcessEvent( t );
}
}
EXPORT_FROM_DLL void Sentient::SetAnim
(
const char *anim
)
{
assert( anim );
assert ( !deadflag );
if ( str( anim ) == currentAnim )
{
if (!animating && !stopanimating_tillchange)
StartAnimating();
return;
}
stopanimating_tillchange = false;
currentAnim = str( anim );
if ( animOverride )
{
return;
}
RandomAnimate( currentAnim.c_str(), EV_Sentient_AnimLoop );
if (!animating)
StartAnimating();
}
EXPORT_FROM_DLL void Sentient::TempAnim
(
const char *anim,
Event *event
)
{
assert ( !deadflag );
assert( anim );
animOverride = true;
tempAnimEvent = event;
RandomAnimate( anim, EV_Sentient_AnimLoop );
}
void Sentient::TempAnim
(
const char *anim,
Event &event
)
{
Event *ev;
ev = new Event( event );
TempAnim( anim, ev );
}
void Sentient::PrintDamageLocationToAttacker
(
edict_s *attacker,
const char *victim_name,
const char *location
)
{
const char *expanded_location;
expanded_location = ExpandLocation( location );
if ( expanded_location )
gi.cprintf ( attacker, PRINT_MEDIUM, "You hit %s in the %s.\n", victim_name, expanded_location );
}
void Sentient::PrintDamageLocationToVictim
(
edict_s *victim,
const char *location
)
{
const char *expanded_location;
expanded_location = ExpandLocation( location );
if ( expanded_location )
gi.cprintf ( victim, PRINT_MEDIUM, "%s damage\n", expanded_location );
}
qboolean Sentient::DoGib
(
int meansofdeath,
Entity *inflictor
)
{
if ( !( flags & FL_DIE_GIBS ) || parentmode->value )
{
return false;
}
if (
( meansofdeath == MOD_TELEFRAG ) ||
( meansofdeath == MOD_MUTANTHANDS ) ||
( meansofdeath == MOD_HELIGUN ) ||
( meansofdeath == MOD_LAVA ) ||
( ( meansofdeath == MOD_FISTS ) && ( inflictor->flags & FL_ADRENALINE ) ) ||
( ( meansofdeath == MOD_SHOTGUN ) && ( G_Random() < 0.3 ) )
)
{
return true;
}
if ( health > -75 )
{
return false;
}
// Impact and Crush < -75 health
if ( ( meansofdeath == MOD_IMPACT ) ||
( meansofdeath == MOD_CRUSH ) ||
( meansofdeath == MOD_VEHICLE )
)
{
return true;
}
// Any projectiles except spear
if ( inflictor->isSubclassOf( Projectile ) )
{
if ( meansofdeath != MOD_SPEARGUN )
{
return true;
}
}
// Shotgun only 10% of the time
if ( meansofdeath == MOD_SHOTGUN )
{
if ( G_Random() > 0.5 )
{
return true;
}
}
return false;
}
void Sentient::ArmorDamage
(
Event *ev
)
{
Armor *armor=0;
Entity *inflictor;
Entity *attacker;
float damage;
float armor_damage=0;
Vector momentum;
Vector position;
Vector normal;
Vector direction;
Event *event;
int dflags;
int meansofdeath;
int knockback;
float damage_mult;
int groupnum;
int trinum;
const char *location="";
float unmodified_damage=0;
if ( ( takedamage == DAMAGE_NO ) || ( movetype == MOVETYPE_NOCLIP ) )
{
if ( isClient () )
{
Player *player;
player = ( Player * )this;
if ( !player->GetVehicle() )
return;
}
else
{
return;
}
}
damage = ev->GetFloat ( 1 );
inflictor = ev->GetEntity ( 2 );
attacker = ev->GetEntity ( 3 );
position = ev->GetVector ( 4 );
direction = ev->GetVector ( 5 );
normal = ev->GetVector ( 6 );
knockback = ev->GetInteger( 7 );
dflags = ev->GetInteger( 8 );
meansofdeath = ev->GetInteger( 9 );
groupnum = ev->GetInteger( 10 );
trinum = ev->GetInteger( 11 );
damage_mult = ev->GetFloat ( 12 );
// Forcefields make objects invulnerable
if ( flags & FL_FORCEFIELD )
{
float alpha;
float radius;
Vector delta;
Vector org;
Entity *forcefield;
//
// spawn forcefield
//
forcefield = new Entity;
delta = centroid - worldorigin;
radius = delta.length();
//
// transform the centroid around by the current orientation
//
MatrixTransformVector( delta.vec3(), orientation, org.vec3() );
org += worldorigin;
forcefield->setModel( "sphere2.def" );
forcefield->setOrigin( org );
forcefield->worldorigin.copyTo(forcefield->edict->s.old_origin);
forcefield->setMoveType( MOVETYPE_NONE );
forcefield->setSolidType( SOLID_NOT );
forcefield->edict->s.scale = radius / 16;
alpha = ( damage * damage_mult ) / 100;
if ( alpha > 1 )
alpha = 1;
if ( alpha < 0.15f )
alpha = 0.15f;
forcefield->edict->s.alpha = alpha;
forcefield->edict->s.renderfx |= RF_TRANSLUCENT;
forcefield->PostEvent( EV_Remove, 0.1f );
return;
}
// if enabled you can't hurt teammates (but you can hurt yourself)
// knockback still occurs
if ( ( attacker != this ) && ( DM_FLAG( DF_MODELTEAMS | DF_SKINTEAMS ) ) )
{
if ( OnSameTeam ( this, attacker ) )
{
// check for friendly fire
if ( DM_FLAG( DF_FRIENDLY_FIRE ) )
meansofdeath = MOD_FRIENDLY_FIRE;
else
damage = 0;
}
}
if (groupnum == -1)
location = "all";
else
location = gi.Group_NumToName( edict->s.modelindex, groupnum );
// Adjust damage for skill level
if ( isClient() && !deathmatch->value && !(dflags & DAMAGE_NO_SKILL))
{
// Clamp the damage multiplier
if ( damage_mult > 2 )
damage_mult = 2;
switch( ( int )skill->value )
{
case 0:
damage *= 0.2f;
break;
case 1:
damage *= 0.4f;
break;
case 2:
damage *= 0.6f;
break;
default:
damage *= 0.8f;
break;
}
}
// Shields reduce damage by 75%
if ( flags & FL_SHIELDS )
{
damage *= 0.25f;
}
else if ( flags & FL_MUTANT )
{
damage *= 0.33f;
}
// If in deathmatch, client takes a minimum of 33% damage from source
if ( deathmatch->value )
{
damage *= 0.66f;
unmodified_damage = damage * 0.33f;
}
// check to see if we have armor in this location to reduce the damage
if (location[0] && !(dflags & DAMAGE_NO_ARMOR) )
{
if ( !strncmp( location,"all",3 ) )
{
char *armortypes[] = {"RiotHelmet", "FlakJacket", "FlakPants", NULL};
int i = 0;
float reduced_damage = 0;
// Go through all the armor types
while (armortypes[i])
{
float partial_damage = damage / 3;
float odam = partial_damage;
armor = ( Armor * )FindItem( armortypes[i] );
// Check for armor in this spot
if ( armor && ( armor->Amount() > 0 ) )
{
// Reduce the parital damage by the amount of armor
partial_damage -= armor->Amount();
if ( partial_damage < 0 )
partial_damage = 0;
// Remove the amount absorbed by the armor from the armor.
armor->Remove( odam - partial_damage );
// Keep track of the damage done to the armor for testing purposes
armor_damage += (odam - partial_damage );
}
// Keep track of damage done after armor has been applied
reduced_damage += partial_damage;
i++;
}
// This is the damage after all armor is done
damage = reduced_damage;
}
// else check for specific location based
else if ( !strncmp( location,"head",4 ) )
armor = ( Armor * )FindItem( "RiotHelmet" );
else if ( !strncmp(location,"torso",4 ) )
armor = ( Armor * )FindItem( "FlakJacket" );
// else if ( !strncmp( location,"arm",3 ) )
// armor = ( Armor * )FindItem( "FlakJacket" );
else if ( !strncmp(location,"leg",3 ) )
armor = ( Armor * )FindItem( "FlakPants" );
// If armor is there, remove the appropriate amount
if ( armor && ( armor->Amount() > 0 ) && !(dflags & DAMAGE_NO_ARMOR) )
{
float odam = damage;
damage -= armor->Amount();
if ( damage < 0 )
damage = 0;
armor->Remove( odam-damage );
armor_damage += (odam - damage );
}
}
damage += unmodified_damage;
// Damage multiplier
damage *= damage_mult;
// Damage skins if armor didn't absorb all damage
if ( ( damage > 0 ) && ( groupnum != -1 ) && ( flags & FL_BLOOD ) )
if ( !edict->s.groups[ groupnum ] )
edict->s.groups[ groupnum ]++;
// Show location based damage.
if ( sv_showdamagelocation->value && deathmatch->value )
{
// Send message to attacker
if ( attacker->isClient() )
{
if ( this->client )
{
PrintDamageLocationToAttacker( attacker->edict, this->client->pers.netname, location );
}
}
// Send message to victim
if ( this->isClient() && attacker != this )
{
PrintDamageLocationToVictim(this->edict, location);
}
}
// Shows detailed damage messages
if ( sv_showdamage->value )
{
// Send message to attacker
if ( attacker->isClient() )
{
if ( this->client )
{
gi.cprintf ( attacker->edict, PRINT_HIGH, "TARG:%s ARMOR_DAM:%0.2f TOT_DAM:%0.2f LOC:%s\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -