codemp/game/g_turret_G2.c File Reference

#include "g_local.h"
#include "../ghoul2/G2.h"
#include "q_shared.h"

Go to the source code of this file.

Defines

#define SPF_TURRETG2_CANRESPAWN   4
#define SPF_TURRETG2_TURBO   8
#define SPF_TURRETG2_LEAD_ENEMY   16
#define SPF_SHOWONRADAR   32
#define ARM_ANGLE_RANGE   60
#define HEAD_ANGLE_RANGE   90
#define name   "models/map_objects/imp_mine/turret_canon.glm"
#define name2   "models/map_objects/imp_mine/turret_damage.md3"
#define name3   "models/map_objects/wedge/laser_cannon_model.glm"
#define START_DIS   15

Functions

void G_SetEnemy (gentity_t *self, gentity_t *enemy)
void finish_spawning_turretG2 (gentity_t *base)
void ObjectDie (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath)
void turretG2_base_use (gentity_t *self, gentity_t *other, gentity_t *activator)
void G2Tur_SetBoneAngles (gentity_t *ent, char *bone, vec3_t angles)
void turretG2_set_models (gentity_t *self, qboolean dying)
void TurretG2Pain (gentity_t *self, gentity_t *attacker, int damage)
void turretG2_die (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath)
void TurboLaser_SetBoneAnim (gentity_t *eweb, int startFrame, int endFrame)
void WP_FireTurboLaserMissile (gentity_t *ent, vec3_t start, vec3_t dir)
void turretG2_respawn (gentity_t *self)
void turretG2_head_think (gentity_t *self)
void turretG2_base_think (gentity_t *self)
void SP_misc_turretG2 (gentity_t *base)


Define Documentation

#define ARM_ANGLE_RANGE   60
 

Definition at line 16 of file g_turret_G2.c.

#define HEAD_ANGLE_RANGE   90
 

Definition at line 17 of file g_turret_G2.c.

#define name   "models/map_objects/imp_mine/turret_canon.glm"
 

Definition at line 19 of file g_turret_G2.c.

Referenced by BG_SiegeFindClassByName(), BG_SiegeFindClassIndexByName(), BG_SiegeFindTeamForTheme(), BG_SiegeParseClassFile(), BG_SiegeParseTeamFile(), BG_SiegeTranslateForcePowers(), BG_SiegeTranslateGenericTable(), BindingIDFromName(), CG_DrawActiveFrame(), Cmd_DebugSetBodyAnim_f(), Cmd_Give_f(), COM_BeginParseSession(), G_BoneIndex(), G_BSPIndex(), G_ClientNumberFromName(), G_ClientNumberFromStrippedName(), G_EffectIndex(), G_GetBotInfoByName(), G_IconIndex(), G_ItemDisabled(), G_ModelIndex(), G_Say(), G_SoundIndex(), G_SoundSetIndex(), GetIDForString(), Item_Model_Paint(), Item_RunScript(), ItemParse_asset_model_go(), ItemParse_model_g2anim_go(), Menu_GetMatchingItemByNumber(), Menu_ItemDisable(), Menu_ItemsMatchingGroup(), Menu_SetFeederSelection(), NPC_Kill_f(), Q3_GetFloat(), Q3_GetString(), Q3_GetTag(), Q3_GetVector(), Q3_Kill(), Q3_Play(), Q3_PlaySound(), Q3_Remove(), Q3_SetICARUSFreeze(), Q3_SetLoopSound(), Script_Close(), Script_Disable(), Script_FadeIn(), Script_FadeOut(), Script_Hide(), Script_Open(), Script_Orbit(), Script_Scale(), Script_SetAsset(), Script_SetBackground(), Script_SetColor(), Script_SetFocus(), Script_SetItemBackground(), Script_SetItemColor(), Script_SetItemColorCvar(), Script_SetPlayerModel(), Script_Show(), Script_Transition(), Script_Transition2(), Script_Transition3(), SelectRandomTeamSpawnPoint(), SP_emplaced_gun(), Svcmd_AddBot_f(), Svcmd_BotList_f(), TAG_Add(), TAG_Find(), TAG_FindOwner(), TAG_GetAngles(), TAG_GetFlags(), TAG_GetOrigin(), TAG_GetOrigin2(), TAG_GetRadius(), TranslateSaberColor(), TranslateSaberStyle(), TranslateSaberType(), trap_AS_AddPrecacheEntry(), trap_AS_GetBModelSound(), trap_BotGetMapLocationGoal(), trap_BotGoalName(), trap_BotSetChatName(), trap_Cvar_GetHiddenVarValue(), trap_Cvar_Reset(), trap_ICARUS_GetFloatVariable(), trap_ICARUS_GetStringVariable(), trap_ICARUS_GetVectorVariable(), trap_ICARUS_RegisterScript(), trap_ICARUS_RunScript(), trap_LAN_AddServer(), trap_R_RegisterModel(), trap_R_RegisterShader(), trap_R_RegisterShaderNoMip(), trap_R_RegisterSkin(), trap_R_ShaderNameFromIndex(), trap_S_AddLocalSet(), trap_S_UpdateAmbientSet(), trap_SetBrushModel(), turretG2_set_models(), UI_GetBotInfoByName(), VEH_VehicleIndexForName(), VEH_VehWeaponIndexForName(), and WP_RemoveSaber().

#define name2   "models/map_objects/imp_mine/turret_damage.md3"
 

Definition at line 20 of file g_turret_G2.c.

Referenced by turretG2_set_models().

#define name3   "models/map_objects/wedge/laser_cannon_model.glm"
 

Definition at line 21 of file g_turret_G2.c.

Referenced by turretG2_set_models().

#define SPF_SHOWONRADAR   32
 

Definition at line 14 of file g_turret_G2.c.

Referenced by SP_misc_turretG2().

#define SPF_TURRETG2_CANRESPAWN   4
 

