Compare commits

..

13 Commits

Author SHA1 Message Date
Aeadoin 25f5898bae [Release] 22.8.2 (#3161) 2023-03-30 09:22:58 -04:00
Aeadoin 934ff3dadf [Bug Fix] Correct logic checks for Bot rule AllowOwnerOptionAltCombat (#3158)
* [Bug Fix] Correct logic checks for Bot rule AllowOwnerOptionAltCombat

* fix ordering of raid/group checks
2023-03-30 08:31:57 -04:00
Aeadoin e4ff76dceb [Bug Fix] Fix for OOZ Group updates when removing/inviting Bots (#3159)
* [Bug Fix] Fix for Cross Zone Group updates with Bots when disbanding/joining groups.

* check for nullptr
2023-03-30 08:31:50 -04:00
Alex King 6960a1a682 [Bug Fix] Fix issues with Lua tables not starting at index 1 (#3160)
* [Bug Fix] Fix issues with Lua tables not starting at index 1

# Notes
- This would cause the first item in the table to be inaccessible since Lua tables start at index `1` instead of index `0`.
- All other spots using Lua tables have their indexes starting at `1`.

* Update lua_general.cpp
2023-03-30 06:02:53 -04:00
Aeadoin d4174ca236 [Fix] Fix strcpy-param-overlap (#3157) 2023-03-29 08:33:06 -04:00
Aeadoin 7854130a93 [Bug Fix] Check Rule "Bots Enabled" to prevent bot database calls on connect (#3154)
* [Bug Fix] Check for Rule "Bots Enabled" to prevent bot database calls if not enabled.

* formatting

* check if LoadBotsList failed, or is bots_list empty
2023-03-28 22:44:47 -04:00
Alex King e9c63c7d94 [Rules] Remove Guild Bank Zone ID Rule (#3156)
# notes
- This rule is useless as guild bank zone ID is hard-coded into the client.
2023-03-28 21:58:58 -04:00
Aeadoin 27e0665aae [Bug Fix] Fix bot_raid_members.sql for MYSQL. (#3155) 2023-03-28 15:25:16 -04:00
Alex King ea2f431fce [Fix] Fix an issue with EVENT_DISCONNECT not firing on regular /camp (#3153)
* [Fix] Fix an issue with EVENT_DISCONNECT not firing on regular /camp

# Notes
- We were only sending `EVENT_DISCONNECT` on GM instant camps or linkdeads.

* Update client_process.cpp
2023-03-27 21:45:02 -04:00
Aeadoin 8bdcf7cb94 [Crash] Add Checks for out of bounds & dereferencing nullptrs (#3151)
* [Crash] Add Checks for out of bounds/nullptr dereferences

* formatting

* formatting

* formatting

* Update bot.cpp

---------

Co-authored-by: Alex King <89047260+Kinglykrab@users.noreply.github.com>
2023-03-27 21:43:46 -04:00
Aeadoin 87cb74b851 [Release] 22.8.1 (#3152) 2023-03-27 17:55:48 -04:00
Alex King 26c267db1b [Cleanup] "equipped" not "equiped", "dual" not "duel". (#3149)
* [Cleanup] "equipped" not "equiped", "dual" not "duel".

# Notes
- These are spelled incorrectly.

* Update spdat.h

* Formatting further.

* Update api_service.cpp
2023-03-27 17:55:37 -04:00
Aeadoin 99f8e6cef5 [Bug Fix] Fix for NPCs having spells interrupted. (#3150) 2023-03-27 16:57:08 -04:00
30 changed files with 691 additions and 639 deletions
+30
View File
@@ -1,3 +1,33 @@
## [22.8.2] - 03/30/2023
### Code
* "equipped" not "equiped", "dual" not "duel". ([#3149](https://github.com/EQEmu/Server/pull/3149)) @Kinglykrab 2023-03-27
### Crash
* Add Checks for out of bounds & dereferencing nullptrs ([#3151](https://github.com/EQEmu/Server/pull/3151)) @Aeadoin 2023-03-28
### Fixes
* Check Rule "Bots Enabled" to prevent bot database calls on connect ([#3154](https://github.com/EQEmu/Server/pull/3154)) @Aeadoin 2023-03-29
* Correct logic checks for Bot rule AllowOwnerOptionAltCombat ([#3158](https://github.com/EQEmu/Server/pull/3158)) @Aeadoin 2023-03-30
* Fix an issue with EVENT_DISCONNECT not firing on regular /camp ([#3153](https://github.com/EQEmu/Server/pull/3153)) @Kinglykrab 2023-03-28
* Fix bot_raid_members.sql for MYSQL. ([#3155](https://github.com/EQEmu/Server/pull/3155)) @Aeadoin 2023-03-28
* Fix for OOZ Group updates when removing/inviting Bots ([#3159](https://github.com/EQEmu/Server/pull/3159)) @Aeadoin 2023-03-30
* Fix issues with Lua tables not starting at index 1 ([#3160](https://github.com/EQEmu/Server/pull/3160)) @Kinglykrab 2023-03-30
* Fix strcpy-param-overlap ([#3157](https://github.com/EQEmu/Server/pull/3157)) @Aeadoin 2023-03-29
### Rules
* Remove Guild Bank Zone ID Rule ([#3156](https://github.com/EQEmu/Server/pull/3156)) @Kinglykrab 2023-03-29
## [22.8.1] - 03/27/2023
### Fixes
* Fix for NPCs having spells interrupted. ([#3150](https://github.com/EQEmu/Server/pull/3150)) @Aeadoin 2023-03-27
## [22.8.0] - 03/25/2023
### Code
-1
View File
@@ -274,7 +274,6 @@ RULE_BOOL(World, EnableTutorialButton, true, "Setting whether the Tutorial butto
RULE_BOOL(World, EnableReturnHomeButton, true, "Setting whether the Return Home button should be active")
RULE_INT(World, MaxLevelForTutorial, 10, "The highest level with which you can enter the tutorial")
RULE_INT(World, TutorialZoneID, 189, "Zone ID of the tutorial")
RULE_INT(World, GuildBankZoneID, 345, "Zone ID of the guild bank")
RULE_INT(World, MinOfflineTimeToReturnHome, 21600, "Minimum offline time to activate the Return Home button. 21600 seconds is 6 Hours")
RULE_INT(World, MaxClientsPerIP, -1, "Maximum number of clients allowed to connect per IP address if account status is < AddMaxClientsStatus. Default value: -1 (feature disabled)")
RULE_INT(World, ExemptMaxClientsStatus, -1, "Exempt accounts from the MaxClientsPerIP and AddMaxClientsStatus rules, if their status is >= this value. Default value: -1 (feature disabled)")
+2 -2
View File
@@ -504,7 +504,7 @@ enum SpellRestriction
HAS_NO_ILLUSIONS_OF_GRANDEUR_BUFF = 12519, //
IS_HP_ABOVE_50_PCT = 16010, //
IS_HP_UNDER_50_PCT = 16031, //
IS_OFF_HAND_EQUIPED = 27672, // You must be wielding a weapon or shield in your offhand to use this ability.
IS_OFF_HAND_EQUIPPED = 27672, // You must be wielding a weapon or shield in your offhand to use this ability.
HAS_NO_PACT_OF_FATE_RECOURSE_BUFF = 29556, // This spell will not work while Pact of Fate Recourse is active. | caster restriction |
HAS_NO_SHROUD_OF_PRAYER_BUFF = 32339, // Your target cannot receive another Quiet Prayer this soon.
IS_MANA_BELOW_20_PCT = 38311, // This ability requires you to be at or below 20% of your maximum mana.
@@ -1211,7 +1211,7 @@ typedef enum {
#define SE_Double_Backstab_Front 473 // implemented - Chance to double backstab from front
#define SE_Pet_Crit_Melee_Damage_Pct_Owner 474 // implemenetd - Critical damage mod applied to pets from owner
#define SE_Trigger_Spell_Non_Item 475 // implemented - Trigger spell on cast only if not from item click.
#define SE_Weapon_Stance 476 // implemented, @Misc, Apply a specific spell buffs automatically depending 2Hander, Shield or Duel Wield is equiped, base: spellid, base: 0=2H 1=Shield 2=DW, max: none
#define SE_Weapon_Stance 476 // implemented, @Misc, Apply a specific spell buffs automatically depending 2Hander, Shield or Dual Wield is equipped, base: spellid, base: 0=2H 1=Shield 2=DW, max: none
#define SE_Hatelist_To_Top_Index 477 // Implemented - Chance to be set to top of rampage list
#define SE_Hatelist_To_Tail_Index 478 // Implemented - Chance to be set to bottom of rampage list
#define SE_Ff_Value_Min 479 // implemented, @Ff, Minimum base value of a spell that can be focused, base: spells to be focused base1 value
+1 -1
View File
@@ -25,7 +25,7 @@
// Build variables
// these get injected during the build pipeline
#define CURRENT_VERSION "22.8.0-dev" // always append -dev to the current version for custom-builds
#define CURRENT_VERSION "22.8.2-dev" // always append -dev to the current version for custom-builds
#define LOGIN_VERSION "0.8.0"
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "eqemu-server",
"version": "22.8.0",
"version": "22.8.2",
"repository": {
"type": "git",
"url": "https://github.com/EQEmu/Server.git"
@@ -1,4 +1,4 @@
DROP INDEX IF EXISTS `PRIMARY` ON `raid_members`;
CREATE UNIQUE INDEX IF NOT EXISTS `UNIQUE` ON `raid_members`(`name`);
DROP INDEX `PRIMARY` ON `raid_members`;
CREATE UNIQUE INDEX `UNIQUE` ON `raid_members`(`name`);
ALTER TABLE `raid_members` ADD COLUMN `bot_id` int(4) NOT NULL DEFAULT 0 AFTER `charid`;
ALTER TABLE `raid_members` ADD COLUMN `id` BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST;
ALTER TABLE `raid_members` ADD COLUMN `id` BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST;
+171 -171
View File
@@ -402,177 +402,177 @@ Json::Value ApiGetMobListDetail(EQ::Net::WebsocketServerConnection *connection,
/**
* Rest
*/
row["ac"] = mob->GetAC();
row["ac_softcap"] = mob->GetACSoftcap();
row["ac_sum"] = mob->ACSum();
row["active_light_type"] = mob->GetActiveLightType();
row["aggro_range"] = mob->GetAggroRange();
row["allow_beneficial"] = mob->GetAllowBeneficial();
row["animation"] = mob->GetAnimation();
row["assist_range"] = mob->GetAssistRange();
row["aura_slots"] = mob->GetAuraSlots();
row["base_fear_speed"] = mob->GetBaseFearSpeed();
row["base_runspeed"] = mob->GetBaseRunspeed();
row["base_size"] = mob->GetBaseSize();
row["base_walkspeed"] = mob->GetBaseWalkspeed();
row["beard"] = mob->GetBeard();
row["beard_color"] = mob->GetBeardColor();
row["best_melee_skill"] = mob->GetBestMeleeSkill();
row["calc_fear_resist_chance"] = mob->CalcFearResistChance();
row["calc_resist_chance_bonus"] = mob->CalcResistChanceBonus();
row["can_block_spell"] = mob->CanBlockSpell();
row["can_facestab"] = mob->CanFacestab();
row["casted_spell_inv_slot"] = mob->GetCastedSpellInvSlot();
row["casting_spell_id"] = mob->CastingSpellID();
row["charmed"] = mob->Charmed();
row["check_last_los_state"] = mob->CheckLastLosState();
row["class"] = mob->GetClass();
row["class_level_factor"] = mob->GetClassLevelFactor();
row["class_race_ac_bonus"] = mob->GetClassRaceACBonus();
row["compute_defense"] = mob->compute_defense();
row["count_dispellable_buffs"] = mob->CountDispellableBuffs();
row["cripp_blow_chance"] = mob->GetCrippBlowChance();
row["cur_wp"] = mob->GetCurWp();
row["cwp"] = mob->GetCWP();
row["cwpp"] = mob->GetCWPP();
row["divine_aura"] = mob->DivineAura();
row["dont_buff_me_before"] = mob->DontBuffMeBefore();
row["dont_cure_me_before"] = mob->DontCureMeBefore();
row["dont_dot_me_before"] = mob->DontDotMeBefore();
row["dont_heal_me_before"] = mob->DontHealMeBefore();
row["dont_root_me_before"] = mob->DontRootMeBefore();
row["dont_snare_me_before"] = mob->DontSnareMeBefore();
row["drakkin_details"] = mob->GetDrakkinDetails();
row["drakkin_heritage"] = mob->GetDrakkinHeritage();
row["drakkin_tattoo"] = mob->GetDrakkinTattoo();
row["emote_id"] = mob->GetEmoteID();
row["equipment_light_type"] = mob->GetEquipmentLightType();
row["eye_color1"] = mob->GetEyeColor1();
row["eye_color2"] = mob->GetEyeColor2();
row["fear_speed"] = mob->GetFearSpeed();
row["flurry_chance"] = mob->GetFlurryChance();
row["follow_can_run"] = mob->GetFollowCanRun();
row["follow_distance"] = mob->GetFollowDistance();
row["follow_id"] = mob->GetFollowID();
row["gender"] = mob->GetGender();
row["hair_color"] = mob->GetHairColor();
row["hair_style"] = mob->GetHairStyle();
row["has_active_song"] = mob->HasActiveSong();
row["has_assist_aggro"] = mob->HasAssistAggro();
row["has_died"] = mob->HasDied();
row["has_disc_buff"] = mob->HasDiscBuff();
row["has_endur_upkeep"] = mob->HasEndurUpkeep();
row["has_free_aura_slots"] = mob->HasFreeAuraSlots();
row["has_free_trap_slots"] = mob->HasFreeTrapSlots();
row["has_mgb"] = mob->HasMGB();
row["has_numhits"] = mob->HasNumhits();
row["has_pet"] = mob->HasPet();
row["has_pet_affinity"] = mob->HasPetAffinity();
row["has_primary_aggro"] = mob->HasPrimaryAggro();
row["has_project_illusion"] = mob->HasProjectIllusion();
row["has_projectile_attack"] = mob->HasProjectileAttack();
row["has_shield_equiped"] = mob->HasShieldEquiped();
row["has_special_abilities"] = mob->HasSpecialAbilities();
row["has_tar_reflection"] = mob->HasTargetReflection();
row["has_temp_pets_active"] = mob->HasTempPetsActive();
row["has_two_hand_blunt_equiped"] = mob->HasTwoHandBluntEquiped();
row["has_two_hander_equipped"] = mob->HasTwoHanderEquipped();
row["hate_summon"] = mob->HateSummon();
row["helm_texture"] = mob->GetHelmTexture();
row["hp"] = mob->GetHP();
row["improved_taunt"] = mob->ImprovedTaunt();
row["innate_light_type"] = mob->GetInnateLightType();
row["is_ai_controlled"] = mob->IsAIControlled();
row["is_amnesiad"] = mob->IsAmnesiad();
row["is_animation"] = mob->IsAnimation();
row["is_blind"] = mob->IsBlind();
row["is_casting"] = mob->IsCasting();
row["is_charmed"] = mob->IsCharmed();
row["is_destructible_object"] = mob->IsDestructibleObject();
row["is_engaged"] = mob->IsEngaged();
row["is_enraged"] = mob->IsEnraged();
row["is_familiar"] = mob->IsFamiliar();
row["is_feared"] = mob->IsFeared();
row["is_findable"] = mob->IsFindable();
row["is_focused"] = mob->IsFocused();
row["is_g_held"] = mob->IsGHeld();
row["is_grouped"] = mob->IsGrouped();
row["is_held"] = mob->IsHeld();
row["is_looting"] = mob->IsLooting();
row["is_melee_disabled"] = mob->IsMeleeDisabled();
row["is_mezzed"] = mob->IsMezzed();
row["is_moved"] = mob->IsMoved();
row["is_moving"] = mob->IsMoving();
row["is_no_cast"] = mob->IsNoCast();
row["is_off_hand_atk"] = mob->IsOffHandAtk();
row["is_pet_owner_client"] = mob->IsPetOwnerClient();
row["is_pet_regroup"] = mob->IsPetRegroup();
row["is_pet_stop"] = mob->IsPetStop();
row["is_pseudo_rooted"] = mob->IsPseudoRooted();
row["is_raid_grouped"] = mob->IsRaidGrouped();
row["is_rare_spawn"] = mob->IsRareSpawn();
row["is_roamer"] = mob->IsRoamer();
row["is_rooted"] = mob->IsRooted();
row["is_running"] = mob->IsRunning();
row["is_silenced"] = mob->IsSilenced();
row["is_stunned"] = mob->IsStunned();
row["is_tar_lock_pet"] = mob->IsTargetLockPet();
row["is_tarable"] = mob->IsTargetable();
row["is_tared"] = mob->IsTargeted();
row["is_temp_pet"] = mob->IsTempPet();
row["is_trackable"] = mob->IsTrackable();
row["item_hp_bonuses"] = mob->GetItemHPBonuses();
row["last_name"] = mob->GetLastName();
row["level"] = mob->GetLevel();
row["luclin_face"] = mob->GetLuclinFace();
row["mana"] = mob->GetMana();
row["mana_percent"] = mob->GetManaPercent();
row["mana_ratio"] = mob->GetManaRatio();
row["max_hp"] = mob->GetMaxHP();
row["max_mana"] = mob->GetMaxMana();
row["melee_mitigation"] = mob->GetMeleeMitigation();
row["mitigation_ac"] = mob->GetMitigationAC();
row["movespeed"] = mob->GetMovespeed();
row["name"] = mob->GetName();
row["next_hp_event"] = mob->GetNextHPEvent();
row["next_inc_hp_event"] = mob->GetNextIncHPEvent();
row["npc_assist_cap"] = mob->NPCAssistCap();
row["npc_type_id"] = mob->GetNPCTypeID();
row["orig_level"] = mob->GetOrigLevel();
row["orig_name"] = mob->GetOrigName();
row["owner_id"] = mob->GetOwnerID();
row["pet_id"] = mob->GetPetID();
row["pet_power"] = mob->GetPetPower();
row["pet_tar_lock_id"] = mob->GetPetTargetLockID();
row["qglobal"] = mob->GetQglobal();
row["race"] = mob->GetRace();
row["run_anim_speed"] = mob->GetRunAnimSpeed();
row["sanctuary"] = mob->Sanctuary();
row["see_hide"] = mob->SeeHide();
row["see_improved_hide"] = mob->SeeImprovedHide();
row["see_invisible"] = mob->SeeInvisible();
row["see_invisible_undead"] = mob->SeeInvisibleUndead();
row["size"] = mob->GetSize();
row["slow_mitigation"] = mob->GetSlowMitigation();
row["snared_amount"] = mob->GetSnaredAmount();
row["spawned"] = mob->Spawned();
row["spell_hp_bonuses"] = mob->GetSpellHPBonuses();
row["spell_light_type"] = mob->GetSpellLightType();
row["spell_power_distance_mod"] = mob->GetSpellPowerDistanceMod();
row["spell_x"] = mob->GetSpellX();
row["spell_y"] = mob->GetSpellY();
row["spell_z"] = mob->GetSpellZ();
row["tar_ring_x"] = mob->GetTargetRingX();
row["tar_ring_y"] = mob->GetTargetRingY();
row["tar_ring_z"] = mob->GetTargetRingZ();
row["temp_pet_count"] = mob->GetTempPetCount();
row["texture"] = mob->GetTexture();
row["trap_slots"] = mob->GetTrapSlots();
row["try_death_save"] = mob->TryDeathSave();
row["try_divine_save"] = mob->TryDivineSave();
row["try_spell_on_death"] = mob->TrySpellOnDeath();
row["update_active_light"] = mob->UpdateActiveLight();
row["wander_type"] = mob->GetWanderType();
row["ac"] = mob->GetAC();
row["ac_softcap"] = mob->GetACSoftcap();
row["ac_sum"] = mob->ACSum();
row["active_light_type"] = mob->GetActiveLightType();
row["aggro_range"] = mob->GetAggroRange();
row["allow_beneficial"] = mob->GetAllowBeneficial();
row["animation"] = mob->GetAnimation();
row["assist_range"] = mob->GetAssistRange();
row["aura_slots"] = mob->GetAuraSlots();
row["base_fear_speed"] = mob->GetBaseFearSpeed();
row["base_runspeed"] = mob->GetBaseRunspeed();
row["base_size"] = mob->GetBaseSize();
row["base_walkspeed"] = mob->GetBaseWalkspeed();
row["beard"] = mob->GetBeard();
row["beard_color"] = mob->GetBeardColor();
row["best_melee_skill"] = mob->GetBestMeleeSkill();
row["calc_fear_resist_chance"] = mob->CalcFearResistChance();
row["calc_resist_chance_bonus"] = mob->CalcResistChanceBonus();
row["can_block_spell"] = mob->CanBlockSpell();
row["can_facestab"] = mob->CanFacestab();
row["casted_spell_inv_slot"] = mob->GetCastedSpellInvSlot();
row["casting_spell_id"] = mob->CastingSpellID();
row["charmed"] = mob->Charmed();
row["check_last_los_state"] = mob->CheckLastLosState();
row["class"] = mob->GetClass();
row["class_level_factor"] = mob->GetClassLevelFactor();
row["class_race_ac_bonus"] = mob->GetClassRaceACBonus();
row["compute_defense"] = mob->compute_defense();
row["count_dispellable_buffs"] = mob->CountDispellableBuffs();
row["cripp_blow_chance"] = mob->GetCrippBlowChance();
row["cur_wp"] = mob->GetCurWp();
row["cwp"] = mob->GetCWP();
row["cwpp"] = mob->GetCWPP();
row["divine_aura"] = mob->DivineAura();
row["dont_buff_me_before"] = mob->DontBuffMeBefore();
row["dont_cure_me_before"] = mob->DontCureMeBefore();
row["dont_dot_me_before"] = mob->DontDotMeBefore();
row["dont_heal_me_before"] = mob->DontHealMeBefore();
row["dont_root_me_before"] = mob->DontRootMeBefore();
row["dont_snare_me_before"] = mob->DontSnareMeBefore();
row["drakkin_details"] = mob->GetDrakkinDetails();
row["drakkin_heritage"] = mob->GetDrakkinHeritage();
row["drakkin_tattoo"] = mob->GetDrakkinTattoo();
row["emote_id"] = mob->GetEmoteID();
row["equipment_light_type"] = mob->GetEquipmentLightType();
row["eye_color1"] = mob->GetEyeColor1();
row["eye_color2"] = mob->GetEyeColor2();
row["fear_speed"] = mob->GetFearSpeed();
row["flurry_chance"] = mob->GetFlurryChance();
row["follow_can_run"] = mob->GetFollowCanRun();
row["follow_distance"] = mob->GetFollowDistance();
row["follow_id"] = mob->GetFollowID();
row["gender"] = mob->GetGender();
row["hair_color"] = mob->GetHairColor();
row["hair_style"] = mob->GetHairStyle();
row["has_active_song"] = mob->HasActiveSong();
row["has_assist_aggro"] = mob->HasAssistAggro();
row["has_died"] = mob->HasDied();
row["has_disc_buff"] = mob->HasDiscBuff();
row["has_endur_upkeep"] = mob->HasEndurUpkeep();
row["has_free_aura_slots"] = mob->HasFreeAuraSlots();
row["has_free_trap_slots"] = mob->HasFreeTrapSlots();
row["has_mgb"] = mob->HasMGB();
row["has_numhits"] = mob->HasNumhits();
row["has_pet"] = mob->HasPet();
row["has_pet_affinity"] = mob->HasPetAffinity();
row["has_primary_aggro"] = mob->HasPrimaryAggro();
row["has_project_illusion"] = mob->HasProjectIllusion();
row["has_projectile_attack"] = mob->HasProjectileAttack();
row["has_shield_equipped"] = mob->HasShieldEquipped();
row["has_special_abilities"] = mob->HasSpecialAbilities();
row["has_tar_reflection"] = mob->HasTargetReflection();
row["has_temp_pets_active"] = mob->HasTempPetsActive();
row["has_two_hand_blunt_equipped"] = mob->HasTwoHandBluntEquipped();
row["has_two_hander_equipped"] = mob->HasTwoHanderEquipped();
row["hate_summon"] = mob->HateSummon();
row["helm_texture"] = mob->GetHelmTexture();
row["hp"] = mob->GetHP();
row["improved_taunt"] = mob->ImprovedTaunt();
row["innate_light_type"] = mob->GetInnateLightType();
row["is_ai_controlled"] = mob->IsAIControlled();
row["is_amnesiad"] = mob->IsAmnesiad();
row["is_animation"] = mob->IsAnimation();
row["is_blind"] = mob->IsBlind();
row["is_casting"] = mob->IsCasting();
row["is_charmed"] = mob->IsCharmed();
row["is_destructible_object"] = mob->IsDestructibleObject();
row["is_engaged"] = mob->IsEngaged();
row["is_enraged"] = mob->IsEnraged();
row["is_familiar"] = mob->IsFamiliar();
row["is_feared"] = mob->IsFeared();
row["is_findable"] = mob->IsFindable();
row["is_focused"] = mob->IsFocused();
row["is_g_held"] = mob->IsGHeld();
row["is_grouped"] = mob->IsGrouped();
row["is_held"] = mob->IsHeld();
row["is_looting"] = mob->IsLooting();
row["is_melee_disabled"] = mob->IsMeleeDisabled();
row["is_mezzed"] = mob->IsMezzed();
row["is_moved"] = mob->IsMoved();
row["is_moving"] = mob->IsMoving();
row["is_no_cast"] = mob->IsNoCast();
row["is_off_hand_atk"] = mob->IsOffHandAtk();
row["is_pet_owner_client"] = mob->IsPetOwnerClient();
row["is_pet_regroup"] = mob->IsPetRegroup();
row["is_pet_stop"] = mob->IsPetStop();
row["is_pseudo_rooted"] = mob->IsPseudoRooted();
row["is_raid_grouped"] = mob->IsRaidGrouped();
row["is_rare_spawn"] = mob->IsRareSpawn();
row["is_roamer"] = mob->IsRoamer();
row["is_rooted"] = mob->IsRooted();
row["is_running"] = mob->IsRunning();
row["is_silenced"] = mob->IsSilenced();
row["is_stunned"] = mob->IsStunned();
row["is_tar_lock_pet"] = mob->IsTargetLockPet();
row["is_tarable"] = mob->IsTargetable();
row["is_tared"] = mob->IsTargeted();
row["is_temp_pet"] = mob->IsTempPet();
row["is_trackable"] = mob->IsTrackable();
row["item_hp_bonuses"] = mob->GetItemHPBonuses();
row["last_name"] = mob->GetLastName();
row["level"] = mob->GetLevel();
row["luclin_face"] = mob->GetLuclinFace();
row["mana"] = mob->GetMana();
row["mana_percent"] = mob->GetManaPercent();
row["mana_ratio"] = mob->GetManaRatio();
row["max_hp"] = mob->GetMaxHP();
row["max_mana"] = mob->GetMaxMana();
row["melee_mitigation"] = mob->GetMeleeMitigation();
row["mitigation_ac"] = mob->GetMitigationAC();
row["movespeed"] = mob->GetMovespeed();
row["name"] = mob->GetName();
row["next_hp_event"] = mob->GetNextHPEvent();
row["next_inc_hp_event"] = mob->GetNextIncHPEvent();
row["npc_assist_cap"] = mob->NPCAssistCap();
row["npc_type_id"] = mob->GetNPCTypeID();
row["orig_level"] = mob->GetOrigLevel();
row["orig_name"] = mob->GetOrigName();
row["owner_id"] = mob->GetOwnerID();
row["pet_id"] = mob->GetPetID();
row["pet_power"] = mob->GetPetPower();
row["pet_tar_lock_id"] = mob->GetPetTargetLockID();
row["qglobal"] = mob->GetQglobal();
row["race"] = mob->GetRace();
row["run_anim_speed"] = mob->GetRunAnimSpeed();
row["sanctuary"] = mob->Sanctuary();
row["see_hide"] = mob->SeeHide();
row["see_improved_hide"] = mob->SeeImprovedHide();
row["see_invisible"] = mob->SeeInvisible();
row["see_invisible_undead"] = mob->SeeInvisibleUndead();
row["size"] = mob->GetSize();
row["slow_mitigation"] = mob->GetSlowMitigation();
row["snared_amount"] = mob->GetSnaredAmount();
row["spawned"] = mob->Spawned();
row["spell_hp_bonuses"] = mob->GetSpellHPBonuses();
row["spell_light_type"] = mob->GetSpellLightType();
row["spell_power_distance_mod"] = mob->GetSpellPowerDistanceMod();
row["spell_x"] = mob->GetSpellX();
row["spell_y"] = mob->GetSpellY();
row["spell_z"] = mob->GetSpellZ();
row["tar_ring_x"] = mob->GetTargetRingX();
row["tar_ring_y"] = mob->GetTargetRingY();
row["tar_ring_z"] = mob->GetTargetRingZ();
row["temp_pet_count"] = mob->GetTempPetCount();
row["texture"] = mob->GetTexture();
row["trap_slots"] = mob->GetTrapSlots();
row["try_death_save"] = mob->TryDeathSave();
row["try_divine_save"] = mob->TryDivineSave();
row["try_spell_on_death"] = mob->TrySpellOnDeath();
row["update_active_light"] = mob->UpdateActiveLight();
row["wander_type"] = mob->GetWanderType();
response.append(row);
}
+5 -5
View File
@@ -592,7 +592,7 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
}
// Try Shield Block OR TwoHandBluntBlockCheck
if (HasShieldEquiped() && (aabonuses.ShieldBlock || spellbonuses.ShieldBlock || itembonuses.ShieldBlock) && (InFront || bBlockFromRear)) {
if (HasShieldEquipped() && (aabonuses.ShieldBlock || spellbonuses.ShieldBlock || itembonuses.ShieldBlock) && (InFront || bBlockFromRear)) {
int chance = aabonuses.ShieldBlock + spellbonuses.ShieldBlock + itembonuses.ShieldBlock;
if (counter_block || counter_all) {
float counter = (counter_block + counter_all) / 100.0f;
@@ -604,7 +604,7 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
}
}
if (HasTwoHandBluntEquiped() && (aabonuses.TwoHandBluntBlock || spellbonuses.TwoHandBluntBlock || itembonuses.TwoHandBluntBlock) && (InFront || bBlockFromRear)) {
if (HasTwoHandBluntEquipped() && (aabonuses.TwoHandBluntBlock || spellbonuses.TwoHandBluntBlock || itembonuses.TwoHandBluntBlock) && (InFront || bBlockFromRear)) {
int chance = aabonuses.TwoHandBluntBlock + itembonuses.TwoHandBluntBlock + spellbonuses.TwoHandBluntBlock;
if (counter_block || counter_all) {
float counter = (counter_block + counter_all) / 100.0f;
@@ -874,7 +874,7 @@ int Mob::ACSum(bool skip_caps)
int ac = 0; // this should be base AC whenever shrouds come around
ac += itembonuses.AC; // items + food + tribute
int shield_ac = 0;
if (HasShieldEquiped() && IsOfClientBot()) {
if (HasShieldEquipped() && IsOfClientBot()) {
auto inst = (IsClient()) ? GetInv().GetItem(EQ::invslot::slotSecondary) : CastToBot()->GetBotItem(EQ::invslot::slotSecondary);
if (inst) {
if (inst->GetItemRecommendedLevel(true) <= GetLevel()) {
@@ -1555,7 +1555,7 @@ bool Mob::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
if (Hand == EQ::invslot::slotPrimary || Hand == EQ::invslot::slotSecondary)
my_hit.base_damage = DoDamageCaps(my_hit.base_damage);
auto shield_inc = spellbonuses.ShieldEquipDmgMod + itembonuses.ShieldEquipDmgMod + aabonuses.ShieldEquipDmgMod;
if (shield_inc > 0 && HasShieldEquiped() && Hand == EQ::invslot::slotPrimary) {
if (shield_inc > 0 && HasShieldEquipped() && Hand == EQ::invslot::slotPrimary) {
my_hit.base_damage = my_hit.base_damage * (100 + shield_inc) / 100;
hate = hate * (100 + shield_inc) / 100;
}
@@ -5995,7 +5995,7 @@ void Mob::DoShieldDamageOnShielder(Mob *shield_target, int64 hit_damage_done, EQ
}
int mitigation = shielder->GetShielderMitigation(); //Default shielder mitigates 25 pct of damage taken, this can be increased up to max 50 by equipping a shield item
if (shielder->IsClient() && shielder->HasShieldEquiped()) {
if (shielder->IsClient() && shielder->HasShieldEquipped()) {
EQ::ItemInstance* inst = shielder->CastToClient()->GetInv().GetItem(EQ::invslot::slotSecondary);
if (inst) {
const EQ::ItemData* shield = inst->GetItem();
+7 -7
View File
@@ -145,10 +145,10 @@ int Mob::CalcRecommendedLevelBonus(uint8 current_level, uint8 recommended_level,
void Mob::CalcItemBonuses(StatBonuses* b) {
ClearItemFactionBonuses();
SetShieldEquiped(false);
SetTwoHandBluntEquiped(false);
SetShieldEquipped(false);
SetTwoHandBluntEquipped(false);
SetTwoHanderEquipped(false);
SetDuelWeaponsEquiped(false);
SetDualWeaponsEquipped(false);
int16 i;
@@ -178,13 +178,13 @@ void Mob::CalcItemBonuses(StatBonuses* b) {
item->ItemType == EQ::item::ItemTypeShield &&
i == EQ::invslot::slotSecondary
) {
SetShieldEquiped(true);
SetShieldEquipped(true);
} else if (
item &&
item->ItemType == EQ::item::ItemType2HBlunt &&
i == EQ::invslot::slotPrimary
) {
SetTwoHandBluntEquiped(true);
SetTwoHandBluntEquipped(true);
SetTwoHanderEquipped(true);
} else if (
item &&
@@ -196,7 +196,7 @@ void Mob::CalcItemBonuses(StatBonuses* b) {
}
if (CanThisClassDualWield()) {
SetDuelWeaponsEquiped(true);
SetDualWeaponsEquipped(true);
}
if (IsOfClientBot()) {
@@ -5864,4 +5864,4 @@ float Mob::CheckHeroicBonusesDataBuckets(std::string bucket_name)
}
return Strings::ToFloat(bucket_value);
}
}
+241 -244
View File
@@ -1112,7 +1112,7 @@ void Bot::GenerateAppearance() {
uint16 Bot::GetPrimarySkillValue() {
EQ::skills::SkillType skill = EQ::skills::HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill
if (bool equiped = m_inv.GetItem(EQ::invslot::slotPrimary); !equiped) {
if (bool equipped = m_inv.GetItem(EQ::invslot::slotPrimary); !equipped) {
skill = EQ::skills::SkillHandtoHand;
} else {
uint8 type = m_inv.GetItem(EQ::invslot::slotPrimary)->GetItem()->ItemType; //is this the best way to do this?
@@ -2735,18 +2735,15 @@ void Bot::CalcMeleeDistances(const Mob* tar, const EQ::ItemInstance* const& p_it
bool Bot::IsValidTarget(Client* bot_owner, Client* leash_owner, float lo_distance, float leash_distance, bool bo_alt_combat, Mob* tar, float tar_distance) {
if (HOLDING ||
!tar->IsNPC() ||
tar->IsMezzed() ||
lo_distance > leash_distance ||
tar_distance > leash_distance ||
(!GetAttackingFlag() && !CheckLosFN(tar) && !leash_owner->CheckLosFN(tar)) || // This is suppose to keep bots from attacking things behind walls
!IsAttackAllowed(tar) ||
(bo_alt_combat &&
(!GetAttackingFlag() && NOT_PULLING_BOT && !leash_owner->AutoAttackEnabled() && !tar->GetHateAmount(this) && !tar->GetHateAmount(leash_owner))
)
)
{
if (!tar || !bot_owner || !leash_owner) {
return false;
}
bool valid_target_state = HOLDING || !tar->IsNPC() || tar->IsMezzed() || lo_distance > leash_distance || tar_distance > leash_distance;
bool valid_target = !GetAttackingFlag() && !CheckLosFN(tar) && !leash_owner->CheckLosFN(tar);
bool valid_bo_target = !GetAttackingFlag() && NOT_PULLING_BOT && !leash_owner->AutoAttackEnabled() && !tar->GetHateAmount(this) && !tar->GetHateAmount(leash_owner);
if (valid_target_state || valid_target || !IsAttackAllowed(tar) || (bo_alt_combat && valid_bo_target)) {
// Normally, we wouldn't want to do this without class checks..but, too many issues can arise if we let enchanter animation pets run rampant
if (HasPet()) {
GetPet()->RemoveFromHateList(tar);
@@ -2810,12 +2807,13 @@ void Bot::AcquireBotTarget(Group* bot_group, Raid* raid, Client* leash_owner, fl
Mob* assist_mob = nullptr;
bool find_target = true;
if (bot_group) {
assist_mob = entity_list.GetMob(bot_group->GetMainAssistName());
}
else if (raid) {
if (raid) {
assist_mob = raid->GetRaidMainAssistOne();
}
else if (bot_group) {
assist_mob = entity_list.GetMob(bot_group->GetMainAssistName());
}
if (assist_mob) {
if (assist_mob->GetTarget()) {
@@ -2947,24 +2945,10 @@ void Bot::SetBotTarget(Client* bot_owner, Raid* raid, Group* bot_group, Client*
if (bo_alt_combat && m_alt_combat_hate_timer.Check(false)) {
// Empty hate list - let's find some aggro
if (!IsEngaged() && NOT_HOLDING && NOT_PASSIVE && (!bot_owner->GetBotPulling() || NOT_PULLING_BOT)) {
if (bot_owner->IsEngaged() && !IsEngaged() && NOT_HOLDING && NOT_PASSIVE && (!bot_owner->GetBotPulling() || NOT_PULLING_BOT)) {
SetLeashOwnerTarget(leash_owner, bot_owner, lo_distance, leash_distance);
}
else if (bot_group) {
for (const auto& bg_member: bot_group->members) {
if (!bg_member) {
continue;
}
auto bgm_target = bg_member->GetTarget();
if (!bgm_target || !bgm_target->IsNPC()) {
continue;
}
SetBotGroupTarget(bot_owner, leash_owner, lo_distance, leash_distance, bg_member, bgm_target);
}
}
else if (raid) {
else if (!IsEngaged() && raid) {
for (const auto& raid_member : raid->members) {
if (!raid_member.member) {
continue;
@@ -2977,6 +2961,19 @@ void Bot::SetBotTarget(Client* bot_owner, Raid* raid, Group* bot_group, Client*
SetBotGroupTarget(bot_owner, leash_owner, lo_distance, leash_distance, raid_member.member, rm_target);
}
}
else if (!IsEngaged() && bot_group) {
for (const auto& bg_member: bot_group->members) {
if (!bg_member) {
continue;
}
auto bgm_target = bg_member->GetTarget();
if (!bgm_target || !bgm_target->IsNPC()) {
continue;
}
SetBotGroupTarget(bot_owner, leash_owner, lo_distance, leash_distance, bg_member, bgm_target);
}
}
}
}
@@ -3314,14 +3311,11 @@ bool Bot::Spawn(Client* botCharacterOwner) {
}
}
Raid* raid = nullptr;
Group* group = nullptr;
if (raid = entity_list.GetRaidByBotName(GetName())) {
if (auto raid = entity_list.GetRaidByBotName(GetName())) {
raid->VerifyRaid();
SetRaidGrouped(true);
}
else if (group = entity_list.GetGroupByMobName(GetName())) {
else if (auto group = entity_list.GetGroupByMobName(GetName())) {
group->VerifyGroup();
SetGrouped(true);
}
@@ -3840,6 +3834,7 @@ bool Bot::RemoveBotFromGroup(Bot* bot, Group* group) {
if (!group->IsLeader(bot)) {
bot->SetFollowID(0);
if (group->DelMember(bot)) {
group->DelMemberOOZ(bot->GetName());
database.SetGroupID(bot->GetCleanName(), 0, bot->GetBotID());
if (group->GroupCount() < 1) {
group->DisbandGroup();
@@ -3862,8 +3857,12 @@ bool Bot::RemoveBotFromGroup(Bot* bot, Group* group) {
}
bool Bot::AddBotToGroup(Bot* bot, Group* group) {
bool Result = false;
if (bot && group && group->AddMember(bot)) {
bool result = false;
if (!group || group->GroupCount() >= MAX_GROUP_MEMBERS) {
return result;
}
if (bot && group->AddMember(bot)) {
if (group->GetLeader()) {
bot->SetFollowID(group->GetLeader()->GetID());
// Need to send this only once when a group is formed with a bot so the client knows it is also the group leader
@@ -3874,9 +3873,10 @@ bool Bot::AddBotToGroup(Bot* bot, Group* group) {
}
}
group->VerifyGroup();
Result = true;
group->SendGroupJoinOOZ(bot);
result = true;
}
return Result;
return result;
}
// Completes a trade with a client bot owner
@@ -4562,56 +4562,66 @@ bool Bot::Death(Mob *killerMob, int64 damage, uint16 spell_id, EQ::skills::Skill
if (entity_list.GetCorpseByID(GetID()))
entity_list.GetCorpseByID(GetID())->Depop();
Group *g = GetGroup();
if (g) {
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (g->members[i]) {
if (g->members[i] == this) {
// If the leader dies, make the next bot the leader
// and reset all bots followid
if (g->IsLeader(g->members[i])) {
if (g->members[i + 1]) {
g->SetLeader(g->members[i + 1]);
g->members[i + 1]->SetFollowID(g->members[i]->GetFollowID());
for (int j = 0; j < MAX_GROUP_MEMBERS; j++) {
if (g->members[j] && (g->members[j] != g->members[i + 1]))
g->members[j]->SetFollowID(g->members[i + 1]->GetID());
if (HasRaid()) {
if (auto raid = entity_list.GetRaidByBotName(GetName()); raid) {
for (auto& m: raid->members) {
if (strcmp(m.member_name, GetName()) == 0) {
m.member = nullptr;
}
}
}
}
else if (HasGroup()) {
if (auto g = GetGroup()) {
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (g->members[i]) {
if (g->members[i] == this) {
// If the leader dies, make the next bot the leader
// and reset all bots followid
if (g->IsLeader(g->members[i])) {
if (g->members[i + 1]) {
g->SetLeader(g->members[i + 1]);
g->members[i + 1]->SetFollowID(g->members[i]->GetFollowID());
for (int j = 0; j < MAX_GROUP_MEMBERS; j++) {
if (g->members[j] && (g->members[j] != g->members[i + 1]))
g->members[j]->SetFollowID(g->members[i + 1]->GetID());
}
}
}
}
// delete from group data
RemoveBotFromGroup(this, g);
//Make sure group still exists if it doesnt they were already updated in RemoveBotFromGroup
g = GetGroup();
if (!g)
break;
// delete from group data
RemoveBotFromGroup(this, g);
//Make sure group still exists if it doesnt they were already updated in RemoveBotFromGroup
g = GetGroup();
if (!g)
break;
// if group members exist below this one, move
// them all up one slot in the group list
int j = (i + 1);
for (; j < MAX_GROUP_MEMBERS; j++) {
if (g->members[j]) {
g->members[j-1] = g->members[j];
strcpy(g->membername[j-1], g->members[j]->GetCleanName());
g->membername[j][0] = '\0';
memset(g->membername[j], 0, 64);
g->members[j] = nullptr;
// if group members exist below this one, move
// them all up one slot in the group list
int j = (i + 1);
for (; j < MAX_GROUP_MEMBERS; j++) {
if (g->members[j]) {
g->members[j - 1] = g->members[j];
strcpy(g->membername[j - 1], g->members[j]->GetCleanName());
g->membername[j][0] = '\0';
memset(g->membername[j], 0, 64);
g->members[j] = nullptr;
}
}
}
// update the client group
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
GroupJoin_Struct* gu = (GroupJoin_Struct*)outapp->pBuffer;
gu->action = groupActLeave;
strcpy(gu->membername, GetCleanName());
if (g) {
for (int k = 0; k < MAX_GROUP_MEMBERS; k++) {
if (g->members[k] && g->members[k]->IsClient())
g->members[k]->CastToClient()->QueuePacket(outapp);
// update the client group
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
GroupJoin_Struct* gu = (GroupJoin_Struct*) outapp->pBuffer;
gu->action = groupActLeave;
strcpy(gu->membername, GetCleanName());
if (g) {
for (int k = 0; k < MAX_GROUP_MEMBERS; k++) {
if (g->members[k] && g->members[k]->IsClient())
g->members[k]->CastToClient()->QueuePacket(outapp);
}
}
safe_delete(outapp);
}
safe_delete(outapp);
}
}
}
@@ -4623,18 +4633,6 @@ bool Bot::Death(Mob *killerMob, int64 damage, uint16 spell_id, EQ::skills::Skill
my_owner->CastToClient()->SetBotPulling(false);
}
if (auto raid = entity_list.GetRaidByBotName(GetName()); raid)
{
for (auto& m : raid->members)
{
if (strcmp(m.member_name, GetName()) == 0)
{
m.member = nullptr;
}
}
}
if (parse->BotHasQuestSub(EVENT_DEATH_COMPLETE)) {
const auto& export_string = fmt::format(
"{} {} {} {}",
@@ -4870,7 +4868,7 @@ int Bot::GetBaseSkillDamage(EQ::skills::SkillType skill, Mob *target)
float skill_bonus = skill_level / 10.0f;
float ac_bonus = 0.0f;
const EQ::ItemInstance *inst = nullptr;
if (HasShieldEquiped())
if (HasShieldEquipped())
inst = GetBotItem(EQ::invslot::slotSecondary);
else if (HasTwoHanderEquipped())
inst = GetBotItem(EQ::invslot::slotPrimary);
@@ -6667,8 +6665,7 @@ void Bot::Camp(bool save_to_database) {
}
void Bot::Zone() {
Raid* raid = entity_list.GetRaidByBotName(GetName());
if (raid) {
if (auto raid = entity_list.GetRaidByBotName(GetName())) {
raid->MemberZoned(CastToClient());
}
else if (HasGroup()) {
@@ -6856,7 +6853,7 @@ Bot* Bot::GetBotByBotClientOwnerAndBotName(Client* c, const std::string& botName
}
void Bot::ProcessBotGroupInvite(Client* c, std::string const& botName) {
if (c) {
if (c && !c->HasRaid()) {
Bot* invitedBot = GetBotByBotClientOwnerAndBotName(c, botName);
if (invitedBot && !invitedBot->HasGroup() && !invitedBot->HasRaid()) {
@@ -6872,13 +6869,8 @@ void Bot::ProcessBotGroupInvite(Client* c, std::string const& botName) {
delete g;
}
} else {
AddBotToGroup(invitedBot, c->GetGroup());
database.SetGroupID(invitedBot->GetCleanName(), c->GetGroup()->GetID(), invitedBot->GetBotID());
}
if (c->HasRaid() && c->HasGroup()) {
Raid* raid = entity_list.GetRaidByClient(c);
if (raid) {
raid->AddBot(invitedBot, raid->GetGroup(c), false, false, false);
if (AddBotToGroup(invitedBot, c->GetGroup())) {
database.SetGroupID(invitedBot->GetCleanName(), c->GetGroup()->GetID(), invitedBot->GetBotID());
}
}
} else if (invitedBot->HasGroup()) {
@@ -7106,46 +7098,13 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
uint8 botCasterClass = caster->GetClass();
if (iSpellTypes == SpellType_Heal) {
if ( botCasterClass == CLERIC || botCasterClass == DRUID || botCasterClass == SHAMAN) {
if (caster->HasGroup()) {
Group *g = caster->GetGroup();
if (g) {
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (g->members[i] && !g->members[i]->qglobal) {
if (g->members[i]->IsClient() && g->members[i]->GetHPRatio() < 90) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if ((g->members[i]->GetClass() == WARRIOR || g->members[i]->GetClass() == PALADIN || g->members[i]->GetClass() == SHADOWKNIGHT) && g->members[i]->GetHPRatio() < 95) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if (g->members[i]->GetClass() == ENCHANTER && g->members[i]->GetHPRatio() < 80) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if (g->members[i]->GetHPRatio() < 70) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
}
}
if (g->members[i] && !g->members[i]->qglobal && g->members[i]->HasPet() && g->members[i]->GetPet()->GetHPRatio() < 50) {
if (g->members[i]->GetPet()->GetOwner() != caster && caster->IsEngaged() && g->members[i]->IsCasting() && g->members[i]->GetClass() != ENCHANTER )
continue;
if (caster->AICastSpell(g->members[i]->GetPet(), 100, SpellType_Heal))
return true;
}
}
}
}
else if (caster->IsRaidGrouped())
{
//added raid check
if (botCasterClass == CLERIC || botCasterClass == DRUID || botCasterClass == SHAMAN) {
if (caster->IsRaidGrouped()) {
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
uint32 gid = raid->GetGroup(caster->GetName());
if (gid < MAX_RAID_GROUPS) {
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
//for (auto& iter : raid->GetRaidGroupMembers(g)) {
if (iter->member && !iter->member->qglobal) {
if (iter->member->IsClient() && iter->member->GetHPRatio() < 90) {
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
@@ -7176,6 +7135,37 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
}
}
}
else if (caster->HasGroup()) {
Group *g = caster->GetGroup();
if (g) {
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (g->members[i] && !g->members[i]->qglobal) {
if (g->members[i]->IsClient() && g->members[i]->GetHPRatio() < 90) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if ((g->members[i]->GetClass() == WARRIOR || g->members[i]->GetClass() == PALADIN || g->members[i]->GetClass() == SHADOWKNIGHT) && g->members[i]->GetHPRatio() < 95) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if (g->members[i]->GetClass() == ENCHANTER && g->members[i]->GetHPRatio() < 80) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if (g->members[i]->GetHPRatio() < 70) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
}
}
if (g->members[i] && !g->members[i]->qglobal && g->members[i]->HasPet() && g->members[i]->GetPet()->GetHPRatio() < 50) {
if (g->members[i]->GetPet()->GetOwner() != caster && caster->IsEngaged() && g->members[i]->IsCasting() && g->members[i]->GetClass() != ENCHANTER )
continue;
if (caster->AICastSpell(g->members[i]->GetPet(), 100, SpellType_Heal))
return true;
}
}
}
}
}
if ((botCasterClass == PALADIN || botCasterClass == BEASTLORD || botCasterClass == RANGER) && (caster->HasGroup() || caster->IsRaidGrouped())) {
@@ -7195,70 +7185,78 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
hpRatioToHeal = 25.0f;
break;
}
Group* g = caster->GetGroup();
uint32 gid = RAID_GROUPLESS;
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
if (raid) {
gid = raid->GetGroup(caster->GetName());
}
if (caster->IsRaidGrouped()) {
if (auto raid = entity_list.GetRaidByBotName(caster->GetName())) {
uint32 gid = RAID_GROUPLESS;
gid = raid->GetGroup(caster->GetName());
if (gid < MAX_RAID_GROUPS) {
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin();
iter != raid_group_members.end(); ++iter) {
if (iter->member && !iter->member->qglobal) {
if (iter->member->IsClient() && iter->member->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
return true;
} else if (
(iter->member->GetClass() == WARRIOR || iter->member->GetClass() == PALADIN ||
iter->member->GetClass() == SHADOWKNIGHT) &&
iter->member->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
return true;
} else if (iter->member->GetClass() == ENCHANTER &&
iter->member->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
return true;
} else if (iter->member->GetHPRatio() < hpRatioToHeal / 2) {
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
return true;
}
}
if (g) {
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (g->members[i] && !g->members[i]->qglobal) {
if (g->members[i]->IsClient() && g->members[i]->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if ((g->members[i]->GetClass() == WARRIOR || g->members[i]->GetClass() == PALADIN || g->members[i]->GetClass() == SHADOWKNIGHT) && g->members[i]->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if (g->members[i]->GetClass() == ENCHANTER && g->members[i]->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if (g->members[i]->GetHPRatio() < hpRatioToHeal/2) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
if (iter->member && !iter->member->qglobal && iter->member->HasPet() &&
iter->member->GetPet()->GetHPRatio() < 25) {
if (iter->member->GetPet()->GetOwner() != caster && caster->IsEngaged() &&
iter->member->IsCasting() && iter->member->GetClass() != ENCHANTER)
continue;
if (caster->AICastSpell(iter->member->GetPet(), 100, SpellType_Heal))
return true;
}
}
}
if (g->members[i] && !g->members[i]->qglobal && g->members[i]->HasPet() && g->members[i]->GetPet()->GetHPRatio() < 25) {
if (g->members[i]->GetPet()->GetOwner() != caster && caster->IsEngaged() && g->members[i]->IsCasting() && g->members[i]->GetClass() != ENCHANTER )
continue;
if (caster->AICastSpell(g->members[i]->GetPet(), 100, SpellType_Heal))
return true;
}
}
}
else if (gid < MAX_RAID_GROUPS)
{
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
//for (auto& iter : raid->GetRaidGroupMembers(gid)) {
if (iter->member && !iter->member->qglobal) {
if (iter->member->IsClient() && iter->member->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
return true;
else if (caster->HasGroup()) {
if (auto g = caster->GetGroup()) {
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (g->members[i] && !g->members[i]->qglobal) {
if (g->members[i]->IsClient() && g->members[i]->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if ((g->members[i]->GetClass() == WARRIOR || g->members[i]->GetClass() == PALADIN ||
g->members[i]->GetClass() == SHADOWKNIGHT) &&
g->members[i]->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if (g->members[i]->GetClass() == ENCHANTER &&
g->members[i]->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
} else if (g->members[i]->GetHPRatio() < hpRatioToHeal / 2) {
if (caster->AICastSpell(g->members[i], 100, SpellType_Heal))
return true;
}
}
else if ((iter->member->GetClass() == WARRIOR || iter->member->GetClass() == PALADIN || iter->member->GetClass() == SHADOWKNIGHT) && iter->member->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
return true;
}
else if (iter->member->GetClass() == ENCHANTER && iter->member->GetHPRatio() < hpRatioToHeal) {
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
return true;
}
else if (iter->member->GetHPRatio() < hpRatioToHeal / 2) {
if (caster->AICastSpell(iter->member, 100, SpellType_Heal))
return true;
}
}
if (iter->member && !iter->member->qglobal && iter->member->HasPet() && iter->member->GetPet()->GetHPRatio() < 25) {
if (iter->member->GetPet()->GetOwner() != caster && caster->IsEngaged() && iter->member->IsCasting() && iter->member->GetClass() != ENCHANTER)
continue;
if (g->members[i] && !g->members[i]->qglobal && g->members[i]->HasPet() &&
g->members[i]->GetPet()->GetHPRatio() < 25) {
if (g->members[i]->GetPet()->GetOwner() != caster && caster->IsEngaged() &&
g->members[i]->IsCasting() && g->members[i]->GetClass() != ENCHANTER)
continue;
if (caster->AICastSpell(iter->member->GetPet(), 100, SpellType_Heal))
return true;
if (caster->AICastSpell(g->members[i]->GetPet(), 100, SpellType_Heal))
return true;
}
}
}
}
@@ -7300,8 +7298,29 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
}
}
if ( iSpellTypes == SpellType_Cure) {
if (caster->HasGroup()) {
if (iSpellTypes == SpellType_Cure) {
if (caster->IsRaidGrouped()) {
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
uint32 gid = raid->GetGroup(caster->GetName());
if (gid < MAX_RAID_GROUPS) {
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
if (iter->member && caster->GetNeedsCured(iter->member)) {
if (caster->AICastSpell(iter->member, caster->GetChanceToCastBySpellType(SpellType_Cure), SpellType_Cure))
return true;
else if (botCasterClass == BARD) {
return false;
}
}
if (iter->member && iter->member->GetPet() && caster->GetNeedsCured(iter->member->GetPet())) {
if (caster->AICastSpell(iter->member->GetPet(), (int)caster->GetChanceToCastBySpellType(SpellType_Cure) / 4, SpellType_Cure))
return true;
}
}
}
}
else if (caster->HasGroup()) {
Group *g = caster->GetGroup();
if (g) {
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
@@ -7319,46 +7338,13 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
}
}
}
else if (caster->IsRaidGrouped())
{
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
uint32 gid = raid->GetGroup(caster->GetName());
if (gid < MAX_RAID_GROUPS) {
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(gid);
for (std::vector<RaidMember>::iterator iter = raid_group_members.begin(); iter != raid_group_members.end(); ++iter) {
if (iter->member && caster->GetNeedsCured(iter->member)) {
if (caster->AICastSpell(iter->member, caster->GetChanceToCastBySpellType(SpellType_Cure), SpellType_Cure))
return true;
else if (botCasterClass == BARD)
return false;
}
if (iter->member && iter->member->GetPet() && caster->GetNeedsCured(iter->member->GetPet())) {
if (caster->AICastSpell(iter->member->GetPet(), (int)caster->GetChanceToCastBySpellType(SpellType_Cure) / 4, SpellType_Cure))
return true;
}
}
}
}
}
if (iSpellTypes == SpellType_HateRedux) {
if (!caster->IsEngaged())
return false;
if (caster->HasGroup()) {
Group *g = caster->GetGroup();
if (g) {
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (g->members[i] && caster->GetNeedsHateRedux(g->members[i])) {
if (caster->AICastSpell(g->members[i], caster->GetChanceToCastBySpellType(SpellType_HateRedux), SpellType_HateRedux))
return true;
}
}
}
}
else if (caster->IsRaidGrouped())
{
if (caster->IsRaidGrouped()) {
Raid* raid = entity_list.GetRaidByBotName(caster->GetName());
uint32 gid = raid->GetGroup(caster->GetName());
if (gid < MAX_RAID_GROUPS) {
@@ -7371,7 +7357,17 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
}
}
}
else if (caster->HasGroup()) {
Group *g = caster->GetGroup();
if (g) {
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (g->members[i] && caster->GetNeedsHateRedux(g->members[i])) {
if (caster->AICastSpell(g->members[i], caster->GetChanceToCastBySpellType(SpellType_HateRedux), SpellType_HateRedux))
return true;
}
}
}
}
}
if (iSpellTypes == SpellType_PreCombatBuff) {
@@ -8354,11 +8350,12 @@ void Bot::SpawnBotGroupByName(Client* c, const std::string& botgroup_name, uint3
}
}
if (group) {
group->VerifyGroup();
} else if (raid) {
if (raid) {
raid->VerifyRaid();
}
else if (group) {
group->VerifyGroup();
}
c->Message(
Chat::White,
@@ -8944,6 +8941,12 @@ bool Bot::CheckSpawnConditions(Client* c) {
return false;
}
Raid* raid = entity_list.GetRaidByClient(c);
if (raid && raid->IsEngaged()) {
c->Message(Chat::White, "You cannot spawn bots while your raid is engaged.");
return false;
}
auto* owner_group = c->GetGroup();
if (owner_group) {
std::list<Client*> member_list;
@@ -8963,12 +8966,6 @@ bool Bot::CheckSpawnConditions(Client* c) {
}
}
Raid* raid = entity_list.GetRaidByClient(c);
if (raid && raid->IsEngaged()) {
c->Message(Chat::White, "You cannot spawn bots while your raid is engaged.");
return false;
}
return true;
}
+32
View File
@@ -17,6 +17,8 @@
*/
#include "bot.h"
#include "bot_command.h"
#include "client.h"
#include "object.h"
#include "raids.h"
#include "doors.h"
@@ -186,6 +188,10 @@ void Bot::ProcessRaidInvite(Mob* invitee, Client* invitor, bool group_invite) {
Raid* raid = entity_list.GetRaidByClient(invitor);
if (raid && raid->RaidCount() >= MAX_RAID_MEMBERS) {
invitor->MessageString(Chat::Red, RAID_IS_FULL);
return;
}
Bot::CreateBotRaid(invitee, invitor, group_invite, raid);
}
@@ -296,4 +302,30 @@ void Bot::ProcessBotGroupAdd(Group* group, Raid* raid, Client* client, bool new_
raid->GroupUpdate(raid_free_group_id);
}
void Client::SpawnRaidBotsOnConnect(Raid* raid) {
std::list<BotsAvailableList> bots_list;
if (!database.botdb.LoadBotsList(CharacterID(), bots_list) || bots_list.empty()) {
return;
}
std::vector<RaidMember> r_members = raid->GetMembers();
for (const auto& m: r_members) {
if (strlen(m.member_name) != 0) {
for (const auto& b: bots_list) {
if (strcmp(m.member_name, b.Name) == 0) {
std::string buffer = "^spawn ";
buffer.append(m.member_name);
bot_command_real_dispatch(this, buffer.c_str());
auto bot = entity_list.GetBotByBotName(m.member_name);
if (bot) {
bot->SetRaidGrouped(true);
bot->p_raid_instance = raid;
}
}
}
}
}
}
+20 -20
View File
@@ -806,7 +806,7 @@ void Client::QueuePacket(const EQApplicationPacket* app, bool ack_req, CLIENT_CO
AddPacket(app, ack_req);
return;
}
// if the program doesnt care about the status or if the status isnt what we requested
if (required_state != CLIENT_CONNECTINGALL && client_state != required_state) {
// todo: save packets for later use
@@ -825,7 +825,7 @@ void Client::FastQueuePacket(EQApplicationPacket** app, bool ack_req, CLIENT_CON
return;
}
else {
if(eqs)
if(eqs)
eqs->FastQueuePacket((EQApplicationPacket **)app, ack_req);
else if (app && (*app))
delete *app;
@@ -1328,7 +1328,7 @@ void Client::ChannelMessageSend(const char* from, const char* to, uint8 chan_num
cm->chan_num = chan_num;
strcpy(&cm->message[0], buffer);
QueuePacket(&app);
bool senderCanTrainSelf = RuleB(Client, SelfLanguageLearning);
@@ -4162,7 +4162,7 @@ bool Client::GroupFollow(Client* inviter) {
if (iraid == raid) {
//both in same raid
uint32 ngid = raid->GetGroup(inviter->GetName());
if (raid->GroupCount(ngid) < 6) {
if (raid->GroupCount(ngid) < MAX_GROUP_MEMBERS) {
raid->MoveMember(GetName(), ngid);
raid->SendGroupDisband(this);
raid->GroupUpdate(ngid);
@@ -4183,7 +4183,7 @@ bool Client::GroupFollow(Client* inviter) {
if (!GetXTargetAutoMgr()->empty())
SetDirtyAutoHaters();
if (raid->GroupCount(groupToUse) < 6)
if (raid->GroupCount(groupToUse) < MAX_GROUP_MEMBERS)
{
raid->SendRaidCreate(this);
raid->SendMakeLeaderPacketTo(raid->leadername, this);
@@ -4323,9 +4323,9 @@ bool Client::GroupFollow(Client* inviter) {
uint16 Client::GetPrimarySkillValue()
{
EQ::skills::SkillType skill = EQ::skills::HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill
bool equiped = m_inv.GetItem(EQ::invslot::slotPrimary);
bool equipped = m_inv.GetItem(EQ::invslot::slotPrimary);
if (!equiped)
if (!equipped)
skill = EQ::skills::SkillHandtoHand;
else {
@@ -10710,11 +10710,11 @@ void Client::ApplyWeaponsStance()
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
}
else if (!HasShieldEquiped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
else if (!HasShieldEquipped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
}
else if (!HasDualWeaponsEquiped() &&
else if (!HasDualWeaponsEquipped() &&
IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
BuffFadeBySpellID(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
@@ -10726,14 +10726,14 @@ void Client::ApplyWeaponsStance()
}
weaponstance.spellbonus_buff_spell_id = spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
}
else if (HasShieldEquiped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
else if (HasShieldEquipped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
if (!FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
SpellOnTarget(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
}
weaponstance.spellbonus_buff_spell_id = spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
}
else if (HasDualWeaponsEquiped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
else if (HasDualWeaponsEquipped() && IsBuffSpell(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
if (!FindBuff(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
SpellOnTarget(spellbonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
@@ -10776,11 +10776,11 @@ void Client::ApplyWeaponsStance()
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H])) {
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
}
else if (!HasShieldEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
else if (!HasShieldEquipped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
}
else if (!HasDualWeaponsEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
else if (!HasDualWeaponsEquipped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
BuffFadeBySpellID(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
}
@@ -10793,14 +10793,14 @@ void Client::ApplyWeaponsStance()
}
weaponstance.itembonus_buff_spell_id = itembonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
}
else if (HasShieldEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
else if (HasShieldEquipped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
if (!FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
SpellOnTarget(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
}
weaponstance.itembonus_buff_spell_id = itembonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
}
else if (HasDualWeaponsEquiped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
else if (HasDualWeaponsEquipped() && IsBuffSpell(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
if (!FindBuff(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
SpellOnTarget(itembonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
}
@@ -10833,12 +10833,12 @@ void Client::ApplyWeaponsStance()
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H]);
}
else if (!HasShieldEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
else if (!HasShieldEquipped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]) &&
FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD]);
}
else if (!HasDualWeaponsEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
else if (!HasDualWeaponsEquipped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]) &&
FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
BuffFadeBySpellID(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD]);
}
@@ -10851,14 +10851,14 @@ void Client::ApplyWeaponsStance()
weaponstance.aabonus_buff_spell_id = aabonuses.WeaponStance[WEAPON_STANCE_TYPE_2H];
}
else if (HasShieldEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
else if (HasShieldEquipped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
if (!FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD])) {
SpellOnTarget(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD], this);
}
weaponstance.aabonus_buff_spell_id = aabonuses.WeaponStance[WEAPON_STANCE_TYPE_SHIELD];
}
else if (HasDualWeaponsEquiped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
else if (HasDualWeaponsEquipped() && IsBuffSpell(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
if (!FindBuff(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD])) {
SpellOnTarget(aabonuses.WeaponStance[WEAPON_STANCE_TYPE_DUAL_WIELD], this);
@@ -12174,4 +12174,4 @@ void Client::PlayerTradeEventLog(Trade *t, Trade *t2)
RecordPlayerEventLogWithClient(trader, PlayerEvent::TRADE, e);
RecordPlayerEventLogWithClient(trader2, PlayerEvent::TRADE, e);
}
}
+2 -2
View File
@@ -588,7 +588,7 @@ public:
//This calculates total Attack Rating to match very close to what the client should show
uint32 GetTotalATK();
uint32 GetATKRating();
//This gets the skill value of the item type equiped in the Primary Slot
//This gets the skill value of the item type equipped in the Primary Slot
uint16 GetPrimarySkillValue();
bool Flurry();
@@ -2033,6 +2033,7 @@ public:
void SetBotSpawnLimit(int new_spawn_limit, uint8 class_id = NO_CLASS);
void CampAllBots(uint8 class_id = NO_CLASS);
void SpawnRaidBotsOnConnect(Raid* raid);
private:
bool bot_owner_options[_booCount];
@@ -2042,7 +2043,6 @@ private:
bool CanTradeFVNoDropItem();
void SendMobPositions();
void PlayerTradeEventLog(Trade *t, Trade *t2);
};
#endif
+7 -27
View File
@@ -607,28 +607,8 @@ void Client::CompleteConnect()
if (raid) {
SetRaidGrouped(true);
raid->LearnMembers();
std::list<BotsAvailableList> bots_list;
database.botdb.LoadBotsList(this->CharacterID(), bots_list);
std::vector<RaidMember> r_members = raid->GetMembers();
for (const RaidMember& iter : r_members) {
if (iter.member_name) {
for (const BotsAvailableList& b_iter : bots_list)
{
if (strcmp(iter.member_name, b_iter.Name) == 0)
{
char buffer[71] = "^spawn ";
strcat(buffer, iter.member_name);
bot_command_real_dispatch(this, buffer);
Bot* b = entity_list.GetBotByBotName(iter.member_name);
if (b)
{
b->SetRaidGrouped(true);
b->p_raid_instance = raid;
//b->SetFollowID(this->GetID());
}
}
}
}
if (RuleB(Bots, Enabled)) {
SpawnRaidBotsOnConnect(raid);
}
raid->VerifyRaid();
raid->GetRaidDetails();
@@ -867,7 +847,7 @@ void Client::CompleteConnect()
CalcItemScale();
DoItemEnterZone();
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks)
if (zone->GetZoneID() == Zones::GUILDHALL && GuildBanks)
GuildBanks->SendGuildBank(this);
if (ClientVersion() >= EQ::versions::ClientVersion::SoD)
@@ -1426,7 +1406,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
}
}
m_pp.guildrank = rank;
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID))
if (zone->GetZoneID() == Zones::GUILDHALL)
GuildBanker = (guild_mgr.IsGuildLeader(GuildID(), CharacterID()) || guild_mgr.GetBankerFlag(CharacterID()));
}
m_pp.guildbanker = GuildBanker;
@@ -7446,7 +7426,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
if (!GuildBanks)
return;
if ((int)zone->GetZoneID() != RuleI(World, GuildBankZoneID))
if (zone->GetZoneID() != Zones::GUILDHALL)
{
Message(Chat::Red, "The Guild Bank is not available in this zone.");
@@ -7796,7 +7776,7 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app)
{
Message(Chat::Yellow, "You are now the leader of %s", GuildName);
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks)
if (zone->GetZoneID() == Zones::GUILDHALL && GuildBanks)
GuildBanks->SendGuildBank(this);
SendGuildRanks();
}
@@ -8126,7 +8106,7 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app)
Message(Chat::Red, "There was an error during the invite, DB may now be inconsistent.");
return;
}
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks)
if (zone->GetZoneID() == Zones::GUILDHALL && GuildBanks)
GuildBanks->SendGuildBank(this);
}
}
+21 -21
View File
@@ -689,61 +689,61 @@ bool Client::Process() {
/* Just a set of actions preformed all over in Client::Process */
void Client::OnDisconnect(bool hard_disconnect) {
if(hard_disconnect)
{
if (hard_disconnect) {
LeaveGroup();
if (GetMerc())
{
if (GetMerc()) {
GetMerc()->Save();
GetMerc()->Depop();
}
Raid *MyRaid = entity_list.GetRaidByClient(this);
if (MyRaid)
MyRaid->MemberZoned(this);
auto* r = entity_list.GetRaidByClient(this);
RecordPlayerEventLog(PlayerEvent::WENT_OFFLINE, PlayerEvent::EmptyEvent{});
if (parse->PlayerHasQuestSub(EVENT_DISCONNECT)) {
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
if (r) {
r->MemberZoned(this);
}
/* QS: PlayerLogConnectDisconnect */
if (RuleB(QueryServ, PlayerLogConnectDisconnect)){
if (RuleB(QueryServ, PlayerLogConnectDisconnect)) {
std::string event_desc = StringFormat("Disconnect :: in zoneid:%i instid:%i", GetZoneID(), GetInstanceID());
QServ->PlayerLogEvent(Player_Log_Connect_State, CharacterID(), event_desc);
}
}
if (!bZoning)
{
if (!bZoning) {
SetDynamicZoneMemberStatus(DynamicZoneMemberStatus::Offline);
}
RemoveAllAuras();
Mob *Other = trade->With();
if(Other)
{
auto* o = trade->With();
if (o) {
LogTrading("Client disconnected during a trade. Returning their items");
FinishTrade(this);
if(Other->IsClient())
Other->CastToClient()->FinishTrade(Other);
if (o->IsClient()) {
o->CastToClient()->FinishTrade(o);
}
/* Reset both sides of the trade */
trade->Reset();
Other->trade->Reset();
o->trade->Reset();
}
database.SetFirstLogon(CharacterID(), 0); //We change firstlogon status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world.
/* Remove ourself from all proximities */
/* Remove from all proximities */
ClearAllProximities();
auto outapp = new EQApplicationPacket(OP_LogoutReply);
FastQueuePacket(&outapp);
RecordPlayerEventLog(PlayerEvent::WENT_OFFLINE, PlayerEvent::EmptyEvent{});
if (parse->PlayerHasQuestSub(EVENT_DISCONNECT)) {
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
}
Disconnect();
}
+1 -1
View File
@@ -236,7 +236,7 @@ void Client::RefreshGuildInfo()
guild_id = info.guild_id;
GuildBanker = info.banker || guild_mgr.IsGuildLeader(GuildID(), CharacterID());
if(((int)zone->GetZoneID() == RuleI(World, GuildBankZoneID)))
if(zone->GetZoneID() == Zones::GUILDHALL)
{
if(WasBanker != GuildBanker)
{
+2 -2
View File
@@ -2828,7 +2828,7 @@ luabind::object Lua_Client::GetPEQZoneFlags(lua_State* L) {
if (d_) {
auto self = reinterpret_cast<NativeType*>(d_);
auto l = self->GetPEQZoneFlags();
auto i = 0;
auto i = 1;
for (const auto& f : l) {
t[i] = f;
i++;
@@ -2843,7 +2843,7 @@ luabind::object Lua_Client::GetZoneFlags(lua_State* L) {
if (d_) {
auto self = reinterpret_cast<NativeType*>(d_);
auto l = self->GetZoneFlags();
auto i = 0;
auto i = 1;
for (const auto& f : l) {
t[i] = f;
i++;
+3 -3
View File
@@ -1017,7 +1017,7 @@ luabind::adl::object lua_get_instance_ids(lua_State* L, std::string zone_name) {
auto instance_ids = quest_manager.GetInstanceIDs(zone_name);
for (int i = 0; i < instance_ids.size(); i++) {
ret[i] = instance_ids[i];
ret[i + 1] = instance_ids[i];
}
return ret;
@@ -1028,7 +1028,7 @@ luabind::adl::object lua_get_instance_ids_by_char_id(lua_State* L, std::string z
auto instance_ids = quest_manager.GetInstanceIDs(zone_name, character_id);
for (int i = 0; i < instance_ids.size(); i++) {
ret[i] = instance_ids[i];
ret[i + 1] = instance_ids[i];
}
return ret;
@@ -4182,7 +4182,7 @@ luabind::scope lua_register_general() {
luabind::def("get_instance_id", &lua_get_instance_id),
luabind::def("get_instance_id_by_char_id", &lua_get_instance_id_by_char_id),
luabind::def("get_instance_ids", &lua_get_instance_ids),
luabind::def("get_instance_ids_by_char_id", &lua_get_instance_id_by_char_id),
luabind::def("get_instance_ids_by_char_id", &lua_get_instance_ids_by_char_id),
luabind::def("get_instance_timer", &lua_get_instance_timer),
luabind::def("get_instance_timer_by_id", &lua_get_instance_timer_by_id),
luabind::def("get_instance_version_by_id", &lua_get_instance_version_by_id),
+7 -7
View File
@@ -2170,14 +2170,14 @@ bool Lua_Mob::IsTargetable() {
return self->IsTargetable();
}
bool Lua_Mob::HasShieldEquiped() {
bool Lua_Mob::HasShieldEquipped() {
Lua_Safe_Call_Bool();
return self->HasShieldEquiped();
return self->HasShieldEquipped();
}
bool Lua_Mob::HasTwoHandBluntEquiped() {
bool Lua_Mob::HasTwoHandBluntEquipped() {
Lua_Safe_Call_Bool();
return self->HasTwoHandBluntEquiped();
return self->HasTwoHandBluntEquipped();
}
bool Lua_Mob::HasTwoHanderEquipped() {
@@ -2709,7 +2709,7 @@ luabind::object Lua_Mob::GetEntityVariables(lua_State* L) {
if (d_) {
auto self = reinterpret_cast<NativeType*>(d_);
auto l = self->GetEntityVariables();
auto i = 0;
auto i = 1;
for (const auto& v : l) {
t[i] = v;
i++;
@@ -3321,9 +3321,9 @@ luabind::scope lua_register_mob() {
.def("HasOwner", (bool(Lua_Mob::*)(void))&Lua_Mob::HasOwner)
.def("HasPet", (bool(Lua_Mob::*)(void))&Lua_Mob::HasPet)
.def("HasProcs", &Lua_Mob::HasProcs)
.def("HasShieldEquiped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasShieldEquiped)
.def("HasShieldEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasShieldEquipped)
.def("HasTimer", &Lua_Mob::HasTimer)
.def("HasTwoHandBluntEquiped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHandBluntEquiped)
.def("HasTwoHandBluntEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHandBluntEquipped)
.def("HasTwoHanderEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHanderEquipped)
.def("Heal", &Lua_Mob::Heal)
.def("HealDamage", (void(Lua_Mob::*)(uint64))&Lua_Mob::HealDamage)
+2 -2
View File
@@ -431,8 +431,8 @@ public:
uint8 GetNimbusEffect2();
uint8 GetNimbusEffect3();
bool IsTargetable();
bool HasShieldEquiped();
bool HasTwoHandBluntEquiped();
bool HasShieldEquipped();
bool HasTwoHandBluntEquipped();
bool HasTwoHanderEquipped();
uint32 GetHerosForgeModel(uint8 material_slot);
uint32 IsEliteMaterialItem(uint8 material_slot);
+1 -1
View File
@@ -173,7 +173,7 @@ luabind::object Lua_Object::GetEntityVariables(lua_State* L) {
if (d_) {
auto self = reinterpret_cast<NativeType*>(d_);
auto l = self->GetEntityVariables();
auto i = 0;
auto i = 1;
for (const auto& v : l) {
t[i] = v;
i++;
+55 -59
View File
@@ -131,36 +131,40 @@ Mob::Mob(
mMovementManager = &MobMovementManager::Get();
mMovementManager->AddMob(this);
targeted = 0;
targeted = 0;
currently_fleeing = false;
AI_Init();
SetMoving(false);
moved = false;
turning = false;
m_RewindLocation = glm::vec3();
moved = false;
turning = false;
m_RewindLocation = glm::vec3();
m_RelativePosition = glm::vec4();
name[0] = 0;
name[0] = 0;
orig_name[0] = 0;
clean_name[0] = 0;
lastname[0] = 0;
if (in_name) {
strn0cpy(name, in_name, 64);
strn0cpy(orig_name, in_name, 64);
}
if (in_lastname) {
strn0cpy(lastname, in_lastname, 64);
}
current_hp = in_cur_hp;
current_hp = in_cur_hp;
max_hp = in_max_hp;
base_hp = in_max_hp;
gender = in_gender;
race = in_race;
base_gender = in_gender;
base_race = in_race;
use_model = in_usemodel;
use_model = in_usemodel;
class_ = in_class;
bodytype = in_bodytype;
orig_bodytype = in_bodytype;
@@ -185,8 +189,7 @@ Mob::Mob(
fearspeed = 0.625f;
base_fearspeed = 25;
// npcs
}
else {
} else {
base_walkspeed = base_runspeed * 100 / 265;
walkspeed = ((float) base_walkspeed) * 0.025f;
base_fearspeed = base_runspeed * 100 / 127;
@@ -200,7 +203,6 @@ Mob::Mob(
m_PlayerState = 0;
// sanity check
if (runspeed < 0 || runspeed > 20) {
runspeed = 1.25f;
@@ -220,38 +222,33 @@ Mob::Mob(
feettexture = in_feettexture;
multitexture = (armtexture || bracertexture || handtexture || legtexture || feettexture);
haircolor = in_haircolor;
beardcolor = in_beardcolor;
eyecolor1 = in_eyecolor1;
eyecolor2 = in_eyecolor2;
hairstyle = in_hairstyle;
luclinface = in_luclinface;
beard = in_beard;
drakkin_heritage = in_drakkin_heritage;
drakkin_tattoo = in_drakkin_tattoo;
drakkin_details = in_drakkin_details;
attack_speed = 0;
attack_delay = 0;
slow_mitigation = 0;
findable = false;
trackable = true;
has_shieldequiped = false;
has_twohandbluntequiped = false;
has_twohanderequipped = false;
has_duelweaponsequiped = false;
can_facestab = false;
has_numhits = false;
has_MGB = false;
has_ProjectIllusion = false;
SpellPowerDistanceMod = 0;
last_los_check = false;
haircolor = in_haircolor;
beardcolor = in_beardcolor;
eyecolor1 = in_eyecolor1;
eyecolor2 = in_eyecolor2;
hairstyle = in_hairstyle;
luclinface = in_luclinface;
beard = in_beard;
drakkin_heritage = in_drakkin_heritage;
drakkin_tattoo = in_drakkin_tattoo;
drakkin_details = in_drakkin_details;
attack_speed = 0;
attack_delay = 0;
slow_mitigation = 0;
findable = false;
trackable = true;
has_shield_equipped = false;
has_two_hand_blunt_equipped = false;
has_two_hander_equipped = false;
has_dual_weapons_equipped = false;
can_facestab = false;
has_numhits = false;
has_MGB = false;
has_ProjectIllusion = false;
SpellPowerDistanceMod = 0;
last_los_check = false;
if (in_aa_title > 0) {
aa_title = in_aa_title;
}
else {
aa_title = 0xFF;
}
aa_title = in_aa_title > 0 ? in_aa_title : 0xFF;
AC = in_ac;
ATK = in_atk;
@@ -428,24 +425,24 @@ Mob::Mob(
permarooted = (runspeed > 0) ? false : true;
pause_timer_complete = false;
ForcedMovement = 0;
roamer = false;
rooted = false;
charmed = false;
ForcedMovement = 0;
roamer = false;
rooted = false;
charmed = false;
weaponstance.enabled = false;
weaponstance.spellbonus_enabled = false; //Set when bonus is applied
weaponstance.itembonus_enabled = false; //Set when bonus is applied
weaponstance.aabonus_enabled = false; //Controlled by function TogglePassiveAA
weaponstance.enabled = false;
weaponstance.spellbonus_enabled = false; //Set when bonus is applied
weaponstance.itembonus_enabled = false; //Set when bonus is applied
weaponstance.aabonus_enabled = false; //Controlled by function TogglePassiveAA
weaponstance.spellbonus_buff_spell_id = 0;
weaponstance.itembonus_buff_spell_id = 0;
weaponstance.aabonus_buff_spell_id = 0;
weaponstance.itembonus_buff_spell_id = 0;
weaponstance.aabonus_buff_spell_id = 0;
pStandingPetOrder = SPO_Follow;
pseudo_rooted = false;
nobuff_invisible = 0;
see_invis = 0;
see_invis = 0;
innate_see_invis = GetSeeInvisibleLevelFromNPCStat(in_see_invis);
see_invis_undead = GetSeeInvisibleLevelFromNPCStat(in_see_invis_undead);
@@ -492,19 +489,19 @@ Mob::Mob(
}
for (int i = 0; i < MAX_APPEARANCE_EFFECTS; i++) {
appearance_effects_id[i] = 0;
appearance_effects_id[i] = 0;
appearance_effects_slot[i] = 0;
}
emoteid = 0;
endur_upkeep = false;
degenerating_effects = false;
PrimaryAggro = false;
AssistAggro = false;
npc_assist_cap = 0;
PrimaryAggro = false;
AssistAggro = false;
npc_assist_cap = 0;
use_double_melee_round_dmg_bonus = false;
dw_same_delay = 0;
dw_same_delay = 0;
queue_wearchange_slot = -1;
@@ -1138,7 +1135,6 @@ void Mob::SetSpawnLastNameByClass(NewSpawn_Struct* ns)
strcpy(ns->spawn.lastName, "Mercenary Liaison");
break;
default:
strcpy(ns->spawn.lastName, ns->spawn.lastName);
break;
}
}
@@ -7141,4 +7137,4 @@ int Mob::DispatchZoneControllerEvent(
}
return ret;
}
}
+12 -12
View File
@@ -484,19 +484,19 @@ public:
void TempName(const char *newname = nullptr);
void SetTargetable(bool on);
bool IsTargetable() const { return m_targetable; }
bool HasShieldEquiped() const { return has_shieldequiped; }
inline void SetShieldEquiped(bool val) { has_shieldequiped = val; }
bool HasTwoHandBluntEquiped() const { return has_twohandbluntequiped; }
inline void SetTwoHandBluntEquiped(bool val) { has_twohandbluntequiped = val; }
bool HasTwoHanderEquipped() { return has_twohanderequipped; }
void SetTwoHanderEquipped(bool val) { has_twohanderequipped = val; }
bool HasDualWeaponsEquiped() const { return has_duelweaponsequiped; }
bool HasShieldEquipped() const { return has_shield_equipped; }
inline void SetShieldEquipped(bool val) { has_shield_equipped = val; }
bool HasTwoHandBluntEquipped() const { return has_two_hand_blunt_equipped; }
inline void SetTwoHandBluntEquipped(bool val) { has_two_hand_blunt_equipped = val; }
bool HasTwoHanderEquipped() { return has_two_hander_equipped; }
void SetTwoHanderEquipped(bool val) { has_two_hander_equipped = val; }
bool HasDualWeaponsEquipped() const { return has_dual_weapons_equipped; }
bool HasBowEquipped() const { return has_bowequipped; }
void SetBowEquipped(bool val) { has_bowequipped = val; }
bool HasArrowEquipped() const { return has_arrowequipped; }
void SetArrowEquipped(bool val) { has_arrowequipped = val; }
bool HasBowAndArrowEquipped() const { return HasBowEquipped() && HasArrowEquipped(); }
inline void SetDuelWeaponsEquiped(bool val) { has_duelweaponsequiped = val; }
inline void SetDualWeaponsEquipped(bool val) { has_dual_weapons_equipped = val; }
bool CanFacestab() { return can_facestab; }
void SetFacestab(bool val) { can_facestab = val; }
virtual uint8 ConvertItemTypeToSkillID(uint8 item_type);
@@ -1699,10 +1699,10 @@ protected:
bool silenced;
bool amnesiad;
bool offhand;
bool has_shieldequiped;
bool has_twohandbluntequiped;
bool has_twohanderequipped;
bool has_duelweaponsequiped;
bool has_shield_equipped;
bool has_two_hand_blunt_equipped;
bool has_two_hander_equipped;
bool has_dual_weapons_equipped;
bool has_bowequipped = false;
bool has_arrowequipped = false;
bool use_double_melee_round_dmg_bonus;
+6 -6
View File
@@ -2273,14 +2273,14 @@ bool Perl_Mob_IsTargetable(Mob* self) // @categories Stats and Attributes
return self->IsTargetable();
}
bool Perl_Mob_HasShieldEquiped(Mob* self) // @categories Stats and Attributes
bool Perl_Mob_HasShieldEquipped(Mob* self) // @categories Stats and Attributes
{
return self->HasShieldEquiped();
return self->HasShieldEquipped();
}
bool Perl_Mob_HasTwoHandBluntEquiped(Mob* self) // @categories Stats and Attributes
bool Perl_Mob_HasTwoHandBluntEquipped(Mob* self) // @categories Stats and Attributes
{
return self->HasTwoHandBluntEquiped();
return self->HasTwoHandBluntEquipped();
}
bool Perl_Mob_HasTwoHanderEquipped(Mob* self) // @categories Stats and Attributes
@@ -3257,9 +3257,9 @@ void perl_register_mob()
package.add("HasOwner", &Perl_Mob_HasOwner);
package.add("HasPet", &Perl_Mob_HasPet);
package.add("HasProcs", &Perl_Mob_HasProcs);
package.add("HasShieldEquiped", &Perl_Mob_HasShieldEquiped);
package.add("HasShieldEquipped", &Perl_Mob_HasShieldEquipped);
package.add("HasTimer", &Perl_Mob_HasTimer);
package.add("HasTwoHandBluntEquiped", &Perl_Mob_HasTwoHandBluntEquiped);
package.add("HasTwoHandBluntEquipped", &Perl_Mob_HasTwoHandBluntEquipped);
package.add("HasTwoHanderEquipped", &Perl_Mob_HasTwoHanderEquipped);
package.add("HateSummon", &Perl_Mob_HateSummon);
package.add("Heal", &Perl_Mob_Heal);
+1 -1
View File
@@ -133,7 +133,7 @@ int Mob::GetBaseSkillDamage(EQ::skills::SkillType skill, Mob *target)
float ac_bonus = 0.0f;
const EQ::ItemInstance *inst = nullptr;
if (IsClient()) {
if (HasShieldEquiped()) {
if (HasShieldEquipped()) {
inst = CastToClient()->GetInv().GetItem(EQ::invslot::slotSecondary);
} else if (HasTwoHanderEquipped()) {
inst = CastToClient()->GetInv().GetItem(EQ::invslot::slotPrimary);
+50 -35
View File
@@ -207,11 +207,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
}
}
if(IsVirusSpell(spell_id)) {
if (IsVirusSpell(spell_id) && buffslot > -1) {
if (!viral_timer.Enabled()) {
viral_timer.Start(1000);
}
buffs[buffslot].virus_spread_time = zone->random.Int(GetViralMinSpreadTime(spell_id), GetViralMaxSpreadTime(spell_id));
}
@@ -819,20 +819,20 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
// define spells with fixed duration
// charm spells with -1 in field 209 are all of fixed duration, so lets use that instead of spell_ids
if(spells[spell_id].no_resist)
if (spells[spell_id].no_resist) {
bBreak = true;
if (!bBreak)
{
int resistMod = static_cast<int>(partial) + (GetCHA()/25);
resistMod = resistMod > 100 ? 100 : resistMod;
buffs[buffslot].ticsremaining = resistMod * buffs[buffslot].ticsremaining / 100;
}
if (IsClient() || IsBot())
{
if(buffs[buffslot].ticsremaining > RuleI(Character, MaxCharmDurationForPlayerCharacter))
if (buffslot > -1) {
if (!bBreak) {
int resistMod = static_cast<int>(partial) + (GetCHA() / 25);
resistMod = resistMod > 100 ? 100 : resistMod;
buffs[buffslot].ticsremaining = resistMod * buffs[buffslot].ticsremaining / 100;
}
if (IsOfClientBot() && buffs[buffslot].ticsremaining > RuleI(Character, MaxCharmDurationForPlayerCharacter)) {
buffs[buffslot].ticsremaining = RuleI(Character, MaxCharmDurationForPlayerCharacter);
}
}
break;
@@ -887,8 +887,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Fear: %+i", effect_value);
#endif
if (IsClient() || IsBot())
{
if (IsOfClientBot() && buffslot > -1) {
if (buffs[buffslot].ticsremaining > RuleI(Character, MaxFearDurationForPlayerCharacter)) {
buffs[buffslot].ticsremaining = RuleI(Character, MaxFearDurationForPlayerCharacter);
}
@@ -902,13 +901,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
}
CalculateNewFearpoint();
if (currently_fleeing)
{
if (currently_fleeing) {
break;
}
}
else
{
else if (buffslot > -1) {
Stun(buffs[buffslot].ticsremaining * 6000 - (6000 - tic_timer.GetRemainingTime()));
}
break;
@@ -1307,8 +1304,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Invulnerability");
#endif
if(spell_id==4789) // Touch of the Divine - Divine Save
buffs[buffslot].ticsremaining = spells[spell_id].buff_duration; // Prevent focus/aa buff extension
if (spell_id == 4789 && buffslot > -1) { // Touch of the Divine - Divine Save
buffs[buffslot].ticsremaining = spells[spell_id].buff_duration;
} // Prevent focus/aa buff extension
SetInvul(true);
break;
@@ -1355,7 +1353,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Melee Absorb Rune: %+i", effect_value);
#endif
buffs[buffslot].melee_rune = effect_value;
if (buffslot > -1) {
buffs[buffslot].melee_rune = effect_value;
}
break;
}
@@ -1364,47 +1364,60 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Spell Absorb Rune: %+i", effect_value);
#endif
if(effect_value > 0)
if (effect_value > 0 && buffslot > -1) {
buffs[buffslot].magic_rune = effect_value;
}
break;
}
case SE_MitigateMeleeDamage:
{
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
if (buffslot > -1) {
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
}
break;
}
case SE_MeleeThresholdGuard:
{
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
if (buffslot > -1) {
buffs[buffslot].melee_rune = spells[spell_id].max_value[i];
}
break;
}
case SE_SpellThresholdGuard:
{
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
if (buffslot > -1) {
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
}
break;
}
case SE_MitigateSpellDamage:
{
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
if (buffslot > -1) {
buffs[buffslot].magic_rune = spells[spell_id].max_value[i];
}
break;
}
case SE_MitigateDotDamage:
{
buffs[buffslot].dot_rune = spells[spell_id].max_value[i];
if (buffslot > -1) {
buffs[buffslot].dot_rune = spells[spell_id].max_value[i];
}
break;
}
case SE_DistanceRemoval:
{
buffs[buffslot].caston_x = int(GetX());
buffs[buffslot].caston_y = int(GetY());
buffs[buffslot].caston_z = int(GetZ());
if (buffslot > -1) {
buffs[buffslot].caston_x = int(GetX());
buffs[buffslot].caston_y = int(GetY());
buffs[buffslot].caston_z = int(GetZ());
}
break;
}
@@ -1434,7 +1447,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
caster->spellbonuses.UnfailingDivinity;
}
buffs[buffslot].ExtraDIChance = mod;
if (buffslot > -1) {
buffs[buffslot].ExtraDIChance = mod;
}
break;
}
@@ -1694,7 +1709,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#endif
rooted = true;
if (caster){
if (caster && buffslot > -1) {
buffs[buffslot].RootBreakChance = caster->aabonuses.RootBreakChance +
caster->itembonuses.RootBreakChance +
caster->spellbonuses.RootBreakChance;
@@ -8075,8 +8090,8 @@ bool Mob::PassCastRestriction(int value)
return true;
break;
case IS_OFF_HAND_EQUIPED:
if (HasShieldEquiped() || CanThisClassDualWield())
case IS_OFF_HAND_EQUIPPED:
if (HasShieldEquipped() || CanThisClassDualWield())
return true;
break;
@@ -9284,7 +9299,7 @@ void Mob::SendCastRestrictionMessage(int requirement_id, bool target_requirement
case IS_HP_UNDER_50_PCT:
Message(Chat::Red, fmt::format("{} This target must be at oe below 50 pct of its maximum hit points.", msg).c_str());
break;
case IS_OFF_HAND_EQUIPED:
case IS_OFF_HAND_EQUIPPED:
Message(Chat::Red, fmt::format("{} You must be wielding a weapon or shield in your offhand to use this ability.", msg).c_str());
break;
case HAS_NO_PACT_OF_FATE_RECOURSE_BUFF:
+3 -2
View File
@@ -437,9 +437,10 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
//this is a special case for NPCs with no mana...
if (IsNPC() && my_curmana == my_maxmana) {
mana_cost = 0;
} else {
DoSpellInterrupt(spell_id, mana_cost, my_curmana);
return false;
}
DoSpellInterrupt(spell_id, mana_cost, my_curmana);
return false;
}
}
+2
View File
@@ -358,6 +358,7 @@
#define WHOALL_NO_RESULTS 5029 //There are no players in EverQuest that match those who filters.
#define TELL_QUEUED_MESSAGE 5045 //You told %1 '%T2. %3'
#define TOLD_NOT_ONLINE 5046 //%1 is not online at this time.
#define RAID_IS_FULL 5048 //The raid is full.
#define ZONING_NO_EXPANSION 5052 //The zone that you are attempting to enter is part of an expansion that you do not yet own. You may need to return to the Login screen and enter an account key for that expansion. If you have received this message in error, please /petition or send an email to EQAccounts@soe.sony.com
#define PETITION_NO_DELETE 5053 //You do not have a petition in the queue.
#define PETITION_DELETED 5054 //Your petition was successfully deleted.
@@ -460,6 +461,7 @@
#define NO_ABILITY_OUT_OF_COMBAT 9194 //You can not use this ability while out of combat.
#define LESSER_SPELL_VERSION 11004 //%1 is a lesser version of %2 and cannot be scribed
#define AE_RAMPAGE 11015 //%1 goes on a WILD RAMPAGE!
#define GROUP_IS_FULL 12000 //You cannot join that group, it is full.
#define FACE_ACCEPTED 12028 //Facial features accepted.
#define TRACKING_BEGIN 12040 //You begin tracking %1.
#define SPELL_LEVEL_TO_LOW 12048 //You will have to achieve level %1 before you can scribe the %2.
+2 -2
View File
@@ -920,7 +920,7 @@ int64 Mob::TuneClientAttack(Mob* other, bool no_avoid, bool no_hit_chance, int h
if (Hand == EQ::invslot::slotPrimary || Hand == EQ::invslot::slotSecondary)
my_hit.base_damage = CastToClient()->DoDamageCaps(my_hit.base_damage);
auto shield_inc = spellbonuses.ShieldEquipDmgMod + itembonuses.ShieldEquipDmgMod + aabonuses.ShieldEquipDmgMod;
if (shield_inc > 0 && HasShieldEquiped() && Hand == EQ::invslot::slotPrimary) {
if (shield_inc > 0 && HasShieldEquipped() && Hand == EQ::invslot::slotPrimary) {
my_hit.base_damage = my_hit.base_damage * (100 + shield_inc) / 100;
hate = hate * (100 + shield_inc) / 100;
}
@@ -1040,7 +1040,7 @@ int64 Mob::TuneACSum(bool skip_caps, int ac_override, int add_ac)
}
int shield_ac = 0;
if (HasShieldEquiped() && IsOfClientBot()) {
if (HasShieldEquipped() && IsOfClientBot()) {
auto inst = (IsClient()) ? GetInv().GetItem(EQ::invslot::slotSecondary) : CastToBot()->GetBotItem(EQ::invslot::slotSecondary);
if (inst) {
if (inst->GetItemRecommendedLevel(true) <= GetLevel()) {
+1 -1
View File
@@ -1059,7 +1059,7 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
did_adventure_actions = false;
database.QGlobalPurge();
if(zoneid == RuleI(World, GuildBankZoneID))
if(zoneid == Zones::GUILDHALL)
GuildBanks = new GuildBankManager;
else
GuildBanks = nullptr;