diff --git a/zone/MobAI.cpp b/zone/MobAI.cpp index c6d014c26..903b4883f 100644 --- a/zone/MobAI.cpp +++ b/zone/MobAI.cpp @@ -1235,7 +1235,7 @@ void Mob::AI_Process() { int32 RandRoll = MakeRandomInt(0, 99); if (RandRoll < (GetLevel() + 20)) { - if (Attack(target, 14)); + Attack(target, 14); } } } diff --git a/zone/command.cpp b/zone/command.cpp index 12966fbb2..f71cf5b62 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -8273,17 +8273,13 @@ void command_acceptrules(Client *c, const Seperator *sep) void command_guildcreate(Client *c, const Seperator *sep) { - char founders[3]; - if (database.GetVariable("GuildCreation", founders, 3)); + if(strlen(sep->argplus[1])>4 && strlen(sep->argplus[1])<16) { - if(strlen(sep->argplus[1])>4 && strlen(sep->argplus[1])<16) - { - guild_mgr.AddGuildApproval(sep->argplus[1],c); - } - else - { - c->Message(0,"Guild name must be more than 4 characters and less than 16."); - } + guild_mgr.AddGuildApproval(sep->argplus[1],c); + } + else + { + c->Message(0,"Guild name must be more than 4 characters and less than 16."); } } diff --git a/zone/common.h b/zone/common.h index a614a9d12..5414bb004 100644 --- a/zone/common.h +++ b/zone/common.h @@ -81,54 +81,43 @@ typedef enum { //focus types } focusType; //Any new FocusType needs to be added to the Mob::IsFocus function #define HIGHEST_FOCUS focusAdditionalHeal //Should always be last focusType in enum - -/* -Used: -b,d,f,g,j,m,n,o,p,r,t -A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,Q,R,S,T,U,W,Y - -Unused: -a,c,e,h,k,l,q,s,u,v,w,x,y,z -P,V,X -*/ - enum { SPECATK_NONE = 0, - SPECATK_SUMMON, // S - SPECATK_ENRAGE, // E - SPECATK_RAMPAGE, // R - SPECATK_AREA_RAMPAGE, // r - SPECATK_FLURRY, // F - SPECATK_TRIPLE, // T - SPECATK_QUAD, // Q - SPECATK_INNATE_DW, // L - SPECATK_BANE, // b - SPECATK_MAGICAL, // m - SPECATK_RANGED_ATK, // Y - UNSLOWABLE, // U - UNMEZABLE, // M - UNCHARMABLE, // C - UNSTUNABLE, // N - UNSNAREABLE, // I - UNFEARABLE, // D - UNDISPELLABLE, // K - IMMUNE_MELEE, // A - IMMUNE_MAGIC, // B - IMMUNE_FLEEING, // f - IMMUNE_MELEE_EXCEPT_BANE, // O - IMMUNE_MELEE_NONMAGICAL, // W - IMMUNE_AGGRO, // H - Won't aggro, ever. - IMMUNE_AGGRO_ON, // G - Immune to being aggroed - IMMUNE_CASTING_FROM_RANGE, // g - IMMUNE_FEIGN_DEATH, // d - IMMUNE_TAUNT, // i - NPC_TUNNELVISION, // t - NPC_NO_BUFFHEAL_FRIENDS, // n - IMMUNE_PACIFY, // p - LEASH, // J - Dispell, wipe agro && return to spawn - TETHER, // j - Return to spawn - DESTRUCTIBLE_OBJECT, // o - This is only for destructible objects - NO_HARM_FROM_CLIENT // Z - This is to prevent attacking NPC's period for clients + SPECATK_SUMMON = 1, + SPECATK_ENRAGE = 2, + SPECATK_RAMPAGE = 3, + SPECATK_AREA_RAMPAGE = 4, + SPECATK_FLURRY = 5, + 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, + NPC_NO_BUFFHEAL_FRIENDS = 30, + IMMUNE_PACIFY = 31, + LEASH = 32, + TETHER = 33, + DESTRUCTIBLE_OBJECT = 34, + NO_HARM_FROM_CLIENT = 35 }; typedef enum { //fear states diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index 19ef5aec3..0c7436514 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -1571,7 +1571,6 @@ void GuildApproval::GuildApproved() { owner->Message(0, "%s",members[i]->GetName()); owner->Message(0, "%i",members[i]->CharacterID()); - if(guild_mgr.IsGuildLeader(tmpeq,members[i]->CharacterID())); guild_mgr.SetGuild(members[i]->CharacterID(),tmpeq,0); size_t len = MBUFFER - strlen(gmembers)+1; strncat(gmembers," ",len); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 557b294ee..af33a34bc 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -696,10 +696,6 @@ luabind::object lua_get_qglobals(lua_State *L, Lua_NPC npc, Lua_Client client) { NPC *n = npc; Client *c = client; - if(n && !n->GetQglobal()) { - return ret; - } - std::list global_map; QGlobalCache::GetQGlobals(global_map, n, c, zone); auto iter = global_map.begin(); diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 650ddd04d..f81ab58ee 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -11,6 +11,8 @@ #include "lua_hate_list.h" #include "lua_client.h" +struct SpecialAbilities { }; + const char *Lua_Mob::GetName() { Lua_Safe_Call_String(); return self->GetName(); @@ -1686,6 +1688,36 @@ int Lua_Mob::GetSkill(int skill) { return self->GetSkill(static_cast(skill)); } +int Lua_Mob::GetSpecialAbility(int ability) { + Lua_Safe_Call_Int(); + return self->GetSpecialAbility(ability); +} + +void Lua_Mob::SetSpecialAbility(int ability, int level) { + Lua_Safe_Call_Void(); + self->SetSpecialAbility(ability, level); +} + +void Lua_Mob::ClearSpecialAbilities() { + Lua_Safe_Call_Void(); + self->ClearSpecialAbilities(); +} + +void Lua_Mob::ProcessSpecialAbilities(std::string str) { + Lua_Safe_Call_Void(); + self->ProcessSpecialAbilities(str); +} + +void Lua_Mob::SetAppearance(int app) { + Lua_Safe_Call_Void(); + self->SetAppearance(static_cast(app)); +} + +void Lua_Mob::SetAppearance(int app, bool ignore_self) { + Lua_Safe_Call_Void(); + self->SetAppearance(static_cast(app), ignore_self); +} + luabind::scope lua_register_mob() { return luabind::class_("Mob") .def(luabind::constructor<>()) @@ -1983,7 +2015,56 @@ luabind::scope lua_register_mob() { .def("IsMeleeDisabled", (bool(Lua_Mob::*)(void))&Lua_Mob::IsMeleeDisabled) .def("SetFlurryChance", (void(Lua_Mob::*)(int))&Lua_Mob::SetFlurryChance) .def("GetFlurryChance", (int(Lua_Mob::*)(void))&Lua_Mob::GetFlurryChance) - .def("GetSkill", (int(Lua_Mob::*)(int))&Lua_Mob::GetSkill); + .def("GetSkill", (int(Lua_Mob::*)(int))&Lua_Mob::GetSkill) + .def("GetSpecialAbility", (int(Lua_Mob::*)(int))&Lua_Mob::GetSpecialAbility) + .def("SetSpecialAbility", (void(Lua_Mob::*)(int,int))&Lua_Mob::SetSpecialAbility) + .def("ClearSpecialAbilities", (void(Lua_Mob::*)(void))&Lua_Mob::ClearSpecialAbilities) + .def("ProcessSpecialAbilities", (void(Lua_Mob::*)(std::string))&Lua_Mob::ProcessSpecialAbilities) + .def("SetAppearance", (void(Lua_Mob::*)(int))&Lua_Mob::SetAppearance) + .def("SetAppearance", (void(Lua_Mob::*)(int,bool))&Lua_Mob::SetAppearance); +} + +luabind::scope lua_register_special_abilities() { + return luabind::class_("SpecialAbility") + .enum_("constants") + [ + luabind::value("none", static_cast(SPECATK_NONE)), + luabind::value("summon", static_cast(SPECATK_SUMMON)), + luabind::value("enrage", static_cast(SPECATK_ENRAGE)), + luabind::value("rampage", static_cast(SPECATK_RAMPAGE)), + luabind::value("area_rampage", static_cast(SPECATK_AREA_RAMPAGE)), + luabind::value("flurry", static_cast(SPECATK_FLURRY)), + luabind::value("triple_attack", static_cast(SPECATK_TRIPLE)), + luabind::value("quad_attack", static_cast(SPECATK_QUAD)), + luabind::value("innate_dual_wield", static_cast(SPECATK_INNATE_DW)), + luabind::value("bane_attack", static_cast(SPECATK_BANE)), + luabind::value("magical_attack", static_cast(SPECATK_MAGICAL)), + luabind::value("ranged_attack", static_cast(SPECATK_RANGED_ATK)), + luabind::value("unslowable", static_cast(UNSLOWABLE)), + luabind::value("unmezable", static_cast(UNMEZABLE)), + luabind::value("uncharmable", static_cast(UNCHARMABLE)), + luabind::value("unstunable", static_cast(UNSTUNABLE)), + luabind::value("unsnareable", static_cast(UNSNAREABLE)), + luabind::value("unfearable", static_cast(UNFEARABLE)), + luabind::value("undispellable", static_cast(UNDISPELLABLE)), + luabind::value("immune_melee", static_cast(IMMUNE_MELEE)), + luabind::value("immune_magic", static_cast(IMMUNE_MAGIC)), + luabind::value("immune_fleeing", static_cast(IMMUNE_FLEEING)), + luabind::value("immune_melee_except_bane", static_cast(IMMUNE_MELEE_EXCEPT_BANE)), + luabind::value("immune_melee_except_magical", static_cast(IMMUNE_MELEE_NONMAGICAL)), + luabind::value("immune_aggro", static_cast(IMMUNE_AGGRO)), + luabind::value("immune_aggro_on", static_cast(IMMUNE_AGGRO_ON)), + luabind::value("immune_casting_from_range", static_cast(IMMUNE_CASTING_FROM_RANGE)), + luabind::value("immune_feign_death", static_cast(IMMUNE_FEIGN_DEATH)), + luabind::value("immune_taunt", static_cast(IMMUNE_TAUNT)), + luabind::value("tunnelvision", static_cast(NPC_TUNNELVISION)), + luabind::value("dont_buff_friends", static_cast(NPC_NO_BUFFHEAL_FRIENDS)), + luabind::value("immune_pacify", static_cast(IMMUNE_PACIFY)), + luabind::value("leash", static_cast(LEASH)), + luabind::value("tether", static_cast(TETHER)), + luabind::value("destructible_object", static_cast(DESTRUCTIBLE_OBJECT)), + luabind::value("no_harm_from_client", static_cast(NO_HARM_FROM_CLIENT)) + ]; } #endif diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 9f23b5d34..ddae83f4a 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -15,6 +15,7 @@ namespace luabind { } luabind::scope lua_register_mob(); +luabind::scope lua_register_special_abilities(); class Lua_Mob : public Lua_Entity { @@ -332,6 +333,12 @@ public: int GetFlurryChance(); int GetSkill(int skill_id); void CalcBonuses(); + int GetSpecialAbility(int ability); + void SetSpecialAbility(int ability, int level); + void ClearSpecialAbilities(); + void ProcessSpecialAbilities(std::string str); + void SetAppearance(int app); + void SetAppearance(int app, bool ignore_self); }; #endif diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index f7b26668e..7a5563be1 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -934,6 +934,7 @@ void LuaParser::MapFunctions(lua_State *L) { lua_register_appearance(), lua_register_entity(), lua_register_mob(), + lua_register_special_abilities(), lua_register_npc(), lua_register_client(), lua_register_inventory(), diff --git a/zone/mob.cpp b/zone/mob.cpp index 4892d8ce3..50bf0c65e 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2336,48 +2336,63 @@ bool Mob::HateSummon() { if(GetOwnerID()) mob_owner = entity_list.GetMob(GetOwnerID()); - if (GetHPRatio() >= 98 || GetSpecialAbility(SPECATK_SUMMON) == 0 || !GetTarget() || - (mob_owner && mob_owner->IsClient() && !CheckLosFN(GetTarget()))) + int summon_level = GetSpecialAbility(SPECATK_SUMMON); + if(summon_level == 1 || summon_level == 3) { + //Summon things after we're hurt + if(GetHPRatio() >= 98 || !GetTarget() || (mob_owner && mob_owner->IsClient() && !CheckLosFN(GetTarget()))) { + return false; + } + } else if(summon_level == 2 || summon_level == 4) { + //Summon things always + if(!GetTarget() || (mob_owner && mob_owner->IsClient() && !CheckLosFN(GetTarget()))) { + return false; + } + } else { + //unsupported summon level or OFF return false; + } // now validate the timer Timer *timer = GetSpecialAbilityTimer(SPECATK_SUMMON); if (!timer) { StartSpecialAbilityTimer(SPECATK_SUMMON, 6000); - } + } else { + if(!timer->Check()) + return false; - // now check the timer - if (!timer->Check()) - return false; + timer->Start(6000); + } // get summon target SetTarget(GetHateTop()); if(target) { - if (target->IsClient()) - target->CastToClient()->Message(15,"You have been summoned!"); - entity_list.MessageClose(this, true, 500, 10, "%s says,'You will not evade me, %s!' ", GetCleanName(), target->GetCleanName() ); - - // RangerDown - GMMove doesn't seem to be working well with players, so use MovePC for them, GMMove for NPC's - if (target->IsClient()) { - target->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x_pos, y_pos, z_pos, target->GetHeading(), 0, SummonPC); - } - else { -#ifdef BOTS - if(target && target->IsBot()) { - // set pre summoning info to return to (to get out of melee range for caster) - target->CastToBot()->SetHasBeenSummoned(true); - target->CastToBot()->SetPreSummonX(target->GetX()); - target->CastToBot()->SetPreSummonY(target->GetY()); - target->CastToBot()->SetPreSummonZ(target->GetZ()); - + if(summon_level == 1 || summon_level == 2) { + entity_list.MessageClose(this, true, 500, 10, "%s says,'You will not evade me, %s!' ", GetCleanName(), target->GetCleanName() ); + + if (target->IsClient()) { + target->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x_pos, y_pos, z_pos, target->GetHeading(), 0, SummonPC); } + else { +#ifdef BOTS + if(target && target->IsBot()) { + // set pre summoning info to return to (to get out of melee range for caster) + target->CastToBot()->SetHasBeenSummoned(true); + target->CastToBot()->SetPreSummonX(target->GetX()); + target->CastToBot()->SetPreSummonY(target->GetY()); + target->CastToBot()->SetPreSummonZ(target->GetZ()); + + } #endif //BOTS - target->GMMove(x_pos, y_pos, z_pos, target->GetHeading()); + target->GMMove(x_pos, y_pos, z_pos, target->GetHeading()); + } + + return true; + } else if(summon_level == 3 || summon_level == 4) { + entity_list.MessageClose(this, true, 500, 10, "%s blinks to %s' ", GetCleanName(), target->GetCleanName()); + GMMove(target->GetX(), target->GetY(), target->GetZ()); } - - return true; } return false; } @@ -4802,7 +4817,6 @@ void Mob::StartSpecialAbilityTimer(int ability, uint32 time) { auto iter = SpecialAbilities.find(ability); if(iter != SpecialAbilities.end()) { SpecialAbility spec = iter->second; - spec.level = level; if(spec.timer) { spec.timer->Start(time); } else { @@ -4813,7 +4827,6 @@ void Mob::StartSpecialAbilityTimer(int ability, uint32 time) { SpecialAbilities[ability] = spec; } else { SpecialAbility spec; - spec.level = level; spec.timer = new Timer(time); spec.timer->Start(); SpecialAbilities[ability] = spec; @@ -4866,11 +4879,6 @@ void Mob::ProcessSpecialAbilities(const std::string str) { SetSpecialAbility(ability, value); switch(ability) { - case SPECATK_SUMMON: - if(value > 0) { - StartSpecialAbilityTimer(SPECATK_SUMMON, 6000); - } - break; case SPECATK_QUAD: if(value > 0) { SetSpecialAbility(SPECATK_TRIPLE, 1); diff --git a/zone/npc.cpp b/zone/npc.cpp index 00e5301c4..0113326bd 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -1440,7 +1440,6 @@ void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool rem StopSpecialAbilityTimer(SPECATK_SUMMON); } else { SetSpecialAbility(SPECATK_SUMMON, 1); - StartSpecialAbilityTimer(SPECATK_SUMMON, 6000); } break; case 'T':