[Rule] Add a Bandolier Swap Delay Rule (#4465)

* [Rule] Add a Bandolier Swap Delay Rule

* Push

* Update exp.cpp
This commit is contained in:
Alex King 2024-09-07 23:05:44 -04:00 committed by GitHub
parent 0e5a38f072
commit bb1578796b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 61 additions and 18 deletions

View File

@ -229,6 +229,7 @@ RULE_BOOL(Character, GroupInvitesRequireTarget, false, "Enable to require player
RULE_BOOL(Character, PlayerTradingLoreFeedback, true, "If enabled, during a player to player trade, if lore items exist, it will output which items.")
RULE_INT(Character, MendAlwaysSucceedValue, 199, "Value at which mend will always succeed its skill check. Default: 199")
RULE_BOOL(Character, SneakAlwaysSucceedOver100, false, "When sneak skill is over 100, always succeed sneak/hide. Default: false")
RULE_INT(Character, BandolierSwapDelay, 0, "Bandolier swap delay in milliseconds, default is 0")
RULE_CATEGORY_END()
RULE_CATEGORY(Mercs)

View File

@ -186,7 +186,8 @@ Client::Client(EQStreamInterface *ieqs) : Mob(
consent_throttle_timer(2000),
tmSitting(0),
parcel_timer(RuleI(Parcel, ParcelDeliveryDelay)),
lazy_load_bank_check_timer(1000)
lazy_load_bank_check_timer(1000),
bandolier_throttle_timer(0)
{
for (auto client_filter = FilterNone; client_filter < _FilterCount; client_filter = eqFilterType(client_filter + 1)) {
SetFilter(client_filter, FilterShow);
@ -12706,3 +12707,26 @@ bool Client::TakeMoneyFromPPWithOverFlow(uint64 copper, bool update_client)
RecalcWeight();
return true;
}
void Client::SendTopLevelInventory()
{
EQ::ItemInstance* inst = nullptr;
static const int16 slots[][2] = {
{ EQ::invslot::POSSESSIONS_BEGIN, EQ::invslot::POSSESSIONS_END },
{ EQ::invbag::GENERAL_BAGS_BEGIN, EQ::invbag::GENERAL_BAGS_END },
{ EQ::invbag::CURSOR_BAG_BEGIN, EQ::invbag::CURSOR_BAG_END }
};
const auto& inv = GetInv();
const size_t slot_index_count = sizeof(slots) / sizeof(slots[0]);
for (int slot_index = 0; slot_index < slot_index_count; ++slot_index) {
for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) {
inst = inv.GetItem(slot_id);
if (inst) {
SendItemPacket(slot_id, inst, ItemPacketType::ItemPacketTrade);
}
}
}
}

View File

@ -2012,6 +2012,8 @@ private:
void ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm);
void ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
void SendTopLevelInventory();
glm::vec4 m_ZoneSummonLocation;
uint16 zonesummon_id;
uint8 zonesummon_ignorerestrictions;
@ -2057,6 +2059,7 @@ private:
Timer pick_lock_timer;
Timer parcel_timer; //Used to limit the number of parcels to one every 30 seconds (default). Changable via rule.
Timer lazy_load_bank_check_timer;
Timer bandolier_throttle_timer;
bool m_lazy_load_bank = false;
int m_lazy_load_sent_bank_slots = 0;

View File

@ -3642,29 +3642,39 @@ void Client::Handle_OP_AutoFire(const EQApplicationPacket *app)
void Client::Handle_OP_Bandolier(const EQApplicationPacket *app)
{
// Although there are three different structs for OP_Bandolier, they are all the same size.
//
if (app->size != sizeof(BandolierCreate_Struct)) {
LogDebug("Size mismatch in OP_Bandolier expected [{}] got [{}]", sizeof(BandolierCreate_Struct), app->size);
DumpPacket(app);
return;
}
BandolierCreate_Struct *bs = (BandolierCreate_Struct*)app->pBuffer;
auto bs = (BandolierCreate_Struct*) app->pBuffer;
switch (bs->Action)
{
case bandolierCreate:
CreateBandolier(app);
break;
case bandolierRemove:
RemoveBandolier(app);
break;
case bandolierSet:
SetBandolier(app);
break;
default:
LogDebug("Unknown Bandolier action [{}]", bs->Action);
break;
switch (bs->Action) {
case bandolierCreate:
CreateBandolier(app);
break;
case bandolierRemove:
RemoveBandolier(app);
break;
case bandolierSet:
if (bandolier_throttle_timer.GetDuration() && !bandolier_throttle_timer.Check()) {
Message(
Chat::White,
fmt::format(
"You may only modify your bandolier once every {}.",
Strings::ToLower(Strings::MillisecondsToTime(RuleI(Character, BandolierSwapDelay)))
).c_str()
);
SendTopLevelInventory();
break;
}
SetBandolier(app);
break;
default:
LogDebug("Unknown Bandolier action [{}]", bs->Action);
break;
}
}

View File

@ -3431,6 +3431,11 @@ void Client::SetBandolier(const EQApplicationPacket *app)
}
}
}
if (RuleI(Character, BandolierSwapDelay) > 0) {
bandolier_throttle_timer.Start(RuleI(Character, BandolierSwapDelay));
}
// finally, recalculate any stat bonuses from the item change
CalcBonuses();
}
@ -4913,4 +4918,4 @@ bool Client::FindNumberOfFreeInventorySlotsWithSizeCheck(std::vector<BuyerLineTr
}
}
return false;
};
};