diff --git a/zone/client.cpp b/zone/client.cpp index eb157dc2f..acbb7cc74 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -8566,6 +8566,42 @@ void Client::QuestReward(Mob* target, uint32 copper, uint32 silver, uint32 gold, safe_delete(outapp); } +void Client::QuestReward(Mob* target, const QuestReward_Struct &reward, bool faction) +{ + auto outapp = new EQApplicationPacket(OP_Sound, sizeof(QuestReward_Struct)); + memset(outapp->pBuffer, 0, sizeof(QuestReward_Struct)); + QuestReward_Struct* qr = (QuestReward_Struct*)outapp->pBuffer; + + memcpy(qr, &reward, sizeof(QuestReward_Struct)); + + // not set in caller because reasons + qr->mob_id = target->GetID(); // Entity ID for the from mob name + + if (reward.copper > 0 || reward.silver > 0 || reward.gold > 0 || reward.platinum > 0) + AddMoneyToPP(reward.copper, reward.silver, reward.gold, reward.platinum, false); + + for (int i = 0; i < QUESTREWARD_COUNT; ++i) + if (reward.item_id[i] > 0) + SummonItem(reward.item_id[i], 0, 0, 0, 0, 0, 0, false, EQEmu::invslot::slotCursor); + + if (faction) + { + if (target->IsNPC()) + { + 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. + } + } + + if (reward.exp_reward> 0) + AddEXP(reward.exp_reward); + + QueuePacket(outapp, true, Client::CLIENT_CONNECTED); + safe_delete(outapp); +} + void Client::SendHPUpdateMarquee(){ if (!this || !this->IsClient() || !this->current_hp || !this->max_hp) return; diff --git a/zone/client.h b/zone/client.h index 4ff431520..300073bb5 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1282,6 +1282,7 @@ public: int32 GetMeleeDamage(Mob* other, bool GetMinDamage = false); void QuestReward(Mob* target, uint32 copper = 0, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0, uint32 itemid = 0, uint32 exp = 0, bool faction = false); + void QuestReward(Mob* target, const QuestReward_Struct &reward, bool faction); // TODO: Fix faction processing void ResetHPUpdateTimer() { hpupdate_timer.Start(); } diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 14c009b12..9d0873360 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -1385,18 +1385,23 @@ void Lua_Client::QuestReward(Lua_Mob target, luabind::adl::object reward) { return; } - uint32 copper = 0; - uint32 silver = 0; - uint32 gold = 0; - uint32 platinum = 0; - uint32 itemid = 0; - uint32 exp = 0; + QuestReward_Struct quest_reward; + quest_reward.mob_id = 0; + quest_reward.target_id = self->GetID(); + quest_reward.copper = 0; + quest_reward.silver = 0; + quest_reward.gold = 0; + quest_reward.platinum = 0; + quest_reward.exp_reward = 0; + quest_reward.faction = 0; + quest_reward.faction_mod = 0; bool faction = false; + std::fill(std::begin(quest_reward.item_id), std::end(quest_reward.item_id), -1); auto cur = reward["copper"]; if (luabind::type(cur) != LUA_TNIL) { try { - copper = luabind::object_cast(cur); + quest_reward.copper = luabind::object_cast(cur); } catch (luabind::cast_failed &) { } } @@ -1404,7 +1409,7 @@ void Lua_Client::QuestReward(Lua_Mob target, luabind::adl::object reward) { cur = reward["silver"]; if (luabind::type(cur) != LUA_TNIL) { try { - silver = luabind::object_cast(cur); + quest_reward.silver = luabind::object_cast(cur); } catch (luabind::cast_failed &) { } } @@ -1412,7 +1417,7 @@ void Lua_Client::QuestReward(Lua_Mob target, luabind::adl::object reward) { cur = reward["gold"]; if (luabind::type(cur) != LUA_TNIL) { try { - gold = luabind::object_cast(cur); + quest_reward.gold = luabind::object_cast(cur); } catch (luabind::cast_failed &) { } } @@ -1420,7 +1425,7 @@ void Lua_Client::QuestReward(Lua_Mob target, luabind::adl::object reward) { cur = reward["platinum"]; if (luabind::type(cur) != LUA_TNIL) { try { - platinum = luabind::object_cast(cur); + quest_reward.platinum = luabind::object_cast(cur); } catch (luabind::cast_failed &) { } } @@ -1428,7 +1433,30 @@ void Lua_Client::QuestReward(Lua_Mob target, luabind::adl::object reward) { cur = reward["itemid"]; if (luabind::type(cur) != LUA_TNIL) { try { - itemid = luabind::object_cast(cur); + quest_reward.item_id[0] = luabind::object_cast(cur); + } catch (luabind::cast_failed &) { + } + } + + // if you define both an itemid and items table, the itemid is thrown away + // should we error? + cur = reward["items"]; + if (luabind::type(cur) == LUA_TTABLE) { + try { + // assume they defined a compatible table + for (int i = 1; i <= QUESTREWARD_COUNT; ++i) { + auto item = cur[i]; + int cur_value = -1; + if (luabind::type(item) != LUA_TNIL) { + try { + cur_value = luabind::object_cast(item); + } catch (luabind::cast_failed &) { + } + } else { + break; + } + quest_reward.item_id[i - 1] = cur_value; + } } catch (luabind::cast_failed &) { } } @@ -1436,7 +1464,7 @@ void Lua_Client::QuestReward(Lua_Mob target, luabind::adl::object reward) { cur = reward["exp"]; if (luabind::type(cur) != LUA_TNIL) { try { - exp = luabind::object_cast(cur); + quest_reward.exp_reward = luabind::object_cast(cur); } catch (luabind::cast_failed &) { } } @@ -1449,7 +1477,7 @@ void Lua_Client::QuestReward(Lua_Mob target, luabind::adl::object reward) { } } - self->QuestReward(target, copper, silver, gold, platinum, itemid, exp, faction); + self->QuestReward(target, quest_reward, faction); } bool Lua_Client::IsDead() {