#include "g_local.h"#include "q_shared.h"Go to the source code of this file.
Defines | |
| #define | START_DIS 15 |
Functions | |
| void | G_SetEnemy (gentity_t *self, gentity_t *enemy) |
| qboolean | turret_base_spawn_top (gentity_t *base) |
| void | ObjectDie (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath) |
| void | TurretPain (gentity_t *self, gentity_t *attacker, int damage) |
| void | TurretBasePain (gentity_t *self, gentity_t *attacker, int damage) |
| void | auto_turret_die (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath) |
| void | bottom_die (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath) |
| void | turret_head_think (gentity_t *self) |
| void | turret_base_think (gentity_t *self) |
| void | turret_base_use (gentity_t *self, gentity_t *other, gentity_t *activator) |
| void | SP_misc_turret (gentity_t *base) |
|
|
Definition at line 126 of file g_turret.c. Referenced by turret_head_think(), and turretG2_head_think(). |
|
||||||||||||||||||||||||
|
Definition at line 51 of file g_turret.c. References entityState_s::apos, entityShared_t::currentAngles, entityShared_t::currentOrigin, gentity_s::die, EFFECT_EXPLOSION_TURRET, G_EffectIndex(), g_entities, G_PlayEffect(), G_PlayEffectID(), G_RadiusDamage(), G_UseTargets(), gentity_t, gentity_s::health, entityState_s::health, entityState_s::loopSound, entityShared_t::maxs, MOD_UNKNOWN, entityState_s::modelindex, entityState_s::modelindex2, NULL, ObjectDie(), entityShared_t::ownerNum, qfalse, gentity_s::r, gentity_s::s, entityState_s::shouldtarget, gentity_s::splashDamage, gentity_s::splashRadius, gentity_s::takedamage, gentity_s::target, gentity_s::target_ent, trajectory_t::trBase, trajectory_t::trDelta, vec3_t, VectorClear, VectorCopy, and entityState_s::weapon. Referenced by bottom_die(), and turret_base_spawn_top().
00053 {
00054 vec3_t forward = { 0,0, 1 }, pos;
00055
00056 // Turn off the thinking of the base & use it's targets
00057 g_entities[self->r.ownerNum].think = NULL;
00058 g_entities[self->r.ownerNum].use = NULL;
00059
00060 // clear my data
00061 self->die = NULL;
00062 self->takedamage = qfalse;
00063 self->s.health = self->health = 0;
00064 self->s.loopSound = 0;
00065 self->s.shouldtarget = qfalse;
00066 //self->s.owner = MAX_CLIENTS; //not owned by any client
00067
00068 VectorCopy( self->r.currentOrigin, pos );
00069 pos[2] += self->r.maxs[2]*0.5f;
00070 G_PlayEffect( EFFECT_EXPLOSION_TURRET, pos, forward );
00071 G_PlayEffectID( G_EffectIndex( "turret/explode" ), pos, forward );
00072
00073 if ( self->splashDamage > 0 && self->splashRadius > 0 )
00074 {
00075 G_RadiusDamage( self->r.currentOrigin,
00076 attacker,
00077 self->splashDamage,
00078 self->splashRadius,
00079 attacker,
00080 NULL,
00081 MOD_UNKNOWN );
00082 }
00083
00084 self->s.weapon = 0; // crosshair code uses this to mark crosshair red
00085
00086
00087 if ( self->s.modelindex2 )
00088 {
00089 // switch to damage model if we should
00090 self->s.modelindex = self->s.modelindex2;
00091
00092 if (self->target_ent && self->target_ent->s.modelindex2)
00093 {
00094 self->target_ent->s.modelindex = self->target_ent->s.modelindex2;
00095 }
00096
00097 VectorCopy( self->r.currentAngles, self->s.apos.trBase );
00098 VectorClear( self->s.apos.trDelta );
00099
00100 if ( self->target )
00101 {
00102 G_UseTargets( self, attacker );
00103 }
00104 }
00105 else
00106 {
00107 ObjectDie( self, inflictor, attacker, damage, meansOfDeath );
00108 }
00109 }
|
|
||||||||||||||||||||||||
|
Definition at line 112 of file g_turret.c. References auto_turret_die(), G_ScaleNetHealth(), gentity_t, gentity_s::health, gentity_s::maxHealth, and gentity_s::target_ent. Referenced by turret_base_spawn_top().
00114 {
00115 if (self->target_ent && self->target_ent->health > 0)
00116 {
00117 self->target_ent->health = self->health;
00118 if (self->target_ent->maxHealth)
00119 {
00120 G_ScaleNetHealth(self->target_ent);
00121 }
00122 auto_turret_die(self->target_ent, inflictor, attacker, damage, meansOfDeath);
00123 }
00124 }
|
|
||||||||||||
|
|
|
||||||||||||||||||||||||
|
Definition at line 21 of file g_combat.c.
00022 {
00023 if(self->target)
00024 {
00025 G_UseTargets(self, attacker);
00026 }
00027
00028 //remove my script_targetname
00029 G_FreeEntity( self );
00030 }
|
|
|
Definition at line 663 of file g_turret.c. References entityState_s::angles, entityShared_t::contents, CONTENTS_BODY, FRAMETIME, G_FreeEntity(), G_IconIndex(), G_ModelIndex(), G_SetAngles(), G_SetOrigin(), G_SpawnString(), entityState_s::genericenemyindex, gentity_t, level, entityShared_t::maxs, entityShared_t::mins, entityState_s::modelindex, entityState_s::modelindex2, gentity_s::nextthink, entityState_s::origin, gentity_s::r, gentity_s::s, gentity_s::think, level_locals_t::time, trap_LinkEntity(), turret_base_spawn_top(), turret_base_think(), turret_base_use(), gentity_s::use, and VectorSet.
00665 {
00666 char* s;
00667
00668 base->s.modelindex2 = G_ModelIndex( "models/map_objects/hoth/turret_bottom.md3" );
00669 base->s.modelindex = G_ModelIndex( "models/map_objects/hoth/turret_base.md3" );
00670 //base->playerModel = gi.G2API_InitGhoul2Model( base->ghoul2, "models/map_objects/imp_mine/turret_canon.glm", base->s.modelindex );
00671 //base->s.radius = 80.0f;
00672
00673 //gi.G2API_SetBoneAngles( &base->ghoul2[base->playerModel], "Bone_body", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Y, POSITIVE_Z, POSITIVE_X, NULL );
00674 //base->torsoBolt = gi.G2API_AddBolt( &base->ghoul2[base->playerModel], "*flash03" );
00675
00676 G_SpawnString( "icon", "", &s );
00677 if (s && s[0])
00678 {
00679 // We have an icon, so index it now. We are reusing the genericenemyindex
00680 // variable rather than adding a new one to the entity state.
00681 base->s.genericenemyindex = G_IconIndex(s);
00682 }
00683
00684 G_SetAngles( base, base->s.angles );
00685 G_SetOrigin( base, base->s.origin );
00686
00687 base->r.contents = CONTENTS_BODY;
00688
00689 VectorSet( base->r.maxs, 32.0f, 32.0f, 128.0f );
00690 VectorSet( base->r.mins, -32.0f, -32.0f, 0.0f );
00691
00692 base->use = turret_base_use;
00693 base->think = turret_base_think;
00694 // don't start working right away
00695 base->nextthink = level.time + FRAMETIME * 5;
00696
00697 trap_LinkEntity( base );
00698
00699 if ( !turret_base_spawn_top( base ) )
00700 {
00701 G_FreeEntity( base );
00702 }
00703 }
|
|
|
Definition at line 706 of file g_turret.c. References gentity_s::alliedTeam, entityState_s::angles, atoi(), auto_turret_die(), BG_FindItemForWeapon(), bottom_die(), entityShared_t::contents, CONTENTS_BODY, gentity_s::count, gentity_s::damage, gentity_s::die, ET_GENERAL, entityState_s::eType, G_EffectIndex(), G_ModelIndex(), G_ScaleNetHealth(), G_SetAngles(), G_SetOrigin(), G_SoundIndex(), G_Spawn(), G_SpawnFloat(), G_SpawnInt(), gentity_s::genericValue13, gentity_s::genericValue14, gentity_s::genericValue15, gentity_t, gentity_s::health, gentity_s::mass, MAT_METAL, gentity_s::material, gentity_s::maxHealth, entityShared_t::maxs, entityShared_t::mins, entityState_s::modelindex, entityState_s::modelindex2, NULL, entityState_s::number, entityState_s::origin, entityShared_t::ownerNum, gentity_s::pain, qboolean, qfalse, qtrue, gentity_s::r, gentity_s::radius, random, RegisterItem(), gentity_s::s, entityState_s::shouldtarget, gentity_s::speed, gentity_s::splashDamage, gentity_s::splashRadius, gentity_s::takedamage, gentity_s::target_ent, gentity_s::team, gentity_s::teamnodmg, entityState_s::teamowner, trap_LinkEntity(), TurretBasePain(), TurretPain(), vec3_t, VectorCopy, VectorSet, gentity_s::wait, entityState_s::weapon, and WP_EMPLACED_GUN. Referenced by SP_misc_turret().
00707 {
00708 vec3_t org;
00709 int t;
00710
00711 gentity_t *top = G_Spawn();
00712 if ( !top )
00713 {
00714 return qfalse;
00715 }
00716
00717 top->s.modelindex = G_ModelIndex( "models/map_objects/hoth/turret_top_new.md3" );
00718 top->s.modelindex2 = G_ModelIndex( "models/map_objects/hoth/turret_top.md3" );
00719 G_SetAngles( top, base->s.angles );
00720 VectorCopy( base->s.origin, org );
00721 org[2] += 128;
00722 G_SetOrigin( top, org );
00723
00724 base->r.ownerNum = top->s.number;
00725 top->r.ownerNum = base->s.number;
00726
00727 if ( base->team && base->team[0] && //g_gametype.integer == GT_SIEGE &&
00728 !base->teamnodmg)
00729 {
00730 base->teamnodmg = atoi(base->team);
00731 }
00732 base->team = NULL;
00733 top->teamnodmg = base->teamnodmg;
00734 top->alliedTeam = base->alliedTeam;
00735
00736 base->s.eType = ET_GENERAL;
00737
00738 // Set up our explosion effect for the ExplodeDeath code....
00739 G_EffectIndex( "turret/explode" );
00740 G_EffectIndex( "sparks/spark_exp_nosnd" );
00741 G_EffectIndex( "turret/hoth_muzzle_flash" );
00742
00743 // this is really the pitch angle.....
00744 top->speed = 0;
00745
00746 // this is a random time offset for the no-enemy-search-around-mode
00747 top->count = random() * 9000;
00748
00749 if ( !base->health )
00750 {
00751 base->health = 3000;
00752 }
00753 top->health = base->health;
00754
00755 G_SpawnInt( "showhealth", "0", &t );
00756
00757 if (t)
00758 { //a non-0 maxhealth value will mean we want to show the health on the hud
00759 top->maxHealth = base->health; //acts as "maxhealth"
00760 G_ScaleNetHealth(top);
00761
00762 base->maxHealth = base->health;
00763 G_ScaleNetHealth(base);
00764 }
00765
00766 base->takedamage = qtrue;
00767 base->pain = TurretBasePain;
00768 base->die = bottom_die;
00769
00770 //design specified shot speed
00771 G_SpawnFloat( "shotspeed", "1100", &base->mass );
00772 top->mass = base->mass;
00773
00774 //even if we don't want to show health, let's at least light the crosshair up properly over ourself
00775 if ( !top->s.teamowner )
00776 {
00777 top->s.teamowner = top->alliedTeam;
00778 }
00779
00780 base->alliedTeam = top->alliedTeam;
00781 base->s.teamowner = top->s.teamowner;
00782
00783 base->s.shouldtarget = qtrue;
00784 top->s.shouldtarget = qtrue;
00785
00786 //link them to each other
00787 base->target_ent = top;
00788 top->target_ent = base;
00789
00790 //top->s.owner = MAX_CLIENTS; //not owned by any client
00791
00792 // search radius
00793 if ( !base->radius )
00794 {
00795 base->radius = 1024;
00796 }
00797 top->radius = base->radius;
00798
00799 // How quickly to fire
00800 if ( !base->wait )
00801 {
00802 base->wait = 300 + random() * 55;
00803 }
00804 top->wait = base->wait;
00805
00806 if ( !base->splashDamage )
00807 {
00808 base->splashDamage = 300;
00809 }
00810 top->splashDamage = base->splashDamage;
00811
00812 if ( !base->splashRadius )
00813 {
00814 base->splashRadius = 128;
00815 }
00816 top->splashRadius = base->splashRadius;
00817
00818 // how much damage each shot does
00819 if ( !base->damage )
00820 {
00821 base->damage = 100;
00822 }
00823 top->damage = base->damage;
00824
00825 // how fast it turns
00826 if ( !base->speed )
00827 {
00828 base->speed = 20;
00829 }
00830 top->speed = base->speed;
00831
00832 VectorSet( top->r.maxs, 48.0f, 48.0f, 16.0f );
00833 VectorSet( top->r.mins, -48.0f, -48.0f, 0.0f );
00834 // Precache moving sounds
00835 //G_SoundIndex( "sound/chars/turret/startup.wav" );
00836 //G_SoundIndex( "sound/chars/turret/shutdown.wav" );
00837 //G_SoundIndex( "sound/chars/turret/ping.wav" );
00838 G_SoundIndex( "sound/vehicles/weapons/hoth_turret/turn.wav" );
00839 top->genericValue13 = G_EffectIndex( "turret/hoth_muzzle_flash" );
00840 top->genericValue14 = G_EffectIndex( "turret/hoth_shot" );
00841 top->genericValue15 = G_EffectIndex( "turret/hoth_impact" );
00842
00843 top->r.contents = CONTENTS_BODY;
00844
00845 //base->max_health = base->health;
00846 top->takedamage = qtrue;
00847 top->pain = TurretPain;
00848 top->die = auto_turret_die;
00849
00850 top->material = MAT_METAL;
00851 //base->r.svFlags |= SVF_NO_TELEPORT|SVF_NONNPC_ENEMY|SVF_SELF_ANIMATING;
00852
00853 // Register this so that we can use it for the missile effect
00854 RegisterItem( BG_FindItemForWeapon( WP_EMPLACED_GUN ));
00855
00856 // But set us as a turret so that we can be identified as a turret
00857 top->s.weapon = WP_EMPLACED_GUN;
00858
00859 trap_LinkEntity( top );
00860 return qtrue;
00861 }
|
|
|
Definition at line 505 of file g_turret.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_t, gentity_s::health, 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, trace_t::startsolid, TEAM_SPECTATOR, level_locals_t::time, trap_InPVS(), trap_Trace(), turret_head_think(), vec3_t, VectorCopy, and VectorSubtract. Referenced by SP_misc_turret().
00507 {
00508 qboolean turnOff = qtrue;
00509 float enemyDist;
00510 vec3_t enemyDir, org, org2;
00511
00512 if ( self->spawnflags & 1 )
00513 {
00514 // not turned on
00515 turret_turnoff( self );
00516
00517 // No target
00518 self->flags |= FL_NOTARGET;
00519 self->nextthink = -1;//never think again
00520 return;
00521 }
00522 else
00523 {
00524 // I'm all hot and bothered
00525 self->flags &= ~FL_NOTARGET;
00526 //remember to keep thinking!
00527 self->nextthink = level.time + FRAMETIME;
00528 }
00529
00530 if ( !self->enemy )
00531 {
00532 if ( turret_find_enemies( self ))
00533 {
00534 turnOff = qfalse;
00535 }
00536 }
00537 else if ( self->enemy->client && self->enemy->client->sess.sessionTeam == TEAM_SPECTATOR )
00538 {//don't keep going after spectators
00539 self->enemy = NULL;
00540 }
00541 else
00542 {//FIXME: remain single-minded or look for a new enemy every now and then?
00543 if ( self->enemy->health > 0 )
00544 {
00545 // enemy is alive
00546 VectorSubtract( self->enemy->r.currentOrigin, self->r.currentOrigin, enemyDir );
00547 enemyDist = VectorLengthSquared( enemyDir );
00548
00549 if ( enemyDist < (self->radius * self->radius) )
00550 {
00551 // was in valid radius
00552 if ( trap_InPVS( self->r.currentOrigin, self->enemy->r.currentOrigin ) )
00553 {
00554 // Every now and again, check to see if we can even trace to the enemy
00555 trace_t tr;
00556
00557 if ( self->enemy->client )
00558 {
00559 VectorCopy( self->enemy->client->renderInfo.eyePoint, org );
00560 }
00561 else
00562 {
00563 VectorCopy( self->enemy->r.currentOrigin, org );
00564 }
00565 VectorCopy( self->r.currentOrigin, org2 );
00566 if ( self->spawnflags & 2 )
00567 {
00568 org2[2] += 10;
00569 }
00570 else
00571 {
00572 org2[2] -= 10;
00573 }
00574 trap_Trace( &tr, org2, NULL, NULL, org, self->s.number, MASK_SHOT );
00575
00576 if ( !tr.allsolid && !tr.startsolid && tr.entityNum == self->enemy->s.number )
00577 {
00578 turnOff = qfalse; // Can see our enemy
00579 }
00580 }
00581 }
00582 }
00583
00584 turret_head_think( self );
00585 }
00586
00587 if ( turnOff )
00588 {
00589 if ( self->bounceCount < level.time ) // bounceCount is used to keep the thing from ping-ponging from on to off
00590 {
00591 turret_sleep( self );
00592 }
00593 }
00594 else
00595 {
00596 // keep our enemy for a minimum of 2 seconds from now
00597 self->bounceCount = level.time + 2000 + random() * 150;
00598 }
00599
00600 turret_aim( self );
00601 }
|
|
||||||||||||||||
|
Definition at line 604 of file g_turret.c. References gentity_t, and gentity_s::spawnflags. Referenced by SP_misc_turret().
00606 {
00607 // Toggle on and off
00608 self->spawnflags = (self->spawnflags ^ 1);
00609
00610 /*
00611 if (( self->s.eFlags & EF_SHADER_ANIM ) && ( self->spawnflags & 1 )) // Start_Off
00612 {
00613 self->s.frame = 1; // black
00614 }
00615 else
00616 {
00617 self->s.frame = 0; // glow
00618 }
00619 */
00620 }
|
|
|
Definition at line 179 of file g_turret.c. References AngleVectors(), gentity_s::attackDebounceTime, entityShared_t::currentAngles, entityShared_t::currentOrigin, EFFECT_SPARKS, gentity_s::enemy, gentity_s::fly_sound_debounce_time, g_entities, G_PlayEffect(), gentity_t, level, entityShared_t::maxs, NULL, entityShared_t::ownerNum, gentity_s::painDebounceTime, Q_irand(), gentity_s::r, gentity_s::setTime, START_DIS, level_locals_t::time, vec3_t, VectorCopy, VectorMA, VectorSet, and gentity_s::wait. Referenced by turret_base_think().
00181 {
00182 gentity_t *top = &g_entities[self->r.ownerNum];
00183 if ( !top )
00184 {
00185 return;
00186 }
00187 if ( self->painDebounceTime > level.time )
00188 {
00189 vec3_t v_up;
00190 VectorSet( v_up, 0, 0, 1 );
00191 G_PlayEffect( EFFECT_SPARKS, self->r.currentOrigin, v_up );
00192 if ( Q_irand( 0, 3) )
00193 {//25% chance of still firing
00194 return;
00195 }
00196 }
00197 // if it's time to fire and we have an enemy, then gun 'em down! pushDebounce time controls next fire time
00198 if ( self->enemy && self->setTime < level.time && self->attackDebounceTime < level.time )
00199 {
00200 vec3_t fwd, org;
00201 // set up our next fire time
00202 self->setTime = level.time + self->wait;
00203
00204 /*
00205 mdxaBone_t boltMatrix;
00206
00207 // Getting the flash bolt here
00208 gi.G2API_GetBoltMatrix( self->ghoul2, self->playerModel,
00209 self->torsoBolt,
00210 &boltMatrix, self->r.currentAngles, self->r.currentOrigin, (cg.time?cg.time:level.time),
00211 NULL, self->s.modelScale );
00212
00213 gi.G2API_GiveMeVectorFromMatrix( boltMatrix, ORIGIN, org );
00214 gi.G2API_GiveMeVectorFromMatrix( boltMatrix, POSITIVE_Y, fwd );
00215 */
00216 VectorCopy( top->r.currentOrigin, org );
00217 org[2] += top->r.maxs[2]-8;
00218 AngleVectors( top->r.currentAngles, fwd, NULL, NULL );
00219
00220 VectorMA( org, START_DIS, fwd, org );
00221
00222 turret_fire( top, org, fwd );
00223 self->fly_sound_debounce_time = level.time;//used as lastShotTime
00224 }
00225 }
|
|
||||||||||||||||
|
Definition at line 35 of file g_turret.c. References G_ScaleNetHealth(), gentity_t, gentity_s::health, gentity_s::maxHealth, gentity_s::target_ent, and TurretPain(). Referenced by turret_base_spawn_top().
00037 {
00038 if (self->target_ent)
00039 {
00040 self->target_ent->health = self->health;
00041 if (self->target_ent->maxHealth)
00042 {
00043 G_ScaleNetHealth(self->target_ent);
00044 }
00045
00046 TurretPain(self->target_ent, attacker, damage);
00047 }
00048 }
|
|
||||||||||||||||
|
Definition at line 11 of file g_turret.c. References gentity_s::attackDebounceTime, gentity_s::client, gentity_s::enemy, G_ScaleNetHealth(), G_SetEnemy(), gentity_t, gentity_s::health, level, gentity_s::maxHealth, gentity_s::painDebounceTime, gclient_s::ps, random, gentity_s::target_ent, level_locals_t::time, playerState_s::weapon, and WP_DEMP2. Referenced by turret_base_spawn_top(), and TurretBasePain().
00013 {
00014 if (self->target_ent)
00015 {
00016 self->target_ent->health = self->health;
00017 if (self->target_ent->maxHealth)
00018 {
00019 G_ScaleNetHealth(self->target_ent);
00020 }
00021 }
00022
00023 if ( attacker->client && attacker->client->ps.weapon == WP_DEMP2 )
00024 {
00025 self->attackDebounceTime = level.time + 800 + random() * 500;
00026 self->painDebounceTime = self->attackDebounceTime;
00027 }
00028 if ( !self->enemy )
00029 {//react to being hit
00030 G_SetEnemy( self, attacker );
00031 }
00032 }
|