diff --git a/src/Client/DefScript/DynamicEvent.cpp b/src/Client/DefScript/DynamicEvent.cpp index 9f91b28..f0acace 100644 --- a/src/Client/DefScript/DynamicEvent.cpp +++ b/src/Client/DefScript/DynamicEvent.cpp @@ -5,83 +5,99 @@ struct DefScript_DynamicEvent { std::string name, cmd, parent; clock_t counter, interval; + bool ran; // if a script has an execution time longer then the interval, and modifies an event, need to check if the event was already triggered, to prevent endless loop }; DefScript_DynamicEventMgr::DefScript_DynamicEventMgr(DefScriptPackage *pack) { _pack = pack; _lastclock = clock(); + _events_changed = false; } DefScript_DynamicEventMgr::~DefScript_DynamicEventMgr() { - for(DefDynamicEventList::iterator i = _storage.begin(); i != _storage.end(); i++) - { - delete *i; - } + _storage.Clear(); } -void DefScript_DynamicEventMgr::Add(std::string name, std::string script, clock_t interval, const char *parent) +void DefScript_DynamicEventMgr::Add(std::string name, std::string script, clock_t interval, const char *parent, bool force) { _DEFSC_DEBUG( printf("DEFSCRIPT: Add Event %s, interval=%u, parent=%s\n",name.c_str(),interval,parent?parent:""); printf("DEFSCRIPT: EventRun='%s'\n",script.c_str()); ) if(name.empty() || script.empty() || interval==0) return; - for(DefDynamicEventList::iterator i = _storage.begin(); i != _storage.end(); i++) - if((*i)->name == name) - return; // event with that name is already registered - DefScript_DynamicEvent *e = new DefScript_DynamicEvent; + if(_storage.Exists(name) && !force) + return; + + DefScript_DynamicEvent *e = _storage.Get(name); e->name = name; e->cmd = script; e->interval = interval; e->parent = parent?parent:""; e->counter = 0; - _storage.push_back(e); + e->ran = false; + _events_changed = true; } void DefScript_DynamicEventMgr::Remove(std::string name) { - if(name.empty()) - return; - for(DefDynamicEventList::iterator i = _storage.begin(); i != _storage.end(); i++) - { - if((*i)->name == name) - { - delete *i; - _storage.erase(i); - break; - } - } - return; + _storage.Delete(name); + _events_changed = true; } void DefScript_DynamicEventMgr::Update(void) { + bool decr_timer = false; clock_t diff = clock() - _lastclock; _lastclock = clock(); DefScript *sc; - for(DefDynamicEventList::iterator i = _storage.begin(); i != _storage.end(); i++) + DefScript_DynamicEvent *e; + _events_changed = false; + + for(std::map::iterator i = _storage.GetMap().begin(); i != _storage.GetMap().end(); i++ ) { + i->second->ran = false; + } + + for(std::map::iterator i = _storage.GetMap().begin(); i != _storage.GetMap().end(); ) + { + e = i->second; sc = NULL; try { - (*i)->counter += diff; - if((*i)->counter >= (*i)->interval) + e->counter += diff; + if(e->counter >= e->interval && !e->ran) { - (*i)->counter %= (*i)->interval; + decr_timer = true; - if(!(*i)->parent.empty()) - sc = _pack->GetScript((*i)->parent); + if(!e->parent.empty()) + sc = _pack->GetScript(e->parent); if(sc) - _pack->RunSingleLineFromScript((*i)->cmd,sc); + _pack->RunSingleLineFromScript(e->cmd,sc); else - _pack->RunSingleLine((*i)->cmd); + _pack->RunSingleLine(e->cmd); } } catch (...) { printf("Error in DefScript_DynamicEventMgr::Update()\n"); + return; } + if(decr_timer) + { + e->counter %= e->interval; + e->ran = true; + decr_timer = false; + } + if(_events_changed) + { + _events_changed = false; + i = _storage.GetMap().begin(); + } + else + { + i++; + } } } \ No newline at end of file diff --git a/src/Client/DefScript/DynamicEvent.h b/src/Client/DefScript/DynamicEvent.h index 8cfab41..8df9c2f 100644 --- a/src/Client/DefScript/DynamicEvent.h +++ b/src/Client/DefScript/DynamicEvent.h @@ -5,24 +5,27 @@ #include #include +#include "TypeStorage.h" + struct DefScript_DynamicEvent; class DefScript; class DefScriptPackage; -typedef std::list DefDynamicEventList; +typedef TypeStorage DefDynamicEventStorage; class DefScript_DynamicEventMgr { public: DefScript_DynamicEventMgr(DefScriptPackage *pack); ~DefScript_DynamicEventMgr(); - void Add(std::string name, std::string script, clock_t interval, const char *parent); + void Add(std::string name, std::string script, clock_t interval, const char *parent, bool force = false); void Remove(std::string name); void Update(void); private: - DefDynamicEventList _storage; + DefDynamicEventStorage _storage; clock_t _lastclock; DefScriptPackage *_pack; + bool _events_changed; // this one helps to detect if a script called from an event has modified the event storage (risk of iterator invalidation!) }; #endif diff --git a/src/Client/DefScript/TypeStorage.h b/src/Client/DefScript/TypeStorage.h index c7d1ae9..94d7163 100644 --- a/src/Client/DefScript/TypeStorage.h +++ b/src/Client/DefScript/TypeStorage.h @@ -7,6 +7,7 @@ template class TypeStorage { public: + TypeStorage() { _keep = false; } ~TypeStorage(); bool Exists(std::string); void Delete(std::string); @@ -17,27 +18,27 @@ public: void Unlink(std::string); void UnlinkByPtr(T*); std::string GetNameByPtr(T*); + inline std::map &GetMap(void) { return _storage; } + inline bool SetKeepOnDestruct(bool b = true) { _keep = true; } + inline unsigned int Size(void) { return _storage.size(); } + void Clear(bool keep = false); private: T *_Create(std::string); std::map _storage; + bool _keep; }; // check whether an object with this name is already present template bool TypeStorage::Exists(std::string s) { - for(std::map::iterator it = _storage.begin(); it != _storage.end(); it++) - { - if(it->first == s) - return true; - } - return false; + return _storage.find(s) != _storage.end(); } // helper to create and assign a new object template T *TypeStorage::_Create(std::string s) { - T *elem = new T(); + T *elem = new T; _storage[s] = elem; return elem; } @@ -45,14 +46,11 @@ template T *TypeStorage::_Create(std::string s) // delete object with that name, if present template void TypeStorage::Delete(std::string s) { - for(std::map::iterator it = _storage.begin(); it != _storage.end(); it++) + std::map::iterator it = _storage.find(s); + if(it != _storage.end()) { - if(it->first == s) - { - delete it->second; - _storage.erase(it); - return; - } + delete it->second; + _storage.erase(it); } } @@ -73,9 +71,9 @@ template void TypeStorage::DeleteByPtr(T *ptr) // return the the object with that name. return NULL if not found template T *TypeStorage::GetNoCreate(std::string s) { - for(std::map::iterator it = _storage.begin(); it != _storage.end(); it++) - if(it->first == s) - return it->second; + std::map::iterator it = _storage.find(s); + if(it != _storage.end()) + return it->second; return NULL; } @@ -89,6 +87,16 @@ template T *TypeStorage::Get(std::string s) // when destroying the TypeStorage, delete all stored objects template TypeStorage::~TypeStorage() { + Clear(_keep); +} + +template void TypeStorage::Clear(bool keep) +{ + if(keep) + { + _storage.clear(); + return; + } for(std::map::iterator it = _storage.begin(); it != _storage.end();) { delete it->second; diff --git a/src/Client/World/Item.cpp b/src/Client/World/Item.cpp index 0c04c3b..e78d558 100644 --- a/src/Client/World/Item.cpp +++ b/src/Client/World/Item.cpp @@ -18,7 +18,7 @@ void WorldSession::_HandleItemQuerySingleResponseOpcode(WorldPacket& recvPacket) recvPacket >> proto->SubClass; recvPacket >> unk; // dont need that value? recvPacket >> proto->Name; - recvPacket >> s >> s >> s; // strip name1-4 + recvPacket >> s >> s >> s; // strip name2-4 recvPacket >> proto->DisplayInfoID; recvPacket >> proto->Quality; recvPacket >> proto->Flags; diff --git a/src/Client/World/ObjMgr.cpp b/src/Client/World/ObjMgr.cpp index 3d367d6..19bd6d3 100644 --- a/src/Client/World/ObjMgr.cpp +++ b/src/Client/World/ObjMgr.cpp @@ -70,7 +70,7 @@ Object *ObjMgr::GetObj(uint64 guid) return NULL; } -// iterate over all objects and assign a name to all matching the entry and typemask +// iterate over all objects and assign a name to all matching the entry and typeid uint32 ObjMgr::AssignNameToObj(uint32 entry, uint8 type, std::string name) { uint32 changed = 0;