mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-19 12:21:34 +00:00
[Tasks] Implement alternate currency rewards (#2827)
* Reward currency on task completion * Handle reward window * Tweaks
This commit is contained in:
parent
404f7cada8
commit
d369b47ef4
@ -1028,4 +1028,7 @@ enum ZoningMessage : int8
|
|||||||
ZoneNoExperience = -7
|
ZoneNoExperience = -7
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ALT_CURRENCY_ID_RADIANT 4
|
||||||
|
#define ALT_CURRENCY_ID_EBON 5
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
@ -1072,6 +1072,16 @@ void ClientTaskState::RewardTask(Client *c, const TaskInformation *ti, ClientTas
|
|||||||
c->AddCrystals(ti->reward_points, 0);
|
c->AddCrystals(ti->reward_points, 0);
|
||||||
} else if (ti->reward_point_type == static_cast<int32_t>(zone->GetCurrencyID(EBON_CRYSTAL))) {
|
} else if (ti->reward_point_type == static_cast<int32_t>(zone->GetCurrencyID(EBON_CRYSTAL))) {
|
||||||
c->AddCrystals(0, ti->reward_points);
|
c->AddCrystals(0, ti->reward_points);
|
||||||
|
} else {
|
||||||
|
for (const auto& ac : zone->AlternateCurrencies) {
|
||||||
|
if (ti->reward_point_type == ac.id) {
|
||||||
|
const EQ::ItemData *item = database.GetItem(ac.item_id);
|
||||||
|
if (item) {
|
||||||
|
c->AddAlternateCurrencyValue(ti->reward_point_type, ti->reward_points);
|
||||||
|
c->Message(Chat::Yellow, fmt::format("You have received ({}) {}!", ti->reward_points, item->Name).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -706,9 +706,9 @@ void TaskManager::SharedTaskSelector(Client* client, Mob* mob, const std::vector
|
|||||||
validation_failed = true;
|
validation_failed = true;
|
||||||
|
|
||||||
auto it = std::find_if(request.members.begin(), request.members.end(),
|
auto it = std::find_if(request.members.begin(), request.members.end(),
|
||||||
[&](const SharedTaskMember& member) {
|
[&](const SharedTaskMember& member) {
|
||||||
return member.character_id == shared_task_members.front().character_id;
|
return member.character_id == shared_task_members.front().character_id;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (it != request.members.end()) {
|
if (it != request.members.end()) {
|
||||||
if (request.group_type == SharedTaskRequestGroupType::Group) {
|
if (request.group_type == SharedTaskRequestGroupType::Group) {
|
||||||
@ -761,14 +761,14 @@ bool TaskManager::CanOfferSharedTask(int task_id, const SharedTaskRequest& reque
|
|||||||
if (task->min_level > 0 && request.lowest_level < task->min_level)
|
if (task->min_level > 0 && request.lowest_level < task->min_level)
|
||||||
{
|
{
|
||||||
LogTasksDetail("lowest level [{}] is below task [{}] min level [{}]",
|
LogTasksDetail("lowest level [{}] is below task [{}] min level [{}]",
|
||||||
request.lowest_level, task_id, task->min_level);
|
request.lowest_level, task_id, task->min_level);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task->max_level > 0 && request.highest_level > task->max_level)
|
if (task->max_level > 0 && request.highest_level > task->max_level)
|
||||||
{
|
{
|
||||||
LogTasksDetail("highest level [{}] exceeds task [{}] max level [{}]",
|
LogTasksDetail("highest level [{}] exceeds task [{}] max level [{}]",
|
||||||
request.highest_level, task_id, task->max_level);
|
request.highest_level, task_id, task->max_level);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1154,6 +1154,10 @@ void TaskManager::SendActiveTaskDescription(
|
|||||||
+ sizeof(TaskDescriptionData1_Struct) + t->description.length() + 1
|
+ sizeof(TaskDescriptionData1_Struct) + t->description.length() + 1
|
||||||
+ sizeof(TaskDescriptionData2_Struct) + 1 + sizeof(TaskDescriptionTrailer_Struct);
|
+ sizeof(TaskDescriptionData2_Struct) + 1 + sizeof(TaskDescriptionTrailer_Struct);
|
||||||
|
|
||||||
|
std::string reward = t->reward;
|
||||||
|
bool is_don_reward = (t->reward_point_type == ALT_CURRENCY_ID_RADIANT ||
|
||||||
|
t->reward_point_type == ALT_CURRENCY_ID_EBON);
|
||||||
|
|
||||||
// If there is an item make the reward text into a link to the item (only the first item if a list
|
// If there is an item make the reward text into a link to the item (only the first item if a list
|
||||||
// is specified). I have been unable to get multiple item links to work.
|
// is specified). I have been unable to get multiple item links to work.
|
||||||
//
|
//
|
||||||
@ -1173,7 +1177,34 @@ void TaskManager::SendActiveTaskDescription(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_length += t->reward.length() + 1 + t->item_link.length() + 1;
|
// display alternate currency in reward window manually
|
||||||
|
// there may be a more formal packet structure for displaying this but this is what it is for
|
||||||
|
// now to have bare minimum support
|
||||||
|
if (t->reward_point_type > 0 && t->reward_points > 0 && !is_don_reward) {
|
||||||
|
for (const auto& ac : zone->AlternateCurrencies) {
|
||||||
|
if (t->reward_point_type == ac.id) {
|
||||||
|
const EQ::ItemData *item = database.GetItem(ac.item_id);
|
||||||
|
if (item) {
|
||||||
|
std::string currency_description = fmt::format(
|
||||||
|
"{} ({})",
|
||||||
|
item->Name,
|
||||||
|
t->reward_points
|
||||||
|
);
|
||||||
|
|
||||||
|
reward = currency_description;
|
||||||
|
|
||||||
|
EQ::SayLinkEngine l;
|
||||||
|
l.SetLinkType(EQ::saylink::SayLinkItemData);
|
||||||
|
l.SetItemData(item);
|
||||||
|
l.SetTaskUse();
|
||||||
|
l.SetProxyText(currency_description.c_str());
|
||||||
|
t->item_link = l.GenerateLink();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_length += reward.length() + 1 + t->item_link.length() + 1;
|
||||||
|
|
||||||
char *Ptr;
|
char *Ptr;
|
||||||
TaskDescriptionHeader_Struct *task_description_header;
|
TaskDescriptionHeader_Struct *task_description_header;
|
||||||
@ -1190,7 +1221,7 @@ void TaskManager::SendActiveTaskDescription(
|
|||||||
task_description_header->open_window = bring_up_task_journal;
|
task_description_header->open_window = bring_up_task_journal;
|
||||||
task_description_header->task_type = static_cast<uint32>(t->type);
|
task_description_header->task_type = static_cast<uint32>(t->type);
|
||||||
|
|
||||||
task_description_header->reward_type = t->reward_point_type;
|
task_description_header->reward_type = is_don_reward ? t->reward_point_type : 0;
|
||||||
|
|
||||||
Ptr = (char *) task_description_header + sizeof(TaskDescriptionHeader_Struct);
|
Ptr = (char *) task_description_header + sizeof(TaskDescriptionHeader_Struct);
|
||||||
|
|
||||||
@ -1224,16 +1255,17 @@ void TaskManager::SendActiveTaskDescription(
|
|||||||
|
|
||||||
// we actually have 2 strings here. One is max length 96 and not parsed for item links
|
// we actually have 2 strings here. One is max length 96 and not parsed for item links
|
||||||
// We actually skipped past that string incorrectly before, so TODO: fix item link string
|
// We actually skipped past that string incorrectly before, so TODO: fix item link string
|
||||||
sprintf(Ptr, "%s", t->reward.c_str());
|
sprintf(Ptr, "%s", reward.c_str());
|
||||||
Ptr += t->reward.length() + 1;
|
Ptr += reward.length() + 1;
|
||||||
|
|
||||||
// second string is parsed for item links
|
// second string is parsed for item links
|
||||||
sprintf(Ptr, "%s", t->item_link.c_str());
|
sprintf(Ptr, "%s", t->item_link.c_str());
|
||||||
Ptr += t->item_link.length() + 1;
|
Ptr += t->item_link.length() + 1;
|
||||||
|
|
||||||
tdt = (TaskDescriptionTrailer_Struct *) Ptr;
|
tdt = (TaskDescriptionTrailer_Struct *) Ptr;
|
||||||
|
|
||||||
// shared tasks show radiant/ebon crystal reward, non-shared tasks show generic points
|
// shared tasks show radiant/ebon crystal reward, non-shared tasks show generic points
|
||||||
tdt->Points = t->reward_points;
|
tdt->Points = is_don_reward ? t->reward_points : 0;
|
||||||
|
|
||||||
tdt->has_reward_selection = 0; // TODO: new rewards window
|
tdt->has_reward_selection = 0; // TODO: new rewards window
|
||||||
|
|
||||||
@ -1720,7 +1752,7 @@ void TaskManager::SyncClientSharedTaskRemoveLocalIfNotExists(Client *c, ClientTa
|
|||||||
CharacterActivitiesRepository::DeleteWhere(database, delete_where);
|
CharacterActivitiesRepository::DeleteWhere(database, delete_where);
|
||||||
|
|
||||||
c->MessageString(Chat::Yellow, TaskStr::NO_LONGER_MEMBER_TITLE,
|
c->MessageString(Chat::Yellow, TaskStr::NO_LONGER_MEMBER_TITLE,
|
||||||
m_task_data[cts->m_active_shared_task.task_id].title.c_str());
|
m_task_data[cts->m_active_shared_task.task_id].title.c_str());
|
||||||
|
|
||||||
// remove as active task if doesn't exist
|
// remove as active task if doesn't exist
|
||||||
cts->m_active_shared_task = {};
|
cts->m_active_shared_task = {};
|
||||||
@ -1830,7 +1862,7 @@ bool TaskManager::IsActiveTaskComplete(ClientTaskInformation& client_task)
|
|||||||
for (int i = 0; i < task_data->activity_count; ++i)
|
for (int i = 0; i < task_data->activity_count; ++i)
|
||||||
{
|
{
|
||||||
if (client_task.activity[i].activity_state != ActivityCompleted &&
|
if (client_task.activity[i].activity_state != ActivityCompleted &&
|
||||||
!task_data->activity_information[i].optional)
|
!task_data->activity_information[i].optional)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user