void turret_driver_think(edict_t *self) { vec3_t target; vec3_t dir; float reaction_time; if (!self) { return; } self->nextthink = level.time + FRAMETIME; if (self->enemy && (!self->enemy->inuse || (self->enemy->health <= 0))) { self->enemy = NULL; } if (!self->enemy) { if (!FindTarget(self)) { return; } self->monsterinfo.trail_time = level.time; self->monsterinfo.aiflags &= ~AI_LOST_SIGHT; } else { if (visible(self, self->enemy)) { if (self->monsterinfo.aiflags & AI_LOST_SIGHT) { self->monsterinfo.trail_time = level.time; self->monsterinfo.aiflags &= ~AI_LOST_SIGHT; } } else { self->monsterinfo.aiflags |= AI_LOST_SIGHT; return; } } /* let the turret know where we want it to aim */ VectorCopy(self->enemy->s.origin, target); target[2] += self->enemy->viewheight; VectorSubtract(target, self->target_ent->s.origin, dir); vectoangles(dir, self->target_ent->move_angles); /* decide if we should shoot */ if (level.time < self->monsterinfo.attack_finished) { return; } reaction_time = (3 - skill->value) * 1.0; if ((level.time - self->monsterinfo.trail_time) < reaction_time) { return; } self->monsterinfo.attack_finished = level.time + reaction_time + 1.0; self->target_ent->spawnflags |= 65536; }
static void SetSys (const char* Sys) /* Define a target system */ { switch (Target = FindTarget (Sys)) { case TGT_NONE: break; case TGT_MODULE: AbEnd ("Cannot use `module' as a target for the compiler"); break; case TGT_ATARI: DefineNumericMacro ("__ATARI__", 1); break; case TGT_ATARIXL: DefineNumericMacro ("__ATARI__", 1); DefineNumericMacro ("__ATARIXL__", 1); break; case TGT_C16: cbmsys ("__C16__"); break; case TGT_C64: cbmsys ("__C64__"); break; case TGT_VIC20: cbmsys ("__VIC20__"); break; case TGT_C128: cbmsys ("__C128__"); break; case TGT_PLUS4: cbmsys ("__C16__"); DefineNumericMacro ("__PLUS4__", 1); break; case TGT_CBM510: cbmsys ("__CBM510__"); break; case TGT_CBM610: cbmsys ("__CBM610__"); break; case TGT_PET: cbmsys ("__PET__"); break; case TGT_BBC: DefineNumericMacro ("__BBC__", 1); break; case TGT_APPLE2: DefineNumericMacro ("__APPLE2__", 1); break; case TGT_APPLE2ENH: DefineNumericMacro ("__APPLE2__", 1); DefineNumericMacro ("__APPLE2ENH__", 1); break; case TGT_GEOS_CBM: /* Do not handle as a CBM system */ DefineNumericMacro ("__GEOS__", 1); DefineNumericMacro ("__GEOS_CBM__", 1); break; case TGT_GEOS_APPLE: DefineNumericMacro ("__GEOS__", 1); DefineNumericMacro ("__GEOS_APPLE__", 1); break; case TGT_LUNIX: DefineNumericMacro ("__LUNIX__", 1); break; case TGT_ATMOS: DefineNumericMacro ("__ATMOS__", 1); break; case TGT_NES: DefineNumericMacro ("__NES__", 1); break; case TGT_SUPERVISION: DefineNumericMacro ("__SUPERVISION__", 1); break; case TGT_LYNX: DefineNumericMacro ("__LYNX__", 1); break; case TGT_SIM6502: DefineNumericMacro ("__SIM6502__", 1); break; case TGT_SIM65C02: DefineNumericMacro ("__SIM65C02__", 1); break; default: AbEnd ("Unknown target system type %d", Target); } /* Initialize the translation tables for the target system */ TgtTranslateInit (); }
void CFuncTank::TrackTarget( void ) { trace_t tr; bool updateTime = FALSE, lineOfSight; QAngle angles; Vector barrelEnd; CBaseEntity *pTarget = NULL; barrelEnd.Init(); // Get a position to aim for if (m_pController) { // Tanks attempt to mirror the player's angles angles = m_pController->EyeAngles(); SetNextThink( gpGlobals->curtime + 0.05 ); } else { if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 0.1f ); } else { return; } // ----------------------------------- // Get world target position // ----------------------------------- barrelEnd = WorldBarrelPosition(); Vector worldTargetPosition; if (m_spawnflags & SF_TANK_AIM_AT_POS) { worldTargetPosition = m_vTargetPosition; } else { CBaseEntity *pEntity = (CBaseEntity *)m_hTarget; if ( !pEntity || ( pEntity->GetFlags() & FL_NOTARGET ) ) { if ( m_targetEntityName != NULL_STRING ) // New HL2 behavior { m_hTarget = FindTarget( m_targetEntityName, NULL ); } else // HL1 style { m_hTarget = ToBasePlayer( GetContainingEntity( UTIL_FindClientInPVS( edict() ) ) ); } if ( m_hTarget != NULL ) { SetNextThink( gpGlobals->curtime ); // Think again immediately } else { if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 2 ); // Wait 2 secs } if ( m_fireLast !=0 ) { m_OnLoseTarget.FireOutput(this, this); m_fireLast = 0; } } return; } pTarget = pEntity; // Calculate angle needed to aim at target worldTargetPosition = pEntity->EyePosition(); } float range = (worldTargetPosition - barrelEnd).Length(); if ( !InRange( range ) ) return; UTIL_TraceLine( barrelEnd, worldTargetPosition, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); if (m_spawnflags & SF_TANK_AIM_AT_POS) { updateTime = TRUE; m_sightOrigin = m_vTargetPosition; } else { lineOfSight = FALSE; // No line of sight, don't track if ( tr.fraction == 1.0 || tr.m_pEnt == pTarget ) { lineOfSight = TRUE; CBaseEntity *pInstance = pTarget; if ( InRange( range ) && pInstance && pInstance->IsAlive() ) { updateTime = TRUE; // Sight position is BodyTarget with no noise (so gun doesn't bob up and down) m_sightOrigin = pInstance->BodyTarget( GetLocalOrigin(), false ); } } } // Convert targetPosition to parent angles = AimBarrelAt( m_parentMatrix.WorldToLocal( m_sightOrigin ) ); } // Force the angles to be relative to the center position float offsetY = UTIL_AngleDistance( angles.y, m_yawCenter ); float offsetX = UTIL_AngleDistance( angles.x, m_pitchCenter ); angles.y = m_yawCenter + offsetY; angles.x = m_pitchCenter + offsetX; // Limit against range in y if ( ( fabs( offsetY ) > m_yawRange + m_yawTolerance ) || ( fabs( offsetX ) > m_pitchRange + m_pitchTolerance ) ) { // Don't update if you saw the player, but out of range updateTime = false; if ( angles.y > m_yawCenter + m_yawRange ) { angles.y = m_yawCenter + m_yawRange; } else if ( angles.y < (m_yawCenter - m_yawRange) ) { angles.y = (m_yawCenter - m_yawRange); } } if ( updateTime ) { m_lastSightTime = gpGlobals->curtime; m_persist2burst = 0; } // Move toward target at rate or less float distY = UTIL_AngleDistance( angles.y, GetLocalAngles().y ); QAngle vecAngVel = GetLocalAngularVelocity(); vecAngVel.y = distY * 10; vecAngVel.y = clamp( vecAngVel.y, -m_yawRate, m_yawRate ); // Limit against range in x angles.x = clamp( angles.x, m_pitchCenter - m_pitchRange, m_pitchCenter + m_pitchRange ); // Move toward target at rate or less float distX = UTIL_AngleDistance( angles.x, GetLocalAngles().x ); vecAngVel.x = distX * 10; vecAngVel.x = clamp( vecAngVel.x, -m_pitchRate, m_pitchRate ); SetLocalAngularVelocity( vecAngVel ); SetMoveDoneTime( 0.1 ); if ( m_pController ) return; if ( CanFire() && ( (fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (m_spawnflags & SF_TANK_LINEOFSIGHT) ) ) { bool fire = FALSE; Vector forward; AngleVectors( GetLocalAngles(), &forward ); forward = m_parentMatrix.ApplyRotation( forward ); if ( m_spawnflags & SF_TANK_LINEOFSIGHT ) { float length = (m_maxRange > 0) ? m_maxRange : MAX_TRACE_LENGTH; UTIL_TraceLine( barrelEnd, barrelEnd + forward * length, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); if ( tr.m_pEnt == pTarget ) fire = TRUE; } else fire = TRUE; if ( fire ) { if (m_fireLast == 0) { m_OnAquireTarget.FireOutput(this, this); } FiringSequence( barrelEnd, forward, this ); } else { if (m_fireLast !=0) { m_OnLoseTarget.FireOutput(this, this); } m_fireLast = 0; } } else { if (m_fireLast !=0) { m_OnLoseTarget.FireOutput(this, this); } m_fireLast = 0; } }
BOOL CCameraView::FindNextTarget(void) { m_ctrlCameraTree.SetActiveWindow(); m_ctrlCameraTree.SetFocus(); if (m_sFindStr.IsEmpty()) return FALSE; BOOL bRet = FALSE; HTREEITEM hItemFind = NULL; //Child's Item need to find. HTREEITEM hItemChild = m_ctrlCameraTree.GetChildItem(m_hItemCurFind); //if (hItemChild) // hItemFind = FindTarget(hItemChild, m_sFindStr); if(hItemChild) { while(hItemChild) { hItemFind = FindTarget(hItemChild, m_sFindStr); if (hItemFind) { m_hItemCurFind = hItemFind; m_ctrlCameraTree.SelectItem(m_hItemCurFind); return TRUE; } hItemChild = m_ctrlCameraTree.GetNextSiblingItem(hItemChild); } } //Brother's Item need to find. HTREEITEM hItemBrother=m_ctrlCameraTree.GetNextSiblingItem(m_hItemCurFind); //ignor itself while(hItemBrother) { hItemFind = FindTarget(hItemBrother, m_sFindStr); if (hItemFind) { m_hItemCurFind = hItemFind; m_ctrlCameraTree.SelectItem(m_hItemCurFind); return TRUE; } hItemBrother=m_ctrlCameraTree.GetNextSiblingItem(hItemBrother); } //Father's Item Need to find HTREEITEM hItemFather = m_ctrlCameraTree.GetParentItem(m_hItemCurFind); while(hItemFather) { CString szString = m_ctrlCameraTree.GetItemText(hItemFather); //ignor itself hItemBrother = hItemFather; //polling all item of Father's brother do //all of the brother... { hItemBrother = m_ctrlCameraTree.GetNextSiblingItem(hItemBrother); if (hItemBrother) hItemFind = FindTarget(hItemBrother, m_sFindStr); else break; if (hItemFind) { m_hItemCurFind = hItemFind; m_ctrlCameraTree.SelectItem(m_hItemCurFind); return TRUE; } } while(hItemBrother); hItemFather = m_ctrlCameraTree.GetParentItem(hItemFather); //polling father's father } //----------------------- return bRet; }
RPG::SaveTarget* Game_Targets::GetTeleportTarget(int map_id) { std::vector<RPG::SaveTarget>::iterator target = FindTarget(map_id, false); return target == data.end() ? NULL : &*target; }
/* ============= ai_run The monster has an enemy it is trying to kill ============= */ void ai_run( float dist ) { vec3_t tmpv; if ( k_bloodfest ) { if ( (int)self->s.v.flags & FL_SWIM ) { dist *= 5; // let fish swim faster in bloodfest mode. } else if ( self->bloodfest_boss ) { dist *= 2; // let boss move faster } } movedist = dist; // see if the enemy is dead if ( ISDEAD( PROG_TO_EDICT( self->s.v.enemy ) ) || ( (int)PROG_TO_EDICT( self->s.v.enemy )->s.v.flags & FL_NOTARGET ) ) { self->s.v.enemy = EDICT_TO_PROG( world ); // FIXME: look all around for other targets if ( self->oldenemy && ISLIVE( self->oldenemy ) && !( (int)self->oldenemy->s.v.flags & FL_NOTARGET ) ) { self->s.v.enemy = EDICT_TO_PROG( self->oldenemy ); HuntTarget (); } else { if ( !self->movetarget || self->movetarget == world ) { if ( self->th_stand ) self->th_stand(); } else { if ( self->th_walk ) self->th_walk(); } return; } } self->show_hostile = g_globalvars.time + 1; // wake up other monsters // check knowledge of enemy enemy_vis = visible( PROG_TO_EDICT( self->s.v.enemy ) ); if ( enemy_vis ) self->search_time = g_globalvars.time + 5; // does not search for enemy next 5 seconds // look for other coop players if ( coop && self->search_time < g_globalvars.time ) { if ( FindTarget() ) { // this is fix for too frequent enemy sighting, required for bloodfest mode. if ( !visible( PROG_TO_EDICT( self->s.v.enemy ) ) ) { self->search_time = g_globalvars.time + 5; // does not search for enemy next 5 seconds } return; } } enemy_infront = infront( PROG_TO_EDICT( self->s.v.enemy ) ); enemy_range = range( PROG_TO_EDICT( self->s.v.enemy ) ); VectorSubtract( PROG_TO_EDICT( self->s.v.enemy )->s.v.origin, self->s.v.origin, tmpv); enemy_yaw = vectoyaw( tmpv ); if ( self->attack_state == AS_MISSILE ) { //dprint ("ai_run_missile\n"); ai_run_missile(); return; } if ( self->attack_state == AS_MELEE ) { //dprint ("ai_run_melee\n"); ai_run_melee(); return; } if ( CheckAnyAttack() ) return; // beginning an attack if ( self->attack_state == AS_SLIDING ) { ai_run_slide(); return; } // head straight in movetogoal( dist ); // done in C code... }
void CFuncTank::TrackTarget( void ) { TraceResult tr; edict_t *pPlayer = FIND_CLIENT_IN_PVS( edict() ); BOOL updateTime = FALSE, lineOfSight; Vector angles, direction, targetPosition, barrelEnd; edict_t *pTarget; // Get a position to aim for if (m_pController) { // Tanks attempt to mirror the player's angles angles = m_pController->pev->v_angle; angles[0] = 0 - angles[0]; pev->nextthink = pev->ltime + 0.05; } else { if ( IsActive() ) pev->nextthink = pev->ltime + 0.1; else return; if ( FNullEnt( pPlayer ) ) { if ( IsActive() ) pev->nextthink = pev->ltime + 2; // Wait 2 secs return; } pTarget = FindTarget( pPlayer ); if ( !pTarget ) return; // Calculate angle needed to aim at target barrelEnd = BarrelPosition(); targetPosition = pTarget->v.origin + pTarget->v.view_ofs; float range = (targetPosition - barrelEnd).Length(); if ( !InRange( range ) ) return; UTIL_TraceLine( barrelEnd, targetPosition, dont_ignore_monsters, edict(), &tr ); lineOfSight = FALSE; // No line of sight, don't track if ( tr.flFraction == 1.0 || tr.pHit == pTarget ) { lineOfSight = TRUE; CBaseEntity *pInstance = CBaseEntity::Instance(pTarget); if ( InRange( range ) && pInstance && pInstance->IsAlive() ) { updateTime = TRUE; m_sightOrigin = UpdateTargetPosition( pInstance ); } } // Track sight origin // !!! I'm not sure what i changed direction = m_sightOrigin - pev->origin; // direction = m_sightOrigin - barrelEnd; angles = UTIL_VecToAngles( direction ); // Calculate the additional rotation to point the end of the barrel at the target (not the gun's center) AdjustAnglesForBarrel( angles, direction.Length() ); } angles.x = -angles.x; // Force the angles to be relative to the center position angles.y = m_yawCenter + UTIL_AngleDistance( angles.y, m_yawCenter ); angles.x = m_pitchCenter + UTIL_AngleDistance( angles.x, m_pitchCenter ); // Limit against range in y if ( angles.y > m_yawCenter + m_yawRange ) { angles.y = m_yawCenter + m_yawRange; updateTime = FALSE; // Don't update if you saw the player, but out of range } else if ( angles.y < (m_yawCenter - m_yawRange) ) { angles.y = (m_yawCenter - m_yawRange); updateTime = FALSE; // Don't update if you saw the player, but out of range } if ( updateTime ) m_lastSightTime = gpGlobals->time; // Move toward target at rate or less float distY = UTIL_AngleDistance( angles.y, pev->angles.y ); pev->avelocity.y = distY * 10; if ( pev->avelocity.y > m_yawRate ) pev->avelocity.y = m_yawRate; else if ( pev->avelocity.y < -m_yawRate ) pev->avelocity.y = -m_yawRate; // Limit against range in x if ( angles.x > m_pitchCenter + m_pitchRange ) angles.x = m_pitchCenter + m_pitchRange; else if ( angles.x < m_pitchCenter - m_pitchRange ) angles.x = m_pitchCenter - m_pitchRange; // Move toward target at rate or less float distX = UTIL_AngleDistance( angles.x, pev->angles.x ); pev->avelocity.x = distX * 10; if ( pev->avelocity.x > m_pitchRate ) pev->avelocity.x = m_pitchRate; else if ( pev->avelocity.x < -m_pitchRate ) pev->avelocity.x = -m_pitchRate; if ( m_pController ) return; if ( CanFire() && ( (fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (pev->spawnflags & SF_TANK_LINEOFSIGHT) ) ) { BOOL fire = FALSE; Vector forward; UTIL_MakeVectorsPrivate( pev->angles, forward, NULL, NULL ); if ( pev->spawnflags & SF_TANK_LINEOFSIGHT ) { float length = direction.Length(); UTIL_TraceLine( barrelEnd, barrelEnd + forward * length, dont_ignore_monsters, edict(), &tr ); if ( tr.pHit == pTarget ) fire = TRUE; } else fire = TRUE; if ( fire ) { Fire( BarrelPosition(), forward, pev ); } else m_fireLast = 0; } else m_fireLast = 0; }
static void SetSys (const char* Sys) /* Define a target system */ { switch (Target = FindTarget (Sys)) { case TGT_NONE: break; case TGT_MODULE: AbEnd ("Cannot use `module' as a target for the assembler"); break; case TGT_ATARI: NewSymbol ("__ATARI__", 1); break; case TGT_ATARIXL: NewSymbol ("__ATARI__", 1); NewSymbol ("__ATARIXL__", 1); break; case TGT_C16: CBMSystem ("__C16__"); break; case TGT_C64: CBMSystem ("__C64__"); break; case TGT_VIC20: CBMSystem ("__VIC20__"); break; case TGT_C128: CBMSystem ("__C128__"); break; case TGT_PLUS4: CBMSystem ("__C16__"); NewSymbol ("__PLUS4__", 1); break; case TGT_CBM510: CBMSystem ("__CBM510__"); break; case TGT_CBM610: CBMSystem ("__CBM610__"); break; case TGT_PET: CBMSystem ("__PET__"); break; case TGT_BBC: NewSymbol ("__BBC__", 1); break; case TGT_APPLE2: NewSymbol ("__APPLE2__", 1); break; case TGT_APPLE2ENH: NewSymbol ("__APPLE2__", 1); NewSymbol ("__APPLE2ENH__", 1); break; case TGT_GEOS_CBM: /* Do not handle as a CBM system */ NewSymbol ("__GEOS__", 1); NewSymbol ("__GEOS_CBM__", 1); break; case TGT_GEOS_APPLE: NewSymbol ("__GEOS__", 1); NewSymbol ("__GEOS_APPLE__", 1); break; case TGT_LUNIX: NewSymbol ("__LUNIX__", 1); break; case TGT_ATMOS: NewSymbol ("__ATMOS__", 1); break; case TGT_NES: NewSymbol ("__NES__", 1); break; case TGT_SUPERVISION: NewSymbol ("__SUPERVISION__", 1); break; case TGT_LYNX: NewSymbol ("__LYNX__", 1); break; case TGT_SIM6502: NewSymbol ("__SIM6502__", 1); break; case TGT_SIM65C02: NewSymbol ("__SIM65C02__", 1); break; default: AbEnd ("Invalid target name: `%s'", Sys); } /* Initialize the translation tables for the target system */ TgtTranslateInit (); }
void Chaser::UnitFinished(int unit){ const UnitDef* ud = G->cb->GetUnitDef(unit); if(ud == 0){ G->L->print("UnitDef call filed, was this unit blown up as soon as it was created?"); return; } Command Cmd; if(ud->weapons.empty() == false){ if(ud->weapons.front().def->stockpile == true){ Cmd.id = CMD_STOCKPILE; for(int i = 0;i<110;i++){ G->cb->GiveOrder(unit, &Cmd); } sweap.insert(unit); } } vector<string> v; v = bds::set_cont(v, "CORKROG, CORPYRO, CORSUMO, CORHRK, TLLAAK, TLLPBOT, TLLPRIVATE, ARMZEUS, ARMFIDO, ARMMAV, ARMPW, ARMJETH, ARMHAM, TLLLASBOT, TLLARTYBOT, CORBATS, CORCRUS, CORSHARK, CORSSUB, CORMSHIP, CORSUB, CORROY, CORGOL, CORSENT, CORRAID, CORAK, CORTHUD, CORMIST, CORLEVLR, CORSEAL, CORCAN, CORMORT, CORSTORM, CORCRASH"); bool atk = false; for(vector<string>::iterator vi = v.begin(); vi != v.end();++vi){ if(*vi == ud->name){ atk = true; break; } } if(atk == true){ Command* c = new Command; c->id = CMD_MOVE_STATE; c->params.push_back(3); G->cb->GiveOrder(unit,c); Command* c2 = new Command; c2->id = CMD_TRAJECTORY; c2->params.push_back(3); G->cb->GiveOrder(unit,c); Add(unit); string mess = "new attacker added :"; mess += ud->name.c_str(); G->L->print(mess.c_str()); acknum++; if(acknum>threshold){ bool idled = false; if((groups.empty() == false)&&(groups.back().gid != groups.front().gid)){ for(vector<ackforce>::iterator ad = groups.begin();ad != groups.end();++ad){ if(ad->idle){ ad->acknum += acknum; for(set<int>::iterator acf = Attackers.begin();acf != Attackers.end();++acf){ ad->units.insert(*acf); } idled = true; Attackers.clear(); acknum = 0; FindTarget(&*ad); break; } } } if(idled == false){ ackforce ac(G); ac.acknum = this->acknum; forces++; ac.gid = forces; ac.idle = true; ac.units = Attackers; groups.push_back(ac); Attackers.clear(); acknum = 0; FindTarget(&groups.back()); } } else { Attackers.insert(unit); } } }
//----------------------------------------------------------------------------- // Rotate and scan for targets //----------------------------------------------------------------------------- void CObjectSentrygun::SentryRotate( void ) { // if we're playing a fire gesture, stop it if ( IsPlayingGesture( ACT_RANGE_ATTACK1 ) ) { RemoveGesture( ACT_RANGE_ATTACK1 ); } if ( IsPlayingGesture( ACT_RANGE_ATTACK1_LOW ) ) { RemoveGesture( ACT_RANGE_ATTACK1_LOW ); } // animate StudioFrameAdvance(); // Look for a target if ( FindTarget() ) return; // Rotate if ( !MoveTurret() ) { // Change direction if ( IsDisabled() ) { EmitSound( "Building_Sentrygun.Disabled" ); m_vecGoalAngles.x = 30; } else { switch( m_iUpgradeLevel ) { case 1: default: EmitSound( "Building_Sentrygun.Idle" ); break; case 2: EmitSound( "Building_Sentrygun.Idle2" ); break; case 3: EmitSound( "Building_Sentrygun.Idle3" ); break; } // Switch rotation direction if ( m_bTurningRight ) { m_bTurningRight = false; m_vecGoalAngles.y = m_iLeftBound; } else { m_bTurningRight = true; m_vecGoalAngles.y = m_iRightBound; } // Randomly look up and down a bit if (random->RandomFloat(0, 1) < 0.3) { m_vecGoalAngles.x = (int)random->RandomFloat(-10,10); } } } }
void Chaser::Update(){ // decrease threat values of all sectors.. for(int xa = 0; xa < xSectors; xa++){ for(int ya = 0; ya < ySectors; ya++){ if(sector[xa][ya].ebuildings != 0) sector[xa][ya].ebuildings *= 0.999f; if(sector[xa][ya].ebuildings != 0) sector[xa][ya].ground_threat *= 0.985f; //if(sector[x][y].ebuildings!= 0) sector[x][y].ebuildings *= 1+(sector[x][y].buildings.size()/10); } } // Run the code that handles stockpiled weapons. if(sweap.empty() == false){ FireSilos(); } // calculate new threads float3 pos = ZeroVector; int x, y = 0; // get all enemies in los int* en = new int[10000]; int unum = G->cb->GetEnemyUnits(en); // go through the list if(unum > 1){ for(int i = 0; i < 10000; i++){ // if 0 end of array reached if(en[i] == 0){ continue; }else{ const UnitDef* def = G->cb->GetUnitDef(en[i]); if(def == 0) continue; pos = G->cb->GetUnitPos(en[i]); // if pos is one of the below then it will cause a divide by zero error and throw an exception, so we must prevent this. if(pos == ZeroVector) continue; if(pos == UpVector) continue; // calculate in which sector unit is located x = int(pos.x/xSize); y = int(pos.z/ySize); // check if gorund unit or ship if(def != 0){ if(G->cb->UnitBeingBuilt(en[i]) == true){ // this unti is being built, which signifies the presence of a construction unit or factory, which means a base. sector[x][y].ebuildings += ((def->metalCost+def->energyCost+0.1)/2)+def->energyMake+((def->extractsMetal+0.1)*30)+def->buildSpeed; }else if(def->movedata){ if(def->builder != 0 ){ sector[x][y].ebuildings += ((def->metalCost+def->energyCost+0.1)/2)+def->energyMake+((def->extractsMetal+0.1)*30)+def->buildSpeed; }else{ sector[x][y].ground_threat += def->power; } }else if(def->canfly == false){ // its a building sector[x][y].ebuildings += ((def->metalCost+def->energyCost+0.1)/2)+def->energyMake+((def->extractsMetal+0.1)*30)+def->buildSpeed; } } en[i] = 0; } } } delete en; // NTAI attack group handling code /*vector<ackforce>::iterator af; bool a = false; vector<ackforce>::iterator bf; bool b = false; if(groups.empty() == false){ // |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // merge idle attack forces together. for(vector<ackforce>::iterator ad = groups.begin();ad != groups.end();++ad){ if(ad->idle){ if(a == false){ af = ad; a = true; continue; } else if(b == false){ bf = ad; b = true; for(set<int>::iterator acf = bf->units.begin();(acf != bf->units.end())&&(bf->units.empty() == false);++acf){ af->units.insert(*acf); af->acknum++; } bf->units.clear(); groups.erase(bf); FindTarget(&*af); a = false; b = false; break; } } } }*/ // |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // re-evaluate the target of an attack force if(G->cb->GetCurrentFrame()%240 == 0){ if(groups.empty() == false){ for(vector<ackforce>::iterator af = groups.begin();af != groups.end();++af){ if(af->units.empty() == false) FindTarget(&*af); } } } }
//----------------------------------------------------------------------------- // Purpose: Constructs a network message out of the packet //----------------------------------------------------------------------------- void CTrackerNET::ParseIncomingPacket(IBinaryBuffer *packet, CNetAddress netAddress, bool encrypted) { // construct a ReceiveMessage from it // parse out the packet header void *bufData = packet->GetBufferData(); packet_header_t *pHeader = (packet_header_t *)bufData; // check the protocol version if (pHeader->protocolNumber != PROTOCOL_VERSION) { // just throw away the packet if protocol is bad WriteToLog("!! Packet with invalid protocol - dropped\n"); packet->Release(); return; } // check the packet header size if (pHeader->headerSize != PACKET_HEADER_SIZE) { // just throw away the packet if protocol is bad packet->Release(); WriteToLog("!! Malformed packet - dropped\n"); return; } // match to a target int targetIndex = FindTarget(netAddress, pHeader->targetID, pHeader->sequenceNumber); NetworkTarget_t *target = &m_TargetList[targetIndex]; // mark the activity time // target->activityTime = m_pThreads->GetTime(); // update received if (pHeader->sequenceReply) { if (pHeader->sequenceReply > target->outgoingAcknowledged) { WriteToLog("<- Sequence acknowledged (%d in target %d)\n", target->outgoingAcknowledged, target->targetID); // this affects which packets we have to resend target->outgoingAcknowledged = pHeader->sequenceReply; } if (pHeader->sequenceReply > target->outgoingSequence) { // we've got a mismatch in the network stream; the Client is acknowledging a packet we haven't sent yet // just bump our outgoing up to match WriteToLog("<- Mismatched sequence numbers; increasing local outgoingSequence to match (%d -> %d)\n", target->outgoingSequence, pHeader->sequenceReply); target->outgoingSequence = pHeader->sequenceReply + 1; } } if (pHeader->sequenceNumber) { // check it against the incoming sequence number // if it's not the next packet in the sequence, just throw it away if (pHeader->sequenceNumber != target->incomingSequence + 1 && (target->incomingSequence > 0)) { HandleOutOfSequencePacket(packet, pHeader, target, netAddress, encrypted); return; } } // advance in the buffer over the packet header packet->Advance(pHeader->headerSize); //!! check for fragmentation/reassembly // build a receive message out of it CReceiveMessage *msg = new CReceiveMessage(packet, encrypted); msg->SetNetAddress(netAddress); msg->SetSessionID(pHeader->sessionID); // throw away bad messages if (!msg->IsValid()) { delete msg; return; } WriteToLog("<- Received '%d' (is:%d reply:%d)\n", msg->GetMsgID(), pHeader->sequenceNumber, pHeader->sequenceReply); // throw away any Ack packets if (msg->GetMsgID() == TMSG_ACK) { delete msg; return; } // add message to received list int receivedIndex = m_ReceivedMsgs.AddToTail(); m_ReceivedMsgs[receivedIndex].message = msg; if (pHeader->sequenceNumber) { // update the sequence, this may add more messages to the queue UpdateSequence(target, targetIndex, pHeader->sequenceNumber); } }
//----------------------------------------------------------------------------- // Purpose: Sends a message to a target address //----------------------------------------------------------------------------- void CTrackerNET::SendMessage(ISendMessage *pMsg, Reliability_e state) { pMsg->SetReliable(state == NET_RELIABLE); if (state == NET_RELIABLE && (pMsg->NetAddress().IP() == 0 || pMsg->NetAddress().Port() == 0)) return; assert(state != NET_RELIABLE || pMsg->NetAddress().IP() > 0); assert(state != NET_RELIABLE || pMsg->NetAddress().Port() > 0); CNetAddress address; int sequenceNumber = 0; int targetIndex = -1; NetworkTarget_t *target = NULL; if (state != NET_BROADCAST) { targetIndex = FindTarget(pMsg->NetAddress()); target = &m_TargetList[targetIndex]; // mark the activity time // target->activityTime = m_pThreads->GetTime(); // setup the message with the target info address = target->netAddress; } if (pMsg->IsReliable()) { // set and increment the sequence number if (target) { sequenceNumber = target->outgoingSequence++; } // save off the message int newIndex = m_ReliableMessages.AddToTail(); SentMessage_t &msg = m_ReliableMessages[newIndex]; msg.sequenceNumber = sequenceNumber; msg.message = pMsg; msg.resendAttempt = 0; msg.resendTime = m_pThreads->GetTime() + RESEND_TIME; msg.networkTargetHandle = targetIndex; msg.networkTargetID = target->targetID; // make sure we're in the message window before sending, other just hold until the resend attempt if (msg.sequenceNumber < target->outgoingAcknowledged + MESSAGE_WINDOW) { WriteToLog("-> Sending '%d' (os:%d) (%s)\n", pMsg->GetMsgID(), sequenceNumber, target->netAddress.ToStaticString()); } else { // don't send yet WriteToLog("-> Holding for send '%d' (os:%d) (%s)\n", pMsg->GetMsgID(), sequenceNumber, target->netAddress.ToStaticString()); return; } } else if (state == NET_BROADCAST) { WriteToLog("-> Sending '%d' (BROADCAST)\n", pMsg->GetMsgID(), sequenceNumber); } else { WriteToLog("-> Sending '%d' (UNRELIABLE)\n", pMsg->GetMsgID(), sequenceNumber); } InternalSendMessage(pMsg, target, sequenceNumber); }
void medic_cable_attack (edict_t *self) { vec3_t offset, start, end, f, r; trace_t tr; vec3_t dir; // vec3_t angles; float distance; if ((!self->enemy) || (!self->enemy->inuse) || (self->enemy->s.effects & EF_GIB)) { // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("medic_commander - aborting heal due to target's disappearance\n"); abortHeal (self, true, false, false); return; } // see if our enemy has changed to a client, or our target has more than 0 health, // abort it .. we got switched to someone else due to damage if ((self->enemy->client) || (self->enemy->health > 0)) { abortHeal (self, true, false, false); return; } AngleVectors (self->s.angles, f, r, NULL); VectorCopy (medic_cable_offsets[self->s.frame - FRAME_attack42], offset); G_ProjectSource (self->s.origin, offset, f, r, start); // check for max distance // not needed, done in checkattack // check for min distance VectorSubtract (start, self->enemy->s.origin, dir); distance = VectorLength(dir); if (distance < MEDIC_MIN_DISTANCE) { // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("medic_commander - aborting heal due to proximity to target "); abortHeal (self, true, true, false ); return; } // if ((g_showlogic)&&(g_showlogic->value)) // gi.dprintf ("distance to target is %f\n", distance); // if (distance > 300) // return; // check for min/max pitch // PMM -- took out since it doesn't look bad when it fails // vectoangles (dir, angles); // if (angles[0] < -180) // angles[0] += 360; // if (fabs(angles[0]) > 45) // { // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("medic_commander - aborting heal due to bad angle\n"); // abortHeal(self); // return; // } tr = gi.trace (start, NULL, NULL, self->enemy->s.origin, self, MASK_SOLID); if (tr.fraction != 1.0 && tr.ent != self->enemy) { if (tr.ent == world) { // give up on second try if (self->monsterinfo.medicTries > 1) { abortHeal (self, true, false, true); return; } self->monsterinfo.medicTries++; cleanupHeal (self, 1); return; } // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("medic_commander - aborting heal due to beamus interruptus\n"); abortHeal (self, true, false, false); return; } if (self->s.frame == FRAME_attack43) { // PMM - commander sounds if (self->mass == 400) gi.sound (self->enemy, CHAN_AUTO, sound_hook_hit, 1, ATTN_NORM, 0); else gi.sound (self->enemy, CHAN_AUTO, commander_sound_hook_hit, 1, ATTN_NORM, 0); self->enemy->monsterinfo.aiflags |= AI_RESURRECTING; self->enemy->takedamage = DAMAGE_NO; M_SetEffects (self->enemy); } else if (self->s.frame == FRAME_attack50) { vec3_t maxs; self->enemy->spawnflags = 0; self->enemy->monsterinfo.aiflags = 0; self->enemy->target = NULL; self->enemy->targetname = NULL; self->enemy->combattarget = NULL; self->enemy->deathtarget = NULL; self->enemy->monsterinfo.healer = self; VectorCopy (self->enemy->maxs, maxs); maxs[2] += 48; // compensate for change when they die tr = gi.trace (self->enemy->s.origin, self->enemy->mins, maxs, self->enemy->s.origin, self->enemy, MASK_MONSTERSOLID); if (tr.startsolid || tr.allsolid) { // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("Spawn point obstructed, aborting heal!\n"); abortHeal (self, true, true, false); return; } else if (tr.ent != world) { // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf("heal in entity %s\n", tr.ent->classname); abortHeal (self, true, true, false); return; } /* else if (tr.ent == world) { if ((g_showlogic) && (g_showlogic->value)) gi.dprintf ("heal in world, aborting!\n"); abortHeal (self, 1); return; } */ else { self->enemy->monsterinfo.aiflags |= AI_DO_NOT_COUNT; ED_CallSpawn (self->enemy); if (self->enemy->think) { self->enemy->nextthink = level.time; self->enemy->think (self->enemy); } // self->enemy->monsterinfo.aiflags |= AI_RESURRECTING; self->enemy->monsterinfo.aiflags &= ~AI_RESURRECTING; self->enemy->monsterinfo.aiflags |= AI_IGNORE_SHOTS|AI_DO_NOT_COUNT; // turn off flies self->enemy->s.effects &= ~EF_FLIES; self->enemy->monsterinfo.healer = NULL; if ((self->oldenemy) && (self->oldenemy->inuse) && (self->oldenemy->health > 0)) { // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("setting heal target's enemy to %s\n", self->oldenemy->classname); self->enemy->enemy = self->oldenemy; // HuntTarget (self->enemy); FoundTarget (self->enemy); } else { // if (g_showlogic && g_showlogic->value) // gi.dprintf ("no valid enemy to set!\n"); self->enemy->enemy = NULL; if (!FindTarget (self->enemy)) { // no valid enemy, so stop acting self->enemy->monsterinfo.pausetime = level.time + 100000000; self->enemy->monsterinfo.stand (self->enemy); } self->enemy = NULL; self->oldenemy = NULL; if (!FindTarget (self)) { // no valid enemy, so stop acting self->monsterinfo.pausetime = level.time + 100000000; self->monsterinfo.stand (self); return; } } } } else { if (self->s.frame == FRAME_attack44) // PMM - medic commander sounds if (self->mass == 400) gi.sound (self, CHAN_WEAPON, sound_hook_heal, 1, ATTN_NORM, 0); else gi.sound (self, CHAN_WEAPON, commander_sound_hook_heal, 1, ATTN_NORM, 0); } // adjust start for beam origin being in middle of a segment VectorMA (start, 8, f, start); // adjust end z for end spot since the monster is currently dead VectorCopy (self->enemy->s.origin, end); end[2] = self->enemy->absmin[2] + self->enemy->size[2] / 2; gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_MEDIC_CABLE_ATTACK); gi.WriteShort (self - g_edicts); gi.WritePosition (start); gi.WritePosition (end); gi.multicast (self->s.origin, MULTICAST_PVS); }
void turret_brain_think (edict_t *self) { vec3_t target; vec3_t dir; vec3_t endpos; float reaction_time; trace_t trace; self->nextthink = level.time + FRAMETIME; if (self->enemy) { if(!self->enemy->inuse) self->enemy = NULL; else if(self->enemy->takedamage && self->enemy->health <= 0) self->enemy = NULL; } if (!self->enemy) { if (!FindTarget (self)) return; self->monsterinfo.trail_time = level.time; self->monsterinfo.aiflags &= ~AI_LOST_SIGHT; } else { VectorAdd (self->enemy->absmax, self->enemy->absmin, endpos); VectorScale (endpos, 0.5, endpos); trace = gi.trace (self->target_ent->s.origin, vec3_origin, vec3_origin, endpos, self->target_ent, MASK_SHOT); if(trace.fraction == 1 || trace.ent == self->enemy) { if (self->monsterinfo.aiflags & AI_LOST_SIGHT) { self->monsterinfo.trail_time = level.time; self->monsterinfo.aiflags &= ~AI_LOST_SIGHT; } } else { self->monsterinfo.aiflags |= AI_LOST_SIGHT; return; } } // let the turret know where we want it to aim VectorCopy (endpos, target); VectorSubtract (target, self->target_ent->s.origin, dir); vectoangles (dir, self->target_ent->move_angles); // decide if we should shoot if (level.time < self->monsterinfo.attack_finished) return; if(self->delay) reaction_time = self->delay; else reaction_time = (3 - skill->value) * 1.0; if ((level.time - self->monsterinfo.trail_time) < reaction_time) return; self->monsterinfo.attack_finished = level.time + reaction_time + 1.0; //FIXME how do we really want to pass this along? self->target_ent->spawnflags |= 65536; }
void CDefendTask::Update() { ++updCount; /* * Merge tasks if possible */ if (updCount % 32 == 1) { CMilitaryManager* militaryManager = static_cast<CMilitaryManager*>(manager); if ((attackPower >= maxPower) || !militaryManager->GetTasks(check).empty()) { IFighterTask* task = militaryManager->EnqueueTask(promote); decltype(units) tmpUnits = units; for (CCircuitUnit* unit : tmpUnits) { manager->AssignTask(unit, task); } // manager->DoneTask(this); // NOTE: RemoveAssignee will abort task return; } ISquadTask* task = GetMergeTask(); if (task != nullptr) { task->Merge(this); units.clear(); manager->AbortTask(this); return; } } /* * No regroup */ bool isExecute = (updCount % 8 == 2); if (!isExecute) { for (CCircuitUnit* unit : units) { isExecute |= unit->IsForceExecute(); } if (!isExecute) { return; } } else { ISquadTask::Update(); if (leader == nullptr) { // task aborted return; } } /* * Update target */ FindTarget(); CCircuitAI* circuit = manager->GetCircuit(); int frame = circuit->GetLastFrame() + FRAMES_PER_SEC * 60; state = State::ROAM; if (target != nullptr) { state = State::ENGAGE; for (CCircuitUnit* unit : units) { unit->Attack(target->GetPos(), frame); } } else { for (CCircuitUnit* unit : units) { AIFloat3 pos = utils::get_radial_pos(position, SQUARE_SIZE * 32); TRY_UNIT(circuit, unit, unit->GetUnit()->Fight(pos, UNIT_COMMAND_OPTION_RIGHT_MOUSE_KEY, frame); unit->GetUnit()->SetWantedMaxSpeed(MAX_UNIT_SPEED); ) } } }
void CFuncTank::TrackTarget(void) { TraceResult tr; edict_t *pPlayer = FIND_CLIENT_IN_PVS(edict()); BOOL updateTime = FALSE, lineOfSight; Vector angles, direction, targetPosition, barrelEnd; edict_t *pTarget = NULL; if (m_pController) { angles = m_pController->pev->v_angle; angles[0] = 0 - angles[0]; pev->nextthink = pev->ltime + 0.05; } else { if (IsActive()) pev->nextthink = pev->ltime + 0.1; else return; if (FNullEnt(pPlayer)) { if (IsActive()) pev->nextthink = pev->ltime + 2; return; } pTarget = FindTarget(pPlayer); if (!pTarget) return; barrelEnd = BarrelPosition(); targetPosition = pTarget->v.origin + pTarget->v.view_ofs; float range = (targetPosition - barrelEnd).Length(); if (!InRange(range)) return; UTIL_TraceLine(barrelEnd, targetPosition, dont_ignore_monsters, edict(), &tr); lineOfSight = FALSE; if (tr.flFraction == 1 || tr.pHit == pTarget) { lineOfSight = TRUE; CBaseEntity *pInstance = CBaseEntity::Instance(pTarget); if (InRange(range) && pInstance && pInstance->IsAlive()) { updateTime = TRUE; m_sightOrigin = UpdateTargetPosition(pInstance); } } direction = m_sightOrigin - pev->origin; angles = UTIL_VecToAngles(direction); AdjustAnglesForBarrel(angles, direction.Length()); } angles.x = -angles.x; angles.y = m_yawCenter + UTIL_AngleDistance(angles.y, m_yawCenter); angles.x = m_pitchCenter + UTIL_AngleDistance(angles.x, m_pitchCenter); if (angles.y > m_yawCenter + m_yawRange) { angles.y = m_yawCenter + m_yawRange; updateTime = FALSE; } else if (angles.y < (m_yawCenter - m_yawRange)) { angles.y = (m_yawCenter - m_yawRange); updateTime = FALSE; } if (updateTime) m_lastSightTime = gpGlobals->time; float distY = UTIL_AngleDistance(angles.y, pev->angles.y); pev->avelocity.y = distY * 10; if (pev->avelocity.y > m_yawRate) pev->avelocity.y = m_yawRate; else if (pev->avelocity.y < -m_yawRate) pev->avelocity.y = -m_yawRate; if (angles.x > m_pitchCenter + m_pitchRange) angles.x = m_pitchCenter + m_pitchRange; else if (angles.x < m_pitchCenter - m_pitchRange) angles.x = m_pitchCenter - m_pitchRange; float distX = UTIL_AngleDistance(angles.x, pev->angles.x); pev->avelocity.x = distX * 10; if (pev->avelocity.x > m_pitchRate) pev->avelocity.x = m_pitchRate; else if (pev->avelocity.x < -m_pitchRate) pev->avelocity.x = -m_pitchRate; if (m_pController) return; if (CanFire() && ((fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (pev->spawnflags & SF_TANK_LINEOFSIGHT))) { BOOL fire = FALSE; Vector forward; UTIL_MakeVectorsPrivate(pev->angles, forward, NULL, NULL); if (pev->spawnflags & SF_TANK_LINEOFSIGHT) { float length = direction.Length(); UTIL_TraceLine(barrelEnd, barrelEnd + forward * length, dont_ignore_monsters, edict(), &tr); if (tr.pHit == pTarget) fire = TRUE; } else fire = TRUE; if (fire) Fire(BarrelPosition(), forward, pev); else m_fireLast = 0; } else m_fireLast = 0; }
void Game_Targets::RemoveTeleportTarget(int map_id) { std::vector<RPG::SaveTarget>::iterator target = FindTarget(map_id, false); if (target == data.end()) return; data.erase(target); }
void CAPCController::TrackTarget( void ) { trace_t tr; bool updateTime = FALSE, lineOfSight; QAngle angles; Vector barrelEnd; CBaseEntity *pTarget = NULL; barrelEnd.Init(); if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 0.1f ); } else { return; } // ----------------------------------- // Get world target position // ----------------------------------- barrelEnd = WorldBarrelPosition(); Vector worldTargetPosition; CBaseEntity *pEntity = (CBaseEntity *)m_hTarget; if ( !pEntity || ( pEntity->GetFlags() & FL_NOTARGET ) ) { m_hTarget = FindTarget( m_targetEntityName, NULL ); if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 2 ); // Wait 2 sec s } return; } pTarget = pEntity; // Calculate angle needed to aim at target worldTargetPosition = pEntity->EyePosition(); float range = (worldTargetPosition - barrelEnd).Length(); if ( !InRange( range ) ) { m_bFireDelayed = false; return; } UTIL_TraceLine( barrelEnd, worldTargetPosition, MASK_BLOCKLOS, this, COLLISION_GROUP_NONE, &tr ); lineOfSight = FALSE; // No line of sight, don't track if ( tr.fraction == 1.0 || tr.m_pEnt == pTarget ) { lineOfSight = TRUE; CBaseEntity *pInstance = pTarget; if ( InRange( range ) && pInstance && pInstance->IsAlive() ) { updateTime = TRUE; // Sight position is BodyTarget with no noise (so gun doesn't bob up and down) m_sightOrigin = pInstance->BodyTarget( GetLocalOrigin(), false ); } } // Convert targetPosition to parent angles = AimBarrelAt( m_parentMatrix.WorldToLocal( m_sightOrigin ) ); // Force the angles to be relative to the center position float offsetY = UTIL_AngleDistance( angles.y, m_yawCenter ); float offsetX = UTIL_AngleDistance( angles.x, m_pitchCenter ); angles.y = m_yawCenter + offsetY; angles.x = m_pitchCenter + offsetX; // Move toward target at rate or less float distY = UTIL_AngleDistance( angles.y, GetLocalAngles().y ); QAngle vecAngVel = GetLocalAngularVelocity(); vecAngVel.y = distY * 10; vecAngVel.y = clamp( vecAngVel.y, -m_yawRate, m_yawRate ); // Move toward target at rate or less float distX = UTIL_AngleDistance( angles.x, GetLocalAngles().x ); vecAngVel.x = distX * 10; vecAngVel.x = clamp( vecAngVel.x, -m_pitchRate, m_pitchRate ); SetLocalAngularVelocity( vecAngVel ); SetMoveDoneTime( 0.1 ); Vector forward; AngleVectors( GetLocalAngles(), &forward ); forward = m_parentMatrix.ApplyRotation( forward ); AngleVectors(angles, &forward); if ( lineOfSight == TRUE ) { // FIXME: This will ultimately have to deal with NPCs being in the vehicle as well // See if the target is in a vehicle. If so, check its relationship CBasePlayer *pPlayer = ToBasePlayer( pTarget ); if ( pPlayer && pPlayer->IsInAVehicle() ) { IServerVehicle *pVehicle = pPlayer->GetVehicle(); if ( pVehicle->ClassifyPassenger( pPlayer, CLASS_PLAYER ) == CLASS_PLAYER) { if ( !m_bFireDelayed ) { m_bFireDelayed = true; m_flFiringDelay = gpGlobals->curtime + 1.5; // setup delay time before we start firing return; } if ( gpGlobals->curtime > m_flFiringDelay ) { m_OnFireAtTarget.Set(forward, this, this); // tell apc to fire rockets, and what direction } } } } else { m_bFireDelayed = false; // reset flag since we can no longer see target } }
//----------------------------------------------------------------------------- // Purpose: Input handler for setting the target entity by name. //----------------------------------------------------------------------------- void CTankTrainAI::InputTargetEntity( inputdata_t &inputdata ) { m_targetEntityName = inputdata.value.StringID(); m_hTargetEntity = FindTarget( m_targetEntityName, inputdata.pActivator ); SetNextThink( gpGlobals->curtime ); }
/* ============= ai_run The monster has an enemy it is trying to kill ============= */ void ai_run (edict_t *self, float dist) { vec3_t v; edict_t *tempgoal; edict_t *save; bool newcourse; edict_t *marker; float d1, d2; trace_t tr; vec3_t v_forward, v_right; float left, center, right; vec3_t left_target, right_target; // if we're going to a combat point, just proceed if (self->monsterinfo.aiflags & AI_COMBAT_POINT) { M_MoveToGoal (self, dist); return; } if (self->monsterinfo.aiflags & AI_SOUND_TARGET) { VectorSubtract (self->s.origin, self->enemy->s.origin, v); if (VectorLength(v) < 64) { self->monsterinfo.aiflags |= (AI_STAND_GROUND | AI_TEMP_STAND_GROUND); self->monsterinfo.stand (self); return; } M_MoveToGoal (self, dist); if (!FindTarget (self)) return; } if (ai_checkattack (self, dist)) return; if (self->monsterinfo.attack_state == AS_SLIDING) { ai_run_slide (self, dist); return; } if (enemy_vis) { M_MoveToGoal (self, dist); self->monsterinfo.aiflags &= ~AI_LOST_SIGHT; VectorCopy (self->enemy->s.origin, self->monsterinfo.last_sighting); self->monsterinfo.trail_time = level.time; return; } #ifdef AI_FIXME // coop will change to another enemy if visible if (coop->integer) { // FIXME: insane guys get mad with this, which causes crashes! if (FindTarget (self)) return; } #endif if ((self->monsterinfo.search_time) && (level.time > (self->monsterinfo.search_time + 20000))) { M_MoveToGoal (self, dist); self->monsterinfo.search_time = 0; return; } save = self->goalentity; tempgoal = G_Spawn(); self->goalentity = tempgoal; newcourse = false; if (!(self->monsterinfo.aiflags & AI_LOST_SIGHT)) { // just lost sight of the player, decide where to go first self->monsterinfo.aiflags |= (AI_LOST_SIGHT | AI_PURSUIT_LAST_SEEN); self->monsterinfo.aiflags &= ~(AI_PURSUE_NEXT | AI_PURSUE_TEMP); newcourse = true; } if (self->monsterinfo.aiflags & AI_PURSUE_NEXT) { self->monsterinfo.aiflags &= ~AI_PURSUE_NEXT; // give ourself more time since we got this far self->monsterinfo.search_time = level.time + 5000; if (self->monsterinfo.aiflags & AI_PURSUE_TEMP) { self->monsterinfo.aiflags &= ~AI_PURSUE_TEMP; marker = NULL; VectorCopy (self->monsterinfo.saved_goal, self->monsterinfo.last_sighting); newcourse = true; } else if (self->monsterinfo.aiflags & AI_PURSUIT_LAST_SEEN) { self->monsterinfo.aiflags &= ~AI_PURSUIT_LAST_SEEN; marker = G_PlayerTrail_PickFirst (self); } else { marker = G_PlayerTrail_PickNext (self); } if (marker) { VectorCopy (marker->s.origin, self->monsterinfo.last_sighting); self->monsterinfo.trail_time = marker->timeStamp; self->s.angles[YAW] = self->ideal_yaw = marker->s.angles[YAW]; newcourse = true; } } VectorSubtract (self->s.origin, self->monsterinfo.last_sighting, v); d1 = VectorLength(v); if (d1 <= dist) { self->monsterinfo.aiflags |= AI_PURSUE_NEXT; dist = d1; } VectorCopy (self->monsterinfo.last_sighting, self->goalentity->s.origin); if (newcourse) { G_Trace (&tr, self->s.origin, self->r.mins, self->r.maxs, self->monsterinfo.last_sighting, self, MASK_PLAYERSOLID); if (tr.fraction < 1) { VectorSubtract (self->goalentity->s.origin, self->s.origin, v); d1 = VectorLength(v); center = tr.fraction; d2 = d1 * ((center+1)/2); self->s.angles[YAW] = self->ideal_yaw = vectoyaw(v); AngleVectors(self->s.angles, v_forward, v_right, NULL); VectorSet(v, d2, -16, 0); G_ProjectSource (self->s.origin, v, v_forward, v_right, left_target); G_Trace (&tr, self->s.origin, self->r.mins, self->r.maxs, left_target, self, MASK_PLAYERSOLID); left = tr.fraction; VectorSet(v, d2, 16, 0); G_ProjectSource (self->s.origin, v, v_forward, v_right, right_target); G_Trace (&tr, self->s.origin, self->r.mins, self->r.maxs, right_target, self, MASK_PLAYERSOLID); right = tr.fraction; center = (d1*center)/d2; if (left >= center && left > right) { if (left < 1) { VectorSet(v, d2 * left * 0.5, -16, 0); G_ProjectSource (self->s.origin, v, v_forward, v_right, left_target); } VectorCopy (self->monsterinfo.last_sighting, self->monsterinfo.saved_goal); self->monsterinfo.aiflags |= AI_PURSUE_TEMP; VectorCopy (left_target, self->goalentity->s.origin); VectorCopy (left_target, self->monsterinfo.last_sighting); VectorSubtract (self->goalentity->s.origin, self->s.origin, v); self->s.angles[YAW] = self->ideal_yaw = vectoyaw(v); } else if (right >= center && right > left) { if (right < 1) { VectorSet(v, d2 * right * 0.5, 16, 0); G_ProjectSource (self->s.origin, v, v_forward, v_right, right_target); } VectorCopy (self->monsterinfo.last_sighting, self->monsterinfo.saved_goal); self->monsterinfo.aiflags |= AI_PURSUE_TEMP; VectorCopy (right_target, self->goalentity->s.origin); VectorCopy (right_target, self->monsterinfo.last_sighting); VectorSubtract (self->goalentity->s.origin, self->s.origin, v); self->s.angles[YAW] = self->ideal_yaw = vectoyaw(v); } } } M_MoveToGoal (self, dist); G_FreeEdict(tempgoal); if (self) self->goalentity = save; }