Definition at line 11 of file g_turret_G2.c.

Referenced by finish_spawning_turretG2(), turretG2_base_think(), and turretG2_die().

#define SPF_TURRETG2_LEAD_ENEMY   16
 

Definition at line 13 of file g_turret_G2.c.

#define SPF_TURRETG2_TURBO   8
 

Definition at line 12 of file g_turret_G2.c.

Referenced by finish_spawning_turretG2(), SP_misc_turretG2(), turretG2_head_think(), and turretG2_set_models().

#define START_DIS   15
 

Definition at line 310 of file g_turret_G2.c.


Function Documentation

void finish_spawning_turretG2 gentity_t base  ) 
 

Definition at line 1076 of file g_turret_G2.c.

References entityState_s::angles, AngleVectors(), atoi(), BG_FindItemForWeapon(), entityShared_t::contents, CONTENTS_BODY, CONTENTS_MONSTERCLIP, CONTENTS_PLAYERCLIP, CONTENTS_SHOTCLIP, gentity_s::count, entityShared_t::currentAngles, gentity_s::damage, gentity_s::die, EF2_BRACKET_ENTITY, entityState_s::eFlags2, ET_GENERAL, entityState_s::eType, FRAMETIME, G_EffectIndex(), g_gametype, G_ScaleNetHealth(), G_SetAngles(), G_SetOrigin(), G_SoundIndex(), G_SpawnFloat(), G_SpawnInt(), gentity_s::genericValue13, gentity_s::genericValue14, gentity_s::genericValue15, gentity_s::genericValue6, gentity_t, GT_SIEGE, gentity_s::health, entityState_s::iModelScale, vmCvar_t::integer, level, gentity_s::mass, MAT_METAL, gentity_s::material, gentity_s::maxHealth, entityShared_t::maxs, entityShared_t::mins, gentity_s::nextthink, NULL, entityState_s::origin, gentity_s::pain, qtrue, gentity_s::r, gentity_s::radius, random, gentity_s::random, RegisterItem(), ROLL, gentity_s::s, entityState_s::shouldtarget, gentity_s::spawnflags, gentity_s::speed, SPF_TURRETG2_CANRESPAWN, SPF_TURRETG2_TURBO, gentity_s::splashDamage, gentity_s::splashRadius, gentity_s::takedamage, gentity_s::team, gentity_s::teamnodmg, gentity_s::think, level_locals_t::time, trap_LinkEntity(), TurboLaser_SetBoneAnim(), turretG2_base_think(), turretG2_base_use(), turretG2_die(), TurretG2Pain(), gentity_s::use, vec3_t, VectorScale, VectorSet, gentity_s::wait, entityState_s::weapon, WP_BLASTER, and WP_TURRET.

Referenced by SP_misc_turretG2().

