EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
NPC.cpp
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: Zhur
24  Updates: Allan
25 */
26 
27 
28 #include "eve-server.h"
29 
30 #include "Client.h"
31 #include "EntityList.h"
32 #include "EVEServerConfig.h"
33 #include "StaticDataMgr.h"
35 #include "npc/NPC.h"
36 #include "npc/NPCAI.h"
37 #include "system/Container.h"
38 #include "system/Damage.h"
39 #include "system/DestinyManager.h"
40 #include "system/SystemBubble.h"
41 #include "system/SystemManager.h"
43 
44 
46 : DynamicSystemEntity(self, services, system),
47 m_spawnMgr(spawnMgr),
48 m_AI(new NPCAIMgr(this))
49 {
50  m_allyID = data.allianceID;
51  m_warID = data.factionID;
52  m_corpID = data.corporationID;
53  m_ownerID = data.ownerID;
54 
55  // Create default dynamic attributes in the AttributeMap:
59  m_self->SetAttribute(AttrWarpCapacitorNeed, 0.00001, false);
60  m_self->SetAttribute(AttrMass, m_self->type().mass(), false);
66 
67  /* Gets the value from the NPC and put on our own vars */
76 
77  _log(NPC__TRACE, "Created NPC object for %s (%u) - Data: O:%u, C:%u, A:%u, W:%u", \
78  m_self.get()->name(), m_self.get()->itemID(), \
80 }
81 
84 }
85 
86 bool NPC::Load()
87 {
89 
90  SetResists();
91 
93 }
94 
95 
96 void NPC::Process() {
97  if (m_killed)
98  return;
99 
100  double profileStartTime = GetTimeUSeconds();
101 
102  /* Enable base call to Process Targeting and Movement */
104 
105  m_AI->Process();
106 
107  if (sConfig.debug.UseProfiling)
108  sProfiler.AddTime(Profile::npc, GetTimeUSeconds() - profileStartTime);
109 }
110 
112  if (who == nullptr) {
113  m_orbitingID = 0;
114  } else {
115  m_orbitingID = who->GetID();
116  }
117 }
118 
120  m_AI->TargetLost(who);
121 }
122 
124  m_AI->Targeted(who);
125 }
126 
128 {
129  using namespace Destiny;
130 
131  uint8 mode = m_destiny->GetState(); //Ball::Mode::STOP;
132 
133  BallHeader head = BallHeader();
134  head.entityID = GetID();
135  head.mode = mode;
136  head.radius = GetRadius();
137  head.posX = x();
138  head.posY = y();
139  head.posZ = z();
141  into.Append( head );
142  MassSector mass = MassSector();
143  mass.mass = m_destiny->GetMass();
144  mass.cloak = (m_destiny->IsCloaked() ? 1 : 0);
145  mass.harmonic = m_harmonic;
146  mass.corporationID = m_corpID;
147  mass.allianceID = (IsAlliance(m_allyID) ? m_allyID : -1);
148  into.Append( mass );
149  DataSector data = DataSector();
151  data.velX = m_destiny->GetVelocity().x;
152  data.velY = m_destiny->GetVelocity().y;
153  data.velZ = m_destiny->GetVelocity().z;
154  data.inertia = m_destiny->GetInertia();
156  into.Append( data );
157  switch (mode) {
158  case Ball::Mode::WARP: {
159  GPoint target = m_destiny->GetTargetPoint();
160  WARP_Struct warp;
161  warp.formationID = 0xFF;
162  warp.targX = target.x;
163  warp.targY = target.y;
164  warp.targZ = target.z;
165  warp.speed = m_destiny->GetWarpSpeed(); //ship warp speed x10 (dont ask...this is what it is...more dumb ccp shit)
166  // warp timing. see Ship::EncodeDestiny() for notes/updates
167  warp.effectStamp = -1; //m_destiny->GetStateStamp(); //timestamp when warp started
168  warp.followRange = 0; //this isnt right
169  warp.followID = 0; //this isnt right
170  into.Append( warp );
171  } break;
172  case Ball::Mode::FOLLOW: {
173  FOLLOW_Struct follow;
174  follow.followID = m_destiny->GetTargetID();
176  follow.formationID = 0xFF;
177  into.Append( follow );
178  } break;
179  case Ball::Mode::ORBIT: {
180  ORBIT_Struct orbit;
181  orbit.targetID = m_destiny->GetTargetID();
183  orbit.formationID = 0xFF;
184  into.Append( orbit );
185  } break;
186  case Ball::Mode::GOTO: {
187  GPoint target = m_destiny->GetTargetPoint();
188  GOTO_Struct go;
189  go.formationID = 0xFF;
190  go.x = target.x;
191  go.y = target.y;
192  go.z = target.z;
193  into.Append( go );
194  } break;
195  default: {
197  main.formationID = 0xFF;
198  into.Append( main );
199  } break;
200  }
201 
202  std::string modeStr = "Goto";
203  switch (mode) {
204  case 1: modeStr = "Follow"; break;
205  case 2: modeStr = "Stop"; break;
206  case 3: modeStr = "Warp"; break;
207  case 4: modeStr = "Orbit"; break;
208  case 5: modeStr = "Missile"; break;
209  case 6: modeStr = "Mushroom"; break;
210  case 7: modeStr = "Boid"; break;
211  case 8: modeStr = "Troll"; break;
212  case 9: modeStr = "Miniball"; break;
213  case 10: modeStr = "Field"; break;
214  case 11: modeStr = "Rigid"; break;
215  case 12: modeStr = "Formation"; break;
216  }
217 
218  _log(SE__DESTINY, "NPC::EncodeDestiny(): %s - id:%li, mode:%s, flags:0x%X, Vel:%.1f, %.1f, %.1f", \
219  GetName(), head.entityID, modeStr.c_str(), head.flags, data.velX, data.velY, data.velZ);
220 }
221 
223 {
224  // We recharge our shield until it's full.
230  } else {
231  m_AI->DisableRepTimers(true, false);
232  }
233 
234  // TODO: Need to send SpecialFX / amount update
235  UpdateDamage();
236 }
237 
239 {
240  if (m_armorDamage > 0) {
242  if (m_armorDamage < 0.0)
243  m_armorDamage = 0.0;
245  } else {
246  m_AI->DisableRepTimers(false, true);
247  }
248 
249  // TODO: Need to send SpecialFX / amount update
250  UpdateDamage();
251 }
252 
254 {
255  if (m_hullDamage > 0) {
256  //m_hullDamage -= m_self->GetAttribute(AttrEntityhullRepairAmount).get_float(); << NSA - create later
257  if (m_hullDamage < 0.0)
258  m_hullDamage = 0.0;
260  } else {
261  m_AI->DisableRepTimers(false, false);
262  }
263 
264  // TODO: Need to send SpecialFX / amount update
265  // gfxBoosterID
266  UpdateDamage();
267 }
268 
270 {
271  m_AI->MissileLaunched(pMissile);
272 }
273 
275 {
276  m_self->SaveItem();
277 }
278 
280 {
281  //this is called from SystemManager::RemoveNPC() which calls other SE* methods as needed
282  m_self->Delete();
283 }
284 
286  /* fix for missing resist attribs -allan 18April16 */
287  // Shield Resonance
292  // Armor Resonance
297  // Hull Resonance
302 }
303 
304 void NPC::Killed(Damage &fatal_blow) {
305  if ((m_bubble == nullptr) or (m_destiny == nullptr) or (m_system == nullptr))
306  return; // make error here?
307 
308  //notify our spawn manager that we are gone.
309  if ((m_spawnMgr != nullptr) and (m_self.get() != nullptr))
311 
312  uint32 killerID = 0;
313  Client* pClient(nullptr);
314  SystemEntity *killer(fatal_blow.srcSE);
315 
316  if (killer->HasPilot()) {
317  pClient = killer->GetPilot();
318  killerID = pClient->GetCharacterID();
319  } else if (killer->IsDroneSE()) {
320  pClient = sEntityList.FindClientByCharID( killer->GetSelf()->ownerID() );
321  if (pClient == nullptr) {
322  sLog.Error("NPC::Killed()", "killer == IsDrone and pPlayer == nullptr");
323  } else {
324  killerID = pClient->GetCharacterID();
325  }
326  } else {
327  killerID = killer->GetID();
328  }
329 
330  uint32 locationID = GetLocationID();
331  // log faction kill in dynamic data -allan
332  MapDB::AddKill(locationID);
333  MapDB::AddFactionKill(locationID);
334 
335  if (pClient != nullptr) {
336  //award kill bounty.
337  AwardBounty( pClient );
339  AwardSecurityStatus(m_self, pClient->GetChar().get()); // this awards secStatusChange for npcs in empire space
340  }
341 
342  GPoint wreckPosition = m_destiny->GetPosition();
343  if (wreckPosition.isNaN()) {
344  sLog.Error("NPC::Killed()", "Wreck Position is NaN");
345  return;
346  }
347  uint32 wreckTypeID = sDataMgr.GetWreckID(m_self->typeID());
348  if (!IsWreckTypeID(wreckTypeID)) {
349  sLog.Error("NPC::Killed()", "Could not get wreckType for %s of type %u", m_self->name(), m_self->typeID());
350  // default to generic frigate wreck till i get better checks and/or complete wreck data
351  wreckTypeID = 26557;
352  }
353 
354  std::string wreck_name = m_self->itemName();
355  wreck_name += " Wreck";
356  ItemData wreckItemData(wreckTypeID, killerID, locationID, flagNone, wreck_name.c_str(), wreckPosition, itoa(m_allyID));
357  WreckContainerRef wreckItemRef = sItemFactory.SpawnWreckContainer( wreckItemData );
358  if (wreckItemRef.get() == nullptr) {
359  sLog.Error("NPC::Killed()", "Creating Wreck Item Failed for %s of type %u", wreck_name.c_str(), wreckTypeID);
360  return;
361  }
362 
363  if (is_log_enabled(PHYSICS__TRACE))
364  _log(PHYSICS__TRACE, "NPC::Killed() - NPC %s(%u) Position: %.2f,%.2f,%.2f. Wreck %s(%u) Position: %.2f,%.2f,%.2f.", \
365  GetName(), GetID(), x(), y(), z(), wreckItemRef->name(), wreckItemRef->itemID(), wreckPosition.x, wreckPosition.y, wreckPosition.z);
366 
368  wreckEntity.allianceID = (killer->GetAllianceID() == 0 ? m_allyID : killer->GetAllianceID());
370  wreckEntity.corporationID = killer->GetCorporationID();
371  wreckEntity.factionID = (killer->GetWarFactionID() == 0 ? m_warID : killer->GetWarFactionID());
372  wreckEntity.groupID = EVEDB::invGroups::Wreck;
373  wreckEntity.itemID = wreckItemRef->itemID();
374  wreckEntity.itemName = wreck_name;
375  wreckEntity.ownerID = killerID;
376  wreckEntity.typeID = wreckTypeID;
377  wreckEntity.position = wreckPosition;
378 
379  if (!m_system->BuildDynamicEntity(wreckEntity, m_self->itemID())) {
380  sLog.Error("NPC::Killed()", "Spawning Wreck Failed for typeID %u", wreckTypeID);
381  wreckItemRef->Delete();
382  return;
383  }
385 
386  if ((MakeRandomFloat() < sConfig.npc.LootDropChance) or (m_allyID == factionRogueDrones))
387  DropLoot(wreckItemRef, m_self->groupID(), killerID);
388 }
389 
390 
392 {
395  //DropLoot(wreckItemRef, m_self->groupID());
396 }
float m_armorDamage
Definition: NPC.h:99
void Append(const T &value)
Appends a single value to buffer.
Definition: Buffer.h:437
#define sConfig
A macro for easier access to the singleton.
unsigned __int8 uint8
Definition: eve-compat.h:46
virtual void Process()
virtual void EncodeDestiny(Buffer &into)
Definition: NPC.cpp:127
double GetFollowDistance()
#define _log(type, fmt,...)
Definition: logsys.h:124
virtual void Process()
Definition: NPC.cpp:96
float m_hullDamage
Definition: NPC.h:98
#define IsWreckTypeID(typeID)
Definition: EVE_Defines.h:203
DestinyManager * m_destiny
Definition: SystemEntity.h:265
double GetRadius()
Definition: SystemEntity.h:208
virtual ~NPC()
Definition: NPC.cpp:82
void UseShieldRecharge()
Definition: NPC.cpp:222
uint32 m_ownerID
Definition: SystemEntity.h:283
bool HasAttribute(const uint16 attrID) const
virtual bool Load()
Definition: NPC.cpp:86
uint32 ownerID() const
Definition: InventoryItem.h:99
virtual void TargetLost(SystemEntity *who)
Definition: NPC.cpp:119
void SendJettisonPacket() const
virtual bool Load()
Definition: SystemEntity.h:492
void Process()
Definition: NPCAI.cpp:271
void Orbit(SystemEntity *who)
Definition: NPC.cpp:111
double MakeRandomFloat(double low, double high)
Generates random real from interval [low; high].
Definition: misc.cpp:114
double y()
Definition: SystemEntity.h:214
virtual bool HasPilot()
Definition: SystemEntity.h:258
GaExpInl bool isNaN() const
Definition: GaTypes.h:194
#define sProfiler
Definition: dbcore.cpp:39
SpawnMgr * m_spawnMgr
Definition: NPC.h:89
static void AddKill(uint32 sysID)
Definition: MapDB.cpp:250
virtual Client * GetPilot()
Definition: SystemEntity.h:259
const GVector & GetVelocity() const
SystemBubble * m_bubble
Definition: SystemEntity.h:262
int32 GetCharacterID() const
Definition: Client.h:113
static void AddFactionKill(uint32 sysID)
Definition: MapDB.cpp:256
SystemEntity * srcSE
Definition: Damage.h:84
#define sEntityList
Definition: EntityList.h:208
const float GetSystemSecurityRating()
Definition: SystemManager.h:86
void SpawnKilled(SystemBubble *pBubble, uint32 itemID)
Definition: SpawnMgr.cpp:229
const char * name()
CharacterRef GetChar() const
Definition: Client.h:164
GaFloat x
Definition: GaTypes.h:207
bool BuildDynamicEntity(const DBSystemDynamicEntity &entity, uint32 launcherID=0)
int32 m_harmonic
Definition: SystemEntity.h:276
virtual void MissileLaunched(Missile *pMissile)
Definition: NPC.cpp:269
float capacity() const
Definition: ItemType.h:71
uint32 GetTargetID()
float m_shieldCapacity
Definition: NPC.h:101
EvilNumber EvilZero
Definition: EvilNumber.cpp:32
void SafeDelete(T *&p)
Deletes and nullifies a pointer.
Definition: SafeMem.h:83
NPCAIMgr * m_AI
Definition: NPC.h:88
uint16 groupID() const
const ItemType & type() const
float GetSpeedFraction()
#define is_log_enabled(type)
Definition: logsys.h:78
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
Definition: gpoint.h:33
InventoryItemRef m_self
Definition: SystemEntity.h:269
double GetTimeUSeconds()
Definition: utils_time.cpp:116
Generic class for buffers.
Definition: Buffer.h:40
InventoryItemRef GetSelf()
Definition: SystemEntity.h:202
int32 GetWarpSpeed()
uint32 m_corpID
Definition: SystemEntity.h:281
uint32 GetLocationID()
Definition: SystemEntity.h:209
void RemoveNPC()
Definition: NPC.cpp:279
NPC(InventoryItemRef self, PyServiceMgr &services, SystemManager *system, const FactionData &data, SpawnMgr *spawnMgr=nullptr)
Definition: NPC.cpp:45
void SaveNPC()
Definition: NPC.cpp:274
Definition: Damage.h:33
float mass() const
Definition: ItemType.h:69
float m_emDamage
Definition: NPC.h:94
double GetMaxVelocity()
float m_shieldCharge
Definition: NPC.h:100
SystemManager * m_system
Definition: SystemEntity.h:263
double GetInertia()
double z()
Definition: SystemEntity.h:215
int32 GetAllianceID()
Definition: SystemEntity.h:216
void SetAttribute(uint16 attrID, int num, bool notify=true)
uint32 GetID()
Definition: SystemEntity.h:207
float m_expDamage
Definition: NPC.h:95
void UseHullRepairer()
Definition: NPC.cpp:253
X * get() const
Definition: RefPtr.h:213
void CmdDropLoot()
Definition: NPC.cpp:391
const char * GetName() const
Definition: SystemEntity.h:210
double x()
Definition: SystemEntity.h:213
Definition: Client.h:66
unsigned __int32 uint32
Definition: eve-compat.h:50
void MissileLaunched(Missile *pMissile)
Definition: NPCAI.cpp:820
uint32 corporationID
void TargetLost(SystemEntity *pSE)
Definition: NPCAI.cpp:665
void AwardBounty(Client *pClient)
GaFloat y
Definition: GaTypes.h:207
void DisableRepTimers(bool shield=true, bool armor=true)
Definition: NPCAI.cpp:852
void SetResists()
Definition: NPC.cpp:285
GPoint GetTargetPoint()
uint32 GetCorporationID()
Definition: SystemEntity.h:218
virtual void TargetedAdd(SystemEntity *who)
Definition: NPC.cpp:123
const std::string & itemName() const
int main(int argc, char *argv[])
void UseArmorRepairer()
Definition: NPC.cpp:238
void DropLoot(WreckContainerRef wreckRef, uint32 groupID, uint32 owner)
EvilNumber GetAttribute(const uint16 attrID) const
Definition: NPCAI.h:54
virtual void UpdateDamage()
void AwardSecurityStatus(InventoryItemRef iRef, Character *pChar)
const GPoint & GetPosition() const
float radius() const
Definition: ItemType.h:68
float volume() const
Definition: ItemType.h:70
virtual void Delete()
#define sItemFactory
Definition: ItemFactory.h:165
EvilNumber EvilOne
Definition: EvilNumber.cpp:34
#define IsAlliance(itemID)
Definition: EVE_Defines.h:244
float get_float()
Definition: EvilNumber.cpp:184
virtual void Killed(Damage &fatal_blow)
Definition: NPC.cpp:304
void Targeted(SystemEntity *pSE)
Definition: NPCAI.cpp:615
float m_therDamage
Definition: NPC.h:97
virtual bool IsDroneSE()
Definition: SystemEntity.h:187
uint16 typeID() const
GaFloat z
Definition: GaTypes.h:207
const char * itoa(int64 num)
Convers num to string.
float m_kinDamage
Definition: NPC.h:96
uint32 itemID() const
Definition: InventoryItem.h:98
uint32 m_orbitingID
Definition: NPC.h:92
int32 GetWarFactionID()
Definition: SystemEntity.h:217
#define sDataMgr