mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-10 06:40:26 +00:00
[Feature] Faction Association (#2408)
* Add faction logging category Probably should use this for more things * Add FactionAssociation struct This is simply just a struct that contains an array of faction ids and multiplier. This can hold a maximum of 10 entries (Seru hit is 8, so 2 extra) this can be raised if need be. * Add database changes and other data point changes This is all the database changes and loading changes Included is an optional SQL that will be used as a starting point, there is likely errors or typos, but we will fix those as they are discovered. * Add Client::RewardFaction function This just takes the faction ID and the magnitude of the primary faction hit and calculates the rest. The minimum change will be either 1 or -1. We stop processing after we see an ID of 0 and assume there will be no later entries. The primary faction ID will always receive a hit even if there is no faction association entries * Add users of RewardFaction to NPC death, tasks, and QuestRewards This will only use the new system if the magnitude is set, otherwise we will just use the old system still * Add quest system calls and lua QuestReward support * Add #factionassociation command This just calls RewardFaction, mostly useful for debugging
This commit is contained in:
committed by
GitHub
parent
efe1879115
commit
2b4e555eae
+40
-4
@@ -8760,7 +8760,7 @@ void Client::QuestReward(Mob* target, uint32 copper, uint32 silver, uint32 gold,
|
||||
int32 nfl_id = target->CastToNPC()->GetNPCFactionID();
|
||||
SetFactionLevel(CharacterID(), nfl_id, GetBaseClass(), GetBaseRace(), GetDeity(), true);
|
||||
qr->faction = target->CastToNPC()->GetPrimaryFaction();
|
||||
qr->faction_mod = 1; // Too lazy to get real value, not sure if this is even used by client anyhow.
|
||||
qr->faction_mod = 1; // Too lazy to get real value, not even used by client anyhow.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8780,7 +8780,7 @@ void Client::QuestReward(Mob* target, const QuestReward_Struct &reward, bool fac
|
||||
memcpy(qr, &reward, sizeof(QuestReward_Struct));
|
||||
|
||||
// not set in caller because reasons
|
||||
qr->mob_id = target ? target->GetID() : 0; // Entity ID for the from mob name
|
||||
qr->mob_id = target ? target->GetID() : 0; // Entity ID for the from mob name, tasks won't set this
|
||||
|
||||
if (reward.copper > 0 || reward.silver > 0 || reward.gold > 0 || reward.platinum > 0)
|
||||
AddMoneyToPP(reward.copper, reward.silver, reward.gold, reward.platinum);
|
||||
@@ -8789,6 +8789,12 @@ void Client::QuestReward(Mob* target, const QuestReward_Struct &reward, bool fac
|
||||
if (reward.item_id[i] > 0)
|
||||
SummonItem(reward.item_id[i], 0, 0, 0, 0, 0, 0, false, EQ::invslot::slotCursor);
|
||||
|
||||
// only process if both are valid
|
||||
// if we don't have a target here, we want to just reward, but if there is a target, need to check charm
|
||||
if (reward.faction && reward.faction_mod && (target == nullptr || !target->IsCharmed()))
|
||||
RewardFaction(reward.faction, reward.faction_mod);
|
||||
|
||||
// legacy support
|
||||
if (faction)
|
||||
{
|
||||
if (target && target->IsNPC() && !target->IsCharmed())
|
||||
@@ -8796,11 +8802,11 @@ void Client::QuestReward(Mob* target, const QuestReward_Struct &reward, bool fac
|
||||
int32 nfl_id = target->CastToNPC()->GetNPCFactionID();
|
||||
SetFactionLevel(CharacterID(), nfl_id, GetBaseClass(), GetBaseRace(), GetDeity(), true);
|
||||
qr->faction = target->CastToNPC()->GetPrimaryFaction();
|
||||
qr->faction_mod = 1; // Too lazy to get real value, not sure if this is even used by client anyhow.
|
||||
qr->faction_mod = 1; // Too lazy to get real value, not even used by client anyhow.
|
||||
}
|
||||
}
|
||||
|
||||
if (reward.exp_reward> 0)
|
||||
if (reward.exp_reward > 0)
|
||||
AddEXP(reward.exp_reward);
|
||||
|
||||
QueuePacket(outapp, true, Client::CLIENT_CONNECTED);
|
||||
@@ -8821,6 +8827,36 @@ void Client::CashReward(uint32 copper, uint32 silver, uint32 gold, uint32 platin
|
||||
QueuePacket(outapp.get());
|
||||
}
|
||||
|
||||
void Client::RewardFaction(int id, int amount)
|
||||
{
|
||||
// first we hit the primary faction, even without any associations
|
||||
SetFactionLevel2(CharacterID(), id, GetClass(), GetBaseRace(), GetDeity(), amount, false);
|
||||
|
||||
auto faction_assoc = content_db.GetFactionAssociationHit(id);
|
||||
// We could log here, but since it's actually expected for some not to have entries, it would be noisy.
|
||||
if (!faction_assoc) {
|
||||
return;
|
||||
}
|
||||
|
||||
// now hit them in order
|
||||
for (int i = 0; i < MAX_FACTION_ASSOC; ++i) {
|
||||
if (faction_assoc->hits[i].id <= 0) // we don't allow later entries
|
||||
break;
|
||||
if (faction_assoc->hits[i].multiplier == 0.0f) {
|
||||
LogFaction("Bad association multiplier for ID {} entry {}", id, i + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// value is truncated and min clamped to 1 (or -1)
|
||||
float temp = faction_assoc->hits[i].multiplier * amount;
|
||||
int sign = temp < 0.0f ? -1 : 1;
|
||||
int32 new_amount = std::max(1, static_cast<int32>(std::abs(temp))) * sign;
|
||||
|
||||
SetFactionLevel2(CharacterID(), faction_assoc->hits[i].id, GetClass(), GetBaseRace(), GetDeity(),
|
||||
new_amount, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::SendHPUpdateMarquee(){
|
||||
if (!this || !IsClient() || !current_hp || !max_hp)
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user