01077 {
01078         vec3_t          fwd;
01079         int                     t;
01080 
01081         if ( (base->spawnflags&2) )
01082         {
01083                 base->s.angles[ROLL] += 180;
01084                 base->s.origin[2] -= 22.0f;
01085         }
01086 
01087         G_SetAngles( base, base->s.angles );
01088         AngleVectors( base->r.currentAngles, fwd, NULL, NULL );
01089 
01090         G_SetOrigin(base, base->s.origin);
01091 
01092         base->s.eType = ET_GENERAL;
01093 
01094         if ( base->team && base->team[0] && //g_gametype.integer == GT_SIEGE &&
01095                 !base->teamnodmg)
01096         {
01097                 base->teamnodmg = atoi(base->team);
01098         }
01099         base->team = NULL;
01100 
01101         // Set up our explosion effect for the ExplodeDeath code....
01102         G_EffectIndex( "turret/explode" );
01103         G_EffectIndex( "sparks/spark_exp_nosnd" );
01104 
01105         base->use = turretG2_base_use;
01106         base->pain = TurretG2Pain;
01107 
01108         // don't start working right away
01109         base->think = turretG2_base_think;
01110         base->nextthink = level.time + FRAMETIME * 5;
01111 
01112         // this is really the pitch angle.....
01113         base->speed = 0;
01114 
01115         // respawn time defaults to 20 seconds
01116         if ( (base->spawnflags&SPF_TURRETG2_CANRESPAWN) && !base->count )
01117         {
01118                 base->count = 20000;
01119         }
01120 
01121         G_SpawnFloat( "shotspeed", "0", &base->mass );
01122         if ( (base->spawnflags&SPF_TURRETG2_TURBO) )
01123         {
01124                 if ( !base->random )
01125                 {//error worked into projectile direction
01126                         base->random = 2.0f;
01127                 }
01128 
01129                 if ( !base->mass )
01130                 {//misnomer: speed of projectile
01131                         base->mass = 20000;
01132                 }
01133 
01134                 if ( !base->health )
01135                 {
01136                         base->health = 2000;
01137                 }
01138 
01139                 // search radius
01140                 if ( !base->radius )
01141                 {
01142                         base->radius = 32768;
01143                 }
01144 
01145                 // How quickly to fire
01146                 if ( !base->wait )
01147                 {
01148                         base->wait = 1000;// + random() * 500;
01149                 }
01150 
01151                 if ( !base->splashDamage )
01152                 {
01153                         base->splashDamage = 200;
01154                 }
01155 
01156                 if ( !base->splashRadius )
01157                 {
01158                         base->splashRadius = 500;
01159                 }
01160 
01161                 // how much damage each shot does
01162                 if ( !base->damage )
01163                 {
01164                         base->damage = 500;
01165                 }
01166 
01167                 if ( (base->spawnflags&SPF_TURRETG2_TURBO) )
01168                 {
01169                         VectorSet( base->r.maxs, 64.0f, 64.0f, 30.0f );
01170                         VectorSet( base->r.mins, -64.0f, -64.0f, -30.0f );
01171                 }
01172                 //start in "off" anim
01173                 TurboLaser_SetBoneAnim( base, 4, 5 );
01174                 if ( g_gametype.integer == GT_SIEGE )
01175                 {//FIXME: designer-specified?
01176                         //FIXME: put on other entities, too, particularly siege objectives and bbrushes...
01177                         base->s.eFlags2 |= EF2_BRACKET_ENTITY;
01178                 }
01179         }
01180         else
01181         {
01182                 if ( !base->random )
01183                 {//error worked into projectile direction
01184                         base->random = 2.0f;
01185                 }
01186 
01187                 if ( !base->mass )
01188                 {//misnomer: speed of projectile
01189                         base->mass = 1100;
01190                 }
01191 
01192                 if ( !base->health )
01193                 {
01194                         base->health = 100;
01195                 }
01196 
01197                 // search radius
01198                 if ( !base->radius )
01199                 {
01200                         base->radius = 512;
01201                 }
01202 
01203                 // How quickly to fire
01204                 if ( !base->wait )
01205                 {
01206                         base->wait = 150 + random() * 55;
01207                 }
01208 
01209                 if ( !base->splashDamage )
01210                 {
01211                         base->splashDamage = 10;
01212                 }
01213 
01214                 if ( !base->splashRadius )
01215                 {
01216                         base->splashRadius = 25;
01217                 }
01218 
01219                 // how much damage each shot does
01220                 if ( !base->damage )
01221                 {
01222                         base->damage = 5;
01223                 }
01224 
01225                 if ( base->spawnflags & 2 )
01226                 {//upside-down, invert r.mins and maxe
01227                         VectorSet( base->r.maxs, 10.0f, 10.0f, 30.0f );
01228                         VectorSet( base->r.mins, -10.0f, -10.0f, 0.0f );
01229                 }
01230                 else
01231                 {
01232                         VectorSet( base->r.maxs, 10.0f, 10.0f, 0.0f );
01233                         VectorSet( base->r.mins, -10.0f, -10.0f, -30.0f );
01234                 }
01235         }
01236 
01237         //stash health off for respawn.  NOTE: cannot use maxhealth because that might not be set if not showing the health bar
01238         base->genericValue6 = base->health;
01239 
01240         G_SpawnInt( "showhealth", "0", &t );
01241         if (t)
01242         { //a non-0 maxhealth value will mean we want to show the health on the hud
01243                 base->maxHealth = base->health;
01244                 G_ScaleNetHealth(base);
01245                 base->s.shouldtarget = qtrue;
01246                 //base->s.owner = MAX_CLIENTS; //not owned by any client
01247         }
01248 
01249         if (base->s.iModelScale)
01250         { //let's scale the bbox too...
01251                 float fScale = base->s.iModelScale/100.0f;
01252                 VectorScale(base->r.mins, fScale, base->r.mins);
01253                 VectorScale(base->r.maxs, fScale, base->r.maxs);
01254         }
01255 
01256         // Precache special FX and moving sounds
01257         if ( (base->spawnflags&SPF_TURRETG2_TURBO) )
01258         {
01259                 base->genericValue13 = G_EffectIndex( "turret/turb_muzzle_flash" );
01260                 base->genericValue14 = G_EffectIndex( "turret/turb_shot" );
01261                 base->genericValue15 = G_EffectIndex( "turret/turb_impact" );
01262                 //FIXME: Turbo Laser Cannon sounds!
01263                 G_SoundIndex( "sound/vehicles/weapons/turbolaser/turn.wav" );
01264         }
01265         else
01266         {
01267                 G_SoundIndex( "sound/chars/turret/startup.wav" );
01268                 G_SoundIndex( "sound/chars/turret/shutdown.wav" );
01269                 G_SoundIndex( "sound/chars/turret/ping.wav" );
01270                 G_SoundIndex( "sound/chars/turret/move.wav" );
01271         }
01272 
01273         base->r.contents = CONTENTS_BODY|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_SHOTCLIP;
01274 
01275         //base->max_health = base->health;
01276         base->takedamage = qtrue;
01277         base->die  = turretG2_die;
01278 
01279         base->material = MAT_METAL;
01280         //base->r.svFlags |= SVF_NO_TELEPORT|SVF_NONNPC_ENEMY|SVF_SELF_ANIMATING;
01281 
01282         // Register this so that we can use it for the missile effect
01283         RegisterItem( BG_FindItemForWeapon( WP_BLASTER ));
01284 
01285         // But set us as a turret so that we can be identified as a turret
01286         base->s.weapon = WP_TURRET;
01287 
01288         trap_LinkEntity( base );
01289 }

void G2Tur_SetBoneAngles gentity_t ent,
char *  bone,
vec3_t  angles
 

Definition at line 24 of file g_turret_G2.c.

References BONE_ANGLES_POSTMULT, entityState_s::boneAngles1, entityState_s::boneAngles2, entityState_s::boneAngles3, entityState_s::boneAngles4, entityState_s::boneIndex1, entityState_s::boneIndex2, entityState_s::boneIndex3, entityState_s::boneIndex4, entityState_s::boneOrient, byte, Com_Printf(), G_BoneIndex(), gentity_t, gentity_s::ghoul2, level, NEGATIVE_X, NEGATIVE_Z, NULL, POSITIVE_Y, gentity_s::s, level_locals_t::time, trap_G2API_SetBoneAngles(), vec3_t, and VectorCopy.

Referenced by turretG2_set_models().

