mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-30 11:45:46 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c64a2aec94 | |||
| 0e582eda82 | |||
| 7eff6ada87 | |||
| 291997d35b | |||
| ac4572bf79 | |||
| f0a9578b6a | |||
| baa824d8fb | |||
| b19d3ac8a2 | |||
| 6a393bf0c3 | |||
| 09a5551de1 | |||
| 6e2e035d66 | |||
| ac5922bb32 | |||
| ecf2a369cc | |||
| 95b306599f | |||
| 497d20512a | |||
| db916e946e | |||
| 958549b407 | |||
| 71ebf1b2d4 | |||
| e19b8d3056 | |||
| 8b1d64a043 | |||
| 576f99f292 | |||
| e3761cf2a3 | |||
| ad1764b464 | |||
| 1c9ea57a4e | |||
| 03c158b674 | |||
| 39b5374e92 |
@@ -1,3 +1,51 @@
|
||||
## [22.11.0] - 04/29/2023
|
||||
|
||||
### Code
|
||||
|
||||
* Add check for owner in quest::pausetimer() ([#3304](https://github.com/EQEmu/Server/pull/3304)) @Kinglykrab 2023-04-23
|
||||
* Add check for owner in quest::resumetimer() ([#3305](https://github.com/EQEmu/Server/pull/3305)) @Kinglykrab 2023-04-23
|
||||
* Add initiator/owner checks to various methods in questmgr.cpp ([#3306](https://github.com/EQEmu/Server/pull/3306)) @Kinglykrab 2023-04-23
|
||||
* Fix possible nullptr in quest::addloot() ([#3303](https://github.com/EQEmu/Server/pull/3303)) @Kinglykrab 2023-04-23
|
||||
* Remove GetClassHPFactor() from zone/client_mods.cpp and zone/client.h ([#3313](https://github.com/EQEmu/Server/pull/3313)) @Kinglykrab 2023-04-30
|
||||
* Remove GetClassHPFactor() from zone/merc.h ([#3314](https://github.com/EQEmu/Server/pull/3314)) @Kinglykrab 2023-04-30
|
||||
* Remove pDontCastBefore_casting_spell from zone/npc.h ([#3311](https://github.com/EQEmu/Server/pull/3311)) @Kinglykrab 2023-04-30
|
||||
* Remove unused code in zone/pets.cpp ([#3310](https://github.com/EQEmu/Server/pull/3310)) @Kinglykrab 2023-04-30
|
||||
* Remove unused methods in zone/bot.cpp and zone/bot.h ([#3315](https://github.com/EQEmu/Server/pull/3315)) @Kinglykrab 2023-04-30
|
||||
* Remove unused methods in zone/client.cpp and zone/client.h ([#3312](https://github.com/EQEmu/Server/pull/3312)) @Kinglykrab 2023-04-30
|
||||
* Remove unused variable in common/crash.cpp ([#3308](https://github.com/EQEmu/Server/pull/3308)) @Kinglykrab 2023-04-30
|
||||
* Use default ctor/dtor in oriented_bounding_box.h ([#3307](https://github.com/EQEmu/Server/pull/3307)) @Kinglykrab 2023-04-30
|
||||
* quest::createBot() unnecessary check against nullptr ([#3302](https://github.com/EQEmu/Server/pull/3302)) @Kinglykrab 2023-04-23
|
||||
* quest::setallskill() had always true condition. ([#3301](https://github.com/EQEmu/Server/pull/3301)) @Kinglykrab 2023-04-30
|
||||
|
||||
### Crash
|
||||
|
||||
* Fix UCS crash that occurs during log reloading ([#3324](https://github.com/EQEmu/Server/pull/3324)) @Akkadius 2023-04-30
|
||||
* Fix possible dereference of nullptr in Client::CalcHPRegen ([#3316](https://github.com/EQEmu/Server/pull/3316)) @Aeadoin 2023-04-23
|
||||
* Fix possible nullptr in Client::GetCharMaxLevelFromQGlobal() ([#3317](https://github.com/EQEmu/Server/pull/3317)) @Kinglykrab 2023-04-23
|
||||
|
||||
### Discord
|
||||
|
||||
* Add Discord webhook callback processing to world ([#3322](https://github.com/EQEmu/Server/pull/3322)) @Akkadius 2023-04-30
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix issue with NPCs no longer using some armor. ([#3318](https://github.com/EQEmu/Server/pull/3318)) @noudess 2023-04-24
|
||||
* Fix issue with spawning Mercs ([#3327](https://github.com/EQEmu/Server/pull/3327)) @Aeadoin 2023-04-29
|
||||
* Possible issues with SummonItem in Client::QuestReward() methods ([#3325](https://github.com/EQEmu/Server/pull/3325)) @Kinglykrab 2023-04-27
|
||||
|
||||
### Maps
|
||||
|
||||
* Update download with faster releases link ([#3321](https://github.com/EQEmu/Server/pull/3321)) @Akkadius 2023-04-30
|
||||
|
||||
### Messages
|
||||
|
||||
* Remove duplicate you have lost a level message ([#3323](https://github.com/EQEmu/Server/pull/3323)) @noudess 2023-04-25
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add GetDefaultRaceSize() overloads to Perl/Lua ([#3320](https://github.com/EQEmu/Server/pull/3320)) @Kinglykrab 2023-04-30
|
||||
* Add HasSpellEffect() to Perl/Lua ([#3319](https://github.com/EQEmu/Server/pull/3319)) @Kinglykrab 2023-04-30
|
||||
|
||||
## [22.10.0] - 04/22/2023
|
||||
|
||||
### Backups
|
||||
|
||||
@@ -41,9 +41,6 @@ void SendCrashReport(const std::string &crash_report)
|
||||
r.set_connection_timeout(1, 0);
|
||||
r.set_read_timeout(1, 0);
|
||||
r.set_write_timeout(1, 0);
|
||||
httplib::Headers headers = {
|
||||
{"Content-Type", "application/json"}
|
||||
};
|
||||
|
||||
// os info
|
||||
auto os = EQ::GetOS();
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
|
||||
// Build variables
|
||||
// these get injected during the build pipeline
|
||||
#define CURRENT_VERSION "22.10.0-dev" // always append -dev to the current version for custom-builds
|
||||
#define CURRENT_VERSION "22.11.0-dev" // always append -dev to the current version for custom-builds
|
||||
#define LOGIN_VERSION "0.8.0"
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eqemu-server",
|
||||
"version": "22.10.0",
|
||||
"version": "22.11.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EQEmu/Server.git"
|
||||
|
||||
@@ -144,6 +144,8 @@ int main() {
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
|
||||
player_event_logs.SetDatabase(&database)->Init();
|
||||
|
||||
char tmp[64];
|
||||
|
||||
// ucs has no 'reload rules' handler
|
||||
|
||||
@@ -1801,23 +1801,9 @@ sub fetch_peq_db_full
|
||||
sub map_files_fetch_bulk
|
||||
{
|
||||
print "[Install] Fetching Latest Maps... (This could take a few minutes...)\n";
|
||||
get_remote_file("http://analytics.akkadius.com/maps.zip", "maps/maps.zip", 1);
|
||||
get_remote_file("https://github.com/Akkadius/eqemu-maps/releases/latest/download/maps.zip", "maps/maps.zip", 1);
|
||||
unzip('maps/maps.zip', 'maps/');
|
||||
my @files;
|
||||
my $start_dir = "maps/EQEmuMaps-master/";
|
||||
find(
|
||||
sub { push @files, $File::Find::name unless -d; },
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
$destination_file = $file;
|
||||
$destination_file =~ s/maps\/EQEmuMaps-master\///g;
|
||||
print "[Install] Installing [" . $destination_file . "]\n";
|
||||
copy_file($file, "maps/" . $destination_file);
|
||||
}
|
||||
print "[Install] Fetched Latest Maps\n";
|
||||
|
||||
rmtree('maps/EQEmuMaps-master');
|
||||
unlink('maps/maps.zip');
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
void Disconnect() { if(connection && connection->Handle()) connection->Handle()->Disconnect(); }
|
||||
void SendMessage(const char *From, const char *Message);
|
||||
const std::shared_ptr<EQ::Net::ServertalkServerConnection> &GetConnection() const;
|
||||
inline bool IsConnected() const { return connection->Handle() ? connection->Handle()->IsConnected() : false; }
|
||||
|
||||
private:
|
||||
inline std::string GetIP() const { return (connection && connection->Handle()) ? connection->Handle()->RemoteIP() : 0; }
|
||||
|
||||
@@ -300,6 +300,8 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
|
||||
->SetLogPath(path.GetLogPath())
|
||||
->LoadLogDatabaseSettings();
|
||||
|
||||
LogSys.SetDiscordHandler(&WorldBoot::DiscordWebhookMessageHandler);
|
||||
|
||||
if (!ignore_db) {
|
||||
LogInfo("Checking Database Conversions");
|
||||
database.CheckDatabaseConversions();
|
||||
@@ -662,3 +664,18 @@ void WorldBoot::Shutdown()
|
||||
safe_delete(mutex);
|
||||
}
|
||||
|
||||
void WorldBoot::SendDiscordMessage(int webhook_id, const std::string &message)
|
||||
{
|
||||
if (UCSLink.IsConnected()) {
|
||||
auto pack = new ServerPacket(ServerOP_DiscordWebhookMessage, sizeof(DiscordWebhookMessage_Struct) + 1);
|
||||
auto *q = (DiscordWebhookMessage_Struct *) pack->pBuffer;
|
||||
|
||||
strn0cpy(q->message, message.c_str(), 2000);
|
||||
q->webhook_id = webhook_id;
|
||||
|
||||
UCSLink.SendPacket(pack);
|
||||
|
||||
safe_delete(pack);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include <string>
|
||||
#include "../common/types.h"
|
||||
#include "../common/discord/discord.h"
|
||||
|
||||
extern UCSConnection UCSLink;
|
||||
|
||||
class WorldBoot {
|
||||
public:
|
||||
@@ -16,6 +19,16 @@ public:
|
||||
static bool DatabaseLoadRoutines(int argc, char **argv);
|
||||
static void CheckForPossibleConfigurationIssues();
|
||||
static void Shutdown();
|
||||
static void SendDiscordMessage(int webhook_id, const std::string& message);
|
||||
static void DiscordWebhookMessageHandler(uint16 log_category, int webhook_id, const std::string &message)
|
||||
{
|
||||
std::string message_prefix = fmt::format(
|
||||
"[**{}**] **World** ",
|
||||
Logs::LogCategoryName[log_category]
|
||||
);
|
||||
|
||||
SendDiscordMessage(webhook_id, message_prefix + Discord::FormatDiscordMessage(log_category, message));
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
+5
-11
@@ -58,16 +58,10 @@ void Mob::CalcBonuses()
|
||||
void NPC::CalcBonuses()
|
||||
{
|
||||
memset(&itembonuses, 0, sizeof(StatBonuses));
|
||||
if (RuleB(NPC, UseItemBonusesForNonPets)) {
|
||||
memset(&itembonuses, 0, sizeof(StatBonuses));
|
||||
|
||||
if (GetOwner() || RuleB(NPC, UseItemBonusesForNonPets)) {
|
||||
CalcItemBonuses(&itembonuses);
|
||||
}
|
||||
else {
|
||||
if (GetOwner()) {
|
||||
memset(&itembonuses, 0, sizeof(StatBonuses));
|
||||
CalcItemBonuses(&itembonuses);
|
||||
}
|
||||
}
|
||||
|
||||
// This has to happen last, so we actually take the item bonuses into account.
|
||||
Mob::CalcBonuses();
|
||||
@@ -268,7 +262,7 @@ void Mob::AddItemBonuses(const EQ::ItemInstance* inst, StatBonuses* b, bool is_a
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_tribute && !inst->IsEquipable(GetBaseRace(), GetClass())) {
|
||||
if (IsClient() && !is_tribute && !inst->IsEquipable(GetBaseRace(), GetClass())) {
|
||||
if (item->ItemType != EQ::item::ItemTypeFood && item->ItemType != EQ::item::ItemTypeDrink) {
|
||||
return;
|
||||
}
|
||||
@@ -276,14 +270,14 @@ void Mob::AddItemBonuses(const EQ::ItemInstance* inst, StatBonuses* b, bool is_a
|
||||
|
||||
const auto current_level = GetLevel();
|
||||
|
||||
if (current_level < inst->GetItemRequiredLevel(true)) {
|
||||
if (IsClient() && current_level < inst->GetItemRequiredLevel(true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_ammo_item) {
|
||||
const auto recommended_level = is_augment ? recommended_level_override : inst->GetItemRecommendedLevel(true);
|
||||
|
||||
if (current_level >= recommended_level) {
|
||||
if (IsNPC() || current_level >= recommended_level) {
|
||||
b->HP += item->HP;
|
||||
b->Mana += item->Mana;
|
||||
b->Endurance += item->Endur;
|
||||
|
||||
@@ -3605,19 +3605,6 @@ void Bot::LevelBotWithClient(Client* client, uint8 level, bool sendlvlapp) {
|
||||
}
|
||||
}
|
||||
|
||||
void Bot::SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color) {
|
||||
auto outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct));
|
||||
auto wc = (WearChange_Struct*)outapp->pBuffer;
|
||||
|
||||
wc->spawn_id = GetID();
|
||||
wc->material = material;
|
||||
wc->color.Color = color;
|
||||
wc->wear_slot_id = material_slot;
|
||||
|
||||
entity_list.QueueClients(this, outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
// Returns the item id that is in the bot inventory collection for the specified slot.
|
||||
EQ::ItemInstance* Bot::GetBotItem(uint16 slot_id) {
|
||||
EQ::ItemInstance* item = m_inv.GetItem(slot_id);
|
||||
@@ -5867,16 +5854,6 @@ void Bot::GenerateSpecialAttacks() {
|
||||
SetSpecialAbility(SPECATK_TRIPLE, 1);
|
||||
}
|
||||
|
||||
bool Bot::DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
|
||||
if (GetClass() == BARD) {
|
||||
if (!ApplyBardPulse(bardsong, this, bardsong_slot))
|
||||
InterruptSpell(SONG_ENDS_ABRUPTLY, 0x121, bardsong);
|
||||
|
||||
stopLogic = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
|
||||
|
||||
if (
|
||||
|
||||
@@ -196,10 +196,8 @@ public:
|
||||
void SetAttackTimer() override;
|
||||
uint64 GetClassHPFactor();
|
||||
int64 CalcMaxHP() override;
|
||||
bool DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
|
||||
bool DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
|
||||
bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
|
||||
void SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color);
|
||||
void Camp(bool save_to_database = true);
|
||||
void SetTarget(Mob* mob) override;
|
||||
void Zone();
|
||||
|
||||
+2
-9
@@ -2783,13 +2783,6 @@ void Client::GMKill() {
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
bool Client::CheckAccess(int16 iDBLevel, int16 iDefaultLevel) {
|
||||
if ((admin >= iDBLevel) || (iDBLevel == AccountStatus::Max && admin >= iDefaultLevel))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void Client::MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing, uint32 reduction){
|
||||
if (slot < 0 || slot >= EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
|
||||
return;
|
||||
@@ -8545,7 +8538,7 @@ void Client::QuestReward(Mob* target, uint32 copper, uint32 silver, uint32 gold,
|
||||
AddMoneyToPP(copper, silver, gold, platinum);
|
||||
|
||||
if (itemid > 0)
|
||||
SummonItem(itemid, -1, 0, 0, 0, 0, 0, false, EQ::invslot::slotCursor);
|
||||
SummonItem(itemid, -1, 0, 0, 0, 0, 0, 0, false, EQ::invslot::slotCursor);
|
||||
|
||||
if (faction)
|
||||
{
|
||||
@@ -8581,7 +8574,7 @@ void Client::QuestReward(Mob* target, const QuestReward_Struct &reward, bool fac
|
||||
|
||||
for (int i = 0; i < QUESTREWARD_COUNT; ++i)
|
||||
if (reward.item_id[i] > 0)
|
||||
SummonItem(reward.item_id[i], -1, 0, 0, 0, 0, 0, false, EQ::invslot::slotCursor);
|
||||
SummonItem(reward.item_id[i], -1, 0, 0, 0, 0, 0, 0, false, EQ::invslot::slotCursor);
|
||||
|
||||
// only process if both are valid
|
||||
// if we don't have a target here, we want to just reward, but if there is a target, need to check charm
|
||||
|
||||
@@ -322,7 +322,6 @@ public:
|
||||
void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
bool ShouldISpawnFor(Client *c) { return !GMHideMe(c) && !IsHoveringForRespawn(); }
|
||||
virtual bool Process();
|
||||
void ProcessPackets();
|
||||
void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone);
|
||||
void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL);
|
||||
void ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_skill, const char* orig_message, const char* targetname = nullptr, bool is_silent = false);
|
||||
@@ -379,12 +378,8 @@ public:
|
||||
|
||||
void SetPetCommandState(int button, int state);
|
||||
|
||||
bool CheckAccess(int16 iDBLevel, int16 iDefaultLevel);
|
||||
|
||||
void CheckQuests(const char* zonename, const char* message, uint32 npc_id, uint32 item_id, Mob* other);
|
||||
bool AutoAttackEnabled() const { return auto_attack; }
|
||||
bool AutoFireEnabled() const { return auto_fire; }
|
||||
void MakeCorpse(uint32 exploss);
|
||||
|
||||
bool ChangeFirstName(const char* in_firstname,const char* gmname);
|
||||
|
||||
@@ -394,7 +389,6 @@ public:
|
||||
|
||||
virtual void SetMaxHP();
|
||||
int32 LevelRegen();
|
||||
void HPTick();
|
||||
void SetGM(bool toggle);
|
||||
void SetPVP(bool toggle, bool message = true);
|
||||
|
||||
@@ -1719,7 +1713,6 @@ private:
|
||||
int64 CalcHPRegen(bool bCombat = false);
|
||||
int64 CalcManaRegen(bool bCombat = false);
|
||||
int64 CalcBaseManaRegen();
|
||||
uint64 GetClassHPFactor();
|
||||
void DoHPRegen();
|
||||
void DoManaRegen();
|
||||
void DoStaminaHungerUpdate();
|
||||
|
||||
+1
-45
@@ -288,7 +288,7 @@ int64 Client::CalcHPRegen(bool bCombat)
|
||||
|
||||
if (!bCombat && CanFastRegen() && (IsSitting() || CanMedOnHorse())) {
|
||||
auto max_hp = GetMaxHP();
|
||||
int fast_regen = 6 * (max_hp / zone->newzone_data.fast_regen_hp);
|
||||
int64 fast_regen = 6 * (max_hp / (zone ? zone->newzone_data.fast_regen_hp : 180));
|
||||
if (base < fast_regen) // weird, but what the client is doing
|
||||
base = fast_regen;
|
||||
}
|
||||
@@ -506,50 +506,6 @@ int64 Client::CalcBaseHP()
|
||||
return base_hp;
|
||||
}
|
||||
|
||||
// This is for calculating Base HPs + STA bonus for SoD or later clients.
|
||||
uint64 Client::GetClassHPFactor()
|
||||
{
|
||||
int factor;
|
||||
// Note: Base HP factor under level 41 is equal to factor / 12, and from level 41 to 80 is factor / 6.
|
||||
// Base HP over level 80 is factor / 10
|
||||
// HP per STA point per level is factor / 30 for level 80+
|
||||
// HP per STA under level 40 is the level 80 HP Per STA / 120, and for over 40 it is / 60.
|
||||
switch (GetClass()) {
|
||||
case DRUID:
|
||||
case ENCHANTER:
|
||||
case NECROMANCER:
|
||||
case MAGICIAN:
|
||||
case WIZARD:
|
||||
factor = 240;
|
||||
break;
|
||||
case BEASTLORD:
|
||||
case BERSERKER:
|
||||
case MONK:
|
||||
case ROGUE:
|
||||
case SHAMAN:
|
||||
factor = 255;
|
||||
break;
|
||||
case BARD:
|
||||
case CLERIC:
|
||||
factor = 264;
|
||||
break;
|
||||
case SHADOWKNIGHT:
|
||||
case PALADIN:
|
||||
factor = 288;
|
||||
break;
|
||||
case RANGER:
|
||||
factor = 276;
|
||||
break;
|
||||
case WARRIOR:
|
||||
factor = 300;
|
||||
break;
|
||||
default:
|
||||
factor = 240;
|
||||
break;
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
|
||||
// This should return the combined AC of all the items the player is wearing.
|
||||
int32 Client::GetRawItemAC()
|
||||
{
|
||||
|
||||
+3
-3
@@ -783,8 +783,6 @@ void Client::SetEXP(uint64 set_exp, uint64 set_aaxp, bool isrezzexp) {
|
||||
if (check_level == RuleI(Character, DeathExpLossLevel))
|
||||
MessageString(Chat::Yellow, CORPSE_EXP_LOST);
|
||||
}
|
||||
else
|
||||
MessageString(Chat::Experience, LOSE_LEVEL, ConvertArray(check_level, val1));
|
||||
|
||||
uint8 myoldlevel = GetLevel();
|
||||
|
||||
@@ -1256,8 +1254,10 @@ uint8 Client::GetCharMaxLevelFromQGlobal() {
|
||||
|
||||
std::list<QGlobal> global_map;
|
||||
|
||||
const uint32 zone_id = zone ? zone->GetZoneID() : 0;
|
||||
|
||||
if (char_cache) {
|
||||
QGlobalCache::Combine(global_map, char_cache->GetBucket(), 0, CharacterID(), zone->GetZoneID());
|
||||
QGlobalCache::Combine(global_map, char_cache->GetBucket(), 0, CharacterID(), zone_id);
|
||||
}
|
||||
|
||||
for (const auto& global : global_map) {
|
||||
|
||||
+6
-2
@@ -361,11 +361,12 @@ void NPC::AddLootDrop(
|
||||
SetArrowEquipped(true);
|
||||
}
|
||||
|
||||
bool found = false; // track if we found an empty slot we fit into
|
||||
|
||||
if (loot_drop.equip_item > 0) {
|
||||
uint8 eslot = 0xFF;
|
||||
char newid[20];
|
||||
const EQ::ItemData* compitem = nullptr;
|
||||
bool found = false; // track if we found an empty slot we fit into
|
||||
int32 foundslot = -1; // for multi-slot items
|
||||
|
||||
// Equip rules are as follows:
|
||||
@@ -500,7 +501,6 @@ void NPC::AddLootDrop(
|
||||
|
||||
}
|
||||
if (found) {
|
||||
CalcBonuses(); // This is less than ideal for bulk adding of items
|
||||
item->equip_slot = foundslot;
|
||||
}
|
||||
}
|
||||
@@ -510,6 +510,10 @@ void NPC::AddLootDrop(
|
||||
}
|
||||
else safe_delete(item);
|
||||
|
||||
if (found) {
|
||||
CalcBonuses();
|
||||
}
|
||||
|
||||
if (IsRecordLootStats()) {
|
||||
m_rolled_items.emplace_back(item->item_id);
|
||||
}
|
||||
|
||||
+19
-1
@@ -2875,6 +2875,16 @@ float Lua_Mob::GetDefaultRaceSize() {
|
||||
return self->GetDefaultRaceSize();
|
||||
}
|
||||
|
||||
float Lua_Mob::GetDefaultRaceSize(int race_id) {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetDefaultRaceSize(race_id);
|
||||
}
|
||||
|
||||
float Lua_Mob::GetDefaultRaceSize(int race_id, int gender_id) {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetDefaultRaceSize(race_id, gender_id);
|
||||
}
|
||||
|
||||
float Lua_Mob::GetActSpellRange(uint16 spell_id, float range) {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetActSpellRange(spell_id, range);
|
||||
@@ -3000,6 +3010,11 @@ luabind::object Lua_Mob::GetBuffSpellIDs(lua_State* L) {
|
||||
return t;
|
||||
}
|
||||
|
||||
bool Lua_Mob::HasSpellEffect(int effect_id) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasSpellEffect(effect_id);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_mob() {
|
||||
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
||||
.def(luabind::constructor<>())
|
||||
@@ -3212,7 +3227,9 @@ luabind::scope lua_register_mob() {
|
||||
.def("GetDEX", &Lua_Mob::GetDEX)
|
||||
.def("GetDR", &Lua_Mob::GetDR)
|
||||
.def("GetDamageAmount", (uint32(Lua_Mob::*)(Lua_Mob))&Lua_Mob::GetDamageAmount)
|
||||
.def("GetDefaultRaceSize", &Lua_Mob::GetDefaultRaceSize)
|
||||
.def("GetDefaultRaceSize", (float(Lua_Mob::*)(void))&Lua_Mob::GetDefaultRaceSize)
|
||||
.def("GetDefaultRaceSize", (float(Lua_Mob::*)(int))&Lua_Mob::GetDefaultRaceSize)
|
||||
.def("GetDefaultRaceSize", (float(Lua_Mob::*)(int,int))&Lua_Mob::GetDefaultRaceSize)
|
||||
.def("GetDeity", &Lua_Mob::GetDeity)
|
||||
.def("GetDisplayAC", &Lua_Mob::GetDisplayAC)
|
||||
.def("GetDrakkinDetails", &Lua_Mob::GetDrakkinDetails)
|
||||
@@ -3338,6 +3355,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("HasPet", (bool(Lua_Mob::*)(void))&Lua_Mob::HasPet)
|
||||
.def("HasProcs", &Lua_Mob::HasProcs)
|
||||
.def("HasShieldEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasShieldEquipped)
|
||||
.def("HasSpellEffect", &Lua_Mob::HasSpellEffect)
|
||||
.def("HasTimer", &Lua_Mob::HasTimer)
|
||||
.def("HasTwoHandBluntEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHandBluntEquipped)
|
||||
.def("HasTwoHanderEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHanderEquipped)
|
||||
|
||||
@@ -516,6 +516,8 @@ public:
|
||||
bool IsFindable();
|
||||
bool IsTrackable();
|
||||
float GetDefaultRaceSize();
|
||||
float GetDefaultRaceSize(int race_id);
|
||||
float GetDefaultRaceSize(int race_id, int gender_id);
|
||||
int64 GetActDoTDamage(uint16 spell_id, int64 value, Lua_Mob target);
|
||||
int64 GetActDoTDamage(uint16 spell_id, int64 value, Lua_Mob target, bool from_buff_tic);
|
||||
int64 GetActReflectedSpellDamage(uint16 spell_id, int64 value, int effectiveness);
|
||||
@@ -539,6 +541,7 @@ public:
|
||||
void StopAllTimers();
|
||||
void StopTimer(const char* timer_name);
|
||||
luabind::object GetBuffSpellIDs(lua_State* L);
|
||||
bool HasSpellEffect(int effect_id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -4302,7 +4302,7 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id,
|
||||
|
||||
const NPCType* npc_type_to_copy = nullptr;
|
||||
if (c) {
|
||||
const NPCType* npc_type_to_copy = content_db.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel());
|
||||
npc_type_to_copy = content_db.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel());
|
||||
}
|
||||
|
||||
if(npc_type_to_copy != nullptr)
|
||||
|
||||
@@ -307,7 +307,6 @@ private:
|
||||
int32 CalcCorrup();
|
||||
int64 CalcMaxHP();
|
||||
int64 CalcBaseHP();
|
||||
int64 GetClassHPFactor();
|
||||
int64 CalcHPRegen();
|
||||
int64 CalcHPRegenCap();
|
||||
int64 CalcMaxMana();
|
||||
|
||||
+13
-10
@@ -6227,20 +6227,20 @@ FACTION_VALUE Mob::GetSpecialFactionCon(Mob* iOther) {
|
||||
|
||||
bool Mob::HasSpellEffect(int effect_id)
|
||||
{
|
||||
int i;
|
||||
const auto buff_count = GetMaxTotalSlots();
|
||||
for (int i = 0; i < buff_count; i++) {
|
||||
const auto spell_id = buffs[i].spellid;
|
||||
|
||||
int buff_count = GetMaxTotalSlots();
|
||||
for(i = 0; i < buff_count; i++)
|
||||
{
|
||||
if (!IsValidSpell(buffs[i].spellid)) {
|
||||
if (!IsValidSpell(spell_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsEffectInSpell(buffs[i].spellid, effect_id)) {
|
||||
return(1);
|
||||
if (IsEffectInSpell(spell_id, effect_id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int Mob::GetSpecialAbility(int ability)
|
||||
@@ -6724,8 +6724,11 @@ void Mob::CommonBreakInvisible()
|
||||
CancelSneakHide();
|
||||
}
|
||||
|
||||
float Mob::GetDefaultRaceSize() const {
|
||||
return GetRaceGenderDefaultHeight(race, gender);
|
||||
float Mob::GetDefaultRaceSize(int race_id, int gender_id) const {
|
||||
return GetRaceGenderDefaultHeight(
|
||||
race_id > 0 ? race_id : race,
|
||||
gender_id >= 0 ? gender_id : gender
|
||||
);
|
||||
}
|
||||
|
||||
bool Mob::ShieldAbility(uint32 target_id, int shielder_max_distance, int shield_duration, int shield_target_mitigation, int shielder_mitigation, bool use_aa, bool can_shield_npc)
|
||||
|
||||
+1
-1
@@ -1205,7 +1205,7 @@ public:
|
||||
void SendTo(float new_x, float new_y, float new_z);
|
||||
void SendToFixZ(float new_x, float new_y, float new_z);
|
||||
float GetZOffset() const;
|
||||
float GetDefaultRaceSize() const;
|
||||
float GetDefaultRaceSize(int race_id = -1, int gender_id = -1) const;
|
||||
void FixZ(int32 z_find_offset = 5, bool fix_client_z = false);
|
||||
float GetFixedZ(const glm::vec3 &destination, int32 z_find_offset = 5);
|
||||
virtual int GetStuckBehavior() const { return 0; }
|
||||
|
||||
@@ -584,7 +584,6 @@ protected:
|
||||
uint32 npc_spells_id;
|
||||
uint8 casting_spell_AIindex;
|
||||
|
||||
uint32* pDontCastBefore_casting_spell;
|
||||
std::vector<AISpells_Struct> AIspells;
|
||||
bool HasAISpell;
|
||||
virtual bool AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes, bool bInnates = false);
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
class OrientedBoundingBox
|
||||
{
|
||||
public:
|
||||
OrientedBoundingBox() { }
|
||||
OrientedBoundingBox() = default;
|
||||
OrientedBoundingBox(const glm::vec3 &pos, const glm::vec3 &rot, const glm::vec3 &scale, const glm::vec3 &extents);
|
||||
~OrientedBoundingBox() { }
|
||||
~OrientedBoundingBox() = default;
|
||||
|
||||
bool ContainsPoint(const glm::vec3 &p) const;
|
||||
private:
|
||||
|
||||
+19
-1
@@ -2887,6 +2887,16 @@ float Perl_Mob_GetDefaultRaceSize(Mob* self) // @categories Script Utility
|
||||
return self->GetDefaultRaceSize();
|
||||
}
|
||||
|
||||
float Perl_Mob_GetDefaultRaceSize(Mob* self, int race_id) // @categories Script Utility
|
||||
{
|
||||
return self->GetDefaultRaceSize(race_id);
|
||||
}
|
||||
|
||||
float Perl_Mob_GetDefaultRaceSize(Mob* self, int race_id, int gender_id) // @categories Script Utility
|
||||
{
|
||||
return self->GetDefaultRaceSize(race_id, gender_id);
|
||||
}
|
||||
|
||||
uint32 Perl_Mob_GetRemainingTimeMS(Mob* self, const char* timer_name)
|
||||
{
|
||||
return quest_manager.getremainingtimeMS(timer_name, self);
|
||||
@@ -2950,6 +2960,11 @@ perl::array Perl_Mob_GetBuffSpellIDs(Mob* self)
|
||||
return l;
|
||||
}
|
||||
|
||||
bool Perl_Mob_HasSpellEffect(Mob* self, int effect_id)
|
||||
{
|
||||
return self->HasSpellEffect(effect_id);
|
||||
}
|
||||
|
||||
void perl_register_mob()
|
||||
{
|
||||
perl::interpreter perl(PERL_GET_THX);
|
||||
@@ -3141,7 +3156,9 @@ void perl_register_mob()
|
||||
package.add("GetClassName", &Perl_Mob_GetClassName);
|
||||
package.add("GetCleanName", &Perl_Mob_GetCleanName);
|
||||
package.add("GetCorruption", &Perl_Mob_GetCorruption);
|
||||
package.add("GetDefaultRaceSize", &Perl_Mob_GetDefaultRaceSize);
|
||||
package.add("GetDefaultRaceSize", (float(*)(Mob*))&Perl_Mob_GetDefaultRaceSize);
|
||||
package.add("GetDefaultRaceSize", (float(*)(Mob*, int))&Perl_Mob_GetDefaultRaceSize);
|
||||
package.add("GetDefaultRaceSize", (float(*)(Mob*, int, int))&Perl_Mob_GetDefaultRaceSize);
|
||||
package.add("GetDEX", &Perl_Mob_GetDEX);
|
||||
package.add("GetDR", &Perl_Mob_GetDR);
|
||||
package.add("GetDamageAmount", &Perl_Mob_GetDamageAmount);
|
||||
@@ -3272,6 +3289,7 @@ void perl_register_mob()
|
||||
package.add("HasPet", &Perl_Mob_HasPet);
|
||||
package.add("HasProcs", &Perl_Mob_HasProcs);
|
||||
package.add("HasShieldEquipped", &Perl_Mob_HasShieldEquipped);
|
||||
package.add("HasSpellEffect", &Perl_Mob_HasSpellEffect);
|
||||
package.add("HasTimer", &Perl_Mob_HasTimer);
|
||||
package.add("HasTwoHandBluntEquipped", &Perl_Mob_HasTwoHandBluntEquipped);
|
||||
package.add("HasTwoHanderEquipped", &Perl_Mob_HasTwoHanderEquipped);
|
||||
|
||||
@@ -75,103 +75,6 @@ void GetRandPetName(char *name)
|
||||
strn0cpy(name, temp.c_str(), 64);
|
||||
}
|
||||
|
||||
//not used anymore
|
||||
/*int CalcPetHp(int levelb, int classb, int STA)
|
||||
{
|
||||
int multiplier = 0;
|
||||
int base_hp = 0;
|
||||
switch(classb) {
|
||||
case WARRIOR:{
|
||||
if (levelb < 20)
|
||||
multiplier = 22;
|
||||
else if (levelb < 30)
|
||||
multiplier = 23;
|
||||
else if (levelb < 40)
|
||||
multiplier = 25;
|
||||
else if (levelb < 53)
|
||||
multiplier = 27;
|
||||
else if (levelb < 57)
|
||||
multiplier = 28;
|
||||
else
|
||||
multiplier = 30;
|
||||
break;
|
||||
}
|
||||
case DRUID:
|
||||
case CLERIC:
|
||||
case SHAMAN:{
|
||||
multiplier = 15;
|
||||
break;
|
||||
}
|
||||
case PALADIN:
|
||||
case SHADOWKNIGHT:{
|
||||
if (levelb < 35)
|
||||
multiplier = 21;
|
||||
else if (levelb < 45)
|
||||
multiplier = 22;
|
||||
else if (levelb < 51)
|
||||
multiplier = 23;
|
||||
else if (levelb < 56)
|
||||
multiplier = 24;
|
||||
else if (levelb < 60)
|
||||
multiplier = 25;
|
||||
else
|
||||
multiplier = 26;
|
||||
break;
|
||||
}
|
||||
case MONK:
|
||||
case BARD:
|
||||
case ROGUE:
|
||||
case BEASTLORD:{
|
||||
if (levelb < 51)
|
||||
multiplier = 18;
|
||||
else if (levelb < 58)
|
||||
multiplier = 19;
|
||||
else
|
||||
multiplier = 20;
|
||||
break;
|
||||
}
|
||||
case RANGER:{
|
||||
if (levelb < 58)
|
||||
multiplier = 20;
|
||||
else
|
||||
multiplier = 21;
|
||||
break;
|
||||
}
|
||||
case MAGICIAN:
|
||||
case WIZARD:
|
||||
case NECROMANCER:
|
||||
case ENCHANTER:{
|
||||
multiplier = 12;
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
if (levelb < 35)
|
||||
multiplier = 21;
|
||||
else if (levelb < 45)
|
||||
multiplier = 22;
|
||||
else if (levelb < 51)
|
||||
multiplier = 23;
|
||||
else if (levelb < 56)
|
||||
multiplier = 24;
|
||||
else if (levelb < 60)
|
||||
multiplier = 25;
|
||||
else
|
||||
multiplier = 26;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (multiplier == 0)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Multiplier == 0 in CalcPetHp,using Generic....");;
|
||||
multiplier=12;
|
||||
}
|
||||
|
||||
base_hp = 5 + (multiplier*levelb) + ((multiplier*levelb*STA) + 1)/300;
|
||||
return base_hp;
|
||||
}
|
||||
*/
|
||||
|
||||
void Mob::MakePet(uint16 spell_id, const char* pettype, const char *petname) {
|
||||
// petpower of -1 is used to get the petpower based on whichever focus is currently
|
||||
// equipped. This should replicate the old functionality for the most part.
|
||||
|
||||
+498
-293
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user