Compare commits

..

26 Commits

Author SHA1 Message Date
Chris Miles c64a2aec94 [Release] 22.11.0 (#3328)
* [Release] 22.11.0

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

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

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

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

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

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

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

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

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

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

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

* Update questmgr.cpp

* Update questmgr.cpp

* Update questmgr.cpp

* Update questmgr.cpp
2023-04-23 15:08:32 -04:00
Alex King e3761cf2a3 [Cleanup] Add check for owner in quest::resumetimer() (#3305)
# Notes
- We didn't check for owner before doing `owner->GetName()`.
2023-04-23 15:07:49 -04:00
Alex King ad1764b464 [Cleanup] Add cehck for owner in quest::pausetimer() (#3304)
# Notes
- We didn't check for `owner` before doing `owner->GetName()`.
2023-04-23 15:07:09 -04:00
Alex King 1c9ea57a4e [Cleanup] Fix possible nullptr in quest::addloot() (#3303)
# Notes
- We didn't check for `owner` before calling `owner->IsNPC()`.
2023-04-23 15:06:53 -04:00
Alex King 03c158b674 [Crash] Fix possible nullptr in Client::GetCharMaxLevelFromQGlobal() (#3317)
# Notes
- We could possibly not have a `zone` here, causing a crash.
- http://spire.akkadius.com/dev/release/22.9.1?id=3051
- http://spire.akkadius.com/dev/release/22.9.1?id=3052
- http://spire.akkadius.com/dev/release/22.9.1?id=3073
- http://spire.akkadius.com/dev/release/22.9.1?id=3102
- http://spire.akkadius.com/dev/release/22.9.1?id=3103
- http://spire.akkadius.com/dev/release/22.9.1?id=3104
- http://spire.akkadius.com/dev/release/22.9.1?id=3107
- http://spire.akkadius.com/dev/release/22.9.1?id=3108
- http://spire.akkadius.com/dev/release/22.9.1?id=3109
- http://spire.akkadius.com/dev/release/22.9.1?id=3110
- http://spire.akkadius.com/dev/release/22.9.1?id=3111
- http://spire.akkadius.com/dev/release/22.9.1?id=3112
- http://spire.akkadius.com/dev/release/22.9.1?id=3113
- http://spire.akkadius.com/dev/release/22.9.1?id=3114
2023-04-23 15:05:47 -04:00
Aeadoin 39b5374e92 [Crash] Fix possible dereference of nullptr in Client::CalcHPRegen (#3316) 2023-04-23 14:27:43 -04:00
28 changed files with 657 additions and 530 deletions
+48
View File
@@ -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
-3
View File
@@ -41,9 +41,6 @@ void SendCrashReport(const std::string &crash_report)
r.set_connection_timeout(1, 0);
r.set_read_timeout(1, 0);
r.set_write_timeout(1, 0);
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
// os info
auto os = EQ::GetOS();
+1 -1
View File
@@ -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
View File
@@ -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"
+2
View File
@@ -144,6 +144,8 @@ int main() {
->LoadLogDatabaseSettings()
->StartFileLogs();
player_event_logs.SetDatabase(&database)->Init();
char tmp[64];
// ucs has no 'reload rules' handler
+1 -15
View File
@@ -1801,23 +1801,9 @@ sub fetch_peq_db_full
sub map_files_fetch_bulk
{
print "[Install] Fetching Latest Maps... (This could take a few minutes...)\n";
get_remote_file("http://analytics.akkadius.com/maps.zip", "maps/maps.zip", 1);
get_remote_file("https://github.com/Akkadius/eqemu-maps/releases/latest/download/maps.zip", "maps/maps.zip", 1);
unzip('maps/maps.zip', 'maps/');
my @files;
my $start_dir = "maps/EQEmuMaps-master/";
find(
sub { push @files, $File::Find::name unless -d; },
$start_dir
);
for my $file (@files) {
$destination_file = $file;
$destination_file =~ s/maps\/EQEmuMaps-master\///g;
print "[Install] Installing [" . $destination_file . "]\n";
copy_file($file, "maps/" . $destination_file);
}
print "[Install] Fetched Latest Maps\n";
rmtree('maps/EQEmuMaps-master');
unlink('maps/maps.zip');
}
+1
View File
@@ -17,6 +17,7 @@ public:
void Disconnect() { if(connection && connection->Handle()) connection->Handle()->Disconnect(); }
void SendMessage(const char *From, const char *Message);
const std::shared_ptr<EQ::Net::ServertalkServerConnection> &GetConnection() const;
inline bool IsConnected() const { return connection->Handle() ? connection->Handle()->IsConnected() : false; }
private:
inline std::string GetIP() const { return (connection && connection->Handle()) ? connection->Handle()->RemoteIP() : 0; }
+17
View File
@@ -300,6 +300,8 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
->SetLogPath(path.GetLogPath())
->LoadLogDatabaseSettings();
LogSys.SetDiscordHandler(&WorldBoot::DiscordWebhookMessageHandler);
if (!ignore_db) {
LogInfo("Checking Database Conversions");
database.CheckDatabaseConversions();
@@ -662,3 +664,18 @@ void WorldBoot::Shutdown()
safe_delete(mutex);
}
void WorldBoot::SendDiscordMessage(int webhook_id, const std::string &message)
{
if (UCSLink.IsConnected()) {
auto pack = new ServerPacket(ServerOP_DiscordWebhookMessage, sizeof(DiscordWebhookMessage_Struct) + 1);
auto *q = (DiscordWebhookMessage_Struct *) pack->pBuffer;
strn0cpy(q->message, message.c_str(), 2000);
q->webhook_id = webhook_id;
UCSLink.SendPacket(pack);
safe_delete(pack);
}
}
+13
View File
@@ -3,6 +3,9 @@
#include <string>
#include "../common/types.h"
#include "../common/discord/discord.h"
extern UCSConnection UCSLink;
class WorldBoot {
public:
@@ -16,6 +19,16 @@ public:
static bool DatabaseLoadRoutines(int argc, char **argv);
static void CheckForPossibleConfigurationIssues();
static void Shutdown();
static void SendDiscordMessage(int webhook_id, const std::string& message);
static void DiscordWebhookMessageHandler(uint16 log_category, int webhook_id, const std::string &message)
{
std::string message_prefix = fmt::format(
"[**{}**] **World** ",
Logs::LogCategoryName[log_category]
);
SendDiscordMessage(webhook_id, message_prefix + Discord::FormatDiscordMessage(log_category, message));
};
};
+5 -11
View File
@@ -58,16 +58,10 @@ void Mob::CalcBonuses()
void NPC::CalcBonuses()
{
memset(&itembonuses, 0, sizeof(StatBonuses));
if (RuleB(NPC, UseItemBonusesForNonPets)) {
memset(&itembonuses, 0, sizeof(StatBonuses));
if (GetOwner() || RuleB(NPC, UseItemBonusesForNonPets)) {
CalcItemBonuses(&itembonuses);
}
else {
if (GetOwner()) {
memset(&itembonuses, 0, sizeof(StatBonuses));
CalcItemBonuses(&itembonuses);
}
}
// This has to happen last, so we actually take the item bonuses into account.
Mob::CalcBonuses();
@@ -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;
-23
View File
@@ -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 (
-2
View File
@@ -196,10 +196,8 @@ public:
void SetAttackTimer() override;
uint64 GetClassHPFactor();
int64 CalcMaxHP() override;
bool DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
bool DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
void SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color);
void Camp(bool save_to_database = true);
void SetTarget(Mob* mob) override;
void Zone();
+2 -9
View File
@@ -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
-7
View File
@@ -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
View File
@@ -288,7 +288,7 @@ int64 Client::CalcHPRegen(bool bCombat)
if (!bCombat && CanFastRegen() && (IsSitting() || CanMedOnHorse())) {
auto max_hp = GetMaxHP();
int fast_regen = 6 * (max_hp / zone->newzone_data.fast_regen_hp);
int64 fast_regen = 6 * (max_hp / (zone ? zone->newzone_data.fast_regen_hp : 180));
if (base < fast_regen) // weird, but what the client is doing
base = fast_regen;
}
@@ -506,50 +506,6 @@ int64 Client::CalcBaseHP()
return base_hp;
}
// This is for calculating Base HPs + STA bonus for SoD or later clients.
uint64 Client::GetClassHPFactor()
{
int factor;
// Note: Base HP factor under level 41 is equal to factor / 12, and from level 41 to 80 is factor / 6.
// Base HP over level 80 is factor / 10
// HP per STA point per level is factor / 30 for level 80+
// HP per STA under level 40 is the level 80 HP Per STA / 120, and for over 40 it is / 60.
switch (GetClass()) {
case DRUID:
case ENCHANTER:
case NECROMANCER:
case MAGICIAN:
case WIZARD:
factor = 240;
break;
case BEASTLORD:
case BERSERKER:
case MONK:
case ROGUE:
case SHAMAN:
factor = 255;
break;
case BARD:
case CLERIC:
factor = 264;
break;
case SHADOWKNIGHT:
case PALADIN:
factor = 288;
break;
case RANGER:
factor = 276;
break;
case WARRIOR:
factor = 300;
break;
default:
factor = 240;
break;
}
return factor;
}
// This should return the combined AC of all the items the player is wearing.
int32 Client::GetRawItemAC()
{
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+3
View File
@@ -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
View File
@@ -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)
-1
View File
@@ -307,7 +307,6 @@ private:
int32 CalcCorrup();
int64 CalcMaxHP();
int64 CalcBaseHP();
int64 GetClassHPFactor();
int64 CalcHPRegen();
int64 CalcHPRegenCap();
int64 CalcMaxMana();
+13 -10
View File
@@ -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
View File
@@ -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; }
-1
View File
@@ -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);
+2 -2
View File
@@ -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
View File
@@ -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);
-97
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff