From 239d4afb1320998e1c148e0b495b2195349c9597 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 11 Jul 2013 13:44:45 -0700 Subject: [PATCH] NPC Special Attacks should all work right: also huge explanation in changelog.txt --- changelog.txt | 109 ++++++++++++++++++ .../2013_07_11_NPC_Special_Abilities.sql | 39 +++++++ zone/MobAI.cpp | 77 ++++++++----- zone/hate_list.cpp | 6 +- zone/hate_list.h | 2 +- zone/lua_bit.cpp | 2 +- zone/lua_door.cpp | 27 ++++- zone/lua_door.h | 5 + zone/lua_mob.cpp | 1 + zone/mob.cpp | 1 - 10 files changed, 233 insertions(+), 36 deletions(-) create mode 100644 utils/sql/git/required/2013_07_11_NPC_Special_Abilities.sql diff --git a/changelog.txt b/changelog.txt index 21abf9bb1..7fd582340 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,114 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- + +== 07/11/2013 == +KLS: Added a few lua functions. +KLS: Redid the npcspecialatk system with a new system that is more flexible but a little more complicated (this will break any 3rd party tools that deal with them). + +Instead of a string such as "ERS" to denote "Enrage Rampage Summon" abilities are indexed by their ability number, level and params separated by '^'. +It is stored in the following format: ability,level[,param0,param1,param2,param3,param4,param5,param6,param7] Params will be read until there are 8 total or a '^' is reached. +Eg: 'ERS' -> '2,1^3,1^1,1 + +Levels allow us to dictate how abilities behave that may be different even though they're the same ability. +Params allow us to further refine behaviors on a case by case basis. Passing 0 as a param will use the default value. + +NOTE: Be sure to source 2013_07_11_NPC_Special_Abilities.sql. Also due to the large impact this has on a database it is very HIGHLY SUGGESTED to BACKUP YOUR DATABASE FIRST. + +The following are the special abilities currently in the game as well as their levels and parameters currently in use: + +SPECATK_SUMMON = 1 +Level 1: Summon target to NPC +Level 2: Summon NPC to target +Param0: Cooldown in ms (default: 6000) +Param1: HP ratio required to summon (default: 97) + +SPECATK_ENRAGE = 2 +Param0: HP ratio required to enrage (default: rule NPC:StartEnrageValue) +Param1: Enrage duration in ms (default: 10000) +Param2: Enrage cooldown in ms (default: 360000) + +SPECATK_RAMPAGE = 3 +Param0: Proc chance (default: 20) +Param1: Rampage target count (default: rule Combat:MaxRampageTargets) +Param2: Percent of a normal attack damage to deal (default: 100) +Param3: Flat damage bonus to add to the rampage attack (default: 0) +Param4: Ignore % armor for this attack (default 0) +Param5: Ignore flat armor for this attack (default 0) +Param6: Percent of npc's natual crit that can go toward this rampage (default: 100) +Param7: Flat crit bonus on top of npc's natual crit that can go toward this attack (default 0) + +SPECATK_AREA_RAMPAGE = 4 +Param0: Proc chance (default: 20) +Param1: Rampage target count (default: 1) +Param2: Percent of a normal attack damage to deal (default: 100) +Param3: Flat damage bonus to add to the rampage attack (default: 0) +Param4: Ignore % armor for this attack (default 0) +Param5: Ignore flat armor for this attack (default 0) +Param6: Percent of npc's natual crit that can go toward this rampage (default: 100) +Param7: Flat crit bonus on top of npc's natual crit that can go toward this attack (default 0) + +SPECATK_FLURRY = 5 +Param0: Proc chance (default: rule Combat:NPCFlurryChance) +Param1: Flurry attack count (default: rule Combat:MaxFlurryHits) +Param2: Percent of a normal attack damage to deal (default: 100) +Param3: Flat damage bonus to add to the flurry attack (default: 0) +Param4: Ignore % armor for this attack (default 0) +Param5: Ignore flat armor for this attack (default 0) +Param6: Percent of npc's natual crit that can go toward this attack (default: 100) +Param7: Flat crit bonus on top of npc's natual crit that can go toward this attack (default 0) + +Ex: Normal Flurry with 25% proc rate and 100% crit chance that ignores 500 armor. +5,1,25,0,0,0,0,500,0,100 + +SPECATK_TRIPLE = 6 +SPECATK_QUAD = 7 +SPECATK_INNATE_DW = 8 +SPECATK_BANE = 9 +SPECATK_MAGICAL = 10 +SPECATK_RANGED_ATK = 11 +UNSLOWABLE = 12 +UNMEZABLE = 13 +UNCHARMABLE = 14 +UNSTUNABLE = 15 +UNSNAREABLE = 16 +UNFEARABLE = 17 +UNDISPELLABLE = 18 +IMMUNE_MELEE = 19 +IMMUNE_MAGIC = 20 +IMMUNE_FLEEING = 21 +IMMUNE_MELEE_EXCEPT_BANE = 22 +IMMUNE_MELEE_NONMAGICAL = 23 +IMMUNE_AGGRO = 24 +IMMUNE_AGGRO_ON = 25 +IMMUNE_CASTING_FROM_RANGE = 26 +IMMUNE_FEIGN_DEATH = 27 +IMMUNE_TAUNT = 28 + +NPC_TUNNELVISION = 29 +Param0: Aggro modifier on non-tanks (default: rule Aggro:TunnelVisionAggroMod) + +NPC_NO_BUFFHEAL_FRIENDS = 30 +IMMUNE_PACIFY = 31 + +LEASH = 32 +Param0: Range (default: aggro range * aggro range) + +TETHER = 33 +Param0: Range (default: aggro range * aggro range) + +DESTRUCTIBLE_OBJECT = 34 +NO_HARM_FROM_CLIENT = 35 + +The following Lua API functions were added to deal with the new system: +Integer GetSpecialAbility(Integer ability); +Integer GetSpecialAbilityParam(Integer ability, Integer param); +Void SetSpecialAbility(Integer ability, Integer level); +Void SetSpecialAbilityParam(Integer ability, Integer param, Integer value); +Void ClearSpecialAbilities(); +Void ProcessSpecialAbilities(String str); + +The old API functions that worked with letters still exist for backwards compatibility reasons but wont be updated further. + == 07/08/2013 == Secrets: Cleanup of some log functions that did not have an 'off' function.** Secrets: Unknown opcode messages only show on EQDEBUG* >= 5 or higher now. (including the dumped packet) diff --git a/utils/sql/git/required/2013_07_11_NPC_Special_Abilities.sql b/utils/sql/git/required/2013_07_11_NPC_Special_Abilities.sql new file mode 100644 index 000000000..772303d29 --- /dev/null +++ b/utils/sql/git/required/2013_07_11_NPC_Special_Abilities.sql @@ -0,0 +1,39 @@ +ALTER TABLE `npc_types` ADD COLUMN `special_abilities` TEXT NOT NULL DEFAULT '' AFTER `npcspecialattks`; + +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "1,1^") WHERE npcspecialattks LIKE BINARY '%S%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "2,1^") WHERE npcspecialattks LIKE BINARY '%E%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "3,1^") WHERE npcspecialattks LIKE BINARY '%R%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "4,1^") WHERE npcspecialattks LIKE BINARY '%r%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "5,1^") WHERE npcspecialattks LIKE BINARY '%F%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "6,1^") WHERE npcspecialattks LIKE BINARY '%T%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "7,1^") WHERE npcspecialattks LIKE BINARY '%Q%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "8,1^") WHERE npcspecialattks LIKE BINARY '%L%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "9,1^") WHERE npcspecialattks LIKE BINARY '%b%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "10,1^") WHERE npcspecialattks LIKE BINARY '%m%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "11,1^") WHERE npcspecialattks LIKE BINARY '%Y%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "12,1^") WHERE npcspecialattks LIKE BINARY '%U%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "13,1^") WHERE npcspecialattks LIKE BINARY '%M%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "14,1^") WHERE npcspecialattks LIKE BINARY '%C%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "15,1^") WHERE npcspecialattks LIKE BINARY '%N%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "16,1^") WHERE npcspecialattks LIKE BINARY '%I%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "17,1^") WHERE npcspecialattks LIKE BINARY '%D%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "18,1^") WHERE npcspecialattks LIKE BINARY '%K%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "19,1^") WHERE npcspecialattks LIKE BINARY '%A%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "20,1^") WHERE npcspecialattks LIKE BINARY '%B%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "21,1^") WHERE npcspecialattks LIKE BINARY '%f%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "22,1^") WHERE npcspecialattks LIKE BINARY '%O%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "23,1^") WHERE npcspecialattks LIKE BINARY '%W%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "24,1^") WHERE npcspecialattks LIKE BINARY '%H%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "25,1^") WHERE npcspecialattks LIKE BINARY '%G%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "26,1^") WHERE npcspecialattks LIKE BINARY '%g%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "27,1^") WHERE npcspecialattks LIKE BINARY '%d%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "28,1^") WHERE npcspecialattks LIKE BINARY '%i%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "29,1^") WHERE npcspecialattks LIKE BINARY '%t%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "30,1^") WHERE npcspecialattks LIKE BINARY '%n%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "31,1^") WHERE npcspecialattks LIKE BINARY '%p%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "32,1^") WHERE npcspecialattks LIKE BINARY '%J%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "33,1^") WHERE npcspecialattks LIKE BINARY '%j%'; +UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "34,1^") WHERE npcspecialattks LIKE BINARY '%o%'; +UPDATE npc_types SET special_abilities = TRIM(TRAILING '^' FROM special_abilities); + +ALTER TABLE `npc_types` DROP COLUMN `npcspecialattks`; \ No newline at end of file diff --git a/zone/MobAI.cpp b/zone/MobAI.cpp index 5b011c722..54b1ffc2f 100644 --- a/zone/MobAI.cpp +++ b/zone/MobAI.cpp @@ -1095,15 +1095,23 @@ void Mob::AI_Process() { if(DivineAura()) return; - if(GetSpecialAbility(TETHER) || GetSpecialAbility(LEASH)) { - if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > pAggroRange*pAggroRange) { + if(GetSpecialAbility(TETHER)) { + float aggro_range = static_cast(GetSpecialAbilityParam(TETHER, 0)); + aggro_range = aggro_range > 0.0f ? aggro_range : pAggroRange * pAggroRange; + + if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > aggro_range) { GMMove(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY(), CastToNPC()->GetSpawnPointZ(), CastToNPC()->GetSpawnPointH()); - if(GetSpecialAbility(LEASH)) { - SetHP(GetMaxHP()); - BuffFadeAll(); - WipeHateList(); - return; - } + } + } else if(GetSpecialAbility(LEASH)) { + float aggro_range = static_cast(GetSpecialAbilityParam(LEASH, 0)); + aggro_range = aggro_range > 0.0f ? aggro_range : pAggroRange * pAggroRange; + + if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > aggro_range) { + GMMove(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY(), CastToNPC()->GetSpawnPointZ(), CastToNPC()->GetSpawnPointH()); + SetHP(GetMaxHP()); + BuffFadeAll(); + WipeHateList(); + return; } } @@ -1180,32 +1188,32 @@ void Mob::AI_Process() { flurry_chance = flurry_chance > 0 ? flurry_chance : RuleI(Combat, NPCFlurryChance); ExtraAttackOptions opts; - int cur = GetSpecialAbilityParam(SPECATK_FLURRY, 1); + int cur = GetSpecialAbilityParam(SPECATK_FLURRY, 2); if(cur > 0) { opts.damage_percent = cur / 100.0f; } - cur = GetSpecialAbilityParam(SPECATK_FLURRY, 2); + cur = GetSpecialAbilityParam(SPECATK_FLURRY, 3); if(cur > 0) { opts.damage_flat = cur; } - cur = GetSpecialAbilityParam(SPECATK_FLURRY, 3); + cur = GetSpecialAbilityParam(SPECATK_FLURRY, 4); if(cur > 0) { opts.armor_pen_percent = cur / 100.0f; } - cur = GetSpecialAbilityParam(SPECATK_FLURRY, 4); + cur = GetSpecialAbilityParam(SPECATK_FLURRY, 5); if(cur > 0) { opts.armor_pen_flat = cur; } - cur = GetSpecialAbilityParam(SPECATK_FLURRY, 5); + cur = GetSpecialAbilityParam(SPECATK_FLURRY, 6); if(cur > 0) { opts.crit_percent = cur / 100.0f; } - cur = GetSpecialAbilityParam(SPECATK_FLURRY, 6); + cur = GetSpecialAbilityParam(SPECATK_FLURRY, 7); if(cur > 0) { opts.crit_flat = cur; } @@ -1232,32 +1240,32 @@ void Mob::AI_Process() { rampage_chance = rampage_chance > 0 ? rampage_chance : 20; if(MakeRandomInt(0, 99) < rampage_chance) { ExtraAttackOptions opts; - int cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 1); + int cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 2); if(cur > 0) { opts.damage_percent = cur / 100.0f; } - cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 2); + cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 3); if(cur > 0) { opts.damage_flat = cur; } - cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 3); + cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 4); if(cur > 0) { opts.armor_pen_percent = cur / 100.0f; } - cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 4); + cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 5); if(cur > 0) { opts.armor_pen_flat = cur; } - cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 5); + cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 6); if(cur > 0) { opts.crit_percent = cur / 100.0f; } - cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 6); + cur = GetSpecialAbilityParam(SPECATK_RAMPAGE, 7); if(cur > 0) { opts.crit_flat = cur; } @@ -1271,32 +1279,32 @@ void Mob::AI_Process() { rampage_chance = rampage_chance > 0 ? rampage_chance : 20; if(MakeRandomInt(0, 99) < rampage_chance) { ExtraAttackOptions opts; - int cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 1); + int cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 2); if(cur > 0) { opts.damage_percent = cur / 100.0f; } - cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 2); + cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 3); if(cur > 0) { opts.damage_flat = cur; } - cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 3); + cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 4); if(cur > 0) { opts.armor_pen_percent = cur / 100.0f; } - cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 4); + cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 5); if(cur > 0) { opts.armor_pen_flat = cur; } - cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 5); + cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 6); if(cur > 0) { opts.crit_percent = cur / 100.0f; } - cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 6); + cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 7); if(cur > 0) { opts.crit_flat = cur; } @@ -2008,7 +2016,10 @@ bool Mob::Flurry(ExtraAttackOptions *opts) } else { entity_list.MessageClose_StringID(this, true, 200, MT_PetFlurry, NPC_FLURRY, GetCleanName(), target->GetCleanName()); } - for (int i = 0; i < RuleI(Combat, MaxFlurryHits); i++) + + int num_attacks = GetSpecialAbilityParam(SPECATK_FLURRY, 1); + num_attacks = num_attacks > 0 ? num_attacks : RuleI(Combat, MaxFlurryHits); + for (int i = 0; i < num_attacks; i++) Attack(target, 13, false, false, false, opts); } return true; @@ -2045,9 +2056,12 @@ bool Mob::Rampage(ExtraAttackOptions *opts) } else { entity_list.MessageClose_StringID(this, true, 200, MT_PetFlurry, NPC_RAMPAGE, GetCleanName()); } + + int rampage_targets = GetSpecialAbilityParam(SPECATK_RAMPAGE, 1); + rampage_targets = rampage_targets > 0 ? rampage_targets : RuleI(Combat, MaxRampageTargets); for (int i = 0; i < RampageArray.size(); i++) { - if(index_hit >= RuleI(Combat, MaxRampageTargets)) + if(index_hit >= rampage_targets) break; // range is important Mob *m_target = entity_list.GetMob(RampageArray[i].c_str()); @@ -2063,7 +2077,7 @@ bool Mob::Rampage(ExtraAttackOptions *opts) } } - if(index_hit < RuleI(Combat, MaxRampageTargets)) { + if(index_hit < rampage_targets) { Attack(GetTarget(), 13, false, false, false, opts); } return true; @@ -2077,7 +2091,10 @@ void Mob::AreaRampage(ExtraAttackOptions *opts) } else { entity_list.MessageClose_StringID(this, true, 200, MT_PetFlurry, AE_RAMPAGE, GetCleanName()); } - index_hit = hate_list.AreaRampage(this, GetTarget(), opts); + + int rampage_targets = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 1); + rampage_targets = rampage_targets > 0 ? rampage_targets : 1; + index_hit = hate_list.AreaRampage(this, GetTarget(), rampage_targets, opts); if(index_hit == 0) { Attack(GetTarget(), 13, false, false, false, opts); diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 907b42527..7ff0ad61b 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -473,7 +473,7 @@ void HateList::PrintToClient(Client *c) } } -int HateList::AreaRampage(Mob *caster, Mob *target, ExtraAttackOptions *opts) +int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts) { if(!target || !caster) return 0; @@ -501,7 +501,9 @@ int HateList::AreaRampage(Mob *caster, Mob *target, ExtraAttackOptions *opts) Mob *cur = entity_list.GetMobID((*iter)); if(cur) { - caster->Attack(cur, 13, false, false, false, opts); + for(int i = 0; i < count; ++i) { + caster->Attack(cur, 13, false, false, false, opts); + } } iter++; } diff --git a/zone/hate_list.h b/zone/hate_list.h index d38e60c52..7b708895d 100644 --- a/zone/hate_list.h +++ b/zone/hate_list.h @@ -59,7 +59,7 @@ public: //Gets the target with the most hate regardless of things like frenzy etc. Mob* GetMostHate(); - int AreaRampage(Mob *caster, Mob *target, ExtraAttackOptions *opts); + int AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts); void SpellCast(Mob *caster, uint32 spell_id, float range); diff --git a/zone/lua_bit.cpp b/zone/lua_bit.cpp index 7a5a614cb..b923d534d 100644 --- a/zone/lua_bit.cpp +++ b/zone/lua_bit.cpp @@ -151,7 +151,7 @@ static const struct luaL_Reg bit_funcs[] = { */ #define BAD_SAR (bsar(-8, 2) != (SBits)-2) -LUALIB_API int luaopen_bit(lua_State *L) +int luaopen_bit(lua_State *L) { UBits b; lua_pushnumber(L, (lua_Number)1437217655L); diff --git a/zone/lua_door.cpp b/zone/lua_door.cpp index 869d82cdf..091cd0c0e 100644 --- a/zone/lua_door.cpp +++ b/zone/lua_door.cpp @@ -5,6 +5,7 @@ #include #include "doors.h" +#include "lua_mob.h" #include "lua_door.h" void Lua_Door::SetDoorName(const char *name) { @@ -137,6 +138,26 @@ void Lua_Door::CreateDatabaseEntry() { self->CreateDatabaseEntry(); } +void Lua_Door::ForceOpen(Lua_Mob sender) { + Lua_Safe_Call_Void(); + self->ForceOpen(sender); +} + +void Lua_Door::ForceOpen(Lua_Mob sender, bool alt_mode) { + Lua_Safe_Call_Void(); + self->ForceOpen(sender, alt_mode); +} + +void Lua_Door::ForceClose(Lua_Mob sender) { + Lua_Safe_Call_Void(); + self->ForceClose(sender); +} + +void Lua_Door::ForceClose(Lua_Mob sender, bool alt_mode) { + Lua_Safe_Call_Void(); + self->ForceClose(sender, alt_mode); +} + luabind::scope lua_register_door() { return luabind::class_("Door") .def(luabind::constructor<>()) @@ -167,7 +188,11 @@ luabind::scope lua_register_door() { .def("GetKeyItem", (uint32(Lua_Door::*)(void))&Lua_Door::GetKeyItem) .def("SetNoKeyring", (void(Lua_Door::*)(int))&Lua_Door::SetNoKeyring) .def("GetNoKeyring", (int(Lua_Door::*)(void))&Lua_Door::GetNoKeyring) - .def("CreateDatabaseEntry", (void(Lua_Door::*)(void))&Lua_Door::CreateDatabaseEntry); + .def("CreateDatabaseEntry", (void(Lua_Door::*)(void))&Lua_Door::CreateDatabaseEntry) + .def("ForceOpen", (void(Lua_Door::*)(Lua_Mob))&Lua_Door::ForceOpen) + .def("ForceOpen", (void(Lua_Door::*)(Lua_Mob,bool))&Lua_Door::ForceOpen) + .def("ForceClose", (void(Lua_Door::*)(Lua_Mob))&Lua_Door::ForceClose) + .def("ForceClose", (void(Lua_Door::*)(Lua_Mob,bool))&Lua_Door::ForceClose); } #endif diff --git a/zone/lua_door.h b/zone/lua_door.h index c7baad8cc..309dc7f21 100644 --- a/zone/lua_door.h +++ b/zone/lua_door.h @@ -5,6 +5,7 @@ #include "lua_entity.h" class Doors; +class Lua_Mob; namespace luabind { struct scope; @@ -55,6 +56,10 @@ public: void SetNoKeyring(int type); int GetNoKeyring(); void CreateDatabaseEntry(); + void ForceOpen(Lua_Mob sender); + void ForceOpen(Lua_Mob sender, bool alt_mode); + void ForceClose(Lua_Mob sender); + void ForceClose(Lua_Mob sender, bool alt_mode); }; #endif diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index a792a0ff2..98a48e8fc 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -1820,6 +1820,7 @@ luabind::scope lua_register_mob() { .def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int,bool))&Lua_Mob::Attack) .def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int,bool,bool))&Lua_Mob::Attack) .def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int,bool,bool,bool))&Lua_Mob::Attack) + .def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int,bool,bool,bool,luabind::object))&Lua_Mob::Attack) .def("Damage", (void(Lua_Mob::*)(Lua_Mob,int,int,int))&Lua_Mob::Damage) .def("Damage", (void(Lua_Mob::*)(Lua_Mob,int,int,int,bool))&Lua_Mob::Damage) .def("Damage", (void(Lua_Mob::*)(Lua_Mob,int,int,int,bool,int))&Lua_Mob::Damage) diff --git a/zone/mob.cpp b/zone/mob.cpp index 78303bc35..b4b7a4840 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2338,7 +2338,6 @@ bool Mob::HateSummon() { int summon_level = GetSpecialAbility(SPECATK_SUMMON); if(summon_level == 1 || summon_level == 2) { - //Summon things always if(!GetTarget() || (mob_owner && mob_owner->IsClient() && !CheckLosFN(GetTarget()))) { return false; }