mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-17 03:20:06 +00:00
More skill handlers
Note: need to revisit these when active powers are implemented to make sure they are correct. DamageNDebuff isn't even implemented yet.
This commit is contained in:
parent
9bc7e8de62
commit
e768ebcabe
@ -12,31 +12,127 @@ using namespace Abilities;
|
|||||||
std::map<int32_t, SkillData> Abilities::SkillTable;
|
std::map<int32_t, SkillData> Abilities::SkillTable;
|
||||||
|
|
||||||
#pragma region Skill handlers
|
#pragma region Skill handlers
|
||||||
static SkillResult handleSkillBuff(SkillData* skill, ICombatant* target) {
|
static SkillResult handleSkillDamage(SkillData* skill, int power, ICombatant* source, ICombatant* target) {
|
||||||
// the buff skill is special in that its application is not aligned
|
EntityRef sourceRef = source->getRef();
|
||||||
// with the SKILL_USE_SUCC packet, since buffs are calculated every tick.
|
double scalingFactor = 1;
|
||||||
// thus, no game state changes should happen here.
|
if(sourceRef.kind == EntityKind::PLAYER)
|
||||||
sSkillResult_Buff result{};
|
scalingFactor = std::max(source->getMaxHP(), target->getMaxHP()) / 1000.0;
|
||||||
result.iConditionBitFlag = target->getCompositeCondition();
|
else
|
||||||
result.iID = target->getID();
|
scalingFactor = source->getMaxHP() / 1500.0;
|
||||||
result.bProtected = 0;
|
|
||||||
|
int damage = (int)(skill->values[0][power] * scalingFactor);
|
||||||
|
int dealt = target->takeDamage(sourceRef, damage);
|
||||||
|
|
||||||
|
sSkillResult_Damage result{};
|
||||||
result.eCT = target->getCharType();
|
result.eCT = target->getCharType();
|
||||||
|
result.iID = target->getID();
|
||||||
|
result.bProtected = dealt <= 0;
|
||||||
|
result.iDamage = dealt;
|
||||||
|
result.iHP = target->getCurrentHP();
|
||||||
|
return SkillResult(sizeof(sSkillResult_Damage), &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SkillResult handleSkillHealHP(SkillData* skill, int power, ICombatant* source, ICombatant* target) {
|
||||||
|
EntityRef sourceRef = source->getRef();
|
||||||
|
int heal = skill->values[0][power];
|
||||||
|
int healed = target->heal(sourceRef, heal);
|
||||||
|
|
||||||
|
sSkillResult_Heal_HP result{};
|
||||||
|
result.eCT = target->getCharType();
|
||||||
|
result.iID = target->getID();
|
||||||
|
result.iHealHP = heal;
|
||||||
|
result.iHP = target->getCurrentHP();
|
||||||
|
return SkillResult(sizeof(sSkillResult_Heal_HP), &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SkillResult handleSkillDamageNDebuff(SkillData* skill, int power, ICombatant* source, ICombatant* target) {
|
||||||
|
// TODO abilities
|
||||||
|
sSkillResult_Damage_N_Debuff result{};
|
||||||
|
result.eCT = target->getCharType();
|
||||||
|
result.iID = target->getID();
|
||||||
|
result.bProtected = false;
|
||||||
|
result.iConditionBitFlag = target->getCompositeCondition();
|
||||||
|
return SkillResult(sizeof(sSkillResult_Damage_N_Debuff), &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SkillResult handleSkillBuff(SkillData* skill, int power, ICombatant* source, ICombatant* target) {
|
||||||
|
sSkillResult_Buff result{};
|
||||||
|
result.eCT = target->getCharType();
|
||||||
|
result.iID = target->getID();
|
||||||
|
result.bProtected = false;
|
||||||
|
result.iConditionBitFlag = target->getCompositeCondition();
|
||||||
return SkillResult(sizeof(sSkillResult_Buff), &result);
|
return SkillResult(sizeof(sSkillResult_Buff), &result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SkillResult handleSkillBatteryDrain(SkillData* skill, int power, ICombatant* source, ICombatant* target) {
|
||||||
|
if(target->getCharType() != 1)
|
||||||
|
return SkillResult(); // only Players are valid targets for battery drain
|
||||||
|
Player* plr = dynamic_cast<Player*>(target);
|
||||||
|
|
||||||
|
const double scalingFactor = (18 + source->getLevel()) / 36.0;
|
||||||
|
|
||||||
|
int boostDrain = (int)(skill->values[0][power] * scalingFactor);
|
||||||
|
if(boostDrain > plr->batteryW) boostDrain = plr->batteryW;
|
||||||
|
plr->batteryW -= boostDrain;
|
||||||
|
|
||||||
|
int potionDrain = (int)(skill->values[1][power] * scalingFactor);
|
||||||
|
if(potionDrain > plr->batteryN) potionDrain = plr->batteryN;
|
||||||
|
plr->batteryN -= potionDrain;
|
||||||
|
|
||||||
|
sSkillResult_BatteryDrain result{};
|
||||||
|
result.eCT = target->getCharType();
|
||||||
|
result.iID = target->getID();
|
||||||
|
result.bProtected = target->hasBuff(ECSB_PROTECT_BATTERY);
|
||||||
|
result.iDrainW = boostDrain;
|
||||||
|
result.iBatteryW = plr->batteryW;
|
||||||
|
result.iDrainN = potionDrain;
|
||||||
|
result.iBatteryN = plr->batteryN;
|
||||||
|
result.iStamina = plr->getActiveNano()->iStamina;
|
||||||
|
result.bNanoDeactive = plr->getActiveNano()->iStamina <= 0;
|
||||||
|
result.iConditionBitFlag = target->getCompositeCondition();
|
||||||
|
return SkillResult(sizeof(sSkillResult_BatteryDrain), &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SkillResult handleSkillMove(SkillData* skill, int power, ICombatant* source, ICombatant* target) {
|
||||||
|
if(source->getCharType() != 1)
|
||||||
|
return SkillResult(); // only Players are valid sources for recall
|
||||||
|
Player* plr = dynamic_cast<Player*>(source);
|
||||||
|
|
||||||
|
sSkillResult_Move result{};
|
||||||
|
result.eCT = target->getCharType();
|
||||||
|
result.iID = target->getID();
|
||||||
|
result.iMapNum = plr->recallInstance;
|
||||||
|
result.iMoveX = plr->recallX;
|
||||||
|
result.iMoveY = plr->recallY;
|
||||||
|
result.iMoveZ = plr->recallZ;
|
||||||
|
return SkillResult(sizeof(sSkillResult_Move), &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SkillResult handleSkillResurrect(SkillData* skill, int power, ICombatant* source, ICombatant* target) {
|
||||||
|
sSkillResult_Resurrect result{};
|
||||||
|
result.eCT = target->getCharType();
|
||||||
|
result.iID = target->getID();
|
||||||
|
result.iRegenHP = target->getCurrentHP();
|
||||||
|
return SkillResult(sizeof(sSkillResult_Resurrect), &result);
|
||||||
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
void Abilities::broadcastNanoSkill(CNSocket* sock, sNano& nano, std::vector<ICombatant*> affected) {
|
static std::vector<SkillResult> handleSkill(SkillData* skill, int power, ICombatant* src, std::vector<ICombatant*> targets) {
|
||||||
if(SkillTable.count(nano.iSkillID) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SkillData* skill = &SkillTable[nano.iSkillID];
|
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
|
||||||
int count = affected.size();
|
|
||||||
|
|
||||||
size_t resultSize = 0;
|
size_t resultSize = 0;
|
||||||
SkillResult (*skillHandler)(SkillData*, ICombatant*) = nullptr;
|
SkillResult (*skillHandler)(SkillData*, int, ICombatant*, ICombatant*) = nullptr;
|
||||||
|
std::vector<SkillResult> results;
|
||||||
|
|
||||||
switch(skill->skillType)
|
switch(skill->skillType)
|
||||||
{
|
{
|
||||||
|
case EST_DAMAGE:
|
||||||
|
resultSize = sizeof(sSkillResult_Damage);
|
||||||
|
skillHandler = handleSkillDamage;
|
||||||
|
break;
|
||||||
|
case EST_HEAL_HP:
|
||||||
|
case EST_RETURNHOMEHEAL:
|
||||||
|
resultSize = sizeof(sSkillResult_Heal_HP);
|
||||||
|
skillHandler = handleSkillHealHP;
|
||||||
|
break;
|
||||||
case EST_JUMP:
|
case EST_JUMP:
|
||||||
case EST_RUN:
|
case EST_RUN:
|
||||||
case EST_FREEDOM:
|
case EST_FREEDOM:
|
||||||
@ -54,28 +150,54 @@ void Abilities::broadcastNanoSkill(CNSocket* sock, sNano& nano, std::vector<ICom
|
|||||||
resultSize = sizeof(sSkillResult_Buff);
|
resultSize = sizeof(sSkillResult_Buff);
|
||||||
skillHandler = handleSkillBuff;
|
skillHandler = handleSkillBuff;
|
||||||
break;
|
break;
|
||||||
|
case EST_BATTERYDRAIN:
|
||||||
|
resultSize = sizeof(sSkillResult_BatteryDrain);
|
||||||
|
skillHandler = handleSkillBatteryDrain;
|
||||||
|
break;
|
||||||
|
case EST_RECALL:
|
||||||
|
case EST_RECALL_GROUP:
|
||||||
|
resultSize = sizeof(sSkillResult_Move);
|
||||||
|
skillHandler = handleSkillMove;
|
||||||
|
break;
|
||||||
|
case EST_PHOENIX_GROUP:
|
||||||
|
resultSize = sizeof(sSkillResult_Resurrect);
|
||||||
|
skillHandler = handleSkillResurrect;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
std::cout << "[WARN] Unhandled skill type " << skill->skillType << std::endl;
|
std::cout << "[WARN] Unhandled skill type " << skill->skillType << std::endl;
|
||||||
return;
|
return results;
|
||||||
}
|
}
|
||||||
|
assert(skillHandler != nullptr);
|
||||||
|
|
||||||
std::vector<SkillResult> results;
|
for(ICombatant* target : targets) {
|
||||||
for(ICombatant* target : affected) {
|
SkillResult result = skillHandler(skill, power, src, target);
|
||||||
SkillResult result = handleSkillBuff(skill, target);
|
if(result.size == 0) continue; // skill not applicable
|
||||||
if(result.size != resultSize) {
|
if(result.size != resultSize) {
|
||||||
std::cout << "[WARN] bad skill result size for " << skill->skillType << " from " << handleSkillBuff << std::endl;
|
std::cout << "[WARN] bad skill result size for " << skill->skillType << " from " << (void*)handleSkillBuff << std::endl;
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
results.push_back(result);
|
results.push_back(result);
|
||||||
}
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
if (!validOutVarPacket(sizeof(sP_FE2CL_NANO_SKILL_USE_SUCC), count, resultSize)) {
|
void Abilities::broadcastNanoSkill(CNSocket* sock, sNano& nano, std::vector<ICombatant*> affected) {
|
||||||
|
if(SkillTable.count(nano.iSkillID) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SkillData* skill = &SkillTable[nano.iSkillID];
|
||||||
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
|
std::vector<SkillResult> results = handleSkill(skill, Nanos::getNanoBoost(plr), plr, affected);
|
||||||
|
size_t resultSize = results.back().size; // guaranteed to be the same for every item
|
||||||
|
|
||||||
|
if (!validOutVarPacket(sizeof(sP_FE2CL_NANO_SKILL_USE_SUCC), results.size(), resultSize)) {
|
||||||
std::cout << "[WARN] bad sP_FE2CL_NANO_SKILL_USE_SUCC packet size\n";
|
std::cout << "[WARN] bad sP_FE2CL_NANO_SKILL_USE_SUCC packet size\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize response struct
|
// initialize response struct
|
||||||
size_t resplen = sizeof(sP_FE2CL_NANO_SKILL_USE_SUCC) + count * resultSize;
|
size_t resplen = sizeof(sP_FE2CL_NANO_SKILL_USE_SUCC) + results.size() * resultSize;
|
||||||
uint8_t respbuf[CN_PACKET_BUFFER_SIZE];
|
uint8_t respbuf[CN_PACKET_BUFFER_SIZE];
|
||||||
memset(respbuf, 0, resplen);
|
memset(respbuf, 0, resplen);
|
||||||
|
|
||||||
@ -86,9 +208,9 @@ void Abilities::broadcastNanoSkill(CNSocket* sock, sNano& nano, std::vector<ICom
|
|||||||
pkt->iNanoStamina = nano.iStamina;
|
pkt->iNanoStamina = nano.iStamina;
|
||||||
pkt->bNanoDeactive = nano.iStamina <= 0;
|
pkt->bNanoDeactive = nano.iStamina <= 0;
|
||||||
pkt->eST = skill->skillType;
|
pkt->eST = skill->skillType;
|
||||||
pkt->iTargetCnt = count;
|
pkt->iTargetCnt = (int32_t)results.size();
|
||||||
|
|
||||||
char* appended = (char*)(pkt + 1);
|
uint8_t* appended = (uint8_t*)(pkt + 1);
|
||||||
for(SkillResult& result : results) {
|
for(SkillResult& result : results) {
|
||||||
memcpy(appended, result.payload, resultSize);
|
memcpy(appended, result.payload, resultSize);
|
||||||
appended += resultSize;
|
appended += resultSize;
|
||||||
|
@ -32,11 +32,14 @@ enum class SkillDrainType {
|
|||||||
|
|
||||||
struct SkillResult {
|
struct SkillResult {
|
||||||
size_t size;
|
size_t size;
|
||||||
char payload[MAX_SKILLRESULT_SIZE];
|
uint8_t payload[MAX_SKILLRESULT_SIZE];
|
||||||
SkillResult(size_t len, void* dat) {
|
SkillResult(size_t len, void* dat) {
|
||||||
size = len;
|
size = len;
|
||||||
memcpy(payload, dat, len);
|
memcpy(payload, dat, len);
|
||||||
}
|
}
|
||||||
|
SkillResult() {
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SkillData {
|
struct SkillData {
|
||||||
|
@ -63,12 +63,19 @@ int Player::getCompositeCondition() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Player::takeDamage(EntityRef src, int amt) {
|
int Player::takeDamage(EntityRef src, int amt) {
|
||||||
HP -= amt;
|
int dmg = amt;
|
||||||
return amt;
|
if(HP - dmg < 0) dmg = HP;
|
||||||
|
HP -= dmg;
|
||||||
|
|
||||||
|
return dmg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::heal(EntityRef src, int amt) {
|
int Player::heal(EntityRef src, int amt) {
|
||||||
// stubbed
|
int heal = amt;
|
||||||
|
if(HP + heal > getMaxHP()) heal = getMaxHP() - HP;
|
||||||
|
HP += heal;
|
||||||
|
|
||||||
|
return heal;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::isAlive() {
|
bool Player::isAlive() {
|
||||||
@ -79,6 +86,14 @@ int Player::getCurrentHP() {
|
|||||||
return HP;
|
return HP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Player::getMaxHP() {
|
||||||
|
return PC_MAXHEALTH(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Player::getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<EntityRef> Player::getGroupMembers() {
|
std::vector<EntityRef> Player::getGroupMembers() {
|
||||||
std::vector<EntityRef> members;
|
std::vector<EntityRef> members;
|
||||||
if(group != nullptr)
|
if(group != nullptr)
|
||||||
@ -96,6 +111,10 @@ int32_t Player::getID() {
|
|||||||
return iID;
|
return iID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityRef Player::getRef() {
|
||||||
|
return EntityRef(PlayerManager::getSockFromID(iID));
|
||||||
|
}
|
||||||
|
|
||||||
void Player::step(time_t currTime) {
|
void Player::step(time_t currTime) {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
@ -121,16 +140,21 @@ int CombatNPC::getCompositeCondition() { /* stubbed */
|
|||||||
}
|
}
|
||||||
|
|
||||||
int CombatNPC::takeDamage(EntityRef src, int amt) {
|
int CombatNPC::takeDamage(EntityRef src, int amt) {
|
||||||
|
int dmg = amt;
|
||||||
|
if(hp - dmg < 0) dmg = hp;
|
||||||
|
hp -= dmg;
|
||||||
|
|
||||||
hp -= amt;
|
if(hp <= 0) transition(AIState::DEAD, src);
|
||||||
if (hp <= 0)
|
|
||||||
transition(AIState::DEAD, src);
|
|
||||||
|
|
||||||
return amt;
|
return dmg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombatNPC::heal(EntityRef src, int amt) {
|
int CombatNPC::heal(EntityRef src, int amt) {
|
||||||
// stubbed
|
int heal = amt;
|
||||||
|
if(hp + heal > getMaxHP()) heal = getMaxHP() - hp;
|
||||||
|
hp += heal;
|
||||||
|
|
||||||
|
return heal;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CombatNPC::isAlive() {
|
bool CombatNPC::isAlive() {
|
||||||
@ -141,6 +165,14 @@ int CombatNPC::getCurrentHP() {
|
|||||||
return hp;
|
return hp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CombatNPC::getMaxHP() {
|
||||||
|
return maxHealth;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CombatNPC::getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<EntityRef> CombatNPC::getGroupMembers() {
|
std::vector<EntityRef> CombatNPC::getGroupMembers() {
|
||||||
std::vector<EntityRef> members;
|
std::vector<EntityRef> members;
|
||||||
if(group != nullptr)
|
if(group != nullptr)
|
||||||
@ -160,6 +192,10 @@ int32_t CombatNPC::getID() {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityRef CombatNPC::getRef() {
|
||||||
|
return EntityRef(id);
|
||||||
|
}
|
||||||
|
|
||||||
void CombatNPC::step(time_t currTime) {
|
void CombatNPC::step(time_t currTime) {
|
||||||
|
|
||||||
if(stateHandlers.find(state) != stateHandlers.end())
|
if(stateHandlers.find(state) != stateHandlers.end())
|
||||||
|
@ -83,6 +83,10 @@ void Egg::enterIntoViewOf(CNSocket *sock) {
|
|||||||
sock->sendPacket(pkt, P_FE2CL_SHINY_ENTER);
|
sock->sendPacket(pkt, P_FE2CL_SHINY_ENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sNano* Player::getActiveNano() {
|
||||||
|
return &Nanos[activeNano];
|
||||||
|
}
|
||||||
|
|
||||||
sPCAppearanceData Player::getAppearanceData() {
|
sPCAppearanceData Player::getAppearanceData() {
|
||||||
sPCAppearanceData data = {};
|
sPCAppearanceData data = {};
|
||||||
data.iID = iID;
|
data.iID = iID;
|
||||||
|
@ -53,12 +53,15 @@ public:
|
|||||||
virtual bool hasBuff(int) = 0;
|
virtual bool hasBuff(int) = 0;
|
||||||
virtual int getCompositeCondition() = 0;
|
virtual int getCompositeCondition() = 0;
|
||||||
virtual int takeDamage(EntityRef, int) = 0;
|
virtual int takeDamage(EntityRef, int) = 0;
|
||||||
virtual void heal(EntityRef, int) = 0;
|
virtual int heal(EntityRef, int) = 0;
|
||||||
virtual bool isAlive() = 0;
|
virtual bool isAlive() = 0;
|
||||||
virtual int getCurrentHP() = 0;
|
virtual int getCurrentHP() = 0;
|
||||||
|
virtual int getMaxHP() = 0;
|
||||||
|
virtual int getLevel() = 0;
|
||||||
virtual std::vector<EntityRef> getGroupMembers() = 0;
|
virtual std::vector<EntityRef> getGroupMembers() = 0;
|
||||||
virtual int32_t getCharType() = 0;
|
virtual int32_t getCharType() = 0;
|
||||||
virtual int32_t getID() = 0;
|
virtual int32_t getID() = 0;
|
||||||
|
virtual EntityRef getRef() = 0;
|
||||||
virtual void step(time_t currTime) = 0;
|
virtual void step(time_t currTime) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,12 +127,15 @@ struct CombatNPC : public BaseNPC, public ICombatant {
|
|||||||
virtual bool hasBuff(int buffId) override;
|
virtual bool hasBuff(int buffId) override;
|
||||||
virtual int getCompositeCondition() override;
|
virtual int getCompositeCondition() override;
|
||||||
virtual int takeDamage(EntityRef src, int amt) override;
|
virtual int takeDamage(EntityRef src, int amt) override;
|
||||||
virtual void heal(EntityRef src, int amt) override;
|
virtual int heal(EntityRef src, int amt) override;
|
||||||
virtual bool isAlive() override;
|
virtual bool isAlive() override;
|
||||||
virtual int getCurrentHP() override;
|
virtual int getCurrentHP() override;
|
||||||
|
virtual int getMaxHP() override;
|
||||||
|
virtual int getLevel() override;
|
||||||
virtual std::vector<EntityRef> getGroupMembers() override;
|
virtual std::vector<EntityRef> getGroupMembers() override;
|
||||||
virtual int32_t getCharType() override;
|
virtual int32_t getCharType() override;
|
||||||
virtual int32_t getID() override;
|
virtual int32_t getID() override;
|
||||||
|
virtual EntityRef getRef() override;
|
||||||
virtual void step(time_t currTime) override;
|
virtual void step(time_t currTime) override;
|
||||||
|
|
||||||
virtual void transition(AIState newState, EntityRef src);
|
virtual void transition(AIState newState, EntityRef src);
|
||||||
|
@ -95,14 +95,18 @@ struct Player : public Entity, public ICombatant {
|
|||||||
virtual bool hasBuff(int buffId) override;
|
virtual bool hasBuff(int buffId) override;
|
||||||
virtual int getCompositeCondition() override;
|
virtual int getCompositeCondition() override;
|
||||||
virtual int takeDamage(EntityRef src, int amt) override;
|
virtual int takeDamage(EntityRef src, int amt) override;
|
||||||
virtual void heal(EntityRef src, int amt) override;
|
virtual int heal(EntityRef src, int amt) override;
|
||||||
virtual bool isAlive() override;
|
virtual bool isAlive() override;
|
||||||
virtual int getCurrentHP() override;
|
virtual int getCurrentHP() override;
|
||||||
|
virtual int getMaxHP() override;
|
||||||
|
virtual int getLevel() override;
|
||||||
virtual std::vector<EntityRef> getGroupMembers() override;
|
virtual std::vector<EntityRef> getGroupMembers() override;
|
||||||
virtual int32_t getCharType() override;
|
virtual int32_t getCharType() override;
|
||||||
virtual int32_t getID() override;
|
virtual int32_t getID() override;
|
||||||
|
virtual EntityRef getRef() override;
|
||||||
|
|
||||||
virtual void step(time_t currTime) override;
|
virtual void step(time_t currTime) override;
|
||||||
|
|
||||||
|
sNano* getActiveNano();
|
||||||
sPCAppearanceData getAppearanceData();
|
sPCAppearanceData getAppearanceData();
|
||||||
};
|
};
|
||||||
|
@ -93,7 +93,7 @@ inline constexpr bool isOutboundPacketID(uint32_t id) {
|
|||||||
|
|
||||||
// overflow-safe validation of variable-length packets
|
// overflow-safe validation of variable-length packets
|
||||||
// for outbound packets
|
// for outbound packets
|
||||||
inline constexpr bool validOutVarPacket(size_t base, int32_t npayloads, size_t plsize) {
|
inline constexpr bool validOutVarPacket(size_t base, size_t npayloads, size_t plsize) {
|
||||||
// check for multiplication overflow
|
// check for multiplication overflow
|
||||||
if (npayloads > 0 && (CN_PACKET_BUFFER_SIZE - 8) / (size_t)npayloads < plsize)
|
if (npayloads > 0 && (CN_PACKET_BUFFER_SIZE - 8) / (size_t)npayloads < plsize)
|
||||||
return false;
|
return false;
|
||||||
@ -110,7 +110,7 @@ inline constexpr bool validOutVarPacket(size_t base, int32_t npayloads, size_t p
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for inbound packets
|
// for inbound packets
|
||||||
inline constexpr bool validInVarPacket(size_t base, int32_t npayloads, size_t plsize, size_t datasize) {
|
inline constexpr bool validInVarPacket(size_t base, size_t npayloads, size_t plsize, size_t datasize) {
|
||||||
// check for multiplication overflow
|
// check for multiplication overflow
|
||||||
if (npayloads > 0 && (CN_PACKET_BUFFER_SIZE - 8) / (size_t)npayloads < plsize)
|
if (npayloads > 0 && (CN_PACKET_BUFFER_SIZE - 8) / (size_t)npayloads < plsize)
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user