00025 {
00026 #ifdef _XBOX
00027         byte *thebone = &ent->s.boneIndex1;
00028         byte *firstFree = NULL;
00029 #else
00030         int *thebone = &ent->s.boneIndex1;
00031         int *firstFree = NULL;
00032 #endif
00033         int i = 0;
00034         int boneIndex = G_BoneIndex(bone);
00035         int flags, up, right, forward;
00036         vec3_t *boneVector = &ent->s.boneAngles1;
00037         vec3_t *freeBoneVec = NULL;
00038 
00039         while (thebone)
00040         {
00041                 if (!*thebone && !firstFree)
00042                 { //if the value is 0 then this index is clear, we can use it if we don't find the bone we want already existing.
00043                         firstFree = thebone;
00044                         freeBoneVec = boneVector;
00045                 }
00046                 else if (*thebone)
00047                 {
00048                         if (*thebone == boneIndex)
00049                         { //this is it
00050                                 break;
00051                         }
00052                 }
00053 
00054                 switch (i)
00055                 {
00056                 case 0:
00057                         thebone = &ent->s.boneIndex2;
00058                         boneVector = &ent->s.boneAngles2;
00059                         break;
00060                 case 1:
00061                         thebone = &ent->s.boneIndex3;
00062                         boneVector = &ent->s.boneAngles3;
00063                         break;
00064                 case 2:
00065                         thebone = &ent->s.boneIndex4;
00066                         boneVector = &ent->s.boneAngles4;
00067                         break;
00068                 default:
00069                         thebone = NULL;
00070                         boneVector = NULL;
00071                         break;
00072                 }
00073 
00074                 i++;
00075         }
00076 
00077         if (!thebone)
00078         { //didn't find it, create it
00079                 if (!firstFree)
00080                 { //no free bones.. can't do a thing then.
00081                         Com_Printf("WARNING: NPC has no free bone indexes\n");
00082                         return;
00083                 }
00084 
00085                 thebone = firstFree;
00086 
00087                 *thebone = boneIndex;
00088                 boneVector = freeBoneVec;
00089         }
00090 
00091         //If we got here then we have a vector and an index.
00092 
00093         //Copy the angles over the vector in the entitystate, so we can use the corresponding index
00094         //to set the bone angles on the client.
00095         VectorCopy(angles, *boneVector);
00096 
00097         //Now set the angles on our server instance if we have one.
00098 
00099         if (!ent->ghoul2)
00100         {
00101                 return;
00102         }
00103 
00104         flags = BONE_ANGLES_POSTMULT;
00105         up = POSITIVE_Y;
00106         right = NEGATIVE_Z;
00107         forward = NEGATIVE_X;
00108 
00109         //first 3 bits is forward, second 3 bits is right, third 3 bits is up
00110         ent->s.boneOrient = ((forward)|(right<<3)|(up<<6));
00111 
00112         trap_G2API_SetBoneAngles( ent->ghoul2,
00113                                         0,
00114                                         bone,
00115                                         angles, 
00116                                         flags,
00117                                         up,
00118                                         right,
00119                                         forward,
00120                                         NULL,
00121                                         100,
00122                                         level.time ); 
00123 }

void G_SetEnemy gentity_t self,
gentity_t enemy
 

void ObjectDie gentity_t self,
gentity_t inflictor,
gentity_t attacker,
int  damage,
int  meansOfDeath
 

Definition at line 21 of file g_combat.c.

References G_FreeEntity(), G_UseTargets(), gentity_t, and gentity_s::target.

Referenced by auto_turret_die(), ExplodeDeath(), and turretG2_die().

00022 {
00023         if(self->target)
00024         {
00025                 G_UseTargets(self, attacker);
00026         }
00027 
00028         //remove my script_targetname
00029         G_FreeEntity( self );
00030 }

void SP_misc_turretG2 gentity_t base  ) 
 

Definition at line 1021 of file g_turret_G2.c.

References EF_RADAROBJECT, EF_SHADER_ANIM, entityState_s::eFlags, finish_spawning_turretG2(), entityState_s::frame, G_IconIndex(), G_SpawnInt(), G_SpawnString(), entityState_s::genericenemyindex, gentity_s::genericValue4, gentity_s::genericValue8, gentity_t, entityState_s::iModelScale, gentity_s::modelScale, qfalse, gentity_s::s, gentity_s::spawnflags, SPF_SHOWONRADAR, SPF_TURRETG2_TURBO, and turretG2_set_models().

01023 {
01024         int customscaleVal;
01025         char* s;
01026 
01027         turretG2_set_models( base, qfalse );
01028 
01029         G_SpawnInt("painwait", "0", &base->genericValue4);
01030         base->genericValue8 = 0;
01031 
01032         G_SpawnInt("customscale", "0", &customscaleVal);
01033         base->s.iModelScale = customscaleVal;
01034         if (base->s.iModelScale)
01035         {
01036                 if (base->s.iModelScale > 1023)
01037                 {
01038                         base->s.iModelScale = 1023;
01039                 }
01040                 base->modelScale[0] = base->modelScale[1] = base->modelScale[2] = base->s.iModelScale/100.0f;
01041         }
01042 
01043         G_SpawnString( "icon", "", &s );
01044         if (s && s[0])
01045         { 
01046                 // We have an icon, so index it now.  We are reusing the genericenemyindex
01047                 // variable rather than adding a new one to the entity state.
01048                 base->s.genericenemyindex = G_IconIndex(s);
01049         }
01050 
01051         finish_spawning_turretG2( base );
01052 
01053         if (( base->spawnflags & 1 )) // Start_Off
01054         {
01055                 base->s.frame = 1; // black
01056         }
01057         else
01058         {
01059                 base->s.frame = 0; // glow
01060         }
01061         if ( !(base->spawnflags&SPF_TURRETG2_TURBO) )
01062         {
01063                 base->s.eFlags |= EF_SHADER_ANIM;
01064         }
01065 
01066         if (base->spawnflags & SPF_SHOWONRADAR)
01067         {
01068                 base->s.eFlags |= EF_RADAROBJECT;
01069         }
01070 #undef name
01071 #undef name2
01072 #undef name3
01073 }

void TurboLaser_SetBoneAnim gentity_t eweb,
int  startFrame,
int  endFrame
 

Definition at line 313 of file g_turret_G2.c.

