mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 09:31:30 +00:00
Merge branch 'master' of https://github.com/EQEmu/Server into io_work
# Conflicts: # common/ruletypes.h
This commit is contained in:
commit
eefe0dfbb7
@ -459,4 +459,9 @@ enum ChatChannelNames : uint16
|
|||||||
ChatChannel_Emotes = 22
|
ChatChannel_Emotes = 22
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace ZoneBlockedSpellTypes {
|
||||||
|
const uint8 ZoneWide = 1;
|
||||||
|
const uint8 Region = 2;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
@ -342,6 +342,7 @@ RULE_INT(Spells, CharismaEffectiveness, 10, "Deterimes how much resist modificat
|
|||||||
RULE_INT(Spells, CharismaEffectivenessCap, 255, "Deterimes how much resist modification charisma applies to charm/pacify checks. Default 10 CHA = -1 resist mod")
|
RULE_INT(Spells, CharismaEffectivenessCap, 255, "Deterimes how much resist modification charisma applies to charm/pacify checks. Default 10 CHA = -1 resist mod")
|
||||||
RULE_BOOL(Spells, CharismaCharmDuration, false, "Allow CHA resist mod to extend charm duration")
|
RULE_BOOL(Spells, CharismaCharmDuration, false, "Allow CHA resist mod to extend charm duration")
|
||||||
RULE_INT(Spells, CharmBreakCheckChance, 25, "Determines chance for a charm break check to occur each buff tick")
|
RULE_INT(Spells, CharmBreakCheckChance, 25, "Determines chance for a charm break check to occur each buff tick")
|
||||||
|
RULE_BOOL(Spells, CharmDisablesSpecialAbilities, false, "When charm is cast on an NPC, strip their special abilities")
|
||||||
RULE_INT(Spells, MaxCastTimeReduction, 50, "Max percent your spell cast time can be reduced by spell haste")
|
RULE_INT(Spells, MaxCastTimeReduction, 50, "Max percent your spell cast time can be reduced by spell haste")
|
||||||
RULE_INT(Spells, RootBreakFromSpells, 55, "Chance for root to break when cast on")
|
RULE_INT(Spells, RootBreakFromSpells, 55, "Chance for root to break when cast on")
|
||||||
RULE_INT(Spells, DeathSaveCharismaMod, 3, "Determines how much charisma effects chance of death save firing")
|
RULE_INT(Spells, DeathSaveCharismaMod, 3, "Determines how much charisma effects chance of death save firing")
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9141
|
#define CURRENT_BINARY_DATABASE_VERSION 9142
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9025
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9025
|
||||||
|
|||||||
@ -395,6 +395,7 @@
|
|||||||
9139|2019_03_25_optional_npc_model.sql|SHOW COLUMNS FROM `npc_types` LIKE 'model'|empty|
|
9139|2019_03_25_optional_npc_model.sql|SHOW COLUMNS FROM `npc_types` LIKE 'model'|empty|
|
||||||
9140|2019_07_03_update_range.sql|SHOW COLUMNS FROM `zone` LIKE 'max_movement_update_range'|empty|
|
9140|2019_07_03_update_range.sql|SHOW COLUMNS FROM `zone` LIKE 'max_movement_update_range'|empty|
|
||||||
9141|2019_07_10_npc_flymode.sql|SHOW COLUMNS FROM `npc_types` LIKE 'flymode'|empty|
|
9141|2019_07_10_npc_flymode.sql|SHOW COLUMNS FROM `npc_types` LIKE 'flymode'|empty|
|
||||||
|
9142|2019_09_02_required_spawn_filter.sql|SHOW COLUMNS FROM `spawnentry` LIKE 'condition_value_filter'|empty|
|
||||||
|
|
||||||
# Upgrade conditions:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `spawnentry` ADD COLUMN `condition_value_filter` MEDIUMINT(9) NOT NULL DEFAULT '1' AFTER `chance`;
|
||||||
@ -803,7 +803,7 @@ Json::Value ApiGetZoneAttributes(EQ::Net::WebsocketServerConnection *connection,
|
|||||||
row["mobs_aggro_count"] = zone->MobsAggroCount();
|
row["mobs_aggro_count"] = zone->MobsAggroCount();
|
||||||
row["save_zone_cfg"] = zone->SaveZoneCFG();
|
row["save_zone_cfg"] = zone->SaveZoneCFG();
|
||||||
row["short_name"] = zone->GetShortName();
|
row["short_name"] = zone->GetShortName();
|
||||||
row["total_blocked_spells"] = zone->GetTotalBlockedSpells();
|
row["total_blocked_spells"] = zone->GetZoneTotalBlockedSpells();
|
||||||
row["zone_id"] = zone->GetZoneID();
|
row["zone_id"] = zone->GetZoneID();
|
||||||
row["zone_type"] = zone->GetZoneType();
|
row["zone_type"] = zone->GetZoneType();
|
||||||
|
|
||||||
|
|||||||
@ -1387,13 +1387,13 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
|| (GetHP() < 0)
|
|| (GetHP() < 0)
|
||||||
|| (!IsAttackAllowed(other))
|
|| (!IsAttackAllowed(other))
|
||||||
) {
|
) {
|
||||||
Log(Logs::Detail, Logs::Combat, "Attack canceled, invalid circumstances.");
|
Log(Logs::Detail, Logs::Combat, "Attack cancelled, invalid circumstances.");
|
||||||
return false; // Only bards can attack while casting
|
return false; // Only bards can attack while casting
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DivineAura() && !GetGM()) {//cant attack while invulnerable unless your a gm
|
if (DivineAura() && !GetGM()) {//cant attack while invulnerable unless your a gm
|
||||||
Log(Logs::Detail, Logs::Combat, "Attack canceled, Divine Aura is in effect.");
|
Log(Logs::Detail, Logs::Combat, "Attack cancelled, Divine Aura is in effect.");
|
||||||
MessageString(Chat::DefaultText, DIVINE_AURA_NO_ATK); //You can't attack while invulnerable!
|
MessageString(Chat::DefaultText, DIVINE_AURA_NO_ATK); //You can't attack while invulnerable
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1412,7 +1412,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
|
|
||||||
if (weapon != nullptr) {
|
if (weapon != nullptr) {
|
||||||
if (!weapon->IsWeapon()) {
|
if (!weapon->IsWeapon()) {
|
||||||
Log(Logs::Detail, Logs::Combat, "Attack canceled, Item %s (%d) is not a weapon.", weapon->GetItem()->Name, weapon->GetID());
|
Log(Logs::Detail, Logs::Combat, "Attack cancelled, Item %s (%d) is not a weapon.", weapon->GetItem()->Name, weapon->GetID());
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
Log(Logs::Detail, Logs::Combat, "Attacking with weapon: %s (%d)", weapon->GetItem()->Name, weapon->GetID());
|
Log(Logs::Detail, Logs::Combat, "Attacking with weapon: %s (%d)", weapon->GetItem()->Name, weapon->GetID());
|
||||||
@ -1952,8 +1952,8 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
|||||||
if (weapon) {
|
if (weapon) {
|
||||||
Log(Logs::Detail, Logs::Combat, "Attacking with weapon: %s (%d) (too bad im not using it for much)", weapon->Name, weapon->ID);
|
Log(Logs::Detail, Logs::Combat, "Attacking with weapon: %s (%d) (too bad im not using it for much)", weapon->Name, weapon->ID);
|
||||||
|
|
||||||
if (Hand == EQEmu::invslot::slotSecondary && weapon->ItemType == EQEmu::item::ItemTypeShield) {
|
if (Hand == EQEmu::invslot::slotSecondary && !weapon->IsType1HWeapon()) {
|
||||||
Log(Logs::Detail, Logs::Combat, "Attack with shield canceled.");
|
Log(Logs::Detail, Logs::Combat, "Attack with non-weapon cancelled.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3941,7 +3941,7 @@ void Mob::TryWeaponProc(const EQEmu::ItemInstance* weapon_g, Mob *on, uint16 han
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (DivineAura()) {
|
if (DivineAura()) {
|
||||||
Log(Logs::Detail, Logs::Combat, "Procs canceled, Divine Aura is in effect.");
|
Log(Logs::Detail, Logs::Combat, "Procs cancelled, Divine Aura is in effect.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1205,8 +1205,12 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_CastingLevel2:
|
|
||||||
case SE_CastingLevel: {
|
case SE_CastingLevel: {
|
||||||
|
newbon->adjusted_casting_skill += base1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SE_CastingLevel2: {
|
||||||
newbon->effective_casting_level += base1;
|
newbon->effective_casting_level += base1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1914,8 +1918,13 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_CastingLevel2:
|
|
||||||
case SE_CastingLevel: // Brilliance of Ro
|
case SE_CastingLevel: // Brilliance of Ro
|
||||||
|
{
|
||||||
|
new_bonus->adjusted_casting_skill += effect_value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SE_CastingLevel2:
|
||||||
{
|
{
|
||||||
new_bonus->effective_casting_level += effect_value;
|
new_bonus->effective_casting_level += effect_value;
|
||||||
break;
|
break;
|
||||||
@ -3850,8 +3859,13 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
|||||||
aabonuses.Corrup = effect_value;
|
aabonuses.Corrup = effect_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_CastingLevel2:
|
|
||||||
case SE_CastingLevel: // Brilliance of Ro
|
case SE_CastingLevel: // Brilliance of Ro
|
||||||
|
spellbonuses.adjusted_casting_skill = effect_value;
|
||||||
|
aabonuses.adjusted_casting_skill = effect_value;
|
||||||
|
itembonuses.adjusted_casting_skill = effect_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SE_CastingLevel2:
|
||||||
spellbonuses.effective_casting_level = effect_value;
|
spellbonuses.effective_casting_level = effect_value;
|
||||||
aabonuses.effective_casting_level = effect_value;
|
aabonuses.effective_casting_level = effect_value;
|
||||||
itembonuses.effective_casting_level = effect_value;
|
itembonuses.effective_casting_level = effect_value;
|
||||||
|
|||||||
@ -2852,12 +2852,16 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app)
|
|||||||
// Poisons that don't proc until a level higher than the
|
// Poisons that don't proc until a level higher than the
|
||||||
// rogue simply won't apply at all, no skill check done.
|
// rogue simply won't apply at all, no skill check done.
|
||||||
|
|
||||||
if (ChanceRoll < (.9 + GetLevel()/1000)) {
|
uint16 poison_skill = GetSkill(EQEmu::skills::SkillApplyPoison);
|
||||||
|
|
||||||
|
if (ChanceRoll < (.75 + poison_skill / 1000)) {
|
||||||
ApplyPoisonSuccessResult = 1;
|
ApplyPoisonSuccessResult = 1;
|
||||||
AddProcToWeapon(poison->Proc.Effect, false,
|
AddProcToWeapon(poison->Proc.Effect, false, (GetDEX() / 100) + 103);
|
||||||
(GetDEX() / 100) + 103);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Message(Chat::Red, "A piercing weapon must be wielded to apply poison.");
|
||||||
|
}
|
||||||
|
|
||||||
// Live always deletes the item, success or failure. Even if too high.
|
// Live always deletes the item, success or failure. Even if too high.
|
||||||
DeleteItemInInventory(ApplyPoisonData->inventorySlot, 1, true);
|
DeleteItemInInventory(ApplyPoisonData->inventorySlot, 1, true);
|
||||||
|
|||||||
@ -388,6 +388,7 @@ struct StatBonuses {
|
|||||||
int32 skillmod[EQEmu::skills::HIGHEST_SKILL + 1];
|
int32 skillmod[EQEmu::skills::HIGHEST_SKILL + 1];
|
||||||
int32 skillmodmax[EQEmu::skills::HIGHEST_SKILL + 1];
|
int32 skillmodmax[EQEmu::skills::HIGHEST_SKILL + 1];
|
||||||
int effective_casting_level;
|
int effective_casting_level;
|
||||||
|
int adjusted_casting_skill; // SPA 112 for fizzles
|
||||||
int reflect_chance; // chance to reflect incoming spell
|
int reflect_chance; // chance to reflect incoming spell
|
||||||
uint32 singingMod;
|
uint32 singingMod;
|
||||||
uint32 Amplification; // stacks with singingMod
|
uint32 Amplification; // stacks with singingMod
|
||||||
|
|||||||
@ -352,7 +352,7 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch
|
|||||||
}
|
}
|
||||||
else if (foundslot == EQEmu::invslot::slotSecondary
|
else if (foundslot == EQEmu::invslot::slotSecondary
|
||||||
&& (GetOwner() != nullptr || (CanThisClassDualWield() && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) &&
|
&& (GetOwner() != nullptr || (CanThisClassDualWield() && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) &&
|
||||||
(item2->IsType1HWeapon() || item2->ItemType == EQEmu::item::ItemTypeShield))
|
(item2->IsType1HWeapon() || item2->ItemType == EQEmu::item::ItemTypeShield || item2->ItemType == EQEmu::item::ItemTypeLight))
|
||||||
{
|
{
|
||||||
if (item2->Proc.Effect!=0)
|
if (item2->Proc.Effect!=0)
|
||||||
CastToMob()->AddProcToWeapon(item2->Proc.Effect, true);
|
CastToMob()->AddProcToWeapon(item2->Proc.Effect, true);
|
||||||
|
|||||||
@ -333,6 +333,11 @@ int Lua_StatBonuses::Geteffective_casting_level() const {
|
|||||||
return self->effective_casting_level;
|
return self->effective_casting_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Lua_StatBonuses::Getadjusted_casting_skill() const {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->adjusted_casting_skill;
|
||||||
|
}
|
||||||
|
|
||||||
int Lua_StatBonuses::Getreflect_chance() const {
|
int Lua_StatBonuses::Getreflect_chance() const {
|
||||||
Lua_Safe_Call_Int();
|
Lua_Safe_Call_Int();
|
||||||
return self->reflect_chance;
|
return self->reflect_chance;
|
||||||
@ -1347,6 +1352,7 @@ luabind::scope lua_register_stat_bonuses() {
|
|||||||
.def("skillmod", &Lua_StatBonuses::Getskillmod)
|
.def("skillmod", &Lua_StatBonuses::Getskillmod)
|
||||||
.def("skillmodmax", &Lua_StatBonuses::Getskillmodmax)
|
.def("skillmodmax", &Lua_StatBonuses::Getskillmodmax)
|
||||||
.def("effective_casting_level", &Lua_StatBonuses::Geteffective_casting_level)
|
.def("effective_casting_level", &Lua_StatBonuses::Geteffective_casting_level)
|
||||||
|
.def("adjusted_casting_skill", &Lua_StatBonuses::Getadjusted_casting_skill)
|
||||||
.def("reflect_chance", &Lua_StatBonuses::Getreflect_chance)
|
.def("reflect_chance", &Lua_StatBonuses::Getreflect_chance)
|
||||||
.def("singingMod", &Lua_StatBonuses::GetsingingMod)
|
.def("singingMod", &Lua_StatBonuses::GetsingingMod)
|
||||||
.def("Amplification", &Lua_StatBonuses::GetAmplification)
|
.def("Amplification", &Lua_StatBonuses::GetAmplification)
|
||||||
|
|||||||
@ -91,6 +91,7 @@ public:
|
|||||||
int32 Getskillmod(int idx) const;
|
int32 Getskillmod(int idx) const;
|
||||||
int32 Getskillmodmax(int idx) const;
|
int32 Getskillmodmax(int idx) const;
|
||||||
int Geteffective_casting_level() const;
|
int Geteffective_casting_level() const;
|
||||||
|
int Getadjusted_casting_skill() const;
|
||||||
int Getreflect_chance() const;
|
int Getreflect_chance() const;
|
||||||
uint32 GetsingingMod() const;
|
uint32 GetsingingMod() const;
|
||||||
uint32 GetAmplification() const;
|
uint32 GetAmplification() const;
|
||||||
|
|||||||
67
zone/npc.cpp
67
zone/npc.cpp
@ -209,6 +209,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
default_accuracy_rating = npc_type_data->accuracy_rating;
|
default_accuracy_rating = npc_type_data->accuracy_rating;
|
||||||
default_avoidance_rating = npc_type_data->avoidance_rating;
|
default_avoidance_rating = npc_type_data->avoidance_rating;
|
||||||
default_atk = npc_type_data->ATK;
|
default_atk = npc_type_data->ATK;
|
||||||
|
strn0cpy(default_special_abilities, npc_type_data->special_abilities, 512);
|
||||||
|
|
||||||
// used for when getting charmed, if 0, doesn't swap
|
// used for when getting charmed, if 0, doesn't swap
|
||||||
charm_ac = npc_type_data->charm_ac;
|
charm_ac = npc_type_data->charm_ac;
|
||||||
@ -2838,39 +2839,61 @@ void NPC::DepopSwarmPets()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::ModifyStatsOnCharm(bool bRemoved)
|
void NPC::ModifyStatsOnCharm(bool is_charm_removed)
|
||||||
{
|
{
|
||||||
if (bRemoved) {
|
if (is_charm_removed) {
|
||||||
if (charm_ac)
|
if (charm_ac) {
|
||||||
AC = default_ac;
|
AC = default_ac;
|
||||||
if (charm_attack_delay)
|
}
|
||||||
|
if (charm_attack_delay) {
|
||||||
attack_delay = default_attack_delay;
|
attack_delay = default_attack_delay;
|
||||||
if (charm_accuracy_rating)
|
}
|
||||||
|
if (charm_accuracy_rating) {
|
||||||
accuracy_rating = default_accuracy_rating;
|
accuracy_rating = default_accuracy_rating;
|
||||||
if (charm_avoidance_rating)
|
}
|
||||||
|
if (charm_avoidance_rating) {
|
||||||
avoidance_rating = default_avoidance_rating;
|
avoidance_rating = default_avoidance_rating;
|
||||||
if (charm_atk)
|
}
|
||||||
|
if (charm_atk) {
|
||||||
ATK = default_atk;
|
ATK = default_atk;
|
||||||
|
}
|
||||||
if (charm_min_dmg || charm_max_dmg) {
|
if (charm_min_dmg || charm_max_dmg) {
|
||||||
base_damage = round((default_max_dmg - default_min_dmg) / 1.9);
|
base_damage = round((default_max_dmg - default_min_dmg) / 1.9);
|
||||||
min_damage = default_min_dmg - round(base_damage / 10.0);
|
min_damage = default_min_dmg - round(base_damage / 10.0);
|
||||||
}
|
}
|
||||||
} else {
|
if (RuleB(Spells, CharmDisablesSpecialAbilities)) {
|
||||||
if (charm_ac)
|
ProcessSpecialAbilities(default_special_abilities);
|
||||||
AC = charm_ac;
|
|
||||||
if (charm_attack_delay)
|
|
||||||
attack_delay = charm_attack_delay;
|
|
||||||
if (charm_accuracy_rating)
|
|
||||||
accuracy_rating = charm_accuracy_rating;
|
|
||||||
if (charm_avoidance_rating)
|
|
||||||
avoidance_rating = charm_avoidance_rating;
|
|
||||||
if (charm_atk)
|
|
||||||
ATK = charm_atk;
|
|
||||||
if (charm_min_dmg || charm_max_dmg) {
|
|
||||||
base_damage = round((charm_max_dmg - charm_min_dmg) / 1.9);
|
|
||||||
min_damage = charm_min_dmg - round(base_damage / 10.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetAttackTimer();
|
||||||
|
CalcAC();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (charm_ac) {
|
||||||
|
AC = charm_ac;
|
||||||
|
}
|
||||||
|
if (charm_attack_delay) {
|
||||||
|
attack_delay = charm_attack_delay;
|
||||||
|
}
|
||||||
|
if (charm_accuracy_rating) {
|
||||||
|
accuracy_rating = charm_accuracy_rating;
|
||||||
|
}
|
||||||
|
if (charm_avoidance_rating) {
|
||||||
|
avoidance_rating = charm_avoidance_rating;
|
||||||
|
}
|
||||||
|
if (charm_atk) {
|
||||||
|
ATK = charm_atk;
|
||||||
|
}
|
||||||
|
if (charm_min_dmg || charm_max_dmg) {
|
||||||
|
base_damage = round((charm_max_dmg - charm_min_dmg) / 1.9);
|
||||||
|
min_damage = charm_min_dmg - round(base_damage / 10.0);
|
||||||
|
}
|
||||||
|
if (RuleB(Spells, CharmDisablesSpecialAbilities)) {
|
||||||
|
ClearSpecialAbilities();
|
||||||
|
}
|
||||||
|
|
||||||
// the rest of the stats aren't cached, so lets just do these two instead of full CalcBonuses()
|
// the rest of the stats aren't cached, so lets just do these two instead of full CalcBonuses()
|
||||||
SetAttackTimer();
|
SetAttackTimer();
|
||||||
CalcAC();
|
CalcAC();
|
||||||
|
|||||||
@ -294,7 +294,7 @@ public:
|
|||||||
int32 GetNPCHPRegen() const { return hp_regen + itembonuses.HPRegen + spellbonuses.HPRegen; }
|
int32 GetNPCHPRegen() const { return hp_regen + itembonuses.HPRegen + spellbonuses.HPRegen; }
|
||||||
inline const char* GetAmmoIDfile() const { return ammo_idfile; }
|
inline const char* GetAmmoIDfile() const { return ammo_idfile; }
|
||||||
|
|
||||||
void ModifyStatsOnCharm(bool bRemoved);
|
void ModifyStatsOnCharm(bool is_charm_removed);
|
||||||
|
|
||||||
//waypoint crap
|
//waypoint crap
|
||||||
int GetMaxWp() const { return max_wp; }
|
int GetMaxWp() const { return max_wp; }
|
||||||
@ -541,6 +541,7 @@ protected:
|
|||||||
int default_accuracy_rating;
|
int default_accuracy_rating;
|
||||||
int default_avoidance_rating;
|
int default_avoidance_rating;
|
||||||
int default_atk;
|
int default_atk;
|
||||||
|
char default_special_abilities[512];
|
||||||
|
|
||||||
// when charmed, switch to these
|
// when charmed, switch to these
|
||||||
int charm_ac;
|
int charm_ac;
|
||||||
|
|||||||
@ -443,6 +443,14 @@ bool Object::Process(){
|
|||||||
if(m_ground_spawn && respawn_timer.Check()){
|
if(m_ground_spawn && respawn_timer.Check()){
|
||||||
RandomSpawn(true);
|
RandomSpawn(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user != nullptr && !entity_list.GetClientByCharID(user->CharacterID())) {
|
||||||
|
m_inuse = false;
|
||||||
|
last_user = user;
|
||||||
|
user->SetTradeskillObject(nullptr);
|
||||||
|
user = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,7 +562,6 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
|||||||
ClickObjectAction_Struct* coa = (ClickObjectAction_Struct*)outapp->pBuffer;
|
ClickObjectAction_Struct* coa = (ClickObjectAction_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
//TODO: there is prolly a better way to do this.
|
//TODO: there is prolly a better way to do this.
|
||||||
m_inuse = true;
|
|
||||||
coa->type = m_type;
|
coa->type = m_type;
|
||||||
coa->unknown16 = 0x0a;
|
coa->unknown16 = 0x0a;
|
||||||
|
|
||||||
@ -576,12 +583,6 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sender->IsLooting())
|
|
||||||
{
|
|
||||||
coa->open = 0x00;
|
|
||||||
user = sender;
|
|
||||||
}
|
|
||||||
|
|
||||||
sender->QueuePacket(outapp);
|
sender->QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
@ -590,6 +591,7 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
|||||||
return(false);
|
return(false);
|
||||||
|
|
||||||
// Starting to use this object
|
// Starting to use this object
|
||||||
|
m_inuse = true;
|
||||||
sender->SetTradeskillObject(this);
|
sender->SetTradeskillObject(this);
|
||||||
|
|
||||||
user = sender;
|
user = sender;
|
||||||
|
|||||||
@ -258,7 +258,16 @@ Mob *QuestManager::spawn_from_spawn2(uint32 spawn2_id)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32 npcid = spawn_group->GetNPCType();
|
|
||||||
|
uint16 condition_value=1;
|
||||||
|
uint16 condition_id=found_spawn->GetSpawnCondition();
|
||||||
|
|
||||||
|
if (condition_id > 0) {
|
||||||
|
condition_value = zone->spawn_conditions.GetCondition(zone->GetShortName(), zone->GetInstanceID(), condition_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 npcid = spawn_group->GetNPCType(condition_value);
|
||||||
|
|
||||||
if (npcid == 0) {
|
if (npcid == 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -184,12 +184,18 @@ bool Spawn2::Process() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16 condition_value=1;
|
||||||
|
|
||||||
|
if (condition_id > 0) {
|
||||||
|
condition_value = zone->spawn_conditions.GetCondition(zone->GetShortName(), zone->GetInstanceID(), condition_id);
|
||||||
|
}
|
||||||
|
|
||||||
//have the spawn group pick an NPC for us
|
//have the spawn group pick an NPC for us
|
||||||
uint32 npcid = spawn_group->GetNPCType();
|
uint32 npcid = spawn_group->GetNPCType(condition_value);
|
||||||
if (npcid == 0) {
|
if (npcid == 0) {
|
||||||
Log(Logs::Detail,
|
Log(Logs::Detail,
|
||||||
Logs::Spawns,
|
Logs::Spawns,
|
||||||
"Spawn2 %d: Spawn group %d did not yeild an NPC! not spawning.",
|
"Spawn2 %d: Spawn group %d did not yield an NPC! not spawning.",
|
||||||
spawn2_id,
|
spawn2_id,
|
||||||
spawngroup_id_);
|
spawngroup_id_);
|
||||||
|
|
||||||
@ -202,7 +208,7 @@ bool Spawn2::Process() {
|
|||||||
if (tmp == nullptr) {
|
if (tmp == nullptr) {
|
||||||
Log(Logs::Detail,
|
Log(Logs::Detail,
|
||||||
Logs::Spawns,
|
Logs::Spawns,
|
||||||
"Spawn2 %d: Spawn group %d yeilded an invalid NPC type %d",
|
"Spawn2 %d: Spawn group %d yielded an invalid NPC type %d",
|
||||||
spawn2_id,
|
spawn2_id,
|
||||||
spawngroup_id_,
|
spawngroup_id_,
|
||||||
npcid);
|
npcid);
|
||||||
@ -214,7 +220,7 @@ bool Spawn2::Process() {
|
|||||||
if (!entity_list.LimitCheckName(tmp->name)) {
|
if (!entity_list.LimitCheckName(tmp->name)) {
|
||||||
Log(Logs::Detail,
|
Log(Logs::Detail,
|
||||||
Logs::Spawns,
|
Logs::Spawns,
|
||||||
"Spawn2 %d: Spawn group %d yeilded NPC type %d, which is unique and one already exists.",
|
"Spawn2 %d: Spawn group %d yielded NPC type %d, which is unique and one already exists.",
|
||||||
spawn2_id,
|
spawn2_id,
|
||||||
spawngroup_id_,
|
spawngroup_id_,
|
||||||
npcid);
|
npcid);
|
||||||
@ -227,7 +233,7 @@ bool Spawn2::Process() {
|
|||||||
if (!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) {
|
if (!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) {
|
||||||
Log(Logs::Detail,
|
Log(Logs::Detail,
|
||||||
Logs::Spawns,
|
Logs::Spawns,
|
||||||
"Spawn2 %d: Spawn group %d yeilded NPC type %d, which is over its spawn limit (%d)",
|
"Spawn2 %d: Spawn group %d yielded NPC type %d, which is over its spawn limit (%d)",
|
||||||
spawn2_id,
|
spawn2_id,
|
||||||
spawngroup_id_,
|
spawngroup_id_,
|
||||||
npcid,
|
npcid,
|
||||||
@ -881,19 +887,19 @@ void SpawnConditionManager::ExecEvent(SpawnEvent &event, bool send_update) {
|
|||||||
break;
|
break;
|
||||||
case SpawnEvent::ActionAdd:
|
case SpawnEvent::ActionAdd:
|
||||||
new_value += event.argument;
|
new_value += event.argument;
|
||||||
Log(Logs::Detail, Logs::Spawns, "Event %d: Executing. Adding %d to condition %d, yeilding %d.", event.id, event.argument, event.condition_id, new_value);
|
Log(Logs::Detail, Logs::Spawns, "Event %d: Executing. Adding %d to condition %d, yielding %d.", event.id, event.argument, event.condition_id, new_value);
|
||||||
break;
|
break;
|
||||||
case SpawnEvent::ActionSubtract:
|
case SpawnEvent::ActionSubtract:
|
||||||
new_value -= event.argument;
|
new_value -= event.argument;
|
||||||
Log(Logs::Detail, Logs::Spawns, "Event %d: Executing. Subtracting %d from condition %d, yeilding %d.", event.id, event.argument, event.condition_id, new_value);
|
Log(Logs::Detail, Logs::Spawns, "Event %d: Executing. Subtracting %d from condition %d, yielding %d.", event.id, event.argument, event.condition_id, new_value);
|
||||||
break;
|
break;
|
||||||
case SpawnEvent::ActionMultiply:
|
case SpawnEvent::ActionMultiply:
|
||||||
new_value *= event.argument;
|
new_value *= event.argument;
|
||||||
Log(Logs::Detail, Logs::Spawns, "Event %d: Executing. Multiplying condition %d by %d, yeilding %d.", event.id, event.condition_id, event.argument, new_value);
|
Log(Logs::Detail, Logs::Spawns, "Event %d: Executing. Multiplying condition %d by %d, yielding %d.", event.id, event.condition_id, event.argument, new_value);
|
||||||
break;
|
break;
|
||||||
case SpawnEvent::ActionDivide:
|
case SpawnEvent::ActionDivide:
|
||||||
new_value /= event.argument;
|
new_value /= event.argument;
|
||||||
Log(Logs::Detail, Logs::Spawns, "Event %d: Executing. Dividing condition %d by %d, yeilding %d.", event.id, event.condition_id, event.argument, new_value);
|
Log(Logs::Detail, Logs::Spawns, "Event %d: Executing. Dividing condition %d by %d, yielding %d.", event.id, event.condition_id, event.argument, new_value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log(Logs::Detail, Logs::Spawns, "Event %d: Invalid event action type %d", event.id, event.action);
|
Log(Logs::Detail, Logs::Spawns, "Event %d: Invalid event action type %d", event.id, event.action);
|
||||||
|
|||||||
@ -28,11 +28,12 @@
|
|||||||
extern EntityList entity_list;
|
extern EntityList entity_list;
|
||||||
extern Zone *zone;
|
extern Zone *zone;
|
||||||
|
|
||||||
SpawnEntry::SpawnEntry(uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit)
|
SpawnEntry::SpawnEntry(uint32 in_NPCType, int in_chance, uint16 in_filter, uint8 in_npc_spawn_limit)
|
||||||
{
|
{
|
||||||
NPCType = in_NPCType;
|
NPCType = in_NPCType;
|
||||||
chance = in_chance;
|
chance = in_chance;
|
||||||
npc_spawn_limit = in_npc_spawn_limit;
|
condition_value_filter = in_filter;
|
||||||
|
npc_spawn_limit = in_npc_spawn_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpawnGroup::SpawnGroup(
|
SpawnGroup::SpawnGroup(
|
||||||
@ -64,7 +65,7 @@ SpawnGroup::SpawnGroup(
|
|||||||
despawn_timer = despawn_timer_in;
|
despawn_timer = despawn_timer_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 SpawnGroup::GetNPCType()
|
uint32 SpawnGroup::GetNPCType(uint16 in_filter)
|
||||||
{
|
{
|
||||||
#if EQDEBUG >= 10
|
#if EQDEBUG >= 10
|
||||||
Log(Logs::General, Logs::None, "SpawnGroup[%08x]::GetNPCType()", (uint32) this);
|
Log(Logs::General, Logs::None, "SpawnGroup[%08x]::GetNPCType()", (uint32) this);
|
||||||
@ -87,6 +88,9 @@ uint32 SpawnGroup::GetNPCType()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (se->condition_value_filter != in_filter)
|
||||||
|
continue;
|
||||||
|
|
||||||
totalchance += se->chance;
|
totalchance += se->chance;
|
||||||
possible.push_back(se);
|
possible.push_back(se);
|
||||||
}
|
}
|
||||||
@ -94,7 +98,6 @@ uint32 SpawnGroup::GetNPCType()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32 roll = 0;
|
int32 roll = 0;
|
||||||
roll = zone->random.Int(0, totalchance - 1);
|
roll = zone->random.Int(0, totalchance - 1);
|
||||||
|
|
||||||
@ -242,6 +245,7 @@ bool ZoneDatabase::LoadSpawnGroups(const char *zone_name, uint16 version, SpawnG
|
|||||||
spawnentry.spawngroupID,
|
spawnentry.spawngroupID,
|
||||||
npcid,
|
npcid,
|
||||||
chance,
|
chance,
|
||||||
|
condition_value_filter,
|
||||||
npc_types.spawn_limit
|
npc_types.spawn_limit
|
||||||
AS sl
|
AS sl
|
||||||
FROM
|
FROM
|
||||||
@ -266,7 +270,8 @@ bool ZoneDatabase::LoadSpawnGroups(const char *zone_name, uint16 version, SpawnG
|
|||||||
auto new_spawn_entry = new SpawnEntry(
|
auto new_spawn_entry = new SpawnEntry(
|
||||||
atoi(row[1]),
|
atoi(row[1]),
|
||||||
atoi(row[2]),
|
atoi(row[2]),
|
||||||
(row[3] ? atoi(row[3]) : 0)
|
atoi(row[3]),
|
||||||
|
(row[4] ? atoi(row[4]) : 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
||||||
@ -342,6 +347,7 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList *spawn
|
|||||||
(spawnentry.spawngroupID),
|
(spawnentry.spawngroupID),
|
||||||
spawnentry.npcid,
|
spawnentry.npcid,
|
||||||
spawnentry.chance,
|
spawnentry.chance,
|
||||||
|
spawnentry.condition_value_filter,
|
||||||
spawngroup.spawn_limit
|
spawngroup.spawn_limit
|
||||||
FROM
|
FROM
|
||||||
spawnentry,
|
spawnentry,
|
||||||
@ -362,7 +368,8 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList *spawn
|
|||||||
auto new_spawn_entry = new SpawnEntry(
|
auto new_spawn_entry = new SpawnEntry(
|
||||||
atoi(row[1]),
|
atoi(row[1]),
|
||||||
atoi(row[2]),
|
atoi(row[2]),
|
||||||
(row[3] ? atoi(row[3]) : 0)
|
atoi(row[3]),
|
||||||
|
(row[4] ? atoi(row[4]) : 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
||||||
|
|||||||
@ -25,10 +25,11 @@
|
|||||||
|
|
||||||
class SpawnEntry {
|
class SpawnEntry {
|
||||||
public:
|
public:
|
||||||
SpawnEntry(uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit);
|
SpawnEntry(uint32 in_NPCType, int in_chance, uint16 in_filter, uint8 in_npc_spawn_limit);
|
||||||
~SpawnEntry() {}
|
~SpawnEntry() {}
|
||||||
uint32 NPCType;
|
uint32 NPCType;
|
||||||
int chance;
|
int chance;
|
||||||
|
uint16 condition_value_filter;
|
||||||
|
|
||||||
//this is a cached value from npc_types, for speed
|
//this is a cached value from npc_types, for speed
|
||||||
uint8 npc_spawn_limit; //max # of this entry which can be spawned in this zone
|
uint8 npc_spawn_limit; //max # of this entry which can be spawned in this zone
|
||||||
@ -52,7 +53,7 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
~SpawnGroup();
|
~SpawnGroup();
|
||||||
uint32 GetNPCType();
|
uint32 GetNPCType(uint16 condition_value_filter=1);
|
||||||
void AddSpawnEntry(SpawnEntry *newEntry);
|
void AddSpawnEntry(SpawnEntry *newEntry);
|
||||||
uint32 id;
|
uint32 id;
|
||||||
float roamdist;
|
float roamdist;
|
||||||
|
|||||||
@ -757,6 +757,8 @@ bool Client::CheckFizzle(uint16 spell_id)
|
|||||||
|
|
||||||
act_skill = GetSkill(spells[spell_id].skill);
|
act_skill = GetSkill(spells[spell_id].skill);
|
||||||
act_skill += GetLevel(); // maximum of whatever the client can cheat
|
act_skill += GetLevel(); // maximum of whatever the client can cheat
|
||||||
|
act_skill += itembonuses.adjusted_casting_skill + spellbonuses.adjusted_casting_skill + aabonuses.adjusted_casting_skill;
|
||||||
|
Log(Logs::Detail, Logs::Spells, "Adjusted casting skill: %d+%d+%d+%d+%d=%d", GetSkill(spells[spell_id].skill), GetLevel(), itembonuses.adjusted_casting_skill, spellbonuses.adjusted_casting_skill, aabonuses.adjusted_casting_skill, act_skill);
|
||||||
|
|
||||||
//spell specialization
|
//spell specialization
|
||||||
float specialize = GetSpecializeSkillValue(spell_id);
|
float specialize = GetSpecializeSkillValue(spell_id);
|
||||||
|
|||||||
155
zone/zone.cpp
155
zone/zone.cpp
@ -822,11 +822,11 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
|
|||||||
Weather_Timer = new Timer(60000);
|
Weather_Timer = new Timer(60000);
|
||||||
Weather_Timer->Start();
|
Weather_Timer->Start();
|
||||||
Log(Logs::General, Logs::None, "The next weather check for zone: %s will be in %i seconds.", short_name, Weather_Timer->GetRemainingTime()/1000);
|
Log(Logs::General, Logs::None, "The next weather check for zone: %s will be in %i seconds.", short_name, Weather_Timer->GetRemainingTime()/1000);
|
||||||
zone_weather = 0;
|
zone_weather = 0;
|
||||||
weather_intensity = 0;
|
weather_intensity = 0;
|
||||||
blocked_spells = nullptr;
|
blocked_spells = nullptr;
|
||||||
totalBS = 0;
|
zone_total_blocked_spells = 0;
|
||||||
zone_has_current_time = false;
|
zone_has_current_time = false;
|
||||||
|
|
||||||
Instance_Shutdown_Timer = nullptr;
|
Instance_Shutdown_Timer = nullptr;
|
||||||
bool is_perma = false;
|
bool is_perma = false;
|
||||||
@ -972,7 +972,7 @@ bool Zone::Init(bool iStaticZone) {
|
|||||||
|
|
||||||
//load up the zone's doors (prints inside)
|
//load up the zone's doors (prints inside)
|
||||||
zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion());
|
zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion());
|
||||||
zone->LoadBlockedSpells(zone->GetZoneID());
|
zone->LoadZoneBlockedSpells(zone->GetZoneID());
|
||||||
|
|
||||||
//clear trader items if we are loading the bazaar
|
//clear trader items if we are loading the bazaar
|
||||||
if(strncasecmp(short_name,"bazaar",6)==0) {
|
if(strncasecmp(short_name,"bazaar",6)==0) {
|
||||||
@ -1880,17 +1880,21 @@ bool ZoneDatabase::GetDecayTimes(npcDecayTimes_Struct *npcCorpseDecayTimes)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zone::weatherSend(Client* client)
|
void Zone::weatherSend(Client *client)
|
||||||
{
|
{
|
||||||
auto outapp = new EQApplicationPacket(OP_Weather, 8);
|
auto outapp = new EQApplicationPacket(OP_Weather, 8);
|
||||||
if(zone_weather>0)
|
if (zone_weather > 0) {
|
||||||
outapp->pBuffer[0] = zone_weather-1;
|
outapp->pBuffer[0] = zone_weather - 1;
|
||||||
if(zone_weather>0)
|
}
|
||||||
|
if (zone_weather > 0) {
|
||||||
outapp->pBuffer[4] = zone->weather_intensity;
|
outapp->pBuffer[4] = zone->weather_intensity;
|
||||||
if (client)
|
}
|
||||||
|
if (client) {
|
||||||
client->QueuePacket(outapp);
|
client->QueuePacket(outapp);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
entity_list.QueueClients(0, outapp);
|
entity_list.QueueClients(0, outapp);
|
||||||
|
}
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1908,15 +1912,13 @@ void Zone::SetGraveyard(uint32 zoneid, const glm::vec4& graveyardPosition) {
|
|||||||
m_Graveyard = graveyardPosition;
|
m_Graveyard = graveyardPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zone::LoadBlockedSpells(uint32 zoneid)
|
void Zone::LoadZoneBlockedSpells(uint32 zone_id)
|
||||||
{
|
{
|
||||||
if(!blocked_spells)
|
if (!blocked_spells) {
|
||||||
{
|
zone_total_blocked_spells = database.GetBlockedSpellsCount(zone_id);
|
||||||
totalBS = database.GetBlockedSpellsCount(zoneid);
|
if (zone_total_blocked_spells > 0) {
|
||||||
if(totalBS > 0){
|
blocked_spells = new ZoneSpellsBlocked[zone_total_blocked_spells];
|
||||||
blocked_spells = new ZoneSpellsBlocked[totalBS];
|
if (!database.LoadBlockedSpells(zone_total_blocked_spells, blocked_spells, zone_id)) {
|
||||||
if(!database.LoadBlockedSpells(totalBS, blocked_spells, zoneid))
|
|
||||||
{
|
|
||||||
Log(Logs::General, Logs::Error, "... Failed to load blocked spells.");
|
Log(Logs::General, Logs::Error, "... Failed to load blocked spells.");
|
||||||
ClearBlockedSpells();
|
ClearBlockedSpells();
|
||||||
}
|
}
|
||||||
@ -1926,102 +1928,89 @@ void Zone::LoadBlockedSpells(uint32 zoneid)
|
|||||||
|
|
||||||
void Zone::ClearBlockedSpells()
|
void Zone::ClearBlockedSpells()
|
||||||
{
|
{
|
||||||
if(blocked_spells){
|
if (blocked_spells) {
|
||||||
safe_delete_array(blocked_spells);
|
safe_delete_array(blocked_spells);
|
||||||
totalBS = 0;
|
zone_total_blocked_spells = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Zone::IsSpellBlocked(uint32 spell_id, const glm::vec3& location)
|
bool Zone::IsSpellBlocked(uint32 spell_id, const glm::vec3 &location)
|
||||||
{
|
{
|
||||||
if (blocked_spells)
|
if (blocked_spells) {
|
||||||
{
|
|
||||||
bool exception = false;
|
bool exception = false;
|
||||||
bool block_all = false;
|
bool block_all = false;
|
||||||
for (int x = 0; x < totalBS; x++)
|
|
||||||
{
|
for (int x = 0; x < GetZoneTotalBlockedSpells(); x++) {
|
||||||
if (blocked_spells[x].spellid == spell_id)
|
if (blocked_spells[x].spellid == spell_id) {
|
||||||
{
|
|
||||||
exception = true;
|
exception = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blocked_spells[x].spellid == 0)
|
if (blocked_spells[x].spellid == 0) {
|
||||||
{
|
|
||||||
block_all = true;
|
block_all = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 0; x < totalBS; x++)
|
// If all spells are blocked and this is an exception, it is not blocked
|
||||||
{
|
if (block_all && exception) {
|
||||||
// If spellid is 0, block all spells in the zone
|
return false;
|
||||||
if (block_all)
|
}
|
||||||
{
|
|
||||||
// If the same zone has entries other than spellid 0, they act as exceptions and are allowed
|
|
||||||
if (exception)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (spell_id != blocked_spells[x].spellid)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (blocked_spells[x].type)
|
for (int x = 0; x < GetZoneTotalBlockedSpells(); x++) {
|
||||||
{
|
// Spellid of 0 matches all spells
|
||||||
case 1:
|
if (0 != blocked_spells[x].spellid && spell_id != blocked_spells[x].spellid) {
|
||||||
{
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (blocked_spells[x].type) {
|
||||||
|
case ZoneBlockedSpellTypes::ZoneWide: {
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ZoneBlockedSpellTypes::Region: {
|
||||||
|
if (IsWithinAxisAlignedBox(
|
||||||
|
location,
|
||||||
|
blocked_spells[x].m_Location - blocked_spells[x].m_Difference,
|
||||||
|
blocked_spells[x].m_Location + blocked_spells[x].m_Difference
|
||||||
|
)) {
|
||||||
return true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
if (IsWithinAxisAlignedBox(location, blocked_spells[x].m_Location - blocked_spells[x].m_Difference, blocked_spells[x].m_Location + blocked_spells[x].m_Difference))
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Zone::GetSpellBlockedMessage(uint32 spell_id, const glm::vec3& location)
|
const char *Zone::GetSpellBlockedMessage(uint32 spell_id, const glm::vec3 &location)
|
||||||
{
|
{
|
||||||
if(blocked_spells)
|
if (blocked_spells) {
|
||||||
{
|
for (int x = 0; x < GetZoneTotalBlockedSpells(); x++) {
|
||||||
for(int x = 0; x < totalBS; x++)
|
if (spell_id != blocked_spells[x].spellid && blocked_spells[x].spellid != 0) {
|
||||||
{
|
|
||||||
if(spell_id != blocked_spells[x].spellid && blocked_spells[x].spellid != 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch(blocked_spells[x].type)
|
switch (blocked_spells[x].type) {
|
||||||
{
|
case ZoneBlockedSpellTypes::ZoneWide: {
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
return blocked_spells[x].message;
|
return blocked_spells[x].message;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case ZoneBlockedSpellTypes::Region: {
|
||||||
{
|
if (IsWithinAxisAlignedBox(
|
||||||
if(IsWithinAxisAlignedBox(location, blocked_spells[x].m_Location - blocked_spells[x].m_Difference, blocked_spells[x].m_Location + blocked_spells[x].m_Difference))
|
location,
|
||||||
|
blocked_spells[x].m_Location - blocked_spells[x].m_Difference,
|
||||||
|
blocked_spells[x].m_Location + blocked_spells[x].m_Difference
|
||||||
|
)) {
|
||||||
return blocked_spells[x].message;
|
return blocked_spells[x].message;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default: {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -162,7 +162,7 @@ public:
|
|||||||
inline void SetZoneHasCurrentTime(bool time) { zone_has_current_time = time; }
|
inline void SetZoneHasCurrentTime(bool time) { zone_has_current_time = time; }
|
||||||
inline void ShowNPCGlobalLoot(Client *to, NPC *who) { m_global_loot.ShowNPCGlobalLoot(to, who); }
|
inline void ShowNPCGlobalLoot(Client *to, NPC *who) { m_global_loot.ShowNPCGlobalLoot(to, who); }
|
||||||
inline void ShowZoneGlobalLoot(Client *to) { m_global_loot.ShowZoneGlobalLoot(to); }
|
inline void ShowZoneGlobalLoot(Client *to) { m_global_loot.ShowZoneGlobalLoot(to); }
|
||||||
int GetTotalBlockedSpells() { return totalBS; }
|
int GetZoneTotalBlockedSpells() { return zone_total_blocked_spells; }
|
||||||
int SaveTempItem(uint32 merchantid, uint32 npcid, uint32 item, int32 charges, bool sold = false);
|
int SaveTempItem(uint32 merchantid, uint32 npcid, uint32 item, int32 charges, bool sold = false);
|
||||||
int32 MobsAggroCount() { return aggroedmobs; }
|
int32 MobsAggroCount() { return aggroedmobs; }
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ public:
|
|||||||
void LoadAdventureFlavor();
|
void LoadAdventureFlavor();
|
||||||
void LoadAlternateAdvancement();
|
void LoadAlternateAdvancement();
|
||||||
void LoadAlternateCurrencies();
|
void LoadAlternateCurrencies();
|
||||||
void LoadBlockedSpells(uint32 zoneid);
|
void LoadZoneBlockedSpells(uint32 zone_id);
|
||||||
void LoadLDoNTrapEntries();
|
void LoadLDoNTrapEntries();
|
||||||
void LoadLDoNTraps();
|
void LoadLDoNTraps();
|
||||||
void LoadLevelEXPMods();
|
void LoadLevelEXPMods();
|
||||||
@ -348,7 +348,7 @@ private:
|
|||||||
glm::vec3 m_SafePoint;
|
glm::vec3 m_SafePoint;
|
||||||
glm::vec4 m_Graveyard;
|
glm::vec4 m_Graveyard;
|
||||||
int default_ruleset;
|
int default_ruleset;
|
||||||
int totalBS;
|
int zone_total_blocked_spells;
|
||||||
int npc_position_update_distance;
|
int npc_position_update_distance;
|
||||||
int32 aggroedmobs;
|
int32 aggroedmobs;
|
||||||
uint8 zone_type;
|
uint8 zone_type;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user