Compare commits

...

196 Commits

Author SHA1 Message Date
Paul Coene 75391d96f4 [Release] 22.13.1 (#3406)
* Update version.h for /target Emergency release 22.13.1

* Update CHANGELOG.md for 22.13.1 release

* Update package.json for 22.13.1 emergency patch release

* Update CHANGELOG.md using tool as instructed
2023-06-13 17:50:33 -04:00
Paul Coene 81b07a5aa0 [Targeting] Revert #3383 (#3405) 2023-06-13 15:48:35 -05:00
Alex King 774aa99b29 [Release] 22.13.0 (#3404)
* [Release] 22.13.0

* Update CHANGELOG.md
2023-06-12 20:56:43 -04:00
Alex King 756e835144 [Quest API/Cleanup] Add several spell methods to Perl/Lua (#3379)
* [Quest API/Cleanup] Add several spell methods to Perl/Lua

- Add `quest::CalculateCorruptionCounters(spell_id)`.
- Add `quest::CalculateCounters(spell_id)`.
- Add `quest::CalculateCurseCounters(spell_id)`.
- Add `quest::CalculateDiseaseCounters(spell_id)`.
- Add `quest::CalculatePoisonCounters(spell_id)`.
- Add `quest::GetSpellEffectDescriptionNumber(spell_id)`.
- Add `quest::GetSpellEffectIndex(spell_id, effect_id)`.
- Add `quest::GetSpellFuriousBash(spell_id)`.
- Add `quest::GetSpellMinimumLevel(spell_id)`.
- Add `quest::GetSpellNimbusEffect(spell_id)`.
- Add `quest::GetSpellPartialMagicRuneAmount(spell_id)`.
- Add `quest::GetSpellPartialMagicRuneReduction(spell_id)`.
- Add `quest::GetSpellPartialMeleeRuneAmount(spell_id)`.
- Add `quest::GetSpellPartialMeleeRuneReduction(spell_id)`.
- Add `quest::GetSpellProcLimitTimer(spell_id)`.
- Add `quest::GetSpellResistType(spell_id)`.
- Add `quest::GetSpellResurrectionSicknessCheck(spell_id_one, spell_id_two)`.
- Add `quest::GetSpellTargetType(spell_id)`.
- Add `quest::GetSpellTriggerSpellID(spell_id)`.
- Add `quest::GetSpellViralMaximumSpreadTime(spell_id)`.
- Add `quest::GetSpellViralMinimumSpreadTime(spell_id)`.
- Add `quest::GetSpellViralSpreadRange(spell_id)`.
- Add `quest::IsAEDurationSpell(spell_id)`.
- Add `quest::IsAENukeSpell(spell_id)`.
- Add `quest::IsAERainNukeSpell(spell_id)`.
- Add `quest::IsAllianceSpell(spell_id)`.
- Add `quest::IsBardOnlyStackEffect(effect_id)`.
- Add `quest::IsBardSong(spell_id)`.
- Add `quest::IsBlankSpellEffect(spell_id, effect_index)`.
- Add `quest::IsBlindSpell(spell_id)`.
- Add `quest::IsBuffSpell(spell_id)`.
- Add `quest::IsCastNotStandingSpell(spell_id)`.
- Add `quest::IsCastOnFadeDurationSpell(spell_id)`.
- Add `quest::IsCastRestrictedSpell(spell_id)`.
- Add `quest::IsCastTimeReductionSpell(spell_id)`.
- Add `quest::IsCastWhileInvisibleSpell(spell_id)`.
- Add `quest::IsCharmSpell(spell_id)`.
- Add `quest::IsCombatSkill(spell_id)`.
- Add `quest::IsCompleteHealDurationSpell(spell_id)`.
- Add `quest::IsCompleteHealSpell(spell_id)`.
- Add `quest::IsCureSpell(spell_id)`.
- Add `quest::IsDamageSpell(spell_id)`.
- Add `quest::IsDeathSaveSpell(spell_id)`.
- Add `quest::IsDebuffSpell(spell_id)`.
- Add `quest::IsDetrimentalSpell(spell_id)`.
- Add `quest::IsDiscipline(spell_id)`.
- Add `quest::IsDisciplineBuff(spell_id)`.
- Add `quest::IsDiseaseCounterSpell(spell_id)`.
- Add `quest::IsDistanceModifierSpell(spell_id)`.
- Add `quest::IsEffectIgnoredInStacking(effect_id)`.
- Add `quest::IsFastHealSpell(spell_id)`.
- Add `quest::IsFearSpell(spell_id)`.
- Add `quest::IsFocusLimit(effect_id)`.
- Add `quest::IsFullDeathSaveSpell(spell_id)`.
- Add `quest::IsGateSpell(spell_id)`.
- Add `quest::IsImprovedDamageSpell(spell_id)`.
- Add `quest::IsImprovedHealingSpell(spell_id)`.
- Add `quest::IsIncreaseDurationSpell(spell_id)`.
- Add `quest::IsIncreaseRangeSpell(spell_id)`.
- Add `quest::IsInstrumentModifierAppliedToSpellEffect(spell_id, effect_id)`.
- Add `quest::IsInvisibleSpell(spell_id)`.
- Add `quest::IsInvulnerabilitySpell(spell_id)`.
- Add `quest::IsLDoNObjectSpell(spell_id)`.
- Add `quest::IsLifetapSpell(spell_id)`.
- Add `quest::IsMagicRuneSpell(spell_id)`.
- Add `quest::IsManaCostReductionSpell(spell_id)`.
- Add `quest::IsManaTapSpell(spell_id)`.
- Add `quest::IsMesmerizeSpell(spell_id)`.
- Add `quest::IsNoDetrimentalSpellAggroSpell(spell_id)`.
- Add `quest::IsPBAENukeSpell(spell_id)`.
- Add `quest::IsPartialDeathSaveSpell(spell_id)`.
- Add `quest::IsPartialResistableSpell(spell_id)`.
- Add `quest::IsPercentalHealSpell(spell_id)`.
- Add `quest::IsPersistDeathSpell(spell_id)`.
- Add `quest::IsPetSpell(spell_id)`.
- Add `quest::IsPoisonCounterSpell(spell_id)`.
- Add `quest::IsPulsingBardSong(spell_id)`.
- Add `quest::IsPureNukeSpell(spell_id)`.
- Add `quest::IsRegularGroupHealSpell(spell_id)`.
- Add `quest::IsRegularSingleTargetHealSpell(spell_id)`.
- Add `quest::IsResistDebuffSpell(spell_id)`.
- Add `quest::IsResistableSpell(spell_id)`.
- Add `quest::IsRestAllowedSpell(spell_id)`.
- Add `quest::IsResurrectionEffects(spell_id)`.
- Add `quest::IsRuneSpell(spell_id)`.
- Add `quest::IsRunning(spell_id)`.
- Add `quest::IsSacrificeSpell(spell_id)`.
- Add `quest::IsSelfConversionSpell(spell_id)`.
- Add `quest::IsShadowStepSpell(spell_id)`.
- Add `quest::IsShortDurationBuff(spell_id)`.
- Add `quest::IsSpellUsableInThisZoneType(spell_id)`.
- Add `quest::IsSpellUsableInThisZoneType(spell_id, zone_type)`.
- Add `quest::IsStackableDOT(spell_id)`.
- Add `quest::IsStunSpell(spell_id)`.
- Add `quest::IsSuccorSpell(spell_id)`.
- Add `quest::IsSummonItemSpell(spell_id)`.
- Add `quest::IsSummonPCSpell(spell_id)`.
- Add `quest::IsSummonPetSpell(spell_id)`.
- Add `quest::IsSummonSkeletonSpell(spell_id)`.
- Add `quest::IsSummonSpell(spell_id)`.
- Add `quest::IsSuspendableSpell(spell_id)`.
- Add `quest::IsTargetRequiredForSpell(spell_id)`.
- Add `quest::IsTargetableAESpell(spell_id)`.
- Add `quest::IsTeleportSpell(spell_id)`.
- Add `quest::IsTranslocateSpell(spell_id)`.
- Add `quest::IsValidSpell(spell_id)`.
- Add `quest::IsVeryFastHealSpell(spell_id)`.
- Add `quest::IsVirusSpell(spell_id)`.

- Add `eq.calculate_corruption_counters(spell_id)`.
- Add `eq.calculate_counters(spell_id)`.
- Add `eq.calculate_curse_counters(spell_id)`.
- Add `eq.calculate_disease_counters(spell_id)`.
- Add `eq.calculate_poison_counters(spell_id)`.
- Add `eq.get_spell_effect_description_number(spell_id)`.
- Add `eq.get_spell_effect_index(spell_id, effect_id)`.
- Add `eq.get_spell_furious_bash(spell_id)`.
- Add `eq.get_spell_level(spell_id, class_id)`.
- Add `eq.get_spell_minimum_level(spell_id)`.
- Add `eq.get_spell_nimbus_effect(spell_id)`.
- Add `eq.get_spell_partial_magic_rune_amount(spell_id)`.
- Add `eq.get_spell_partial_magic_rune_reduction(spell_id)`.
- Add `eq.get_spell_partial_melee_rune_amount(spell_id)`.
- Add `eq.get_spell_partial_melee_rune_reduction(spell_id)`.
- Add `eq.get_spell_proc_limit_timer(spell_id)`.
- Add `eq.get_spell_resist_type(spell_id)`.
- Add `eq.get_spell_resurrection_sickness_check(spell_id_one, spell_id_two)`.
- Add `eq.get_spell_target_type(spell_id)`.
- Add `eq.get_spell_trigger_spell_id(spell_id)`.
- Add `eq.get_spell_viral_maximum_spread_time(spell_id)`.
- Add `eq.get_spell_viral_minimum_spread_time(spell_id)`.
- Add `eq.get_spell_viral_spread_range(spell_id)`.
- Add `eq.is_ae_duration_spell(spell_id)`.
- Add `eq.is_ae_nuke_spell(spell_id)`.
- Add `eq.is_ae_rain_nuke_spell(spell_id)`.
- Add `eq.is_alliance_spell(spell_id)`.
- Add `eq.is_bard_only_stack_effect(spell_id)`.
- Add `eq.is_bard_song(spell_id)`.
- Add `eq.is_beneficial_spell(spell_id)`.
- Add `eq.is_blank_spell_effect(spell_id)`.
- Add `eq.is_blind_spell(spell_id)`.
- Add `eq.is_buff_spell(spell_id)`.
- Add `eq.is_cast_not_standing_spell(spell_id)`.
- Add `eq.is_cast_on_fade_duration_spell(spell_id)`.
- Add `eq.is_cast_restricted_spell(spell_id)`.
- Add `eq.is_cast_time_reduction_spell(spell_id)`.
- Add `eq.is_cast_while_invisible_spell(spell_id)`.
- Add `eq.is_charm_spell(spell_id)`.
- Add `eq.is_combat_skill(spell_id)`.
- Add `eq.is_complete_heal_duration_spell(spell_id)`.
- Add `eq.is_complete_heal_spell(spell_id)`.
- Add `eq.is_cure_spell(spell_id)`.
- Add `eq.is_damage_spell(spell_id)`.
- Add `eq.is_death_save_spell(spell_id)`.
- Add `eq.is_debuff_spell(spell_id)`.
- Add `eq.is_detrimental_spell(spell_id)`.
- Add `eq.is_discipline(spell_id)`.
- Add `eq.is_discipline_buff(spell_id)`.
- Add `eq.is_disease_counter_spell(spell_id)`.
- Add `eq.is_distance_modifier_spell(spell_id)`.
- Add `eq.is_effect_ignored_in_stacking(effect_id)`.
- Add `eq.is_effect_in_spell(spell_id, effect_id)`.
- Add `eq.is_fast_heal_spell(spell_id)`.
- Add `eq.is_fear_spell(spell_id)`.
- Add `eq.is_focus_limit(effect_id)`.
- Add `eq.is_full_death_save_spell(spell_id)`.
- Add `eq.is_gate_spell(spell_id)`.
- Add `eq.is_group_complete_heal_spell(spell_id)`.
- Add `eq.is_group_heal_over_time_spell(spell_id)`.
- Add `eq.is_group_only_spell(spell_id)`.
- Add `eq.is_group_spell(spell_id)`.
- Add `eq.is_harmony_spell(spell_id)`.
- Add `eq.is_haste_spell(spell_id)`.
- Add `eq.is_heal_over_time_spell(spell_id)`.
- Add `eq.is_health_spell(spell_id)`.
- Add `eq.is_illusion_spell(spell_id)`.
- Add `eq.is_improved_damage_spell(spell_id)`.
- Add `eq.is_improved_healing_spell(spell_id)`.
- Add `eq.is_increase_duration_spell(spell_id)`.
- Add `eq.is_increase_range_spell(spell_id)`.
- Add `eq.is_instrument_modifier_applied_to_spell_effect(spell_id, effect_id)`.
- Add `eq.is_invisible_spell(spell_id)`.
- Add `eq.is_invulnerability_spell(spell_id)`.
- Add `eq.is_ldon_object_spell(spell_id)`.
- Add `eq.is_lifetap_spell(spell_id)`.
- Add `eq.is_magic_rune_spell(spell_id)`.
- Add `eq.is_mana_cost_reduction_spell(spell_id)`.
- Add `eq.is_mana_tap_spell(spell_id)`.
- Add `eq.is_mesmerize_spell(spell_id)`.
- Add `eq.is_no_detrimental_spell_aggro_spell(spell_id)`.
- Add `eq.is_partial_death_save_spell(spell_id)`.
- Add `eq.is_partial_resistable_spell(spell_id)`.
- Add `eq.is_pbae_nuke_spell(spell_id)`.
- Add `eq.is_percental_heal_spell(spell_id)`.
- Add `eq.is_persist_death_spell(spell_id)`.
- Add `eq.is_pet_spell(spell_id)`.
- Add `eq.is_poison_counter_spell(spell_id)`.
- Add `eq.is_pulsing_bard_song(spell_id)`.
- Add `eq.is_pure_nuke_spell(spell_id)`.
- Add `eq.is_regular_group_heal_spell(spell_id)`.
- Add `eq.is_regular_single_target_heal_spell(spell_id)`.
- Add `eq.is_resist_debuff_spell(spell_id)`.
- Add `eq.is_resistable_spell(spell_id)`.
- Add `eq.is_rest_allowed_spell(spell_id)`.
- Add `eq.is_resurrection_effects(spell_id)`.
- Add `eq.is_rune_spell(spell_id)`.
- Add `eq.is_sacrifice_spell(spell_id)`.
- Add `eq.is_self_conversion_spell(spell_id)`.
- Add `eq.is_shadow_step_spell(spell_id)`.
- Add `eq.is_short_duration_buff(spell_id)`.
- Add `eq.is_spell_usable_in_this_zone_type(spell_id)`.
- Add `eq.is_spell_usable_in_this_zone_type(spell_id, zone_type)`.
- Add `eq.is_stackable_dot(spell_id)`.
- Add `eq.is_stun_spell(spell_id)`.
- Add `eq.is_succor_spell(spell_id)`.
- Add `eq.is_summon_item_spell(spell_id)`.
- Add `eq.is_summon_pc_spell(spell_id)`.
- Add `eq.is_summon_pet_spell(spell_id)`.
- Add `eq.is_summon_skeleton_spell(spell_id)`.
- Add `eq.is_summon_spell(spell_id)`.
- Add `eq.is_suspendable_spell(spell_id)`.
- Add `eq.is_target_required_for_spell(spell_id)`.
- Add `eq.is_targetable_ae_spell(spell_id)`.
- Add `eq.is_teleport_spell(spell_id)`.
- Add `eq.is_tgb_compatible_spell(spell_id)`.
- Add `eq.is_translocate_spell(spell_id)`.
- Add `eq.is_valid_spell(spell_id)`.
- Add `eq.is_very_fast_heal_spell(spell_id)`.
- Add `eq.is_virus_spell(spell_id)`.

- A lot of cleanup in the logic and naming of these methods was done.
- Missing GM restricted spells like Guide spells and GM Health buffs were added as defines.
- Good effect values were added as defines.
- Resurrection effects non-stacking value was added as a define.
- Max fast heal casting time and max very fast heal casting time were added as defines.
- `SE_Display` was uncommented so we could use it instead of the magic number `425`.
- `IsEvacSpell(spell_id)` was removed as it was unnecessary since `IsSuccorSpell(spell_id)` checks for `SE_Succor` as well.
- `GetMorphTrigger(spell_id)` was removed as it was unused.
- `GroupOnlySpell(spell_id)` was removed as it was unnecessary since `IsGroupOnlySpell(spell_id)` exists.
- `CanUseSpell(spell_id)` was removed as it was unnecessary since `GetSpellLevel(spell_id, class_id)` exists.
- `BeneficialSpell(spell_id)` was removed as it was unnecessary since `IsBeneficialSpell(spell_id)` exists.

* Update spell_effects.cpp

* Update spdat.cpp
2023-06-12 20:27:22 -04:00
Alex King c5c575b028 [Quest API] Add GetEXPForLevel() to Perl/Lua (#3403)
# Perl
- Add `$client->GetEXPForLevel(check_level)`.

# Lua
- Add `client:GetEXPForLevel(check_level)`.

# Notes
- This allows operators to see the required experience for a level based on the client provided, this takes race/class modifiers into account as well if enabled.
2023-06-12 19:18:39 -05:00
Alex King 152e99444c [Cleanup] Remove GetClientCount() from zone/entity.cpp and zone/entity.h (#3392)
* [Cleanup] Remove GetClientCount() from zone/entity.cpp and zone/entity.h

# Notes
- This is unused.

* Update entity.cpp
2023-06-12 19:18:17 -05:00
Alex King 795df5c597 [Cleanup] Remove CountTempPets() from zone/entity.cpp and zone/entity.h (#3390)
* [Cleanup] Remove CountTempPets() from zone/entity.cpp and zone/entity.h

# Notes
- This is unused.

* Update entity.h
2023-06-12 19:17:53 -05:00
Alex King 18eff726d0 [Commands] Assign #opcode to a #reload alias (#3401)
* [Commands] Assign #opcode to a #reload alias

# Notes
- Can use `#reload opcodes

* Add ServerOP_ReloadOpcodes
2023-06-12 18:42:39 -04:00
Alex King f06a37a009 [Cleanup] Add GMFind_Struct to packet structures (#3402)
* [Cleanup] Add GMFind_Struct to packet structures

# Notes
- X and Y were swapped in GMSummon_Struct so it displayed XYZ incorrectly in /find, adding its own struct fixes this.

* Update eq_packet_structs.h

* Update eq_packet_structs.h
2023-06-12 18:35:04 -04:00
Paul Coene ae53efc52c [Targeting] /tar <bad target> should not untarget existing target (#3383)
* [Targeting] /tar <bad target> should not untarget existing target

* Forgot string Id file.

* removed unneeded this->
2023-06-12 16:40:09 -05:00
Alex King 548eb65e1d [Cleanup] Remove InteractiveChat() and TakenAction() from zone/npc.h (#3382)
# Notes
- These are unimplemented and unused.
2023-06-12 15:14:34 -05:00
Alex King fede8760d4 [Cleanup] Remove CheckCoordLosNoZLeaps() from zone/entity.cpp and zone/entity.h (#3384)
# Notes
- This is unused.
2023-06-12 15:13:03 -05:00
Alex King 6faa202b57 [Cleanup] Remove pDBAsyncWorkID from zone/entity.h (#3385)
# Notes
- This is unused.
2023-06-12 15:12:47 -05:00
Alex King c406710623 [Cleanup] Remove GetClient(ip, port) from zone/entity.h (#3386)
# Notes
- This is unused.
2023-06-12 15:12:22 -05:00
Alex King 662c4012db [Cleanup] Remove GetGroupByBot(), GetRaidByMob(), and GetRaidByLeaderName() from zone/entity.cpp and zone/entity.h (#3387)
# Notes
- These are unused.
2023-06-12 15:12:00 -05:00
Alex King 849e7b910d [Cleanup] Remove SendAATimer() from zone/entity.h (#3388)
# Notes
- This is unused.
2023-06-12 15:11:32 -05:00
Alex King 8e33755f02 [Cleanup] Remove RemoveMob() and RemoveRaid() from zone/entity.cpp and zone/entity.h (#3389)
# Notes
- These are unused.
2023-06-12 15:11:17 -05:00
Alex King dfaa929778 [Cleanup] Remove GateAllClients() from zone/entity.cpp and zone/entity.h (#3391)
# Notes
- This is unused.
2023-06-12 15:10:36 -05:00
Alex King 306b06745f [Cleanup] Remove LimitCheckBoth() from zone/entity.cpp and zone/entity.h (#3393)
# Notes
- This is unused.
2023-06-12 15:05:39 -05:00
Alex King 108fc82ee0 [Cleanup] Remove Evade() from zone/entity.cpp and zone/entity.h (#3394)
# Notes
- This is unused.
2023-06-12 15:05:23 -05:00
Alex King 577f61b082 [Cleanup] Remove WriteEntityIDs() from zone/entity.cpp and zone/entity.h (#3395)
# Notes
- This is unused.
2023-06-12 15:05:09 -05:00
Alex King a01cf0718d [Cleanup] Remove struct DynamicZoneSafeReturn from zone/entity.h (#3396)
# Notes
- This is unused.
2023-06-12 15:04:54 -05:00
Alex King 90412ba61b [Cleanup] Remove struct TradeEntity from zone/common.h (#3397)
# Notes
- This is unused.
2023-06-12 15:04:38 -05:00
Alex King 5cbc380c62 [Cleanup] Remove CHECK_LOS_STEP from zone/common.h (#3398)
# Notes
- This is unused.
2023-06-12 15:04:25 -05:00
Alex King 6c289a7c71 [Cleanup] Remove _BECOMENPCPET() and _NPCPET() from zone/common.h (#3399)
# Notes
- These are unused.
2023-06-12 15:04:09 -05:00
Alex King 57335b188f [Cleanup] Remove SPECIALIZE_MANA_REDUCE from zone/common.h (#3400)
# Notes
- This is unused.
2023-06-12 15:03:55 -05:00
Alex King 056e429100 [Cleanup] Remove NPC::AddCash() from npc.cpp/npc.h (#3380)
# Notes
- This is unused.
2023-06-09 11:50:52 -04:00
Paul Coene f548aeddb2 [Logging] Fixed statements that logged incorrect data (#3381) 2023-06-07 08:26:04 -04:00
Paul Coene 4ff9faa4e6 [Illusions] RandomizeFeatures and SetGender were killing db texture (#3376)
* [Illusions] RandomizeFeatures and SetGender were killing db texture

* Found actual source of the problem.
2023-06-06 08:30:41 -04:00
Alex King 17fc350d46 [Quest API] Add SendChannelMessage() to Perl/Lua (#3378)
* [Quest API] Add SendChannelMessage() to Perl/Lua

# Perl
- Add `quest::send_channel_message(channel_number, guild_id, language_id, language_skill, message)`.
- Add `quest::send_channel_message(from, channel_number, guild_id, language_id, language_skill, message)`.
- Add `quest::send_channel_message(from, to, channel_number, guild_id, language_id, language_skill, message)`.

# Lua
- Add `eq.send_channel_message(channel_number, guild_id, language_id, language_skill, message)`.
- Add `eq.send_channel_message(from, channel_number, guild_id, language_id, language_skill, message)`.
- Add `eq.send_channel_message(from, to, channel_number, guild_id, language_id, language_skill, message)`.

# Notes
- This allows operators to send channel messages from scripts like a broadcast or tell.

* Update zoneserver.cpp

* Update lua_general.cpp

* Update questmgr.h
2023-06-03 19:06:40 -05:00
Chris Miles b18bc66b42 [Release] 22.12.0 (#3377) 2023-05-30 00:10:44 -05:00
Alex King 324bfd448e [Commands] Add entity variable command (#3345)
* [Commands] Add entity variable commands

# Commands
- Add `#clearentityvariables` to clear all entity variables from yourself or your target.
- Add `#deleteentityvariable [Variable Name]` to delete an entity variable from yourself or your target.
- Add `#setentityvariable [Variable Name] [Variable Value]` to set an entity variable for yourself or your target.
- Add `#viewentityvariables [Search Criteria]` to view your or your target's entity variables.

# Notes
- `#setentityvariable` can use multi-word names/values by using double quotes like `#setentityvariable "Test Variable" "Test Value"`.
- `#viewentityvariable` does not require a search criteria, not using one shows all entity variables on yourself or your target.

* Update viewentityvariables.cpp

* Unnecessary parameter.

* Consolidate commands.

* Update entityvariable.cpp

* Update command.cpp

* Proper arguments.
2023-05-25 19:49:09 -04:00
Alex King 75560ee830 [Performance] Character tribute is now bulk saved (#3340)
* [Performance] Character tribute is now bulk saved

This pull request combines individual `character_tribute` queries during `Save()` into one.

This pull request also adds a primary key of `id` to `character_tribute` and renames the pre-existing `id` column to `character_id`, this allows us to use repositories for this table.

* Update zonedb.cpp

* Update zonedb.cpp
2023-05-25 19:21:18 -04:00
Alex King 50db7637aa [Quest API] Add Memorize and Scribe Spell Events to Perl/Lua (#3363)
* [Quest API] Add Memorize and Scribe Spell Events to Perl/Lua

# Perl
- Add `EVENT_MEMORIZE_SPELL`.
- Add `EVENT_UNMEMORIZE_SPELL`.
- Add `EVENT_SCRIBE_SPELL`.
- Add `EVENT_UNSCRIBE_SPELL`.

# Lua
- Add `event_memorize_spell`.
- Add `event_unmemorize_spell`.
- Add `event_scribe_spell`.
- Add `event_unscribe_spell`.

# Notes
- Allows operators to perform events on memorization, unmemorization, scribe, or unscribe.
- Cleaned up target description messages for `#unscribespell`.

* Update client.cpp
2023-05-25 18:18:14 -05:00
Alex King 67fdc75df3 [Commands] Cleanup #setanim (#3350)
# Notes
- Make use of constants instead of hard-coded strings.
2023-05-25 18:04:09 -05:00
Chris Miles 9993022418 [Pets] Fix saving inconsistencies with pets (#3375) 2023-05-25 11:33:34 -04:00
Alex King bd95ed44fd [Cleanup] Remove GetMaxRank() from aa_ability.cpp/aa_ability.h (#3347)
# Notes
- This is unused.
2023-05-24 22:44:53 -05:00
Alex King 65fd323eab [Cleanup] Remove LoadSpawn2() and PopulateZoneSpawnListClose() from spawn2.cpp/zonedb.h (#3344)
# Notes
- These are unused.
2023-05-24 22:42:20 -05:00
Aeadoin 290c58741e [Bug Fix] Fix issue with Group Pointers/Member roles (#3374)
* [Bug Fix] Fix issue with Group Corruption

* cleanup

* Fix for Group Roles

* Fix for Group Roles
2023-05-24 22:40:59 -05:00
Alex King 39d0772a01 [Cleanup] Remove IsRaid() from raids.h (#3361)
# Notes
- This is unused.
2023-05-24 22:40:32 -05:00
Alex King 622fe50479 [Cleanup] Remove numMembers from raids.h (#3362)
# Notes
- This is unused.
2023-05-24 22:40:20 -05:00
Alex King f41a219309 [Cleanup] Remove CalcPetHp from spdat.h (#3364)
# Notes
- This is unused.
2023-05-24 22:37:04 -05:00
Alex King 23bc3c7fd6 [Cleanup] Remove Z_AGGRO from spdat.h (#3365)
# Notes
- This is unused.
2023-05-24 22:36:52 -05:00
Alex King 3144ac1a28 [Cleanup] Cleanup #setskill and #setskillall Commands (#3367)
# Notes
- No need to cap at 400 for max skill.
- When setting skill/skills, if we go over cap, set to cap.
2023-05-24 22:36:38 -05:00
Alex King a5106420e8 [Commands] Add #findcurrency Command (#3368)
* [Commands] Add #findcurrency Command

# Notes
- Allows you to find alternate currencies by item ID or name.
- Has a saylink for summoning a stack of the currency if the GM can use the `#summonitem` command.

* Update findcurrency.cpp

* Update findcurrency.cpp
2023-05-24 22:30:06 -05:00
Alex King 5a42c4f667 [Quest API] Add zone data methods to Perl/Lua (#3342)
# Perl
- Add `quest::GetZoneSafeX(zone_id)`.
- Add `quest::GetZoneSafeX(zone_id, version)`.
- Add `quest::GetZoneSafeY(zone_id)`.
- Add `quest::GetZoneSafeY(zone_id, version)`.
- Add `quest::GetZoneSafeZ(zone_id)`.
- Add `quest::GetZoneSafeZ(zone_id, version)`.
- Add `quest::GetZoneSafeHeading(zone_id)`.
- Add `quest::GetZoneSafeHeading(zone_id, version)`.
- Add `quest::GetZoneMinimumLevel(zone_id)`.
- Add `quest::GetZoneMinimumLevel(zone_id, version)`.
- Add `quest::GetZoneMaximumLevel(zone_id)`.
- Add `quest::GetZoneMaximumLevel(zone_id, version)`.
- Add `quest::GetZoneMinimumStatus(zone_id)`.
- Add `quest::GetZoneMinimumStatus(zone_id, version)`.
- Add `quest::GetZoneTimeZone(zone_id)`.
- Add `quest::GetZoneTimeZone(zone_id, version)`.
- Add `quest::GetZoneMaximumPlayers(zone_id)`.
- Add `quest::GetZoneMaximumPlayers(zone_id, version)`.
- Add `quest::GetZoneRuleSet(zone_id)`.
- Add `quest::GetZoneRuleSet(zone_id, version)`.
- Add `quest::GetZoneNote(zone_id)`.
- Add `quest::GetZoneNote(zone_id, version)`.
- Add `quest::GetZoneUnderworld(zone_id)`.
- Add `quest::GetZoneUnderworld(zone_id, version)`.
- Add `quest::GetZoneMinimumClip(zone_id)`.
- Add `quest::GetZoneMinimumClip(zone_id, version)`.
- Add `quest::GetZoneMaximumClip(zone_id)`.
- Add `quest::GetZoneMaximumClip(zone_id, version)`.
- Add `quest::GetZoneFogMinimumClip(zone_id)`.
- Add `quest::GetZoneFogMinimumClip(zone_id, slot)`.
- Add `quest::GetZoneFogMinimumClip(zone_id, slot, version)`.
- Add `quest::GetZoneFogMaximumClip(zone_id)`.
- Add `quest::GetZoneFogMaximumClip(zone_id, slot)`.
- Add `quest::GetZoneFogMaximumClip(zone_id, slot, version)`.
- Add `quest::GetZoneFogRed(zone_id)`.
- Add `quest::GetZoneFogRed(zone_id, slot)`.
- Add `quest::GetZoneFogRed(zone_id, slot, version)`.
- Add `quest::GetZoneFogGreen(zone_id)`.
- Add `quest::GetZoneFogGreen(zone_id, slot)`.
- Add `quest::GetZoneFogGreen(zone_id, slot, version)`.
- Add `quest::GetZoneFogBlue(zone_id)`.
- Add `quest::GetZoneFogBlue(zone_id, slot)`.
- Add `quest::GetZoneFogBlue(zone_id, slot, version)`.
- Add `quest::GetZoneSky(zone_id)`.
- Add `quest::GetZoneSky(zone_id, version)`.
- Add `quest::GetZoneZType(zone_id)`.
- Add `quest::GetZoneZType(zone_id, version)`.
- Add `quest::GetZoneExperienceMultiplier(zone_id)`.
- Add `quest::GetZoneExperienceMultiplier(zone_id, version)`.
- Add `quest::GetZoneWalkSpeed(zone_id)`.
- Add `quest::GetZoneWalkSpeed(zone_id, version)`.
- Add `quest::GetZoneTimeType(zone_id)`.
- Add `quest::GetZoneTimeType(zone_id, version)`.
- Add `quest::GetZoneFogDensity(zone_id)`.
- Add `quest::GetZoneFogDensity(zone_id, version)`.
- Add `quest::GetZoneFlagNeeded(zone_id)`.
- Add `quest::GetZoneFlagNeeded(zone_id, version)`.
- Add `quest::GetZoneCanBind(zone_id)`.
- Add `quest::GetZoneCanBind(zone_id, version)`.
- Add `quest::GetZoneCanCombat(zone_id)`.
- Add `quest::GetZoneCanCombat(zone_id, version)`.
- Add `quest::GetZoneCanLevitate(zone_id)`.
- Add `quest::GetZoneCanLevitate(zone_id, version)`.
- Add `quest::GetZoneCastOutdoor(zone_id)`.
- Add `quest::GetZoneCastOutdoor(zone_id, version)`.
- Add `quest::GetZoneHotzone(zone_id)`.
- Add `quest::GetZoneHotzone(zone_id, version)`.
- Add `quest::GetZoneInstanceType(zone_id)`.
- Add `quest::GetZoneInstanceType(zone_id, version)`.
- Add `quest::GetZoneShutdownDelay(zone_id)`.
- Add `quest::GetZoneShutdownDelay(zone_id, version)`.
- Add `quest::GetZonePEQZone(zone_id)`.
- Add `quest::GetZonePEQZone(zone_id, version)`.
- Add `quest::GetZoneExpansion(zone_id)`.
- Add `quest::GetZoneExpansion(zone_id, version)`.
- Add `quest::GetZoneBypassExpansionCheck(zone_id)`.
- Add `quest::GetZoneBypassExpansionCheck(zone_id, version)`.
- Add `quest::GetZoneSuspendBuffs(zone_id)`.
- Add `quest::GetZoneSuspendBuffs(zone_id, version)`.
- Add `quest::GetZoneRainChance(zone_id)`.
- Add `quest::GetZoneRainChance(zone_id, slot)`.
- Add `quest::GetZoneRainChance(zone_id, slot, version)`.
- Add `quest::GetZoneRainDuration(zone_id)`.
- Add `quest::GetZoneRainDuration(zone_id, slot)`.
- Add `quest::GetZoneRainDuration(zone_id, slot, version)`.
- Add `quest::GetZoneSnowChance(zone_id)`.
- Add `quest::GetZoneSnowChance(zone_id, slot)`.
- Add `quest::GetZoneSnowChance(zone_id, slot, version)`.
- Add `quest::GetZoneSnowDuration(zone_id)`.
- Add `quest::GetZoneSnowDuration(zone_id, slot)`.
- Add `quest::GetZoneSnowDuration(zone_id, slot, version)`.
- Add `quest::GetZoneGravity(zone_id)`.
- Add `quest::GetZoneGravity(zone_id, version)`.
- Add `quest::GetZoneType(zone_id)`.
- Add `quest::GetZoneType(zone_id, version)`.
- Add `quest::GetZoneSkyLock(zone_id)`.
- Add `quest::GetZoneSkyLock(zone_id, version)`.
- Add `quest::GetZoneFastRegenHP(zone_id)`.
- Add `quest::GetZoneFastRegenHP(zone_id, version)`.
- Add `quest::GetZoneFastRegenMana(zone_id)`.
- Add `quest::GetZoneFastRegenMana(zone_id, version)`.
- Add `quest::GetZoneFastRegenEndurance(zone_id)`.
- Add `quest::GetZoneFastRegenEndurance(zone_id, version)`.
- Add `quest::GetZoneNPCMaximumAggroDistance(zone_id)`.
- Add `quest::GetZoneNPCMaximumAggroDistance(zone_id, version)`.
- Add `quest::GetZoneMaximumMovementUpdateRange(zone_id)`.
- Add `quest::GetZoneMaximumMovementUpdateRange(zone_id, version)`.
- Add `quest::GetZoneMinimumExpansion(zone_id)`.
- Add `quest::GetZoneMinimumExpansion(zone_id, version)`.
- Add `quest::GetZoneMaximumExpansion(zone_id)`.
- Add `quest::GetZoneMaximumExpansion(zone_id, version)`.
- Add `quest::GetZoneContentFlags(zone_id)`.
- Add `quest::GetZoneContentFlags(zone_id, version)`.
- Add `quest::GetZoneContentFlagsDisabled(zone_id)`.
- Add `quest::GetZoneContentFlagsDisabled(zone_id, version)`.
- Add `quest::GetZoneUnderworldTeleportIndex(zone_id)`.
- Add `quest::GetZoneUnderworldTeleportIndex(zone_id, version)`.
- Add `quest::GetZoneLavaDamage(zone_id)`.
- Add `quest::GetZoneLavaDamage(zone_id, version)`.
- Add `quest::GetZoneMinimumLavaDamage(zone_id)`.
- Add `quest::GetZoneMinimumLavaDamage(zone_id, version)`.

# Lua
- Add `eq.get_zone_safe_x(zone_id)`.
- Add `eq.get_zone_safe_x(zone_id, version)`.
- Add `eq.get_zone_safe_y(zone_id)`.
- Add `eq.get_zone_safe_y(zone_id, version)`.
- Add `eq.get_zone_safe_z(zone_id)`.
- Add `eq.get_zone_safe_z(zone_id, version)`.
- Add `eq.get_zone_safe_heading(zone_id)`.
- Add `eq.get_zone_safe_heading(zone_id, version)`.
- Add `eq.get_zone_minimum_level(zone_id)`.
- Add `eq.get_zone_minimum_level(zone_id, version)`.
- Add `eq.get_zone_maximum_level(zone_id)`.
- Add `eq.get_zone_maximum_level(zone_id, version)`.
- Add `eq.get_zone_minimum_status(zone_id)`.
- Add `eq.get_zone_minimum_status(zone_id, version)`.
- Add `eq.get_zone_time_zone(zone_id)`.
- Add `eq.get_zone_time_zone(zone_id, version)`.
- Add `eq.get_zone_maximum_players(zone_id)`.
- Add `eq.get_zone_maximum_players(zone_id, version)`.
- Add `eq.get_zone_rule_set(zone_id)`.
- Add `eq.get_zone_rule_set(zone_id, version)`.
- Add `eq.get_zone_note(zone_id)`.
- Add `eq.get_zone_note(zone_id, version)`.
- Add `eq.get_zone_underworld(zone_id)`.
- Add `eq.get_zone_underworld(zone_id, version)`.
- Add `eq.get_zone_minimum_clip(zone_id)`.
- Add `eq.get_zone_minimum_clip(zone_id, version)`.
- Add `eq.get_zone_maximum_clip(zone_id)`.
- Add `eq.get_zone_maximum_clip(zone_id, version)`.
- Add `eq.get_zone_fog_minimum_clip(zone_id)`.
- Add `eq.get_zone_fog_minimum_clip(zone_id, slot)`.
- Add `eq.get_zone_fog_minimum_clip(zone_id, slot, version)`.
- Add `eq.get_zone_fog_maximum_clip(zone_id)`.
- Add `eq.get_zone_fog_maximum_clip(zone_id, slot)`.
- Add `eq.get_zone_fog_maximum_clip(zone_id, slot, version)`.
- Add `eq.get_zone_fog_red(zone_id)`.
- Add `eq.get_zone_fog_red(zone_id, slot)`.
- Add `eq.get_zone_fog_red(zone_id, slot, version)`.
- Add `eq.get_zone_fog_green(zone_id)`.
- Add `eq.get_zone_fog_green(zone_id, slot)`.
- Add `eq.get_zone_fog_green(zone_id, slot, version)`.
- Add `eq.get_zone_fog_blue(zone_id)`.
- Add `eq.get_zone_fog_blue(zone_id, slot)`.
- Add `eq.get_zone_fog_blue(zone_id, slot, version)`.
- Add `eq.get_zone_sky(zone_id)`.
- Add `eq.get_zone_sky(zone_id, version)`.
- Add `eq.get_zone_ztype(zone_id)`.
- Add `eq.get_zone_ztype(zone_id, version)`.
- Add `eq.get_zone_experience_multiplier(zone_id)`.
- Add `eq.get_zone_experience_multiplier(zone_id, version)`.
- Add `eq.get_zone_walk_speed(zone_id)`.
- Add `eq.get_zone_walk_speed(zone_id, version)`.
- Add `eq.get_zone_time_type(zone_id)`.
- Add `eq.get_zone_time_type(zone_id, version)`.
- Add `eq.get_zone_fog_density(zone_id)`.
- Add `eq.get_zone_fog_density(zone_id, version)`.
- Add `eq.get_zone_flag_needed(zone_id)`.
- Add `eq.get_zone_flag_needed(zone_id, version)`.
- Add `eq.get_zone_can_bind(zone_id)`.
- Add `eq.get_zone_can_bind(zone_id, version)`.
- Add `eq.get_zone_can_combat(zone_id)`.
- Add `eq.get_zone_can_combat(zone_id, version)`.
- Add `eq.get_zone_can_levitate(zone_id)`.
- Add `eq.get_zone_can_levitate(zone_id, version)`.
- Add `eq.get_zone_cast_outdoor(zone_id)`.
- Add `eq.get_zone_cast_outdoor(zone_id, version)`.
- Add `eq.get_zone_hotzone(zone_id)`.
- Add `eq.get_zone_hotzone(zone_id, version)`.
- Add `eq.get_zone_instance_type(zone_id)`.
- Add `eq.get_zone_instance_type(zone_id, version)`.
- Add `eq.get_zone_shutdown_delay(zone_id)`.
- Add `eq.get_zone_shutdown_delay(zone_id, version)`.
- Add `eq.get_zone_peqzone(zone_id)`.
- Add `eq.get_zone_peqzone(zone_id, version)`.
- Add `eq.get_zone_expansion(zone_id)`.
- Add `eq.get_zone_expansion(zone_id, version)`.
- Add `eq.get_zone_bypass_expansion_check(zone_id)`.
- Add `eq.get_zone_bypass_expansion_check(zone_id, version)`.
- Add `eq.get_zone_suspend_buffs(zone_id)`.
- Add `eq.get_zone_suspend_buffs(zone_id, version)`.
- Add `eq.get_zone_rain_chance(zone_id)`.
- Add `eq.get_zone_rain_chance(zone_id, slot)`.
- Add `eq.get_zone_rain_chance(zone_id, slot, version)`.
- Add `eq.get_zone_rain_duration(zone_id)`.
- Add `eq.get_zone_rain_duration(zone_id, slot)`.
- Add `eq.get_zone_rain_duration(zone_id, slot, version)`.
- Add `eq.get_zone_snow_chance(zone_id)`.
- Add `eq.get_zone_snow_chance(zone_id, slot)`.
- Add `eq.get_zone_snow_chance(zone_id, slot, version)`.
- Add `eq.get_zone_snow_duration(zone_id)`.
- Add `eq.get_zone_snow_duration(zone_id, slot)`.
- Add `eq.get_zone_snow_duration(zone_id, slot, version)`.
- Add `eq.get_zone_gravity(zone_id)`.
- Add `eq.get_zone_gravity(zone_id, version)`.
- Add `eq.get_zone_type(zone_id)`.
- Add `eq.get_zone_type(zone_id, version)`.
- Add `eq.get_zone_sky_lock(zone_id)`.
- Add `eq.get_zone_sky_lock(zone_id, version)`.
- Add `eq.get_zone_fast_regen_hp(zone_id)`.
- Add `eq.get_zone_fast_regen_hp(zone_id, version)`.
- Add `eq.get_zone_fast_regen_mana(zone_id)`.
- Add `eq.get_zone_fast_regen_mana(zone_id, version)`.
- Add `eq.get_zone_fast_regen_endurance(zone_id)`.
- Add `eq.get_zone_fast_regen_endurance(zone_id, version)`.
- Add `eq.get_zone_npc_maximum_aggro_distance(zone_id)`.
- Add `eq.get_zone_npc_maximum_aggro_distance(zone_id, version)`.
- Add `eq.get_zone_maximum_movement_update_range(zone_id)`.
- Add `eq.get_zone_maximum_movement_update_range(zone_id, version)`.
- Add `eq.get_zone_minimum_expansion(zone_id)`.
- Add `eq.get_zone_minimum_expansion(zone_id, version)`.
- Add `eq.get_zone_maximum_expansion(zone_id)`.
- Add `eq.get_zone_maximum_expansion(zone_id, version)`.
- Add `eq.get_zone_content_flags(zone_id)`.
- Add `eq.get_zone_content_flags(zone_id, version)`.
- Add `eq.get_zone_content_flags_disabled(zone_id)`.
- Add `eq.get_zone_content_flags_disabled(zone_id, version)`.
- Add `eq.get_zone_underworld_teleport_index(zone_id)`.
- Add `eq.get_zone_underworld_teleport_index(zone_id, version)`.
- Add `eq.get_zone_lava_damage(zone_id)`.
- Add `eq.get_zone_lava_damage(zone_id, version)`.
- Add `eq.get_zone_minimum_lava_damage(zone_id)`.
- Add `eq.get_zone_minimum_lava_damage(zone_id, version)`.

# Notes
- These methods add support for reading every value that the `zone` table contains, allowing operators to get any information about a specific zone and version they could need.
2023-05-24 17:59:18 -04:00
Alex King a3107cc54d [Bug Fix] Fix duplicate messages in #npcedit (#3372)
# Notes
- `#npcedit special_attacks` and `#npcedit special_abilities` send duplicate messages since the `d` variable wasn't being set and a message was being sent instead, meaning a message was sent inside the condition as well as a blank message at the bottom of the command.
2023-05-21 18:56:51 -04:00
Alex King f0152cef66 [Rules] Add World:MaximumQuestErrors Rule (#3349)
* [Rules] Add World:MaximumQuestErrors Rule

# Notes
- Allows operators to display more than 30 errors with #questerrors if they want.

* Update quest_interface.h
2023-05-21 18:48:30 -04:00
Alex King 21755a9f9e [Bug Fix] Fix typos in #zheader (#3370)
# Notes
- Argument 2 and 3 were being used when it should have been arguments 1 and 2.
2023-05-21 18:48:22 -04:00
Alex King b329515a07 [Quest API] Cleanup The Darkened Sea Quest Methods Names (#3369)
# Notes
- These were spelled incorrectly.
2023-05-21 18:48:15 -04:00
Alex King ff4b117cfa [Cleanup] Fix #spawn command NPCs having 0 health (#3371)
# Notes
- NPCs when spawned with this command have 0 health by default, requiring operators to manually edit their health if they're using this NPC as an NPC in their hub.
2023-05-21 18:48:08 -04:00
Paul Coene e305ba852b [Bug Fix] NPC Armor Upgrade to a slot not handled correctly (#3366)
* [NPC Armor - Bug] NPC upgardes in armor not correct

* Revert "[NPC Armor - Bug] NPC upgardes in armor not correct"

This reverts commit d5a68654a7.

* [NPC item bonuses] Upgrades not processed correctly

* Update loottables.cpp

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-19 22:28:01 -04:00
RekkasGit b8c91cf4f9 [Bug Fix] Mob scaling issue with min dmg set to zero while max dmg is not (#3351)
* fix for mob scaling issue with min dmg set to zero while max dmg is not.

* Cleanup

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-19 22:11:11 -04:00
Alex King cd82bd8472 [Cleanup] Remove DumpMerchantList() from zone.cpp/zone.h (#3343)
# Notes
- This is unused.
2023-05-17 09:02:14 -04:00
Alex King 20bed20f47 [Cleanup] Delete message.h (#3348)
# Notes
- This is unsued.
2023-05-17 09:00:38 -04:00
Alex King c93054421f [Cleanup] Remove CountNPC() and QueueManaged() from entity.cpp/entity.h (#3346)
# Notes
- These are unused.
2023-05-17 08:58:50 -04:00
Alex King b7a1fc6644 [Cleanup] Remove IsEntityInFrenzyMode() from hate_list.cpp/hate_list.h (#3352)
# Notes
- This is unused.
2023-05-17 08:58:27 -04:00
Alex King 6bfb8fca2e [Cleanup] Remove GetEscapingEntOnHateList() from hate_list.cpp/hate_list.h (#3353)
# Notes
- This is unused.
2023-05-17 08:58:13 -04:00
Alex King 9d6a7ad743 [Cleanup] Remove SetGraveyard() from zone.cpp/zone.h (#3354)
# Notes
- This is unused.
2023-05-17 08:58:02 -04:00
Alex King 076b88be9a [Cleanup] Remove TypeToSkill() from tradeskills.cpp/object.h (#3355)
# Notes
- This is unused.
2023-05-17 08:57:51 -04:00
Alex King 84a779c4df [Cleanup] Remove SetTradeCash() from trading.cpp/common.h (#3356)
# Notes
- This is unused.
2023-05-17 08:57:09 -04:00
Alex King 3fb479e612 [Cleanup] Remove TraderUpdate() from trading.cpp/client.h (#3357)
# Notes
- This is unused.
2023-05-17 08:56:42 -04:00
Alex King c1f4ee0e65 [Cleanup] Remove GetDamageReceived() and GetHealReceived() from combat_record.cpp/combat_record.h (#3358)
# Notes
- These are unused.
2023-05-17 08:56:09 -04:00
RekkasGit 32f7dc3d1b [Quest API] Add GetHateListClosest(), GetHateListClosestBot(), GetHateListClosestClient(), and GetHateListClosestNPC() methods/overloads to Perl/Lua (#3359)
* Add HateListClosestClient available for scripting.

* Add other methods.

* Use pre-existing constants.

* Typos

* Update mob.h

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-15 21:23:19 -04:00
RekkasGit fa55fd1664 [Bug Fix] Fix Heroic INT/WIS Bonuses (#3341)
* fix for heroic int/wis for hybrids

* Update classes.cpp

* Update classes.cpp

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-15 10:52:53 -04:00
Chris Miles c44c0d4efa [Performance] Character buffs now save in bulk (#3336)
* [Performance] Character buffs now save in bulk

* Only insert if we have buffs to insert

* Swap for .empty()
2023-05-09 13:28:34 -05:00
Chris Miles 50c63b95db [Performance] Character pet bulk saving (#3337)
* [Performance] Character pet bulk saving

* Update zonedb.cpp
2023-05-09 13:27:17 -05:00
Chris Miles 612029de6e [Performance] Character bind is now bulk saved (#3338)
* [Performance] Character bind is now bulk saved

* Fix bind heading
2023-05-09 13:22:57 -05:00
Chris Miles dbc6346fe8 [Performance] Mail key is now cached during player load (#3339)
* [Performance] Mail key is now cached during player load

* More refactoring
2023-05-09 13:22:43 -05:00
nytmyr 93a4153a4b [Rules] ResurrectionEffectBlock to prevent/allow/move buffs. (#3288)
* [Rules] ResurrectionEffectsBlock to prevent/allow/move buffs.

This removes the rule ResurrectionEffectsBlock (Bool) and creates ResurrectionEffectsBlock (Int)

Default = 2

Setting to 0 = Functions as it did before any blocking changes, Focus of Spirit and Strength buffs can overwrite Resurrection Effects.

Setting to 1 = Blocks all buffs that could overwrite Resurrection Effects.

Setting to 2 = Allows all buffs that would overwrite Resurrection Effects to land, however they will be moved to a new buff slot if one is available to allow both the beneficial buff to land and detrimental effects of Resurrection Effects to stay in effect until the duration is expired.

* Update logging

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-05-08 08:32:21 -05:00
Akkadius 434f270f68 Revert "[Bug Fix] ReloadQuests() on Zone::Init() to avoid cached global quests/plugins (#3333)"
This reverts commit 8c23eee42a.
2023-05-07 23:33:43 -05:00
Alex King 5ba33b88bd [Cleanup] Set GetAugmentType() to int again (#3335)
# Notes
- Augment type can be `-1` for all augment types.
2023-05-07 21:40:45 -04:00
Alex King ce1de9997b [Quest API] Add GetPet() to Perl (#3309)
# Perl
- Add `$mob->GetPet()`.

# Notes
- This exists in Lua, but not Perl.
2023-05-07 19:13:26 -05:00
Chris Miles 8814ab26cd [Hotfix] Fix mob item bonus calc (#3334) 2023-05-07 18:23:22 -05:00
Alex King 8c23eee42a [Bug Fix] ReloadQuests() on Zone::Init() to avoid cached global quests/plugins (#3333)
# Notes
- Before this, quests/plugins would be cached in an old state, so you'd have to either enter the zone and `#reload quest` or `#reload world` to get them to update.
2023-05-07 14:41:57 -04:00
Alex King 5475615448 [Bug Fix] #augmentitem bypasses augment restrictions (#3332)
* [Bug Fix] #augmentitem bypasses augment restrictions

# Notes
- `Object::HandleAugmentation` did not properly check for `augrestrict` values. This allowed augment restrictions to be bypassed with `#augmentitem` or anything else that uses this method.
- `Client::SummonItem` already properly checked these, so I just broke it out into a `Client::IsAugmentRestricted()` method.

* Update item_instance.h
2023-05-07 11:40:04 -04:00
Chris Miles 4a5559022f [Memory Leak] Fix large memory leak introduced in CalcItemBonuses (#3331) 2023-05-07 09:47:03 -04:00
Paul Coene 5be2041085 [Messages] Remove duplicate heal message for healing yourself (#3329) 2023-05-03 16:50:54 -04:00
Jasdac 9f4d60ec36 [Feature] Intoxication setter/getter for source, getter for Perl/Lua (#3330)
* Add setter and getter methods for intoxication
Add GetIntoxication functions for perl and Lua

* Remove trailing tab

* Use clamp instead of min/max
2023-05-03 16:19:53 -04:00
Chris Miles c64a2aec94 [Release] 22.11.0 (#3328)
* [Release] 22.11.0

* Update version.h
2023-04-29 20:37:04 -05:00
Alex King 0e582eda82 [Quest API] Add HasSpellEffect() to Perl/Lua (#3319)
* [Quest API] Add HasSpellEffect() to Perl/Lua

# Perl
- Add `$mob->HasSpellEffect(effect_id)`.

# Lua
- Add `mob:HasSpellEffect(effect_id)`.

# Notes
- Allows operators to see if a Mob has an effect ID from any of their buffs.

* Update mob.cpp
2023-04-29 20:09:00 -05:00
Alex King 7eff6ada87 [Cleanup] Remove unused code in zone/pets.cpp (#3310)
# Notes
- This code is unused.
2023-04-29 20:00:37 -05:00
Alex King 291997d35b [Cleanup] Remove pDontCastBefore_casting_spell from zone/npc.h (#3311)
# Notes
- This is unused.
2023-04-29 20:00:20 -05:00
Alex King ac4572bf79 [Cleanup] Remove unused methods in zone/client.cpp and zone/client.h (#3312)
* [Cleanup] Remove unused methods in zone/client.cpp and zone/client.h

# Notes
- Remove `CheckAccess()` in `zone/client.cpp`.
- Remove `CheckAccess()` in `zone/client.h`.
- Remove `CheckQuests()` in `zone/client.h`.
- Remove `MakeCorpse()` in `zone/client.h`.
- Remove `HPTick()` in `zone/client.h`.
- These methods are unused.

* Update client.h
2023-04-29 20:00:08 -05:00
Alex King f0a9578b6a [Cleanup] Remove GetClassHPFactor() from zone/merc.h (#3314)
# Notes
- This is unused.
2023-04-29 19:59:50 -05:00
Alex King baa824d8fb [Cleanup] Remove GetClassHPFactor() from zone/client_mods.cpp and zone/client.h (#3313)
# Notes
- This is unused.
2023-04-29 19:59:19 -05:00
Alex King b19d3ac8a2 [Cleanup] Remove unused methods in zone/bot.cpp and zone/bot.h (#3315)
# Notes
- Remove `DoFinishedSpellAETarget()`.
- Remove `SendBotArcheryWearChange()`.
- These are unused.
2023-04-29 19:59:05 -05:00
Alex King 6a393bf0c3 [Quest API] Add GetDefaultRaceSize() overloads to Perl/Lua (#3320)
# Perl
- Add `$mob->GetDefaultRaceSize(race_id)`.
- Add `$mob->GetDefaultRaceSize(race_id, gender_id)`.

# Lua
- Add `mob:GetDefaultRaceSize(race_id)`.
- Add `mob:GetDefaultRaceSize(race_id, gender_id)`.

# Notes
- This allows you to get a default size for a race and gender that isn't the current mob's race and gender.
2023-04-29 19:53:49 -05:00
Alex King 09a5551de1 [Cleanup] quest::setallskill() had always true condition. (#3301)
# Notes
- Remove unnecessary double check of `initiator`.
- Cleanup logic to use `EQ::skills::GetSkillTypeMap()`.
2023-04-29 19:52:30 -05:00
Alex King 6e2e035d66 [Cleanup] Remove unused variable in common/crash.cpp (#3308)
# Notes
- This variable is unused.
2023-04-29 19:51:41 -05:00
Alex King ac5922bb32 [Cleanup] Use default ctor/dtor in oriented_bounding_box.h (#3307)
# Notes
- Use default ctor/dtor instead of empty ones.
2023-04-29 19:51:21 -05:00
Chris Miles ecf2a369cc [Discord] Add Discord webhook callback processing to world (#3322) 2023-04-29 20:49:06 -04:00
Chris Miles 95b306599f [Maps] Update download with faster releases link (#3321) 2023-04-29 19:39:24 -05:00
Chris Miles 497d20512a [Crash] Fix UCS crash that occurs during log reloading (#3324) 2023-04-29 19:39:13 -05:00
Aeadoin db916e946e [Bug Fix] Fix issue with spawning Mercs (#3327) 2023-04-29 18:45:35 -04:00
Alex King 958549b407 [Bug Fix] Possible issues with SummonItem in Client::QuestReward() methods (#3325)
# Notes
- These methods were ignoring the sixth augment slot and could cause item to be summoned attuned being `EQ::invslot::slotCursor` is a non-zero value.
2023-04-26 21:28:24 -04:00
Paul Coene 71ebf1b2d4 [Messages] Remove duplicate you have lost a level message (#3323) 2023-04-25 17:42:31 -04:00
Paul Coene e19b8d3056 [Bug Fix] Fix issue with NPCs no longer using some armor. (#3318)
* [BugFix/NPCs] Fix issue with NPCs no longer using some armor.

* Removed redundant memory clear
2023-04-24 17:05:29 -04:00
Alex King 8b1d64a043 [Cleanup] quest::createBot() unnecessary check against nullptr (#3302)
# Notes
- We initialize this variable, so it can never be a nullptr.
2023-04-23 15:08:50 -04:00
Alex King 576f99f292 [Cleanup] Add initiator/owner checks to various methods in questmgr.cpp (#3306)
* [Cleanup] Add initiator/owner checks to various methods in questmgr.cpp

# Notes
- Add `initiator` check to `quest::permaclass()`.
- Add `initiator` check to `quest::permarace()`.
- Add `initiator` check to `quest::permagender()`.
- Add `initiator` check to `quest::scribespells()`.
- Add `initiator` check to `quest::traindiscs()`.
- Add `initiator` check to `quest::unscribespells()`.
- Add `initiator` check to `quest::untraindiscs()`.
- Cleanup `initiator` check in `quest::pvp()`.
- Cleanup `initiator` check in `quest::movepc()`.
- Cleanup `initiator` check in `quest::gmmove()`.
- Cleanup `initiator` check in `quest::movegrp()`.
- Add `owner` check to `quest::doanim()`.
- Cleanup `initiator` check in `quest::addskill()`.
- Cleanup `initiator` check in `quest::setlanguage()`.
- Cleanup `initiator` check in `quest::setskill()`.

* Update questmgr.cpp

* Update questmgr.cpp

* Update questmgr.cpp

* Update questmgr.cpp
2023-04-23 15:08:32 -04:00
Alex King e3761cf2a3 [Cleanup] Add check for owner in quest::resumetimer() (#3305)
# Notes
- We didn't check for owner before doing `owner->GetName()`.
2023-04-23 15:07:49 -04:00
Alex King ad1764b464 [Cleanup] Add cehck for owner in quest::pausetimer() (#3304)
# Notes
- We didn't check for `owner` before doing `owner->GetName()`.
2023-04-23 15:07:09 -04:00
Alex King 1c9ea57a4e [Cleanup] Fix possible nullptr in quest::addloot() (#3303)
# Notes
- We didn't check for `owner` before calling `owner->IsNPC()`.
2023-04-23 15:06:53 -04:00
Alex King 03c158b674 [Crash] Fix possible nullptr in Client::GetCharMaxLevelFromQGlobal() (#3317)
# Notes
- We could possibly not have a `zone` here, causing a crash.
- http://spire.akkadius.com/dev/release/22.9.1?id=3051
- http://spire.akkadius.com/dev/release/22.9.1?id=3052
- http://spire.akkadius.com/dev/release/22.9.1?id=3073
- http://spire.akkadius.com/dev/release/22.9.1?id=3102
- http://spire.akkadius.com/dev/release/22.9.1?id=3103
- http://spire.akkadius.com/dev/release/22.9.1?id=3104
- http://spire.akkadius.com/dev/release/22.9.1?id=3107
- http://spire.akkadius.com/dev/release/22.9.1?id=3108
- http://spire.akkadius.com/dev/release/22.9.1?id=3109
- http://spire.akkadius.com/dev/release/22.9.1?id=3110
- http://spire.akkadius.com/dev/release/22.9.1?id=3111
- http://spire.akkadius.com/dev/release/22.9.1?id=3112
- http://spire.akkadius.com/dev/release/22.9.1?id=3113
- http://spire.akkadius.com/dev/release/22.9.1?id=3114
2023-04-23 15:05:47 -04:00
Aeadoin 39b5374e92 [Crash] Fix possible dereference of nullptr in Client::CalcHPRegen (#3316) 2023-04-23 14:27:43 -04:00
Aeadoin 2d3ddcb574 [Release] 22.10.0 (#3300) 2023-04-22 10:17:20 -04:00
Aeadoin ed09281f66 [Bug Fix] Camping was causing player to leave raid, causing unexpected behavior (#3299) 2023-04-22 10:03:40 -04:00
Paul Coene 8e51bf8b19 Fix crash when Removing empty password protected channel. (#3298) 2023-04-22 08:49:34 -04:00
Alex King 844efa7e20 [Cleanup] Breaks in wrong spot in cases in spell_effects.cpp (#3297)
* [Cleanup] Breaks in wrong spot in cases in spell_effects.cpp

# Notes
- These breaks were inside conditions, meaning the case wasn't always broken.

* Update spell_effects.cpp
2023-04-22 08:49:13 -04:00
Alex King fa3a5c7a72 [Feature] Make ornamentations work with any augment type (#3281)
* [Feature] Make ornamentations work with any augment type

# Notes
- On Live there are augments that are not type 20/21 and are ornamentations.
- We also only allow a singular augment type to be ornamentation augment types, this will allow you to use any augment type as an ornamentation if it has a proper Hero's Forge model or a non-IT63/non-IT64 idfile.

* Update ruletypes.h

* Update client_packet.cpp

* Update item_instance.cpp

* Cleanup.
2023-04-16 10:26:19 -04:00
Aeadoin 93db35658a [Crash] Add additional raid integrity checks on Bot Spawn. (#3295)
* simple cleanup before changes

* can't be in a raid yet

* change to sizeof

* change to use sizeof
2023-04-16 10:06:19 -04:00
Alex King d45a57056a [Cleanup] Remove getd(), geti(), InUse(), lasterr(), my_get_sv(), and VarExists() in embperl.cpp/embperl.h (#3283)
* [Cleanup] Remove getd(), geti(), InUse(), lasterr(), and VarExists() in embperl.cpp/embperl.h

# Notes
- These are unused.

* Update embperl.h

* Update embperl.cpp
2023-04-15 13:20:18 -04:00
Alex King ff40dbc710 [Cleanup] Utilize IsTaunting(), SetPetPower(), SetPetType(), and SetTaunting() (#3275)
* [Cleanup] Utilize SetPetPower() in zone/pets.cpp

# Notes
- This wasn't used before.

* Utilize other methods.

* Update special_attacks.cpp
2023-04-15 13:20:04 -04:00
Aeadoin 7523c972fa [Crash] Fix crash with uninitialized item instance, and Bot timeout (#3296) 2023-04-15 13:12:48 -04:00
Alex King 4320c1429e [Cleanup] Remove _GetMovementSpeed() from mob.h (#3276)
# Notes
- This is unused.
2023-04-14 19:42:48 -04:00
Alex King dc8bfddd7a [Cleanup] Remove IsFullHP from mob.cpp/mob.h (#3277)
# Notes
- This is unused.
2023-04-14 19:42:39 -04:00
Alex King a8cdfb07e6 [Cleanup] Remove pendinggroup from mob.h (#3278)
# Notes
- This is unused.
2023-04-14 19:42:27 -04:00
Alex King 011de2692e [Cleanup] Remove IsMeleeDmg() from skills.cpp/skills.h (#3279)
# Notes
- This is unused.
2023-04-14 19:42:14 -04:00
Alex King 0cc76ab489 [Cleanup] Remove position_same_update_count from client.cpp/client.h (#3280)
# Notes
- This is unused.
2023-04-14 19:42:01 -04:00
Alex King c5c9985e0d [Cleanup] Remove ExportVarComplex() from embparser.cpp/embparser.h (#3282)
# Notes
- This is unused.
2023-04-14 19:41:23 -04:00
Alex King a7e95d7818 [Cleanup] Delete embxs.cpp/embxs.h (#3284)
* [Cleanup] Delete embxs.cpp/embxs.h

# Notes
- These files and the one method in them are unused.

* Update embperl.cpp
2023-04-14 19:40:51 -04:00
Alex King 933d856b5b [Cleanup] Remove GetQGlobal() from qglobals.cpp/qglobals.h (#3285)
# Notes
- This is unused.
2023-04-14 19:40:35 -04:00
Alex King 285cc3af29 [Cleanup] Remove item_timers from questmgr.cpp/questmgr.h (#3286)
* [Cleanup] Remove item_timers from questmgr.cpp/questmgr.h

# Notes
- This is unused.

* Update questmgr.h
2023-04-14 19:40:21 -04:00
Alex King de8ae7afa6 [Cleanup] Cleanup zone/zoning.cpp (#3289)
# Notes
- Duplicate outcome cases in `Client::Handle_OP_ZoneChange`.
- Use `.length()` over `strlen` in array defintition.
- Remove unnecessary `else if` in `Client::ZonePC`
2023-04-14 19:40:01 -04:00
Alex King 1b272cba50 [Cleanup] Remove unused ctor and use default dtor in xtargetautohaters.h (#3290)
* [Cleanup] Remove unused ctor and use default dtor in xtargetautohaters.h

# Notes
- Utilize default dtor.
- Remove unused ctor.

* Update zone_event_scheduler.cpp
2023-04-14 19:39:25 -04:00
Alex King e35e38b039 [Cleanup] Remove unused variables and use reference in task_manager.cpp (#3291)
# Notes
- Remove unused `query` and `item` variable.
- Use a reference for task data instead of calling `cts->m_completed_tasks[task_index]` over and over.
2023-04-14 19:39:07 -04:00
Alex King 9215ba7a8a [Cleanup] Remove always true statements in task_client_state.cpp (#3292)
# Notes
- `!tasks_enabled.empty()` is always true.
- `tasks_disabled.size()` is always true.
2023-04-14 19:38:35 -04:00
Alex King 3f4334985b [Cleanup] Remove unnecessary condition and cleanup variable name in tasks.cpp (#3293)
# Notes
- `task_state` is verified by `safe_delete`.
- `size` is the name of a member variable, we should just use `sizeof(uint32_t)` instead.
2023-04-14 19:38:28 -04:00
Alex King 21002c2e8a [Quest API] Fix LDoN Methods in Perl/Lua (#3287)
# Perl
- Add `quest::removeldonloss(theme_id)`.
- Add `quest::removeldonwin(theme_id)`.

# Lua
- Fix `eq.remove_ldon_win(theme_id)` as it was using `quest_manager.addldonwin(theme_id)` instead of `quest_manager.removeldonwin(theme_id)`.
2023-04-10 16:16:54 -04:00
Alex King 445f967ed6 [Quest API] Add ApplySpellRaid() and SetSpellDurationRaid() to Bots in Perl/Lua (#3274)
# Perl
- Add `$bot->ApplySpellRaid(spell_id)`.
- Add `$bot->ApplySpellRaid(spell_id, duration)`.
- Add `$bot->ApplySpellRaid(spell_id, duration, allow_pets)`.
- Add `$bot->ApplySpellRaid(spell_id, duration, allow_pets, is_raid_group_only)`.
- Add `$bot->SetSpellDuration(spell_id)`.
- Add `$bot->SetSpellDuration(spell_id, duration)`.
- Add `$bot->SetSpellDuration(spell_id, duration, allow_pets)`.
- Add `$bot->SetSpellDuration(spell_id, duration, allow_pets, is_raid_group_only)`.

# Lua
- Add `bot:ApplySpellRaid(spell_id)`.
- Add `bot:ApplySpellRaid(spell_id, duration)`.
- Add `bot:ApplySpellRaid(spell_id, duration, allow_pets)`.
- Add `bot:ApplySpellRaid(spell_id, duration, allow_pets, is_raid_group_only)`.
- Add `bot:SetSpellDuration(spell_id)`.
- Add `bot:SetSpellDuration(spell_id, duration)`.
- Add `bot:SetSpellDuration(spell_id, duration, allow_pets)`.
- Add `bot:SetSpellDuration(spell_id, duration, allow_pets, is_raid_group_only)`.

# Notes
- These methods weren't added initially as we did not support bots in raid groups until recently.
2023-04-09 12:00:12 -04:00
Alex King 57a15d473f [Quest API] Add GetBuffSpellIDs() to Perl/Lua (#3273)
# Perl
- Add `$mob->GetBuffSpellIDs()`.

# Lua
- Add `$mob->GetBuffSpellIDs()`.

# Notes
- These methods allow operators to get a list of a mob's buff IDs without having to loop through their buffs themselves.
2023-04-09 10:58:35 -04:00
Trent df92c578d2 [Rules] Optional summoning when already in melee range (#3204)
* Add summon melee range rule

* Fix compilation

* Remove redundant range check for HateSummon
2023-04-08 18:04:17 -04:00
Aeadoin 3af43a8e8d [Hotfix] Resolve loading of inventory (#3272) 2023-04-08 17:45:06 -04:00
Aeadoin 647bcce30b [Crash] Resolve crash due to uninitialized pointer. (#3271) 2023-04-08 17:21:53 -04:00
Alex King 25b527156c [Cleanup] Fix possible nullptr inst in GetSharedBank() (#3190)
* [Cleanup] Fix possible nullptr inst in GetSharedBank()

# Notes
- We weren't continuing if we had a `nullptr`.

* Update shareddb.cpp

* Fix.
2023-04-08 09:42:10 -04:00
Aeadoin b3ab7deb80 [Bots] Cleanup GetBotTables() (#3270) 2023-04-06 17:43:57 -05:00
Alex King 4a9cb07132 [Cleanup] Remove unnecessary setting of reuse variable in Bot::DoClassAttacks() (#3233)
# Notes
- Bash, Kick, and Taunt have the same reuse time, no reason to set it to the same value.
2023-04-05 19:17:15 -04:00
Alex King 8f1b62d166 [Cleanup] Remove always true/false conditions from bot.cpp (#3237)
* [Cleanup] Remove always true/false conditions from bot.cpp

# Notes
- Some of these conditions were always true or false based on previous conditions.

* Update bot.cpp
2023-04-05 19:05:49 -04:00
Alex King 7e9994b5d4 [Cleanup] Fix ornamentation augment icons in inspect requests (#3264)
* [Cleanup] Fix ornamentation augment icons in inspect requests

# Notes
- We were not setting `aug_item` to the ornamentation augment when we found one.

* Update client.cpp
2023-04-05 19:04:32 -04:00
Chris Miles f2f8fae58b [Telnet] Telnet encoding fix (#3269) 2023-04-05 12:16:25 -04:00
Alex King 3a1e88f9ed [Cleanup] Remove unused SetConfigFile in common/eqemu_config.h (#3208)
# Notes
- This is unused.
2023-04-05 12:15:10 -04:00
Alex King 4e101aa6d6 [Cleanup] Use default dtor instead of empty dtor for EQTime in eqtime.cpp/eqtime.h (#3210)
# Notes
- This is better than using an empty dtor.
2023-04-05 12:15:02 -04:00
Alex King ef411ee154 [Cleanup] Use default ctor instead of an empty ctor. (#3206)
# Notes
- Use `= default;` instead of an empty ctor.
- https://pvs-studio.com/en/docs/warnings/v832/
2023-04-05 12:14:22 -04:00
Alex King 93b3f97f24 [Cleanup] Cleanup discord.cpp and discord_manager.cpp (#3205)
# Notes
- Unused variables in `discord.cpp`.
- Use `.clear()` instead of setting to `""` in `discord_manager.cpp`.
2023-04-05 12:14:14 -04:00
Alex King c1d4cb90b9 [Cleanup] Cleanup cheap-to-copy reference to use value instead in eq_stream_ident.cpp/eq_stream_ident.h (#3209)
# Notes
- More performant to pass by value than by reference.
2023-04-05 12:14:01 -04:00
Alex King e939c82717 [Cleanup] Convert equipable_slot_list to std::vector from std::list in bot_command.cpp (#3253)
# Notes
- No need to use a `std::list` here.
2023-04-05 11:35:04 -04:00
Alex King 7d03479f41 [Cleanup] Use constant reference and check for empty string properly in dbcore.cpp (#3203)
# Notes
- Passing by constant reference is more performant.
- Checking for empty string with `!= '\0'` is more performant.
- https://pvs-studio.com/en/docs/warnings/v805/
- https://pvs-studio.com/en/docs/warnings/v813/
2023-04-05 11:27:50 -04:00
Alex King ff440e16b6 [Cleanup] Use .clear() and .empty() instead of comparing to empty string or setting to empty string in CheckDatabaseConvertPPBlob() (#3201)
# Notes
- Use these methods to increase performance.
2023-04-05 11:27:12 -04:00
Alex King c6bb0f6495 [Cleanup] Move variable definition to more relevant scope in DatabaseDumpService::Dump() (#3200)
# Notes
- This was unused except for in this one spot, move to scope of condition where it's used.
- https://pvs-studio.com/en/docs/warnings/v821/
2023-04-05 11:26:21 -04:00
Alex King d142bc552a [Cleanuo] Only define row if we have results in Database::GetCharacterID() (#3199)
# Notes
- This is more performant and we don't unnecessarily define a variable we can't use.
- https://pvs-studio.com/en/docs/warnings/v821/
2023-04-05 11:25:28 -04:00
Alex King 7dc57c3b05 [Cleanup] Utilize .empty() instead of checking for an empty string in Database::ReserveName() (#3198)
# Notes
- This is more performant.
- https://pvs-studio.com/en/docs/warnings/v815/
2023-04-05 11:24:54 -04:00
Alex King ea9b09cf1f [Cleanup] Remove unused variable in Database::CopyCharacter() (#3197)
# Notes
- This variable was created but never used.
- https://pvs-studio.com/en/docs/warnings/v808/
2023-04-05 11:24:27 -04:00
Alex King 968278d8f8 [Cleanup] Use .clear() instead of setting string to empty in eqemu_command_handler.cpp (#3195)
# Notes
- `x = ""` has less performance than `x.clear()`.
- https://pvs-studio.com/en/docs/warnings/v815/
2023-04-05 11:24:12 -04:00
Alex King aa910864c8 [Cleanup] Remove unused macros in common/types.h (#3194)
# Notes
- These are unused.
2023-04-05 11:23:37 -04:00
Alex King 1499f3338e [Cleanup] Remove always true condition in Strings::Commify() (#3193)
# Notes
- `i < 0` was always true.
2023-04-05 11:23:24 -04:00
Alex King fef2f9fc61 [Cleanup] Fix shared_tasks.cpp/shared_tasks.cpp variable named same as class member (#3192)
* [Cleanup] Fix shared_tasks.cpp/shared_tasks.cpp variable named same as class member

# Notes
- This variable was named `m_db_shared_task` which is the same as `SharedTask:;m_db_shared_task`.

* Single letter receiver of complex type.
2023-04-05 11:22:42 -04:00
Alex King 8afbc585da [Cleanup] Remove bool return from GetSharedPlatinum() (#3191)
# Notes
- This was returning `false` and implicitly converting it to an integer.
2023-04-05 11:22:23 -04:00
Alex King 457ce85746 [Cleanup] Cleanup always true/false statements in shareddb.cpp (#3189)
# Notes
- `parent_index < EQ::invslot::SLOT_BEGIN` was always `false`.
- `item->LoreGroup != -1` was always `true`.
2023-04-05 11:21:43 -04:00
Alex King 49c093dc62 [Cleanup] Remove always true statement in say_link.cpp (#3188)
# Notes
- This is always true since we check `!saylinks.empty()` prior to this.
2023-04-05 11:20:52 -04:00
Alex King beccd557a8 [Cleanup] Cleanup item_instance.cpp always true statements and reassigning of same values (#3187)
# Notes
- Some things were always true.
- Some values were reassigned to the value they already were.
2023-04-05 11:20:36 -04:00
Alex King e11610b9fa [Cleanup] Remove unnecessary check for IsStackable() in DeleteItem() (#3186)
# Notes
- We check the opposites therefore we don't need either.
- https://pvs-studio.com/en/docs/warnings/v728/
2023-04-05 11:20:13 -04:00
Alex King 3e652b98bc [Cleanup] Cleanup macros in features.h (#3185)
# Notes
- These needed to either be wrapped in parentheses or simplified to their values.
- https://pvs-studio.com/en/docs/warnings/v1003/
2023-04-05 11:18:22 -04:00
Alex King d43af28de4 [Cleanup] Multiple cases with same outcome in GetDiscordPayloadFromEvent() (#3184)
# Notes
- All 4 of these use `FormatWithNodata`.
2023-04-05 11:17:52 -04:00
Alex King f5106b6af6 [Cleanup] Remove unused code in eq_packet.cpp/eq_packet.h (#3183)
# Notes
- These are unused.
2023-04-05 11:17:29 -04:00
Alex King 3386d13d2d [Cleanup] results variable is assigned but never used in SaveCharacterCreate() (#3180)
# Notes
- This was unnecessary since `QueryDatabase()` runs regardless.
2023-04-05 11:17:10 -04:00
Alex King d1b7c675f9 [Cleanup] Validate for nullptrs in bot.cpp (#3232)
* [Cleanup] Validate for nullptrs in bot.cpp

# Notes
- Validate for nullptrs in these spots in bot.cpp before using the variable.

* Update bot.cpp
2023-04-05 11:15:46 -04:00
Alex King a40e1cf893 [Cleanup] Add missing breaks and returns in bonuses.cpp (#3231)
# Notes
- Many spots were missing a `break;` or a `return` for their value.
2023-04-05 11:15:22 -04:00
Alex King c81ab00764 [Cleanup] Set bonuses to use spell ID instead of boolean (#3230)
# Notes
- Spell bonuses `Illusion` is the spell ID, not a boolean.
2023-04-05 11:14:55 -04:00
Alex King 025ef5e1d6 [Cleanup] Move unreachable code in ApplySpellsBonuses() (#3229)
# Notes
- This code was unreachable since it was inside the switch and should have been checked on its own in the condition where we verify we are using AISpellEffects.
2023-04-05 11:14:28 -04:00
Alex King 1f29a40e6d [Cleanup] Remove extraneous check for NegateAttacks in SE_NegateAttacks (#3228)
# Notes
- We checked both, we only need to check one.
2023-04-05 11:12:02 -04:00
Alex King 66cadd599b [Cleanup] Remove extraneous parentheses around math in Mob::ApplySpellsBonuses() (#3227)
# Notes
- Extra parentheses.
2023-04-05 11:11:41 -04:00
Alex King aa0345c1f1 [Cleanup] Cleanup duplicate conditions in negate bonuses in bonuses.cpp (#3226)
# Notes
- Lots of duplicate conditions.
2023-04-05 11:11:22 -04:00
Alex King 73b11c5036 [Cleanup] SE_StrikeThrough and SE_StrikeThrough2 are the same in bonuses.cpp (#3223)
# Notes
- These were the same code duplicated.
2023-04-05 11:05:59 -04:00
Alex King efbeb2dbb7 [Cleanup] SE_AttackSpeed3 effect_value is always less than 0 (#3222)
# Notes
- This was always false.
2023-04-05 11:05:44 -04:00
Alex King 8c97c20727 [Cleanup] Fix skill_used being used as boolean in Mob::CommonDamage() (#3220)
# Notes
- This is unnecessary as we always have a skill value.
2023-04-05 11:03:28 -04:00
Alex King f2d07e5c69 [Cleanup] Remove unnecessary break in while loop in Mob::AddToHateList() (#3219)
# Notes
- This is unnecessary and breaks the loop for no reason.
2023-04-05 10:31:57 -04:00
Alex King 64d5b54e65 [Cleanup] Fix filter condition in attack.cpp (#3218)
# Notes
- This condition was causing them to be used as `booleans` versus being checked individually.
2023-04-05 10:31:34 -04:00
Alex King 89b3a04eb3 [Cleanup] Identical conditions right beside each other in aa.cpp (#3213)
# Notes
- These conditions were identical and could be consolidated.
2023-04-05 10:30:27 -04:00
Alex King 1bafe0b6b3 [Cleanup] other is always defined in these cases in attack.cpp (#3217)
# Notes
- `other` is always defined since we check it prior to checking here.
2023-04-05 10:30:13 -04:00
Alex King 82762c3f5a [Cleanup] Use variable for character instead of a loop (#3268)
# Notes
- Store character in a variable instead of looping a list of 1 entry.
2023-04-05 10:29:16 -04:00
Alex King 2742eca119 [Cleanup] Remove unnecessary conditions in Client::SendFactionMessage() (#3267)
# Notes
- `faction_value < this_faction_max` and `faction_value > this_faction_min` are always true if they get to that point in the code.
2023-04-05 10:27:15 -04:00
Alex King 8fc7f3a732 [Cleanup] Cleanup unnecessary condition in Client::SendAlternateCurrencyValue() (#3266)
# Notes
- `value == 0` is unnecessary as it can only be 0 if we fail the `value > 0` check.
2023-04-05 10:27:01 -04:00
Alex King 39ce0178f9 [Cleanup] Remove unnecessary conditions in Client::Consume() (#3265)
# Notes
- We check `increase < 0` prior to this, so this can't ever happen.
2023-04-05 10:26:32 -04:00
Alex King 3d2f560436 [Cleanup] Fix GetLastName() length check in Client::SendWindow() (#3263)
# Notes
- `target->GetLastName()` was always true, we need to make sure the target has a last name.
2023-04-05 10:23:54 -04:00
Alex King a0768d2d28 [Cleanup] Remove unnecessary conditions in Client::FilteredMessageCheck() (#3262)
# Notes
- We check `FilterHide` prior to the secondary conditions, so it can never show up.
2023-04-05 10:23:33 -04:00
Alex King 9009a7aa23 [Cleanup] Remove extra assignment of current_endurance in Client ctor (#3261)
# Notes
- We already assign `current_endurance` to `0`, no need to do it again.
2023-04-05 10:23:20 -04:00
Alex King 67b03b4e31 [Cleanup] Combine similar cases in Client::InitInnates() (#3260)
# Notes
- These cases were the same, consolidating them is better.
2023-04-05 10:23:05 -04:00
Alex King b08975aefb [Cleanup] Use .empty() in Client::ScribeSpells() and Client::LearnDisciplines() (#3259)
* [Cleanup] Use .empty() in Client::ScribeSpells() and Client::LearnDisciplines()

# Notes
- Use `.empty()` instead of using a variable storing size in condition.

* Update client.cpp
2023-04-05 10:22:36 -04:00
Alex King ea3a7cae0b [Cleanup] Remove always true conditions and unreachable code in Client::SendMercPersonalInfo() (#3258)
* [Cleanup] Remove unreachable code in Client::SendMercPersonalInfo()

# Notes
- This cannot be reached due to prior returns.

* Update client.cpp

* Update client.cpp
2023-04-05 10:14:07 -04:00
Alex King 81314a3315 [Cleanup] Fix check for !this in Client::SendHPUpdateMarquee() (#3257)
# Notes
- `!this` isn't valid, as `this` can never be nullptr.
2023-04-05 10:13:24 -04:00
Alex King d33cfad567 [Cleanup] Fix always false conditions in Client::IncStats() (#3256)
# Notes
- Value can never be less than `0` as it's unsigned.
2023-04-05 10:12:32 -04:00
Alex King c1698a5bdd [Cleanup] Fix possible overflows in Client::AddPlatinum() and Client::TakePlatinum() (#3255)
# Notes
- Fix possible overflows by casting properly.
2023-04-05 10:10:33 -04:00
Alex King 2a094e8792 [Cleanup] Use variable for c->GetTarget() instead of calling multiple times in bot_command.cpp (#3254)
# Notes
- Calling multiple times is less performant than using a variable.
2023-04-05 10:09:19 -04:00
Alex King 4a0725e278 [Cleanup] Cleanup string -> char* -> string conversions in bot_command.cpp (#3252)
# Notes
- We were converting back and forth between types unnecessarily.
2023-04-05 09:59:43 -04:00
Alex King 218ffbb2c5 [Cleanup] Delete unused strings in bot_command.cpp (#3251)
# Notes
- These are unused.
2023-04-05 09:59:24 -04:00
Chris Miles 3e30e78158 [Backups] Fix database dump error reporting (#3175)
* [Backups] Fix database dump error reporting

* Update database_dump_service.cpp
2023-04-04 00:14:23 -05:00
175 changed files with 10386 additions and 4573 deletions
+302
View File
@@ -1,3 +1,305 @@
## [22.13.1] - 06/13/2023
### Targeting
* Revert #3383 ([#3405](https://github.com/EQEmu/Server/pull/3405)) @noudess 2023-06-13
## [22.13.0] - 06/12/2023
### Code
* Add GMFind_Struct to packet structures ([#3402](https://github.com/EQEmu/Server/pull/3402)) @Kinglykrab 2023-06-12
* Remove CHECK_LOS_STEP from zone/common.h ([#3398](https://github.com/EQEmu/Server/pull/3398)) @Kinglykrab 2023-06-12
* Remove CheckCoordLosNoZLeaps() from zone/entity.cpp and zone/entity.h ([#3384](https://github.com/EQEmu/Server/pull/3384)) @Kinglykrab 2023-06-12
* Remove CountTempPets() from zone/entity.cpp and zone/entity.h ([#3390](https://github.com/EQEmu/Server/pull/3390)) @Kinglykrab 2023-06-12
* Remove Evade() from zone/entity.cpp and zone/entity.h ([#3394](https://github.com/EQEmu/Server/pull/3394)) @Kinglykrab 2023-06-12
* Remove GateAllClients() from zone/entity.cpp and zone/entity.h ([#3391](https://github.com/EQEmu/Server/pull/3391)) @Kinglykrab 2023-06-12
* Remove GetClient(ip, port) from zone/entity.h ([#3386](https://github.com/EQEmu/Server/pull/3386)) @Kinglykrab 2023-06-12
* Remove GetClientCount() from zone/entity.cpp and zone/entity.h ([#3392](https://github.com/EQEmu/Server/pull/3392)) @Kinglykrab 2023-06-12
* Remove GetGroupByBot(), GetRaidByMob(), and GetRaidByLeaderName() from zone/entity.cpp and zone/entity.h ([#3387](https://github.com/EQEmu/Server/pull/3387)) @Kinglykrab 2023-06-12
* Remove InteractiveChat() and TakenAction() from zone/npc.h ([#3382](https://github.com/EQEmu/Server/pull/3382)) @Kinglykrab 2023-06-12
* Remove LimitCheckBoth() from zone/entity.cpp and zone/entity.h ([#3393](https://github.com/EQEmu/Server/pull/3393)) @Kinglykrab 2023-06-12
* Remove NPC::AddCash() from npc.cpp/npc.h ([#3380](https://github.com/EQEmu/Server/pull/3380)) @Kinglykrab 2023-06-09
* Remove RemoveMob() and RemoveRaid() from zone/entity.cpp and zone/entity.h ([#3389](https://github.com/EQEmu/Server/pull/3389)) @Kinglykrab 2023-06-12
* Remove SPECIALIZE_MANA_REDUCE from zone/common.h ([#3400](https://github.com/EQEmu/Server/pull/3400)) @Kinglykrab 2023-06-12
* Remove SendAATimer() from zone/entity.h ([#3388](https://github.com/EQEmu/Server/pull/3388)) @Kinglykrab 2023-06-12
* Remove WriteEntityIDs() from zone/entity.cpp and zone/entity.h ([#3395](https://github.com/EQEmu/Server/pull/3395)) @Kinglykrab 2023-06-12
* Remove _BECOMENPCPET() and _NPCPET() from zone/common.h ([#3399](https://github.com/EQEmu/Server/pull/3399)) @Kinglykrab 2023-06-12
* Remove pDBAsyncWorkID from zone/entity.h ([#3385](https://github.com/EQEmu/Server/pull/3385)) @Kinglykrab 2023-06-12
* Remove struct DynamicZoneSafeReturn from zone/entity.h ([#3396](https://github.com/EQEmu/Server/pull/3396)) @Kinglykrab 2023-06-12
* Remove struct TradeEntity from zone/common.h ([#3397](https://github.com/EQEmu/Server/pull/3397)) @Kinglykrab 2023-06-12
### Commands
* Assign #opcode to a #reload alias ([#3401](https://github.com/EQEmu/Server/pull/3401)) @Kinglykrab 2023-06-12
### Illusions
* RandomizeFeatures and SetGender were killing db texture ([#3376](https://github.com/EQEmu/Server/pull/3376)) @noudess 2023-06-06
### Logging
* Fixed statements that logged incorrect data ([#3381](https://github.com/EQEmu/Server/pull/3381)) @noudess 2023-06-07
### Quest API
* Add GetEXPForLevel() to Perl/Lua ([#3403](https://github.com/EQEmu/Server/pull/3403)) @Kinglykrab 2023-06-12
* Add SendChannelMessage() to Perl/Lua ([#3378](https://github.com/EQEmu/Server/pull/3378)) @Kinglykrab 2023-06-04
* Add several spell methods to Perl/Lua ([#3379](https://github.com/EQEmu/Server/pull/3379)) @Kinglykrab 2023-06-12
### Targeting
* /tar <bad target> should not untarget existing target ([#3383](https://github.com/EQEmu/Server/pull/3383)) @noudess 2023-06-12
## [22.12.0] - 05/29/2023
### Code
* Cleanup #setskill and #setskillall Commands ([#3367](https://github.com/EQEmu/Server/pull/3367)) @Kinglykrab 2023-05-25
* Delete message.h ([#3348](https://github.com/EQEmu/Server/pull/3348)) @Kinglykrab 2023-05-17
* Fix #spawn command NPCs having 0 health ([#3371](https://github.com/EQEmu/Server/pull/3371)) @Kinglykrab 2023-05-21
* Remove CalcPetHp from spdat.h ([#3364](https://github.com/EQEmu/Server/pull/3364)) @Kinglykrab 2023-05-25
* Remove CountNPC() and QueueManaged() from entity.cpp/entity.h ([#3346](https://github.com/EQEmu/Server/pull/3346)) @Kinglykrab 2023-05-17
* Remove DumpMerchantList() from zone.cpp/zone.h ([#3343](https://github.com/EQEmu/Server/pull/3343)) @Kinglykrab 2023-05-17
* Remove GetDamageReceived() and GetHealReceived() from combat_record.cpp/combat_record.h ([#3358](https://github.com/EQEmu/Server/pull/3358)) @Kinglykrab 2023-05-17
* Remove GetEscapingEntOnHateList() from hate_list.cpp/hate_list.h ([#3353](https://github.com/EQEmu/Server/pull/3353)) @Kinglykrab 2023-05-17
* Remove GetMaxRank() from aa_ability.cpp/aa_ability.h ([#3347](https://github.com/EQEmu/Server/pull/3347)) @Kinglykrab 2023-05-25
* Remove IsEntityInFrenzyMode() from hate_list.cpp/hate_list.h ([#3352](https://github.com/EQEmu/Server/pull/3352)) @Kinglykrab 2023-05-17
* Remove IsRaid() from raids.h ([#3361](https://github.com/EQEmu/Server/pull/3361)) @Kinglykrab 2023-05-25
* Remove LoadSpawn2() and PopulateZoneSpawnListClose() from spawn2.cpp/zonedb.h ([#3344](https://github.com/EQEmu/Server/pull/3344)) @Kinglykrab 2023-05-25
* Remove SetGraveyard() from zone.cpp/zone.h ([#3354](https://github.com/EQEmu/Server/pull/3354)) @Kinglykrab 2023-05-17
* Remove SetTradeCash() from trading.cpp/common.h ([#3356](https://github.com/EQEmu/Server/pull/3356)) @Kinglykrab 2023-05-17
* Remove TraderUpdate() from trading.cpp/client.h ([#3357](https://github.com/EQEmu/Server/pull/3357)) @Kinglykrab 2023-05-17
* Remove TypeToSkill() from tradeskills.cpp/object.h ([#3355](https://github.com/EQEmu/Server/pull/3355)) @Kinglykrab 2023-05-17
* Remove Z_AGGRO from spdat.h ([#3365](https://github.com/EQEmu/Server/pull/3365)) @Kinglykrab 2023-05-25
* Remove numMembers from raids.h ([#3362](https://github.com/EQEmu/Server/pull/3362)) @Kinglykrab 2023-05-25
* Set GetAugmentType() to int again ([#3335](https://github.com/EQEmu/Server/pull/3335)) @Kinglykrab 2023-05-08
### Commands
* Add #findcurrency Command ([#3368](https://github.com/EQEmu/Server/pull/3368)) @Kinglykrab 2023-05-25
* Add entity variable command ([#3345](https://github.com/EQEmu/Server/pull/3345)) @Kinglykrab 2023-05-25
* Cleanup #setanim ([#3350](https://github.com/EQEmu/Server/pull/3350)) @Kinglykrab 2023-05-25
### Feature
* Intoxication setter/getter for source, getter for Perl/Lua ([#3330](https://github.com/EQEmu/Server/pull/3330)) @JasXSL 2023-05-03
### Fixes
* #augmentitem bypasses augment restrictions ([#3332](https://github.com/EQEmu/Server/pull/3332)) @Kinglykrab 2023-05-07
* Fix Heroic INT/WIS Bonuses ([#3341](https://github.com/EQEmu/Server/pull/3341)) @RekkasGit 2023-05-15
* Fix duplicate messages in #npcedit ([#3372](https://github.com/EQEmu/Server/pull/3372)) @Kinglykrab 2023-05-21
* Fix issue with Group Pointers/Member roles ([#3374](https://github.com/EQEmu/Server/pull/3374)) @Aeadoin 2023-05-25
* Fix mob item bonus calc ([#3334](https://github.com/EQEmu/Server/pull/3334)) @Akkadius 2023-05-07
* Fix typos in #zheader ([#3370](https://github.com/EQEmu/Server/pull/3370)) @Kinglykrab 2023-05-21
* Mob scaling issue with min dmg set to zero while max dmg is not ([#3351](https://github.com/EQEmu/Server/pull/3351)) @RekkasGit 2023-05-20
* NPC Armor Upgrade to a slot not handled correctly ([#3366](https://github.com/EQEmu/Server/pull/3366)) @noudess 2023-05-20
* ReloadQuests() on Zone::Init() to avoid cached global quests/plugins ([#3333](https://github.com/EQEmu/Server/pull/3333)) @Kinglykrab 2023-05-07
* Revert " ReloadQuests() on Zone::Init() to avoid cached global quests/plugins " ([#3333](https://github.com/EQEmu/Server/pull/3333)) @Akkadius 2023-05-08
### Memory Leak
* Fix large memory leak introduced in CalcItemBonuses ([#3331](https://github.com/EQEmu/Server/pull/3331)) @Akkadius 2023-05-07
### Messages
* Remove duplicate heal message for healing yourself ([#3329](https://github.com/EQEmu/Server/pull/3329)) @noudess 2023-05-03
### Performance
* Character bind is now bulk saved ([#3338](https://github.com/EQEmu/Server/pull/3338)) @Akkadius 2023-05-09
* Character buffs now save in bulk ([#3336](https://github.com/EQEmu/Server/pull/3336)) @Akkadius 2023-05-09
* Character pet bulk saving ([#3337](https://github.com/EQEmu/Server/pull/3337)) @Akkadius 2023-05-09
* Character tribute is now bulk saved ([#3340](https://github.com/EQEmu/Server/pull/3340)) @Kinglykrab 2023-05-25
* Mail key is now cached during player load ([#3339](https://github.com/EQEmu/Server/pull/3339)) @Akkadius 2023-05-09
### Pets
* Fix saving inconsistencies with pets ([#3375](https://github.com/EQEmu/Server/pull/3375)) @Akkadius 2023-05-25
### Quest API
* Add GetHateListClosest(), GetHateListClosestBot(), GetHateListClosestClient(), and GetHateListClosestNPC() methods/overloads to Perl/Lua ([#3359](https://github.com/EQEmu/Server/pull/3359)) @RekkasGit 2023-05-16
* Add GetPet() to Perl ([#3309](https://github.com/EQEmu/Server/pull/3309)) @Kinglykrab 2023-05-08
* Add Memorize and Scribe Spell Events to Perl/Lua ([#3363](https://github.com/EQEmu/Server/pull/3363)) @Kinglykrab 2023-05-25
* Add zone data methods to Perl/Lua ([#3342](https://github.com/EQEmu/Server/pull/3342)) @Kinglykrab 2023-05-24
* Cleanup The Darkened Sea Quest Methods Names ([#3369](https://github.com/EQEmu/Server/pull/3369)) @Kinglykrab 2023-05-21
### Rules
* Add World:MaximumQuestErrors Rule ([#3349](https://github.com/EQEmu/Server/pull/3349)) @Kinglykrab 2023-05-21
* ResurrectionEffectBlock to prevent/allow/move buffs. ([#3288](https://github.com/EQEmu/Server/pull/3288)) @nytmyr 2023-05-08
## [22.11.0] - 04/29/2023
### Code
* Add check for owner in quest::pausetimer() ([#3304](https://github.com/EQEmu/Server/pull/3304)) @Kinglykrab 2023-04-23
* Add check for owner in quest::resumetimer() ([#3305](https://github.com/EQEmu/Server/pull/3305)) @Kinglykrab 2023-04-23
* Add initiator/owner checks to various methods in questmgr.cpp ([#3306](https://github.com/EQEmu/Server/pull/3306)) @Kinglykrab 2023-04-23
* Fix possible nullptr in quest::addloot() ([#3303](https://github.com/EQEmu/Server/pull/3303)) @Kinglykrab 2023-04-23
* Remove GetClassHPFactor() from zone/client_mods.cpp and zone/client.h ([#3313](https://github.com/EQEmu/Server/pull/3313)) @Kinglykrab 2023-04-30
* Remove GetClassHPFactor() from zone/merc.h ([#3314](https://github.com/EQEmu/Server/pull/3314)) @Kinglykrab 2023-04-30
* Remove pDontCastBefore_casting_spell from zone/npc.h ([#3311](https://github.com/EQEmu/Server/pull/3311)) @Kinglykrab 2023-04-30
* Remove unused code in zone/pets.cpp ([#3310](https://github.com/EQEmu/Server/pull/3310)) @Kinglykrab 2023-04-30
* Remove unused methods in zone/bot.cpp and zone/bot.h ([#3315](https://github.com/EQEmu/Server/pull/3315)) @Kinglykrab 2023-04-30
* Remove unused methods in zone/client.cpp and zone/client.h ([#3312](https://github.com/EQEmu/Server/pull/3312)) @Kinglykrab 2023-04-30
* Remove unused variable in common/crash.cpp ([#3308](https://github.com/EQEmu/Server/pull/3308)) @Kinglykrab 2023-04-30
* Use default ctor/dtor in oriented_bounding_box.h ([#3307](https://github.com/EQEmu/Server/pull/3307)) @Kinglykrab 2023-04-30
* quest::createBot() unnecessary check against nullptr ([#3302](https://github.com/EQEmu/Server/pull/3302)) @Kinglykrab 2023-04-23
* quest::setallskill() had always true condition. ([#3301](https://github.com/EQEmu/Server/pull/3301)) @Kinglykrab 2023-04-30
### Crash
* Fix UCS crash that occurs during log reloading ([#3324](https://github.com/EQEmu/Server/pull/3324)) @Akkadius 2023-04-30
* Fix possible dereference of nullptr in Client::CalcHPRegen ([#3316](https://github.com/EQEmu/Server/pull/3316)) @Aeadoin 2023-04-23
* Fix possible nullptr in Client::GetCharMaxLevelFromQGlobal() ([#3317](https://github.com/EQEmu/Server/pull/3317)) @Kinglykrab 2023-04-23
### Discord
* Add Discord webhook callback processing to world ([#3322](https://github.com/EQEmu/Server/pull/3322)) @Akkadius 2023-04-30
### Fixes
* Fix issue with NPCs no longer using some armor. ([#3318](https://github.com/EQEmu/Server/pull/3318)) @noudess 2023-04-24
* Fix issue with spawning Mercs ([#3327](https://github.com/EQEmu/Server/pull/3327)) @Aeadoin 2023-04-29
* Possible issues with SummonItem in Client::QuestReward() methods ([#3325](https://github.com/EQEmu/Server/pull/3325)) @Kinglykrab 2023-04-27
### Maps
* Update download with faster releases link ([#3321](https://github.com/EQEmu/Server/pull/3321)) @Akkadius 2023-04-30
### Messages
* Remove duplicate you have lost a level message ([#3323](https://github.com/EQEmu/Server/pull/3323)) @noudess 2023-04-25
### Quest API
* Add GetDefaultRaceSize() overloads to Perl/Lua ([#3320](https://github.com/EQEmu/Server/pull/3320)) @Kinglykrab 2023-04-30
* Add HasSpellEffect() to Perl/Lua ([#3319](https://github.com/EQEmu/Server/pull/3319)) @Kinglykrab 2023-04-30
## [22.10.0] - 04/22/2023
### Backups
* Fix database dump error reporting ([#3175](https://github.com/EQEmu/Server/pull/3175)) @Akkadius 2023-04-04
### Bots
* Cleanup GetBotTables() ([#3270](https://github.com/EQEmu/Server/pull/3270)) @Aeadoin 2023-04-06
### Cleanuo
* Only define row if we have results in Database::GetCharacterID() ([#3199](https://github.com/EQEmu/Server/pull/3199)) @Kinglykrab 2023-04-05
### Code
* Add missing breaks and returns in bonuses.cpp ([#3231](https://github.com/EQEmu/Server/pull/3231)) @Kinglykrab 2023-04-05
* Breaks in wrong spot in cases in spell_effects.cpp ([#3297](https://github.com/EQEmu/Server/pull/3297)) @Kinglykrab 2023-04-22
* Cleanup always true/false statements in shareddb.cpp ([#3189](https://github.com/EQEmu/Server/pull/3189)) @Kinglykrab 2023-04-05
* Cleanup cheap-to-copy reference to use value instead in eq_stream_ident.cpp/eq_stream_ident.h ([#3209](https://github.com/EQEmu/Server/pull/3209)) @Kinglykrab 2023-04-05
* Cleanup discord.cpp and discord_manager.cpp ([#3205](https://github.com/EQEmu/Server/pull/3205)) @Kinglykrab 2023-04-05
* Cleanup duplicate conditions in negate bonuses in bonuses.cpp ([#3226](https://github.com/EQEmu/Server/pull/3226)) @Kinglykrab 2023-04-05
* Cleanup item_instance.cpp always true statements and reassigning of same values ([#3187](https://github.com/EQEmu/Server/pull/3187)) @Kinglykrab 2023-04-05
* Cleanup macros in features.h ([#3185](https://github.com/EQEmu/Server/pull/3185)) @Kinglykrab 2023-04-05
* Cleanup string -> char* -> string conversions in bot_command.cpp ([#3252](https://github.com/EQEmu/Server/pull/3252)) @Kinglykrab 2023-04-05
* Cleanup unnecessary condition in Client::SendAlternateCurrencyValue() ([#3266](https://github.com/EQEmu/Server/pull/3266)) @Kinglykrab 2023-04-05
* Cleanup zone/zoning.cpp ([#3289](https://github.com/EQEmu/Server/pull/3289)) @Kinglykrab 2023-04-14
* Combine similar cases in Client::InitInnates() ([#3260](https://github.com/EQEmu/Server/pull/3260)) @Kinglykrab 2023-04-05
* Convert equipable_slot_list to std::vector from std::list in bot_command.cpp ([#3253](https://github.com/EQEmu/Server/pull/3253)) @Kinglykrab 2023-04-05
* Delete embxs.cpp/embxs.h ([#3284](https://github.com/EQEmu/Server/pull/3284)) @Kinglykrab 2023-04-14
* Delete unused strings in bot_command.cpp ([#3251](https://github.com/EQEmu/Server/pull/3251)) @Kinglykrab 2023-04-05
* Fix GetLastName() length check in Client::SendWindow() ([#3263](https://github.com/EQEmu/Server/pull/3263)) @Kinglykrab 2023-04-05
* Fix always false conditions in Client::IncStats() ([#3256](https://github.com/EQEmu/Server/pull/3256)) @Kinglykrab 2023-04-05
* Fix check for !this in Client::SendHPUpdateMarquee() ([#3257](https://github.com/EQEmu/Server/pull/3257)) @Kinglykrab 2023-04-05
* Fix filter condition in attack.cpp ([#3218](https://github.com/EQEmu/Server/pull/3218)) @Kinglykrab 2023-04-05
* Fix ornamentation augment icons in inspect requests ([#3264](https://github.com/EQEmu/Server/pull/3264)) @Kinglykrab 2023-04-05
* Fix possible nullptr inst in GetSharedBank() ([#3190](https://github.com/EQEmu/Server/pull/3190)) @Kinglykrab 2023-04-08
* Fix possible overflows in Client::AddPlatinum() and Client::TakePlatinum() ([#3255](https://github.com/EQEmu/Server/pull/3255)) @Kinglykrab 2023-04-05
* Fix shared_tasks.cpp/shared_tasks.cpp variable named same as class member ([#3192](https://github.com/EQEmu/Server/pull/3192)) @Kinglykrab 2023-04-05
* Fix skill_used being used as boolean in Mob::CommonDamage() ([#3220](https://github.com/EQEmu/Server/pull/3220)) @Kinglykrab 2023-04-05
* Identical conditions right beside each other in aa.cpp ([#3213](https://github.com/EQEmu/Server/pull/3213)) @Kinglykrab 2023-04-05
* Move unreachable code in ApplySpellsBonuses() ([#3229](https://github.com/EQEmu/Server/pull/3229)) @Kinglykrab 2023-04-05
* Move variable definition to more relevant scope in DatabaseDumpService::Dump() ([#3200](https://github.com/EQEmu/Server/pull/3200)) @Kinglykrab 2023-04-05
* Multiple cases with same outcome in GetDiscordPayloadFromEvent() ([#3184](https://github.com/EQEmu/Server/pull/3184)) @Kinglykrab 2023-04-05
* Remove ExportVarComplex() from embparser.cpp/embparser.h ([#3282](https://github.com/EQEmu/Server/pull/3282)) @Kinglykrab 2023-04-14
* Remove GetQGlobal() from qglobals.cpp/qglobals.h ([#3285](https://github.com/EQEmu/Server/pull/3285)) @Kinglykrab 2023-04-14
* Remove IsFullHP from mob.cpp/mob.h ([#3277](https://github.com/EQEmu/Server/pull/3277)) @Kinglykrab 2023-04-14
* Remove IsMeleeDmg() from skills.cpp/skills.h ([#3279](https://github.com/EQEmu/Server/pull/3279)) @Kinglykrab 2023-04-14
* Remove _GetMovementSpeed() from mob.h ([#3276](https://github.com/EQEmu/Server/pull/3276)) @Kinglykrab 2023-04-14
* Remove always true condition in Strings::Commify() ([#3193](https://github.com/EQEmu/Server/pull/3193)) @Kinglykrab 2023-04-05
* Remove always true conditions and unreachable code in Client::SendMercPersonalInfo() ([#3258](https://github.com/EQEmu/Server/pull/3258)) @Kinglykrab 2023-04-05
* Remove always true statement in say_link.cpp ([#3188](https://github.com/EQEmu/Server/pull/3188)) @Kinglykrab 2023-04-05
* Remove always true statements in task_client_state.cpp ([#3292](https://github.com/EQEmu/Server/pull/3292)) @Kinglykrab 2023-04-14
* Remove always true/false conditions from bot.cpp ([#3237](https://github.com/EQEmu/Server/pull/3237)) @Kinglykrab 2023-04-05
* Remove bool return from GetSharedPlatinum() ([#3191](https://github.com/EQEmu/Server/pull/3191)) @Kinglykrab 2023-04-05
* Remove extra assignment of current_endurance in Client ctor ([#3261](https://github.com/EQEmu/Server/pull/3261)) @Kinglykrab 2023-04-05
* Remove extraneous check for NegateAttacks in SE_NegateAttacks ([#3228](https://github.com/EQEmu/Server/pull/3228)) @Kinglykrab 2023-04-05
* Remove extraneous parentheses around math in Mob::ApplySpellsBonuses() ([#3227](https://github.com/EQEmu/Server/pull/3227)) @Kinglykrab 2023-04-05
* Remove getd(), geti(), InUse(), lasterr(), my_get_sv(), and VarExists() in embperl.cpp/embperl.h ([#3283](https://github.com/EQEmu/Server/pull/3283)) @Kinglykrab 2023-04-15
* Remove item_timers from questmgr.cpp/questmgr.h ([#3286](https://github.com/EQEmu/Server/pull/3286)) @Kinglykrab 2023-04-14
* Remove pendinggroup from mob.h ([#3278](https://github.com/EQEmu/Server/pull/3278)) @Kinglykrab 2023-04-14
* Remove position_same_update_count from client.cpp/client.h ([#3280](https://github.com/EQEmu/Server/pull/3280)) @Kinglykrab 2023-04-14
* Remove unnecessary break in while loop in Mob::AddToHateList() ([#3219](https://github.com/EQEmu/Server/pull/3219)) @Kinglykrab 2023-04-05
* Remove unnecessary check for IsStackable() in DeleteItem() ([#3186](https://github.com/EQEmu/Server/pull/3186)) @Kinglykrab 2023-04-05
* Remove unnecessary condition and cleanup variable name in tasks.cpp ([#3293](https://github.com/EQEmu/Server/pull/3293)) @Kinglykrab 2023-04-14
* Remove unnecessary conditions in Client::Consume() ([#3265](https://github.com/EQEmu/Server/pull/3265)) @Kinglykrab 2023-04-05
* Remove unnecessary conditions in Client::FilteredMessageCheck() ([#3262](https://github.com/EQEmu/Server/pull/3262)) @Kinglykrab 2023-04-05
* Remove unnecessary conditions in Client::SendFactionMessage() ([#3267](https://github.com/EQEmu/Server/pull/3267)) @Kinglykrab 2023-04-05
* Remove unnecessary setting of reuse variable in Bot::DoClassAttacks() ([#3233](https://github.com/EQEmu/Server/pull/3233)) @Kinglykrab 2023-04-05
* Remove unused SetConfigFile in common/eqemu_config.h ([#3208](https://github.com/EQEmu/Server/pull/3208)) @Kinglykrab 2023-04-05
* Remove unused code in eq_packet.cpp/eq_packet.h ([#3183](https://github.com/EQEmu/Server/pull/3183)) @Kinglykrab 2023-04-05
* Remove unused ctor and use default dtor in xtargetautohaters.h ([#3290](https://github.com/EQEmu/Server/pull/3290)) @Kinglykrab 2023-04-14
* Remove unused macros in common/types.h ([#3194](https://github.com/EQEmu/Server/pull/3194)) @Kinglykrab 2023-04-05
* Remove unused variable in Database::CopyCharacter() ([#3197](https://github.com/EQEmu/Server/pull/3197)) @Kinglykrab 2023-04-05
* Remove unused variables and use reference in task_manager.cpp ([#3291](https://github.com/EQEmu/Server/pull/3291)) @Kinglykrab 2023-04-14
* SE_AttackSpeed3 effect_value is always less than 0 ([#3222](https://github.com/EQEmu/Server/pull/3222)) @Kinglykrab 2023-04-05
* SE_StrikeThrough and SE_StrikeThrough2 are the same in bonuses.cpp ([#3223](https://github.com/EQEmu/Server/pull/3223)) @Kinglykrab 2023-04-05
* Set bonuses to use spell ID instead of boolean ([#3230](https://github.com/EQEmu/Server/pull/3230)) @Kinglykrab 2023-04-05
* Use .clear() and .empty() instead of comparing to empty string or setting to empty string in CheckDatabaseConvertPPBlob() ([#3201](https://github.com/EQEmu/Server/pull/3201)) @Kinglykrab 2023-04-05
* Use .clear() instead of setting string to empty in eqemu_command_handler.cpp ([#3195](https://github.com/EQEmu/Server/pull/3195)) @Kinglykrab 2023-04-05
* Use .empty() in Client::ScribeSpells() and Client::LearnDisciplines() ([#3259](https://github.com/EQEmu/Server/pull/3259)) @Kinglykrab 2023-04-05
* Use constant reference and check for empty string properly in dbcore.cpp ([#3203](https://github.com/EQEmu/Server/pull/3203)) @Kinglykrab 2023-04-05
* Use default ctor instead of an empty ctor. ([#3206](https://github.com/EQEmu/Server/pull/3206)) @Kinglykrab 2023-04-05
* Use default dtor instead of empty dtor for EQTime in eqtime.cpp/eqtime.h ([#3210](https://github.com/EQEmu/Server/pull/3210)) @Kinglykrab 2023-04-05
* Use variable for c->GetTarget() instead of calling multiple times in bot_command.cpp ([#3254](https://github.com/EQEmu/Server/pull/3254)) @Kinglykrab 2023-04-05
* Use variable for character instead of a loop ([#3268](https://github.com/EQEmu/Server/pull/3268)) @Kinglykrab 2023-04-05
* Utilize .empty() instead of checking for an empty string in Database::ReserveName() ([#3198](https://github.com/EQEmu/Server/pull/3198)) @Kinglykrab 2023-04-05
* Utilize IsTaunting(), SetPetPower(), SetPetType(), and SetTaunting() ([#3275](https://github.com/EQEmu/Server/pull/3275)) @Kinglykrab 2023-04-15
* Validate for nullptrs in bot.cpp ([#3232](https://github.com/EQEmu/Server/pull/3232)) @Kinglykrab 2023-04-05
* other is always defined in these cases in attack.cpp ([#3217](https://github.com/EQEmu/Server/pull/3217)) @Kinglykrab 2023-04-05
* results variable is assigned but never used in SaveCharacterCreate() ([#3180](https://github.com/EQEmu/Server/pull/3180)) @Kinglykrab 2023-04-05
### Crash
* Add additional raid integrity checks on Bot Spawn. ([#3295](https://github.com/EQEmu/Server/pull/3295)) @Aeadoin 2023-04-16
* Fix crash with uninitialized item instance, and Bot timeout ([#3296](https://github.com/EQEmu/Server/pull/3296)) @Aeadoin 2023-04-15
* Resolve crash due to uninitialized pointer. ([#3271](https://github.com/EQEmu/Server/pull/3271)) @Aeadoin 2023-04-08
### Feature
* Make ornamentations work with any augment type ([#3281](https://github.com/EQEmu/Server/pull/3281)) @Kinglykrab 2023-04-16
### Fixes
* Camping was causing player to leave raid, causing unexpected behavior ([#3299](https://github.com/EQEmu/Server/pull/3299)) @Aeadoin 2023-04-22
* Resolve loading of inventory ([#3272](https://github.com/EQEmu/Server/pull/3272)) @Aeadoin 2023-04-08
### Quest API
* Add ApplySpellRaid() and SetSpellDurationRaid() to Bots in Perl/Lua ([#3274](https://github.com/EQEmu/Server/pull/3274)) @Kinglykrab 2023-04-09
* Add GetBuffSpellIDs() to Perl/Lua ([#3273](https://github.com/EQEmu/Server/pull/3273)) @Kinglykrab 2023-04-09
* Fix LDoN Methods in Perl/Lua ([#3287](https://github.com/EQEmu/Server/pull/3287)) @Kinglykrab 2023-04-10
### Rules
* Optional summoning when already in melee range ([#3204](https://github.com/EQEmu/Server/pull/3204)) @trentdm 2023-04-08
### Telnet
* Telnet encoding fix ([#3269](https://github.com/EQEmu/Server/pull/3269)) @Akkadius 2023-04-05
## [22.9.1] - 04/03/2023
### Code
+29
View File
@@ -630,6 +630,20 @@ bool IsINTCasterClass(uint8 class_id)
}
}
bool IsHeroicINTCasterClass(uint8 class_id)
{
switch (class_id) {
case NECROMANCER:
case WIZARD:
case MAGICIAN:
case ENCHANTER:
case SHADOWKNIGHT:
return true;
default:
return false;
}
}
bool IsWISCasterClass(uint8 class_id)
{
switch (class_id) {
@@ -642,6 +656,21 @@ bool IsWISCasterClass(uint8 class_id)
}
}
bool IsHeroicWISCasterClass(uint8 class_id)
{
switch (class_id) {
case CLERIC:
case DRUID:
case SHAMAN:
case PALADIN:
case BEASTLORD:
case RANGER:
return true;
default:
return false;
}
}
bool IsPlateClass(uint8 class_id)
{
switch (class_id) {
+2 -1
View File
@@ -140,7 +140,8 @@ bool IsHybridClass(uint8 class_id);
bool IsCasterClass(uint8 class_id);
bool IsINTCasterClass(uint8 class_id);
bool IsWISCasterClass(uint8 class_id);
bool IsHeroicINTCasterClass(uint8 class_id);
bool IsHeroicWISCasterClass(uint8 class_id);
bool IsPlateClass(uint8 class_id);
bool IsChainClass(uint8 class_id);
bool IsLeatherClass(uint8 class_id);
+1 -1
View File
@@ -160,7 +160,7 @@ namespace EQEmuCommand {
*/
std::string command_section;
for (auto &it: in_function_map) {
description = "";
description.clear();
(it.second)(argc, argv, cmd, description);
-3
View File
@@ -41,9 +41,6 @@ void SendCrashReport(const std::string &crash_report)
r.set_connection_timeout(1, 0);
r.set_read_timeout(1, 0);
r.set_write_timeout(1, 0);
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
// os info
auto os = EQ::GetOS();
+138 -121
View File
@@ -353,7 +353,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name);
results = QueryDatabase(query);
if (!results.Success() || results.ErrorMessage() != ""){ return false; }
if (!results.Success() || !results.ErrorMessage().empty()){ return false; }
// Put character into the default guild if rule is being used.
int guild_id = RuleI(Character, DefaultGuild);
@@ -363,7 +363,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
if (character_id > -1) {
query = StringFormat("INSERT INTO `guild_members` SET `char_id` = %i, `guild_id` = '%i'", character_id, guild_id);
results = QueryDatabase(query);
if (!results.Success() || results.ErrorMessage() != ""){
if (!results.Success() || !results.ErrorMessage().empty()){
LogInfo("Could not put character [{}] into default Guild", name);
}
}
@@ -449,7 +449,8 @@ bool Database::DeleteCharacter(char *character_name)
return true;
}
bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp){
bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp)
{
std::string query = StringFormat(
"REPLACE INTO `character_data` ("
"id,"
@@ -634,101 +635,102 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
"%u," // guild_auto_consent
"%u" // RestTimer
")",
character_id, // " id, "
account_id, // " account_id, "
Strings::Escape(pp->name).c_str(), // " `name`, "
character_id, // " id, "
account_id, // " account_id, "
Strings::Escape(pp->name).c_str(), // " `name`, "
Strings::Escape(pp->last_name).c_str(), // " last_name, "
pp->gender, // " gender, "
pp->race, // " race, "
pp->class_, // " class, "
pp->level, // " `level`, "
pp->deity, // " deity, "
pp->birthday, // " birthday, "
pp->lastlogin, // " last_login, "
pp->timePlayedMin, // " time_played, "
pp->pvp, // " pvp_status, "
pp->level2, // " level2, "
pp->anon, // " anon, "
pp->gm, // " gm, "
pp->intoxication, // " intoxication, "
pp->haircolor, // " hair_color, "
pp->beardcolor, // " beard_color, "
pp->eyecolor1, // " eye_color_1, "
pp->eyecolor2, // " eye_color_2, "
pp->hairstyle, // " hair_style, "
pp->beard, // " beard, "
pp->ability_time_seconds, // " ability_time_seconds, "
pp->ability_number, // " ability_number, "
pp->ability_time_minutes, // " ability_time_minutes, "
pp->ability_time_hours, // " ability_time_hours, "
pp->gender, // " gender, "
pp->race, // " race, "
pp->class_, // " class, "
pp->level, // " `level`, "
pp->deity, // " deity, "
pp->birthday, // " birthday, "
pp->lastlogin, // " last_login, "
pp->timePlayedMin, // " time_played, "
pp->pvp, // " pvp_status, "
pp->level2, // " level2, "
pp->anon, // " anon, "
pp->gm, // " gm, "
pp->intoxication, // " intoxication, "
pp->haircolor, // " hair_color, "
pp->beardcolor, // " beard_color, "
pp->eyecolor1, // " eye_color_1, "
pp->eyecolor2, // " eye_color_2, "
pp->hairstyle, // " hair_style, "
pp->beard, // " beard, "
pp->ability_time_seconds, // " ability_time_seconds, "
pp->ability_number, // " ability_number, "
pp->ability_time_minutes, // " ability_time_minutes, "
pp->ability_time_hours, // " ability_time_hours, "
Strings::Escape(pp->title).c_str(), // " title, "
Strings::Escape(pp->suffix).c_str(), // " suffix, "
pp->exp, // " exp, "
pp->points, // " points, "
pp->mana, // " mana, "
pp->cur_hp, // " cur_hp, "
pp->STR, // " str, "
pp->STA, // " sta, "
pp->CHA, // " cha, "
pp->DEX, // " dex, "
pp->INT, // " `int`, "
pp->AGI, // " agi, "
pp->WIS, // " wis, "
pp->face, // " face, "
pp->y, // " y, "
pp->x, // " x, "
pp->z, // " z, "
pp->heading, // " heading, "
pp->pvp2, // " pvp2, "
pp->pvptype, // " pvp_type, "
pp->autosplit, // " autosplit_enabled, "
pp->zone_change_count, // " zone_change_count, "
pp->drakkin_heritage, // " drakkin_heritage, "
pp->drakkin_tattoo, // " drakkin_tattoo, "
pp->drakkin_details, // " drakkin_details, "
pp->toxicity, // " toxicity, "
pp->hunger_level, // " hunger_level, "
pp->thirst_level, // " thirst_level, "
pp->ability_up, // " ability_up, "
pp->zone_id, // " zone_id, "
pp->zoneInstance, // " zone_instance, "
pp->leadAAActive, // " leadership_exp_on, "
pp->ldon_points_guk, // " ldon_points_guk, "
pp->ldon_points_mir, // " ldon_points_mir, "
pp->ldon_points_mmc, // " ldon_points_mmc, "
pp->ldon_points_ruj, // " ldon_points_ruj, "
pp->ldon_points_tak, // " ldon_points_tak, "
pp->ldon_points_available, // " ldon_points_available, "
pp->tribute_time_remaining, // " tribute_time_remaining, "
pp->showhelm, // " show_helm, "
pp->career_tribute_points, // " career_tribute_points, "
pp->tribute_points, // " tribute_points, "
pp->tribute_active, // " tribute_active, "
pp->endurance, // " endurance, "
pp->group_leadership_exp, // " group_leadership_exp, "
pp->raid_leadership_exp, // " raid_leadership_exp, "
pp->group_leadership_points, // " group_leadership_points, "
pp->raid_leadership_points, // " raid_leadership_points, "
pp->air_remaining, // " air_remaining, "
pp->PVPKills, // " pvp_kills, "
pp->PVPDeaths, // " pvp_deaths, "
pp->PVPCurrentPoints, // " pvp_current_points, "
pp->PVPCareerPoints, // " pvp_career_points, "
pp->PVPBestKillStreak, // " pvp_best_kill_streak, "
pp->PVPWorstDeathStreak, // " pvp_worst_death_streak, "
pp->PVPCurrentKillStreak, // " pvp_current_kill_streak, "
pp->aapoints_spent, // " aa_points_spent, "
pp->expAA, // " aa_exp, "
pp->aapoints, // " aa_points, "
pp->groupAutoconsent, // " group_auto_consent, "
pp->raidAutoconsent, // " raid_auto_consent, "
pp->guildAutoconsent, // " guild_auto_consent, "
pp->RestTimer // " RestTimer) "
pp->exp, // " exp, "
pp->points, // " points, "
pp->mana, // " mana, "
pp->cur_hp, // " cur_hp, "
pp->STR, // " str, "
pp->STA, // " sta, "
pp->CHA, // " cha, "
pp->DEX, // " dex, "
pp->INT, // " `int`, "
pp->AGI, // " agi, "
pp->WIS, // " wis, "
pp->face, // " face, "
pp->y, // " y, "
pp->x, // " x, "
pp->z, // " z, "
pp->heading, // " heading, "
pp->pvp2, // " pvp2, "
pp->pvptype, // " pvp_type, "
pp->autosplit, // " autosplit_enabled, "
pp->zone_change_count, // " zone_change_count, "
pp->drakkin_heritage, // " drakkin_heritage, "
pp->drakkin_tattoo, // " drakkin_tattoo, "
pp->drakkin_details, // " drakkin_details, "
pp->toxicity, // " toxicity, "
pp->hunger_level, // " hunger_level, "
pp->thirst_level, // " thirst_level, "
pp->ability_up, // " ability_up, "
pp->zone_id, // " zone_id, "
pp->zoneInstance, // " zone_instance, "
pp->leadAAActive, // " leadership_exp_on, "
pp->ldon_points_guk, // " ldon_points_guk, "
pp->ldon_points_mir, // " ldon_points_mir, "
pp->ldon_points_mmc, // " ldon_points_mmc, "
pp->ldon_points_ruj, // " ldon_points_ruj, "
pp->ldon_points_tak, // " ldon_points_tak, "
pp->ldon_points_available, // " ldon_points_available, "
pp->tribute_time_remaining, // " tribute_time_remaining, "
pp->showhelm, // " show_helm, "
pp->career_tribute_points, // " career_tribute_points, "
pp->tribute_points, // " tribute_points, "
pp->tribute_active, // " tribute_active, "
pp->endurance, // " endurance, "
pp->group_leadership_exp, // " group_leadership_exp, "
pp->raid_leadership_exp, // " raid_leadership_exp, "
pp->group_leadership_points, // " group_leadership_points, "
pp->raid_leadership_points, // " raid_leadership_points, "
pp->air_remaining, // " air_remaining, "
pp->PVPKills, // " pvp_kills, "
pp->PVPDeaths, // " pvp_deaths, "
pp->PVPCurrentPoints, // " pvp_current_points, "
pp->PVPCareerPoints, // " pvp_career_points, "
pp->PVPBestKillStreak, // " pvp_best_kill_streak, "
pp->PVPWorstDeathStreak, // " pvp_worst_death_streak, "
pp->PVPCurrentKillStreak, // " pvp_current_kill_streak, "
pp->aapoints_spent, // " aa_points_spent, "
pp->expAA, // " aa_exp, "
pp->aapoints, // " aa_points, "
pp->groupAutoconsent, // " group_auto_consent, "
pp->raidAutoconsent, // " raid_auto_consent, "
pp->guildAutoconsent, // " guild_auto_consent, "
pp->RestTimer // " RestTimer) "
);
auto results = QueryDatabase(query);
QueryDatabase(query);
/* Save Bind Points */
query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
query = StringFormat(
"REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i), "
"(%u, %u, %u, %f, %f, %f, %f, %i), "
"(%u, %u, %u, %f, %f, %f, %f, %i), "
@@ -739,57 +741,73 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
character_id, pp->binds[2].zone_id, 0, pp->binds[2].x, pp->binds[2].y, pp->binds[2].z, pp->binds[2].heading, 2,
character_id, pp->binds[3].zone_id, 0, pp->binds[3].x, pp->binds[3].y, pp->binds[3].z, pp->binds[3].heading, 3,
character_id, pp->binds[4].zone_id, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading, 4
); results = QueryDatabase(query);
);
QueryDatabase(query);
/* HoTT Ability */
if(RuleB(Character, GrantHoTTOnCreate))
{
query = StringFormat("INSERT INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%u, %i, %i)", character_id, 14, 1);
results = QueryDatabase(query);
}
/* HoTT Ability */
if (RuleB(Character, GrantHoTTOnCreate)) {
query = StringFormat(
"INSERT INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%u, %i, %i)",
character_id,
14,
1
);
QueryDatabase(query);
}
/* Save Skills */
int firstquery = 0;
for (int i = 0; i < MAX_PP_SKILL; i++){
if (pp->skills[i] > 0){
if (firstquery != 1){
int firstquery = 0;
for (int i = 0; i < MAX_PP_SKILL; i++) {
if (pp->skills[i] > 0) {
if (firstquery != 1) {
firstquery = 1;
query = StringFormat("REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)", character_id, i, pp->skills[i]);
}
else{
query = StringFormat(
"REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)",
character_id,
i,
pp->skills[i]
);
} else {
query = query + StringFormat(", (%u, %u, %u)", character_id, i, pp->skills[i]);
}
}
}
results = QueryDatabase(query);
QueryDatabase(query);
/* Save Language */
firstquery = 0;
for (int i = 0; i < MAX_PP_LANGUAGE; i++){
if (pp->languages[i] > 0){
if (firstquery != 1){
for (int i = 0; i < MAX_PP_LANGUAGE; i++) {
if (pp->languages[i] > 0) {
if (firstquery != 1) {
firstquery = 1;
query = StringFormat("REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)", character_id, i, pp->languages[i]);
}
else{
query = StringFormat(
"REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)",
character_id,
i,
pp->languages[i]
);
} else {
query = query + StringFormat(", (%u, %u, %u)", character_id, i, pp->languages[i]);
}
}
}
results = QueryDatabase(query);
QueryDatabase(query);
return true;
}
uint32 Database::GetCharacterID(const char *name) {
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name);
const auto query = fmt::format(
"SELECT `id` FROM `character_data` WHERE `name` = '{}'",
Strings::Escape(name)
);
auto results = QueryDatabase(query);
auto row = results.begin();
if (results.RowCount() == 1)
{
return Strings::ToUnsignedInt(row[0]);
if (!results.Success() || !results.RowCount()) {
return 0;
}
return 0;
auto row = results.begin();
return Strings::ToUnsignedInt(row[0]);
}
/*
@@ -2274,7 +2292,6 @@ bool Database::CopyCharacter(
new_rows.emplace_back(new_values);
}
std::string insert_values;
std::vector<std::string> insert_rows;
for (auto &r: new_rows) {
+43 -11
View File
@@ -28,6 +28,7 @@
#include "../database_schema.h"
#include "../file.h"
#include "../process/process.h"
#include "../termcolor/rang.hpp"
#include <ctime>
@@ -36,6 +37,7 @@
#else
#include <sys/time.h>
#include <thread>
#endif
@@ -145,7 +147,7 @@ std::string DatabaseDumpService::GetQueryServTables()
std::string DatabaseDumpService::GetSystemTablesList()
{
auto system_tables = DatabaseSchema::GetServerTables();
auto system_tables = DatabaseSchema::GetServerTables();
auto version_tables = DatabaseSchema::GetVersionTables();
system_tables.insert(
@@ -199,7 +201,7 @@ std::string DatabaseDumpService::GetDumpFileNameWithPath()
return GetSetDumpPath() + GetDumpFileName();
}
void DatabaseDumpService::Dump()
void DatabaseDumpService::DatabaseDump()
{
if (!IsMySQLInstalled()) {
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
@@ -293,14 +295,6 @@ void DatabaseDumpService::Dump()
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
}
std::string execute_command = fmt::format(
"{} {} {} {}",
GetBaseMySQLDumpCommand(),
options,
tables_to_dump,
pipe_file
);
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
File::Makedir(GetSetDumpPath());
}
@@ -308,7 +302,7 @@ void DatabaseDumpService::Dump()
if (IsDumpDropTableSyntaxOnly()) {
std::vector<std::string> tables = Strings::Split(tables_to_dump, ' ');
for (auto &table : tables) {
for (auto &table: tables) {
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
}
@@ -317,12 +311,40 @@ void DatabaseDumpService::Dump()
}
}
else {
const auto execute_command = fmt::format(
"{} {} {} {}",
GetBaseMySQLDumpCommand(),
options,
tables_to_dump,
pipe_file
);
std::string execution_result = Process::execute(execute_command);
if (!execution_result.empty() && IsDumpOutputToConsole()) {
std::cout << execution_result;
}
}
LogSys.EnableConsoleLogging();
if (!pipe_file.empty()) {
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
auto r = File::GetContents(file);
if (!r.error.empty()) {
LogError("{}", r.error);
}
for (auto &line: Strings::Split(r.contents, "\n")) {
if (Strings::Contains(line, "mysqldump:")) {
LogError("{}", line);
LogError("Database dump failed. Correct the error before continuing or trying again");
LogError("This is to prevent data loss on behalf of the server operator");
RemoveSqlBackup();
std::exit(1);
}
}
}
if (!tables_to_dump.empty()) {
LogInfo("Dumping Tables [{}]", Strings::Trim(tables_to_dump));
}
@@ -343,6 +365,7 @@ void DatabaseDumpService::Dump()
)
);
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
RemoveSqlBackup();
}
else if (Is7ZipAvailable()) {
Process::execute(
@@ -353,6 +376,7 @@ void DatabaseDumpService::Dump()
)
);
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
RemoveSqlBackup();
}
else {
LogInfo("Compression requested, but no available compression binary was found");
@@ -535,3 +559,11 @@ void DatabaseDumpService::SetDumpMercTables(bool dump_merc_tables)
{
DatabaseDumpService::dump_merc_tables = dump_merc_tables;
}
void DatabaseDumpService::RemoveSqlBackup()
{
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
if (File::Exists(file)) {
std::filesystem::remove(file);
}
}
+2 -1
View File
@@ -24,7 +24,7 @@
class DatabaseDumpService {
public:
void Dump();
void DatabaseDump();
bool IsDumpAllTables() const;
void SetDumpAllTables(bool dump_all_tables);
bool IsDumpWithNoData() const;
@@ -92,6 +92,7 @@ private:
std::string GetDumpFileNameWithPath();
std::string GetSetDumpPath();
std::string GetQueryServTables();
void RemoveSqlBackup();
};
+31 -31
View File
@@ -967,7 +967,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
loadbar(char_iter_count, number_of_characters, 50);
/* Run inspect message convert */
if (inspectmessage != ""){
if (!inspectmessage.empty()){
std::string rquery = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message)"
"VALUES (%u, '%s')",
character_id,
@@ -1314,7 +1314,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
The speed difference is dramatic
*/
/* Run AA Convert */
int first_entry = 0; rquery = "";
int first_entry = 0; rquery.clear();
for (i = 0; i < MAX_PP_AA_ARRAY; i++){
if (pp->aa_array[i].AA > 0 && pp->aa_array[i].value > 0){
if (first_entry != 1){
@@ -1327,14 +1327,14 @@ bool Database::CheckDatabaseConvertPPDeblob(){
}
}
}
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
/* Run Bind Home Convert */
if (pp->binds[4].zone_id < 999 && !_ISNAN_(pp->binds[4].x) && !_ISNAN_(pp->binds[4].y) && !_ISNAN_(pp->binds[4].z) && !_ISNAN_(pp->binds[4].heading)) {
rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, 1)",
character_id, pp->binds[4].zone_id, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading);
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
}
/* Run Bind Convert */
@@ -1342,10 +1342,10 @@ bool Database::CheckDatabaseConvertPPDeblob(){
rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, 0)",
character_id, pp->binds[0].zone_id, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading);
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
}
/* Run Language Convert */
first_entry = 0; rquery = "";
first_entry = 0; rquery.clear();
for (i = 0; i < MAX_PP_LANGUAGE; i++){
if (pp->languages[i] > 0){
if (first_entry != 1){
@@ -1355,9 +1355,9 @@ bool Database::CheckDatabaseConvertPPDeblob(){
rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->languages[i]);
}
}
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
/* Run Skill Convert */
first_entry = 0; rquery = "";
first_entry = 0; rquery.clear();
for (i = 0; i < MAX_PP_SKILL; i++){
if (pp->skills[i] > 0){
if (first_entry != 1){
@@ -1367,9 +1367,9 @@ bool Database::CheckDatabaseConvertPPDeblob(){
rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->skills[i]);
}
}
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
/* Run Spell Convert */
first_entry = 0; rquery = "";
first_entry = 0; rquery.clear();
for (i = 0; i < 480; i++){
if (pp->spell_book[i] > 0 && pp->spell_book[i] != 4294967295 && pp->spell_book[i] < 40000 && pp->spell_book[i] != 1){
if (first_entry != 1){
@@ -1379,9 +1379,9 @@ bool Database::CheckDatabaseConvertPPDeblob(){
rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->spell_book[i]);
}
}
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
/* Run Max Memmed Spell Convert */
first_entry = 0; rquery = "";
first_entry = 0; rquery.clear();
for (i = 0; i < 9; i++){
if (pp->mem_spells[i] > 0 && pp->mem_spells[i] != 65535 && pp->mem_spells[i] != 4294967295){
if (first_entry != 1){
@@ -1391,9 +1391,9 @@ bool Database::CheckDatabaseConvertPPDeblob(){
rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->mem_spells[i]);
}
}
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
/* Run Discipline Convert */
first_entry = 0; rquery = "";
first_entry = 0; rquery.clear();
for (i = 0; i < MAX_PP_DISCIPLINES; i++){
if (pp->disciplines.values[i] > 0 && pp->disciplines.values[i] < 60000){
if (first_entry != 1){
@@ -1403,9 +1403,9 @@ bool Database::CheckDatabaseConvertPPDeblob(){
rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->disciplines.values[i]);
}
}
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
/* Run Material Color Convert */
first_entry = 0; rquery = "";
first_entry = 0; rquery.clear();
for (i = EQ::textures::textureBegin; i < EQ::textures::materialCount; i++){
if (pp->item_tint[i].color > 0){
if (first_entry != 1){
@@ -1415,9 +1415,9 @@ bool Database::CheckDatabaseConvertPPDeblob(){
rquery = rquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color);
}
}
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
/* Run Tribute Convert */
first_entry = 0; rquery = "";
first_entry = 0; rquery.clear();
for (i = 0; i < 5; i++){
if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != 4294967295){
if (first_entry != 1){
@@ -1427,9 +1427,9 @@ bool Database::CheckDatabaseConvertPPDeblob(){
rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute);
}
}
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
/* Run Bandolier Convert */
first_entry = 0; rquery = "";
first_entry = 0; rquery.clear();
for (i = 0; i < Convert::BANDOLIERS_SIZE; i++){
if (strlen(pp->bandoliers[i].Name) < 32) {
for (int si = 0; si < Convert::BANDOLIER_ITEM_COUNT; si++){
@@ -1443,9 +1443,9 @@ bool Database::CheckDatabaseConvertPPDeblob(){
}
}
}
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
/* Run Potion Belt Convert */
first_entry = 0; rquery = "";
first_entry = 0; rquery.clear();
for (i = 0; i < Convert::POTION_BELT_ITEM_COUNT; i++){
if (pp->potionbelt.Items[i].ID > 0){
if (first_entry != 1){
@@ -1456,9 +1456,9 @@ bool Database::CheckDatabaseConvertPPDeblob(){
}
}
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
/* Run Leadership AA Convert */
first_entry = 0; rquery = "";
first_entry = 0; rquery.clear();
for (i = 0; i < MAX_LEADERSHIP_AA_ARRAY; i++){
if (pp->leader_abilities.ranks[i] > 0 && pp->leader_abilities.ranks[i] < 6){
if (first_entry != 1){
@@ -1468,7 +1468,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
rquery = rquery + StringFormat(", (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]);
}
}
if (rquery != ""){ results = QueryDatabase(rquery); }
if (!rquery.empty()){ results = QueryDatabase(rquery); }
}
}
if (runconvert == 1){
@@ -1672,10 +1672,10 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
dbpc->item_tint[8].color,
Strings::ToUnsignedInt(row2[0])
);
if (scquery != ""){ auto sc_results = QueryDatabase(scquery); }
if (!scquery.empty()){ auto sc_results = QueryDatabase(scquery); }
first_entry = 0;
scquery = "";
scquery.clear();
/* Print Items */
for (unsigned int i = 0; i < dbpc->itemcount; i++) {
if (first_entry != 1){
@@ -1712,7 +1712,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
);
}
}
if (scquery != ""){ auto sc_results = QueryDatabase(scquery); }
if (!scquery.empty()){ auto sc_results = QueryDatabase(scquery); }
}
else{
/* Classic Converter */
@@ -1780,10 +1780,10 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
dbpc_c->item_tint[8].color,
Strings::ToUnsignedInt(row2[0])
);
if (scquery != ""){ auto sc_results = QueryDatabase(scquery); }
if (!scquery.empty()){ auto sc_results = QueryDatabase(scquery); }
first_entry = 0;
scquery = "";
scquery.clear();
/* Print Items */
for (unsigned int i = 0; i < dbpc_c->itemcount; i++) {
@@ -1821,7 +1821,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
);
}
}
if (scquery != ""){ auto sc_results = QueryDatabase(scquery); }
if (!scquery.empty()){ auto sc_results = QueryDatabase(scquery); }
}
}
}
+1 -4
View File
@@ -68,7 +68,7 @@ namespace DatabaseSchema {
{"character_spells", "id"},
{"character_task_timers", "character_id"},
{"character_tasks", "charid"},
{"character_tribute", "id"},
{"character_tribute", "character_id"},
{"completed_tasks", "charid"},
{"data_buckets", "id"},
{"faction_values", "char_id"},
@@ -392,9 +392,6 @@ namespace DatabaseSchema {
"bot_command_settings",
"bot_create_combinations",
"bot_data",
"bot_group_members",
"bot_groups",
"bot_guild_members",
"bot_heal_rotation_members",
"bot_heal_rotation_targets",
"bot_heal_rotations",
+2 -2
View File
@@ -80,7 +80,7 @@ MySQLRequestResult DBcore::QueryDatabase(const std::string& query, bool retryOnF
return r;
}
bool DBcore::DoesTableExist(std::string table_name)
bool DBcore::DoesTableExist(const std::string& table_name)
{
auto results = QueryDatabase(fmt::format("SHOW TABLES LIKE '{}'", table_name));
@@ -136,7 +136,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
/**
* Error logging
*/
if (mysql_errno(mysql) > 0 && strlen(query) > 0) {
if (mysql_errno(mysql) > 0 && query[0] != '\0') {
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(mysql), mysql_error(mysql), query);
}
+1 -1
View File
@@ -35,7 +35,7 @@ public:
const std::string &GetOriginHost() const;
void SetOriginHost(const std::string &origin_host);
bool DoesTableExist(std::string table_name);
bool DoesTableExist(const std::string& table_name);
void SetMySQL(const DBcore &o)
{
-6
View File
@@ -27,9 +27,6 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
cli.set_connection_timeout(0, 15000000); // 15 sec
cli.set_read_timeout(15, 0); // 15 seconds
cli.set_write_timeout(15, 0); // 15 seconds
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
// payload
Json::Value p;
@@ -96,9 +93,6 @@ void Discord::SendPlayerEventMessage(
cli.set_connection_timeout(0, 15000000); // 15 sec
cli.set_read_timeout(15, 0); // 15 seconds
cli.set_write_timeout(15, 0); // 15 seconds
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
std::string payload = PlayerEventLogs::GetDiscordPayloadFromEvent(e);
if (payload.empty()) {
+2 -2
View File
@@ -37,7 +37,7 @@ void DiscordManager::ProcessMessageQueue()
message,
webhook.webhook_url
);
message = "";
message.clear();
}
message += m;
@@ -51,7 +51,7 @@ void DiscordManager::ProcessMessageQueue()
webhook.webhook_url
);
}
message = "";
message.clear();
}
}
// final flush
+7
View File
@@ -1045,4 +1045,11 @@ enum ResurrectionActions
Accept
};
enum ScribeSpellActions
{
Scribe,
Memorize,
Unmemorize
};
#endif /*COMMON_EQ_CONSTANTS_H*/
+1 -138
View File
@@ -236,26 +236,6 @@ uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
return size+OpCodeBytes;
}
/*EQProtocolPacket::EQProtocolPacket(uint16 op, const unsigned char *buf, uint32 len)
: BasePacket(buf, len),
opcode(op)
{
uint32 offset;
opcode=ntohs(*(const uint16 *)buf);
offset=2;
if (len-offset) {
pBuffer= new unsigned char[len-offset];
memcpy(pBuffer,buf+offset,len-offset);
size=len-offset;
} else {
pBuffer=nullptr;
size=0;
}
OpMgr=&RawOpcodeManager;
}*/
bool EQProtocolPacket::combine(const EQProtocolPacket *rhs)
{
bool result=false;
@@ -287,74 +267,6 @@ bool result=false;
}
/*
this is the code to do app-layer combining, instead of protocol layer.
this was taken out due to complex interactions with the opcode manager,
and will require a bit more thinking (likely moving into EQStream) to
get running again... but might be a good thing some day.
bool EQApplicationPacket::combine(const EQApplicationPacket *rhs)
{
uint32 newsize=0, offset=0;
unsigned char *tmpbuffer=nullptr;
if (opcode!=OP_AppCombined) {
newsize=app_opcode_size+size+(size>254?3:1)+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
offset=0;
if (size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(size);
offset+=1;
} else {
tmpbuffer[offset++]=size;
}
offset+=serialize(tmpbuffer+offset);
} else {
newsize=size+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
memcpy(tmpbuffer,pBuffer,size);
offset=size;
}
if (rhs->size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(rhs->size);
offset+=1;
} else {
tmpbuffer[offset++]=rhs->size;
}
offset+=rhs->serialize(tmpbuffer+offset);
size=offset;
opcode=OP_AppCombined;
delete[] pBuffer;
pBuffer=tmpbuffer;
return true;
}
*/
bool EQProtocolPacket::ValidateCRC(const unsigned char *buffer, int length, uint32 Key)
{
bool valid=false;
// OP_SessionRequest, OP_SessionResponse, OP_OutOfSession are not CRC'd
if (buffer[0]==0x00 && (buffer[1]==OP_SessionRequest || buffer[1]==OP_SessionResponse || buffer[1]==OP_OutOfSession)) {
valid=true;
} else {
uint16 comp_crc=CRC16(buffer,length-2,Key);
uint16 packet_crc=ntohs(*(const uint16 *)(buffer+length-2));
#ifdef EQN_DEBUG
if (packet_crc && comp_crc != packet_crc) {
std::cout << "CRC mismatch: comp=" << std::hex << comp_crc << ", packet=" << packet_crc << std::dec << std::endl;
}
#endif
valid = (!packet_crc || comp_crc == packet_crc);
}
return valid;
}
uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
{
uint32 newlen=0;
@@ -403,55 +315,6 @@ uint32 flag_offset=1,newlength;
return newlength;
}
void EQProtocolPacket::ChatDecode(unsigned char *buffer, int size, int DecodeKey)
{
if ((size >= 2) && buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=DecodeKey;
unsigned char *test=(unsigned char *)malloc(size);
buffer+=2;
size-=2;
int i;
for (i = 0 ; i+4 <= size ; i+=4)
{
int pt = (*(int*)&buffer[i])^(Key);
Key = (*(int*)&buffer[i]);
*(int*)&test[i]=pt;
}
unsigned char KC=Key&0xFF;
for ( ; i < size ; i++)
{
test[i]=buffer[i]^KC;
}
memcpy(buffer,test,size);
free(test);
}
}
void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey)
{
if (buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=EncodeKey;
char *test=(char*)malloc(size);
int i;
buffer+=2;
size-=2;
for ( i = 0 ; i+4 <= size ; i+=4)
{
int pt = (*(int*)&buffer[i])^(Key);
Key = pt;
*(int*)&test[i]=pt;
}
unsigned char KC=Key&0xFF;
for ( ; i < size ; i++)
{
test[i]=buffer[i]^KC;
}
memcpy(buffer,test,size);
free(test);
}
}
EQApplicationPacket *EQApplicationPacket::Copy() const {
return(new EQApplicationPacket(*this));
}
@@ -515,4 +378,4 @@ std::string DumpPacketToString(const EQApplicationPacket* app){
std::ostringstream out;
out << DumpPacketHexToString(app->pBuffer, app->size);
return out.str();
}
}
-3
View File
@@ -80,11 +80,8 @@ public:
protected:
static bool ValidateCRC(const unsigned char *buffer, int length, uint32 Key);
static uint32 Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
static uint32 Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
static void ChatDecode(unsigned char *buffer, int size, int DecodeKey);
static void ChatEncode(unsigned char *buffer, int size, int EncodeKey);
uint16 GetRawOpcode() const { return(opcode); }
+11
View File
@@ -1793,6 +1793,17 @@ struct GMSummon_Struct {
/*104*/ uint32 unknown2; // E0 E0 56 00
};
struct GMFind_Struct {
char charname[64];
char gmname[64];
uint32 success;
uint32 zoneID;
float x;
float y;
float z;
uint32 unknown2;
};
struct GMGoto_Struct { // x,y is swapped as compared to summon and makes sense as own packet
/* 0*/ char charname[64];
+1 -1
View File
@@ -26,7 +26,7 @@ EQStreamIdentifier::~EQStreamIdentifier() {
}
}
void EQStreamIdentifier::RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
void EQStreamIdentifier::RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
auto p = new Patch;
p->signature = sig;
p->name = name;
+1 -1
View File
@@ -18,7 +18,7 @@ public:
~EQStreamIdentifier();
//registration interface.
void RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
void RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
//main processing interface
void Process();
-3
View File
@@ -23,9 +23,6 @@
EQDB EQDB::s_EQDB;
EQDB::EQDB() {
}
unsigned int EQDB::field_count() {
return mysql_field_count(mysql_ref);
}
+1 -1
View File
@@ -27,7 +27,7 @@
//this is the main object exported to perl.
class EQDB {
EQDB();
EQDB() = default;
public:
static EQDB *Singleton() { return(&s_EQDB); }
-6
View File
@@ -147,12 +147,6 @@ class EQEmuConfig
return (_config);
}
// Allow the use to set the conf file to be used.
static void SetConfigFile(std::string file)
{
EQEmuConfig::ConfigFile = file;
}
// Load the config
static bool LoadConfig(const std::string& path = "")
{
+1 -5
View File
@@ -58,10 +58,6 @@ EQTime::EQTime()
SetCurrentEQTimeOfDay(start, time(0));
}
EQTime::~EQTime()
{
}
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
//This function was written by the ShowEQ Project.
//Input: Current Time (as a time_t), a pointer to the TimeOfDay_Struct that will be written to.
@@ -203,4 +199,4 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
t->month, t->day, t->year, t->hour, t->minute);
buf[127] = '\0';
str = buf;
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ public:
//Constructor/destructor
EQTime(TimeOfDay_Struct start_eq, time_t start_real);
EQTime();
~EQTime();
~EQTime() = default;
//Get functions
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
+4 -10
View File
@@ -333,7 +333,10 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
payload = PlayerEventDiscordFormatter::FormatDroppedItemEvent(e, n);
break;
}
case PlayerEvent::FISH_FAILURE: {
case PlayerEvent::FISH_FAILURE:
case PlayerEvent::FORAGE_FAILURE:
case PlayerEvent::WENT_ONLINE:
case PlayerEvent::WENT_OFFLINE: {
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
break;
}
@@ -348,10 +351,6 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
payload = PlayerEventDiscordFormatter::FormatFishSuccessEvent(e, n);
break;
}
case PlayerEvent::FORAGE_FAILURE: {
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
break;
}
case PlayerEvent::FORAGE_SUCCESS: {
PlayerEvent::ForageSuccessEvent n{};
std::stringstream ss;
@@ -550,11 +549,6 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
payload = PlayerEventDiscordFormatter::FormatResurrectAcceptEvent(e, n);
break;
}
case PlayerEvent::WENT_ONLINE:
case PlayerEvent::WENT_OFFLINE: {
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
break;
}
case PlayerEvent::MERCHANT_PURCHASE: {
PlayerEvent::MerchantPurchaseEvent n{};
std::stringstream ss;
+3 -3
View File
@@ -218,14 +218,14 @@ enum { //some random constants
#define HARD_LEVEL_CAP 127
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
#define USE_NPC_RANGE2 200*200 //arbitrary right now
#define USE_NPC_RANGE2 40000 //arbitrary right now
// Squared range for rampage 75.0 * 75.0 for now
#define NPC_RAMPAGE_RANGE2 5625.0f
//the formula for experience for killing a mob.
//level is the only valid variable to use
#define EXP_FORMULA level*level*75*35/10
#define EXP_FORMULA (level * level * 75 * 35 / 10)
#define HIGHEST_AA_VALUE 35
@@ -295,7 +295,7 @@ Developer configuration
#define COMMON_PROFILE
#define PROFILE_DUMP_TIME 3*60
#define PROFILE_DUMP_TIME 180
#endif //EQPROFILE
+24
View File
@@ -37,6 +37,7 @@
#include <fmt/format.h>
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
@@ -80,3 +81,26 @@ std::string File::GetCwd()
{
return fs::current_path().string();
}
FileContentsResult File::GetContents(const std::string &file_name)
{
std::string error;
std::ifstream f;
f.open(file_name);
std::string line;
std::string lines;
if (f.is_open()) {
while (f) {
std::getline(f, line);
lines += line + "\n";
}
}
else {
error = fmt::format("Couldn't open file [{}]", file_name);
}
return FileContentsResult{
.contents = lines,
.error = error,
};
}
+6
View File
@@ -25,10 +25,16 @@
namespace fs = std::filesystem;
struct FileContentsResult {
std::string contents;
std::string error;
};
class File {
public:
static bool Exists(const std::string &name);
static void Makedir(const std::string& directory_name);
static FileContentsResult GetContents(const std::string &file_name);
static std::string FindEqemuConfigPath();
static std::string GetCwd();
};
+6 -5
View File
@@ -412,11 +412,12 @@ bool EQ::InventoryProfile::DeleteItem(int16 slot_id, int16 quantity) {
// If there are no charges left on the item,
if (item_to_delete->GetCharges() <= 0) {
// If the item is stackable (e.g arrows), or
// the item is not stackable, and is not a charged item, or is expendable, delete it
if (item_to_delete->IsStackable() ||
(!item_to_delete->IsStackable() &&
((item_to_delete->GetItem()->MaxCharges == 0) || item_to_delete->IsExpendable()))
) {
// the item is not a charged item, or is expendable, delete it
if (
item_to_delete->IsStackable() ||
item_to_delete->GetItem()->MaxCharges == 0 ||
item_to_delete->IsExpendable()
) {
// Item can now be destroyed
InventoryProfile::MarkDirty(item_to_delete);
return true;
+164 -159
View File
@@ -355,181 +355,186 @@ namespace EQ
struct ItemData {
// Non packet based fields
uint8 MinStatus;
uint8 MinStatus {};
// Packet based fields
uint8 ItemClass; // Item Type: 0=common, 1=container, 2=book
char Name[64]; // Name
char Lore[80]; // Lore Name: *=lore, &=summoned, #=artifact, ~=pending lore
char IDFile[30]; // Visible model
uint32 ID; // Unique ID (also PK for DB)
int32 Weight; // Item weight * 10
uint8 NoRent; // No Rent: 0=norent, 255=not norent
uint8 NoDrop; // No Drop: 0=nodrop, 255=not nodrop
uint8 Size; // Size: 0=tiny, 1=small, 2=medium, 3=large, 4=giant
uint32 Slots; // Bitfield for which slots this item can be used in
uint32 Price; // Item cost (?)
uint32 Icon; // Icon Number
int32 LoreGroup; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
bool LoreFlag; // This will be true if LoreGroup is non-zero
bool PendingLoreFlag;
bool ArtifactFlag;
bool SummonedFlag;
uint8 FVNoDrop; // Firiona Vie nodrop flag
uint32 Favor; // Individual favor
uint32 GuildFavor; // Guild favor
uint32 PointType;
uint8 ItemClass {}; // Item Type: 0=common, 1=container, 2=book
char Name[64] {}; // Name
char Lore[80] {}; // Lore Name: *=lore, &=summoned, #=artifact, ~=pending lore
char IDFile[30] {}; // Visible model
uint32 ID {}; // Unique ID (also PK for DB)
int32 Weight {}; // Item weight * 10
uint8 NoRent{} ; // No Rent: 0=norent, 255=not norent
uint8 NoDrop {}; // No Drop: 0=nodrop, 255=not nodrop
uint8 Size {}; // Size: 0=tiny, 1=small, 2=medium, 3=large, 4=giant
uint32 Slots {}; // Bitfield for which slots this item can be used in
uint32 Price {}; // Item cost (?)
uint32 Icon {}; // Icon Number
int32 LoreGroup {}; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
bool LoreFlag {}; // This will be true if LoreGroup is non-zero
bool PendingLoreFlag {};
bool ArtifactFlag {};
bool SummonedFlag {};
uint8 FVNoDrop {}; // Firiona Vie nodrop flag
uint32 Favor {}; // Individual favor
uint32 GuildFavor {}; // Guild favor
uint32 PointType {};
//uint32 Unk117;
//uint32 Unk118;
//uint32 Unk121;
//uint32 Unk124;
uint8 BagType; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
uint8 BagSlots; // Number of slots: can only be 2, 4, 6, 8, or 10
uint8 BagSize; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
uint8 BagWR; // 0->100
uint8 BagType {}; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
uint8 BagSlots {}; // Number of slots: can only be 2, 4, 6, 8, or 10
uint8 BagSize {}; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
uint8 BagWR {}; // 0->100
bool BenefitFlag;
bool Tradeskills; // Is this a tradeskill item?
int8 CR; // Save vs Cold
int8 DR; // Save vs Disease
int8 PR; // Save vs Poison
int8 MR; // Save vs Magic
int8 FR; // Save vs Fire
int8 AStr; // Strength
int8 ASta; // Stamina
int8 AAgi; // Agility
int8 ADex; // Dexterity
int8 ACha; // Charisma
int8 AInt; // Intelligence
int8 AWis; // Wisdom
int32 HP; // HP
int32 Mana; // Mana
int32 AC; // AC
uint32 Deity; // Bitmask of Deities that can equip this item
bool BenefitFlag {};
bool Tradeskills {}; // Is this a tradeskill item?
int8 CR {}; // Save vs Cold
int8 DR {}; // Save vs Disease
int8 PR {}; // Save vs Poison
int8 MR {}; // Save vs Magic
int8 FR {}; // Save vs Fire
int8 AStr {}; // Strength
int8 ASta {}; // Stamina
int8 AAgi {}; // Agility
int8 ADex {}; // Dexterity
int8 ACha {}; // Charisma
int8 AInt {}; // Intelligence
int8 AWis {}; // Wisdom
int32 HP {}; // HP
int32 Mana {}; // Mana
int32 AC {}; // AC
uint32 Deity {}; // Bitmask of Deities that can equip this item
//uint32 Unk033
int32 SkillModValue; // % Mod to skill specified in SkillModType
int32 SkillModMax; // Max skill point modification
uint32 SkillModType; // Type of skill for SkillModValue to apply to
uint32 BaneDmgRace; // Bane Damage Race
int32 BaneDmgAmt; // Bane Damage Body Amount
uint32 BaneDmgBody; // Bane Damage Body
bool Magic; // True=Magic Item, False=not
int32 CastTime_;
uint8 ReqLevel; // Required Level to use item
uint32 BardType; // Bard Skill Type
int32 BardValue; // Bard Skill Amount
int8 Light; // Light
uint8 Delay; // Delay * 10
uint8 RecLevel; // Recommended level to use item
uint8 RecSkill; // Recommended skill to use item (refers to primary skill of item)
uint8 ElemDmgType; // Elemental Damage Type (1=magic, 2=fire)
uint8 ElemDmgAmt; // Elemental Damage
uint8 Range; // Range of item
uint32 Damage; // Delay between item usage (in 0.1 sec increments)
uint32 Color; // RR GG BB 00 <-- as it appears in pc
uint32 Classes; // Bitfield of classes that can equip item (1 << class#)
uint32 Races; // Bitfield of races that can equip item (1 << race#)
//uint32 Unk054;
int16 MaxCharges; // Maximum charges items can hold: -1 if not a chargeable item
uint8 ItemType; // Item Type/Skill (itemClass* from above)
int32 SubType; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
uint8 Material; // Item material type
uint32 HerosForgeModel;// Hero's Forge Armor Model Type (2-13?)
float SellRate; // Sell rate
//uint32 Unk059;
int32 SkillModValue {}; // % Mod to skill specified in SkillModType
int32 SkillModMax {}; // Max skill point modification
uint32 SkillModType {}; // Type of skill for SkillModValue to apply to
uint32 BaneDmgRace {}; // Bane Damage Race
int32 BaneDmgAmt {}; // Bane Damage Body Amount
uint32 BaneDmgBody {}; // Bane Damage Body
bool Magic {}; // True=Magic Item, False=not
int32 CastTime_ {};
uint8 ReqLevel {}; // Required Level to use item
uint32 BardType {}; // Bard Skill Type
int32 BardValue {}; // Bard Skill Amount
int8 Light {}; // Light
uint8 Delay {}; // Delay * 10
uint8 RecLevel {}; // Recommended level to use item
uint8 RecSkill {}; // Recommended skill to use item (refers to primary skill of item)
uint8 ElemDmgType {}; // Elemental Damage Type (1=magic, 2=fire)
uint8 ElemDmgAmt {}; // Elemental Damage
uint8 Range {}; // Range of item
uint32 Damage {}; // Delay between item usage (in 0.1 sec increments)
uint32 Color {}; // RR GG BB 00 <-- as it appears in pc
uint32 Classes {}; // Bitfield of classes that can equip item (1 << class#)
uint32 Races {}; // Bitfield of races that can equip item (1 << race#)
//uint32 Unk054 {};
int16 MaxCharges {}; // Maximum charges items can hold: -1 if not a chargeable item
uint8 ItemType {}; // Item Type/Skill (itemClass* from above)
int32 SubType {}; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
uint8 Material {}; // Item material type
uint32 HerosForgeModel {};// Hero's Forge Armor Model Type (2-13?)
float SellRate {}; // Sell rate
//uint32 Unk059 {};
union {
uint32 Fulfilment; // Food fulfilment (How long it lasts)
uint32 CastTime; // Cast Time for clicky effects, in milliseconds
};
uint32 EliteMaterial;
int32 ProcRate;
int8 CombatEffects; // PoP: Combat Effects +
int8 Shielding; // PoP: Shielding %
int8 StunResist; // PoP: Stun Resist %
int8 StrikeThrough; // PoP: Strike Through %
int32 ExtraDmgSkill;
int32 ExtraDmgAmt;
int8 SpellShield; // PoP: Spell Shield %
int8 Avoidance; // PoP: Avoidance +
int8 Accuracy; // PoP: Accuracy +
uint32 CharmFileID;
int32 FactionMod1; // Faction Mod 1
int32 FactionMod2; // Faction Mod 2
int32 FactionMod3; // Faction Mod 3
int32 FactionMod4; // Faction Mod 4
int32 FactionAmt1; // Faction Amt 1
int32 FactionAmt2; // Faction Amt 2
int32 FactionAmt3; // Faction Amt 3
int32 FactionAmt4; // Faction Amt 4
char CharmFile[32]; // ?
uint32 AugType;
uint8 AugSlotType[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Type
uint8 AugSlotVisible[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Visible
uint8 AugSlotUnk2[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
uint32 LDoNTheme;
uint32 LDoNPrice;
uint32 LDoNSold;
uint32 BaneDmgRaceAmt;
uint32 AugRestrict;
int32 Endur;
int32 DotShielding;
int32 Attack;
int32 Regen;
int32 ManaRegen;
int32 EnduranceRegen;
int32 Haste;
int32 DamageShield;
uint32 RecastDelay;
int RecastType;
uint32 AugDistiller;
bool Attuneable;
bool NoPet;
bool PotionBelt;
bool Stackable;
bool NoTransfer;
bool QuestItemFlag;
int16 StackSize;
uint8 PotionBeltSlots;
item::ItemEffect_Struct Click, Proc, Worn, Focus, Scroll, Bard;
uint32 EliteMaterial {};
int32 ProcRate {};
int8 CombatEffects {}; // PoP: Combat Effects +
int8 Shielding {}; // PoP: Shielding %
int8 StunResist {}; // PoP: Stun Resist %
int8 StrikeThrough {}; // PoP: Strike Through %
int32 ExtraDmgSkill {};
int32 ExtraDmgAmt {};
int8 SpellShield {}; // PoP: Spell Shield %
int8 Avoidance {}; // PoP: Avoidance +
int8 Accuracy {}; // PoP: Accuracy +
uint32 CharmFileID {};
int32 FactionMod1 {}; // Faction Mod 1
int32 FactionMod2 {}; // Faction Mod 2
int32 FactionMod3 {}; // Faction Mod 3
int32 FactionMod4 {}; // Faction Mod 4
int32 FactionAmt1 {}; // Faction Amt 1
int32 FactionAmt2 {}; // Faction Amt 2
int32 FactionAmt3 {}; // Faction Amt 3
int32 FactionAmt4 {}; // Faction Amt 4
char CharmFile[32] {}; // ?
uint32 AugType {};
uint8 AugSlotType[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Type
uint8 AugSlotVisible[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Visible
uint8 AugSlotUnk2[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
uint32 LDoNTheme {};
uint32 LDoNPrice {};
uint32 LDoNSold {};
uint32 BaneDmgRaceAmt {};
uint32 AugRestrict {};
int32 Endur {};
int32 DotShielding {};
int32 Attack {};
int32 Regen {};
int32 ManaRegen {};
int32 EnduranceRegen {};
int32 Haste {};
int32 DamageShield {};
uint32 RecastDelay {};
int RecastType {};
uint32 AugDistiller {};
bool Attuneable {};
bool NoPet {};
bool PotionBelt {};
bool Stackable {};
bool NoTransfer {};
bool QuestItemFlag {};
int16 StackSize {};
uint8 PotionBeltSlots {};
item::ItemEffect_Struct Click {};
item::ItemEffect_Struct Proc {};
item::ItemEffect_Struct Worn {};
item::ItemEffect_Struct Focus {};
item::ItemEffect_Struct Scroll {};
item::ItemEffect_Struct Bard {};
uint8 Book; // 0=Not book, 1=Book
uint32 BookType;
char Filename[33]; // Filename for book data
uint8 Book {}; // 0=Not book, 1=Book
uint32 BookType {};
char Filename[33] {}; // Filename for book data
// Begin SoF Fields
int32 SVCorruption;
uint32 Purity;
uint8 EvolvingItem;
uint32 EvolvingID;
uint8 EvolvingLevel;
uint8 EvolvingMax;
uint32 BackstabDmg;
uint32 DSMitigation;
int32 HeroicStr;
int32 HeroicInt;
int32 HeroicWis;
int32 HeroicAgi;
int32 HeroicDex;
int32 HeroicSta;
int32 HeroicCha;
int32 HeroicMR;
int32 HeroicFR;
int32 HeroicCR;
int32 HeroicDR;
int32 HeroicPR;
int32 HeroicSVCorrup;
int32 HealAmt;
int32 SpellDmg;
uint32 LDoNSellBackRate;
uint32 ScriptFileID;
uint16 ExpendableArrow;
uint32 Clairvoyance;
char ClickName[65];
char ProcName[65];
char WornName[65];
char FocusName[65];
char ScrollName[65];
int32 SVCorruption {};
uint32 Purity {};
uint8 EvolvingItem {};
uint32 EvolvingID {};
uint8 EvolvingLevel {};
uint8 EvolvingMax {};
uint32 BackstabDmg {};
uint32 DSMitigation {};
int32 HeroicStr {};
int32 HeroicInt {};
int32 HeroicWis {};
int32 HeroicAgi {};
int32 HeroicDex {};
int32 HeroicSta {};
int32 HeroicCha {};
int32 HeroicMR {};
int32 HeroicFR {};
int32 HeroicCR {};
int32 HeroicDR {};
int32 HeroicPR {};
int32 HeroicSVCorrup {};
int32 HealAmt {};
int32 SpellDmg {};
uint32 LDoNSellBackRate {};
uint32 ScriptFileID {};
uint16 ExpendableArrow {};
uint32 Clairvoyance {};
char ClickName[65] {};
char ProcName[65] {};
char WornName[65] {};
char FocusName[65] {};
char ScrollName[65] {};
//BardName
bool IsEquipable(uint16 Race, uint16 Class) const;
+159 -164
View File
@@ -17,6 +17,7 @@
*/
#include "inventory_profile.h"
#include "../common/data_verification.h"
//#include "classes.h"
//#include "global_define.h"
//#include "item_instance.h"
@@ -57,108 +58,62 @@ static inline int32 GetNextItemInstSerialNumber() {
// class EQ::ItemInstance
//
EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
m_use_type = ItemInstNormal;
if(item) {
m_item = new ItemData(*item);
} else {
m_item = nullptr;
}
m_charges = charges;
m_price = 0;
m_attuned = false;
m_merchantslot = 0;
if (m_item && m_item->IsClassCommon())
m_color = m_item->Color;
else
m_color = 0;
m_merchantcount = 1;
m_SerialNumber = GetNextItemInstSerialNumber();
m_exp = 0;
m_evolveLvl = 0;
m_activated = false;
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
if (item) {
m_item = new ItemData(*item);
}
m_charges = charges;
if (m_item && m_item->IsClassCommon()) {
m_color = m_item->Color;
}
m_SerialNumber = GetNextItemInstSerialNumber();
}
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges) {
m_use_type = ItemInstNormal;
m_item = db->GetItem(item_id);
if(m_item) {
m_item = db->GetItem(item_id);
if (m_item) {
m_item = new ItemData(*m_item);
}
else {
m_item = nullptr;
}
m_charges = charges;
m_price = 0;
m_merchantslot = 0;
m_attuned=false;
if (m_item && m_item->IsClassCommon())
m_color = m_item->Color;
else
m_color = 0;
m_merchantcount = 1;
m_SerialNumber = GetNextItemInstSerialNumber();
m_exp = 0;
m_evolveLvl = 0;
m_activated = false;
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
if (m_item && m_item->IsClassCommon()) {
m_color = m_item->Color;
} else {
m_color = 0;
}
m_SerialNumber = GetNextItemInstSerialNumber();
}
EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
m_use_type = use_type;
m_item = nullptr;
m_charges = 0;
m_price = 0;
m_attuned = false;
m_merchantslot = 0;
m_color = 0;
m_exp = 0;
m_evolveLvl = 0;
m_activated = false;
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
m_use_type = use_type;
}
// Make a copy of an EQ::ItemInstance object
EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
{
m_use_type=copy.m_use_type;
if(copy.m_item)
m_item = new ItemData(*copy.m_item);
else
m_item = nullptr;
m_use_type = copy.m_use_type;
if (copy.m_item) {
m_item = new ItemData(*copy.m_item);
} else {
m_item = nullptr;
}
m_charges = copy.m_charges;
m_price = copy.m_price;
m_color = copy.m_color;
m_merchantslot = copy.m_merchantslot;
m_currentslot = copy.m_currentslot;
m_attuned = copy.m_attuned;
m_merchantcount = copy.m_merchantcount;
m_charges=copy.m_charges;
m_price=copy.m_price;
m_color=copy.m_color;
m_merchantslot=copy.m_merchantslot;
m_currentslot=copy.m_currentslot;
m_attuned=copy.m_attuned;
m_merchantcount=copy.m_merchantcount;
// Copy container contents
for (auto it = copy.m_contents.begin(); it != copy.m_contents.end(); ++it) {
ItemInstance* inst_old = it->second;
@@ -168,37 +123,42 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
inst_new = inst_old->Clone();
}
if (inst_new != nullptr) {
if (inst_new) {
m_contents[it->first] = inst_new;
}
}
std::map<std::string, std::string>::const_iterator iter;
for (iter = copy.m_custom_data.begin(); iter != copy.m_custom_data.end(); ++iter) {
m_custom_data[iter->first] = iter->second;
}
m_SerialNumber = copy.m_SerialNumber;
m_custom_data = copy.m_custom_data;
m_timers = copy.m_timers;
m_exp = copy.m_exp;
m_SerialNumber = copy.m_SerialNumber;
m_custom_data = copy.m_custom_data;
m_timers = copy.m_timers;
m_exp = copy.m_exp;
m_evolveLvl = copy.m_evolveLvl;
m_activated = copy.m_activated;
if (copy.m_scaledItem)
if (copy.m_scaledItem) {
m_scaledItem = new ItemData(*copy.m_scaledItem);
else
} else {
m_scaledItem = nullptr;
}
if(copy.m_evolveInfo)
if (copy.m_evolveInfo) {
m_evolveInfo = new EvolveInfo(*copy.m_evolveInfo);
else
} else {
m_evolveInfo = nullptr;
}
m_scaling = copy.m_scaling;
m_ornamenticon = copy.m_ornamenticon;
m_ornamentidfile = copy.m_ornamentidfile;
m_scaling = copy.m_scaling;
m_ornamenticon = copy.m_ornamenticon;
m_ornamentidfile = copy.m_ornamentidfile;
m_ornament_hero_model = copy.m_ornament_hero_model;
m_recast_timestamp = copy.m_recast_timestamp;
m_new_id_file = copy.m_new_id_file;
m_recast_timestamp = copy.m_recast_timestamp;
m_new_id_file = copy.m_new_id_file;
}
// Clean up container contents
@@ -216,11 +176,13 @@ bool EQ::ItemInstance::IsType(item::ItemClass item_class) const
// IsType(<ItemClassTypes>) does not protect against 'm_item = nullptr'
// Check usage type
if ((m_use_type == ItemInstWorldContainer) && (item_class == item::ItemClassBag))
if (m_use_type == ItemInstWorldContainer && item_class == item::ItemClassBag) {
return true;
}
if (!m_item)
if (!m_item) {
return false;
}
return (m_item->ItemClass == item_class);
}
@@ -243,21 +205,20 @@ bool EQ::ItemInstance::IsClassBook() const
// Is item stackable?
bool EQ::ItemInstance::IsStackable() const
{
if (!m_item)
return false;
return m_item->Stackable;
return (m_item && m_item->Stackable);
}
bool EQ::ItemInstance::IsCharged() const
{
if (!m_item)
if (!m_item) {
return false;
}
if (m_item->MaxCharges > 1)
if (m_item->MaxCharges > 1) {
return true;
else
} else {
return false;
}
}
// Can item be equipped?
@@ -306,26 +267,30 @@ bool EQ::ItemInstance::IsEquipable(int16 slot_id) const
bool EQ::ItemInstance::IsAugmentable() const
{
if (!m_item)
if (!m_item) {
return false;
}
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
if (m_item->AugSlotType[index] != 0)
if (m_item->AugSlotType[index] != 0) {
return true;
}
}
return false;
}
bool EQ::ItemInstance::AvailableWearSlot(uint32 aug_wear_slots) const {
if (!m_item || !m_item->IsClassCommon())
if (!m_item || !m_item->IsClassCommon()) {
return false;
}
int index = invslot::EQUIPMENT_BEGIN;
for (; index <= invslot::EQUIPMENT_END; ++index) {
if (m_item->Slots & (1 << index)) {
if (aug_wear_slots & (1 << index))
if (aug_wear_slots & (1 << index)) {
break;
}
}
}
@@ -394,9 +359,10 @@ EQ::ItemInstance* EQ::ItemInstance::GetItem(uint8 index) const
uint32 EQ::ItemInstance::GetItemID(uint8 slot) const
{
ItemInstance *item = GetItem(slot);
if (item)
const auto item = GetItem(slot);
if (item) {
return item->GetID();
}
return 0;
}
@@ -520,14 +486,21 @@ uint8 EQ::ItemInstance::FirstOpenSlot() const
uint8 EQ::ItemInstance::GetTotalItemCount() const
{
if (!m_item)
if (!m_item) {
return 0;
}
uint8 item_count = 1;
if (m_item && !m_item->IsClassBag()) { return item_count; }
if (!m_item->IsClassBag()) {
return item_count;
}
for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) { if (GetItem(index)) { ++item_count; } }
for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) {
if (GetItem(index)) {
++item_count;
}
}
return item_count;
}
@@ -555,78 +528,99 @@ EQ::ItemInstance* EQ::ItemInstance::GetAugment(uint8 augment_index) const
return nullptr;
}
EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAug(int32 ornamentationAugtype) const
bool EQ::ItemInstance::IsOrnamentationAugment(EQ::ItemInstance* augment) const
{
if (!m_item || !m_item->IsClassCommon()) { return nullptr; }
if (ornamentationAugtype == 0) { return nullptr; }
if (!m_item || !m_item->IsClassCommon() || !augment) {
return false;
}
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++)
{
if (GetAugment(i) && m_item->AugSlotType[i] == ornamentationAugtype)
{
const char *item_IDFile = GetAugment(i)->GetItem()->IDFile;
if (
(strncmp(item_IDFile, "IT64", strlen(item_IDFile)) == 0
|| strncmp(item_IDFile, "IT63", strlen(item_IDFile)) == 0)
&& GetAugment(i)->GetItem()->HerosForgeModel == 0
)
{
continue;
}
return GetAugment(i);
const auto augment_item = augment->GetItem();
if (!augment_item) {
return false;
}
const std::string& idfile = augment_item->IDFile;
if (
EQ::ValueWithin(
augment->GetAugmentType(),
OrnamentationAugmentTypes::StandardOrnamentation,
OrnamentationAugmentTypes::SpecialOrnamentation
) ||
(
idfile != "IT63" &&
idfile != "IT64"
) ||
augment_item->HerosForgeModel
) {
return true;
}
return false;
}
EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAugment() const
{
if (!m_item || !m_item->IsClassCommon()) {
return nullptr;
}
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++) {
const auto augment = GetAugment(i);
if (augment && IsOrnamentationAugment(augment)) {
return augment;
}
}
return nullptr;
}
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const {
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const
{
// Not a Hero Forge item.
if (m_ornament_hero_model == 0 || material_slot < 0)
if (m_ornament_hero_model == 0 || material_slot < 0) {
return 0;
}
// Item is using an explicit Hero Forge ID
if (m_ornament_hero_model >= 1000)
if (m_ornament_hero_model >= 1000) {
return m_ornament_hero_model;
}
// Item is using a shorthand ID
return (m_ornament_hero_model * 100) + material_slot;
}
bool EQ::ItemInstance::UpdateOrnamentationInfo() {
if (!m_item || !m_item->IsClassCommon())
bool EQ::ItemInstance::UpdateOrnamentationInfo()
{
if (!m_item || !m_item->IsClassCommon()) {
return false;
}
bool ornamentSet = false;
const auto augment = GetOrnamentationAugment();
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
if (GetOrnamentationAug(ornamentationAugtype))
{
const ItemData* ornamentItem;
ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem();
if (ornamentItem != nullptr)
{
SetOrnamentIcon(ornamentItem->Icon);
SetOrnamentHeroModel(ornamentItem->HerosForgeModel);
if (strlen(ornamentItem->IDFile) > 2)
{
SetOrnamentationIDFile(Strings::ToUnsignedInt(&ornamentItem->IDFile[2]));
}
else
{
if (augment) {
const auto augment_item = GetOrnamentationAugment()->GetItem();
if (augment_item) {
SetOrnamentIcon(augment_item->Icon);
SetOrnamentHeroModel(augment_item->HerosForgeModel);
if (strlen(augment_item->IDFile) > 2) {
SetOrnamentationIDFile(Strings::ToUnsignedInt(&augment_item->IDFile[2]));
} else {
SetOrnamentationIDFile(0);
}
ornamentSet = true;
return true;
}
}
else
{
SetOrnamentIcon(0);
SetOrnamentHeroModel(0);
SetOrnamentationIDFile(0);
}
return ornamentSet;
SetOrnamentIcon(0);
SetOrnamentHeroModel(0);
SetOrnamentationIDFile(0);
return false;
}
bool EQ::ItemInstance::CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll) {
@@ -940,8 +934,9 @@ bool EQ::ItemInstance::IsDroppable(bool recurse) const
void EQ::ItemInstance::Initialize(SharedDatabase *db) {
// if there's no actual item, don't do anything
if (!m_item)
if (!m_item) {
return;
}
// initialize scaling items
if (m_item->CharmFileID != 0) {
@@ -950,7 +945,7 @@ void EQ::ItemInstance::Initialize(SharedDatabase *db) {
}
// initialize evolving items
else if ((db) && m_item->LoreGroup >= 1000 && m_item->LoreGroup != -1) {
else if (db && m_item->LoreGroup >= 1000) {
// not complete yet
}
}
+35 -29
View File
@@ -51,6 +51,11 @@ typedef enum {
byFlagNotSet //apply action if the flag is NOT set
} byFlagSetting;
enum OrnamentationAugmentTypes {
StandardOrnamentation = 20,
SpecialOrnamentation = 21
};
class SharedDatabase;
// ########################################
@@ -103,7 +108,8 @@ namespace EQ
bool AvailableWearSlot(uint32 aug_wear_slots) const;
int8 AvailableAugmentSlot(int32 augment_type) const;
bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const;
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
inline int GetAugmentType() const { return m_item ? m_item->AugType : 0; }
inline uint32 GetAugmentRestriction() const { return m_item ? m_item->AugRestrict : 0; }
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
@@ -136,7 +142,8 @@ namespace EQ
bool IsAugmented();
bool ContainsAugmentByID(uint32 item_id);
int CountAugmentByID(uint32 item_id);
ItemInstance* GetOrnamentationAug(int32 ornamentationAugtype) const;
bool IsOrnamentationAugment(EQ::ItemInstance* augment) const;
ItemInstance* GetOrnamentationAugment() const;
bool UpdateOrnamentationInfo();
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
@@ -304,34 +311,33 @@ namespace EQ
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
ItemInstTypes m_use_type; // Usage type for item
const ItemData* m_item; // Ptr to item data
int16 m_charges; // # of charges for chargeable items
uint32 m_price; // Bazaar /trader price
uint32 m_color;
uint32 m_merchantslot;
int16 m_currentslot;
bool m_attuned;
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
int32 m_SerialNumber; // Unique identifier for this instance of an item. Needed for Bazaar.
uint32 m_exp;
int8 m_evolveLvl;
bool m_activated;
ItemData* m_scaledItem;
::EvolveInfo* m_evolveInfo;
bool m_scaling;
uint32 m_ornamenticon;
uint32 m_ornamentidfile;
uint32 m_new_id_file;
uint32 m_ornament_hero_model;
uint32 m_recast_timestamp;
int m_task_delivered_count = 0;
ItemInstTypes m_use_type {ItemInstNormal}; // Usage type for item
const ItemData* m_item {nullptr}; // Ptr to item data
int16 m_charges {0}; // # of charges for chargeable items
uint32 m_price {0}; // Bazaar /trader price
uint32 m_color {0};
uint32 m_merchantslot {0};
int16 m_currentslot {0};
bool m_attuned {false};
int32 m_merchantcount {1}; //number avaliable on the merchant, -1=unlimited
int32 m_SerialNumber {0}; // Unique identifier for this instance of an item. Needed for Bazaar.
uint32 m_exp {0};
int8 m_evolveLvl {0};
bool m_activated {false};
ItemData* m_scaledItem {nullptr};
::EvolveInfo* m_evolveInfo {nullptr};
bool m_scaling {false};
uint32 m_ornamenticon {0};
uint32 m_ornamentidfile {0};
uint32 m_new_id_file {0};
uint32 m_ornament_hero_model {0};
uint32 m_recast_timestamp {0};
int m_task_delivered_count {0};
//
// Items inside of this item (augs or contents);
std::map<uint8, ItemInstance*> m_contents; // Zero-based index: min=0, max=9
std::map<std::string, std::string> m_custom_data;
std::map<std::string, ::Timer> m_timers;
// Items inside of this item (augs or contents) {};
std::map<uint8, ItemInstance*> m_contents {}; // Zero-based index: min=0, max=9
std::map<std::string, std::string> m_custom_data {};
std::map<std::string, ::Timer> m_timers {};
};
}
+1 -1
View File
@@ -142,7 +142,7 @@ void EQ::Net::TCPConnection::Write(const char *data, size_t count)
WriteBaton *baton = new WriteBaton;
baton->connection = this;
baton->buffer = new char[count];;
baton->buffer = new char[count];
uv_write_t *write_req = new uv_write_t;
memset(write_req, 0, sizeof(uv_write_t));
-1
View File
@@ -5218,7 +5218,6 @@ namespace RoF
/**
* Ornamentation
*/
int ornamentation_augment_type = RuleI(Character, OrnamentationAugmentType);
uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0);
uint32 hero_model = 0;
-1
View File
@@ -5477,7 +5477,6 @@ namespace RoF2
/**
* Ornamentation
*/
int ornamentation_augment_type = RuleI(Character, OrnamentationAugmentType);
uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0);
uint32 hero_model = 0;
+9 -9
View File
@@ -3851,17 +3851,17 @@ namespace UF
ob.write((const char*)&evotop, sizeof(UF::structs::EvolvingItem));
}
//ORNAMENT IDFILE / ICON -
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
uint16 ornaIcon = 0;
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
const EQ::ItemData *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
ornaIcon = aug_weap->Icon;
uint16 ornament_icon = 0;
const auto augment = inst->GetOrnamentationAugment();
ob.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
if (augment) {
const auto augment_item = augment->GetItem();
ornament_icon = augment_item->Icon;
ob.write(augment_item->IDFile, strlen(augment_item->IDFile));
}
else if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
ornaIcon = inst->GetOrnamentationIcon();
ornament_icon = inst->GetOrnamentationIcon();
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
ob.write(tmp, strlen(tmp));
@@ -3870,7 +3870,7 @@ namespace UF
UF::structs::ItemSerializationHeaderFinish hdrf;
hdrf.ornamentIcon = ornaIcon;
hdrf.ornamentIcon = ornament_icon;
hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit..
hdrf.unknown061 = 0; //possibly ornament / special ornament
hdrf.isCopied = 0; //Flag for item to be 'Copied'
+2 -1
View File
@@ -4,7 +4,8 @@
std::string Process::execute(const std::string &cmd)
{
std::shared_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose);
std::string command = fmt::format("{} 2>&1", cmd);
std::shared_ptr<FILE> pipe(popen(command.c_str(), "r"), pclose);
if (!pipe) { return "ERROR"; }
char buffer[128];
std::string result;
@@ -0,0 +1,354 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_CHARACTER_TRIBUTE_REPOSITORY_H
#define EQEMU_BASE_CHARACTER_TRIBUTE_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseCharacterTributeRepository {
public:
struct CharacterTribute {
int32_t id;
uint32_t character_id;
uint8_t tier;
uint32_t tribute;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"character_id",
"tier",
"tribute",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"character_id",
"tier",
"tribute",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("character_tribute");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static CharacterTribute NewEntity()
{
CharacterTribute e{};
e.id = 0;
e.character_id = 0;
e.tier = 0;
e.tribute = 0;
return e;
}
static CharacterTribute GetCharacterTribute(
const std::vector<CharacterTribute> &character_tributes,
int character_tribute_id
)
{
for (auto &character_tribute : character_tributes) {
if (character_tribute.id == character_tribute_id) {
return character_tribute;
}
}
return NewEntity();
}
static CharacterTribute FindOne(
Database& db,
int character_tribute_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
character_tribute_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
CharacterTribute e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.tribute = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int character_tribute_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
character_tribute_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const CharacterTribute &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.character_id));
v.push_back(columns[2] + " = " + std::to_string(e.tier));
v.push_back(columns[3] + " = " + std::to_string(e.tribute));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static CharacterTribute InsertOne(
Database& db,
CharacterTribute e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.tier));
v.push_back(std::to_string(e.tribute));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<CharacterTribute> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.tier));
v.push_back(std::to_string(e.tribute));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<CharacterTribute> All(Database& db)
{
std::vector<CharacterTribute> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterTribute e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.tribute = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<CharacterTribute> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<CharacterTribute> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {}",
BaseSelect(),
where_filter
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterTribute e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.tribute = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_CHARACTER_TRIBUTE_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
#define EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_character_tribute_repository.h"
class CharacterTributeRepository: public BaseCharacterTributeRepository {
public:
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* CharacterTributeRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* CharacterTributeRepository::GetWhereNeverExpires()
* CharacterTributeRepository::GetWhereXAndY()
* CharacterTributeRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
};
#endif //EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
+3 -2
View File
@@ -136,7 +136,6 @@ RULE_BOOL(Character, EnableFoodRequirement, true, "If disabled, food is no longe
RULE_INT(Character, BaseInstrumentSoftCap, 36, "Softcap for instrument mods, 36 commonly referred to as 3.6 as well")
RULE_BOOL(Character, UseSpellFileSongCap, true, "When they removed the AA that increased the cap they removed the above and just use the spell field")
RULE_INT(Character, BaseRunSpeedCap, 158, "Base Run Speed Cap, on live it's 158% which will give you a runspeed of 1.580 hard capped to 225")
RULE_INT(Character, OrnamentationAugmentType, 20, "Ornamentation Augment Type")
RULE_REAL(Character, EnvironmentDamageMulipliter, 1, "Multiplier for environmental damage like fall damage.")
RULE_BOOL(Character, UnmemSpellsOnDeath, true, "Setting whether at death all memorized Spells are forgotten")
RULE_REAL(Character, TradeskillUpAlchemy, 2.0, "Alchemy skillup rate adjustment. Lower is faster")
@@ -298,6 +297,7 @@ RULE_BOOL(World, StartZoneSameAsBindOnCreation, true, "Should the start zone alw
RULE_BOOL(World, EnforceCharacterLimitAtLogin, false, "Enforce the limit for characters that are online at login")
RULE_BOOL(World, EnableDevTools, true, "Enable or Disable the Developer Tools globally (Most of the time you want this enabled)")
RULE_BOOL(World, EnableChecksumVerification, false, "Enable or Disable the Checksum Verification for eqgame.exe and spells_us.txt")
RULE_INT(World, MaximumQuestErrors, 30, "Changes the maximum number of quest errors that can be displayed in #questerrors, default is 30")
RULE_CATEGORY_END()
RULE_CATEGORY(Zone)
@@ -445,7 +445,7 @@ RULE_BOOL(Spells, IllusionsAlwaysPersist, false, "Allows Illusions to persist be
RULE_BOOL(Spells, UseItemCastMessage, false, "Enable to use the \"item begins to glow\" messages when casting from an item.")
RULE_BOOL(Spells, TargetsTargetRequiresCombatRange, true, "Disable to remove combat range requirement from Target's Target Spell Target Type")
RULE_BOOL(Spells, NPCBuffLevelRestrictions, false, "Impose BuffLevelRestrictions on NPCs if true")
RULE_BOOL(Spells, ResurrectionEffectsBlock, true, "If enabled, resurrection effects cannot be overwritten.")
RULE_INT(Spells, ResurrectionEffectBlock, 2, "0 = allow overwrites/rule disabled. If set to 1 = Block all buffs that would overwrite Resurrection Effects. If set to 2 = Will not overwrite Resurrection Effects, instead moves new buff to an empty slot if available. Default is 2.")
RULE_CATEGORY_END()
RULE_CATEGORY(Combat)
@@ -518,6 +518,7 @@ RULE_BOOL(Combat, HeadshotOnlyHumanoids, true, "Enable or disable Headshot only
RULE_BOOL(Combat, EnableWarriorShielding, true, "Enable or disable Warrior Shielding Ability (/shield), true by default.")
RULE_BOOL(Combat, BackstabIgnoresElemental, false, "Enable or disable Elemental weapon damage affecting backstab damage, false by default.")
RULE_BOOL(Combat, BackstabIgnoresBane, false, "Enable or disable Bane weapon damage affecting backstab damage, false by default.")
RULE_BOOL(Combat, SummonMeleeRange, true, "Enable or disable summoning of a player when already in melee range of the summoner.")
RULE_CATEGORY_END()
RULE_CATEGORY(NPC)
+7 -9
View File
@@ -403,16 +403,14 @@ SaylinkRepository::Saylink EQ::SayLinkEngine::GetOrSaveSaylink(std::string sayli
}
// if not found in database - save
if (saylinks.empty()) {
auto new_saylink = SaylinkRepository::NewEntity();
new_saylink.phrase = saylink_text;
auto new_saylink = SaylinkRepository::NewEntity();
new_saylink.phrase = saylink_text;
// persist to database
auto link = SaylinkRepository::InsertOne(database, new_saylink);
if (link.id > 0) {
g_cached_saylinks.emplace_back(link);
return link;
}
// persist to database
auto link = SaylinkRepository::InsertOne(database, new_saylink);
if (link.id > 0) {
g_cached_saylinks.emplace_back(link);
return link;
}
return {};
+13 -12
View File
@@ -235,18 +235,19 @@
#define ServerOP_ReloadMerchants 0x4109
#define ServerOP_ReloadNPCEmotes 0x4110
#define ServerOP_ReloadObjects 0x4111
#define ServerOP_ReloadPerlExportSettings 0x4112
#define ServerOP_ReloadRules 0x4113
#define ServerOP_ReloadStaticZoneData 0x4114
#define ServerOP_ReloadTasks 0x4115
#define ServerOP_ReloadTitles 0x4116
#define ServerOP_ReloadTraps 0x4117
#define ServerOP_ReloadVariables 0x4118
#define ServerOP_ReloadVeteranRewards 0x4119
#define ServerOP_ReloadWorld 0x4120
#define ServerOP_ReloadZonePoints 0x4121
#define ServerOP_ReloadDzTemplates 0x4122
#define ServerOP_ReloadZoneData 0x4123
#define ServerOP_ReloadOpcodes 0x4112
#define ServerOP_ReloadPerlExportSettings 0x4113
#define ServerOP_ReloadRules 0x4114
#define ServerOP_ReloadStaticZoneData 0x4115
#define ServerOP_ReloadTasks 0x4116
#define ServerOP_ReloadTitles 0x4117
#define ServerOP_ReloadTraps 0x4118
#define ServerOP_ReloadVariables 0x4119
#define ServerOP_ReloadVeteranRewards 0x4120
#define ServerOP_ReloadWorld 0x4121
#define ServerOP_ReloadZonePoints 0x4122
#define ServerOP_ReloadDzTemplates 0x4123
#define ServerOP_ReloadZoneData 0x4124
#define ServerOP_CZDialogueWindow 0x4500
#define ServerOP_CZLDoNUpdate 0x4501
+2 -2
View File
@@ -47,9 +47,9 @@ const SharedTasksRepository::SharedTasks &SharedTask::GetDbSharedTask() const
return m_db_shared_task;
}
void SharedTask::SetDbSharedTask(const SharedTasksRepository::SharedTasks &m_db_shared_task)
void SharedTask::SetDbSharedTask(const SharedTasksRepository::SharedTasks &t)
{
SharedTask::m_db_shared_task = m_db_shared_task;
SharedTask::m_db_shared_task = t;
}
SharedTaskRequest SharedTask::GetRequestCharacters(Database &db, uint32_t requested_character_id)
+1 -1
View File
@@ -216,7 +216,7 @@ public:
// active record of database shared task
const SharedTasksRepository::SharedTasks &GetDbSharedTask() const;
void SetDbSharedTask(const SharedTasksRepository::SharedTasks &m_db_shared_task);
void SetDbSharedTask(const SharedTasksRepository::SharedTasks &t);
std::vector<SharedTaskActivityStateEntry> m_shared_task_activity_state;
std::vector<SharedTaskMember> m_members;
+92 -69
View File
@@ -133,55 +133,54 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
void SharedDatabase::SetMailKey(int CharID, int IPAddress, int MailKey)
{
char MailKeyString[17];
char mail_key[17];
if (RuleB(Chat, EnableMailKeyIPVerification) == true)
sprintf(MailKeyString, "%08X%08X", IPAddress, MailKey);
else
sprintf(MailKeyString, "%08X", MailKey);
if (RuleB(Chat, EnableMailKeyIPVerification) == true) {
sprintf(mail_key, "%08X%08X", IPAddress, MailKey);
}
else {
sprintf(mail_key, "%08X", MailKey);
}
const std::string query = StringFormat("UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
MailKeyString, CharID);
const auto results = QueryDatabase(query);
if (!results.Success())
LogError("SharedDatabase::SetMailKey({}, {}) : {}", CharID, MailKeyString, results.ErrorMessage().c_str());
const std::string query = StringFormat(
"UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
mail_key, CharID
);
const auto results = QueryDatabase(query);
if (!results.Success()) {
LogError("SharedDatabase::SetMailKey({}, {}) : {}", CharID, mail_key, results.ErrorMessage().c_str());
}
}
std::string SharedDatabase::GetMailKey(int CharID, bool key_only)
SharedDatabase::MailKeys SharedDatabase::GetMailKey(int character_id)
{
const std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `id`='%i' LIMIT 1", CharID);
auto results = QueryDatabase(query);
const std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `id`='%i' LIMIT 1", character_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
Log(Logs::Detail, Logs::MySQLError, "Error retrieving mailkey from database: %s", results.ErrorMessage().c_str());
return std::string();
return MailKeys{};
}
if (!results.RowCount()) {
Log(Logs::General, Logs::ClientLogin, "Error: Mailkey for character id [%i] does not exist or could not be found", CharID);
return std::string();
Log(Logs::General,
Logs::ClientLogin,
"Error: Mailkey for character id [%i] does not exist or could not be found",
character_id
);
return MailKeys{};
}
auto& row = results.begin();
auto &row = results.begin();
if (row != results.end()) {
std::string mail_key = row[0];
if (mail_key.length() > 8 && key_only) {
return mail_key.substr(8);
}
else {
return mail_key;
}
return MailKeys{
.mail_key = mail_key.substr(8),
.mail_key_full = mail_key
};
}
else {
Log(Logs::General, Logs::MySQLError, "Internal MySQL error in SharedDatabase::GetMailKey(int, bool)");
return std::string();
}
return MailKeys{};
}
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<EQ::ItemInstance*>::const_iterator &start, std::list<EQ::ItemInstance*>::const_iterator &end)
@@ -425,17 +424,13 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
int32 SharedDatabase::GetSharedPlatinum(uint32 account_id)
{
const std::string query = StringFormat("SELECT sharedplat FROM account WHERE id = '%i'", account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
if (results.RowCount() != 1)
return 0;
auto& row = results.begin();
const auto query = fmt::format("SELECT sharedplat FROM account WHERE id = {}", account_id);
auto results = QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
return 0;
}
auto row = results.begin();
return Strings::ToInt(row[0]);
}
@@ -499,25 +494,32 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is
{
std::string query;
if (is_charid)
query = StringFormat("SELECT sb.slotid, sb.itemid, sb.charges, "
"sb.augslot1, sb.augslot2, sb.augslot3, "
"sb.augslot4, sb.augslot5, sb.augslot6, sb.custom_data "
"FROM sharedbank sb INNER JOIN character_data ch "
"ON ch.account_id=sb.acctid WHERE ch.id = %i ORDER BY sb.slotid",
id);
else
query = StringFormat("SELECT slotid, itemid, charges, "
"augslot1, augslot2, augslot3, "
"augslot4, augslot5, augslot6, custom_data "
"FROM sharedbank WHERE acctid=%i ORDER BY slotid",
id);
if (is_charid) {
query = fmt::format(
"SELECT sb.slotid, sb.itemid, sb.charges, "
"sb.augslot1, sb.augslot2, sb.augslot3, "
"sb.augslot4, sb.augslot5, sb.augslot6, sb.custom_data "
"FROM sharedbank sb INNER JOIN character_data ch "
"ON ch.account_id = sb.acctid WHERE ch.id = {} ORDER BY sb.slotid",
id
);
} else {
query = fmt::format(
"SELECT slotid, itemid, charges, "
"augslot1, augslot2, augslot3, "
"augslot4, augslot5, augslot6, custom_data "
"FROM sharedbank WHERE acctid = {} ORDER BY slotid",
id
);
}
auto results = QueryDatabase(query);
// If we have no results we still need to return true
if (!results.Success()) {
return false;
}
for (auto& row = results.begin(); row != results.end(); ++row) {
for (auto row : results) {
int16 slot_id = static_cast<int16>(Strings::ToInt(row[0]));
uint32 item_id = Strings::ToUnsignedInt(row[1]);
const int16 charges = static_cast<int16>(Strings::ToInt(row[2]));
@@ -533,16 +535,26 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is
const EQ::ItemData *item = GetItem(item_id);
if (!item) {
LogError("Warning: [{}] [{}] has an invalid item_id [{}] in inventory slot [{}]",
((is_charid == true) ? "charid" : "acctid"), id, item_id, slot_id);
LogError(
"Warning: [{}] [{}] has an invalid item_id [{}] in inventory slot [{}]",
is_charid ? "charid" : "acctid",
id,
item_id,
slot_id
);
continue;
}
auto inst = CreateBaseItem(item, charges);
if (!inst) {
continue;
}
EQ::ItemInstance *inst = CreateBaseItem(item, charges);
if (inst && item->IsClassCommon()) {
for (int i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) {
if (aug[i])
if (aug[i]) {
inst->PutAugment(this, i, aug[i]);
}
}
}
@@ -556,14 +568,21 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is
safe_delete(inst);
// Save ptr to item in inventory
if (put_slot_id != INVALID_INDEX)
if (put_slot_id != INVALID_INDEX) {
continue;
}
LogError("Warning: Invalid slot_id for item in shared bank inventory: [{}]=[{}], item_id=[{}], slot_id=[{}]",
((is_charid == true) ? "charid" : "acctid"), id, item_id, slot_id);
LogError(
"Warning: Invalid slot_id for item in shared bank inventory: [{}]=[{}], item_id=[{}], slot_id=[{}]",
is_charid ? "charid" : "acctid",
id,
item_id,
slot_id
);
if (is_charid)
if (is_charid) {
SaveInventory(id, nullptr, slot_id);
}
}
return true;
@@ -619,7 +638,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv)
}
else if (slot_id <= EQ::invbag::BANK_BAGS_END && slot_id >= EQ::invbag::BANK_BAGS_BEGIN) { // Titanium check
const auto parent_index = ((slot_id - EQ::invbag::BANK_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT);
if (parent_index < EQ::invslot::SLOT_BEGIN || parent_index >= bank_size) {
if (parent_index >= bank_size) {
cv_conflict = true;
continue;
}
@@ -1564,24 +1583,28 @@ EQ::ItemInstance* SharedDatabase::CreateBaseItem(const EQ::ItemData* item, int16
if (item) {
// if maxcharges is -1 that means it is an unlimited use item.
// set it to 1 charge so that it is usable on creation
if (charges == 0 && item->MaxCharges == -1)
if (charges == 0 && item->MaxCharges == -1) {
charges = 1;
}
// Stackable items need a minimum charge of 1 to remain moveable.
if(charges <= 0 && item->Stackable)
if (charges <= 0 && item->Stackable) {
charges = 1;
}
inst = new EQ::ItemInstance(item, charges);
if (inst == nullptr) {
if (!inst) {
LogError("Error: valid item data returned a null reference for EQ::ItemInstance creation in SharedDatabase::CreateBaseItem()");
LogError("Item Data = ID: {}, Name: {}, Charges: {}", item->ID, item->Name, charges);
return nullptr;
}
if(item->CharmFileID != 0 || (item->LoreGroup >= 1000 && item->LoreGroup != -1)) {
if (item->CharmFileID != 0 || item->LoreGroup >= 1000) {
inst->Initialize(this);
}
}
return inst;
}
+5 -1
View File
@@ -81,7 +81,11 @@ public:
bool SetGMInvul(uint32 account_id, bool gminvul);
bool SetGMFlymode(uint32 account_id, uint8 flymode);
void SetMailKey(int CharID, int IPAddress, int MailKey);
std::string GetMailKey(int CharID, bool key_only = false);
struct MailKeys {
std::string mail_key;
std::string mail_key_full;
};
MailKeys GetMailKey(int character_id);
bool SaveCursor(
uint32 char_id,
std::list<EQ::ItemInstance *>::const_iterator &start,
-27
View File
@@ -148,33 +148,6 @@ int32 EQ::skills::GetBaseDamage(SkillType skill)
}
}
bool EQ::skills::IsMeleeDmg(SkillType skill)
{
switch (skill) {
case Skill1HBlunt:
case Skill1HSlashing:
case Skill2HBlunt:
case Skill2HSlashing:
case SkillBackstab:
case SkillBash:
case SkillDragonPunch:
case SkillEagleStrike:
case SkillFlyingKick:
case SkillHandtoHand:
case SkillKick:
case Skill1HPiercing:
case SkillRiposte:
case SkillRoundKick:
case SkillThrowing:
case SkillTigerClaw:
case SkillFrenzy:
case Skill2HPiercing:
return true;
default:
return false;
}
}
const std::map<EQ::skills::SkillType, std::string>& EQ::skills::GetSkillTypeMap()
{
static const std::map<SkillType, std::string> skill_type_map = {
-1
View File
@@ -168,7 +168,6 @@ namespace EQ
bool IsBardInstrumentSkill(SkillType skill);
bool IsCastingSkill(SkillType skill);
int32 GetBaseDamage(SkillType skill);
bool IsMeleeDmg(SkillType skill);
extern const std::map<SkillType, std::string>& GetSkillTypeMap();
extern const std::vector<SkillType>& GetExtraDamageSkills();
+1177 -700
View File
File diff suppressed because it is too large Load Diff
+101 -60
View File
@@ -171,6 +171,37 @@
#define SPELL_ILLUSION_MALE 1732
#define SPELL_UNSUMMON_SELF 892
#define SPELL_ANCIENT_LIFEBANE 2115
#define SPELL_GMHP25K 6817
#define SPELL_GMHP50K 6818
#define SPELL_GMHP100K 6819
#define SPELL_GMHP225K 6820
#define SPELL_GMHP475K 6821
#define SPELL_GMHP925K 6822
#define SPELL_GMHP2M 6823
#define SPELL_GMHP3M 6824
#define SPELL_GMHP5M 39851
#define SPELL_GUIDE_ACTING_ONE 778
#define SPELL_GUIDE_ALLIANCE_ONE 810
#define SPELL_GUIDE_CANCEL_MAGIC_ONE 811
#define SPELL_GUIDE_JOURNEY_ONE 813
#define SPELL_GUIDE_VISION_ONE 814
#define SPELL_GUIDE_HEALTH_ONE 815
#define SPELL_GUIDE_INVULNERABILITY_ONE 816
#define SPELL_GUIDE_BOLT_ONE 817
#define SPELL_GUIDE_MEMORY_BLUR_ONE 818
#define SPELL_GUIDE_ACTING_TWO 1209
#define SPELL_GUIDE_CANCEL_MAGIC_TWO 1211
#define SPELL_GUIDE_JOURNEY_TWO 1212
#define SPELL_GUIDE_VISION_TWO 1213
#define SPELL_GUIDE_HEALTH_TWO 1214
#define SPELL_GUIDE_INVULNERABILITY_TWO 1215
#define SPELL_GUIDE_BOLT_TWO 1216
#define SPELL_GUIDE_MEMORY_BLUR_TWO 1217
#define SPELL_GUIDE_ALLIANCE_TWO 1219
#define SPELL_GUIDE_EVACUATION 3921
#define SPELL_GUIDE_LEVITATION 39852
#define SPELL_GUIDE_SPELL_HASTE 39853
#define SPELL_GUIDE_HASTE 39854
//spellgroup ids
#define SPELLGROUP_FRENZIED_BURNOUT 2754
@@ -201,8 +232,22 @@
#define INSTRUMENT_LUTE 13011
#define INSTRUMENT_HORN 13012
//option types for the rule Spells:ResurrectionEffectBlock
#define RES_EFFECTS_CANNOT_STACK -1
#define NO_RES_EFFECTS_BLOCK 0
#define RES_EFFECTS_BLOCK 1
#define RES_EFFECTS_BLOCK_WITH_BUFFS 2
#define MOVE_NEW_SLOT 2
const int Z_AGGRO=10;
#define PARTIAL_DEATH_SAVE 1
#define FULL_DEATH_SAVE 2
#define MAX_FAST_HEAL_CASTING_TIME 2000
#define MAX_VERY_FAST_HEAL_CASTING_TIME 1000
#define DETRIMENTAL_EFFECT 0
#define BENEFICIAL_EFFECT 1
#define BENEFICIAL_EFFECT_GROUP_ONLY 2
const uint32 MobAISpellRange=100; // max range of buffs
@@ -1160,7 +1205,7 @@ typedef enum {
#define SE_LimitUseMin 422 // implemented, @Ff Minium amount of numhits for a spell to be focused, base: numhit amt
#define SE_LimitUseType 423 // implemented, @Ff Focus will only affect if has this numhits type, base: numhit type
#define SE_GravityEffect 424 // implemented - Pulls/pushes you toward/away the mob at a set pace
//#define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626)
#define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626)
#define SE_IncreaseExtTargetWindow 426 // *not implmented[AA] - increases the capacity of your extended target window
#define SE_SkillProcAttempt 427 // implemented - chance to proc when using a skill(ie taunt)
#define SE_LimitToSkill 428 // implemented, @Procs, limits what combat skills will effect a skill proc, base: skill value, limit: none, max: none
@@ -1443,7 +1488,7 @@ extern int32 SPDAT_RECORDS;
bool IsTargetableAESpell(uint16 spell_id);
bool IsSacrificeSpell(uint16 spell_id);
bool IsLifetapSpell(uint16 spell_id);
bool IsMezSpell(uint16 spell_id);
bool IsMesmerizeSpell(uint16 spell_id);
bool IsStunSpell(uint16 spell_id);
bool IsSlowSpell(uint16 spell_id);
bool IsHasteSpell(uint16 spell_id);
@@ -1452,22 +1497,23 @@ bool IsPercentalHealSpell(uint16 spell_id);
bool IsGroupOnlySpell(uint16 spell_id);
bool IsBeneficialSpell(uint16 spell_id);
bool IsDetrimentalSpell(uint16 spell_id);
bool IsInvisSpell(uint16 spell_id);
bool IsInvisibleSpell(uint16 spell_id);
bool IsInvulnerabilitySpell(uint16 spell_id);
bool IsCHDurationSpell(uint16 spell_id);
bool IsCompleteHealDurationSpell(uint16 spell_id);
bool IsPoisonCounterSpell(uint16 spell_id);
bool IsDiseaseCounterSpell(uint16 spell_id);
bool IsSummonItemSpell(uint16 spell_id);
bool IsSummonSkeletonSpell(uint16 spell_id);
bool IsSummonPetSpell(uint16 spell_id);
bool IsSummonPCSpell(uint16 spell_id);
bool IsPetSpell(uint16 spell_id);
bool IsCharmSpell(uint16 spell_id);
bool IsBlindSpell(uint16 spell_id);
bool IsEffectHitpointsSpell(uint16 spell_id);
bool IsReduceCastTimeSpell(uint16 spell_id);
bool IsHealthSpell(uint16 spell_id);
bool IsCastTimeReductionSpell(uint16 spell_id);
bool IsIncreaseDurationSpell(uint16 spell_id);
bool IsReduceManaSpell(uint16 spell_id);
bool IsExtRangeSpell(uint16 spell_id);
bool IsManaCostReductionSpell(uint16 spell_id);
bool IsIncreaseRangeSpell(uint16 spell_id);
bool IsImprovedHealingSpell(uint16 spell_id);
bool IsImprovedDamageSpell(uint16 spell_id);
bool IsAEDurationSpell(uint16 spell_id);
@@ -1475,26 +1521,22 @@ bool IsPureNukeSpell(uint16 spell_id);
bool IsAENukeSpell(uint16 spell_id);
bool IsPBAENukeSpell(uint16 spell_id);
bool IsAERainNukeSpell(uint16 spell_id);
bool IsPartialCapableSpell(uint16 spell_id);
bool IsPartialResistableSpell(uint16 spell_id);
bool IsResistableSpell(uint16 spell_id);
bool IsGroupSpell(uint16 spell_id);
bool IsTGBCompatibleSpell(uint16 spell_id);
bool IsBardSong(uint16 spell_id);
bool IsEffectInSpell(uint16 spellid, int effect);
uint16 GetTriggerSpellID(uint16 spell_id, uint32 effect);
bool IsBlankSpellEffect(uint16 spellid, int effect_index);
bool IsValidSpell(uint32 spellid);
bool IsSummonSpell(uint16 spellid);
bool IsEvacSpell(uint16 spellid);
bool IsDamageSpell(uint16 spellid);
bool IsFearSpell(uint16 spellid);
bool IsCureSpell(uint16 spellid);
bool BeneficialSpell(uint16 spell_id);
bool GroupOnlySpell(uint16 spell_id);
int GetSpellEffectIndex(uint16 spell_id, int effect);
int CanUseSpell(uint16 spellid, int classa, int level);
int GetMinLevel(uint16 spell_id);
int GetSpellLevel(uint16 spell_id, int classa);
bool IsEffectInSpell(uint16 spell_id, int effect_id);
uint16 GetSpellTriggerSpellID(uint16 spell_id, int effect_id);
bool IsBlankSpellEffect(uint16 spell_id, int effect_index);
bool IsValidSpell(uint32 spell_id);
bool IsSummonSpell(uint16 spell_id);
bool IsDamageSpell(uint16 spell_id);
bool IsFearSpell(uint16 spell_id);
bool IsCureSpell(uint16 spell_id);
int GetSpellEffectIndex(uint16 spell_id, int effect_id);
uint8 GetSpellMinimumLevel(uint16 spell_id);
uint8 GetSpellLevel(uint16 spell_id, uint8 class_id);
int CalcBuffDuration_formula(int level, int formula, int duration);
int32 CalculatePoisonCounters(uint16 spell_id);
int32 CalculateDiseaseCounters(uint16 spell_id);
@@ -1505,10 +1547,11 @@ bool IsDisciplineBuff(uint16 spell_id);
bool IsDiscipline(uint16 spell_id);
bool IsCombatSkill(uint16 spell_id);
bool IsResurrectionEffects(uint16 spell_id);
int8 GetSpellResurrectionSicknessCheck(uint16 spell_id_one, uint16 spell_id_two);
bool IsRuneSpell(uint16 spell_id);
bool IsMagicRuneSpell(uint16 spell_id);
bool IsManaTapSpell(uint16 spell_id);
bool IsAllianceSpellLine(uint16 spell_id);
bool IsAllianceSpell(uint16 spell_id);
bool IsDeathSaveSpell(uint16 spell_id);
bool IsFullDeathSaveSpell(uint16 spell_id);
bool IsPartialDeathSaveSpell(uint16 spell_id);
@@ -1517,10 +1560,10 @@ bool IsSuccorSpell(uint16 spell_id);
bool IsTeleportSpell(uint16 spell_id);
bool IsTranslocateSpell(uint16 spell_id);
bool IsGateSpell(uint16 spell_id);
bool IsPlayerIllusionSpell(uint16 spell_id); // seveian 2008-09-23
bool IsIllusionSpell(uint16 spell_id);
bool IsLDoNObjectSpell(uint16 spell_id);
int32 GetSpellResistType(uint16 spell_id);
int32 GetSpellTargetType(uint16 spell_id);
int GetSpellResistType(uint16 spell_id);
int GetSpellTargetType(uint16 spell_id);
bool IsHealOverTimeSpell(uint16 spell_id);
bool IsCompleteHealSpell(uint16 spell_id);
bool IsFastHealSpell(uint16 spell_id);
@@ -1535,38 +1578,36 @@ bool IsSelfConversionSpell(uint16 spell_id);
bool IsBuffSpell(uint16 spell_id);
bool IsPersistDeathSpell(uint16 spell_id);
bool IsSuspendableSpell(uint16 spell_id);
uint32 GetMorphTrigger(uint32 spell_id);
bool IsCastonFadeDurationSpell(uint16 spell_id);
bool IsPowerDistModSpell(uint16 spell_id);
uint32 GetPartialMeleeRuneReduction(uint32 spell_id);
uint32 GetPartialMagicRuneReduction(uint32 spell_id);
uint32 GetPartialMeleeRuneAmount(uint32 spell_id);
uint32 GetPartialMagicRuneAmount(uint32 spell_id);
bool NoDetrimentalSpellAggro(uint16 spell_id);
bool IsStackableDot(uint16 spell_id);
bool IsBardOnlyStackEffect(int effect);
bool IsCastWhileInvis(uint16 spell_id);
bool IsEffectIgnoredInStacking(int spa);
bool IsFocusLimit(int spa);
bool SpellRequiresTarget(int target_type);
bool IsVirusSpell(int32 spell_id);
int GetViralMinSpreadTime(int32 spell_id);
int GetViralMaxSpreadTime(int32 spell_id);
int GetViralSpreadRange(int32 spell_id);
bool IsInstrumentModAppliedToSpellEffect(int32 spell_id, int effect);
bool IsPulsingBardSong(int32 spell_id);
uint32 GetProcLimitTimer(int32 spell_id, int proc_type);
bool IgnoreCastingRestriction(int32 spell_id);
int CalcPetHp(int levelb, int classb, int STA = 75);
int GetSpellEffectDescNum(uint16 spell_id);
DmgShieldType GetDamageShieldType(uint16 spell_id, int32 DSType = 0);
bool DetrimentalSpellAllowsRest(uint16 spell_id);
uint32 GetNimbusEffect(uint16 spell_id);
int32 GetFuriousBash(uint16 spell_id);
bool IsCastOnFadeDurationSpell(uint16 spell_id);
bool IsDistanceModifierSpell(uint16 spell_id);
int GetSpellPartialMeleeRuneReduction(uint16 spell_id);
int GetSpellPartialMagicRuneReduction(uint16 spell_id);
int GetSpellPartialMeleeRuneAmount(uint16 spell_id);
int GetSpellPartialMagicRuneAmount(uint16 spell_id);
bool IsNoDetrimentalSpellAggroSpell(uint16 spell_id);
bool IsStackableDOT(uint16 spell_id);
bool IsBardOnlyStackEffect(int effect_id);
bool IsCastWhileInvisibleSpell(uint16 spell_id);
bool IsEffectIgnoredInStacking(int effect_id);
bool IsFocusLimit(int effect_id);
bool IsTargetRequiredForSpell(uint16 spell_id);
bool IsVirusSpell(uint16 spell_id);
int GetSpellViralMinimumSpreadTime(uint16 spell_id);
int GetSpellViralMaximumSpreadTime(uint16 spell_id);
int GetSpellViralSpreadRange(uint16 spell_id);
bool IsInstrumentModifierAppliedToSpellEffect(uint16 spell_id, int effect_id);
bool IsPulsingBardSong(uint16 spell_id);
int GetSpellProcLimitTimer(uint16 spell_id, int proc_type);
bool IsCastNotStandingSpell(uint16 spell_id);
int GetSpellEffectDescriptionNumber(uint16 spell_id);
DmgShieldType GetDamageShieldType(uint16 spell_id, int damage_shield_type = 0);
bool IsRestAllowedSpell(uint16 spell_id);
int GetSpellNimbusEffect(uint16 spell_id);
int GetSpellFuriousBash(uint16 spell_id);
bool IsShortDurationBuff(uint16 spell_id);
bool IsSpellUsableThisZoneType(uint16 spell_id, uint8 zone_type);
bool IsSpellUsableInThisZoneType(uint16 spell_id, uint8 zone_type);
const char *GetSpellName(uint16 spell_id);
int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot = 0);
bool CastRestrictedSpell(int spellid);
int GetSpellStatValue(uint16 spell_id, const char* stat_identifier, uint8 slot = 0);
bool IsCastRestrictedSpell(uint16 spell_id);
#endif
+2 -5
View File
@@ -287,15 +287,12 @@ std::string Strings::Commify(const std::string &number)
for (i = string_length - 3; i >= 0; i -= 3) {
if (i > 0) {
temp_string = "," + number.substr(static_cast<unsigned long>(i), 3) + temp_string;
}
else {
} else {
temp_string = number.substr(static_cast<unsigned long>(i), 3) + temp_string;
}
}
if (i < 0) {
temp_string = number.substr(0, static_cast<unsigned long>(3 + i)) + temp_string;
}
temp_string = number.substr(0, static_cast<unsigned long>(3 + i)) + temp_string;
return temp_string;
}
-3
View File
@@ -57,9 +57,6 @@ typedef const char Const_char; //for perl XS
#define safe_delete(d) if(d) { delete d; d=nullptr; }
#define safe_delete_array(d) if(d) { delete[] d; d=nullptr; }
#define L32(i) ((uint32) i)
#define H32(i) ((uint32) (i >> 32))
#define L16(i) ((uint16) i)
#ifndef WIN32
// More WIN32 compatability
+2 -2
View File
@@ -25,7 +25,7 @@
// Build variables
// these get injected during the build pipeline
#define CURRENT_VERSION "22.9.1-dev" // always append -dev to the current version for custom-builds
#define CURRENT_VERSION "22.13.1-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__
@@ -42,7 +42,7 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9227
#define CURRENT_BINARY_DATABASE_VERSION 9228
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039
File diff suppressed because it is too large Load Diff
+58
View File
@@ -24,6 +24,8 @@
#include "../common/repositories/zone_repository.h"
#include "../common/repositories/base/base_content_flags_repository.h"
#include <glm/vec4.hpp>
class ZoneStore {
public:
ZoneStore();
@@ -43,6 +45,62 @@ public:
const char *GetZoneName(uint32 zone_id, bool error_unknown = false);
const char *GetZoneLongName(uint32 zone_id, bool error_unknown = false);
ZoneRepository::Zone *GetZoneWithFallback(uint32 zone_id, int version = 0);
glm::vec4 GetZoneSafeCoordinates(uint32 zone_id, int version = 0);
float GetZoneGraveyardID(uint32 zone_id, int version = 0);
uint8 GetZoneMinimumLevel(uint32 zone_id, int version = 0);
uint8 GetZoneMaximumLevel(uint32 zone_id, int version = 0);
uint8 GetZoneMinimumStatus(uint32 zone_id, int version = 0);
int GetZoneTimeZone(uint32 zone_id, int version = 0);
int GetZoneMaximumPlayers(uint32 zone_id, int version = 0);
uint32 GetZoneRuleSet(uint32 zone_id, int version = 0);
const std::string& GetZoneNote(uint32 zone_id, int version = 0);
float GetZoneUnderworld(uint32 zone_id, int version = 0);
float GetZoneMinimumClip(uint32 zone_id, int version = 0);
float GetZoneMaximumClip(uint32 zone_id, int version = 0);
float GetZoneFogMinimumClip(uint32 zone_id, uint8 slot = 0, int version = 0);
float GetZoneFogMaximumClip(uint32 zone_id, uint8 slot = 0, int version = 0);
uint8 GetZoneFogRed(uint32 zone_id, uint8 slot = 0, int version = 0);
uint8 GetZoneFogGreen(uint32 zone_id, uint8 slot = 0, int version = 0);
uint8 GetZoneFogBlue(uint32 zone_id, uint8 slot = 0, int version = 0);
uint8 GetZoneSky(uint32 zone_id, int version = 0);
uint8 GetZoneZType(uint32 zone_id, int version = 0);
float GetZoneExperienceMultiplier(uint32 zone_id, int version = 0);
float GetZoneWalkSpeed(uint32 zone_id, int version = 0);
uint8 GetZoneTimeType(uint32 zone_id, int version = 0);
float GetZoneFogDensity(uint32 zone_id, int version = 0);
const std::string& GetZoneFlagNeeded(uint32 zone_id, int version = 0);
int8 GetZoneCanBind(uint32 zone_id, int version = 0);
int8 GetZoneCanCombat(uint32 zone_id, int version = 0);
int8 GetZoneCanLevitate(uint32 zone_id, int version = 0);
int8 GetZoneCastOutdoor(uint32 zone_id, int version = 0);
uint8 GetZoneHotzone(uint32 zone_id, int version = 0);
uint8 GetZoneInstanceType(uint32 zone_id, int version = 0);
uint64 GetZoneShutdownDelay(uint32 zone_id, int version = 0);
int8 GetZonePEQZone(uint32 zone_id, int version = 0);
int8 GetZoneExpansion(uint32 zone_id, int version = 0);
int8 GetZoneBypassExpansionCheck(uint32 zone_id, int version = 0);
uint8 GetZoneSuspendBuffs(uint32 zone_id, int version = 0);
int GetZoneRainChance(uint32 zone_id, uint8 slot = 0, int version = 0);
int GetZoneRainDuration(uint32 zone_id, uint8 slot = 0, int version = 0);
int GetZoneSnowChance(uint32 zone_id, uint8 slot = 0, int version = 0);
int GetZoneSnowDuration(uint32 zone_id, uint8 slot = 0, int version = 0);
float GetZoneGravity(uint32 zone_id, int version = 0);
int GetZoneType(uint32 zone_id, int version = 0);
int8 GetZoneSkyLock(uint32 zone_id, int version = 0);
int GetZoneFastRegenHP(uint32 zone_id, int version = 0);
int GetZoneFastRegenMana(uint32 zone_id, int version = 0);
int GetZoneFastRegenEndurance(uint32 zone_id, int version = 0);
int GetZoneNPCMaximumAggroDistance(uint32 zone_id, int version = 0);
uint32 GetZoneMaximumMovementUpdateRange(uint32 zone_id, int version = 0);
int8 GetZoneMinimumExpansion(uint32 zone_id, int version = 0);
int8 GetZoneMaximumExpansion(uint32 zone_id, int version = 0);
const std::string& GetZoneContentFlags(uint32 zone_id, int version = 0);
const std::string& GetZoneContentFlagsDisabled(uint32 zone_id, int version = 0);
int GetZoneUnderworldTeleportIndex(uint32 zone_id, int version = 0);
int GetZoneLavaDamage(uint32 zone_id, int version = 0);
int GetZoneMinimumLavaDamage(uint32 zone_id, int version = 0);
private:
std::vector<ZoneRepository::Zone> m_zones;
};
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "eqemu-server",
"version": "22.9.1",
"version": "22.13.1",
"repository": {
"type": "git",
"url": "https://github.com/EQEmu/Server.git"
+4 -4
View File
@@ -701,11 +701,11 @@ void ChatChannelList::Process() {
LogDebug("Empty temporary password protected channel [{}] being destroyed",
CurrentChannel->GetName().c_str());
RemoveChannel(CurrentChannel);
iterator.RemoveCurrent();
}
else {
iterator.Advance();
}
iterator.Advance();
}
}
+2
View File
@@ -144,6 +144,8 @@ int main() {
->LoadLogDatabaseSettings()
->StartFileLogs();
player_event_logs.SetDatabase(&database)->Init();
char tmp[64];
// ucs has no 'reload rules' handler
+1 -15
View File
@@ -1801,23 +1801,9 @@ sub fetch_peq_db_full
sub map_files_fetch_bulk
{
print "[Install] Fetching Latest Maps... (This could take a few minutes...)\n";
get_remote_file("http://analytics.akkadius.com/maps.zip", "maps/maps.zip", 1);
get_remote_file("https://github.com/Akkadius/eqemu-maps/releases/latest/download/maps.zip", "maps/maps.zip", 1);
unzip('maps/maps.zip', 'maps/');
my @files;
my $start_dir = "maps/EQEmuMaps-master/";
find(
sub { push @files, $File::Find::name unless -d; },
$start_dir
);
for my $file (@files) {
$destination_file = $file;
$destination_file =~ s/maps\/EQEmuMaps-master\///g;
print "[Install] Installing [" . $destination_file . "]\n";
copy_file($file, "maps/" . $destination_file);
}
print "[Install] Fetched Latest Maps\n";
rmtree('maps/EQEmuMaps-master');
unlink('maps/maps.zip');
}
+1
View File
@@ -481,6 +481,7 @@
9225|2023_01_21_bots_raid_members.sql|SHOW COLUMNS FROM `raid_members` LIKE 'bot_id'|empty|
9226|2023_03_17_corpse_fields.sql|SHOW COLUMNS FROM `character_corpse_items` LIKE 'custom_data'|empty|
9227|2023_03_24_npc_scale_global_base_verify.sql|SHOW COLUMNS FROM `npc_scale_global_base` LIKE 'heroic_strikethrough'|not_empty|
9228|2023_05_08_character_tribute_primary_key.sql|SHOW COLUMNS FROM `character_tribute` LIKE 'character_id'|empty|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not
@@ -0,0 +1,4 @@
ALTER TABLE `character_tribute`
CHANGE COLUMN `id` `character_id` int(11) UNSIGNED NOT NULL DEFAULT 0,
ADD COLUMN `id` int(11) NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (`id`);
+2 -8
View File
@@ -36,9 +36,7 @@ void WorldserverCLI::DatabaseDump(int argc, char **argv, argh::parser &cmd, std:
s->SetDumpPath(cmd("--dump-path").str());
}
/**
* Set Option
*/
// options
s->SetDumpContentTables(cmd[{"--content-tables"}] || dump_all);
s->SetDumpLoginServerTables(cmd[{"--login-tables"}] || dump_all);
s->SetDumpPlayerTables(cmd[{"--player-tables"}] || dump_all);
@@ -48,15 +46,11 @@ void WorldserverCLI::DatabaseDump(int argc, char **argv, argh::parser &cmd, std:
s->SetDumpSystemTables(cmd[{"--system-tables"}] || dump_all);
s->SetDumpQueryServerTables(cmd[{"--query-serv-tables"}] || dump_all);
s->SetDumpAllTables(dump_all);
s->SetDumpWithNoData(cmd[{"--table-structure-only"}]);
s->SetDumpTableLock(cmd[{"--table-lock"}]);
s->SetDumpWithCompression(cmd[{"--compress"}]);
s->SetDumpOutputToConsole(cmd[{"--dump-output-to-console"}]);
s->SetDumpDropTableSyntaxOnly(cmd[{"--drop-table-syntax-only"}]);
/**
* Dump
*/
s->Dump();
s->DatabaseDump();
}
+2 -2
View File
@@ -268,8 +268,8 @@ void ClientList::SendCLEList(const int16& admin, const char* to, WorldTCPConnect
strcpy(newline, "\r\n");
else
strcpy(newline, "^");
std::vector<char> out;
auto out = fmt::memory_buffer();
iterator.Reset();
while(iterator.MoreElements()) {
ClientListEntry* cle = iterator.GetData();
@@ -1008,7 +1008,7 @@ void ClientList::ConsoleSendWhoAll(const char* to, int16 admin, Who_All_Struct*
if (whom)
whomlen = strlen(whom->whom);
std::vector<char> out;
auto out = fmt::memory_buffer();
fmt::format_to(std::back_inserter(out), "Players on server:");
if (connection->IsConsole())
fmt::format_to(std::back_inserter(out), "\r\n");
+5 -5
View File
@@ -361,7 +361,7 @@ void ConsoleTell(
auto join_args = args;
join_args.erase(join_args.begin(), join_args.begin() + 1);
zoneserver_list.SendChannelMessage(tmpname, to.c_str(), 7, 0, Strings::Join(join_args, " ").c_str());
zoneserver_list.SendChannelMessage(tmpname, to.c_str(), ChatChannel_Tell, 0, Strings::Join(join_args, " ").c_str());
}
/**
@@ -382,7 +382,7 @@ void ConsoleBroadcast(
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], connection->UserName().c_str());
zoneserver_list.SendChannelMessage(tmpname, 0, 6, 0, Strings::Join(args, " ").c_str());
zoneserver_list.SendChannelMessage(tmpname, 0, ChatChannel_Broadcast, 0, Strings::Join(args, " ").c_str());
}
/**
@@ -403,7 +403,7 @@ void ConsoleGMSay(
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], connection->UserName().c_str());
zoneserver_list.SendChannelMessage(tmpname, 0, 11, 0, Strings::Join(args, " ").c_str());
zoneserver_list.SendChannelMessage(tmpname, 0, ChatChannel_GMSAY, 0, Strings::Join(args, " ").c_str());
}
/**
@@ -457,7 +457,7 @@ void ConsoleOOC(
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], connection->UserName().c_str());
zoneserver_list.SendChannelMessage(tmpname, 0, 5, 0, Strings::Join(args, " ").c_str());
zoneserver_list.SendChannelMessage(tmpname, 0, ChatChannel_OOC, 0, Strings::Join(args, " ").c_str());
}
/**
@@ -478,7 +478,7 @@ void ConsoleAuction(
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], connection->UserName().c_str());
zoneserver_list.SendChannelMessage(tmpname, 0, 4, 0, Strings::Join(args, " ").c_str());
zoneserver_list.SendChannelMessage(tmpname, 0, ChatChannel_Auction, 0, Strings::Join(args, " ").c_str());
}
/**
+1
View File
@@ -146,6 +146,7 @@ std::vector<Reload> reload_types = {
Reload{.command = "merchants", .opcode = ServerOP_ReloadMerchants, .desc = "Merchants"},
Reload{.command = "npc_emotes", .opcode = ServerOP_ReloadNPCEmotes, .desc = "NPC Emotes"},
Reload{.command = "objects", .opcode = ServerOP_ReloadObjects, .desc = "Objects"},
Reload{.command = "opcodes", .opcode = ServerOP_ReloadOpcodes, .desc = "Opcodes"},
Reload{.command = "perl_export", .opcode = ServerOP_ReloadPerlExportSettings, .desc = "Perl Event Export Settings"},
Reload{.command = "rules", .opcode = ServerOP_ReloadRules, .desc = "Rules"},
Reload{.command = "static", .opcode = ServerOP_ReloadStaticZoneData, .desc = "Static Zone Data"},
+1
View File
@@ -17,6 +17,7 @@ public:
void Disconnect() { if(connection && connection->Handle()) connection->Handle()->Disconnect(); }
void SendMessage(const char *From, const char *Message);
const std::shared_ptr<EQ::Net::ServertalkServerConnection> &GetConnection() const;
inline bool IsConnected() const { return connection->Handle() ? connection->Handle()->IsConnected() : false; }
private:
inline std::string GetIP() const { return (connection && connection->Handle()) ? connection->Handle()->RemoteIP() : 0; }
+17
View File
@@ -300,6 +300,8 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
->SetLogPath(path.GetLogPath())
->LoadLogDatabaseSettings();
LogSys.SetDiscordHandler(&WorldBoot::DiscordWebhookMessageHandler);
if (!ignore_db) {
LogInfo("Checking Database Conversions");
database.CheckDatabaseConversions();
@@ -662,3 +664,18 @@ void WorldBoot::Shutdown()
safe_delete(mutex);
}
void WorldBoot::SendDiscordMessage(int webhook_id, const std::string &message)
{
if (UCSLink.IsConnected()) {
auto pack = new ServerPacket(ServerOP_DiscordWebhookMessage, sizeof(DiscordWebhookMessage_Struct) + 1);
auto *q = (DiscordWebhookMessage_Struct *) pack->pBuffer;
strn0cpy(q->message, message.c_str(), 2000);
q->webhook_id = webhook_id;
UCSLink.SendPacket(pack);
safe_delete(pack);
}
}
+13
View File
@@ -3,6 +3,9 @@
#include <string>
#include "../common/types.h"
#include "../common/discord/discord.h"
extern UCSConnection UCSLink;
class WorldBoot {
public:
@@ -16,6 +19,16 @@ public:
static bool DatabaseLoadRoutines(int argc, char **argv);
static void CheckForPossibleConfigurationIssues();
static void Shutdown();
static void SendDiscordMessage(int webhook_id, const std::string& message);
static void DiscordWebhookMessageHandler(uint16 log_category, int webhook_id, const std::string &message)
{
std::string message_prefix = fmt::format(
"[**{}**] **World** ",
Logs::LogCategoryName[log_category]
);
SendDiscordMessage(webhook_id, message_prefix + Discord::FormatDiscordMessage(log_category, message));
};
};
+1 -1
View File
@@ -311,7 +311,7 @@ void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* con
strcpy(locked, "No");
}
std::vector<char> out;
auto out = fmt::memory_buffer();
if (connection->IsConsole()) {
fmt::format_to(std::back_inserter(out), "World Locked: {}\r\n", locked);
+5
View File
@@ -45,6 +45,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../common/content/world_content_service.h"
#include "../common/repositories/player_event_logs_repository.h"
#include "../common/events/player_event_logs.h"
#include "../common/patches/patches.h"
extern ClientList client_list;
extern GroupLFPList LFPGroupList;
@@ -1296,6 +1297,10 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
QSLink.SendPacket(pack);
break;
}
case ServerOP_ReloadOpcodes: {
ReloadAllPatches();
break;
}
case ServerOP_CZDialogueWindow:
case ServerOP_CZLDoNUpdate:
case ServerOP_CZMarquee:
-4
View File
@@ -32,7 +32,6 @@ SET(zone_sources
embparser.cpp
embparser_api.cpp
embperl.cpp
embxs.cpp
encounter.cpp
entity.cpp
exp.cpp
@@ -77,7 +76,6 @@ SET(zone_sources
lua_spell.cpp
lua_stat_bonuses.cpp
embperl.cpp
embxs.cpp
entity.cpp
exp.cpp
fearpath.cpp
@@ -186,7 +184,6 @@ SET(zone_headers
dynamic_zone.h
embparser.h
embperl.h
embxs.h
encounter.h
entity.h
errmsg.h
@@ -231,7 +228,6 @@ SET(zone_headers
lua_stat_bonuses.h
map.h
masterentity.h
message.h
merc.h
mob.h
mob_movement_manager.h
+11 -10
View File
@@ -1320,7 +1320,7 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
timer_duration = 0;
}
if (!IsCastWhileInvis(rank->spell))
if (!IsCastWhileInvisibleSpell(rank->spell))
CommonBreakInvisible();
if (spells[rank->spell].sneak && (!hidden || (hidden && (Timer::GetCurrentTime() - tmHidden) < 4000))) {
@@ -1333,7 +1333,7 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
target_id = GetPetID();
// extra handling for cast_not_standing spells
if (!IgnoreCastingRestriction(rank->spell)) {
if (!IsCastNotStandingSpell(rank->spell)) {
if (GetAppearance() == eaSitting) // we need to stand!
SetAppearance(eaStanding, false);
@@ -1398,27 +1398,28 @@ int Mob::GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in) {
void Mob::ExpendAlternateAdvancementCharge(uint32 aa_id) {
for (auto &iter : aa_ranks) {
AA::Ability *ability = zone->GetAlternateAdvancementAbility(iter.first);
auto ability = zone->GetAlternateAdvancementAbility(iter.first);
if (ability && aa_id == ability->id) {
if (iter.second.second > 0) {
iter.second.second -= 1;
if (iter.second.second == 0) {
if (IsClient()) {
AA::Rank *r = ability->GetRankByPointsSpent(iter.second.first);
if (r) {
CastToClient()->GetEPP().expended_aa += r->cost;
}
}
if (IsClient()) {
auto c = CastToClient();
auto r = ability->GetRankByPointsSpent(iter.second.first);
if (r) {
c->GetEPP().expended_aa += r->cost;
}
c->RemoveExpendedAA(ability->first_rank_id);
}
aa_ranks.erase(iter.first);
}
if (IsClient()) {
Client *c = CastToClient();
auto c = CastToClient();
c->SaveAA();
c->SendAlternateAdvancementPoints();
}
+3 -15
View File
@@ -21,22 +21,10 @@
#include "masterentity.h"
#include "aa_ability.h"
AA::Rank *AA::Ability::GetMaxRank() {
if(!first)
return nullptr;
Rank *current = first;
while(current->next) {
current = current->next;
}
return current;
}
AA::Rank *AA::Ability::GetRankByPointsSpent(int current_level) {
if(current_level == 0)
return nullptr;
if(!first)
return nullptr;
@@ -65,6 +53,6 @@ int AA::Ability::GetMaxLevel(Mob *who) {
max_level++;
current = current->next;
}
return max_level;
}
}
-1
View File
@@ -37,7 +37,6 @@ public:
Ability() { }
~Ability() { }
Rank *GetMaxRank();
Rank *GetRankByPointsSpent(int current_level);
int GetMaxLevel(Mob *who);
+1 -1
View File
@@ -1161,7 +1161,7 @@ bool Mob::CheckLosFN(glm::vec3 posWatcher, float sizeWatcher, glm::vec3 posTarge
//offensive spell aggro
int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc)
{
if (NoDetrimentalSpellAggro(spell_id))
if (IsNoDetrimentalSpellAggroSpell(spell_id))
return 0;
int32 AggroAmount = 0;
+77 -69
View File
@@ -160,7 +160,7 @@ int Mob::compute_tohit(EQ::skills::SkillType skillinuse)
if (IsNPC())
tohit += CastToNPC()->GetAccuracyRating();
if (IsClient()) {
double reduction = CastToClient()->m_pp.intoxication / 2.0;
double reduction = CastToClient()->GetIntoxication() / 2.0;
if (reduction > 20.0) {
reduction = std::min((110 - reduction) / 100.0, 1.0);
tohit = reduction * static_cast<double>(tohit);
@@ -256,7 +256,7 @@ int Mob::compute_defense()
defense += CastToNPC()->GetAvoidanceRating();
if (IsClient()) {
double reduction = CastToClient()->m_pp.intoxication / 2.0;
double reduction = CastToClient()->GetIntoxication() / 2.0;
if (reduction > 20.0) {
reduction = std::min((110 - reduction) / 100.0, 1.0);
defense = reduction * static_cast<double>(defense);
@@ -1473,7 +1473,7 @@ bool Mob::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
SetTarget(other);
}
LogCombatDetail("Attacking [{}] with hand [{}] [{}]", other ? other->GetName() : "nullptr", Hand, bRiposte ? "this is a riposte" : "");
LogCombatDetail("Attacking [{}] with hand [{}] [{}]", other->GetName(), Hand, bRiposte ? "this is a riposte" : "");
if (
(IsCasting() && GetClass() != BARD && !IsFromSpell)
@@ -2110,14 +2110,16 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
//Check that we can attack before we calc heading and face our target
if (!IsAttackAllowed(other)) {
if (GetOwnerID())
if (GetOwnerID()) {
SayString(NOT_LEGAL_TARGET);
if (other) {
if (other->IsClient())
other->CastToClient()->RemoveXTarget(this, false);
RemoveFromHateList(other);
LogCombat("I am not allowed to attack [{}]", other->GetName());
}
if (other->IsClient()) {
other->CastToClient()->RemoveXTarget(this, false);
}
RemoveFromHateList(other);
LogCombat("I am not allowed to attack [{}]", other->GetName());
return false;
}
@@ -2131,17 +2133,19 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
my_hit.skill = static_cast<EQ::skills::SkillType>(GetPrimSkill());
OffHandAtk(false);
}
if (Hand == EQ::invslot::slotSecondary) {
my_hit.skill = static_cast<EQ::skills::SkillType>(GetSecSkill());
OffHandAtk(true);
}
//figure out what weapon they are using, if any
const EQ::ItemData* weapon = nullptr;
if (Hand == EQ::invslot::slotPrimary && equipment[EQ::invslot::slotPrimary] > 0)
const EQ::ItemData *weapon = nullptr;
if (Hand == EQ::invslot::slotPrimary && equipment[EQ::invslot::slotPrimary] > 0) {
weapon = database.GetItem(equipment[EQ::invslot::slotPrimary]);
else if (equipment[EQ::invslot::slotSecondary])
} else if (equipment[EQ::invslot::slotSecondary]) {
weapon = database.GetItem(equipment[EQ::invslot::slotSecondary]);
}
//We dont factor much from the weapon into the attack.
//Just the skill type so it doesn't look silly using punching animations and stuff while wielding weapons
@@ -2154,34 +2158,34 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
}
switch (weapon->ItemType) {
case EQ::item::ItemType1HSlash:
my_hit.skill = EQ::skills::Skill1HSlashing;
break;
case EQ::item::ItemType2HSlash:
my_hit.skill = EQ::skills::Skill2HSlashing;
break;
case EQ::item::ItemType1HPiercing:
my_hit.skill = EQ::skills::Skill1HPiercing;
break;
case EQ::item::ItemType2HPiercing:
my_hit.skill = EQ::skills::Skill2HPiercing;
break;
case EQ::item::ItemType1HBlunt:
my_hit.skill = EQ::skills::Skill1HBlunt;
break;
case EQ::item::ItemType2HBlunt:
my_hit.skill = EQ::skills::Skill2HBlunt;
break;
case EQ::item::ItemTypeBow:
my_hit.skill = EQ::skills::SkillArchery;
break;
case EQ::item::ItemTypeLargeThrowing:
case EQ::item::ItemTypeSmallThrowing:
my_hit.skill = EQ::skills::SkillThrowing;
break;
default:
my_hit.skill = EQ::skills::SkillHandtoHand;
break;
case EQ::item::ItemType1HSlash:
my_hit.skill = EQ::skills::Skill1HSlashing;
break;
case EQ::item::ItemType2HSlash:
my_hit.skill = EQ::skills::Skill2HSlashing;
break;
case EQ::item::ItemType1HPiercing:
my_hit.skill = EQ::skills::Skill1HPiercing;
break;
case EQ::item::ItemType2HPiercing:
my_hit.skill = EQ::skills::Skill2HPiercing;
break;
case EQ::item::ItemType1HBlunt:
my_hit.skill = EQ::skills::Skill1HBlunt;
break;
case EQ::item::ItemType2HBlunt:
my_hit.skill = EQ::skills::Skill2HBlunt;
break;
case EQ::item::ItemTypeBow:
my_hit.skill = EQ::skills::SkillArchery;
break;
case EQ::item::ItemTypeLargeThrowing:
case EQ::item::ItemTypeSmallThrowing:
my_hit.skill = EQ::skills::SkillThrowing;
break;
default:
my_hit.skill = EQ::skills::SkillHandtoHand;
break;
}
}
@@ -2194,6 +2198,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
if (!mob) {
continue;
}
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(other->GetPosition(), mob->GetPosition());
if ((mob->CheckLosFN(other) || mob->CheckLosFN(this)) && distance <= 70) {
@@ -2910,19 +2915,17 @@ void Mob::AddToHateList(Mob* other, int64 hate /*= 0*/, int64 damage /*= 0*/, bo
Mob* targetmob = GetTarget();
bool on_hatelist = CheckAggro(other);
if (other) {
AddRampage(other);
if (on_hatelist) { // odd reason, if you're not on the hate list, subtlety etc don't apply!
// Spell Casting Subtlety etc
int64 hatemod = 100 + other->spellbonuses.hatemod + other->itembonuses.hatemod + other->aabonuses.hatemod;
AddRampage(other);
if (on_hatelist) { // odd reason, if you're not on the hate list, subtlety etc don't apply!
// Spell Casting Subtlety etc
int64 hatemod = 100 + other->spellbonuses.hatemod + other->itembonuses.hatemod + other->aabonuses.hatemod;
if (hatemod < 1)
hatemod = 1;
hate = ((hate * (hatemod)) / 100);
}
else {
hate += 100; // 100 bonus initial aggro
}
if (hatemod < 1)
hatemod = 1;
hate = ((hate * (hatemod)) / 100);
}
else {
hate += 100; // 100 bonus initial aggro
}
// Pet that is /pet hold on will not add to their hate list if they're not engaged
@@ -2955,7 +2958,7 @@ void Mob::AddToHateList(Mob* other, int64 hate /*= 0*/, int64 damage /*= 0*/, bo
if (GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && other->IsClient())
return;
if (IsValidSpell(spell_id) && NoDetrimentalSpellAggro(spell_id))
if (IsValidSpell(spell_id) && IsNoDetrimentalSpellAggroSpell(spell_id))
return;
if (other == myowner)
@@ -2999,29 +3002,26 @@ void Mob::AddToHateList(Mob* other, int64 hate /*= 0*/, int64 damage /*= 0*/, bo
// if other is a bot, add the bots client to the hate list
if (RuleB(Bots, Enabled)) {
while (other->IsBot()) {
if (other->IsBot()) {
auto other_ = other->CastToBot();
if (!other_ || !other_->GetBotOwner()) {
break;
return;
}
auto owner_ = other_->GetBotOwner()->CastToClient();
if (!owner_ || owner_->IsDead() ||
!owner_->InZone()) { // added isdead and inzone checks to avoid issues in AddAutoXTarget(...) below
break;
return;
}
if (owner_->GetFeigned()) {
AddFeignMemory(owner_);
}
else if (!hate_list.IsEntOnHateList(owner_)) {
hate_list.AddEntToHateList(owner_, 0, 0, false, true);
owner_->AddAutoXTarget(this); // this was being called on dead/out-of-zone clients
}
break;
}
}
@@ -3883,9 +3883,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
damage = ReduceAllDamage(damage);
TryTriggerThreshHold(damage, SE_TriggerMeleeThreshold, attacker);
if (skill_used)
CheckNumHitsRemaining(NumHit::IncomingHitSuccess);
CheckNumHitsRemaining(NumHit::IncomingHitSuccess);
}
else {
int64 origdmg = damage;
@@ -4449,14 +4447,24 @@ void Mob::HealDamage(uint64 amount, Mob* caster, uint16 spell_id)
}
}
else { // normal heals
FilteredMessageString(caster, Chat::NonMelee, FilterSpellDamage,
YOU_HEALED, caster->GetCleanName(), itoa(acthealed));
// Message to caster
if (caster->IsClient()) {
caster->FilteredMessageString(caster, Chat::NonMelee,
FilterSpellDamage, YOU_HEAL, GetCleanName(),
itoa(acthealed));
}
caster->FilteredMessageString(caster, Chat::NonMelee, FilterSpellDamage,
YOU_HEAL, GetCleanName(), itoa(acthealed));
// Message to target
if (IsClient() && caster != this) {
FilteredMessageString(caster, Chat::NonMelee,
FilterSpellDamage, YOU_HEALED, caster->GetCleanName(),
itoa(acthealed));
}
}
}
else if (CastToClient()->GetFilter(FilterHealOverTime) != (FilterShowSelfOnly || FilterHide)) {
} else if (
CastToClient()->GetFilter(FilterHealOverTime) != FilterShowSelfOnly ||
CastToClient()->GetFilter(FilterHealOverTime) != FilterHide
) {
Message(Chat::NonMelee, "You have been healed for %d points of damage.", acthealed);
}
}
+395 -230
View File
@@ -58,16 +58,10 @@ void Mob::CalcBonuses()
void NPC::CalcBonuses()
{
memset(&itembonuses, 0, sizeof(StatBonuses));
if (RuleB(NPC, UseItemBonusesForNonPets)) {
memset(&itembonuses, 0, sizeof(StatBonuses));
if (GetOwner() || RuleB(NPC, UseItemBonusesForNonPets)) {
CalcItemBonuses(&itembonuses);
}
else {
if (GetOwner()) {
memset(&itembonuses, 0, sizeof(StatBonuses));
CalcItemBonuses(&itembonuses);
}
}
// This has to happen last, so we actually take the item bonuses into account.
Mob::CalcBonuses();
@@ -152,18 +146,7 @@ void Mob::CalcItemBonuses(StatBonuses* b) {
int16 i;
for (i = EQ::invslot::BONUS_BEGIN; i <= EQ::invslot::BONUS_SKILL_END; i++) {
const EQ::ItemInstance* inst = nullptr;
if (IsOfClientBotMerc()) {
inst = GetInv().GetItem(i);
} else {
const auto* item = CastToNPC()->GetItem(i);
if (!item) {
continue;
}
inst = database.CreateItem(item->item_id);
}
const EQ::ItemInstance* inst = GetInv().GetItem(i);
if (!inst) {
continue;
}
@@ -268,7 +251,7 @@ void Mob::AddItemBonuses(const EQ::ItemInstance* inst, StatBonuses* b, bool is_a
return;
}
if (!is_tribute && !inst->IsEquipable(GetBaseRace(), GetClass())) {
if (IsClient() && !is_tribute && !inst->IsEquipable(GetBaseRace(), GetClass())) {
if (item->ItemType != EQ::item::ItemTypeFood && item->ItemType != EQ::item::ItemTypeDrink) {
return;
}
@@ -276,14 +259,14 @@ void Mob::AddItemBonuses(const EQ::ItemInstance* inst, StatBonuses* b, bool is_a
const auto current_level = GetLevel();
if (current_level < inst->GetItemRequiredLevel(true)) {
if (IsClient() && current_level < inst->GetItemRequiredLevel(true)) {
return;
}
if (!is_ammo_item) {
const auto recommended_level = is_augment ? recommended_level_override : inst->GetItemRecommendedLevel(true);
if (current_level >= recommended_level) {
if (IsNPC() || current_level >= recommended_level) {
b->HP += item->HP;
b->Mana += item->Mana;
b->Endurance += item->Endur;
@@ -1225,6 +1208,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
newbon->HitChanceEffect[EQ::skills::HIGHEST_SKILL + 1] += base_value;
else
newbon->HitChanceEffect[limit_value] += base_value;
break;
}
case SE_ProcOnKillShot:
@@ -1405,6 +1389,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
break;
}
}
break;
}
case SE_DamageModifier: {
@@ -1651,7 +1636,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
}
case SE_Illusion:
newbon->Illusion = true;
newbon->Illusion = rank.spell;
break;
case SE_IllusionPersistence:
@@ -2115,10 +2100,17 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
//Use AISpellEffects
else {
spell_effect_id = effect_id;
effect_value = se_base;
limit_value = se_limit;
max_value = se_max;
i = (EFFECT_COUNT - 1); // AISpellEffects do a single pass
effect_value = se_base;
limit_value = se_limit;
max_value = se_max;
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
//Non-Focused Effect to modify incoming spell damage by resist type.
if (spell_effect_id == SE_FcSpellVulnerability) {
ModVulnerability(limit_value, effect_value);
}
break;
}
switch (spell_effect_id)
@@ -2169,7 +2161,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
}
else if ((effect_value - 100) < 0) { // Slow
int real_slow_value = (100 - effect_value) * -1;
real_slow_value -= ((real_slow_value * GetSlowMitigation()/100));
real_slow_value -= (real_slow_value * GetSlowMitigation()/100);
if (real_slow_value < new_bonus->haste)
new_bonus->haste = real_slow_value;
}
@@ -2186,7 +2178,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
}
else if ((effect_value - 100) < 0) { // Slow
int real_slow_value = (100 - effect_value) * -1;
real_slow_value -= ((real_slow_value * GetSlowMitigation()/100));
real_slow_value -= (real_slow_value * GetSlowMitigation()/100);
if (real_slow_value < new_bonus->hastetype2)
new_bonus->hastetype2 = real_slow_value;
}
@@ -2196,7 +2188,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
case SE_AttackSpeed3:
{
if (effect_value < 0){ //Slow
effect_value -= ((effect_value * GetSlowMitigation()/100));
effect_value -= (effect_value * GetSlowMitigation()/100);
if (effect_value < new_bonus->hastetype3)
new_bonus->hastetype3 = effect_value;
}
@@ -2220,7 +2212,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
effect_value = effect_value * -1;
if (effect_value > 0 && effect_value > new_bonus->inhibitmelee) {
effect_value -= ((effect_value * GetSlowMitigation()/100));
effect_value -= (effect_value * GetSlowMitigation()/100);
if (effect_value > new_bonus->inhibitmelee)
new_bonus->inhibitmelee = effect_value;
}
@@ -3201,8 +3193,13 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
case SE_NegateAttacks:
{
if (!new_bonus->NegateAttacks[SBIndex::NEGATE_ATK_EXISTS] ||
((new_bonus->NegateAttacks[SBIndex::NEGATE_ATK_EXISTS] && new_bonus->NegateAttacks[SBIndex::NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT]) && (new_bonus->NegateAttacks[SBIndex::NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT] < max_value))){
if (
!new_bonus->NegateAttacks[SBIndex::NEGATE_ATK_EXISTS] ||
(
new_bonus->NegateAttacks[SBIndex::NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT] &&
new_bonus->NegateAttacks[SBIndex::NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT] < max_value
)
) {
new_bonus->NegateAttacks[SBIndex::NEGATE_ATK_EXISTS] = 1;
new_bonus->NegateAttacks[SBIndex::NEGATE_ATK_BUFFSLOT] = buffslot;
new_bonus->NegateAttacks[SBIndex::NEGATE_ATK_MAX_DMG_ABSORB_PER_HIT] = max_value;
@@ -3520,6 +3517,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
case SE_DoubleRiposte:
{
new_bonus->DoubleRiposte += effect_value;
break;
}
case SE_GiveDoubleRiposte:
@@ -3805,6 +3803,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
break;
}
}
break;
}
case SE_PC_Pet_Rampage: {
@@ -4063,15 +4062,6 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
case SE_TrapCircumvention:
new_bonus->TrapCircumvention += effect_value;
break;
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
if (IsAISpellEffect) {
//Non-Focused Effect to modify incoming spell damage by resist type.
case SE_FcSpellVulnerability:
ModVulnerability(limit_value, effect_value);
break;
}
}
}
}
@@ -4317,11 +4307,11 @@ uint8 Mob::IsFocusEffect(uint16 spell_id,int effect_index, bool AA,uint32 aa_eff
case SE_SpellResistReduction:
return focusResistRate;
case SE_Fc_ResistIncoming:
focusFcResistIncoming;
return focusFcResistIncoming;
case SE_Fc_Amplify_Mod:
focusFcAmplifyMod;
return focusFcAmplifyMod;
case SE_Fc_Amplify_Amt:
focusFcAmplifyAmt;
return focusFcAmplifyAmt;
case SE_SpellHateMod:
return focusSpellHateMod;
case SE_ReduceReuseTimer:
@@ -4488,12 +4478,9 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
case SE_AttackSpeed3:
{
if (effect_value > 0) {
if (negate_spellbonus) { spellbonuses.hastetype3 = effect_value; }
if (negate_aabonus) { aabonuses.hastetype3 = effect_value; }
if (negate_itembonus) { itembonuses.hastetype3 = effect_value; }
}
if (negate_spellbonus) { spellbonuses.hastetype3 = effect_value; }
if (negate_aabonus) { aabonuses.hastetype3 = effect_value; }
if (negate_itembonus) { itembonuses.hastetype3 = effect_value; }
break;
}
@@ -4585,29 +4572,36 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
case SE_AllStats:
{
if (negate_spellbonus) { spellbonuses.STR = effect_value; }
if (negate_spellbonus) { spellbonuses.DEX = effect_value; }
if (negate_spellbonus) { spellbonuses.AGI = effect_value; }
if (negate_spellbonus) { spellbonuses.STA = effect_value; }
if (negate_spellbonus) { spellbonuses.INT = effect_value; }
if (negate_spellbonus) { spellbonuses.WIS = effect_value; }
if (negate_spellbonus) { spellbonuses.CHA = effect_value; }
if (negate_spellbonus) {
spellbonuses.STR = effect_value;
spellbonuses.DEX = effect_value;
spellbonuses.AGI = effect_value;
spellbonuses.STA = effect_value;
spellbonuses.INT = effect_value;
spellbonuses.WIS = effect_value;
spellbonuses.CHA = effect_value;
}
if (negate_itembonus) { itembonuses.STR = effect_value; }
if (negate_itembonus) { itembonuses.DEX = effect_value; }
if (negate_itembonus) { itembonuses.AGI = effect_value; }
if (negate_itembonus) { itembonuses.STA = effect_value; }
if (negate_itembonus) { itembonuses.INT = effect_value; }
if (negate_itembonus) { itembonuses.WIS = effect_value; }
if (negate_itembonus) { itembonuses.CHA = effect_value; }
if (negate_itembonus) {
itembonuses.STR = effect_value;
itembonuses.DEX = effect_value;
itembonuses.AGI = effect_value;
itembonuses.STA = effect_value;
itembonuses.INT = effect_value;
itembonuses.WIS = effect_value;
itembonuses.CHA = effect_value;
}
if (negate_aabonus) {
aabonuses.STR = effect_value;
aabonuses.DEX = effect_value;
aabonuses.AGI = effect_value;
aabonuses.STA = effect_value;
aabonuses.INT = effect_value;
aabonuses.WIS = effect_value;
aabonuses.CHA = effect_value;
}
if (negate_aabonus) { aabonuses.STR = effect_value; }
if (negate_aabonus) { aabonuses.DEX = effect_value; }
if (negate_aabonus) { aabonuses.AGI = effect_value; }
if (negate_aabonus) { aabonuses.STA = effect_value; }
if (negate_aabonus) { aabonuses.INT = effect_value; }
if (negate_aabonus) { aabonuses.WIS = effect_value; }
if (negate_aabonus) { aabonuses.CHA = effect_value; }
break;
}
@@ -4643,23 +4637,30 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
case SE_ResistAll:
{
if (negate_spellbonus) { spellbonuses.MR = effect_value; }
if (negate_spellbonus) { spellbonuses.DR = effect_value; }
if (negate_spellbonus) { spellbonuses.PR = effect_value; }
if (negate_spellbonus) { spellbonuses.CR = effect_value; }
if (negate_spellbonus) { spellbonuses.FR = effect_value; }
if (negate_spellbonus) {
spellbonuses.MR = effect_value;
spellbonuses.DR = effect_value;
spellbonuses.PR = effect_value;
spellbonuses.CR = effect_value;
spellbonuses.FR = effect_value;
}
if (negate_aabonus) { aabonuses.MR = effect_value; }
if (negate_aabonus) { aabonuses.DR = effect_value; }
if (negate_aabonus) { aabonuses.PR = effect_value; }
if (negate_aabonus) { aabonuses.CR = effect_value; }
if (negate_aabonus) { aabonuses.FR = effect_value; }
if (negate_aabonus) {
aabonuses.MR = effect_value;
aabonuses.DR = effect_value;
aabonuses.PR = effect_value;
aabonuses.CR = effect_value;
aabonuses.FR = effect_value;
}
if (negate_itembonus) {
itembonuses.MR = effect_value;
itembonuses.DR = effect_value;
itembonuses.PR = effect_value;
itembonuses.CR = effect_value;
itembonuses.FR = effect_value;
}
if (negate_itembonus) { itembonuses.MR = effect_value; }
if (negate_itembonus) { itembonuses.DR = effect_value; }
if (negate_itembonus) { itembonuses.PR = effect_value; }
if (negate_itembonus) { itembonuses.CR = effect_value; }
if (negate_itembonus) { itembonuses.FR = effect_value; }
break;
}
@@ -4796,23 +4797,29 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
case SE_AllInstrumentMod:
{
if (negate_spellbonus) { spellbonuses.singingMod = effect_value; }
if (negate_spellbonus) { spellbonuses.brassMod = effect_value; }
if (negate_spellbonus) { spellbonuses.percussionMod = effect_value; }
if (negate_spellbonus) { spellbonuses.windMod = effect_value; }
if (negate_spellbonus) { spellbonuses.stringedMod = effect_value; }
if (negate_spellbonus) {
spellbonuses.singingMod = effect_value;
spellbonuses.brassMod = effect_value;
spellbonuses.percussionMod = effect_value;
spellbonuses.windMod = effect_value;
spellbonuses.stringedMod = effect_value;
}
if (negate_itembonus) { itembonuses.singingMod = effect_value; }
if (negate_itembonus) { itembonuses.brassMod = effect_value; }
if (negate_itembonus) { itembonuses.percussionMod = effect_value; }
if (negate_itembonus) { itembonuses.windMod = effect_value; }
if (negate_itembonus) { itembonuses.stringedMod = effect_value; }
if (negate_itembonus) {
itembonuses.singingMod = effect_value;
itembonuses.brassMod = effect_value;
itembonuses.percussionMod = effect_value;
itembonuses.windMod = effect_value;
itembonuses.stringedMod = effect_value;
}
if (negate_aabonus) { aabonuses.singingMod = effect_value; }
if (negate_aabonus) { aabonuses.brassMod = effect_value; }
if (negate_aabonus) { aabonuses.percussionMod = effect_value; }
if (negate_aabonus) { aabonuses.windMod = effect_value; }
if (negate_aabonus) { aabonuses.stringedMod = effect_value; }
if (negate_aabonus) {
aabonuses.singingMod = effect_value;
aabonuses.brassMod = effect_value;
aabonuses.percussionMod = effect_value;
aabonuses.windMod = effect_value;
aabonuses.stringedMod = effect_value;
}
break;
}
@@ -4823,8 +4830,11 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
break;
case SE_ResistFearChance:
if (negate_spellbonus) { spellbonuses.Fearless = false; }
if (negate_spellbonus) { spellbonuses.ResistFearChance = effect_value; }
if (negate_spellbonus) {
spellbonuses.Fearless = false;
spellbonuses.ResistFearChance = effect_value;
}
if (negate_aabonus) { aabonuses.ResistFearChance = effect_value; }
if (negate_itembonus) { itembonuses.ResistFearChance = effect_value; }
break;
@@ -5001,12 +5011,21 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
break;
case SE_CriticalSpellChance:
if (negate_spellbonus) { spellbonuses.CriticalSpellChance = effect_value; }
if (negate_spellbonus) { spellbonuses.SpellCritDmgIncrease = effect_value; }
if (negate_aabonus) { aabonuses.CriticalSpellChance = effect_value; }
if (negate_aabonus) { aabonuses.SpellCritDmgIncrease = effect_value; }
if (negate_itembonus) { itembonuses.CriticalSpellChance = effect_value; }
if (negate_itembonus) { itembonuses.SpellCritDmgIncrease = effect_value; }
if (negate_spellbonus) {
spellbonuses.CriticalSpellChance = effect_value;
spellbonuses.SpellCritDmgIncrease = effect_value;
}
if (negate_aabonus) {
aabonuses.CriticalSpellChance = effect_value;
aabonuses.SpellCritDmgIncrease = effect_value;
}
if (negate_itembonus) {
itembonuses.CriticalSpellChance = effect_value;
itembonuses.SpellCritDmgIncrease = effect_value;
}
break;
case SE_SpellCritDmgIncrease:
@@ -5168,35 +5187,53 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
}
case SE_NegateAttacks:
if (negate_spellbonus) { spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_EXISTS] = effect_value; }
if (negate_spellbonus) { spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_BUFFSLOT] = effect_value; }
if (negate_spellbonus) {
spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_EXISTS] = effect_value;
spellbonuses.NegateAttacks[SBIndex::NEGATE_ATK_BUFFSLOT] = effect_value;
}
break;
case SE_MitigateMeleeDamage:
if (negate_spellbonus) { spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_PERCENT] = effect_value; }
if (negate_spellbonus) { spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_BUFFSLOT] = -1; }
if (negate_spellbonus) {
spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_PERCENT] = effect_value;
spellbonuses.MitigateMeleeRune[SBIndex::MITIGATION_RUNE_BUFFSLOT] = -1;
}
break;
case SE_MeleeThresholdGuard:
if (negate_spellbonus) { spellbonuses.MeleeThresholdGuard[SBIndex::THRESHOLDGUARD_MITIGATION_PERCENT] = effect_value; }
if (negate_spellbonus) { spellbonuses.MeleeThresholdGuard[SBIndex::THRESHOLDGUARD_BUFFSLOT] = -1; }
if (negate_spellbonus) { spellbonuses.MeleeThresholdGuard[SBIndex::THRESHOLDGUARD_BUFFSLOT] = effect_value; }
if (negate_spellbonus) {
spellbonuses.MeleeThresholdGuard[SBIndex::THRESHOLDGUARD_MITIGATION_PERCENT] = effect_value;
spellbonuses.MeleeThresholdGuard[SBIndex::THRESHOLDGUARD_BUFFSLOT] = -1;
spellbonuses.MeleeThresholdGuard[SBIndex::THRESHOLDGUARD_BUFFSLOT] = effect_value;
}
break;
case SE_SpellThresholdGuard:
if (negate_spellbonus) { spellbonuses.SpellThresholdGuard[SBIndex::THRESHOLDGUARD_MITIGATION_PERCENT] = effect_value; }
if (negate_spellbonus) { spellbonuses.SpellThresholdGuard[SBIndex::THRESHOLDGUARD_BUFFSLOT] = -1; }
if (negate_spellbonus) { spellbonuses.SpellThresholdGuard[SBIndex::THRESHOLDGUARD_BUFFSLOT] = effect_value; }
if (negate_spellbonus) {
spellbonuses.SpellThresholdGuard[SBIndex::THRESHOLDGUARD_MITIGATION_PERCENT] = effect_value;
spellbonuses.SpellThresholdGuard[SBIndex::THRESHOLDGUARD_BUFFSLOT] = -1;
spellbonuses.SpellThresholdGuard[SBIndex::THRESHOLDGUARD_BUFFSLOT] = effect_value;
}
break;
case SE_MitigateSpellDamage:
if (negate_spellbonus) { spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_PERCENT] = effect_value; }
if (negate_spellbonus) { spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_BUFFSLOT] = -1; }
if (negate_spellbonus) {
spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_PERCENT] = effect_value;
spellbonuses.MitigateSpellRune[SBIndex::MITIGATION_RUNE_BUFFSLOT] = -1;
}
break;
case SE_MitigateDotDamage:
if (negate_spellbonus) { spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_PERCENT] = effect_value; }
if (negate_spellbonus) { spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_BUFFSLOT] = -1; }
if (negate_spellbonus) {
spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_PERCENT] = effect_value;
spellbonuses.MitigateDotRune[SBIndex::MITIGATION_RUNE_BUFFSLOT] = -1;
}
break;
case SE_ManaAbsorbPercentDamage:
@@ -5204,8 +5241,11 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
break;
case SE_Endurance_Absorb_Pct_Damage:
if (negate_spellbonus) { spellbonuses.EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_MITIGIATION] = effect_value; }
if (negate_spellbonus) { spellbonuses.EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_DRAIN_PER_HP] = effect_value; }
if (negate_spellbonus) {
spellbonuses.EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_MITIGIATION] = effect_value;
spellbonuses.EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_DRAIN_PER_HP] = effect_value;
}
break;
case SE_ShieldBlock:
@@ -5316,11 +5356,6 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
break;
case SE_StrikeThrough:
if (negate_spellbonus) { spellbonuses.StrikeThrough = effect_value; }
if (negate_aabonus) { aabonuses.StrikeThrough = effect_value; }
if (negate_itembonus) { itembonuses.StrikeThrough = effect_value; }
break;
case SE_StrikeThrough2:
if (negate_spellbonus) { spellbonuses.StrikeThrough = effect_value; }
if (negate_aabonus) { aabonuses.StrikeThrough = effect_value; }
@@ -5433,8 +5468,10 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
{
for (int e = 0; e < MAX_RESISTABLE_EFFECTS * 2; e += 2)
{
if (negate_spellbonus) { spellbonuses.SEResist[e] = effect_value; }
if (negate_spellbonus) { spellbonuses.SEResist[e + 1] = effect_value; }
if (negate_spellbonus) {
spellbonuses.SEResist[e] = effect_value;
spellbonuses.SEResist[e + 1] = effect_value;
}
}
break;
}
@@ -5458,12 +5495,21 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
break;
case SE_SlayUndead:
if (negate_spellbonus) { spellbonuses.SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] = effect_value; }
if (negate_spellbonus) { spellbonuses.SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = effect_value; }
if (negate_itembonus) { itembonuses.SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] = effect_value; }
if (negate_itembonus) { itembonuses.SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = effect_value; }
if (negate_aabonus) { aabonuses.SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] = effect_value; }
if (negate_aabonus) { aabonuses.SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = effect_value; }
if (negate_spellbonus) {
spellbonuses.SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] = effect_value;
spellbonuses.SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = effect_value;
}
if (negate_itembonus) {
itembonuses.SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] = effect_value;
itembonuses.SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = effect_value;
}
if (negate_aabonus) {
aabonuses.SlayUndead[SBIndex::SLAYUNDEAD_RATE_MOD] = effect_value;
aabonuses.SlayUndead[SBIndex::SLAYUNDEAD_DMG_MOD] = effect_value;
}
break;
case SE_DoubleRangedAttack:
@@ -5513,9 +5559,12 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
break;
case SE_ImprovedTaunt:
if (negate_spellbonus) { spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_MAX_LVL] = effect_value; }
if (negate_spellbonus) { spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_AGGRO_MOD] = effect_value; }
if (negate_spellbonus) { spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_BUFFSLOT] = -1; }
if (negate_spellbonus) {
spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_MAX_LVL] = effect_value;
spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_AGGRO_MOD] = effect_value;
spellbonuses.ImprovedTaunt[SBIndex::IMPROVED_TAUNT_BUFFSLOT] = -1;
}
break;
case SE_FrenziedDevastation:
@@ -5525,18 +5574,27 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
break;
case SE_Root:
if (negate_spellbonus) { spellbonuses.Root[SBIndex::ROOT_EXISTS] = effect_value; }
if (negate_spellbonus) { spellbonuses.Root[SBIndex::ROOT_BUFFSLOT] = -1; }
if (negate_spellbonus) {
spellbonuses.Root[SBIndex::ROOT_EXISTS] = effect_value;
spellbonuses.Root[SBIndex::ROOT_BUFFSLOT] = -1;
}
break;
case SE_Rune:
if (negate_spellbonus) { spellbonuses.MeleeRune[SBIndex::RUNE_AMOUNT] = effect_value; }
if (negate_spellbonus) { spellbonuses.MeleeRune[SBIndex::RUNE_BUFFSLOT] = -1; }
if (negate_spellbonus) {
spellbonuses.MeleeRune[SBIndex::RUNE_AMOUNT] = effect_value;
spellbonuses.MeleeRune[SBIndex::RUNE_BUFFSLOT] = -1;
}
break;
case SE_AbsorbMagicAtt:
if (negate_spellbonus) { spellbonuses.AbsorbMagicAtt[SBIndex::RUNE_AMOUNT] = effect_value; }
if (negate_spellbonus) { spellbonuses.AbsorbMagicAtt[SBIndex::RUNE_BUFFSLOT] = -1; }
if (negate_spellbonus) {
spellbonuses.AbsorbMagicAtt[SBIndex::RUNE_AMOUNT] = effect_value;
spellbonuses.AbsorbMagicAtt[SBIndex::RUNE_BUFFSLOT] = -1;
}
break;
case SE_Berserk:
@@ -5564,57 +5622,111 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
break;
case SE_HeadShot:
if (negate_spellbonus) { spellbonuses.HeadShot[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value; }
if (negate_aabonus) { aabonuses.HeadShot[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value; }
if (negate_itembonus) { itembonuses.HeadShot[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value; }
if (negate_spellbonus) { spellbonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] = effect_value; }
if (negate_aabonus) { aabonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] = effect_value; }
if (negate_itembonus) { itembonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] = effect_value; }
if (negate_spellbonus) {
spellbonuses.HeadShot[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value;
spellbonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] = effect_value;
}
if (negate_aabonus) {
aabonuses.HeadShot[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value;
aabonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] = effect_value;
}
if (negate_itembonus) {
itembonuses.HeadShot[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value;
itembonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] = effect_value;
}
break;
case SE_HeadShotLevel:
if (negate_spellbonus) { spellbonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value; }
if (negate_aabonus) { aabonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value; }
if (negate_itembonus) { itembonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value; }
if (negate_spellbonus) { spellbonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value; }
if (negate_aabonus) { aabonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value; }
if (negate_itembonus) { itembonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value; }
if (negate_spellbonus) {
spellbonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value;
spellbonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value;
}
if (negate_aabonus) {
aabonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value;
aabonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value;
}
if (negate_itembonus) {
itembonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value;
itembonuses.HSLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value;
}
break;
case SE_Assassinate:
if (negate_spellbonus) { spellbonuses.Assassinate[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value; }
if (negate_aabonus) { aabonuses.Assassinate[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value; }
if (negate_itembonus) { itembonuses.Assassinate[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value; }
if (negate_spellbonus) { spellbonuses.Assassinate[SBIndex::FINISHING_EFFECT_DMG] = effect_value; }
if (negate_aabonus) { aabonuses.Assassinate[SBIndex::FINISHING_EFFECT_DMG] = effect_value; }
if (negate_itembonus) { itembonuses.Assassinate[SBIndex::FINISHING_EFFECT_DMG] = effect_value; }
if (negate_spellbonus) {
spellbonuses.Assassinate[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value;
spellbonuses.Assassinate[SBIndex::FINISHING_EFFECT_DMG] = effect_value;
}
if (negate_aabonus) {
aabonuses.Assassinate[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value;
aabonuses.Assassinate[SBIndex::FINISHING_EFFECT_DMG] = effect_value;
}
if (negate_itembonus) {
itembonuses.Assassinate[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value;
itembonuses.Assassinate[SBIndex::FINISHING_EFFECT_DMG] = effect_value;
}
break;
case SE_AssassinateLevel:
if (negate_spellbonus) { spellbonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value; }
if (negate_aabonus) { aabonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value; }
if (negate_itembonus) { itembonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value; }
if (negate_spellbonus) { spellbonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value; }
if (negate_aabonus) { aabonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value; }
if (negate_itembonus) { itembonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value; }
if (negate_spellbonus) {
spellbonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value;
spellbonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value;
}
if (negate_aabonus) {
aabonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value;
aabonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value;
}
if (negate_itembonus) {
itembonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value;
itembonuses.AssassinateLevel[SBIndex::FINISHING_EFFECT_LEVEL_CHANCE_BONUS] = effect_value;
}
break;
case SE_FinishingBlow:
if (negate_spellbonus) { spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value; }
if (negate_aabonus) { aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value; }
if (negate_itembonus) { itembonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value; }
if (negate_spellbonus) { spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] = effect_value; }
if (negate_aabonus) { aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] = effect_value; }
if (negate_itembonus) { itembonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] = effect_value; }
if (negate_spellbonus) {
spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value;
spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] = effect_value;
}
if (negate_aabonus) {
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value;
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] = effect_value;
}
if (negate_itembonus) {
itembonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] = effect_value;
itembonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] = effect_value;
}
break;
case SE_FinishingBlowLvl:
if (negate_spellbonus) { spellbonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value; }
if (negate_aabonus) { aabonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value; }
if (negate_itembonus) { itembonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value; }
if (negate_spellbonus) { spellbonuses.FinishingBlowLvl[SBIndex::FINISHING_BLOW_LEVEL_HP_RATIO] = effect_value; }
if (negate_aabonus) { aabonuses.FinishingBlowLvl[SBIndex::FINISHING_BLOW_LEVEL_HP_RATIO] = effect_value; }
if (negate_itembonus) { itembonuses.FinishingBlowLvl[SBIndex::FINISHING_BLOW_LEVEL_HP_RATIO] = effect_value; }
if (negate_spellbonus) {
spellbonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value;
spellbonuses.FinishingBlowLvl[SBIndex::FINISHING_BLOW_LEVEL_HP_RATIO] = effect_value;
}
if (negate_aabonus) {
aabonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value;
aabonuses.FinishingBlowLvl[SBIndex::FINISHING_BLOW_LEVEL_HP_RATIO] = effect_value;
}
if (negate_itembonus) {
itembonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX] = effect_value;
itembonuses.FinishingBlowLvl[SBIndex::FINISHING_BLOW_LEVEL_HP_RATIO] = effect_value;
}
break;
case SE_Sanctuary:
@@ -5653,41 +5765,76 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
break;
case SE_Melee_Damage_Position_Mod:
if (negate_spellbonus) { spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK] = effect_value; }
if (negate_aabonus) { aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK] = effect_value; }
if (negate_itembonus) { itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK] = effect_value; }
if (negate_spellbonus) { spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT] = effect_value; }
if (negate_aabonus) { aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT] = effect_value; }
if (negate_itembonus) { itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT] = effect_value; }
if (negate_spellbonus) {
spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
spellbonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
}
if (negate_aabonus) {
aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
aabonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
}
if (negate_itembonus) {
itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
itembonuses.Melee_Damage_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
}
break;
case SE_Damage_Taken_Position_Mod:
if (negate_spellbonus) { spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK] = effect_value; }
if (negate_aabonus) { aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK] = effect_value; }
if (negate_itembonus) { itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK] = effect_value; }
if (negate_spellbonus) { spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT] = effect_value; }
if (negate_aabonus) { aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT] = effect_value; }
if (negate_itembonus) { itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT] = effect_value; }
if (negate_spellbonus) {
spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
spellbonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
}
if (negate_aabonus) {
aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
aabonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
}
if (negate_itembonus) {
itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_BACK] = effect_value;
itembonuses.Damage_Taken_Position_Mod[SBIndex::POSITION_FRONT] = effect_value;
}
break;
case SE_Melee_Damage_Position_Amt:
if (negate_spellbonus) { spellbonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK] = effect_value; }
if (negate_aabonus) { aabonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK] = effect_value; }
if (negate_itembonus) { itembonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK] = effect_value; }
if (negate_spellbonus) { spellbonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT] = effect_value; }
if (negate_aabonus) { aabonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT] = effect_value; }
if (negate_itembonus) { itembonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT] = effect_value; }
if (negate_spellbonus) {
spellbonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
spellbonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
}
if (negate_aabonus) {
aabonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
aabonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
}
if (negate_itembonus) {
itembonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
itembonuses.Melee_Damage_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
}
break;
case SE_Damage_Taken_Position_Amt:
if (negate_spellbonus) { spellbonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK] = effect_value; }
if (negate_aabonus) { aabonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK] = effect_value; }
if (negate_itembonus) { itembonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK] = effect_value; }
if (negate_spellbonus) { spellbonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT] = effect_value; }
if (negate_aabonus) { aabonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT] = effect_value; }
if (negate_itembonus) { itembonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT] = effect_value; }
break;
if (negate_spellbonus) {
spellbonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
spellbonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
}
if (negate_aabonus) {
aabonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
aabonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
}
if (negate_itembonus) {
itembonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_BACK] = effect_value;
itembonuses.Damage_Taken_Position_Amt[SBIndex::POSITION_FRONT] = effect_value;
}
break;
case SE_DS_Mitigation_Amount:
if (negate_spellbonus) { spellbonuses.DS_Mitigation_Amount = effect_value; }
@@ -5714,21 +5861,39 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
break;
case SE_PC_Pet_Rampage:
if (negate_spellbonus) { spellbonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value; }
if (negate_itembonus) { itembonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value; }
if (negate_aabonus) { aabonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value; }
if (negate_spellbonus) { spellbonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value; }
if (negate_itembonus) { itembonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value; }
if (negate_aabonus) { aabonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value; }
if (negate_spellbonus) {
spellbonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value;
spellbonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value;
}
if (negate_itembonus) {
itembonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value;
itembonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value;
}
if (negate_aabonus) {
aabonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value;
aabonuses.PC_Pet_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value;
}
break;
case SE_PC_Pet_AE_Rampage:
if (negate_spellbonus) { spellbonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value; }
if (negate_itembonus) { itembonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value; }
if (negate_aabonus) { aabonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value; }
if (negate_spellbonus) { spellbonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value; }
if (negate_itembonus) { itembonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value; }
if (negate_aabonus) { aabonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value; }
if (negate_spellbonus) {
spellbonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value;
spellbonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value;
}
if (negate_itembonus) {
itembonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value;
itembonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value;
}
if (negate_aabonus) {
aabonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_CHANCE] = effect_value;
aabonuses.PC_Pet_AE_Rampage[SBIndex::PET_RAMPAGE_DMG_MOD] = effect_value;
}
break;
@@ -5783,26 +5948,26 @@ void Mob::CalcHeroicBonuses(StatBonuses* newbon)
void Mob::SetHeroicWisBonuses(StatBonuses* n)
{
n->heroic_max_mana += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * RuleR(Character, HeroicWisdomMultiplier) * 10 : 0;
n->heroic_mana_regen += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * RuleR(Character, HeroicWisdomMultiplier) / 25 : 0;
n->heroic_max_mana += IsHeroicWISCasterClass(GetClass()) ? GetHeroicWIS() * RuleR(Character, HeroicWisdomMultiplier) * 10 : 0;
n->heroic_mana_regen += IsHeroicWISCasterClass(GetClass()) ? GetHeroicWIS() * RuleR(Character, HeroicWisdomMultiplier) / 25 : 0;
n->HealAmt += GetHeroicWIS() * RuleR(Character, HeroicWisdomIncreaseHealAmtMultiplier);
if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) {
n->heroic_max_mana += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::WisMaxMana) * 10 : 0;
n->heroic_mana_regen += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::WisManaRegen) / 25 : 0;
n->heroic_max_mana += IsHeroicWISCasterClass(GetClass()) ? GetHeroicWIS() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::WisMaxMana) * 10 : 0;
n->heroic_mana_regen += IsHeroicWISCasterClass(GetClass()) ? GetHeroicWIS() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::WisManaRegen) / 25 : 0;
n->HealAmt += GetHeroicWIS() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::WisHealAmt);
}
}
void Mob::SetHeroicIntBonuses(StatBonuses* n)
{
n->heroic_max_mana += IsINTCasterClass(GetClass()) ? GetHeroicINT() * RuleR(Character, HeroicIntelligenceMultiplier) * 10 : 0;
n->heroic_mana_regen += IsINTCasterClass(GetClass()) ? GetHeroicINT() * RuleR(Character, HeroicIntelligenceMultiplier) / 25 : 0;
n->heroic_max_mana += IsHeroicINTCasterClass(GetClass()) ? GetHeroicINT() * RuleR(Character, HeroicIntelligenceMultiplier) * 10 : 0;
n->heroic_mana_regen += IsHeroicINTCasterClass(GetClass()) ? GetHeroicINT() * RuleR(Character, HeroicIntelligenceMultiplier) / 25 : 0;
n->SpellDmg += GetHeroicINT() * RuleR(Character, HeroicIntelligenceIncreaseSpellDmgMultiplier);
if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) {
n->heroic_max_mana += IsINTCasterClass(GetClass()) ? GetHeroicINT() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::IntMaxMana) * 10 : 0;
n->heroic_mana_regen += IsINTCasterClass(GetClass()) ? GetHeroicINT() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::IntManaRegen) / 25 : 0;
n->heroic_max_mana += IsHeroicINTCasterClass(GetClass()) ? GetHeroicINT() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::IntMaxMana) * 10 : 0;
n->heroic_mana_regen += IsHeroicINTCasterClass(GetClass()) ? GetHeroicINT() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::IntManaRegen) / 25 : 0;
n->SpellDmg += GetHeroicINT() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::IntSpellDmg);
}
}
+40 -59
View File
@@ -259,7 +259,7 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
const SPDat_Spell_Struct& spell = spells[buffs[j1].spellid];
if (int NimbusEffect = GetNimbusEffect(buffs[j1].spellid); NimbusEffect && !IsNimbusEffectActive(NimbusEffect)) {
if (int NimbusEffect = GetSpellNimbusEffect(buffs[j1].spellid); NimbusEffect && !IsNimbusEffectActive(NimbusEffect)) {
SendSpellEffect(NimbusEffect, 500, 0, 1, 3000, true);
}
@@ -422,12 +422,6 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
}
cur_end = max_end;
// Safety Check to confirm we have a valid raid
if (HasRaid() && !GetRaid()->IsRaidMember(GetBotOwner()->CastToClient())) {
Bot::RemoveBotFromRaid(this);
}
}
Bot::~Bot() {
@@ -1501,7 +1495,7 @@ bool Bot::LoadPet()
}
MakePet(pet_spell_id, spells[pet_spell_id].teleport_zone, pet_name.c_str());
if (!GetPet() || !GetPet()->IsNPC()) {
if (!GetPet()->IsNPC()) {
DeletePet();
return false;
}
@@ -2413,6 +2407,10 @@ bool Bot::TrySecondaryWeaponAttacks(Mob* tar, const EQ::ItemInstance* s_item) {
s_itemdata = s_item->GetItem();
}
if (!s_itemdata) {
return false;
}
bool use_fist = true;
if (s_itemdata) {
use_fist = false;
@@ -2432,10 +2430,10 @@ bool Bot::TrySecondaryWeaponAttacks(Mob* tar, const EQ::ItemInstance* s_item) {
if (random < DualWieldProbability) { // Max 78% for DW chance
Attack(tar, EQ::invslot::slotSecondary); // Single attack with offhand
if (!GetTarget() || GetAppearance() == eaDead) { return false; }
if (GetAppearance() == eaDead) { return false; }
TryCombatProcs(s_item, tar, EQ::invslot::slotSecondary);
if (!GetTarget() || GetAppearance() == eaDead) { return false; }
if (GetAppearance() == eaDead) { return false; }
if (CanThisClassDoubleAttack() && CheckBotDoubleAttack() && tar->GetHP() > -10) {
Attack(tar, EQ::invslot::slotSecondary); // Single attack with offhand
}
@@ -2453,33 +2451,33 @@ bool Bot::TryPrimaryWeaponAttacks(Mob* tar, const EQ::ItemInstance* p_item) {
Attack(tar, EQ::invslot::slotPrimary);
if (!GetTarget() || GetAppearance() == eaDead) { return false; }
if (GetAppearance() == eaDead) { return false; }
TriggerDefensiveProcs(tar, EQ::invslot::slotPrimary, false);
if (!GetTarget() || GetAppearance() == eaDead) { return false; }
if (GetAppearance() == eaDead) { return false; }
TryCombatProcs(p_item, tar, EQ::invslot::slotPrimary);
if (!GetTarget() || GetAppearance() == eaDead) { return false; }
if (GetAppearance() == eaDead) { return false; }
if (CanThisClassDoubleAttack()) {
if (CheckBotDoubleAttack()) {
Attack(tar, EQ::invslot::slotPrimary, true);
}
if (!GetTarget() || GetAppearance() == eaDead) { return false; }
if (GetAppearance() == eaDead) { return false; }
if (GetSpecialAbility(SPECATK_TRIPLE) && CheckBotDoubleAttack(true)) {
Attack(tar, EQ::invslot::slotPrimary, true);
}
if (!GetTarget() || GetAppearance() == eaDead) { return false; }
if (GetAppearance() == eaDead) { return false; }
// quad attack, does this belong here??
if (GetSpecialAbility(SPECATK_QUAD) && CheckBotDoubleAttack(true)) {
Attack(tar, EQ::invslot::slotPrimary, true);
}
}
if (!GetTarget() || GetAppearance() == eaDead) { return false; }
if (GetAppearance() == eaDead) { return false; }
// Live AA - Flurry, Rapid Strikes ect (Flurry does not require Triple Attack).
if (int32 flurrychance = (aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance)) {
@@ -2488,12 +2486,12 @@ bool Bot::TryPrimaryWeaponAttacks(Mob* tar, const EQ::ItemInstance* p_item) {
MessageString(Chat::NPCFlurry, YOU_FLURRY);
Attack(tar, EQ::invslot::slotPrimary, false);
if (!GetTarget() || GetAppearance() == eaDead) { return false; }
if (GetAppearance() == eaDead) { return false; }
Attack(tar, EQ::invslot::slotPrimary, false);
}
}
if (!GetTarget() || GetAppearance() == eaDead) { return false; }
if (GetAppearance() == eaDead) { return false; }
auto ExtraAttackChanceBonus =
(spellbonuses.ExtraAttackChance[0] + itembonuses.ExtraAttackChance[0] +
aabonuses.ExtraAttackChance[0]);
@@ -3303,11 +3301,16 @@ bool Bot::Spawn(Client* botCharacterOwner) {
}
if (auto raid = entity_list.GetRaidByBotName(GetName())) {
raid->VerifyRaid();
SetRaidGrouped(true);
// Safety Check to confirm we have a valid raid
if (raid->IsRaidMember(GetBotOwner()->CastToClient())) {
Bot::RemoveBotFromRaid(this);
} else {
raid->LearnMembers();
SetRaidGrouped(true);
}
}
else if (auto group = entity_list.GetGroupByMobName(GetName())) {
group->VerifyGroup();
group->LearnMembers();
SetGrouped(true);
}
@@ -3602,19 +3605,6 @@ void Bot::LevelBotWithClient(Client* client, uint8 level, bool sendlvlapp) {
}
}
void Bot::SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color) {
auto outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct));
auto wc = (WearChange_Struct*)outapp->pBuffer;
wc->spawn_id = GetID();
wc->material = material;
wc->color.Color = color;
wc->wear_slot_id = material_slot;
entity_list.QueueClients(this, outapp);
safe_delete(outapp);
}
// Returns the item id that is in the bot inventory collection for the specified slot.
EQ::ItemInstance* Bot::GetBotItem(uint16 slot_id) {
EQ::ItemInstance* item = m_inv.GetItem(slot_id);
@@ -3666,6 +3656,10 @@ void Bot::BotRemoveEquipItem(uint16 slot_id)
void Bot::BotTradeAddItem(const EQ::ItemInstance* inst, uint16 slot_id, std::string* error_message, bool save_to_database)
{
if (!inst) {
return;
}
if (save_to_database) {
if (!database.botdb.SaveItemBySlot(this, slot_id, inst)) {
*error_message = BotDatabase::fail::SaveItemBySlot();
@@ -4626,8 +4620,13 @@ return true;
}
void Bot::Damage(Mob *from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable, int8 buffslot, bool iBuffTic, eSpecialAttacks special) {
if (spell_id == 0)
if (!from) {
return;
}
if (spell_id == 0) {
spell_id = SPELL_UNKNOWN;
}
//handle EVENT_ATTACK. Resets after we have not been attacked for 12 seconds
if (attacked_timer.Check()) {
@@ -4891,7 +4890,7 @@ void Bot::DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int32 max
if (botweapon->ItemType == EQ::item::ItemTypeShield)
hate += botweapon->AC;
hate = (hate * (100 + GetFuriousBash(botweapon->Focus.Effect)) / 100);
hate = (hate * (100 + GetSpellFuriousBash(botweapon->Focus.Effect)) / 100);
}
}
@@ -5067,7 +5066,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
}
}
if (taunting && target && target->IsNPC() && taunt_time) {
if (taunting && target->IsNPC() && taunt_time) {
if (GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this) {
BotGroupSay(
this,
@@ -5145,7 +5144,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
float HasteModifier = (GetHaste() * 0.01f);
uint16 skill_to_use = -1;
int bot_level = GetLevel();
int reuse = (TauntReuseTime * 1000);
int reuse = (TauntReuseTime * 1000); // Same as Bash and Kick
bool did_attack = false;
switch (GetClass()) {
case WARRIOR:
@@ -5205,7 +5204,6 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
if (GetWeaponDamage(target, GetBotItem(EQ::invslot::slotSecondary)) <= 0 && GetWeaponDamage(target, GetBotItem(EQ::invslot::slotShoulders)) <= 0)
dmg = DMG_INVULNERABLE;
reuse = (BashReuseTime * 1000);
DoSpecialAttackDamage(target, EQ::skills::SkillBash, dmg, 0, -1, reuse);
did_attack = true;
}
@@ -5232,7 +5230,6 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
if (GetWeaponDamage(target, GetBotItem(EQ::invslot::slotFeet)) <= 0)
dmg = DMG_INVULNERABLE;
reuse = (KickReuseTime * 1000);
DoSpecialAttackDamage(target, EQ::skills::SkillKick, dmg, 0, -1, reuse);
did_attack = true;
}
@@ -5539,7 +5536,7 @@ int32 Bot::GetActSpellDuration(uint16 spell_id, int32 duration) {
increase += 20;
}
if (IsMezSpell(spell_id))
if (IsMesmerizeSpell(spell_id))
tic_inc += GetAA(aaMesmerizationMastery);
return (((duration * increase) / 100) + tic_inc);
@@ -5857,16 +5854,6 @@ void Bot::GenerateSpecialAttacks() {
SetSpecialAbility(SPECATK_TRIPLE, 1);
}
bool Bot::DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
if (GetClass() == BARD) {
if (!ApplyBardPulse(bardsong, this, bardsong_slot))
InterruptSpell(SONG_ENDS_ABRUPTLY, 0x121, bardsong);
stopLogic = true;
}
return true;
}
bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
if (
@@ -6339,7 +6326,7 @@ void Bot::CalcRestState() {
for (unsigned int j = 0; j < buff_count; j++) {
if (IsValidSpell(buffs[j].spellid)) {
if (IsDetrimentalSpell(buffs[j].spellid) && (buffs[j].ticsremaining > 0))
if (!DetrimentalSpellAllowsRest(buffs[j].spellid))
if (!IsRestAllowedSpell(buffs[j].spellid))
return;
}
}
@@ -6687,8 +6674,6 @@ void Bot::UpdateGroupCastingRoles(const Group* group, bool disband)
Mob* healer = nullptr;
Mob* slower = nullptr;
Mob* nuker = nullptr;
Mob* doter = nullptr;
for (auto iter : group->members) {
if (!iter)
@@ -6804,10 +6789,6 @@ void Bot::UpdateGroupCastingRoles(const Group* group, bool disband)
healer->CastToBot()->SetGroupHealer();
if (slower && slower->IsBot())
slower->CastToBot()->SetGroupSlower();
if (nuker && nuker->IsBot())
nuker->CastToBot()->SetGroupNuker();
if (doter && doter->IsBot())
doter->CastToBot()->SetGroupDoter();
}
Bot* Bot::GetBotByBotClientOwnerAndBotName(Client* c, const std::string& botName) {
@@ -6901,7 +6882,7 @@ void Bot::ProcessClientZoneChange(Client* botOwner) {
else if (tempBot->HasGroup()) {
Group* g = tempBot->GetGroup();
if (g && g->IsGroupMember(botOwner)) {
if (botOwner && botOwner->IsClient()) {
if (botOwner->IsClient()) {
// Modified to not only zone bots if you're the leader.
// Also zone bots of the non-leader when they change zone.
if (tempBot->GetBotOwnerCharacterID() == botOwner->CharacterID() && g->IsGroupMember(botOwner))
-2
View File
@@ -196,10 +196,8 @@ public:
void SetAttackTimer() override;
uint64 GetClassHPFactor();
int64 CalcMaxHP() override;
bool DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
bool DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
void SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color);
void Camp(bool save_to_database = true);
void SetTarget(Mob* mob) override;
void Zone();
+31 -28
View File
@@ -2526,9 +2526,17 @@ void bot_command_apply_poison(Client *c, const Seperator *sep)
}
Bot *my_rogue_bot = nullptr;
if (c->GetTarget() && c->GetTarget()->IsBot() && c->GetTarget()->CastToBot()->GetBotOwnerCharacterID() == c->CharacterID() && c->GetTarget()->CastToBot()->GetClass() == ROGUE) {
my_rogue_bot = c->GetTarget()->CastToBot();
auto t = c->GetTarget();
if (
t &&
t->IsBot() &&
t->CastToBot()->GetBotOwnerCharacterID() == c->CharacterID() &&
t->GetClass() == ROGUE
) {
my_rogue_bot = t->CastToBot();
}
if (!my_rogue_bot) {
c->Message(Chat::White, "You must target a rogue bot that you own to use this command!");
@@ -2696,7 +2704,7 @@ void bot_command_attack(Client *c, const Seperator *sep)
}
std::list<Bot*> sbl;
if (ActionableBots::PopulateSBL(c, ab_arg.c_str(), sbl, ab_mask, sep->arg[2]) == ActionableBots::ABT_None) {
if (ActionableBots::PopulateSBL(c, ab_arg, sbl, ab_mask, sep->arg[2]) == ActionableBots::ABT_None) {
return;
}
@@ -3582,14 +3590,13 @@ void bot_command_item_use(Client* c, const Seperator* sep)
return;
}
std::list<int16> equipable_slot_list;
std::vector<int16> equipable_slot_list;
for (int16 equipable_slot = EQ::invslot::EQUIPMENT_BEGIN; equipable_slot <= EQ::invslot::EQUIPMENT_END; ++equipable_slot) {
if (item_data->Slots & (1 << equipable_slot)) {
equipable_slot_list.push_back(equipable_slot);
equipable_slot_list.emplace_back(equipable_slot);
}
}
std::string msg;
std::string text_link;
EQ::SayLinkEngine linker;
@@ -3616,7 +3623,7 @@ void bot_command_item_use(Client* c, const Seperator* sep)
bot_iter->GetCleanName()
);
for (auto slot_iter : equipable_slot_list) {
for (const auto& slot_iter : equipable_slot_list) {
// needs more failure criteria - this should cover the bulk for now
if (slot_iter == EQ::invslot::slotSecondary && item_data->Damage && !bot_iter->CanThisClassDualWield()) {
continue;
@@ -5124,8 +5131,6 @@ void bot_subcommand_bot_clone(Client *c, const Seperator *sep)
return;
}
std::string error_message;
bool available_flag = false;
if (!database.botdb.QueryNameAvailablity(bot_name, available_flag)) {
c->Message(
@@ -5559,8 +5564,6 @@ void bot_subcommand_bot_delete(Client *c, const Seperator *sep)
return;
}
std::string error_message;
if (!my_bot->DeleteBot()) {
c->Message(Chat::White, "Failed to delete '%s' due to database error", my_bot->GetCleanName());
return;
@@ -6407,19 +6410,20 @@ void bot_subcommand_bot_report(Client *c, const Seperator *sep)
std::string ab_type_arg = sep->arg[1];
if (ab_type_arg.empty()) {
if (c->GetTarget()) {
if (c->GetTarget()->IsClient() && c->GetTarget()->CastToClient() == c)
auto t = c->GetTarget();
if (t && t->IsClient()) {
if (t->CastToClient() == c) {
ab_type_arg = "ownergroup";
else if (c->GetTarget()->IsClient() && c->GetTarget()->CastToClient() != c)
} else {
ab_type_arg = "targetgroup";
}
else {
}
} else {
ab_type_arg = "spawned";
}
}
std::list<Bot*> sbl;
if (ActionableBots::PopulateSBL(c, ab_type_arg.c_str(), sbl, ab_mask, sep->arg[2]) == ActionableBots::ABT_None)
if (ActionableBots::PopulateSBL(c, ab_type_arg, sbl, ab_mask, sep->arg[2]) == ActionableBots::ABT_None)
return;
for (auto bot_iter : sbl) {
@@ -6959,7 +6963,6 @@ void bot_subcommand_bot_toggle_helm(Client *c, const Seperator *sep)
}
if (ab_type == ActionableBots::ABT_All) {
std::string query;
if (toggle_helm) {
if (!database.botdb.ToggleAllHelmAppearances(c->CharacterID()))
c->Message(Chat::White, "%s", BotDatabase::fail::ToggleAllHelmAppearances());
@@ -7327,7 +7330,7 @@ void bot_subcommand_heal_rotation_adjust_critical(Client *c, const Seperator *se
uint8 armor_type_value = 255;
if (sep->IsNumber(1))
armor_type_value = Strings::ToInt(armor_type_arg.c_str());
armor_type_value = Strings::ToInt(armor_type_arg);
if (armor_type_value > ARMOR_TYPE_LAST) {
c->Message(Chat::White, "You must specify a valid [armor_type: %u-%u] to use this command", ARMOR_TYPE_FIRST, ARMOR_TYPE_LAST);
@@ -7356,7 +7359,7 @@ void bot_subcommand_heal_rotation_adjust_critical(Client *c, const Seperator *se
float critical_ratio = CRITICAL_HP_RATIO_BASE;
if (sep->IsNumber(2))
critical_ratio = Strings::ToFloat(critical_arg.c_str());
critical_ratio = Strings::ToFloat(critical_arg);
else if (!critical_arg.compare("+"))
critical_ratio = (*current_member->MemberOfHealRotation())->ArmorTypeCriticalHPRatio(armor_type_value) + HP_RATIO_DELTA;
else if (!critical_arg.compare("-"))
@@ -7393,7 +7396,7 @@ void bot_subcommand_heal_rotation_adjust_safe(Client *c, const Seperator *sep)
uint8 armor_type_value = 255;
if (sep->IsNumber(1))
armor_type_value = Strings::ToInt(armor_type_arg.c_str());
armor_type_value = Strings::ToInt(armor_type_arg);
if (armor_type_value > ARMOR_TYPE_LAST) {
c->Message(Chat::White, "You must specify a valid [armor_type: %u-%u] to use this command", ARMOR_TYPE_FIRST, ARMOR_TYPE_LAST);
@@ -7422,7 +7425,7 @@ void bot_subcommand_heal_rotation_adjust_safe(Client *c, const Seperator *sep)
float safe_ratio = SAFE_HP_RATIO_BASE;
if (sep->IsNumber(2))
safe_ratio = Strings::ToFloat(safe_arg.c_str());
safe_ratio = Strings::ToFloat(safe_arg);
else if (!safe_arg.compare("+"))
safe_ratio = (*current_member->MemberOfHealRotation())->ArmorTypeSafeHPRatio(armor_type_value) + HP_RATIO_DELTA;
else if (!safe_arg.compare("-"))
@@ -7536,7 +7539,7 @@ void bot_subcommand_heal_rotation_change_interval(Client *c, const Seperator *se
uint32 hr_change_interval_s = CASTING_CYCLE_DEFAULT_INTERVAL_S;
if (!change_interval_arg.empty()) {
hr_change_interval_s = Strings::ToInt(change_interval_arg.c_str());
hr_change_interval_s = Strings::ToInt(change_interval_arg);
}
else {
hr_change_interval_s = (*current_member->MemberOfHealRotation())->IntervalS();
@@ -7684,14 +7687,14 @@ void bot_subcommand_heal_rotation_create(Client *c, const Seperator *sep)
hr_adaptive_targeting = true;
if (!fast_heals_arg.compare("on"))
hr_fast_heals = true;
hr_interval_s = Strings::ToInt(interval_arg.c_str());
hr_interval_s = Strings::ToInt(interval_arg);
}
else if (!casting_override_arg.compare("off")) {
if (!adaptive_targeting_arg.compare("on"))
hr_adaptive_targeting = true;
if (!fast_heals_arg.compare("on"))
hr_fast_heals = true;
hr_interval_s = Strings::ToInt(interval_arg.c_str());
hr_interval_s = Strings::ToInt(interval_arg);
}
if (hr_interval_s < CASTING_CYCLE_MINIMUM_INTERVAL_S || hr_interval_s > CASTING_CYCLE_MAXIMUM_INTERVAL_S)
@@ -9009,7 +9012,7 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
}
auto my_bot = new Bot(Bot::CreateDefaultNPCTypeStructForBot(bot_name.c_str(), "", bot_owner->GetLevel(), bot_race, bot_class, bot_gender), bot_owner);
auto my_bot = new Bot(Bot::CreateDefaultNPCTypeStructForBot(bot_name, "", bot_owner->GetLevel(), bot_race, bot_class, bot_gender), bot_owner);
if (!my_bot->Save()) {
bot_owner->Message(
@@ -9259,7 +9262,7 @@ void helper_command_depart_list(Client* bot_owner, Bot* druid_bot, Bot* wizard_b
destination_number,
local_entry->long_name,
text_link
).c_str()
)
);
destination_count++;
@@ -9294,7 +9297,7 @@ void helper_command_depart_list(Client* bot_owner, Bot* druid_bot, Bot* wizard_b
destination_number,
local_entry->long_name,
text_link
).c_str()
)
);
destination_count++;
+10 -10
View File
@@ -110,7 +110,7 @@ bool Bot::BotCastSong(Mob* tar, uint8 botLevel) {
continue;
if (!CheckSpellRecastTimers(this, iter.SpellIndex))
continue;
if (!IsSpellUsableThisZoneType(iter.SpellId, zone->GetZoneType()))
if (!IsSpellUsableInThisZoneType(iter.SpellId, zone->GetZoneType()))
continue;
switch (spells[iter.SpellId].target_type) {
case ST_AEBard:
@@ -144,7 +144,7 @@ bool Bot::BotCastCombatSong(Mob* tar, uint8 botLevel) {
continue;
if (!CheckSpellRecastTimers(this, iter.SpellIndex))
continue;
if (!IsSpellUsableThisZoneType(iter.SpellId, zone->GetZoneType()))
if (!IsSpellUsableInThisZoneType(iter.SpellId, zone->GetZoneType()))
continue;
switch (spells[iter.SpellId].target_type) {
case ST_AEBard:
@@ -176,7 +176,7 @@ bool Bot::BotCastHateReduction(Mob* tar, uint8 botLevel, const BotSpell& botSpel
continue;
if (!CheckSpellRecastTimers(this, iter.SpellIndex))
continue;
if (!IsSpellUsableThisZoneType(iter.SpellId, zone->GetZoneType()))
if (!IsSpellUsableInThisZoneType(iter.SpellId, zone->GetZoneType()))
continue;
if (spells[iter.SpellId].target_type != ST_Target)
continue;
@@ -316,7 +316,7 @@ bool Bot::BotCastSlow(Mob* tar, uint8 botLevel, uint8 botClass, BotSpell& botSpe
continue;
}
if (!IsSpellUsableThisZoneType(iter.SpellId, zone->GetZoneType())) {
if (!IsSpellUsableInThisZoneType(iter.SpellId, zone->GetZoneType())) {
continue;
}
@@ -582,7 +582,7 @@ bool Bot::BotCastCombatBuff(Mob* tar, uint8 botLevel, uint8 botClass) {
if (
((IsEffectInSpell(s.SpellId, SE_Levitate) && !zone->CanLevitate()) ||
(IsEffectInSpell(s.SpellId, SE_MovementSpeed) && !zone->CanCastOutdoor())) &&
(botClass != BARD || !IsSpellUsableThisZoneType(s.SpellId, zone->GetZoneType()))
(botClass != BARD || !IsSpellUsableInThisZoneType(s.SpellId, zone->GetZoneType()))
) {
continue;
}
@@ -892,7 +892,7 @@ bool Bot::BotCastBuff(Mob* tar, uint8 botLevel, uint8 botClass) {
(IsEffectInSpell(s.SpellId, SE_Levitate) && !zone->CanLevitate()) ||
(IsEffectInSpell(s.SpellId, SE_MovementSpeed) && !zone->CanCastOutdoor())
) &&
(botClass != BARD || !IsSpellUsableThisZoneType(s.SpellId, zone->GetZoneType()))
(botClass != BARD || !IsSpellUsableInThisZoneType(s.SpellId, zone->GetZoneType()))
) {
continue;
}
@@ -1902,7 +1902,7 @@ std::list<BotSpell> Bot::GetBotSpellsForSpellEffect(Bot* botCaster, int spellEff
continue;
}
if (IsEffectInSpell(botSpellList[i].spellid, spellEffect) || GetTriggerSpellID(botSpellList[i].spellid, spellEffect)) {
if (IsEffectInSpell(botSpellList[i].spellid, spellEffect) || GetSpellTriggerSpellID(botSpellList[i].spellid, spellEffect)) {
BotSpell botSpell;
botSpell.SpellId = botSpellList[i].spellid;
botSpell.SpellIndex = i;
@@ -1940,7 +1940,7 @@ std::list<BotSpell> Bot::GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster,
if (
(
IsEffectInSpell(botSpellList[i].spellid, spellEffect) ||
GetTriggerSpellID(botSpellList[i].spellid, spellEffect)
GetSpellTriggerSpellID(botSpellList[i].spellid, spellEffect)
) &&
spells[botSpellList[i].spellid].target_type == targetType
) {
@@ -2313,7 +2313,7 @@ BotSpell Bot::GetBestBotSpellForMez(Bot* botCaster) {
for (std::list<BotSpell>::iterator botSpellListItr = botSpellList.begin(); botSpellListItr != botSpellList.end(); ++botSpellListItr) {
// Assuming all the spells have been loaded into this list by level and in descending order
if (
IsMezSpell(botSpellListItr->SpellId) &&
IsMesmerizeSpell(botSpellListItr->SpellId) &&
CheckSpellRecastTimers(botCaster, botSpellListItr->SpellIndex)
) {
result.SpellId = botSpellListItr->SpellId;
@@ -2388,7 +2388,7 @@ BotSpell Bot::GetBestBotSpellForDiseaseBasedSlow(Bot* botCaster) {
Mob* Bot::GetFirstIncomingMobToMez(Bot* botCaster, BotSpell botSpell) {
Mob* result = 0;
if (botCaster && IsMezSpell(botSpell.SpellId)) {
if (botCaster && IsMesmerizeSpell(botSpell.SpellId)) {
std::list<NPC*> npc_list;
entity_list.GetNPCList(npc_list);
+448 -381
View File
File diff suppressed because it is too large Load Diff
+14 -13
View File
@@ -67,6 +67,7 @@ namespace EQ
#include "task_client_state.h"
#include "cheat_manager.h"
#include "../common/events/player_events.h"
#include "../common/data_verification.h"
#ifdef _WINDOWS
// since windows defines these within windef.h (which windows.h include)
@@ -306,7 +307,6 @@ public:
void ReturnTraderReq(const EQApplicationPacket* app,int16 traderitemcharges, uint32 itemid = 0);
void TradeRequestFailed(const EQApplicationPacket* app);
void BuyTraderItem(TraderBuy_Struct* tbs,Client* trader,const EQApplicationPacket* app);
void TraderUpdate(uint16 slot_id,uint32 trader_id);
void FinishTrade(Mob* with, bool finalizer = false, void* event_entry = nullptr, std::list<void*>* event_details = nullptr);
void SendZonePoints();
@@ -322,7 +322,6 @@ public:
void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
bool ShouldISpawnFor(Client *c) { return !GMHideMe(c) && !IsHoveringForRespawn(); }
virtual bool Process();
void ProcessPackets();
void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone);
void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL);
void ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_skill, const char* orig_message, const char* targetname = nullptr, bool is_silent = false);
@@ -379,12 +378,8 @@ public:
void SetPetCommandState(int button, int state);
bool CheckAccess(int16 iDBLevel, int16 iDefaultLevel);
void CheckQuests(const char* zonename, const char* message, uint32 npc_id, uint32 item_id, Mob* other);
bool AutoAttackEnabled() const { return auto_attack; }
bool AutoFireEnabled() const { return auto_fire; }
void MakeCorpse(uint32 exploss);
bool ChangeFirstName(const char* in_firstname,const char* gmname);
@@ -394,7 +389,6 @@ public:
virtual void SetMaxHP();
int32 LevelRegen();
void HPTick();
void SetGM(bool toggle);
void SetPVP(bool toggle, bool message = true);
@@ -938,7 +932,7 @@ public:
inline uint32 GetAAPercent() const { return m_epp.perAA; }
void SetAATitle(std::string title);
void SetTitleSuffix(std::string suffix);
void MemorizeSpell(uint32 slot, uint32 spellid, uint32 scribing, uint32 reduction = 0);
void MemorizeSpell(uint32 slot, uint32 spell_id, uint32 scribing, uint32 reduction = 0);
// Item methods
void UseAugmentContainer(int container_slot);
@@ -972,6 +966,8 @@ public:
void DropItem(int16 slot_id, bool recurse = true);
void DropItemQS(EQ::ItemInstance* inst, bool pickup);
bool IsAugmentRestricted(uint8 item_type, uint32 augment_restriction);
int GetItemLinkHash(const EQ::ItemInstance* inst); // move to ItemData..or make use of the pre-calculated database field
void SendItemLink(const EQ::ItemInstance* inst, bool sendtoall=false);
@@ -999,6 +995,7 @@ public:
void SetThirst(int32 in_thirst);
void SetConsumption(int32 in_hunger, int32 in_thirst);
bool IsStarved() const { if (GetGM() || !RuleB(Character, EnableFoodRequirement) || !RuleB(Character, EnableHungerPenalties)) return false; return m_pp.hunger_level == 0 || m_pp.thirst_level == 0; }
int32 GetIntoxication() const { return m_pp.intoxication; }
bool CheckTradeLoreConflict(Client* other);
bool CheckTradeNonDroppable();
@@ -1588,6 +1585,7 @@ public:
void SetEnvironmentDamageModifier(int32 val) { environment_damage_modifier = val; }
inline bool GetInvulnerableEnvironmentDamage() const { return invulnerable_environment_damage; }
void SetInvulnerableEnvironmentDamage(bool val) { invulnerable_environment_damage = val; }
void SetIntoxication(int32 in_intoxication);
void ShowNumHits(); // work around function for numhits not showing on buffs
@@ -1643,6 +1641,7 @@ public:
PlayerEvent::PlayerEvent GetPlayerEvent();
void RecordKilledNPCEvent(NPC *n);
uint32 GetEXPForLevel(uint16 check_level);
protected:
friend class Mob;
void CalcEdibleBonuses(StatBonuses* newbon);
@@ -1719,7 +1718,6 @@ private:
int64 CalcHPRegen(bool bCombat = false);
int64 CalcManaRegen(bool bCombat = false);
int64 CalcBaseManaRegen();
uint64 GetClassHPFactor();
void DoHPRegen();
void DoManaRegen();
void DoStaminaHungerUpdate();
@@ -1819,7 +1817,6 @@ private:
bool temp_pvp;
void NPCSpawn(const Seperator* sep);
uint32 GetEXPForLevel(uint16 level);
void SendLogoutPackets();
void SendZoneInPackets();
@@ -1842,9 +1839,6 @@ private:
WaterRegionType last_region_type;
// this is used to try to cut back on position update reflections
int position_update_same_count;
PTimerList p_timers; //persistent timers
Timer hpupdate_timer;
Timer camp_timer;
@@ -2043,6 +2037,13 @@ private:
bool CanTradeFVNoDropItem();
void SendMobPositions();
void PlayerTradeEventLog(Trade *t, Trade *t2);
// full and partial mail key cache
std::string m_mail_key_full;
std::string m_mail_key;
public:
const std::string &GetMailKeyFull() const;
const std::string &GetMailKey() const;
};
#endif
+7 -51
View File
@@ -288,7 +288,7 @@ int64 Client::CalcHPRegen(bool bCombat)
if (!bCombat && CanFastRegen() && (IsSitting() || CanMedOnHorse())) {
auto max_hp = GetMaxHP();
int fast_regen = 6 * (max_hp / zone->newzone_data.fast_regen_hp);
int64 fast_regen = 6 * (max_hp / (zone ? zone->newzone_data.fast_regen_hp : 180));
if (base < fast_regen) // weird, but what the client is doing
base = fast_regen;
}
@@ -506,50 +506,6 @@ int64 Client::CalcBaseHP()
return base_hp;
}
// This is for calculating Base HPs + STA bonus for SoD or later clients.
uint64 Client::GetClassHPFactor()
{
int factor;
// Note: Base HP factor under level 41 is equal to factor / 12, and from level 41 to 80 is factor / 6.
// Base HP over level 80 is factor / 10
// HP per STA point per level is factor / 30 for level 80+
// HP per STA under level 40 is the level 80 HP Per STA / 120, and for over 40 it is / 60.
switch (GetClass()) {
case DRUID:
case ENCHANTER:
case NECROMANCER:
case MAGICIAN:
case WIZARD:
factor = 240;
break;
case BEASTLORD:
case BERSERKER:
case MONK:
case ROGUE:
case SHAMAN:
factor = 255;
break;
case BARD:
case CLERIC:
factor = 264;
break;
case SHADOWKNIGHT:
case PALADIN:
factor = 288;
break;
case RANGER:
factor = 276;
break;
case WARRIOR:
factor = 300;
break;
default:
factor = 240;
break;
}
return factor;
}
// This should return the combined AC of all the items the player is wearing.
int32 Client::GetRawItemAC()
{
@@ -841,10 +797,10 @@ uint32 Client::CalcCurrentWeight()
int32 Client::CalcAlcoholPhysicalEffect()
{
if (m_pp.intoxication <= 55) {
if (GetIntoxication() <= 55) {
return 0;
}
return (m_pp.intoxication - 40) / 16;
return (GetIntoxication() - 40) / 16;
}
int32 Client::CalcSTR()
@@ -922,8 +878,8 @@ int32 Client::CalcINT()
int32 val = m_pp.INT + itembonuses.INT + spellbonuses.INT;
int32 mod = aabonuses.INT;
INT = val + mod;
if (m_pp.intoxication) {
int32 AlcINT = INT - (int32)((float)m_pp.intoxication / 200.0f * (float)INT) - 1;
if (GetIntoxication()) {
int32 AlcINT = INT - (int32)((float)GetIntoxication() / 200.0f * (float)INT) - 1;
if ((AlcINT < (int)(0.2 * INT))) {
INT = (int)(0.2f * (float)INT);
}
@@ -946,8 +902,8 @@ int32 Client::CalcWIS()
int32 val = m_pp.WIS + itembonuses.WIS + spellbonuses.WIS;
int32 mod = aabonuses.WIS;
WIS = val + mod;
if (m_pp.intoxication) {
int32 AlcWIS = WIS - (int32)((float)m_pp.intoxication / 200.0f * (float)WIS) - 1;
if (GetIntoxication()) {
int32 AlcWIS = WIS - (int32)((float)GetIntoxication() / 200.0f * (float)WIS) - 1;
if ((AlcWIS < (int)(0.2 * WIS))) {
WIS = (int)(0.2f * (float)WIS);
}
+83 -73
View File
@@ -656,7 +656,7 @@ void Client::CompleteConnect()
const SPDat_Spell_Struct &spell = spells[buffs[j1].spellid];
int NimbusEffect = GetNimbusEffect(buffs[j1].spellid);
int NimbusEffect = GetSpellNimbusEffect(buffs[j1].spellid);
if (NimbusEffect) {
if (!IsNimbusEffectActive(NimbusEffect))
SendSpellEffect(NimbusEffect, 500, 0, 1, 3000, true);
@@ -721,17 +721,17 @@ void Client::CompleteConnect()
case SE_AddMeleeProc:
case SE_WeaponProc:
{
AddProcToWeapon(GetProcID(buffs[j1].spellid, x1), false, 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid, buffs[j1].casterlevel, GetProcLimitTimer(buffs[j1].spellid, ProcType::MELEE_PROC));
AddProcToWeapon(GetProcID(buffs[j1].spellid, x1), false, 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid, buffs[j1].casterlevel, GetSpellProcLimitTimer(buffs[j1].spellid, ProcType::MELEE_PROC));
break;
}
case SE_DefensiveProc:
{
AddDefensiveProc(GetProcID(buffs[j1].spellid, x1), 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid, GetProcLimitTimer(buffs[j1].spellid, ProcType::DEFENSIVE_PROC));
AddDefensiveProc(GetProcID(buffs[j1].spellid, x1), 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid, GetSpellProcLimitTimer(buffs[j1].spellid, ProcType::DEFENSIVE_PROC));
break;
}
case SE_RangedProc:
{
AddRangedProc(GetProcID(buffs[j1].spellid, x1), 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid, GetProcLimitTimer(buffs[j1].spellid, ProcType::RANGED_PROC));
AddRangedProc(GetProcID(buffs[j1].spellid, x1), 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid, GetSpellProcLimitTimer(buffs[j1].spellid, ProcType::RANGED_PROC));
break;
}
}
@@ -1265,7 +1265,13 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
database.LoadCharacterDisciplines(cid, &m_pp); /* Load Character Disciplines */
database.LoadCharacterLanguages(cid, &m_pp); /* Load Character Languages */
database.LoadCharacterLeadershipAA(cid, &m_pp); /* Load Character Leadership AA's */
database.LoadCharacterTribute(cid, &m_pp); /* Load CharacterTribute */
database.LoadCharacterTribute(this); /* Load CharacterTribute */
// this pattern is strange
// this is remnants of the old way of doing things
auto mail_keys = database.GetMailKey(CharacterID());
m_mail_key_full = mail_keys.mail_key_full;
m_mail_key = mail_keys.mail_key;
/* Load AdventureStats */
AdventureStats_Struct as;
@@ -1309,7 +1315,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
/* If we can maintain intoxication across zones, check for it */
if (!RuleB(Character, MaintainIntoxicationAcrossZones))
m_pp.intoxication = 0;
SetIntoxication(0);
strcpy(name, m_pp.name);
strcpy(lastname, m_pp.last_name);
@@ -1508,30 +1514,31 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
}
if (group) {
// If the group leader is not set, pull the group leader infomrmation from the database.
if (!group->GetLeader()) {
char ln[64];
char MainTankName[64];
char AssistName[64];
char PullerName[64];
char NPCMarkerName[64];
char mentoree_name[64];
int mentor_percent;
GroupLeadershipAA_Struct GLAA;
memset(ln, 0, 64);
database.GetGroupLeadershipInfo(group->GetID(), ln, MainTankName, AssistName, PullerName, NPCMarkerName, mentoree_name, &mentor_percent, &GLAA);
Client *c = entity_list.GetClientByName(ln);
if (c)
group->SetLeader(c);
group->SetMainTank(MainTankName);
group->SetMainAssist(AssistName);
group->SetPuller(PullerName);
group->SetNPCMarker(NPCMarkerName);
group->SetGroupAAs(&GLAA);
group->SetGroupMentor(mentor_percent, mentoree_name);
}
char ln[64];
char MainTankName[64];
char AssistName[64];
char PullerName[64];
char NPCMarkerName[64];
char mentoree_name[64];
int mentor_percent;
GroupLeadershipAA_Struct GLAA;
memset(ln, 0, 64);
database.GetGroupLeadershipInfo(group->GetID(), ln, MainTankName, AssistName, PullerName, NPCMarkerName, mentoree_name, &mentor_percent, &GLAA);
group->LearnMembers();
if (!group->GetLeader()) {
Client *c = entity_list.GetClientByName(ln);
if (c) {
group->SetLeader(c);
}
}
group->SetMainTank(MainTankName);
group->SetMainAssist(AssistName);
group->SetPuller(PullerName);
group->SetNPCMarker(NPCMarkerName);
group->SetGroupAAs(&GLAA);
group->SetGroupMentor(mentor_percent, mentoree_name);
JoinGroupXTargets(group);
group->UpdatePlayer(this);
LFG = false;
@@ -5568,10 +5575,8 @@ void Client::Handle_OP_DeleteItem(const EQApplicationPacket *app)
if (IntoxicationIncrease < 0)
IntoxicationIncrease = 1;
m_pp.intoxication += IntoxicationIncrease;
SetIntoxication(GetIntoxication()+IntoxicationIncrease);
if (m_pp.intoxication > 200)
m_pp.intoxication = 200;
}
DeleteItemInInventory(alc->from_slot, 1);
@@ -6466,27 +6471,28 @@ void Client::Handle_OP_GMFind(const EQApplicationPacket *app)
RecordPlayerEventLog(PlayerEvent::POSSIBLE_HACK, PlayerEvent::PossibleHackEvent{.message = "Used /find"});
return;
}
if (app->size != sizeof(GMSummon_Struct)) {
LogError("Wrong size: OP_GMFind, size=[{}], expected [{}]", app->size, sizeof(GMSummon_Struct));
if (app->size != sizeof(GMFind_Struct)) {
LogError("Wrong size: OP_GMFind, size=[{}], expected [{}]", app->size, sizeof(GMFind_Struct));
return;
}
//Break down incoming
GMSummon_Struct* request = (GMSummon_Struct*)app->pBuffer;
auto* request = (GMFind_Struct*) app->pBuffer;
//Create a new outgoing
auto outapp = new EQApplicationPacket(OP_GMFind, sizeof(GMSummon_Struct));
GMSummon_Struct* foundplayer = (GMSummon_Struct*)outapp->pBuffer;
auto outapp = new EQApplicationPacket(OP_GMFind, sizeof(GMFind_Struct));
auto* foundplayer = (GMFind_Struct*) outapp->pBuffer;
//Copy the constants
strcpy(foundplayer->charname, request->charname);
strcpy(foundplayer->gmname, request->gmname);
//Check if the NPC exits intrazone...
Mob* gt = entity_list.GetMob(request->charname);
if (gt != 0) {
auto* gt = entity_list.GetMob(request->charname);
if (gt) {
foundplayer->success = 1;
foundplayer->x = (int32)gt->GetX();
foundplayer->y = (int32)gt->GetY();
foundplayer->z = (int32)gt->GetZ();
foundplayer->zoneID = zone->GetZoneID();
foundplayer->x = gt->GetX();
foundplayer->y = gt->GetY();
foundplayer->z = gt->GetZ();
foundplayer->zoneID = zone->GetZoneID();
}
//Send the packet...
FastQueuePacket(&outapp);
@@ -6999,7 +7005,7 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
//we have a raid.. see if we're in a raid group
uint32 grp = raid->GetGroup(memberToDisband->GetName());
bool wasGrpLdr = raid->members[raid->GetPlayerIndex(memberToDisband->GetName())].is_group_leader;
if (grp < 12) {
if (grp < MAX_RAID_GROUPS) {
if (wasGrpLdr) {
raid->SetGroupLeader(memberToDisband->GetName(), false);
for (int x = 0; x < MAX_RAID_MEMBERS; x++) {
@@ -8613,47 +8619,51 @@ void Client::Handle_OP_Illusion(const EQApplicationPacket *app)
void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app)
{
if (app->size != sizeof(InspectResponse_Struct)) {
LogError("Wrong size: OP_InspectAnswer, size=[{}], expected [{}]", app->size, sizeof(InspectResponse_Struct));
return;
}
//Fills the app sent from client.
EQApplicationPacket* outapp = app->Copy();
InspectResponse_Struct* insr = (InspectResponse_Struct*)outapp->pBuffer;
Mob* tmp = entity_list.GetMob(insr->TargetID);
const EQ::ItemData* item = nullptr;
auto outapp = app->Copy();
auto insr = (InspectResponse_Struct *) outapp->pBuffer;
auto tmp = entity_list.GetMob(insr->TargetID);
const EQ::ItemData *item = nullptr;
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
for (int16 L = EQ::invslot::EQUIPMENT_BEGIN; L <= EQ::invslot::EQUIPMENT_END; L++) {
const EQ::ItemInstance* inst = GetInv().GetItem(L);
for (int16 L = EQ::invslot::EQUIPMENT_BEGIN; L <= EQ::invslot::EQUIPMENT_END; L++) {
const auto inst = GetInv().GetItem(L);
item = inst ? inst->GetItem() : nullptr;
if (item) {
strcpy(insr->itemnames[L], item->Name);
if (inst && inst->GetOrnamentationAug(ornamentationAugtype)) {
const EQ::ItemData *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
insr->itemicons[L] = aug_item->Icon;
}
else if (inst->GetOrnamentationIcon()) {
insr->itemicons[L] = inst->GetOrnamentationIcon();
}
else {
if (inst) {
const auto augment = inst->GetOrnamentationAugment();
if (augment) {
insr->itemicons[L] = augment->GetItem()->Icon;
} else if (inst->GetOrnamentationIcon()) {
insr->itemicons[L] = inst->GetOrnamentationIcon();
}
} else {
insr->itemicons[L] = item->Icon;
}
} else {
insr->itemicons[L] = 0xFFFFFFFF;
}
else { insr->itemicons[L] = 0xFFFFFFFF; }
}
InspectMessage_Struct* newmessage = (InspectMessage_Struct*)insr->text;
InspectMessage_Struct& playermessage = GetInspectMessage();
memcpy(&playermessage, newmessage, sizeof(InspectMessage_Struct));
database.SaveCharacterInspectMessage(CharacterID(), &playermessage);
auto message = (InspectMessage_Struct *) insr->text;
auto inspect_message = GetInspectMessage();
if (tmp != 0 && tmp->IsClient()) { tmp->CastToClient()->QueuePacket(outapp); } // Send answer to requester
memcpy(&inspect_message, message, sizeof(InspectMessage_Struct));
database.SaveCharacterInspectMessage(CharacterID(), &inspect_message);
return;
if (
tmp &&
tmp->IsClient()
) {
tmp->CastToClient()->QueuePacket(outapp);
} // Send answer to requester
}
void Client::Handle_OP_InspectMessageUpdate(const EQApplicationPacket *app)
@@ -9223,7 +9233,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
return;
}
if (i == 0) {
if (!IsCastWhileInvis(item->Click.Effect)) {
if (!IsCastWhileInvisibleSpell(item->Click.Effect)) {
CommonBreakInvisible(); // client can't do this for us :(
}
if (GetClass() == BARD){
@@ -9295,7 +9305,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
}
if (i == 0) {
if (!IsCastWhileInvis(augitem->Click.Effect)) {
if (!IsCastWhileInvisibleSpell(augitem->Click.Effect)) {
CommonBreakInvisible(); // client can't do this for us :(
}
if (GetClass() == BARD) {
@@ -11460,7 +11470,7 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
if (EntityVariableExists(DIAWIND_RESPONSE_ONE_KEY)) {
response = GetEntityVariable(DIAWIND_RESPONSE_ONE_KEY);
if (!response.empty()) {
ChannelMessageReceived(8, 0, 100, response.c_str(), nullptr, true);
ChannelMessageReceived(ChatChannel_Say, 0, 100, response.c_str(), nullptr, true);
}
}
break;
@@ -11469,7 +11479,7 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
if (EntityVariableExists(DIAWIND_RESPONSE_TWO_KEY)) {
response = GetEntityVariable(DIAWIND_RESPONSE_TWO_KEY);
if (!response.empty()) {
ChannelMessageReceived(8, 0, 100, response.c_str(), nullptr, true);
ChannelMessageReceived(ChatChannel_Say, 0, 100, response.c_str(), nullptr, true);
}
}
break;
@@ -11675,7 +11685,7 @@ void Client::Handle_OP_QueryUCSServerStatus(const EQApplicationPacket *app)
EQApplicationPacket* outapp = nullptr;
std::string buffer;
std::string MailKey = database.GetMailKey(CharacterID(), true);
std::string MailKey = GetMailKey();
EQ::versions::UCSVersion ConnectionType = EQ::versions::ucsUnknown;
// chat server packet
+8 -7
View File
@@ -189,9 +189,10 @@ bool Client::Process() {
}
if (camp_timer.Check()) {
Raid* raid = entity_list.GetRaidByClient(this);
if (raid)
raid->RemoveMember(this->GetName());
Raid *myraid = entity_list.GetRaidByClient(this);
if (myraid) {
myraid->MemberZoned(this);
}
LeaveGroup();
Save();
if (GetMerc())
@@ -517,9 +518,9 @@ bool Client::Process() {
Save(0);
}
if (m_pp.intoxication > 0)
if (GetIntoxication() > 0)
{
--m_pp.intoxication;
SetIntoxication(GetIntoxication()-1);
CalcBonuses();
}
@@ -1034,7 +1035,7 @@ void Client::OPRezzAnswer(uint32 Action, uint32 SpellID, uint16 ZoneID, uint16 I
BuffFadeNonPersistDeath();
}
int SpellEffectDescNum = GetSpellEffectDescNum(SpellID);
int SpellEffectDescNum = GetSpellEffectDescriptionNumber(SpellID);
// Rez spells with Rez effects have this DescNum (first is Titanium, second is 6.2 Client)
if(RuleB(Character, UseResurrectionSickness) && SpellEffectDescNum == 82 || SpellEffectDescNum == 39067) {
SetHP(GetMaxHP() / 5);
@@ -1967,7 +1968,7 @@ void Client::CalcRestState()
for (unsigned int j = 0; j < buff_count; j++) {
if(IsValidSpell(buffs[j].spellid)) {
if(IsDetrimentalSpell(buffs[j].spellid) && (buffs[j].ticsremaining > 0))
if(!DetrimentalSpellAllowsRest(buffs[j].spellid))
if(!IsRestAllowedSpell(buffs[j].spellid))
return;
}
}
-10
View File
@@ -71,13 +71,3 @@ float CombatRecord::GetHealedReceivedPerSecond() const
double time_in_combat = TimeInCombat();
return time_in_combat > 0 ? (m_heal_received / time_in_combat) : m_heal_received;
}
int64 CombatRecord::GetDamageReceived() const
{
return m_damage_received;
}
int64 CombatRecord::GetHealReceived() const
{
return m_heal_received;
}
-2
View File
@@ -12,8 +12,6 @@ public:
bool InCombat() const;
void ProcessHPEvent(int64 hp, int64 current_hp);
double TimeInCombat() const;
int64 GetDamageReceived() const;
int64 GetHealReceived() const;
float GetDamageReceivedPerSecond() const;
float GetHealedReceivedPerSecond() const;
private:
+5 -2
View File
@@ -131,6 +131,7 @@ int command_init(void)
command_add("emptyinventory", "Clears your or your target's entire inventory (Equipment, General, Bank, and Shared Bank)", AccountStatus::GMImpossible, command_emptyinventory) ||
command_add("enablerecipe", "[Recipe ID] - Enables a Recipe", AccountStatus::QuestTroupe, command_enablerecipe) ||
command_add("endurance", "Restores your or your target's endurance.", AccountStatus::Guide, command_endurance) ||
command_add("entityvariable", "[clear|delete|set|view] - Modify entity variables for yourself or your target", AccountStatus::GMAdmin, command_entityvariable) ||
command_add("exptoggle", "[Toggle] - Toggle your or your target's experience gain.", AccountStatus::QuestTroupe, command_exptoggle) ||
command_add("faction", "[Find (criteria | all ) | Review (criteria | all) | Reset (id)] - Resets Player's Faction", AccountStatus::QuestTroupe, command_faction) ||
command_add("factionassociation", "[factionid] [amount] - triggers a faction hits via association", AccountStatus::GMLeadAdmin, command_faction_association) ||
@@ -140,6 +141,7 @@ int command_init(void)
command_add("findaliases", "[Search Criteria]- Searches for available command aliases, by alias or command", AccountStatus::Player, command_findaliases) ||
command_add("findcharacter", "[Search Criteria] - Search for a character", AccountStatus::Guide, command_findcharacter) ||
command_add("findclass", "[Search Criteria] - Search for a class", AccountStatus::Guide, command_findclass) ||
command_add("findcurrency", "[Search Criteria] - Search for an alternate currency", AccountStatus::Guide, command_findcurrency) ||
command_add("findfaction", "[Search Criteria] - Search for a faction", AccountStatus::Guide, command_findfaction) ||
command_add("findnpctype", "[Search Criteria] - Search database NPC types", AccountStatus::GMAdmin, command_findnpctype) ||
command_add("findrace", "[Search Criteria] - Search for a race", AccountStatus::Guide, command_findrace) ||
@@ -230,7 +232,7 @@ int command_init(void)
command_add("nukeitem", "[Item ID] - Removes the specified Item ID from you or your player target's inventory", AccountStatus::GMLeadAdmin, command_nukeitem) ||
command_add("object", "List|Add|Edit|Move|Rotate|Copy|Save|Undo|Delete - Manipulate static and tradeskill objects within the zone", AccountStatus::GMAdmin, command_object) ||
command_add("oocmute", "[0|1] - Enable or Disable Server OOC", AccountStatus::GMMgmt, command_oocmute) ||
command_add("opcode", "Reloads all server patches", AccountStatus::GMImpossible, command_opcode) ||
command_add("opcode", "Reloads all opcodes from server patch files", AccountStatus::GMMgmt, command_reload) ||
command_add("path", "view and edit pathing", AccountStatus::GMMgmt, command_path) ||
command_add("peekinv", "[equip/gen/cursor/poss/limbo/curlim/trib/bank/shbank/allbank/trade/world/all] - Print out contents of your player target's inventory", AccountStatus::GMAdmin, command_peekinv) ||
command_add("peqzone", "[Zone ID|Zone Short Name] - Teleports you to the specified zone if you meet the requirements.", AccountStatus::Player, command_peqzone) ||
@@ -976,12 +978,14 @@ void command_bot(Client *c, const Seperator *sep)
#include "gm_commands/emptyinventory.cpp"
#include "gm_commands/enablerecipe.cpp"
#include "gm_commands/endurance.cpp"
#include "gm_commands/entityvariable.cpp"
#include "gm_commands/exptoggle.cpp"
#include "gm_commands/faction.cpp"
#include "gm_commands/feature.cpp"
#include "gm_commands/findaa.cpp"
#include "gm_commands/findcharacter.cpp"
#include "gm_commands/findclass.cpp"
#include "gm_commands/findcurrency.cpp"
#include "gm_commands/findfaction.cpp"
#include "gm_commands/findnpctype.cpp"
#include "gm_commands/findrace.cpp"
@@ -1069,7 +1073,6 @@ void command_bot(Client *c, const Seperator *sep)
#include "gm_commands/nukeitem.cpp"
#include "gm_commands/object.cpp"
#include "gm_commands/oocmute.cpp"
#include "gm_commands/opcode.cpp"
#include "gm_commands/path.cpp"
#include "gm_commands/peekinv.cpp"
#include "gm_commands/peqzone.cpp"
+2 -1
View File
@@ -82,6 +82,7 @@ void command_emoteview(Client *c, const Seperator *sep);
void command_emptyinventory(Client *c, const Seperator *sep);
void command_enablerecipe(Client *c, const Seperator *sep);
void command_endurance(Client *c, const Seperator *sep);
void command_entityvariable(Client *c, const Seperator *sep);
void command_exptoggle(Client *c, const Seperator *sep);
void command_faction(Client *c, const Seperator *sep);
void command_faction_association(Client *c, const Seperator *sep);
@@ -90,6 +91,7 @@ void command_findaa(Client *c, const Seperator *sep);
void command_findaliases(Client *c, const Seperator *sep);
void command_findcharacter(Client *c, const Seperator *sep);
void command_findclass(Client *c, const Seperator *sep);
void command_findcurrency(Client *c, const Seperator *sep);
void command_findfaction(Client *c, const Seperator *sep);
void command_findnpctype(Client *c, const Seperator *sep);
void command_findrace(Client *c, const Seperator *sep);
@@ -180,7 +182,6 @@ void command_nukebuffs(Client *c, const Seperator *sep);
void command_nukeitem(Client *c, const Seperator *sep);
void command_object(Client *c, const Seperator *sep);
void command_oocmute(Client *c, const Seperator *sep);
void command_opcode(Client *c, const Seperator *sep);
#ifdef PACKET_PROFILER
void command_packetprofile(Client *c, const Seperator *sep);
-6
View File
@@ -14,13 +14,10 @@
#define _CLIENTCORPSE(x) (x && x->IsCorpse() && x->CastToCorpse()->IsPlayerCorpse() && !x->CastToCorpse()->IsBecomeNPCCorpse())
#define _NPCCORPSE(x) (x && x->IsCorpse() && (x->CastToCorpse()->IsNPCCorpse() || x->CastToCorpse()->IsBecomeNPCCorpse()))
#define _CLIENTPET(x) (x && x->CastToMob()->GetOwner() && x->CastToMob()->GetOwner()->IsClient())
#define _NPCPET(x) (x && x->IsNPC() && x->CastToMob()->GetOwner() && x->CastToMob()->GetOwner()->IsNPC())
#define _BECOMENPCPET(x) (x && x->CastToMob()->GetOwner() && x->CastToMob()->GetOwner()->IsClient() && x->CastToMob()->GetOwner()->CastToClient()->IsBecomeNPC())
//LOS Parameters:
#define HEAD_POSITION 0.9f //ratio of GetSize() where NPCs see from
#define SEE_POSITION 0.5f //ratio of GetSize() where NPCs try to see for LOS
#define CHECK_LOS_STEP 1.0f
#define ARCHETYPE_HYBRID 1
#define ARCHETYPE_CASTER 2
@@ -44,7 +41,6 @@
//Spell specialization parameters, not sure of a better place for them
#define SPECIALIZE_FIZZLE 11 //% fizzle chance reduce at 200 specialized
#define SPECIALIZE_MANA_REDUCE 12 //% mana cost reduction at 200 specialized
//these are large right now because the x,y,z coords of the zone
//lines do not make a lot of sense
@@ -232,7 +228,6 @@ enum GravityBehavior {
LevitateWhileRunning
};
struct TradeEntity;
class Trade;
enum TradeState {
TradeNone,
@@ -846,7 +841,6 @@ public:
virtual ~Trade();
void Reset();
void SetTradeCash(uint32 in_pp, uint32 in_gp, uint32 in_sp, uint32 in_cp);
// Initiate a trade with another mob
// Also puts other mob into trader mode with this mob
+3 -3
View File
@@ -623,13 +623,13 @@ void Doors::ForceOpen(Mob *sender, bool alt_mode)
if (!alt_mode) { // original function
if (!m_is_open) {
if (!m_disable_timer) {
LogDoorsDetail("door_id [{}] starting timer", md->doorid);
LogDoorsDetail("door_id [{}] starting timer", m_door_id);
m_close_timer.Start();
}
m_is_open = true;
}
else {
LogDoorsDetail("door_id [{}] disable timer", md->doorid);
LogDoorsDetail("door_id [{}] disable timer", m_door_id);
m_close_timer.Disable();
if (!m_disable_timer) {
m_is_open = false;
@@ -638,7 +638,7 @@ void Doors::ForceOpen(Mob *sender, bool alt_mode)
}
else { // alternative function
if (!m_disable_timer) {
LogDoorsDetail("door_id [{}] alt starting timer", md->doorid);
LogDoorsDetail("door_id [{}] alt starting timer", m_door_id);
m_close_timer.Start();
}
m_is_open = true;
+3 -3
View File
@@ -810,9 +810,9 @@ void Client::SendDisciplineUpdate() {
bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
// Dont let client waste a reuse timer if they can't use the disc
if ((IsStunned() && !IgnoreCastingRestriction(spell_id))||
if ((IsStunned() && !IsCastNotStandingSpell(spell_id))||
IsFeared() ||
(IsMezzed() && !IgnoreCastingRestriction(spell_id)) ||
(IsMezzed() && !IsCastNotStandingSpell(spell_id)) ||
IsAmnesiad() ||
IsPet())
{
@@ -837,7 +837,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
return false;
}
if (DivineAura() && !IgnoreCastingRestriction(spell_id)) {
if (DivineAura() && !IsCastNotStandingSpell(spell_id)) {
return false;
}
+17 -19
View File
@@ -179,6 +179,10 @@ const char *QuestEventSubroutines[_LargestEventID] = {
"EVENT_ITEM_CLICK_CAST_CLIENT",
"EVENT_DESTROY_ITEM_CLIENT",
"EVENT_DROP_ITEM_CLIENT",
"EVENT_MEMORIZE_SPELL",
"EVENT_UNMEMORIZE_SPELL",
"EVENT_SCRIBE_SPELL",
"EVENT_UNSCRIBE_SPELL",
// Add new events before these or Lua crashes
"EVENT_SPELL_EFFECT_BOT",
"EVENT_SPELL_EFFECT_BUFF_TIC_BOT"
@@ -835,25 +839,6 @@ void PerlembParser::ExportVar(const char *pkgprefix, const char *varname, float
}
}
void PerlembParser::ExportVarComplex(const char *pkgprefix, const char *varname, const char *value)
{
if (!perl) {
return;
}
try {
perl->eval(std::string("$").append(pkgprefix).append("::").append(varname).append("=").append(value).append(";").c_str());
}
catch (std::string e) {
AddError(
fmt::format(
"Error exporting Perl variable [{}]",
e
)
);
}
}
void PerlembParser::ExportVar(const char *pkgprefix, const char *varname, const char *value)
{
if (!perl) {
@@ -2179,6 +2164,19 @@ void PerlembParser::ExportEventVariables(
break;
}
case EVENT_MEMORIZE_SPELL:
case EVENT_UNMEMORIZE_SPELL:
case EVENT_SCRIBE_SPELL:
case EVENT_UNSCRIBE_SPELL: {
Seperator sep(data);
ExportVar(package_name.c_str(), "slot_id", sep.arg[0]);
ExportVar(package_name.c_str(), "spell_id", sep.arg[1]);
if (IsValidSpell(Strings::ToUnsignedInt(sep.arg[1]))) {
ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[Strings::ToUnsignedInt(sep.arg[1])]);
}
break;
}
default: {
break;
}
-1
View File
@@ -145,7 +145,6 @@ private:
void ExportVar(const char *pkgprefix, const char *varname, uint32 value);
void ExportVar(const char *pkgprefix, const char *varname, float value);
void ExportVar(const char* pkgprefix, const char* varname, const char* classname, void* value);
void ExportVarComplex(const char *pkgprefix, const char *varname, const char *value);
int EventCommon(
QuestEventID event,
+1474 -19
View File
File diff suppressed because it is too large Load Diff
+39 -6
View File
@@ -314,14 +314,47 @@ bool Embperl::SubExists(const char *package, const char *sub) {
return(hv_exists(stash, sub, len));
}
bool Embperl::VarExists(const char *package, const char *var) {
HV *stash = gv_stashpv(package, false);
if(!stash)
return(false);
int len = strlen(var);
return(hv_exists(stash, var, len));
#ifdef EMBPERL_IO_CAPTURE
XS(XS_EQEmuIO_PRINT); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQEmuIO_PRINT)
{
dXSARGS;
if (items < 2) {
return;
}
for (int r = 1; r < items; r++) {
char *str = SvPV_nolen(ST(r));
char *cur = str;
/* Strip newlines from log message 'str' */
*std::remove(str, str + strlen(str), '\n') = '\0';
std::string log_string = str;
if (
log_string.find("did not return a true") != std::string::npos ||
log_string.find("is experimental") != std::string::npos
) {
return;
}
for (int i = 0; *cur != '\0'; i++, cur++) {
if (*cur == '\n') {
LogQuests("{}", str);
}
}
if (!log_string.empty()) {
LogQuests("{}", log_string);
}
}
XSRETURN_EMPTY;
}
#endif //EMBPERL_IO_CAPTURE
#endif //EMBPERL
-26
View File
@@ -73,13 +73,6 @@ class Embperl
private:
//if we fail inside a script evaluation, this will hold the croak msg (not much help if we die during construction, but that's our own fault)
mutable std::string errmsg;
//kludgy workaround for the fact that we can't directly do something like SvIV(get_sv($big[0]{ass}->{struct}))
SV * my_get_sv(const char * varname) {
char buffer[256];
snprintf(buffer, 256, "if(defined(%s)) { $scratch::temp = %s; } else { $scratch::temp = 'UNDEF'; }", varname, varname);
eval(buffer);
return get_sv("scratch::temp", false);
}
//install a perl func
void init_eval_file(void);
@@ -97,25 +90,11 @@ public:
void Reinit();
//return the last error msg
std::string lasterr(void) const { return errmsg;};
//evaluate an expression. throws string errors on fail
int eval(const char * code);
//execute a subroutine. throws lasterr on failure
int dosub(const char * subname, const std::vector<std::string> * args = nullptr, int mode = G_SCALAR|G_EVAL);
//Access to perl variables
//all varnames here should be of the form package::name
//returns the contents of the perl variable named in varname as a c int
int geti(const char * varname) { return static_cast<int>(SvIV(my_get_sv(varname))); };
//returns the contents of the perl variable named in varname as a c float
float getd(const char * varname) { return static_cast<float>(SvNV(my_get_sv(varname)));};
//returns the contents of the perl variable named in varname as a string
std::string getstr(const char * varname) {
SV * temp = my_get_sv(varname);
return std::string(SvPV_nolen(temp),SvLEN(temp));
}
//put an integer into a perl varable
void seti(const char *varname, int val) const {
SV *t = get_sv(varname, true);
@@ -163,13 +142,8 @@ public:
//idea borrowed from perlembed
int eval_file(const char * packagename, const char * filename);
inline bool InUse() const { return(in_use); }
//check to see if a sub exists in package
bool SubExists(const char *package, const char *sub);
//check to see if a variable exists in package
bool VarExists(const char *package, const char *var);
};
#endif //EMBPERL
-95
View File
@@ -1,95 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef EMBPERL
#include "../common/global_define.h"
#include "../common/eqemu_logsys.h"
#include "embxs.h"
#include "embperl.h"
#include "masterentity.h"
#include "command.h"
const char *getItemName(unsigned itemid)
{
const EQ::ItemData* item = nullptr;
item = database.GetItem(itemid);
if (item)
return item->Name;
else
return nullptr;
}
const char* Perl__qc_getItemName(unsigned itemid)
{
return getItemName(itemid); // possible nullptr return
}
#ifdef EMBPERL_IO_CAPTURE
XS(XS_EQEmuIO_PRINT); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQEmuIO_PRINT)
{
dXSARGS;
if (items < 2)
return;
// Perl_croak(aTHX_ "Usage: EQEmuIO::PRINT(@strings)");
int r;
for (r = 1; r < items; r++) {
char *str = SvPV_nolen(ST(r));
char *cur = str;
/* Strip newlines from log message 'str' */
*std::remove(str, str + strlen(str), '\n') = '\0';
std::string log_string = str;
if (log_string.find("did not return a true") != std::string::npos) {
return;
}
if (log_string.find("is experimental") != std::string::npos) {
return;
}
int i;
int pos = 0;
int len = 0;
for (i = 0; *cur != '\0'; i++, cur++) {
if (*cur == '\n') {
LogQuests("{}", str);
len = 0;
pos = i + 1;
}
else {
len++;
}
}
if (!log_string.empty()) {
LogQuests("{}", log_string);
}
}
XSRETURN_EMPTY;
}
#endif //EMBPERL_IO_CAPTURE
#endif // EMBPERL

Some files were not shown because too many files have changed in this diff Show More