mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-17 03:20:06 +00:00
[WIP] Fix targeting for groups
This commit is contained in:
parent
80dd6b5479
commit
9312706524
@ -270,10 +270,30 @@ void Abilities::useNPCSkill(EntityRef npc, int skillID, std::vector<ICombatant*>
|
|||||||
NPCManager::sendToViewable(entity, pkt, P_FE2CL_NPC_SKILL_HIT, resplen);
|
NPCManager::sendToViewable(entity, pkt, P_FE2CL_NPC_SKILL_HIT, resplen);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ICombatant*> Abilities::matchTargets(SkillData* skill, int count, int32_t *ids) {
|
static std::vector<ICombatant*> entityRefsToCombatants(std::vector<EntityRef> refs) {
|
||||||
|
std::vector<ICombatant*> combatants;
|
||||||
|
for(EntityRef ref : refs) {
|
||||||
|
if(ref.kind == EntityKind::PLAYER)
|
||||||
|
combatants.push_back(dynamic_cast<ICombatant*>(PlayerManager::getPlayer(ref.sock)));
|
||||||
|
else if(ref.kind == EntityKind::COMBAT_NPC || ref.kind == EntityKind::MOB)
|
||||||
|
combatants.push_back(dynamic_cast<ICombatant*>(ref.getEntity()));
|
||||||
|
}
|
||||||
|
return combatants;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ICombatant*> Abilities::matchTargets(ICombatant* src, SkillData* skill, int count, int32_t *ids) {
|
||||||
|
|
||||||
|
if(skill->targetType == SkillTargetType::GROUP) {
|
||||||
|
// group
|
||||||
|
if(count != 1 || ids[0] != src->getID()) {
|
||||||
|
std::cout << "[WARN] skill: bad group targeting (id " << ids[0] << ")\n";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return entityRefsToCombatants(src->getGroupMembers());
|
||||||
|
}
|
||||||
|
|
||||||
|
// individuals
|
||||||
std::vector<ICombatant*> targets;
|
std::vector<ICombatant*> targets;
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
int32_t id = ids[i];
|
int32_t id = ids[i];
|
||||||
if (skill->targetType == SkillTargetType::MOBS) {
|
if (skill->targetType == SkillTargetType::MOBS) {
|
||||||
@ -286,8 +306,8 @@ std::vector<ICombatant*> Abilities::matchTargets(SkillData* skill, int count, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << "[WARN] skill: invalid mob target (id " << id << ")\n";
|
std::cout << "[WARN] skill: invalid mob target (id " << id << ")\n";
|
||||||
} else if(skill->targetType == SkillTargetType::SELF || skill->targetType == SkillTargetType::GROUP) {
|
} else if(skill->targetType == SkillTargetType::PLAYERS) {
|
||||||
// players (?)
|
// player
|
||||||
Player* plr = PlayerManager::getPlayerFromID(id);
|
Player* plr = PlayerManager::getPlayerFromID(id);
|
||||||
if (plr != nullptr) {
|
if (plr != nullptr) {
|
||||||
targets.push_back(dynamic_cast<ICombatant*>(plr));
|
targets.push_back(dynamic_cast<ICombatant*>(plr));
|
||||||
|
@ -21,7 +21,7 @@ enum class SkillEffectTarget {
|
|||||||
|
|
||||||
enum class SkillTargetType {
|
enum class SkillTargetType {
|
||||||
MOBS = 1,
|
MOBS = 1,
|
||||||
SELF = 2,
|
PLAYERS = 2,
|
||||||
GROUP = 3
|
GROUP = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,6 +63,6 @@ namespace Abilities {
|
|||||||
void useNanoSkill(CNSocket*, SkillData*, sNano&, std::vector<ICombatant*>);
|
void useNanoSkill(CNSocket*, SkillData*, sNano&, std::vector<ICombatant*>);
|
||||||
void useNPCSkill(EntityRef, int skillID, std::vector<ICombatant*>);
|
void useNPCSkill(EntityRef, int skillID, std::vector<ICombatant*>);
|
||||||
|
|
||||||
std::vector<ICombatant*> matchTargets(SkillData*, int, int32_t*);
|
std::vector<ICombatant*> matchTargets(ICombatant*, SkillData*, int, int32_t*);
|
||||||
int getCSTBFromST(int eSkillType);
|
int getCSTBFromST(int eSkillType);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ void Eggs::eggBuffPlayer(CNSocket* sock, int skillId, int eggId, int duration) {
|
|||||||
SkillData* skill = &Abilities::SkillTable[skillId];
|
SkillData* skill = &Abilities::SkillTable[skillId];
|
||||||
if(skill->drainType == SkillDrainType::PASSIVE) {
|
if(skill->drainType == SkillDrainType::PASSIVE) {
|
||||||
// apply buff
|
// apply buff
|
||||||
if(skill->targetType != SkillTargetType::SELF) {
|
if(skill->targetType != SkillTargetType::PLAYERS) {
|
||||||
std::cout << "[WARN] weird skill type for egg " << eggId << " with skill " << skillId << ", should be " << (int)skill->targetType << std::endl;
|
std::cout << "[WARN] weird skill type for egg " << eggId << " with skill " << skillId << ", should be " << (int)skill->targetType << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,16 +73,6 @@ std::vector<ICombatant*> Nanos::applyNanoBuff(SkillData* skill, Player* plr) {
|
|||||||
assert(skill->drainType == SkillDrainType::PASSIVE);
|
assert(skill->drainType == SkillDrainType::PASSIVE);
|
||||||
|
|
||||||
EntityRef self = PlayerManager::getSockFromID(plr->iID);
|
EntityRef self = PlayerManager::getSockFromID(plr->iID);
|
||||||
std::vector<ICombatant*> affected;
|
|
||||||
std::vector<EntityRef> targets;
|
|
||||||
if (skill->targetType == SkillTargetType::GROUP) {
|
|
||||||
targets = plr->getGroupMembers(); // group
|
|
||||||
}
|
|
||||||
else if(skill->targetType == SkillTargetType::SELF) {
|
|
||||||
targets.push_back(self); // self
|
|
||||||
} else {
|
|
||||||
std::cout << "[WARN] Passive skill with type " << skill->skillType << " has target type MOB" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int timeBuffId = Abilities::getCSTBFromST(skill->skillType);
|
int timeBuffId = Abilities::getCSTBFromST(skill->skillType);
|
||||||
int boost = Nanos::getNanoBoost(plr) ? 3 : 0;
|
int boost = Nanos::getNanoBoost(plr) ? 3 : 0;
|
||||||
@ -95,21 +85,22 @@ std::vector<ICombatant*> Nanos::applyNanoBuff(SkillData* skill, Player* plr) {
|
|||||||
BuffClass::NONE, // overwritten per target
|
BuffClass::NONE, // overwritten per target
|
||||||
};
|
};
|
||||||
|
|
||||||
for (EntityRef target : targets) {
|
// for passive skills, using just the player as a target is fine
|
||||||
Entity* entity = target.getEntity();
|
// this is because the group skill type will ignore the count,
|
||||||
if (entity->kind != PLAYER && entity->kind != COMBAT_NPC && entity->kind != MOB)
|
// and the other option is single-target
|
||||||
continue; // not a combatant
|
std::vector<ICombatant*> targets = Abilities::matchTargets(dynamic_cast<ICombatant*>(plr), skill, 1, &plr->iID);
|
||||||
|
std::vector<ICombatant*> affected;
|
||||||
|
for (ICombatant* target : targets) {
|
||||||
|
|
||||||
passiveBuff.buffStackClass = target == self ? BuffClass::NANO : BuffClass::GROUP_NANO;
|
passiveBuff.buffStackClass = target == plr ? BuffClass::NANO : BuffClass::GROUP_NANO;
|
||||||
ICombatant* combatant = dynamic_cast<ICombatant*>(entity);
|
if(target->addBuff(timeBuffId,
|
||||||
if(combatant->addBuff(timeBuffId,
|
|
||||||
[](EntityRef self, Buff* buff, int status, BuffStack* stack) {
|
[](EntityRef self, Buff* buff, int status, BuffStack* stack) {
|
||||||
Buffs::timeBuffUpdate(self, buff, status, stack);
|
Buffs::timeBuffUpdate(self, buff, status, stack);
|
||||||
},
|
},
|
||||||
[](EntityRef self, Buff* buff, time_t currTime) {
|
[](EntityRef self, Buff* buff, time_t currTime) {
|
||||||
// no-op
|
// no-op
|
||||||
},
|
},
|
||||||
&passiveBuff)) affected.push_back(combatant);
|
&passiveBuff)) affected.push_back(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
return affected;
|
return affected;
|
||||||
@ -317,8 +308,8 @@ static void nanoSkillUseHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
std::cout << PlayerManager::getPlayerName(plr) << " requested to summon nano skill " << std::endl;
|
std::cout << PlayerManager::getPlayerName(plr) << " requested to summon nano skill " << std::endl;
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO ABILITIES
|
ICombatant* plrCombatant = dynamic_cast<ICombatant*>(plr);
|
||||||
std::vector<ICombatant*> targetData = Abilities::matchTargets(skillData, pkt->iTargetCnt, (int32_t*)(pkt + 1));
|
std::vector<ICombatant*> targetData = Abilities::matchTargets(plrCombatant, skillData, pkt->iTargetCnt, (int32_t*)(pkt + 1));
|
||||||
Abilities::useNanoSkill(sock, skillData, nano, targetData);
|
Abilities::useNanoSkill(sock, skillData, nano, targetData);
|
||||||
|
|
||||||
if (plr->Nanos[plr->activeNano].iStamina < 0)
|
if (plr->Nanos[plr->activeNano].iStamina < 0)
|
||||||
|
@ -401,12 +401,11 @@ static void revivePlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
if (!(plr->hasBuff(ECSB_PHOENIX)))
|
if (!(plr->hasBuff(ECSB_PHOENIX)))
|
||||||
return; // sanity check
|
return; // sanity check
|
||||||
plr->Nanos[plr->activeNano].iStamina = 0;
|
plr->Nanos[plr->activeNano].iStamina = 0;
|
||||||
// TODO ABILITIES
|
|
||||||
//Abilities::applyBuff(sock, plr->Nanos[plr->activeNano].iSkillID, 2, 1, 0);
|
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case ePCRegenType::HereByPhoenixGroup: // revived by group member's nano
|
case ePCRegenType::HereByPhoenixGroup: // revived by group member's nano
|
||||||
plr->HP = PC_MAXHEALTH(plr->level) / 2;
|
plr->HP = PC_MAXHEALTH(plr->level) / 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // plain respawn
|
default: // plain respawn
|
||||||
plr->HP = PC_MAXHEALTH(plr->level) / 2;
|
plr->HP = PC_MAXHEALTH(plr->level) / 2;
|
||||||
// fallthrough
|
// fallthrough
|
||||||
|
Loading…
Reference in New Issue
Block a user