Something went wrong. Try again.
the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
Something went wrong. Try again.
7.0 kB · 252 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252#include "stdafx.h"#include "net.minecraft.world.entity.h"#include "net.minecraft.world.level.h"#include "net.minecraft.world.level.tile.h"#include "net.minecraft.world.phys.h"#include "net.minecraft.world.damagesource.h"#include "CombatTracker.h"
CombatTracker::CombatTracker(LivingEntity *mob){ this->mob = mob;}
CombatTracker::~CombatTracker(){ for (AUTO_VAR(it,entries.begin()); it != entries.end(); ++it) { delete (*it); }}
void CombatTracker::prepareForDamage(){ resetPreparedStatus();
if (mob->onLadder()) { int type = mob->level->getTile(Mth::floor(mob->x), Mth::floor(mob->bb->y0), Mth::floor(mob->z));
if (type == Tile::ladder->id) { nextLocation = eLocation_LADDER; } else if (type == Tile::vine->id) { nextLocation = eLocation_VINES; } } else if (mob->isInWater()) { nextLocation = eLocation_WATER; }}
void CombatTracker::recordDamage(DamageSource *source, float health, float damage){ recheckStatus(); prepareForDamage();
CombatEntry *entry = new CombatEntry(source, mob->tickCount, health, damage, nextLocation, mob->fallDistance);
entries.push_back(entry); lastDamageTime = mob->tickCount; takingDamage = true; inCombat |= entry->isCombatRelated();}
shared_ptr<ChatPacket> CombatTracker::getDeathMessagePacket(){ if (entries.size() == 0) return shared_ptr<ChatPacket>(new ChatPacket(mob->getNetworkName()));
CombatEntry *knockOffEntry = getMostSignificantFall(); CombatEntry *killingBlow = entries[entries.size() - 1]; shared_ptr<ChatPacket> result;
shared_ptr<Entity> killingEntity = killingBlow->getSource()->getEntity();
if (knockOffEntry != NULL && killingBlow->getSource()->equals(DamageSource::fall)) { shared_ptr<Entity> attackerEntity = knockOffEntry->getSource()->getEntity();
if (knockOffEntry->getSource()->equals(DamageSource::fall) || knockOffEntry->getSource()->equals(DamageSource::outOfWorld)) { ChatPacket::EChatPacketMessage message;
switch(getFallLocation(knockOffEntry)) { case eLocation_GENERIC: message = ChatPacket::e_ChatDeathFellAccidentGeneric; break; case eLocation_LADDER: message = ChatPacket::e_ChatDeathFellAccidentLadder; break; case eLocation_VINES: message = ChatPacket::e_ChatDeathFellAccidentVines; break; case eLocation_WATER: message = ChatPacket::e_ChatDeathFellAccidentWater; break; }
result = shared_ptr<ChatPacket>(new ChatPacket(mob->getNetworkName(), message)); } else if (attackerEntity != NULL && (killingEntity == NULL || attackerEntity != killingEntity)) { shared_ptr<ItemInstance> attackerItem = attackerEntity->instanceof(eTYPE_LIVINGENTITY) ? dynamic_pointer_cast<LivingEntity>(attackerEntity)->getCarriedItem() : nullptr;
if (attackerItem != NULL && attackerItem->hasCustomHoverName()) { result = shared_ptr<ChatPacket>(new ChatPacket(mob->getNetworkName(), ChatPacket::e_ChatDeathFellAssistItem, attackerEntity->GetType(), attackerEntity->getNetworkName(), attackerItem->getHoverName())); } else { result = shared_ptr<ChatPacket>(new ChatPacket(mob->getNetworkName(), ChatPacket::e_ChatDeathFellAssist, attackerEntity->GetType(), attackerEntity->getNetworkName())); } } else if (killingEntity != NULL) { shared_ptr<ItemInstance> killerItem = killingEntity->instanceof(eTYPE_LIVINGENTITY) ? dynamic_pointer_cast<LivingEntity>(killingEntity)->getCarriedItem() : nullptr; if (killerItem != NULL && killerItem->hasCustomHoverName()) { result = shared_ptr<ChatPacket>(new ChatPacket(mob->getNetworkName(), ChatPacket::e_ChatDeathFellFinishItem, killingEntity->GetType(), killingEntity->getNetworkName(), killerItem->getHoverName())); } else { result = shared_ptr<ChatPacket>(new ChatPacket(mob->getNetworkName(), ChatPacket::e_ChatDeathFellFinish, killingEntity->GetType(), killingEntity->getNetworkName())); } } else { result = shared_ptr<ChatPacket>(new ChatPacket(mob->getNetworkName(), ChatPacket::e_ChatDeathFellKiller)); } } else { result = killingBlow->getSource()->getDeathMessagePacket(dynamic_pointer_cast<LivingEntity>(mob->shared_from_this())); }
return result;}
shared_ptr<LivingEntity> CombatTracker::getKiller(){ shared_ptr<LivingEntity> bestMob = nullptr; shared_ptr<Player> bestPlayer = nullptr; float bestMobDamage = 0; float bestPlayerDamage = 0;
for (AUTO_VAR(it,entries.begin()); it != entries.end(); ++it) { CombatEntry *entry = *it; if ( entry->getSource() != NULL && entry->getSource()->getEntity() != NULL && entry->getSource()->getEntity()->instanceof(eTYPE_PLAYER) && (bestPlayer == NULL || entry->getDamage() > bestPlayerDamage)) { bestPlayerDamage = entry->getDamage(); bestPlayer = dynamic_pointer_cast<Player>(entry->getSource()->getEntity()); }
if ( entry->getSource() != NULL && entry->getSource()->getEntity() != NULL && entry->getSource()->getEntity()->instanceof(eTYPE_LIVINGENTITY) && (bestMob == NULL || entry->getDamage() > bestMobDamage)) { bestMobDamage = entry->getDamage(); bestMob = dynamic_pointer_cast<LivingEntity>(entry->getSource()->getEntity()); } }
if (bestPlayer != NULL && bestPlayerDamage >= bestMobDamage / 3) { return bestPlayer; } else { return bestMob; }}
CombatEntry *CombatTracker::getMostSignificantFall(){ CombatEntry *result = NULL; CombatEntry *alternative = NULL; int altDamage = 0; float bestFall = 0;
for (int i = 0; i < entries.size(); i++) { CombatEntry *entry = entries.at(i); CombatEntry *previous = i > 0 ? entries.at(i - 1) : NULL;
bool isFall = entry->getSource()->equals(DamageSource::fall); bool isOutOfWorld = entry->getSource()->equals(DamageSource::outOfWorld);
if ((isFall || isOutOfWorld) && (entry->getFallDistance() > 0) && (result == NULL || entry->getFallDistance() > bestFall)) { if (i > 0) { result = previous; } else { result = entry; } bestFall = entry->getFallDistance(); }
if (entry->getLocation() != eLocation_GENERIC && (alternative == NULL || entry->getDamage() > altDamage)) { alternative = entry; } }
if (bestFall > 5 && result != NULL) { return result; } else if (altDamage > 5 && alternative != NULL) { return alternative; } else { return NULL; }}
CombatTracker::eLOCATION CombatTracker::getFallLocation(CombatEntry *entry){ return entry->getLocation();
}
bool CombatTracker::isTakingDamage(){ recheckStatus(); return takingDamage;}
bool CombatTracker::isInCombat(){ recheckStatus(); return inCombat;}
void CombatTracker::resetPreparedStatus(){ nextLocation = eLocation_GENERIC;}
void CombatTracker::recheckStatus(){ int reset = inCombat ? RESET_COMBAT_STATUS_TIME : RESET_DAMAGE_STATUS_TIME;
if (takingDamage && mob->tickCount - lastDamageTime > reset) { for (AUTO_VAR(it,entries.begin()); it != entries.end(); ++it) { delete (*it); } entries.clear(); takingDamage = false; inCombat = false; }}