
Broker/Vault (Fix #10): - Traditional broker integrated (/frombroker), GM itemsearch is still available via /itemsearch. AoM client cannot sell/use shop, can only buy from broker. - DoF and KoS client now support House Shop (sell inventory, vault to broker). - House containers now function like actual containers and can be stored in the vault which will allow placement in the home (to serve as a merchant). - Sales crate merchant windows in player houses implemented for broker. - Peering URI's added for broker/shop support: /addseller, /removeseller, /additemsale, /removeitemsale - House vault and vault slots implemented for DoF, KoS and AoM clients. Stability and Functionality: - World Database now has seq_character_items (Sequence) to sync self and peers instantiating new unique IDs for character items. This is to avoid conflict/overriding another unique id. - spawn and spawn_houses tables have a lua_script that can now be defined outside the existing spawn_scripts table for a singular spawn. - Fixed a watchdog/hangup when clearing hate lists inside a spawn list lock. - Item unique id is being transitioned to int64 (although older clients still only support int32, clients later on are int64). - Fixed so that spells that have no duration will no longer be added to maintained effects. - Fixed spell cleanup, maintained effect does not remain on the Player causing a crash. - Fixed spell conflicts to that check all targets are applicable for the spell. - Fixed issues with maintained effects or spell effects stacking repeatedly. - Fixed assigning items to non inventory slots when 'adding' an item to the Player. - Fixed locking orders between maintained effects and spell effects to avoid deadlocks. - Fixed entering house and visiting houses, targetting of the house door is now enforced server side. - Item locking is now enforced by the type of locking (eg. house placement, crafting, shop list for sale). Locks no longer override/interfere with each other. - Additional logging around spell casting and targets. - Spawns/Objects/Widgets so on related to houses now have their own sub tables _houses, eg. spawn_houses, spawn_npc_houses, spawn_object_houses, so on to avoid conflicting with existing tables non-house. - new LUA Functions: ShowShopWindow(Player, FromSpawn) - opens shop window for player (if in their house) for listing, pricing items, retrieving sales log and coin, etc. SetSpawnHouseScript(Target, LuaScript) - Utilized in the item script 'placed' function to set the spawned house item's lua script. SendBook(Target, ItemID) - Sends the book to the target player based on the item id. GetPickupItemID(Spawn) - Gets the item id that the house spawn would represent SetHouseCharacterID(Spawn, CharID) - Sets the house spawn character id (should be used on Spawn). Set CharID to 0 to set to the current houses character id. - Updated LUA Functions: StartHeroicOpportunity(Caster, ClassID, OverrideTarget) - OverrideTarget now available to change the heroic opportunity target HasItem(Player, ItemID, IncludeBank) - No parameter change, include bank, which serves as 'all' should now work correctly (previously did not check bank/other negative slots), default is false. - Slash Commands Added: /sle - Fix #41, Set Location Entry (DB command for setting spawn location entry values such as offsets and overrides) /store_list_item - used to list an item for broker shop /store_set_price - used for setting items price for shop /store_set_price_local - used for inventory items price for shop /store_start_selling - Begin selling from inventory for shop /store_stop_selling - Stop selling from inventory /store_unlist_item - used to unlist an item from broker shop /close_store_keep_selling - Closes store shop window, but keep selling from inventory while in house /cancel_store - cancel selling from inventory
200 lines
7.1 KiB
C++
200 lines
7.1 KiB
C++
/*
|
|
EQ2Emulator: Everquest II Server Emulator
|
|
Copyright (C) 2005 - 2026 EQ2EMulator Development Team (http://www.eq2emu.com formerly http://www.eq2emulator.net)
|
|
|
|
This file is part of EQ2Emulator.
|
|
|
|
EQ2Emulator 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, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
EQ2Emulator is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; 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 EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef __NPC_AI_H__
|
|
#define __NPC_AI_H__
|
|
#include "NPC.h"
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
using namespace std;
|
|
|
|
class Brain {
|
|
public:
|
|
Brain(NPC* npc);
|
|
virtual ~Brain();
|
|
|
|
/// <summary>The main loop for the brain. This will do all the AI work</summary>
|
|
virtual void Think();
|
|
|
|
/* Timer related functions */
|
|
|
|
/// <summary>Gets the time between calls to Think()</summary>
|
|
/// <returns>Time in miliseconds between calls to Think()</returns>
|
|
int16 Tick() { return m_tick; }
|
|
/// <summary>Sets the time between calls to Think()</summary>
|
|
/// <param name="time">Time in miliseconds</param>
|
|
void SetTick(int16 time) { m_tick = time; }
|
|
/// <summary>Gets the timestamp of the last call to Think()</summary>
|
|
/// <returns>Timestamp of the last call to Think()</returns>
|
|
int32 LastTick() { return m_lastTick; }
|
|
/// <summary>Sets the last tick to the given time</summary>
|
|
/// <param name="time">The time to set the last tick to</param>
|
|
void SetLastTick(int32 time) { m_lastTick = time; }
|
|
|
|
/* Hate related functions */
|
|
|
|
/// <summary>Gets the amount of hate this npc has towards the given entity</summary>
|
|
/// <param name="entity">The entity to check</param>
|
|
/// <returns>The amount of hate towards the given entity</returns>
|
|
sint32 GetHate(Entity* entity);
|
|
/// <summary>Add hate for the given entity to this NPC</summary>
|
|
/// <param name="entity">The entity we are adding to this NPC's hate list</param>
|
|
/// <param name="hate">The amount of hate to add</param>
|
|
virtual void AddHate(Entity* entity, sint32 hate);
|
|
/// <summary>Completely clears the hate list for this npc</summary>
|
|
void ClearHate(bool lockSpawnList = true);
|
|
/// <summary>Removes the given entity from this NPC's hate list</summary>
|
|
/// <param name="entity">Entity to remove from this NPC's hate list</param>
|
|
void ClearHate(Entity* entity);
|
|
/// <summary>Get the entity this NPC hates the most</summary>
|
|
/// <returns>The entity this NPC hates the most</returns>
|
|
Entity* GetMostHated();
|
|
/// <summary>Gets a percentage of hate owned by the given entity</summary>
|
|
/// <param name="entity">Entity to get the percentage for</param>
|
|
/// <returns>Percentage of hate as a sint8</returns>
|
|
sint8 GetHatePercentage(Entity* entity);
|
|
|
|
void SendHateList(Client* client);
|
|
|
|
///<summary>Gets a list of all the entities in the hate list</summary>
|
|
vector<Entity*>* GetHateList();
|
|
|
|
/* Combat related functions */
|
|
|
|
bool BrainCastSpell(Spell* spell, Spawn* cast_on, bool calculate_run_loc = true);
|
|
|
|
/// <summary></summary>
|
|
/// <param name=""></param>
|
|
/// <param name=""></param>
|
|
virtual bool ProcessSpell(Entity* target, float distance);
|
|
/// <summary></summary>
|
|
/// <returns>True if a buff starts casting</returns>
|
|
bool CheckBuffs();
|
|
|
|
/// <summary>Has the NPC make a melee attack</summary>
|
|
/// <param name="target">The target to attack</param>
|
|
/// <param name="distance">The current distance from the target</param>
|
|
void ProcessMelee(Entity* target, float distance);
|
|
|
|
/* Encounter related functions */
|
|
|
|
/// <summary>Adds the given entity and its group and raid members to the encounter list</summary>
|
|
/// <param name="entity">Entity we are adding to the encounter list</param>
|
|
void AddToEncounter(Entity* entity);
|
|
/// <summary>Checks to see if the given entity can loot the corpse</summary>
|
|
/// <param name="entity">Entity trying to loot</param>
|
|
/// <returns>True if the entity can loot</returns>
|
|
bool CheckLootAllowed(Entity* entity);
|
|
/// <summary>Gets the size of the encounter list</summary>
|
|
/// <returns>The size of the list as an int8</returns>
|
|
int8 GetEncounterSize();
|
|
/// <summary>Clears the encounter list</summary>
|
|
void ClearEncounter();
|
|
|
|
void SendEncounterList(Client* client);
|
|
|
|
/// <summary>Gets a copy of the encounter list</summary>
|
|
/// <returns>A copy of the encounter list as a vector<Entity*>*</returns>
|
|
vector<int32>* GetEncounter();
|
|
/// <summary>Checks to see if a player is in the encounter</summary>
|
|
/// <returns>True if the encounter list contains a player</returns>
|
|
bool PlayerInEncounter() { return m_playerInEncounter; }
|
|
bool IsPlayerInEncounter(int32 char_id);
|
|
bool IsEntityInEncounter(int32 id, bool skip_read_lock = false);
|
|
int32 CountPlayerBotInEncounter();
|
|
bool AddToEncounter(int32 id);
|
|
/* Helper functions*/
|
|
|
|
/// <summary>Gets the NPC this brain controls</summary>
|
|
/// <returns>The NPC this brain controls</returns>
|
|
NPC* GetBody() { return m_body; }
|
|
/// <summary>Checks to see if the NPC can cast</summary>
|
|
/// <returns>True if the NPC can cast</returns>
|
|
bool HasRecovered();
|
|
/// <summary>Tells the NPC to move closer to the given target</summary>
|
|
/// <param name="target">The target to move closer to</param>
|
|
void MoveCloser(Spawn* target);
|
|
|
|
protected:
|
|
// m_body = the npc this brain controls
|
|
NPC* m_body;
|
|
// m_spellRecovery = time stamp for when the npc can cast again
|
|
int32 m_spellRecovery;
|
|
private:
|
|
// MHateList = mutex to lock and unlock the hate list
|
|
Mutex MHateList;
|
|
// m_hatelist = the list that stores all the hate,
|
|
// entity is the entity this npc hates and the int32 is the value for how much we hate the entity
|
|
map<int32, sint32> m_hatelist;
|
|
// m_lastTick = the last time we ran this brain
|
|
int32 m_lastTick;
|
|
// m_tick = the amount of time between Think() calls in milliseconds
|
|
int16 m_tick;
|
|
// m_encounter = list of players (entities) that will get a reward (xp/loot) for killing this npc
|
|
vector<int32> m_encounter;
|
|
map<int32, int32> m_encounter_playerlist;
|
|
|
|
// MEncounter = mutex to lock and unlock the encounter list
|
|
Mutex MEncounter;
|
|
//m_playerInEncounter = true if a player is added to the encounter
|
|
bool m_playerInEncounter;
|
|
};
|
|
|
|
// Extension of the default brain for combat pets
|
|
class CombatPetBrain : public Brain {
|
|
public:
|
|
CombatPetBrain(NPC* body);
|
|
virtual ~CombatPetBrain();
|
|
void Think();
|
|
};
|
|
|
|
class NonCombatPetBrain : public Brain {
|
|
public:
|
|
NonCombatPetBrain(NPC* body);
|
|
virtual ~NonCombatPetBrain();
|
|
void Think();
|
|
};
|
|
|
|
class BlankBrain : public Brain {
|
|
public:
|
|
BlankBrain(NPC* body);
|
|
virtual ~BlankBrain();
|
|
void Think();
|
|
};
|
|
|
|
class LuaBrain : public Brain {
|
|
public:
|
|
LuaBrain(NPC* body);
|
|
virtual ~LuaBrain();
|
|
void Think();
|
|
};
|
|
|
|
class DumbFirePetBrain : public Brain {
|
|
public:
|
|
DumbFirePetBrain(NPC* body, Entity* target, int32 expire_time);
|
|
virtual ~DumbFirePetBrain();
|
|
void Think();
|
|
void AddHate(Entity* entity, sint32 hate);
|
|
private:
|
|
int32 m_expireTime;
|
|
};
|
|
#endif
|