References BONE_ANIM_BLEND, BONE_ANIM_OVERRIDE_FREEZE, EF_G2ANIMATING, entityState_s::eFlags, gentity_t, gentity_s::ghoul2, entityState_s::legsAnim, level, gentity_s::s, level_locals_t::time, entityState_s::torsoAnim, entityState_s::torsoFlip, and trap_G2API_SetBoneAnim().

Referenced by finish_spawning_turretG2().

00314 {
00315         //set info on the entity so it knows to start the anim on the client next snapshot.
00316         eweb->s.eFlags |= EF_G2ANIMATING;
00317 
00318         if (eweb->s.torsoAnim == startFrame && eweb->s.legsAnim == endFrame)
00319         { //already playing this anim, let's flag it to restart
00320                 eweb->s.torsoFlip = !eweb->s.torsoFlip;
00321         }
00322         else
00323         {
00324                 eweb->s.torsoAnim = startFrame;
00325                 eweb->s.legsAnim = endFrame;
00326         }
00327 
00328         //now set the animation on the server ghoul2 instance.
00329         assert(eweb->ghoul2);
00330         trap_G2API_SetBoneAnim(eweb->ghoul2, 0, "model_root", startFrame, endFrame,
00331                 (BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND), 1.0f, level.time, -1, 100);
00332 }

void turretG2_base_think gentity_t self  ) 
 

Definition at line 821 of file g_turret_G2.c.

References trace_t::allsolid, gentity_s::bounceCount, gentity_s::client, entityShared_t::currentOrigin, gentity_s::enemy, enemyDist, trace_t::entityNum, renderInfo_s::eyePoint, FL_NOTARGET, gentity_s::flags, FRAMETIME, gentity_s::genericValue5, gentity_t, gentity_s::health, gentity_s::inuse, gentity_s::last_move_time, level, MASK_SHOT, gentity_s::nextthink, NULL, entityState_s::number, qboolean, qfalse, qtrue, gentity_s::r, gentity_s::radius, random, gclient_s::renderInfo, gentity_s::s, gclient_s::sess, clientSession_t::sessionTeam, gentity_s::spawnflags, SPF_TURRETG2_CANRESPAWN, trace_t::startsolid, TEAM_SPECTATOR, level_locals_t::time, trap_InPVS(), trap_Trace(), turretG2_head_think(), turretG2_respawn(), vec3_t, VectorCopy, and VectorSubtract.

Referenced by finish_spawning_turretG2().

00823 {
00824         qboolean        turnOff = qtrue;
00825         float           enemyDist;
00826         vec3_t          enemyDir, org, org2;
00827 
00828         self->nextthink = level.time + FRAMETIME;
00829 
00830         if ( self->health <= 0 )
00831         {//dead
00832                 if (self->spawnflags & SPF_TURRETG2_CANRESPAWN)
00833                 {//can respawn
00834                         if ( self->genericValue5 && self->genericValue5 < level.time )
00835                         { //we are dead, see if it's time to respawn
00836                                 turretG2_respawn( self );
00837                         }
00838                 }
00839                 return;
00840         }
00841         else if ( self->spawnflags & 1 )
00842         {// not turned on
00843                 turretG2_turnoff( self );
00844                 turretG2_aim( self );
00845 
00846                 // No target
00847                 self->flags |= FL_NOTARGET;
00848                 return;
00849         }
00850         else
00851         {
00852                 // I'm all hot and bothered
00853                 self->flags &= ~FL_NOTARGET;
00854         }
00855 
00856         if ( self->enemy )
00857         {
00858                 if ( self->enemy->health < 0 
00859                         || !self->enemy->inuse )
00860                 {
00861                         self->enemy = NULL;
00862                 }
00863         }
00864 
00865         if ( self->last_move_time < level.time )
00866         {//MISNOMER: used a enemy recalcing debouncer
00867                 if ( turretG2_find_enemies( self ) )
00868                 {//found one
00869                         turnOff = qfalse;
00870                         if ( self->enemy->client )
00871                         {//hold on to clients for a min of 3 seconds
00872                                 self->last_move_time = level.time + 3000;
00873                         }
00874                         else
00875                         {//hold less
00876                                 self->last_move_time = level.time + 500;
00877                         }
00878                 }
00879         }
00880 
00881         if ( self->enemy != NULL )
00882         {
00883                 if ( self->enemy->client && self->enemy->client->sess.sessionTeam == TEAM_SPECTATOR )
00884                 {//don't keep going after spectators
00885                         self->enemy = NULL;
00886                 }
00887                 else
00888                 {//FIXME: remain single-minded or look for a new enemy every now and then?
00889                         // enemy is alive
00890                         VectorSubtract( self->enemy->r.currentOrigin, self->r.currentOrigin, enemyDir );
00891                         enemyDist = VectorLengthSquared( enemyDir );
00892 
00893                         if ( enemyDist < self->radius * self->radius )
00894                         {
00895                                 // was in valid radius
00896                                 if ( trap_InPVS( self->r.currentOrigin, self->enemy->r.currentOrigin ) )
00897                                 {
00898                                         // Every now and again, check to see if we can even trace to the enemy
00899                                         trace_t tr;
00900 
00901                                         if ( self->enemy->client )
00902                                         {
00903                                                 VectorCopy( self->enemy->client->renderInfo.eyePoint, org );
00904                                         }
00905                                         else
00906                                         {
00907                                                 VectorCopy( self->enemy->r.currentOrigin, org );
00908                                         }
00909                                         VectorCopy( self->r.currentOrigin, org2 );
00910                                         if ( self->spawnflags & 2 )
00911                                         {
00912                                                 org2[2] += 10;
00913                                         }
00914                                         else
00915                                         {
00916                                                 org2[2] -= 10;
00917                                         }
00918                                         trap_Trace( &tr, org2, NULL, NULL, org, self->s.number, MASK_SHOT );
00919 
00920                                         if ( !tr.allsolid && !tr.startsolid && tr.entityNum == self->enemy->s.number )
00921                                         {
00922                                                 turnOff = qfalse;       // Can see our enemy
00923                                         }
00924                                 }
00925                         }
00926 
00927                 }
00928         }
00929 
00930         if ( turnOff )
00931         {
00932                 if ( self->bounceCount < level.time ) // bounceCount is used to keep the thing from ping-ponging from on to off
00933                 {
00934                         turretG2_turnoff( self );
00935                 }
00936         }
00937         else
00938         {
00939                 // keep our enemy for a minimum of 2 seconds from now
00940                 self->bounceCount = level.time + 2000 + random() * 150;
00941         }
00942 
00943         turretG2_aim( self );
00944         if ( !turnOff )
00945         {
00946                 turretG2_head_think( self );
00947         }
00948 }

