diff --git a/zone/QuestParserCollection.cpp b/zone/QuestParserCollection.cpp index bee3c735d..efdcafcaf 100644 --- a/zone/QuestParserCollection.cpp +++ b/zone/QuestParserCollection.cpp @@ -200,7 +200,7 @@ bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, const char *subname) item_script = "script_"; item_script += itoa(itm->GetItem()->ScriptFileID); } else { - item_script = itoa(itm->GetItem()->ID); + item_script += itoa(itm->GetItem()->ID); } std::map::iterator iter = _item_quest_status.find(item_script); @@ -341,7 +341,7 @@ int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst item_script = "script_"; item_script += itoa(item->GetItem()->ScriptFileID); } else { - item_script = itoa(item->GetItem()->ID); + item_script += itoa(item->GetItem()->ID); } std::map::iterator iter = _item_quest_status.find(item_script); diff --git a/zone/client.cpp b/zone/client.cpp index 172d18ea1..5f0dceb5f 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -151,7 +151,7 @@ Client::Client(EQStreamInterface* ieqs) #endif proximity_timer(ClientProximity_interval), TaskPeriodic_Timer(RuleI(TaskSystem, PeriodicCheckTimer) * 1000), - charm_update_timer(60000), + charm_update_timer(6000), rest_timer(1), charm_class_attacks_timer(3000), charm_cast_timer(3500), @@ -1029,14 +1029,14 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s case 8: { // /say if(message[0] == COMMAND_CHAR) { if(command_dispatch(this, message) == -2) { - if(parse->PlayerHasQuestSub("EVENT_COMMAND")) { - int i = parse->EventPlayer(EVENT_COMMAND, this, message, 0); - if(i != 0) { - Message(13, "Command '%s' not recognized.", message); - } - } else { + //if(parse->PlayerHasQuestSub("EVENT_COMMAND")) { + // int i = parse->EventPlayer(EVENT_COMMAND, this, message, 0); + // if(i != 0) { + // Message(13, "Command '%s' not recognized.", message); + // } + //} else { Message(13, "Command '%s' not recognized.", message); - } + //} } break; } diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 31c93aa1c..739a56480 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -159,7 +159,7 @@ bool Client::Process() { Save(); Group *mygroup = GetGroup(); - if (mygroup) // && zone.GetZoneID() != m_pp.binds[0].zoneId + if (mygroup) { entity_list.MessageGroup(this,true,15,"%s died.", GetName()); mygroup->MemberZoned(this); diff --git a/zone/embparser.cpp b/zone/embparser.cpp index dd378b106..c50c90872 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -95,7 +95,10 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_DUEL_LOSE", "EVENT_ENCOUNTER_LOAD", "EVENT_ENCOUNTER_UNLOAD", - "EVENT_COMMAND" + "EVENT_COMMAND", + "EVENT_DROP_ITEM", + "EVENT_DESTROY_ITEM", + "EVENT_FEIGN_DEATH" }; PerlembParser::PerlembParser() : perl(nullptr), event_queue_in_use_(false) { @@ -312,7 +315,6 @@ bool PerlembParser::ItemHasQuestSub(ItemInst *itm, const char *subname) { } else { - item_name = "item_"; item_name += itoa(item->ID); } @@ -817,7 +819,6 @@ void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlaye package_name += itoa(item->ScriptFileID); } else { - package_name += "item_"; package_name += itoa(objid); } } diff --git a/zone/entity.cpp b/zone/entity.cpp index 4aa53cec0..2dab3300f 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -3362,17 +3362,29 @@ void EntityList::ClearFeignAggro(Mob* targ) { if(iterator.GetData()->SpecAttacks[IMMUNE_FEIGN_DEATH]) { - iterator.GetData()->SetHate(targ, 0); iterator.Advance(); continue; } + if(targ->IsClient()) { + int i = parse->EventPlayer(EVENT_FEIGN_DEATH, targ->CastToClient(), "", 0); + if(i != 0) { + iterator.Advance(); + continue; + } + + if(iterator.GetData()->IsNPC()) { + int i = parse->EventNPC(EVENT_FEIGN_DEATH, iterator.GetData()->CastToNPC(), targ, "", 0); + if(i != 0) { + iterator.Advance(); + continue; + } + } + } + iterator.GetData()->RemoveFromHateList(targ); - // EverHood 6/24/06 - // For client targets if the mob that hated us is 35+ - // there is a 3 outta 5 chance he adds us to feign memory if(targ->IsClient()){ - if (iterator.GetData()->GetLevel() >= 35 && (MakeRandomInt(1,100)<=60)){ + if (iterator.GetData()->GetLevel() >= 35 && MakeRandomInt(1, 100) <= 60){ iterator.GetData()->AddFeignMemory(targ->CastToClient()); } else { targ->CastToClient()->RemoveXTarget(iterator.GetData(), false); @@ -3382,7 +3394,7 @@ void EntityList::ClearFeignAggro(Mob* targ) iterator.Advance(); } } -// EverHood 6/17/06 + void EntityList::ClearZoneFeignAggro(Client* targ) { LinkedListIterator iterator(npc_list); diff --git a/zone/event_codes.h b/zone/event_codes.h index 3562d7ad6..eee96bfc8 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -64,6 +64,9 @@ typedef enum { EVENT_ENCOUNTER_LOAD, EVENT_ENCOUNTER_UNLOAD, EVENT_COMMAND, + EVENT_DROP_ITEM, + EVENT_DESTROY_ITEM, + EVENT_FEIGN_DEATH, _LargestEventID } QuestEventID; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 9a828d1a2..63b60149e 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -32,6 +32,7 @@ #include "../common/StringUtil.h" #include "StringIDs.h" #include "NpcAI.h" +#include "QuestParserCollection.h" extern WorldServer worldserver; // @merth: this needs to be touched up @@ -319,29 +320,34 @@ void Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, // Drop item from inventory to ground (generally only dropped from SLOT_CURSOR) void Client::DropItem(int16 slot_id) { - - if (GetInv().CheckNoDrop(slot_id) && RuleI(World, FVNoDropFlag) == 0 || RuleI(Character, MinStatusForNoDropExemptions) < Admin() && RuleI(World, FVNoDropFlag) == 2) { - //Message(0, "No Drop Exploit: Items Destroyed."); + if(GetInv().CheckNoDrop(slot_id) && RuleI(World, FVNoDropFlag) == 0 || + RuleI(Character, MinStatusForNoDropExemptions) < Admin() && RuleI(World, FVNoDropFlag) == 2) { database.SetHackerFlag(this->AccountName(), this->GetCleanName(), "Tried to drop an item on the ground that was nodrop!"); GetInv().DeleteItem(slot_id); return; } // Take control of item in client inventory - ItemInst* inst = m_inv.PopItem(slot_id); - - if (!inst) { + ItemInst *inst = m_inv.PopItem(slot_id); + if(inst) { + int i = parse->EventItem(EVENT_DROP_ITEM, this, inst, 0, 0); + if(i != 0) { + safe_delete(inst); + return; + } + } else { // Item doesn't exist in inventory! Message(13, "Error: Item not found in slot %i", slot_id); return; } // Save client inventory change to database - if (slot_id==SLOT_CURSOR) { + if(slot_id == SLOT_CURSOR) { std::list::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end(); database.SaveCursor(CharacterID(), s, e); - } else + } else { database.SaveInventory(CharacterID(), nullptr, slot_id); + } // Package as zone object Object* object = new Object(this, inst); @@ -1005,6 +1011,12 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if(move_in->from_slot == (uint32)SLOT_CURSOR) { mlog(INVENTORY__SLOTS, "Client destroyed item from cursor slot %d", move_in->from_slot); if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit + + ItemInst *inst = m_inv.GetItem(SLOT_CURSOR); + if(inst) { + parse->EventItem(EVENT_DESTROY_ITEM, this, inst, 0, 0); + } + DeleteItemInInventory(move_in->from_slot); return true; // Item destroyed by client } diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index d7c340088..09b8d2147 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -93,7 +93,10 @@ const char *LuaEvents[_LargestEventID] = { "event_duel_lose", "event_encounter_load", "event_encounter_unload", - "event_command" + "event_command", + "event_drop_item", + "event_destroy_item", + "event_feign_death" }; extern Zone *zone; @@ -376,8 +379,7 @@ int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, uint3 return 0; } - std::stringstream package_name; - package_name << "item_"; + std::string package_name = "item_"; std::stringstream item_name; const Item_Struct* itm = item->GetItem(); @@ -392,12 +394,11 @@ int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, uint3 } else { - item_name << "item_"; item_name << itm->ID; } - package_name << item_name; + package_name += item_name.str(); - return _EventItem(package_name.str(), evt, client, item, objid, extra_data); + return _EventItem(package_name, evt, client, item, objid, extra_data); } int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data, @@ -422,6 +423,11 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl l_item_o.push(L); lua_setfield(L, -2, "self"); + Lua_Client l_client(client); + luabind::object l_client_o = luabind::object(L, l_client); + l_client_o.push(L); + lua_setfield(L, -2, "owner"); + auto arg_function = ItemArgumentDispatch[evt]; arg_function(this, L, client, item, objid, extra_data); @@ -623,8 +629,7 @@ bool LuaParser::SpellHasQuestSub(uint32 spell_id, const char *subname) { } bool LuaParser::ItemHasQuestSub(ItemInst *itm, const char *subname) { - std::stringstream package_name; - package_name << "item_"; + std::string package_name = "item_"; std::stringstream item_name; const Item_Struct* item = itm->GetItem(); @@ -639,12 +644,11 @@ bool LuaParser::ItemHasQuestSub(ItemInst *itm, const char *subname) { } else { - item_name << "item_"; item_name << item->ID; } - package_name << item_name; - return HasFunction(subname, package_name.str()); + package_name += item_name.str(); + return HasFunction(subname, package_name); } bool LuaParser::EncounterHasQuestSub(std::string encounter_name, const char *subname) { @@ -930,7 +934,6 @@ void LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *it } else { - item_name << "item_"; item_name << itm->ID; } package_name << item_name;