mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-16 19:20:05 +00:00
Move drain to new system
TODO - There is a seg fault that happens when drain kills the mob - leech unimplemented - mob skills unimplemented
This commit is contained in:
parent
1cf2be9968
commit
c1aff8d3c3
@ -93,19 +93,28 @@ static SkillResult handleSkillBuff(SkillData* skill, int power, ICombatant* sour
|
|||||||
int duration = skill->durationTime[power];
|
int duration = skill->durationTime[power];
|
||||||
int strength = skill->values[0][power];
|
int strength = skill->values[0][power];
|
||||||
BuffStack passiveBuff = {
|
BuffStack passiveBuff = {
|
||||||
skill->drainType == SkillDrainType::PASSIVE ? 1 : duration, // ticks
|
skill->drainType == SkillDrainType::PASSIVE ? 1 : (duration * 100) / MS_PER_COMBAT_TICK, // ticks
|
||||||
strength, // value
|
strength, // value
|
||||||
source->getRef(), // source
|
source->getRef(), // source
|
||||||
source == target ? BuffClass::NANO : BuffClass::GROUP_NANO, // buff class
|
source == target ? BuffClass::NANO : BuffClass::GROUP_NANO, // buff class
|
||||||
};
|
};
|
||||||
|
|
||||||
int timeBuffId = Abilities::getCSTBFromST(skill->skillType);
|
int timeBuffId = Abilities::getCSTBFromST(skill->skillType);
|
||||||
|
SkillDrainType drainType = skill->drainType;
|
||||||
if(!target->addBuff(timeBuffId,
|
if(!target->addBuff(timeBuffId,
|
||||||
[](EntityRef self, Buff* buff, int status, BuffStack* stack) {
|
[drainType](EntityRef self, Buff* buff, int status, BuffStack* stack) {
|
||||||
|
if(buff->id == ECSB_BOUNDINGBALL) {
|
||||||
|
// drain
|
||||||
|
ICombatant* combatant = dynamic_cast<ICombatant*>(self.getEntity());
|
||||||
|
combatant->takeDamage(buff->getLastSource(), 0); // aggro
|
||||||
|
}
|
||||||
Buffs::timeBuffUpdate(self, buff, status, stack);
|
Buffs::timeBuffUpdate(self, buff, status, stack);
|
||||||
|
if(drainType == SkillDrainType::ACTIVE && status == ETBU_DEL)
|
||||||
|
Buffs::timeBuffTimeout(self);
|
||||||
},
|
},
|
||||||
[](EntityRef self, Buff* buff, time_t currTime) {
|
[](EntityRef self, Buff* buff, time_t currTime) {
|
||||||
// no-op
|
if(buff->id == ECSB_BOUNDINGBALL)
|
||||||
|
Buffs::tickDrain(self, buff); // drain
|
||||||
},
|
},
|
||||||
&passiveBuff)) return SkillResult(); // no result if already buffed
|
&passiveBuff)) return SkillResult(); // no result if already buffed
|
||||||
|
|
||||||
|
@ -95,6 +95,12 @@ int Buff::getValue(BuffValueSelector selector) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityRef Buff::getLastSource() {
|
||||||
|
if(stacks.empty())
|
||||||
|
return self;
|
||||||
|
return stacks.back().source;
|
||||||
|
}
|
||||||
|
|
||||||
bool Buff::isStale() {
|
bool Buff::isStale() {
|
||||||
return stacks.empty();
|
return stacks.empty();
|
||||||
}
|
}
|
||||||
@ -142,6 +148,7 @@ void Buffs::timeBuffTick(EntityRef self, Buff* buff) {
|
|||||||
return; // not implemented
|
return; // not implemented
|
||||||
Entity* entity = self.getEntity();
|
Entity* entity = self.getEntity();
|
||||||
ICombatant* combatant = dynamic_cast<ICombatant*>(entity);
|
ICombatant* combatant = dynamic_cast<ICombatant*>(entity);
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK, pkt);
|
INITSTRUCT(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK, pkt);
|
||||||
pkt.eCT = combatant->getCharType();
|
pkt.eCT = combatant->getCharType();
|
||||||
pkt.iID = combatant->getID();
|
pkt.iID = combatant->getID();
|
||||||
@ -161,4 +168,30 @@ void Buffs::timeBuffTimeout(EntityRef self) {
|
|||||||
pkt.iConditionBitFlag = combatant->getCompositeCondition();
|
pkt.iConditionBitFlag = combatant->getCompositeCondition();
|
||||||
NPCManager::sendToViewable(entity, &pkt, P_FE2CL_CHAR_TIME_BUFF_TIME_OUT, sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_OUT));
|
NPCManager::sendToViewable(entity, &pkt, P_FE2CL_CHAR_TIME_BUFF_TIME_OUT, sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_OUT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Buffs::tickDrain(EntityRef self, Buff* buff) {
|
||||||
|
if(self.kind != EntityKind::COMBAT_NPC && self.kind != EntityKind::MOB)
|
||||||
|
return; // not implemented
|
||||||
|
Entity* entity = self.getEntity();
|
||||||
|
ICombatant* combatant = dynamic_cast<ICombatant*>(entity);
|
||||||
|
int damage = combatant->takeDamage(buff->getLastSource(), combatant->getMaxHP() / 100);
|
||||||
|
|
||||||
|
size_t resplen = sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK) + sizeof(sSkillResult_Damage);
|
||||||
|
assert(resplen < CN_PACKET_BUFFER_SIZE - 8);
|
||||||
|
uint8_t respbuf[CN_PACKET_BUFFER_SIZE];
|
||||||
|
memset(respbuf, 0, resplen);
|
||||||
|
|
||||||
|
sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK *pkt = (sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK*)respbuf;
|
||||||
|
pkt->iID = self.id;
|
||||||
|
pkt->eCT = combatant->getCharType();
|
||||||
|
pkt->iTB_ID = ECSB_BOUNDINGBALL;
|
||||||
|
|
||||||
|
sSkillResult_Damage *drain = (sSkillResult_Damage*)(respbuf + sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK));
|
||||||
|
drain->iDamage = damage;
|
||||||
|
drain->iHP = combatant->getCurrentHP();
|
||||||
|
drain->eCT = pkt->eCT;
|
||||||
|
drain->iID = pkt->iID;
|
||||||
|
|
||||||
|
NPCManager::sendToViewable(self.getEntity(), (void*)&respbuf, P_FE2CL_CHAR_TIME_BUFF_TIME_TICK, resplen);
|
||||||
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
@ -66,6 +66,7 @@ public:
|
|||||||
BuffClass maxClass();
|
BuffClass maxClass();
|
||||||
|
|
||||||
int getValue(BuffValueSelector selector);
|
int getValue(BuffValueSelector selector);
|
||||||
|
EntityRef getLastSource();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In general, a Buff object won't exist
|
* In general, a Buff object won't exist
|
||||||
@ -88,4 +89,5 @@ namespace Buffs {
|
|||||||
void timeBuffUpdate(EntityRef self, Buff* buff, int status, BuffStack* stack);
|
void timeBuffUpdate(EntityRef self, Buff* buff, int status, BuffStack* stack);
|
||||||
void timeBuffTick(EntityRef self, Buff* buff);
|
void timeBuffTick(EntityRef self, Buff* buff);
|
||||||
void timeBuffTimeout(EntityRef self);
|
void timeBuffTimeout(EntityRef self);
|
||||||
|
void tickDrain(EntityRef self, Buff* buff);
|
||||||
}
|
}
|
||||||
|
@ -553,17 +553,6 @@ void MobAI::combatStep(CombatNPC* npc, time_t currTime) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// drain TODO abilities
|
|
||||||
if (self->skillStyle < 0 && (self->lastDrainTime == 0 || currTime - self->lastDrainTime >= 1000)
|
|
||||||
&& self->hasBuff(ECSB_BOUNDINGBALL)) {
|
|
||||||
drainMobHP(self, self->maxHealth / 20); // lose 5% every second
|
|
||||||
self->lastDrainTime = currTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if drain killed the mob, return early
|
|
||||||
if (self->hp <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// tick buffs
|
// tick buffs
|
||||||
auto it = npc->buffs.begin();
|
auto it = npc->buffs.begin();
|
||||||
while(it != npc->buffs.end()) {
|
while(it != npc->buffs.end()) {
|
||||||
@ -578,6 +567,10 @@ void MobAI::combatStep(CombatNPC* npc, time_t currTime) {
|
|||||||
else it++;
|
else it++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if debuffs killed the mob, return early
|
||||||
|
if (self->hp <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
// skip attack if stunned or asleep
|
// skip attack if stunned or asleep
|
||||||
if (self->hasBuff(ECSB_STUN) || self->hasBuff(ECSB_MEZ)) {
|
if (self->hasBuff(ECSB_STUN) || self->hasBuff(ECSB_MEZ)) {
|
||||||
self->skillStyle = -1; // in this case we also reset the any outlying abilities the mob might be winding up.
|
self->skillStyle = -1; // in this case we also reset the any outlying abilities the mob might be winding up.
|
||||||
|
Loading…
Reference in New Issue
Block a user