void turretG2_base_use gentity_t self,
gentity_t other,
gentity_t activator
 

Definition at line 951 of file g_turret_G2.c.

References EF_SHADER_ANIM, entityState_s::eFlags, entityState_s::frame, gentity_t, gentity_s::s, and gentity_s::spawnflags.

Referenced by finish_spawning_turretG2(), and turretG2_respawn().

00953 {
00954         // Toggle on and off
00955         self->spawnflags = (self->spawnflags ^ 1);
00956 
00957         if (( self->s.eFlags & EF_SHADER_ANIM ) && ( self->spawnflags & 1 )) // Start_Off
00958         {
00959                 self->s.frame = 1; // black
00960         }
00961         else
00962         {
00963                 self->s.frame = 0; // glow
00964         }
00965 }

void turretG2_die gentity_t self,
gentity_t inflictor,
gentity_t attacker,
int  damage,
int  meansOfDeath
 

Definition at line 236 of file g_turret_G2.c.

References entityState_s::apos, gentity_s::count, entityShared_t::currentAngles, entityShared_t::currentOrigin, gentity_s::die, EF_SHADER_ANIM, EFFECT_EXPLOSION_TURRET, entityState_s::eFlags, entityState_s::frame, G_PlayEffect(), G_RadiusDamage(), G_UseTargets(), gentity_s::genericValue5, gentity_t, gentity_s::health, entityState_s::health, level, entityState_s::loopSound, MOD_UNKNOWN, entityState_s::modelindex2, NULL, ObjectDie(), gentity_s::pain, qfalse, qtrue, gentity_s::r, gentity_s::s, entityState_s::shouldtarget, gentity_s::spawnflags, SPF_TURRETG2_CANRESPAWN, gentity_s::splashDamage, gentity_s::splashRadius, gentity_s::takedamage, gentity_s::target, level_locals_t::time, trajectory_t::trBase, trajectory_t::trDelta, turretG2_set_models(), gentity_s::use, vec3_t, VectorClear, VectorCopy, VectorMA, VectorSet, and entityState_s::weapon.

Referenced by finish_spawning_turretG2(), and turretG2_respawn().

00238 {
00239         vec3_t  forward = { 0,0,-1 }, pos;
00240 
00241         // Turn off the thinking of the base & use it's targets
00242         //self->think = NULL;
00243         self->use = NULL;
00244 
00245         // clear my data
00246         self->die  = NULL;
00247         self->pain = NULL;
00248         self->takedamage = qfalse;
00249         self->s.health = self->health = 0;
00250         self->s.loopSound = 0;
00251         self->s.shouldtarget = qfalse;
00252         //self->s.owner = MAX_CLIENTS; //not owned by any client
00253 
00254         // hack the effect angle so that explode death can orient the effect properly
00255         if ( self->spawnflags & 2 )
00256         {
00257                 VectorSet( forward, 0, 0, 1 );
00258         }
00259 
00260 //      VectorCopy( self->r.currentOrigin, self->s.pos.trBase );
00261 
00262         VectorMA( self->r.currentOrigin, 12, forward, pos );
00263         G_PlayEffect( EFFECT_EXPLOSION_TURRET, pos, forward );
00264         
00265         if ( self->splashDamage > 0 && self->splashRadius > 0 )
00266         {
00267                 G_RadiusDamage( self->r.currentOrigin,
00268                                                 attacker,
00269                                                 self->splashDamage,
00270                                                 self->splashRadius,
00271                                                 attacker,
00272                                                 NULL,
00273                                                 MOD_UNKNOWN );
00274         }
00275 
00276         if ( self->s.eFlags & EF_SHADER_ANIM )
00277         {
00278                 self->s.frame = 1; // black
00279         }
00280 
00281         self->s.weapon = 0; // crosshair code uses this to mark crosshair red
00282 
00283         if ( self->s.modelindex2 )
00284         {
00285                 // switch to damage model if we should
00286                 turretG2_set_models( self, qtrue );
00287 
00288                 VectorCopy( self->r.currentAngles, self->s.apos.trBase );
00289                 VectorClear( self->s.apos.trDelta );
00290                 
00291                 if ( self->target )
00292                 {
00293                         G_UseTargets( self, attacker );
00294                 }
00295                 
00296                 if (self->spawnflags & SPF_TURRETG2_CANRESPAWN)
00297                 {//respawn
00298                         if (self->health < 1 && !self->genericValue5)
00299                         { //we are dead, set our respawn delay if we have one
00300                                 self->genericValue5 = level.time + self->count;
00301                         }
00302                 }
00303         }
00304         else
00305         {
00306                 ObjectDie( self, inflictor, attacker, damage, meansOfDeath );
00307         }
00308 }

void turretG2_head_think gentity_t self  ) 
 

Definition at line 429 of file g_turret_G2.c.

