diff --git a/changelog.txt b/changelog.txt index 5d2345521..adc272817 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,12 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- -== 12/07/2016 == +== 12/14/2015 == +Kinglykrab: Added IsBlind() and IsFeared() functionality to Perl and Lua. + - Note: Both methods are Mob methods and may be used on NPCs or PCs. +Natedog: Added Discipline functions, UpdateInstanceTimer function, and UnmemSpellBySpellID to lua and perl + -Examples: http://wiki.eqemulator.org/i?M=Pastebin&Paste=BJ0ygmNM + +== 12/07/2015 == Uleat: Command aliases are no longer handled through the command_add() function. - To add a command alias, edit the database table `command_settings` - here, you will find three columns: `command`, `access` and `aliases` - Adding command aliases require that the command contain an entry in `command_settings`.`command` diff --git a/common/database_conversions.cpp b/common/database_conversions.cpp index fc5877e05..fa7c57a12 100644 --- a/common/database_conversions.cpp +++ b/common/database_conversions.cpp @@ -493,7 +493,7 @@ bool Database::CheckDatabaseConversions() { /* Check for a new version of this script, the arg passed would have to be higher than the copy they have downloaded locally and they will re fetch */ - system("perl eqemu_update.pl V 12"); + system("perl eqemu_update.pl V 13"); /* Run Automatic Database Upgrade Script */ system("perl eqemu_update.pl ran_from_world"); diff --git a/utils/scripts/eqemu_update.pl b/utils/scripts/eqemu_update.pl index b6c4ab1d0..8fd3af540 100644 --- a/utils/scripts/eqemu_update.pl +++ b/utils/scripts/eqemu_update.pl @@ -23,7 +23,7 @@ if($Config{osname}=~/linux/i){ $OS = "Linux"; } if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; } #::: If current version is less than what world is reporting, then download a new one... -$current_version = 12; +$current_version = 13; if($ARGV[0] eq "V"){ if($ARGV[1] > $current_version){ @@ -251,6 +251,7 @@ sub show_menu_prompt { 11 => \&fetch_latest_windows_binaries, 12 => \&fetch_server_dlls, 13 => \&do_windows_login_server_setup, + 19 => \&do_bots_db_schema_drop, 20 => \&do_update_self, 0 => \&script_exit, ); @@ -327,6 +328,7 @@ return < commandlist; +std::map commandaliases; //All allocated CommandRecords get put in here so they get deleted on shutdown LinkedList cleanup_commandlist; @@ -418,6 +419,8 @@ int command_init(void) return -1; } + commandaliases.clear(); + std::map>> command_settings; database.GetCommandSettings(command_settings); for (std::map::iterator iter_cl = commandlist.begin(); iter_cl != commandlist.end(); ++iter_cl) { @@ -442,6 +445,9 @@ int command_init(void) } commandlist[*iter_aka] = iter_cl->second; + commandaliases[*iter_aka] = iter_cl->first; + + Log.Out(Logs::General, Logs::Commands, "command_init(): - Alias '%s' added to command '%s'.", iter_aka->c_str(), commandaliases[*iter_aka].c_str()); } } @@ -461,6 +467,7 @@ int command_init(void) void command_deinit(void) { commandlist.clear(); + commandaliases.clear(); command_dispatch = command_notavail; commandcount = 0; diff --git a/zone/effects.cpp b/zone/effects.cpp index dc069fb2a..dc3392403 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -571,6 +571,33 @@ bool Client::TrainDiscipline(uint32 itemid) { return(false); } +void Client::TrainDiscBySpellID(int32 spell_id) +{ + int i; + for(i = 0; i < MAX_PP_DISCIPLINES; i++) { + if(m_pp.disciplines.values[i] == 0) { + m_pp.disciplines.values[i] = spell_id; + database.SaveCharacterDisc(this->CharacterID(), i, spell_id); + SendDisciplineUpdate(); + Message(15, "You have learned a new combat ability!"); + return; + } + } +} + +int Client::GetDiscSlotBySpellID(int32 spellid) +{ + int i; + + for(i = 0; i < MAX_PP_DISCIPLINES; i++) + { + if(m_pp.disciplines.values[i] == spellid) + return i; + } + + return -1; +} + void Client::SendDisciplineUpdate() { EQApplicationPacket app(OP_DisciplineUpdate, sizeof(Disciplines_Struct)); Disciplines_Struct *d = (Disciplines_Struct*)app.pBuffer; diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index f5de73698..126e8169d 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -2906,6 +2906,19 @@ XS(XS__DestroyInstance) { XSRETURN_EMPTY; } +XS(XS__UpdateInstanceTimer); +XS(XS__UpdateInstanceTimer) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: UpdateInstanceTimer(instance_id, new_duration)"); + + uint16 instance_id = (uint16)SvUV(ST(0)); + uint32 new_duration = (uint32)SvUV(ST(1)); + quest_manager.UpdateInstanceTimer(instance_id, new_duration); + + XSRETURN_EMPTY; +} + XS(XS__GetInstanceID); XS(XS__GetInstanceID) { dXSARGS; @@ -3636,6 +3649,7 @@ EXTERN_C XS(boot_quest) newXS(strcpy(buf, "ChooseRandom"), XS__ChooseRandom, file); newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file); newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file); + newXS(strcpy(buf, "UpdateInstanceTimer"), XS__UpdateInstanceTimer, file); newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file); newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file); newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index b7dad0ce3..1e785ce9b 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -530,6 +530,11 @@ void Lua_Client::UnmemSpell(int slot, bool update_client) { self->UnmemSpell(slot, update_client); } +void Lua_Client::UnmemSpellBySpellID(int32 spell_id) { + Lua_Safe_Call_Void(); + self->UnmemSpellBySpellID(spell_id); +} + void Lua_Client::UnmemSpellAll() { Lua_Safe_Call_Void(); self->UnmemSpellAll(); @@ -575,6 +580,16 @@ void Lua_Client::TrainDisc(int itemid) { self->TrainDiscipline(itemid); } +void Lua_Client::TrainDiscBySpellID(int32 spell_id) { + Lua_Safe_Call_Void(); + self->TrainDiscBySpellID(spell_id); +} + +int Lua_Client::GetDiscSlotBySpellID(int32 spell_id) { + Lua_Safe_Call_Int(); + return self->GetDiscSlotBySpellID(spell_id); +} + void Lua_Client::UntrainDisc(int slot) { Lua_Safe_Call_Void(); self->UntrainDisc(slot); @@ -1426,6 +1441,7 @@ luabind::scope lua_register_client() { .def("MemSpell", (void(Lua_Client::*)(int,int,bool))&Lua_Client::MemSpell) .def("UnmemSpell", (void(Lua_Client::*)(int))&Lua_Client::UnmemSpell) .def("UnmemSpell", (void(Lua_Client::*)(int,bool))&Lua_Client::UnmemSpell) + .def("UnmemSpellBySpellID", (void(Lua_Client::*)(int32))&Lua_Client::UnmemSpellBySpellID) .def("UnmemSpellAll", (void(Lua_Client::*)(void))&Lua_Client::UnmemSpellAll) .def("UnmemSpellAll", (void(Lua_Client::*)(bool))&Lua_Client::UnmemSpellAll) .def("ScribeSpell", (void(Lua_Client::*)(int,int))&Lua_Client::ScribeSpell) @@ -1435,6 +1451,8 @@ luabind::scope lua_register_client() { .def("UnscribeSpellAll", (void(Lua_Client::*)(void))&Lua_Client::UnscribeSpellAll) .def("UnscribeSpellAll", (void(Lua_Client::*)(bool))&Lua_Client::UnscribeSpellAll) .def("TrainDisc", (void(Lua_Client::*)(int))&Lua_Client::TrainDisc) + .def("TrainDiscBySpellID", (void(Lua_Client::*)(int32))&Lua_Client::TrainDiscBySpellID) + .def("GetDiscSlotBySpellID", (int(Lua_Client::*)(int32))&Lua_Client::GetDiscSlotBySpellID) .def("UntrainDisc", (void(Lua_Client::*)(int))&Lua_Client::UntrainDisc) .def("UntrainDisc", (void(Lua_Client::*)(int,bool))&Lua_Client::UntrainDisc) .def("UntrainDiscAll", (void(Lua_Client::*)(void))&Lua_Client::UntrainDiscAll) diff --git a/zone/lua_client.h b/zone/lua_client.h index e50a16b98..4584edfd0 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -131,6 +131,7 @@ public: void MemSpell(int spell_id, int slot, bool update_client); void UnmemSpell(int slot); void UnmemSpell(int slot, bool update_client); + void UnmemSpellBySpellID(int32 spell_id); void UnmemSpellAll(); void UnmemSpellAll(bool update_client); void ScribeSpell(int spell_id, int slot); @@ -140,6 +141,8 @@ public: void UnscribeSpellAll(); void UnscribeSpellAll(bool update_client); void TrainDisc(int itemid); + void TrainDiscBySpellID(int32 spell_id); + int GetDiscSlotBySpellID(int32 spell_id); void UntrainDisc(int slot); void UntrainDisc(int slot, bool update_client); void UntrainDiscAll(); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 15a11604b..bed0fd7bc 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -804,6 +804,10 @@ void lua_destroy_instance(uint32 instance_id) { quest_manager.DestroyInstance(instance_id); } +void lua_update_instance_timer(uint16 instance_id, uint32 new_duration) { + quest_manager.UpdateInstanceTimer(instance_id, new_duration); +} + int lua_get_instance_id(const char *zone, uint32 version) { return quest_manager.GetInstanceID(zone, version); } @@ -1576,6 +1580,7 @@ luabind::scope lua_register_general() { luabind::def("get_guild_name_by_id", &lua_get_guild_name_by_id), luabind::def("create_instance", &lua_create_instance), luabind::def("destroy_instance", &lua_destroy_instance), + luabind::def("update_instance_timer", &lua_update_instance_timer), luabind::def("get_instance_id", &lua_get_instance_id), luabind::def("get_characters_in_instance", &lua_get_characters_in_instance), luabind::def("assign_to_instance", &lua_assign_to_instance), diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 2f0712ec0..3963ec64c 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -1871,6 +1871,16 @@ void Lua_Mob::SetPseudoRoot(bool in) { self->SetPseudoRoot(in); } +bool Lua_Mob::IsFeared() { + Lua_Safe_Call_Bool(); + return self->IsFeared(); +} + +bool Lua_Mob::IsBlind() { + Lua_Safe_Call_Bool(); + return self->IsBlind(); +} + luabind::scope lua_register_mob() { return luabind::class_("Mob") .def(luabind::constructor<>()) @@ -2156,6 +2166,8 @@ luabind::scope lua_register_mob() { .def("WearChange", (void(Lua_Mob::*)(int,int,uint32))&Lua_Mob::WearChange) .def("DoKnockback", (void(Lua_Mob::*)(Lua_Mob,uint32,uint32))&Lua_Mob::DoKnockback) .def("RemoveNimbusEffect", (void(Lua_Mob::*)(int))&Lua_Mob::RemoveNimbusEffect) + .def("IsFeared", (bool(Lua_Mob::*)(void))&Lua_Mob::IsFeared) + .def("IsBlind", (bool(Lua_Mob::*)(void))&Lua_Mob::IsBlind) .def("IsRunning", (bool(Lua_Mob::*)(void))&Lua_Mob::IsRunning) .def("SetRunning", (void(Lua_Mob::*)(bool))&Lua_Mob::SetRunning) .def("SetBodyType", (void(Lua_Mob::*)(int,bool))&Lua_Mob::SetBodyType) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 4f427aca5..3b98b4af3 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -40,6 +40,8 @@ public: void SetLevel(int level, bool command); void SendWearChange(int material_slot); bool IsMoving(); + bool IsFeared(); + bool IsBlind(); void GotoBind(); void Gate(); bool Attack(Lua_Mob other); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 3858eac0e..d4c5f34d0 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -2445,6 +2445,30 @@ XS(XS_Client_UnmemSpell) XSRETURN_EMPTY; } +XS(XS_Client_UnmemSpellBySpellID); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_UnmemSpellBySpellID) +{ + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::UnmemSpellBySpellID(THIS, spell_id)"); + { + Client * THIS; + int32 spell_id = (int32)SvIV(ST(1)); + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Client *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Client"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + THIS->UnmemSpellBySpellID(spell_id); + } + XSRETURN_EMPTY; +} + XS(XS_Client_UnmemSpellAll); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_UnmemSpellAll) { @@ -2568,6 +2592,57 @@ XS(XS_Client_UnscribeSpellAll) XSRETURN_EMPTY; } +XS(XS_Client_TrainDiscBySpellID); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_TrainDiscBySpellID) +{ + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::TrainDiscBySpellID(THIS, spell_id)"); + { + Client * THIS; + int32 spell_id = (int32)SvIV(ST(1)); + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Client *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Client"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + THIS->TrainDiscBySpellID(spell_id); + } + XSRETURN_EMPTY; +} + +XS(XS_Client_GetDiscSlotBySpellID); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_GetDiscSlotBySpellID) +{ + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::GetDiscSlotBySpellID(THIS, spell_id)"); + { + Client * THIS; + int RETVAL; + int32 spell_id = (int32)SvIV(ST(1)); + dXSTARG; + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Client *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Client"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetDiscSlotBySpellID(spell_id); + XSprePUSH; PUSHi((IV)RETVAL); + } + XSRETURN(1); +} + XS(XS_Client_UntrainDisc); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_UntrainDisc) { @@ -6443,10 +6518,13 @@ XS(boot_Client) newXSproto(strcpy(buf, "ResetAA"), XS_Client_ResetAA, file, "$"); newXSproto(strcpy(buf, "MemSpell"), XS_Client_MemSpell, file, "$$$;$"); newXSproto(strcpy(buf, "UnmemSpell"), XS_Client_UnmemSpell, file, "$$;$"); + newXSproto(strcpy(buf, "UnmemSpellBySpellID"), XS_Client_UnmemSpellBySpellID, file, "$$"); newXSproto(strcpy(buf, "UnmemSpellAll"), XS_Client_UnmemSpellAll, file, "$;$"); newXSproto(strcpy(buf, "ScribeSpell"), XS_Client_ScribeSpell, file, "$$$;$"); newXSproto(strcpy(buf, "UnscribeSpell"), XS_Client_UnscribeSpell, file, "$$;$"); newXSproto(strcpy(buf, "UnscribeSpellAll"), XS_Client_UnscribeSpellAll, file, "$;$"); + newXSproto(strcpy(buf, "TrainDiscBySpellID"), XS_Client_TrainDiscBySpellID, file, "$$"); + newXSproto(strcpy(buf, "GetDiscSlotBySpellID"), XS_Client_GetDiscSlotBySpellID, file, "$$"); newXSproto(strcpy(buf, "UntrainDisc"), XS_Client_UntrainDisc, file, "$$;$"); newXSproto(strcpy(buf, "UntrainDiscAll"), XS_Client_UntrainDiscAll, file, "$;$"); newXSproto(strcpy(buf, "IsSitting"), XS_Client_IsSitting, file, "$"); diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 323d22b36..adbdd0301 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -8440,6 +8440,56 @@ XS(XS_Mob_CanClassEquipItem) XSRETURN(1); } +XS(XS_Mob_IsFeared); +XS(XS_Mob_IsFeared) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Mob::IsFeared(THIS)"); + { + Mob* THIS; + bool RETVAL; + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Mob*, tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Mob"); + + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->IsFeared(); + ST(0) = boolSV(RETVAL); + sv_2mortal(ST(0)); + } + XSRETURN(1); +} + +XS(XS_Mob_IsBlind); +XS(XS_Mob_IsBlind) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Mob::IsBlind(THIS)"); + { + Mob* THIS; + bool RETVAL; + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Mob*, tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Mob"); + + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->IsBlind(); + ST(0) = boolSV(RETVAL); + sv_2mortal(ST(0)); + } + XSRETURN(1); +} + #ifdef __cplusplus extern "C" #endif @@ -8751,6 +8801,8 @@ XS(boot_Mob) newXSproto(strcpy(buf, "ClearSpecialAbilities"), XS_Mob_ClearSpecialAbilities, file, "$"); newXSproto(strcpy(buf, "ProcessSpecialAbilities"), XS_Mob_ProcessSpecialAbilities, file, "$$"); newXSproto(strcpy(buf, "CanClassEquipItem"), XS_Mob_CanClassEquipItem, file, "$$"); + newXSproto(strcpy(buf, "IsFeared"), XS_Mob_IsFeared, file, "$"); + newXSproto(strcpy(buf, "IsBlind"), XS_Mob_IsBlind, file, "$"); XSRETURN_YES; } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index fd157f372..cb70f93d3 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2582,6 +2582,22 @@ void QuestManager::DestroyInstance(uint16 instance_id) database.DeleteInstance(instance_id); } +void QuestManager::UpdateInstanceTimer(uint16 instance_id, uint32 new_duration) +{ + std::string query = StringFormat("UPDATE instance_list SET duration = %lu, start_time = UNIX_TIMESTAMP() WHERE id = %lu", + (unsigned long)new_duration, (unsigned long)instance_id); + auto results = database.QueryDatabase(query); + + if (results.Success()) { + auto pack = new ServerPacket(ServerOP_InstanceUpdateTime, sizeof(ServerInstanceUpdateTime_Struct)); + ServerInstanceUpdateTime_Struct *ut = (ServerInstanceUpdateTime_Struct*)pack->pBuffer; + ut->instance_id = instance_id; + ut->new_duration = new_duration; + worldserver.SendPacket(pack); + safe_delete(pack); + } +} + uint16 QuestManager::GetInstanceID(const char *zone, int16 version) { QuestManagerCurrentQuestVars(); diff --git a/zone/questmgr.h b/zone/questmgr.h index 78f4b34ed..cd1c4a303 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -217,6 +217,7 @@ public: void MerchantSetItem(uint32 NPCid, uint32 itemid, uint32 quantity = 0); uint32 MerchantCountItem(uint32 NPCid, uint32 itemid); uint16 CreateInstance(const char *zone, int16 version, uint32 duration); + void UpdateInstanceTimer(uint16 instance_id, uint32 new_duration); void DestroyInstance(uint16 instance_id); uint16 GetInstanceID(const char *zone, int16 version); void AssignToInstance(uint16 instance_id); diff --git a/zone/spells.cpp b/zone/spells.cpp index 9ec68c3ff..18de9a444 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -4910,6 +4910,16 @@ void Client::UnmemSpell(int slot, bool update_client) } } +void Client::UnmemSpellBySpellID(int32 spell_id) +{ + for(int i = 0; i < MAX_PP_MEMSPELL; i++) { + if(m_pp.mem_spells[i] == spell_id) { + UnmemSpell(i, true); + break; + } + } +} + void Client::UnmemSpellAll(bool update_client) { int i;