EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
DroneAI.cpp
Go to the documentation of this file.
1 
10 #include "eve-server.h"
11 
12 #include "Client.h"
14 #include "system/DestinyManager.h"
15 #include "npc/Drone.h"
16 #include "npc/DroneAI.h"
17 #include "system/Damage.h"
18 #include "system/SystemBubble.h"
19 
21 : m_state(DroneAI::State::Idle),
22  m_pDrone(who),
23  m_assignedShip(nullptr),
24  m_mainAttackTimer(0),// dont start timer until we have a target
25  m_processTimer(0),
26  m_beginFindTarget(0),
27  m_warpScramblerTimer(0), //not implemented yet
28  m_webifierTimer(0), //not implemented yet
29  m_sigRadius(who->GetSelf()->GetAttribute(AttrSignatureRadius).get_float()),
30  m_attackSpeed(who->GetSelf()->GetAttribute(AttrSpeed).get_float()),
31  m_cruiseSpeed(who->GetSelf()->GetAttribute(AttrEntityCruiseSpeed).get_int()),
32  m_chaseSpeed(who->GetSelf()->GetAttribute(AttrMaxVelocity).get_int()),
33  m_entityFlyRange(who->GetSelf()->GetAttribute(AttrEntityFlyRange).get_float() + who->GetSelf()->GetAttribute(AttrMaxRange).get_float()),
34  m_entityChaseRange(who->GetSelf()->GetAttribute(AttrEntityChaseMaxDistance).get_float() *2),
35  m_entityOrbitRange(who->GetSelf()->GetAttribute(AttrMaxRange).get_float()),
36  m_entityAttackRange(who->GetSelf()->GetAttribute(AttrEntityAttackRange).get_float() *2),
37  m_shieldBoosterDuration(who->GetSelf()->GetAttribute(AttrEntityShieldBoostDuration).get_int()),
38  m_armorRepairDuration(who->GetSelf()->GetAttribute(AttrEntityArmorRepairDuration).get_int())
39 {
40  m_processTimer.Start(5000); //arbitrary.
41 
42  // proximityRange (154) tells us how far we "see"
43 
44  if (m_entityAttackRange < 10000) // most of these are low...under 6k that sux for targeting
46 }
47 
49  double profileStartTime = GetTimeUSeconds();
50 
51  /* Drone::State definitions -allan 27Nov19
52  * Invalid
53  * Idle = 0, // not doing anything....idle.
54  * Combat = 1, // fighting - needs targetID
55  * Mining = 2, // unsure - needs targetID
56  * Approaching = 3, // too close to chase, but to far to engage
57  * Departing = 4, // return to ship
58  * Departing2 = 5, // leaving. different from Departing
59  * Pursuit = 6, // target out of range to attack/follow, but within npc sight range....use mwd/ab if equiped
60  * Fleeing = 7, // running away
61  * Operating = 9, // whats diff from engaged here? mining maybe?
62  * Engaged = 10, // non-combat? - needs targetID
63  * // internal only
64  * Unknown = 8, // as stated
65  * Guarding = 11,
66  * Assisting = 12,
67  * Incapacitated = 13 // out of control range, but online
68  */
69 
70  // test for drone attributes here - aggressive, focus fire, attack/follow
71  // test for control distance here also. offline drones outside this (AttrDroneControlDistance)
72  switch(m_state) {
74  // check everything in this state. return to ship?
75  } break;
76  case DroneAI::State::Idle: {
77  // orbiting controlling ship
78  } break;
80  //NOTE: getting our pTarget like this is pretty weak...
81  SystemEntity* pTarget = m_pDrone->TargetMgr()->GetFirstTarget(true);
82  if (pTarget == nullptr) {
83  if (m_pDrone->TargetMgr()->HasNoTargets()) {
84  _log(DRONE__AI_TRACE, "Drone %s(%u): Stopped engagement, GetFirstTarget() returned NULL.", m_pDrone->GetName(), m_pDrone->GetID());
85  SetIdle();
86  }
87  return;
88  } else if (pTarget->SysBubble() == nullptr) {
89  m_pDrone->TargetMgr()->ClearTarget(pTarget);
90  //m_pDrone->TargetMgr()->OnTarget(pTarget, TargMgr::Mode::Lost);
91  return;
92  }
93  CheckDistance(pTarget);
94  } break;
95 
96  case DroneAI::State::Departing: { // return to ship. when close enough, set lazy orbit
98  SetIdle();
99  } break;
100  // not sure how im gonna do these...
112  // do nothing here yet
113  } break;
114 
115  //no default on purpose
116  }
117  if (sConfig.debug.UseProfiling)
118  sProfiler.AddTime(Profile::drone, GetTimeUSeconds() - profileStartTime);
119 }
120 
122  switch (m_state) {
126  return DroneAI::State::Idle;
130  default:
131  return m_state;
132  }
133 }
134 
140 }
141 
144  return;
145  // not doing anything....idle.
146  _log(DRONE__AI_TRACE, "Drone %s(%u): SetIdle: returning to idle.",
147  m_pDrone->GetName(), m_pDrone->GetID());
149 
150  // disable ewar timers
155 
156  // orbit assigned ship
158 }
159 
162  return;
163  _log(DRONE__AI_TRACE, "Drone %s(%u): SetEngaged: %s(%u) begin engaging.",
164  m_pDrone->GetName(), m_pDrone->GetID(), pTarget->GetName(), pTarget->GetID());
165  // actively fighting
166  // not sure of the actual orbit speed of npc's, but their 'cruise speed' seems a bit slow.
167  // this sets orbit speed between cruise speed and quarter of max speed (whether mwb or ab)
168  // this will also enable this npc to have a variable speed, instead of fixed upon creation.
170  m_pDrone->DestinyMgr()->Orbit(pTarget, m_entityOrbitRange); //try to get inside orbit range
172 }
173 
175 {
176  //rewrote distance checks for correct logic this time
177  double dist = m_pDrone->GetPosition().distance(pSE->GetPosition());
178  if (dist > m_entityAttackRange) {
179  _log(DRONE__AI_TRACE, "Drone %s(%u): CheckDistance: %s(%u) is too far away (%u). Return to Idle.",
180  m_pDrone->GetName(), m_pDrone->GetID(), pSE->GetName(), pSE->GetID(), dist);
181  if (m_state != DroneAI::State::Idle) {
182  // target is no longer in npc's "sight range". unlock target and return to idle.
183  // should we do anything else here? search for another target? wander around?
184  ClearTarget(pSE);
185  }
186  return;
187  } else if (dist < m_entityFlyRange) { //within weapon max (and within falloff)
188  SetEngaged(pSE); //engage and orbit
189  } else if (dist < m_entityChaseRange) { //within follow
190  // SetFollowing(pSE);
191  } else if (dist < m_entityAttackRange) { //within sight
192  // SetChasing(pSE);
193  return;
194  }
195 
196  if (!m_mainAttackTimer.Enabled())
198 
199  Attack(pSE);
200 }
201 
204 }
205 
208  //m_pDrone->TargetMgr()->OnTarget(nullptr, TargMgr::Mode::Clear, TargMgr::Msg::ClientReq);
209 }
210 
212  bool chase = false;
214  _log(DRONE__AI_TRACE, "Drone %s(%u): Targeting of %s(%u) failed. Clear Target and Return to Idle.",
215  m_pDrone->GetName(), m_pDrone->GetID(), pTarget->GetName(), pTarget->GetID());
216  //ClearAllTargets();
217  SetIdle();
218  return;
219  }
221  CheckDistance(pTarget);
222 
223  /*
224  std::map<std::string, PyRep *> arg;
225  arg["target"] = new PyInt(args.arg);
226  throw PyException(MakeUserError("DeniedDroneTargetForceField", arg));
227  */
228  //DeniedDroneTargetForceField
229 }
230 
232  _log(DRONE__AI_TRACE, "Drone %s(%u): Targeted by %s(%u) while %s.",
233  m_pDrone->GetName(), m_pDrone->GetID(), pAgressor->GetName(), pAgressor->GetID(), GetStateName(m_state).c_str());
234  switch(m_state) {
235  case DroneAI::State::Idle: {
236  } break;
238  } break;
240  } break;
242  } break;
244  } break;
246  } break;
248  } break;
250  } break;
251  case DroneAI::State::Combat: {
252  } break;
253  case DroneAI::State::Mining: {
254  } break;
256  } break;
258  } break;
260  } break;
262  } break;
263  }
264 }
265 
267  switch(m_state) {
269  if (m_pDrone->TargetMgr()->HasNoTargets()) {
270  _log(DRONE__AI_TRACE, "Drone %s(%u): Target %s(%u) lost. No targets remain. Return to Idle.",
271  m_pDrone->GetName(), m_pDrone->GetID(), pTarget->GetName(), pTarget->GetID());
272  SetIdle();
273  } else {
274  _log(DRONE__AI_TRACE, "Drone %s(%u): Target %s(%u) lost, but more targets remain.",
275  m_pDrone->GetName(), m_pDrone->GetID(), pTarget->GetName(), pTarget->GetID());
276  }
277 
278  } break;
279 
280  default:
281  break;
282  }
283 }
284 
286 {
287  if (m_mainAttackTimer.Check()) {
288  if (pSE == nullptr)
289  return;
290  // Check to see if the target still in the bubble (Client warped out)
291  // fighters/bombers are able to follow.
292  if (!m_pDrone->SysBubble()->InBubble(pSE->GetPosition())) {
293  _log(DRONE__AI_TRACE, "Drone %s(%u): Target %s(%u) no longer in bubble. Clear target and move on",
294  m_pDrone->GetName(), m_pDrone->GetID(), pSE->GetName(), pSE->GetID());
295  ClearTarget(pSE);
296  return;
297  }
298  DestinyManager* pDestiny = pSE->DestinyMgr();
299  if (pDestiny == nullptr) {
300  _log(DRONE__AI_TRACE, "Drone %s(%u): Target %s(%u) has no destiny manager. Clear target and move on",
301  m_pDrone->GetName(), m_pDrone->GetID(), pSE->GetName(), pSE->GetID());
302  ClearTarget(pSE);
303  return;
304  }
305  // Check to see if the target is not cloaked:
306  if (pDestiny->IsCloaked()) {
307  _log(DRONE__AI_TRACE, "Drone %s(%u): Target %s(%u) is cloaked. Clear target and move on",
308  m_pDrone->GetName(), m_pDrone->GetID(), pSE->GetName(), pSE->GetID());
309  ClearTarget(pSE);
310  return;
311  }
312 
313  if (m_pDrone->TargetMgr()->CanAttack())
314  AttackTarget(pSE);
315  }
316 }
317 
319  m_pDrone->TargetMgr()->ClearTarget(pSE);
320  //m_pDrone->TargetMgr()->OnTarget(pSE, TargMgr::Mode::Lost);
321 
322  if (m_pDrone->TargetMgr()->HasNoTargets())
323  SetIdle();
324 }
325 
326 //also check for special effects and write code to implement them
327 //modifyTargetSpeedRange, modifyTargetSpeedChance
328 //entityWarpScrambleChance
329 
332  // woot!! --> group:1010 cat:8 Compact Citadel Torpedo Citadel torpedoes for fighter-bombers
333 
334  // effects are listed in EVE_Effects.h
335  // NOTE: drones are called 'entities' in client; EVE_Effects has 'entityxxx' for gfx
336  std::string guid = "effects.Laser"; // client looks for 'turret' in ship.ball.modules for 'effects.laser'
337  //effects.ProjectileFiredForEntities
338  uint32 gfxID = 0;
339  if (m_pDrone->GetSelf()->HasAttribute(AttrGfxTurretID))// graphicID for turret for drone type ships
342  m_pDrone->GetSelf()->itemID(),
343  m_pDrone->GetSelf()->typeID(), //m_pDrone->GetSelf()->GetAttribute(AttrGfxTurretID).get_int(),
344  pTarget->GetID(),
345  0,guid,1,1,1,m_attackSpeed,0,gfxID);
346 
347  Damage d(m_pDrone,
348  m_pDrone->GetSelf(),
349  m_pDrone->GetKinetic(),
350  m_pDrone->GetThermal(),
351  m_pDrone->GetEM(),
353  m_formula.GetDroneToHit(m_pDrone, pTarget),
355  );
356 
358  d *= sConfig.rates.damageRate;
359  pTarget->ApplyDamage(d);
360 }
361 
362 
363 std::string DroneAIMgr::GetStateName(int8 stateID)
364 {
365  switch (stateID) {
366  case DroneAI::State::Idle: return "Idle";
367  case DroneAI::State::Combat: return "Combat";
368  case DroneAI::State::Mining: return "Mining";
369  case DroneAI::State::Approaching: return "Approaching";
370  case DroneAI::State::Departing: return "Returning to ship";
371  case DroneAI::State::Departing2: return "Departing2";
372  case DroneAI::State::Pursuit: return "Pursuit";
373  case DroneAI::State::Engaged: return "Engaged";
374  case DroneAI::State::Fleeing: return "Fleeing";
375  case DroneAI::State::Unknown: return "Unknown";
376  case DroneAI::State::Operating: return "Operating";
377  case DroneAI::State::Assisting: return "Assisting";
378  case DroneAI::State::Guarding: return "Guarding";
379  case DroneAI::State::Incapacitated: return "Incapacitated";
380  default: return "Invalid";
381  }
382 }
void ClearAllTargets()
Definition: DroneAI.cpp:206
uint32 m_chaseSpeed
Definition: DroneAI.h:83
#define sConfig
A macro for easier access to the singleton.
unsigned __int8 uint8
Definition: eve-compat.h:46
Timer m_mainAttackTimer
Definition: DroneAI.h:95
void CheckDistance(SystemEntity *pTarget)
Definition: DroneAI.cpp:174
std::string GetStateName(int8 stateID)
Definition: DroneAI.cpp:363
double m_entityOrbitRange
Definition: DroneAI.h:79
double m_entityFlyRange
Definition: DroneAI.h:78
double m_attackSpeed
Definition: DroneAI.h:77
float GetDroneToHit(DroneSE *pDrone, SystemEntity *pTarget)
TurretFormulas m_formula
Definition: DroneAI.h:92
#define _log(type, fmt,...)
Definition: logsys.h:124
int8 m_state
Definition: DroneAI.h:71
void Disable()
Definition: timer.h:39
void AttackTarget(SystemEntity *pTarget)
Definition: DroneAI.cpp:330
void ClearAllTargets(bool notify=true)
void ClearTarget(SystemEntity *tSE)
bool HasAttribute(const uint16 attrID) const
DroneSE * m_pDrone
Definition: DroneAI.h:89
Timer m_warpScramblerTimer
Definition: DroneAI.h:97
SystemBubble * SysBubble()
Definition: SystemEntity.h:195
bool InBubble(const GPoint &pt, bool inWarp=false) const
int8 GetState()
Definition: DroneAI.cpp:121
Timer m_beginFindTarget
Definition: DroneAI.h:96
double MakeRandomFloat(double low, double high)
Generates random real from interval [low; high].
Definition: misc.cpp:114
float GetThermal()
Definition: Drone.h:91
#define sProfiler
Definition: dbcore.cpp:39
void SetMaxVelocity(float maxVelocity)
double m_entityChaseRange
Definition: DroneAI.h:80
void ClearTargets(bool notify=true)
TargetManager * TargetMgr()
Definition: SystemEntity.h:197
void SetEngaged(SystemEntity *pTarget)
Definition: DroneAI.cpp:160
signed __int8 int8
Definition: eve-compat.h:45
const GPoint & GetPosition() const
Definition: SystemEntity.h:211
float GetEM()
Definition: Drone.h:92
uint32 m_cruiseSpeed
Definition: DroneAI.h:84
void SetIdle()
Definition: DroneAI.cpp:142
void SendSpecialEffect(uint32 entityID, uint32 moduleID, uint32 moduleTypeID, uint32 targetID, uint32 chargeTypeID, std::string guid, bool isOffensive, bool start, bool isActive, int32 duration, uint32 repeat, int32 graphicInfo=0) const
SystemEntity * GetFirstTarget(bool need_locked=false)
DestinyManager * DestinyMgr()
Definition: SystemEntity.h:198
double GetTimeUSeconds()
Definition: utils_time.cpp:116
InventoryItemRef GetSelf()
Definition: SystemEntity.h:202
Timer m_processTimer
Definition: DroneAI.h:94
bool Enabled() const
Definition: timer.h:41
int64 get_int()
Definition: EvilNumber.cpp:166
uint32 get_uint32()
Definition: EvilNumber.cpp:173
Definition: Damage.h:33
ShipSE * m_assignedShip
Definition: DroneAI.h:90
void Targeted(SystemEntity *by_who)
Definition: DroneAI.cpp:231
uint32 GetID()
Definition: SystemEntity.h:207
bool Check(bool reset=true)
Definition: timer.cpp:62
float GetKinetic()
Definition: Drone.h:93
const char * GetName() const
Definition: SystemEntity.h:210
Definition: Drone.h:46
void ClearTarget(SystemEntity *pTarget)
Definition: DroneAI.cpp:318
void Attack(SystemEntity *pTarget)
Definition: DroneAI.cpp:285
unsigned __int32 uint32
Definition: eve-compat.h:50
void Follow(SystemEntity *pSE, uint32 distance)
void TargetLost(SystemEntity *by_who)
Definition: DroneAI.cpp:266
double m_entityAttackRange
Definition: DroneAI.h:81
bool HasNoTargets() const
void Orbit(SystemEntity *pSE, uint32 distance=0)
EvilNumber GetAttribute(const uint16 attrID) const
Timer m_webifierTimer
Definition: DroneAI.h:98
float GetExplosive()
Definition: Drone.h:94
float get_float()
Definition: EvilNumber.cpp:184
GaExpInl GaFloat distance(const GaVec3 &oth) const
Definition: GaTypes.h:158
void ClearTargets()
Definition: DroneAI.cpp:202
bool ApplyDamage(Damage &d)
Definition: Damage.cpp:108
void Target(SystemEntity *by_who)
Definition: DroneAI.cpp:211
void Process()
Definition: DroneAI.cpp:48
uint16 typeID() const
bool StartTargeting(SystemEntity *tSE, ShipItemRef sRef)
void Return()
Definition: DroneAI.cpp:135
uint32 itemID() const
Definition: InventoryItem.h:98
void IdleOrbit(ShipSE *pShipSE=nullptr)
Definition: Drone.cpp:171
ShipSE * GetHomeShip()
Definition: Drone.h:113
DroneAIMgr(DroneSE *who)
Definition: DroneAI.cpp:20
void Start(uint32 setTimerTime=0, bool changeResetTimer=true)
Definition: timer.cpp:81