References gentity_s::alt_fire, gentity_s::attackDebounceTime, entityShared_t::currentAngles, entityShared_t::currentOrigin, gentity_s::enemy, gentity_s::fly_sound_debounce_time, gentity_s::genericValue11, gentity_s::genericValue12, gentity_t, gentity_s::ghoul2, level, gentity_s::modelScale, NEGATIVE_X, NULL, ORIGIN, POSITIVE_X, gentity_s::r, gentity_s::setTime, gentity_s::spawnflags, SPF_TURRETG2_TURBO, START_DIS, level_locals_t::time, trap_G2API_GetBoltMatrix(), vec3_t, VectorMA, and gentity_s::wait.

Referenced by turretG2_base_think().

00431 {
00432         // if it's time to fire and we have an enemy, then gun 'em down!  pushDebounce time controls next fire time
00433         if ( self->enemy 
00434                 && self->setTime < level.time 
00435                 && self->attackDebounceTime < level.time )
00436         {
00437                 vec3_t          fwd, org;
00438                 mdxaBone_t      boltMatrix;
00439 
00440                 // set up our next fire time
00441                 self->setTime = level.time + self->wait;
00442 
00443                 // Getting the flash bolt here
00444                 trap_G2API_GetBoltMatrix( self->ghoul2,
00445                                         0, 
00446                                         (self->alt_fire?self->genericValue12:self->genericValue11),
00447                                         &boltMatrix, 
00448                                         self->r.currentAngles, 
00449                                         self->r.currentOrigin, 
00450                                         level.time,
00451                                         NULL, 
00452                                         self->modelScale );
00453                 if ( (self->spawnflags&SPF_TURRETG2_TURBO) )
00454                 {
00455                         self->alt_fire = !self->alt_fire;
00456                 }
00457 
00458                 BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, org );
00459                 //BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_Y, fwd );
00460                 if ( (self->spawnflags&SPF_TURRETG2_TURBO) )
00461                 {
00462                         BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_X, fwd );
00463                 }
00464                 else
00465                 {
00466                         BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_X, fwd );
00467                 }
00468 
00469                 VectorMA( org, START_DIS, fwd, org );
00470 
00471                 turretG2_fire( self, org, fwd );
00472                 self->fly_sound_debounce_time = level.time;//used as lastShotTime
00473         }
00474 }

void turretG2_respawn gentity_t self  ) 
 

Definition at line 406 of file g_turret_G2.c.

References gentity_s::die, EF_SHADER_ANIM, entityState_s::eFlags, entityState_s::frame, G_ScaleNetHealth(), gentity_s::genericValue5, gentity_s::genericValue6, gentity_t, gentity_s::health, entityState_s::health, gentity_s::maxHealth, gentity_s::pain, qfalse, qtrue, gentity_s::s, entityState_s::shouldtarget, gentity_s::takedamage, turretG2_base_use(), turretG2_die(), turretG2_set_models(), TurretG2Pain(), gentity_s::use, entityState_s::weapon, and WP_TURRET.

Referenced by turretG2_base_think().

00407 {
00408         self->use = turretG2_base_use;
00409         self->pain = TurretG2Pain;
00410         self->die  = turretG2_die;
00411         self->takedamage = qtrue;
00412         self->s.shouldtarget = qtrue;
00413         //self->s.owner = MAX_CLIENTS; //not owned by any client
00414         if ( self->s.eFlags & EF_SHADER_ANIM )
00415         {
00416                 self->s.frame = 0; // normal
00417         }
00418         self->s.weapon = WP_TURRET; // crosshair code uses this to mark crosshair red
00419 
00420         turretG2_set_models( self, qfalse );
00421         self->s.health = self->health = self->genericValue6;
00422         if (self->maxHealth) {
00423                 G_ScaleNetHealth(self);
00424         }
00425         self->genericValue5 = 0;//clear this now
00426 }

void turretG2_set_models gentity_t self,
qboolean  dying
 

Definition at line 125 of file g_turret_G2.c.

References entityState_s::g2radius, G2Tur_SetBoneAngles(), G_KillG2Queue(), G_ModelIndex(), gentity_s::genericValue11, gentity_s::genericValue12, gentity_t, gentity_s::ghoul2, entityState_s::modelGhoul2, entityState_s::modelindex, entityState_s::modelindex2, name, name2, name3, entityState_s::number, gentity_s::s, gentity_s::spawnflags, SPF_TURRETG2_TURBO, trap_G2API_AddBolt(), trap_G2API_InitGhoul2Model(), trap_G2API_RemoveGhoul2Model(), and vec3_origin.

Referenced by SP_misc_turretG2(), turretG2_die(), and turretG2_respawn().

