mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-30 11:45:46 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a7550fbd9e | |||
| cc0171dfe1 | |||
| 913c5da70f | |||
| 40fecbfaf5 | |||
| b1646381b0 | |||
| bb1578796b | |||
| 0e5a38f072 | |||
| 39876ab858 | |||
| ff16a76481 |
@@ -1,3 +1,29 @@
|
||||
## [22.56.0] 9/12/2024
|
||||
|
||||
### Code
|
||||
|
||||
* Add IsCloseToBanker method ([#4462](https://github.com/EQEmu/Server/pull/4462)) @Akkadius 2024-08-27
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Rule to Limit Task Update Messages ([#4459](https://github.com/EQEmu/Server/pull/4459)) @Kinglykrab 2024-08-28
|
||||
* Allow NPCs to cast Sacrifice ([#4470](https://github.com/EQEmu/Server/pull/4470)) @fuzzlecutter 2024-09-12
|
||||
* Lazy Load Bank Contents ([#4453](https://github.com/EQEmu/Server/pull/4453)) @catapultam-habeo 2024-08-27
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add RULE_STRING to RuleManager::ResetRules ([#4467](https://github.com/EQEmu/Server/pull/4467)) @Kinglykrab 2024-09-07
|
||||
* Fix Bard Effect in Migration 9237 ([#4468](https://github.com/EQEmu/Server/pull/4468)) @Kinglykrab 2024-09-09
|
||||
* ModernAAScalingEnabled() Calculation Error ([#4469](https://github.com/EQEmu/Server/pull/4469)) @carolus21rex 2024-09-11
|
||||
|
||||
### Performance
|
||||
|
||||
* Move Discipline Loading to Client::CompleteConnect() ([#4466](https://github.com/EQEmu/Server/pull/4466)) @Kinglykrab 2024-09-09
|
||||
|
||||
### Rules
|
||||
|
||||
* Add a Bandolier Swap Delay Rule ([#4465](https://github.com/EQEmu/Server/pull/4465)) @Kinglykrab 2024-09-08
|
||||
|
||||
## [22.55.1] 8/26/2024
|
||||
|
||||
### Code
|
||||
|
||||
@@ -4947,7 +4947,7 @@ UPDATE `aa_ability` SET `auto_grant_enabled` = 1 WHERE `grant_only` = 0 AND `cha
|
||||
.version = 9237,
|
||||
.description = "2023_10_15_import_13th_floor.sql",
|
||||
.check = "SHOW COLUMNS FROM `items` LIKE 'bardeffect';",
|
||||
.condition = "contains",
|
||||
.condition = "missing",
|
||||
.match = "mediumint",
|
||||
.sql = R"(
|
||||
ALTER TABLE `items`
|
||||
|
||||
@@ -189,6 +189,8 @@ void RuleManager::ResetRules(bool reload) {
|
||||
m_RuleRealValues[ Real__##rule_name ] = default_value;
|
||||
#define RULE_BOOL(category_name, rule_name, default_value, notes) \
|
||||
m_RuleBoolValues[ Bool__##rule_name ] = default_value;
|
||||
#define RULE_STRING(category_name, rule_name, default_value, notes) \
|
||||
m_RuleStringValues[ String__##rule_name ] = default_value;
|
||||
#include "ruletypes.h"
|
||||
|
||||
// restore these rules to their pre-reset values
|
||||
|
||||
@@ -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)
|
||||
@@ -715,6 +716,7 @@ RULE_BOOL(TaskSystem, ExpRewardsIgnoreLevelBasedEXPMods, false, "Rewarding Level
|
||||
RULE_INT(TaskSystem, SharedTasksWorldProcessRate, 6000, "Timer interval (milliseconds) that shared tasks are processed in world")
|
||||
RULE_INT(TaskSystem, SharedTasksTerminateTimerMS, 120000, "Delay (milliseconds) until a shared task is terminated if requirements are no longer met after member removal (default: 2 minutes)")
|
||||
RULE_BOOL(TaskSystem, UpdateOneElementPerTask, true, "If true (live-like) task updates only increment the first matching activity. If false all matching elements will be incremented.")
|
||||
RULE_INT(TaskSystem, MaxUpdateMessages, 50, "Maximum update messages for non-GiveCash activity types in IncrementDoneCount")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Range)
|
||||
@@ -909,6 +911,7 @@ RULE_BOOL(Inventory, AllowAnyWeaponTransformation, false, "Weapons can use any w
|
||||
RULE_BOOL(Inventory, TransformSummonedBags, false, "Transforms summoned bags into disenchanted ones instead of deleting")
|
||||
RULE_BOOL(Inventory, AllowMultipleOfSameAugment, false, "Allows multiple of the same augment to be placed in an item via #augmentitem or MQ2, set to true to allow")
|
||||
RULE_INT(Inventory, AlternateAugmentationSealer, 53, "Allows RoF+ clients to augment items from a special container type")
|
||||
RULE_BOOL(Inventory, LazyLoadBank, true, "Don't load bank during zoning, only when in proximinity to a banker. May increase zone speed and stability")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Client)
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
|
||||
// Build variables
|
||||
// these get injected during the build pipeline
|
||||
#define CURRENT_VERSION "22.55.1-dev" // always append -dev to the current version for custom-builds
|
||||
#define CURRENT_VERSION "22.56.0-dev" // always append -dev to the current version for custom-builds
|
||||
#define LOGIN_VERSION "0.8.0"
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eqemu-server",
|
||||
"version": "22.55.1",
|
||||
"version": "22.56.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EQEmu/Server.git"
|
||||
|
||||
+36
-8
@@ -185,7 +185,9 @@ Client::Client(EQStreamInterface *ieqs) : Mob(
|
||||
position_update_timer(10000),
|
||||
consent_throttle_timer(2000),
|
||||
tmSitting(0),
|
||||
parcel_timer(RuleI(Parcel, ParcelDeliveryDelay))
|
||||
parcel_timer(RuleI(Parcel, ParcelDeliveryDelay)),
|
||||
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);
|
||||
@@ -284,6 +286,7 @@ Client::Client(EQStreamInterface *ieqs) : Mob(
|
||||
memset(&m_epp, 0, sizeof(m_epp));
|
||||
PendingTranslocate = false;
|
||||
PendingSacrifice = false;
|
||||
sacrifice_caster_id = 0;
|
||||
controlling_boat_id = 0;
|
||||
controlled_mob_id = 0;
|
||||
qGlobals = nullptr;
|
||||
@@ -391,7 +394,6 @@ Client::Client(EQStreamInterface *ieqs) : Mob(
|
||||
SetBotPrecombat(false);
|
||||
|
||||
AI_Init();
|
||||
|
||||
}
|
||||
|
||||
Client::~Client() {
|
||||
@@ -3970,7 +3972,7 @@ void Client::SetEndurance(int32 newEnd)
|
||||
CheckManaEndUpdate();
|
||||
}
|
||||
|
||||
void Client::SacrificeConfirm(Client *caster)
|
||||
void Client::SacrificeConfirm(Mob *caster)
|
||||
{
|
||||
auto outapp = new EQApplicationPacket(OP_Sacrifice, sizeof(Sacrifice_Struct));
|
||||
Sacrifice_Struct *ss = (Sacrifice_Struct *)outapp->pBuffer;
|
||||
@@ -3997,14 +3999,14 @@ void Client::SacrificeConfirm(Client *caster)
|
||||
ss->Confirm = 0;
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
// We store the Caster's name, because when the packet comes back, it only has the victim's entityID in it,
|
||||
// We store the Caster's id, because when the packet comes back, it only has the victim's entityID in it,
|
||||
// not the caster.
|
||||
SacrificeCaster += caster->GetName();
|
||||
sacrifice_caster_id = caster->GetID();
|
||||
PendingSacrifice = true;
|
||||
}
|
||||
|
||||
//Essentially a special case death function
|
||||
void Client::Sacrifice(Client *caster)
|
||||
void Client::Sacrifice(Mob *caster)
|
||||
{
|
||||
if (GetLevel() >= RuleI(Spells, SacrificeMinLevel) && GetLevel() <= RuleI(Spells, SacrificeMaxLevel)) {
|
||||
int exploss = (int)(GetLevel() * (GetLevel() / 18.0) * 12000);
|
||||
@@ -4052,8 +4054,11 @@ void Client::Sacrifice(Client *caster)
|
||||
}
|
||||
Save();
|
||||
GoToDeath();
|
||||
if (caster) // I guess it's possible?
|
||||
caster->SummonItem(RuleI(Spells, SacrificeItemID));
|
||||
if (caster && caster->IsClient()) {
|
||||
caster->CastToClient()->SummonItem(RuleI(Spells, SacrificeItemID));
|
||||
} else if (caster && caster->IsNPC()) {
|
||||
caster->CastToNPC()->AddItem(RuleI(Spells, SacrificeItemID), 1, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
caster->MessageString(Chat::Red, SAC_TOO_LOW); // This being is not a worthy sacrifice.
|
||||
@@ -12706,3 +12711,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-4
@@ -762,8 +762,8 @@ public:
|
||||
void GetRaidAAs(RaidLeadershipAA_Struct *into) const;
|
||||
void ClearGroupAAs();
|
||||
void UpdateGroupAAs(int32 points, uint32 type);
|
||||
void SacrificeConfirm(Client* caster);
|
||||
void Sacrifice(Client* caster);
|
||||
void SacrificeConfirm(Mob* caster);
|
||||
void Sacrifice(Mob* caster);
|
||||
void GoToDeath();
|
||||
inline const int32 GetInstanceID() const { return zone->GetInstanceID(); }
|
||||
void SetZoning(bool in) { bZoning = in; }
|
||||
@@ -1245,7 +1245,7 @@ public:
|
||||
bool PendingTranslocate;
|
||||
time_t TranslocateTime;
|
||||
bool PendingSacrifice;
|
||||
std::string SacrificeCaster;
|
||||
uint16 sacrifice_caster_id;
|
||||
PendingTranslocate_Struct PendingTranslocateData;
|
||||
void SendOPTranslocateConfirm(Mob *Caster, uint16 SpellID);
|
||||
|
||||
@@ -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;
|
||||
@@ -2056,6 +2058,11 @@ private:
|
||||
Timer task_request_timer;
|
||||
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;
|
||||
|
||||
glm::vec3 m_Proximity;
|
||||
glm::vec4 last_position_before_bulk_update;
|
||||
@@ -2175,7 +2182,6 @@ private:
|
||||
bool m_has_quest_compass = false;
|
||||
std::vector<uint32_t> m_dynamic_zone_ids;
|
||||
|
||||
|
||||
public:
|
||||
enum BotOwnerOption : size_t {
|
||||
booDeathMarquee,
|
||||
|
||||
+29
-19
@@ -934,6 +934,7 @@ void Client::CompleteConnect()
|
||||
}
|
||||
|
||||
database.LoadAuras(this); // this ends up spawning them so probably safer to load this later (here)
|
||||
database.LoadCharacterDisciplines(this);
|
||||
|
||||
entity_list.RefreshClientXTargets(this);
|
||||
|
||||
@@ -1318,7 +1319,6 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
database.LoadCharacterInspectMessage(cid, &m_inspect_message); /* Load Character Inspect Message */
|
||||
database.LoadCharacterSpellBook(cid, &m_pp); /* Load Character Spell Book */
|
||||
database.LoadCharacterMemmedSpells(cid, &m_pp); /* Load Character Memorized Spells */
|
||||
database.LoadCharacterDisciplines(cid, &m_pp); /* Load Character Disciplines */
|
||||
database.LoadCharacterLanguages(cid, &m_pp); /* Load Character Languages */
|
||||
database.LoadCharacterLeadershipAbilities(cid, &m_pp); /* Load Character Leadership AA's */
|
||||
database.LoadCharacterTribute(this); /* Load CharacterTribute */
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13671,11 +13681,11 @@ void Client::Handle_OP_Sacrifice(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
if (ss->Confirm) {
|
||||
Client *Caster = entity_list.GetClientByName(SacrificeCaster.c_str());
|
||||
Mob *Caster = entity_list.GetMob(sacrifice_caster_id);
|
||||
if (Caster) Sacrifice(Caster);
|
||||
}
|
||||
PendingSacrifice = false;
|
||||
SacrificeCaster.clear();
|
||||
sacrifice_caster_id = 0;
|
||||
}
|
||||
|
||||
void Client::Handle_OP_SafeFallSuccess(const EQApplicationPacket *app) // bit of a misnomer, sent whenever safe fall is used (success of fail)
|
||||
|
||||
+58
-25
@@ -289,6 +289,37 @@ bool Client::Process() {
|
||||
entity_list.ScanCloseMobs(close_mobs, this, IsMoving());
|
||||
}
|
||||
|
||||
if (RuleB(Inventory, LazyLoadBank)) {
|
||||
// poll once a second to see if we are close to a banker and we haven't loaded the bank yet
|
||||
if (!m_lazy_load_bank && lazy_load_bank_check_timer.Check()) {
|
||||
if (m_lazy_load_sent_bank_slots <= EQ::invslot::SHARED_BANK_END && IsCloseToBanker()) {
|
||||
m_lazy_load_bank = true;
|
||||
lazy_load_bank_check_timer.Disable();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_lazy_load_bank && m_lazy_load_sent_bank_slots <= EQ::invslot::SHARED_BANK_END) {
|
||||
const EQ::ItemInstance *inst = nullptr;
|
||||
|
||||
// Jump the gaps
|
||||
if (m_lazy_load_sent_bank_slots < EQ::invslot::BANK_BEGIN) {
|
||||
m_lazy_load_sent_bank_slots = EQ::invslot::BANK_BEGIN;
|
||||
}
|
||||
else if (m_lazy_load_sent_bank_slots > EQ::invslot::BANK_END &&
|
||||
m_lazy_load_sent_bank_slots < EQ::invslot::SHARED_BANK_BEGIN) {
|
||||
m_lazy_load_sent_bank_slots = EQ::invslot::SHARED_BANK_BEGIN;
|
||||
}
|
||||
else {
|
||||
m_lazy_load_sent_bank_slots++;
|
||||
}
|
||||
|
||||
inst = m_inv[m_lazy_load_sent_bank_slots];
|
||||
if (inst) {
|
||||
SendItemPacket(m_lazy_load_sent_bank_slots, inst, ItemPacketType::ItemPacketTrade);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool may_use_attacks = false;
|
||||
/*
|
||||
Things which prevent us from attacking:
|
||||
@@ -780,39 +811,41 @@ void Client::BulkSendInventoryItems()
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
|
||||
// Bank items
|
||||
for (int16 slot_id = EQ::invslot::BANK_BEGIN; slot_id <= EQ::invslot::BANK_END; slot_id++) {
|
||||
const EQ::ItemInstance* inst = m_inv[slot_id];
|
||||
if (!inst)
|
||||
continue;
|
||||
if (!RuleB(Inventory, LazyLoadBank)) {
|
||||
// Bank items
|
||||
for (int16 slot_id = EQ::invslot::BANK_BEGIN; slot_id <= EQ::invslot::BANK_END; slot_id++) {
|
||||
const EQ::ItemInstance* inst = m_inv[slot_id];
|
||||
if (!inst)
|
||||
continue;
|
||||
|
||||
inst->Serialize(ob, slot_id);
|
||||
inst->Serialize(ob, slot_id);
|
||||
|
||||
if (ob.tellp() == last_pos)
|
||||
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
||||
if (ob.tellp() == last_pos)
|
||||
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
|
||||
// SharedBank items
|
||||
for (int16 slot_id = EQ::invslot::SHARED_BANK_BEGIN; slot_id <= EQ::invslot::SHARED_BANK_END; slot_id++) {
|
||||
const EQ::ItemInstance* inst = m_inv[slot_id];
|
||||
if (!inst)
|
||||
continue;
|
||||
// SharedBank items
|
||||
for (int16 slot_id = EQ::invslot::SHARED_BANK_BEGIN; slot_id <= EQ::invslot::SHARED_BANK_END; slot_id++) {
|
||||
const EQ::ItemInstance* inst = m_inv[slot_id];
|
||||
if (!inst)
|
||||
continue;
|
||||
|
||||
inst->Serialize(ob, slot_id);
|
||||
inst->Serialize(ob, slot_id);
|
||||
|
||||
if (ob.tellp() == last_pos)
|
||||
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
||||
if (ob.tellp() == last_pos)
|
||||
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
}
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_CharInventory);
|
||||
outapp->size = ob.size();
|
||||
outapp->pBuffer = ob.detach();
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
auto outapp = new EQApplicationPacket(OP_CharInventory);
|
||||
outapp->size = ob.size();
|
||||
outapp->pBuffer = ob.detach();
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||
|
||||
+1
-1
@@ -527,7 +527,7 @@ void Client::AddEXP(ExpSource exp_source, uint64 in_add_exp, uint8 conlevel, boo
|
||||
// Are we also doing linear AA acceleration?
|
||||
if (RuleB(AA, ModernAAScalingEnabled) && aaexp > 0)
|
||||
{
|
||||
aaexp = ScaleAAXPBasedOnCurrentAATotal(GetAAPoints(), aaexp);
|
||||
aaexp = ScaleAAXPBasedOnCurrentAATotal(GetSpentAA() + GetAAPoints(), aaexp);
|
||||
}
|
||||
|
||||
// Check for AA XP Cap
|
||||
|
||||
+6
-1
@@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2202,10 +2202,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
snprintf(effect_desc, _EDLEN, "Sacrifice");
|
||||
#endif
|
||||
if(!caster || !IsClient() || !caster->IsClient()){
|
||||
if(!caster || !IsClient() ){
|
||||
break;
|
||||
}
|
||||
CastToClient()->SacrificeConfirm(caster->CastToClient());
|
||||
CastToClient()->SacrificeConfirm(caster);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -869,7 +869,12 @@ int ClientTaskState::IncrementDoneCount(
|
||||
if (task_data->type != TaskType::Shared) {
|
||||
// live messages for each increment of non-shared tasks
|
||||
auto activity_type = task_data->activity_information[activity_id].activity_type;
|
||||
int msg_count = activity_type == TaskActivityType::GiveCash ? 1 : count;
|
||||
int msg_count = 1;
|
||||
|
||||
if (activity_type != TaskActivityType::GiveCash) {
|
||||
msg_count = std::min(count, RuleI(TaskSystem, MaxUpdateMessages));
|
||||
}
|
||||
|
||||
for (int i = 0; i < msg_count; ++i) {
|
||||
client->MessageString(Chat::DefaultText, TASK_UPDATED, task_data->title.c_str());
|
||||
}
|
||||
|
||||
+11
-5
@@ -671,12 +671,16 @@ bool ZoneDatabase::LoadCharacterLeadershipAbilities(uint32 character_id, PlayerP
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::LoadCharacterDisciplines(uint32 character_id, PlayerProfile_Struct* pp){
|
||||
bool ZoneDatabase::LoadCharacterDisciplines(Client* c)
|
||||
{
|
||||
if (!c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& l = CharacterDisciplinesRepository::GetWhere(
|
||||
database, fmt::format(
|
||||
"`id` = {} ORDER BY `slot_id`",
|
||||
character_id
|
||||
c->CharacterID()
|
||||
)
|
||||
);
|
||||
|
||||
@@ -684,16 +688,18 @@ bool ZoneDatabase::LoadCharacterDisciplines(uint32 character_id, PlayerProfile_S
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int slot_id = 0; slot_id < MAX_PP_DISCIPLINES; slot_id++) { // Initialize Disciplines
|
||||
pp->disciplines.values[slot_id] = 0;
|
||||
for (int slot_id = 0; slot_id < MAX_PP_DISCIPLINES; slot_id++) {
|
||||
c->GetPP().disciplines.values[slot_id] = 0;
|
||||
}
|
||||
|
||||
for (const auto& e : l) {
|
||||
if (IsValidSpell(e.disc_id) && e.slot_id < MAX_PP_DISCIPLINES) {
|
||||
pp->disciplines.values[e.slot_id] = e.disc_id;
|
||||
c->GetPP().disciplines.values[e.slot_id] = e.disc_id;
|
||||
}
|
||||
}
|
||||
|
||||
c->SendDisciplineUpdate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -436,7 +436,7 @@ public:
|
||||
bool LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
bool LoadCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
bool LoadCharacterData(uint32 character_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp);
|
||||
bool LoadCharacterDisciplines(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
bool LoadCharacterDisciplines(Client* c);
|
||||
bool LoadCharacterFactionValues(uint32 character_id, faction_map & val_list);
|
||||
bool LoadCharacterLanguages(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
bool LoadCharacterLeadershipAbilities(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
|
||||
Reference in New Issue
Block a user