30 #include "../../eve-common/EVE_Damage.h"
58 : srcSE(pSE), effectID(eID), weaponRef(wRef), chargeRef(
InventoryItemRef(nullptr))
69 : srcSE(pSE), effectID(eID), weaponRef(wRef), chargeRef(
InventoryItemRef(nullptr))
78 _log(DAMAGE__WARNING,
"Damage:C'tor - Called by source %s(%u) with weapon %s(%u).",
84 : srcSE(pSE), effectID(eID), weaponRef(wRef), chargeRef(cRef)
93 _log(DAMAGE__WARNING,
"Damage:C'tor - Called by source %s(%u) with weapon %s(%u) using charge %s(%u).",
101 assert(fatal_blow and
"Damage() fatal_blow called without 2nd param being true!");
113 _log(DAMAGE__MESSAGE,
"%s(%u): Initializing %.2f damage from NPC %s(%u) with K:%.3f, T:%.3f, EM:%.3f, E:%.3f",\
117 _log(DAMAGE__MESSAGE,
"%s(%u): Initializing %.2f damage from Drone %s(%u) with K:%.3f, T:%.3f, EM:%.3f, E:%.3f",\
121 _log(DAMAGE__MESSAGE,
"%s(%u): Initializing %.2f damage from %s's %s(%u) using %s(%u) %s with K:%.3f, T:%.3f, EM:%.3f, E:%.3f",\
143 d *=
sConfig.rates.missileDamage;
163 if (modifier == 3.0f) { damageID = 8; }
164 else if (modifier > 1.2501f) { damageID = 7; }
165 else if (modifier > 0.9999f) { damageID = 6; }
166 else if (modifier > 0.7501f) { damageID = 5; }
167 else if (modifier > 0.6251f) { damageID = 4; }
168 else if (modifier > 0.4121f) { damageID = 3; }
169 else if (modifier > 0.3751f) { damageID = 2; }
170 else if (modifier > 0.2501f) { damageID = 1; }
171 else { damageID = 0; }
172 _log(DAMAGE__TRACE,
"%s(%u): Modifier: %.3f, damageID: %u.",
GetName(),
GetID(), modifier, damageID);
187 float total_damage(0.0f);
188 float shield_damage(DamageToShield.
GetTotal());
190 if (shield_damage <= available_shield) {
203 total_damage += shield_damage;
204 float new_charge = available_shield - shield_damage;
207 _log(DAMAGE__DEBUG,
"%s(%u): Applying %.2f damage to shields. New charge: %.2f.",
211 d *= (1 - (available_shield /shield_damage));
212 total_damage += available_shield;
214 if (available_shield > 0.0f) {
215 _log(DAMAGE__INFO,
"%s(%u): Shield depleted with %.2f damage. %.2f damage remains.",
228 float armor_damage = DamageToArmor.
GetTotal();
229 if (armor_damage <= available_armor) {
232 float new_damage = d.
GetTotal() * 0.01;
234 _log(DAMAGE__DEBUG,
"%s(%u): Applying %.2f leakthru damage to structure. New structure damage: %.2f",
238 armor_damage -= new_damage;
241 total_damage += armor_damage;
244 _log(DAMAGE__DEBUG,
"%s(%u): Applying %.2f damage to armor. New armor damage: %.2f",
247 d *= (1 - (available_armor /armor_damage));
248 total_damage += available_armor;
250 if (available_armor > 0) {
251 _log(DAMAGE__INFO,
"%s(%u): Armor depleted with %.2f damage. %.2f damage remains.",
265 float hull_damage = DamageToHull.
GetTotal();
266 if (hull_damage < available_hull) {
267 total_damage += hull_damage;
270 _log(DAMAGE__DEBUG,
"%s(%u): Applying %.2f damage to structure. New structure damage: %.2f",
273 total_damage += available_hull;
275 _log(DAMAGE__INFO,
"%s(%u): %.2f damage has depleted our structure. Time to explode.",
367 if (
sConfig.debug.UseProfiling)
391 if (pClient ==
nullptr) {
393 sLog.Error(
"Ship::Killed()",
"killer == IsDrone and pPlayer == nullptr");
399 killerID = killer->
GetID();
410 if (wreckPosition.
isNaN()) {
411 sLog.Error(
"Ship::Killed()",
"Wreck Position is NaN");
427 if (wreckItemRef.get() ==
nullptr) {
428 sLog.Error(
"Ship::Killed()",
"Creating Wreck Item Failed for %s of type %u", wreck_name.c_str(), wreckTypeID);
433 _log(PHYSICS__TRACE,
"Ship::Killed() - Ship %s(%u) Position: %.2f,%.2f,%.2f. Wreck %s(%u) Position: %.2f,%.2f,%.2f.", \
434 GetName(),
GetID(),
x(),
y(),
z(), wreckItemRef->name(), wreckItemRef->itemID(), wreckPosition.
x, wreckPosition.
y, wreckPosition.
z);
442 wreckEntity.
itemID = wreckItemRef->itemID();
444 wreckEntity.
ownerID = killerID;
445 wreckEntity.
typeID = wreckTypeID;
446 wreckEntity.
position = wreckPosition;
449 sLog.Error(
"Ship::Killed()",
"Spawning Wreck Failed: typeID or typeName not supported: '%u'", wreckTypeID);
451 wreckItemRef->Delete();
463 if (pPilot ==
nullptr)
466 if (pClient !=
nullptr)
474 double modifier = (1 + ((pPilot->GetSecurityRating() - pClient->
GetSecurityRating()) / 90));
504 std::stringstream blob;
505 std::vector<InventoryItemRef> survivedItems;
506 if (pPilot->InPod()) {
507 blob <<
"<items><i t=" << data.
victimShipTypeID <<
" f=0 s=1 d=0 x=1/></items>";
524 std::map<uint32, InventoryItemRef> deadShipInventory;
525 deadShipInventory.clear();
527 if (deadShipInventory.empty()) {
531 for (
auto cur : deadShipInventory) {
533 x = cur.second->quantity();
534 s = (cur.second->isSingleton() ? 1 : 0);
538 s = (bpRef->copy() ? 2 : s);
541 blob <<
"<i t=" << cur.second->typeID() <<
" f=" << cur.second->flag() <<
" s=" << s ;
554 survivedItems.push_back(cur.second);
556 blob <<
" d=" << d <<
" x=" <<
x <<
"/>";
566 pPilot->GetChar()->LogKill(data);
568 if (pPilot->InPod()) {
572 if (pClient !=
nullptr)
575 std::string corpse_name = pPilot->GetName();
576 corpse_name +=
"'s Frozen Corpse";
577 uint32 corpseTypeID = 10041;
580 if (corpseItemRef.get() ==
nullptr) {
581 sLog.Error(
"Ship::Killed()",
"Creating Corpse Item Failed for %s of type %u", corpse_name.c_str(), corpseTypeID);
588 corpseEntity.
itemID = corpseItemRef->itemID();
589 corpseEntity.
itemName = corpse_name;
591 corpseEntity.
typeID = corpseTypeID;
592 corpseEntity.
position = wreckPosition;
594 sLog.Error(
"Ship::Killed()",
"Spawning Corpse Failed: typeID or typeName not supported: '%u'", corpseTypeID);
596 _log(PHYSICS__TRACE,
"Ship::Killed() - Pod %s(%u) Position: %.2f,%.2f,%.2f. Corpse %s(%u) Position: %.2f,%.2f,%.2f.", \
597 GetName(),
GetID(),
x(),
y(),
z(), corpseItemRef->name(), corpseItemRef->itemID(), wreckPosition.
x, wreckPosition.
y, wreckPosition.
z);
602 pPilot->ResetAfterPodded();
609 GPoint podPosition(wreckPosition);
612 pPilot->ResetAfterPopped(podPosition);
616 if (wreckItemRef.get() ==
nullptr) {
617 sLog.Error(
"Ship::Killed()",
"Creating Wreck Item Failed for %s of type %u", wreck_name.c_str(), wreckTypeID);
622 _log(PHYSICS__TRACE,
"Ship::Killed() - Ship %s(%u) Position: %.2f,%.2f,%.2f. Wreck %s(%u) Position: %.2f,%.2f,%.2f.", \
623 GetName(),
GetID(),
x(),
y(),
z(), wreckItemRef->name(), wreckItemRef->itemID(), wreckPosition.
x, wreckPosition.
y, wreckPosition.
z);
631 wreckEntity.
itemID = wreckItemRef->itemID();
633 wreckEntity.
ownerID = pPilot->GetCharacterID();
634 wreckEntity.
typeID = wreckTypeID;
635 wreckEntity.
position = wreckPosition;
638 sLog.Error(
"Ship::Killed()",
"Spawning Wreck Failed for typeID %u", wreckTypeID);
639 wreckItemRef->Delete();
643 DropLoot(wreckItemRef, groupID, killerID);
645 for (
auto cur: survivedItems)
646 cur->Move(wreckItemRef->itemID(),
flagNone);
#define sConfig
A macro for easier access to the singleton.
virtual DroneSE * GetDroneSE()
uint32 finalCorporationID
static const char * Taken[9]
#define _log(type, fmt,...)
#define IsWreckTypeID(typeID)
DestinyManager * m_destiny
InventoryItemRef chargeRef
float GetSecurityRating() const
virtual void Killed(Damage &fatal_blow)
void SendJettisonPacket() const
virtual ShipSE * GetShipSE()
ShipItemRef GetShipItemRef()
double MakeRandomFloat(double low, double high)
Generates random real from interval [low; high].
void QueueDestinyEvent(PyTuple **multiEvent)
GaExpInl bool isNaN() const
static void AddKill(uint32 sysID)
virtual Client * GetPilot()
Python floating point number.
int32 GetCharacterID() const
static void AddFactionKill(uint32 sysID)
const float GetSystemSecurityRating()
CharacterRef GetChar() const
bool BuildDynamicEntity(const DBSystemDynamicEntity &entity, uint32 launcherID=0)
#define is_log_enabled(type)
#define sLog
Evaluates to a NewLog instance.
bool IsEven(int64 number)
void PayBounty(CharacterRef cRef)
static const char * Banked[9]
void SetItem(size_t index, PyRep *object)
Stores Python object.
uint32 victimCorporationID
void SetAttribute(uint16 attrID, int num, bool notify=true)
const char * GetName() const
const char * GetName() const
Damage(SystemEntity *pSE, InventoryItemRef wRef, float mod, uint16 eID)
double finalSecurityStatus
static RefPtr StaticCast(const RefPtr< Y > &oth)
Acts as static_cast from one RefPtr to another.
EVEItemFlags flag() const
void GetInventoryMap(std::map< uint32, InventoryItemRef > &invMap)
RefPtr< InventoryItem > InventoryItemRef
static void AddPodKill(uint32 sysID)
GenericModule * GetModule(EVEItemFlags flag)
int64 MakeRandomInt(int64 low, int64 high)
Generates random integer from interval [low; high].
uint32 GetCorporationID()
const std::string & itemName() const
void SendDamageStateChanged()
void SendTerminalExplosion(uint32 shipID, uint32 bubbleID, bool isGlobal=false) const
void DropLoot(WreckContainerRef wreckRef, uint32 groupID, uint32 owner)
EvilNumber GetAttribute(const uint16 attrID) const
virtual void Killed(Damage &fatal_blow)
static const char * Given[9]
virtual bool IsModuleItem()
void DamageRandModule(float chance)
void SetPopped(bool set=false)
const GPoint & GetPosition() const
void secStatusChange(float amount)
void MakeRandomPointOnSphere(double radius)
Damage MultiplyDup(float kinetic_multiplier, float thermal_multiplier, float em_multiplier, float explosive_multiplier) const
Inventory * GetMyInventory()
bool ApplyDamage(Damage &d)
InventoryItemRef weaponRef
const char * itoa(int64 num)
Convers num to string.
void SetItemString(const char *key, PyRep *value)
SetItemString adds or sets a database entry.
virtual Client * GetPilot()