00126 {
00127         if ( dying )
00128         {
00129                 if ( !(self->spawnflags&SPF_TURRETG2_TURBO) )
00130                 {
00131                         self->s.modelindex = G_ModelIndex( name2 );
00132                         self->s.modelindex2 = G_ModelIndex( name );
00133                 }
00134                 
00135                 trap_G2API_RemoveGhoul2Model( &self->ghoul2, 0 );
00136                 G_KillG2Queue( self->s.number );
00137                 self->s.modelGhoul2 = 0;
00138                 /*
00139                 trap_G2API_InitGhoul2Model( &self->ghoul2,
00140                                                                         name2,
00141                                                                         0, //base->s.modelindex,
00142                                                                         //note, this is not the same kind of index - this one's referring to the actual
00143                                                                         //index of the model in the g2 instance, whereas modelindex is the index of a
00144                                                                         //configstring -rww
00145                                                                         0,
00146                                                                         0,
00147                                                                         0,
00148                                                                         0);
00149                 */
00150         }
00151         else
00152         {
00153                 if ( !(self->spawnflags&SPF_TURRETG2_TURBO) )
00154                 {
00155                         self->s.modelindex = G_ModelIndex( name );
00156                         self->s.modelindex2 = G_ModelIndex( name2 );
00157                         //set the new onw
00158                         trap_G2API_InitGhoul2Model( &self->ghoul2,
00159                                                                                 name,
00160                                                                                 0, //base->s.modelindex,
00161                                                                                 //note, this is not the same kind of index - this one's referring to the actual
00162                                                                                 //index of the model in the g2 instance, whereas modelindex is the index of a
00163                                                                                 //configstring -rww
00164                                                                                 0,
00165                                                                                 0,
00166                                                                                 0,
00167                                                                                 0);
00168                 }
00169                 else
00170                 {
00171                         self->s.modelindex = G_ModelIndex( name3 );
00172                         //set the new onw
00173                         trap_G2API_InitGhoul2Model( &self->ghoul2,
00174                                                                                 name3,
00175                                                                                 0, //base->s.modelindex,
00176                                                                                 //note, this is not the same kind of index - this one's referring to the actual
00177                                                                                 //index of the model in the g2 instance, whereas modelindex is the index of a
00178                                                                                 //configstring -rww
00179                                                                                 0,
00180                                                                                 0,
00181                                                                                 0,
00182                                                                                 0);
00183                 }
00184                 
00185                 self->s.modelGhoul2 = 1;
00186                 if ( (self->spawnflags&SPF_TURRETG2_TURBO) )
00187                 {//larger
00188                         self->s.g2radius = 128;
00189                 }
00190                 else
00191                 {
00192                         self->s.g2radius = 80;
00193                 }
00194 
00195                 if ( (self->spawnflags&SPF_TURRETG2_TURBO) )
00196                 {//different pitch bone and muzzle flash points
00197                         G2Tur_SetBoneAngles(self, "pitch", vec3_origin);
00198                         self->genericValue11 = trap_G2API_AddBolt( self->ghoul2, 0, "*muzzle1" );
00199                         self->genericValue12 = trap_G2API_AddBolt( self->ghoul2, 0, "*muzzle2" );
00200                 }
00201                 else
00202                 {
00203                         G2Tur_SetBoneAngles(self, "Bone_body", vec3_origin);
00204                         self->genericValue11 = trap_G2API_AddBolt( self->ghoul2, 0, "*flash03" );
00205                 }
00206         }
00207 }

void TurretG2Pain gentity_t self,
gentity_t attacker,
int  damage
 

Definition at line 210 of file g_turret_G2.c.

References gentity_s::attackDebounceTime, gentity_s::client, gentity_s::enemy, G_SetEnemy(), G_UseTargets2(), gentity_s::genericValue4, gentity_s::genericValue8, gentity_t, level, gentity_s::painDebounceTime, gentity_s::paintarget, gclient_s::ps, random, level_locals_t::time, playerState_s::weapon, and WP_DEMP2.

Referenced by finish_spawning_turretG2(), and turretG2_respawn().

00212 {
00213         if (self->paintarget && self->paintarget[0])
00214         {
00215                 if (self->genericValue8 < level.time)
00216                 {
00217                         G_UseTargets2(self, self, self->paintarget);
00218                         self->genericValue8 = level.time + self->genericValue4;
00219                 }
00220         }
00221 
00222         if ( attacker->client && attacker->client->ps.weapon == WP_DEMP2 )
00223         {
00224                 self->attackDebounceTime = level.time + 2000 + random() * 500;
00225                 self->painDebounceTime = self->attackDebounceTime;
00226         }
00227         if ( !self->enemy )
00228         {//react to being hit
00229                 G_SetEnemy( self, attacker );
00230         }
00231         //self->s.health = self->health;
00232         //mmm..yes..bad.
00233 }

void WP_FireTurboLaserMissile gentity_t ent,
vec3_t  start,
vec3_t  dir
 

Definition at line 384 of file g_weapon.c.

References gentity_s::bounceCount, gentity_s::classname, gentity_s::clipmask, CreateMissile(), gentity_s::damage, DAMAGE_DEATH_KNOCKBACK, gentity_s::dflags, entityState_s::emplacedOwner, G_FreeEntity(), gentity_s::genericValue14, gentity_s::genericValue15, gentity_t, level, MASK_SHOT, gentity_s::mass, gentity_s::methodOfDeath, MOD_TURBLAST, gentity_s::nextthink, entityState_s::number, entityState_s::otherEntityNum2, entityState_s::owner, qfalse, gentity_s::s, gentity_s::splashDamage, gentity_s::splashMethodOfDeath, gentity_s::splashRadius, gentity_s::think, level_locals_t::time, vec3_t, entityState_s::weapon, and WP_TURRET.

00386 {
00387         int velocity    = ent->mass; //FIXME: externalize
00388         gentity_t *missile;
00389 
00390         missile = CreateMissile( start, dir, velocity, 10000, ent, qfalse );
00391         
00392         //use a custom shot effect
00393         missile->s.otherEntityNum2 = ent->genericValue14;
00394         //use a custom impact effect
00395         missile->s.emplacedOwner = ent->genericValue15;
00396 
00397         missile->classname = "turbo_proj";
00398         missile->s.weapon = WP_TURRET;
00399 
00400         missile->damage = ent->damage;          //FIXME: externalize
00401         missile->splashDamage = ent->splashDamage;      //FIXME: externalize
00402         missile->splashRadius = ent->splashRadius;      //FIXME: externalize
00403         missile->dflags = DAMAGE_DEATH_KNOCKBACK;
00404         missile->methodOfDeath = MOD_TURBLAST; //count as a heavy weap
00405         missile->splashMethodOfDeath = MOD_TURBLAST;// ?SPLASH;
00406         missile->clipmask = MASK_SHOT;
00407 
00408         // we don't want it to bounce forever
00409         missile->bounceCount = 8;
00410 
00411         //set veh as cgame side owner for purpose of fx overrides
00412         missile->s.owner = ent->s.number;
00413 
00414         //don't let them last forever
00415         missile->think = G_FreeEntity;
00416         missile->nextthink = level.time + 5000;//at 20000 speed, that should be more than enough
00417 }