diff --git a/src/Client/DefScript/DefScript.cpp b/src/Client/DefScript/DefScript.cpp index 55d3794..b3a952c 100644 --- a/src/Client/DefScript/DefScript.cpp +++ b/src/Client/DefScript/DefScript.cpp @@ -1163,3 +1163,12 @@ std::string DefScriptPackage::GetUnescapedVar(std::string n) { return UnescapeString(variables.Get(n)); } + +bool DefScriptPackage::RunScriptIfExists(std::string name,CmdSet *pSet) +{ + if(ScriptExists(name)) + { + return BoolRunScript(name,pSet); + } + return false; +} diff --git a/src/Client/DefScript/DefScript.h b/src/Client/DefScript/DefScript.h index df9c8b6..36e194e 100644 --- a/src/Client/DefScript/DefScript.h +++ b/src/Client/DefScript/DefScript.h @@ -120,6 +120,7 @@ public: bool LoadScriptFromFile(std::string); DefReturnResult RunScript(std::string name,CmdSet* pSet,std::string override_name=""); bool BoolRunScript(std::string,CmdSet*); + bool RunScriptIfExists(std::string name, CmdSet *pSet = NULL); unsigned int GetScriptID(std::string); DefReturnResult RunSingleLine(std::string); bool ScriptExists(std::string); diff --git a/src/Client/GUI/SceneWorld.cpp b/src/Client/GUI/SceneWorld.cpp index 4c4006a..935329d 100644 --- a/src/Client/GUI/SceneWorld.cpp +++ b/src/Client/GUI/SceneWorld.cpp @@ -51,6 +51,13 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g) MapMgr *mapmgr = g->GetInstance()->GetWSession()->GetWorld()->GetMapMgr(); + if(!mapmgr) + { + logerror("SceneWorld: MapMgr not present, cant create World GUI. Switching back GUI to idle."); + g->SetSceneState(SCENESTATE_GUISTART); + return; + } + // TODO: better to do this with some ZThread Condition or FastMutex, but dont know how to. help plz! [FG] if(!mapmgr->Loaded()) { @@ -59,6 +66,15 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g) device->sleep(50); } + // TODO: as soon as WMO-only worlds are implemented, remove this!! + if(!mapmgr->GetLoadedMapsCount()) + { + logerror("SceneWorld: Error: No maps loaded, not able to draw any terrain. Switching back GUI to idle."); + logerror("SceneWorld: Hint: Be sure you are not in an WMO-only world (e.g. human capital city or most instances)!"); + g->SetSceneState(SCENESTATE_GUISTART); + return; + } + // something is not good here. we have terrain, but the chunks are read incorrectly. // need to find out where which formula is wrong // the current terrain renderer code is just a test to see if ADT files are read correctly. @@ -76,19 +92,19 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g) for(uint32 chx = 0; chx < 16; chx++) { MapChunk *chunk = maptile->GetChunk(chx, chy); - std::stringstream ss; - DEBUG(logdebug("Apply MapChunk (%u, %u)",chx,chy)); + //std::stringstream ss; + //DEBUG(logdebug("Apply MapChunk (%u, %u)",chx,chy)); for(uint32 hy = 0; hy < 9; hy++) { for(uint32 hx = 0; hx < 9; hx++) { f32 h = chunk->hmap_rough[hx * 9 + hy] + chunk->baseheight; // not sure if hx and hy are used correctly here h *= -1; // as suggested by bLuma - ss.precision(3); - ss << h << '\t'; + //ss.precision(3); + //ss << h << '\t'; terrain->setHeight((144 * tiley) + (9 * chx) + hx, (144 * tilex) + (9 * chy) + hy, h); } - ss << "\n"; + //ss << "\n"; } //DEBUG(logdebug("\n%s\n",ss.str().c_str())); } diff --git a/src/Client/World/MapMgr.cpp b/src/Client/World/MapMgr.cpp index a70a8c9..2a93e5b 100644 --- a/src/Client/World/MapMgr.cpp +++ b/src/Client/World/MapMgr.cpp @@ -145,6 +145,19 @@ uint32 MapMgr::GetGridCoord(float f) return (ZEROPOINT - f) / TILESIZE; } +uint32 MapMgr::GetLoadedMapsCount(void) +{ + uint32 counter = 0; + for(uint32 i = 0; i < 4096; i++) + { + if(_tiles->GetTile(i)) + { + counter++; + } + } + return counter; +} + float MapMgr::GetZ(float x, float y) { uint32 xg,yg; // MapTile IDs. Range 0..64 diff --git a/src/Client/World/MapMgr.h b/src/Client/World/MapMgr.h index 9215a2b..48535cc 100644 --- a/src/Client/World/MapMgr.h +++ b/src/Client/World/MapMgr.h @@ -17,6 +17,7 @@ public: MapTile *GetCurrentTile(void); MapTile *GetNearTile(int32, int32); inline bool Loaded(void) { return _mapsLoaded; } + uint32 GetLoadedMapsCount(void); private: MapTileStorage *_tiles; diff --git a/src/Client/World/Object.cpp b/src/Client/World/Object.cpp index ac5389a..d1258b1 100644 --- a/src/Client/World/Object.cpp +++ b/src/Client/World/Object.cpp @@ -62,6 +62,16 @@ void WorldSession::_HandleDestroyObjectOpcode(WorldPacket& recvPacket) uint64 guid; recvPacket >> guid; logdebug("Destroy Object "I64FMT,guid); + + // call script just before object removal + if(GetInstance()->GetScripts()->ScriptExists("_onobjectdelete")) + { + CmdSet Set; + Set.defaultarg = toString(guid); + Set.arg[0] = "false"; // out of range = false + GetInstance()->GetScripts()->RunScript("_onobjectdelete", &Set); + } + objmgr.Remove(guid); } diff --git a/src/Client/World/UpdateData.cpp b/src/Client/World/UpdateData.cpp index 9b631d6..88e31bf 100644 --- a/src/Client/World/UpdateData.cpp +++ b/src/Client/World/UpdateData.cpp @@ -79,6 +79,7 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket) { logdev("- already exists, deleting old , creating new object"); objmgr.Remove(uguid); + // do not call script here, since the object does not really get deleted } else { @@ -157,11 +158,18 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket) // ...and ask the server for eventually missing data. _QueryObjectInfo(uguid); + + // call script "_OnObjectCreate" + if(GetInstance()->GetScripts()->ScriptExists("_onobjectcreate")) + { + CmdSet Set; + Set.defaultarg = toString(uguid); + Set.arg[0] = toString(objtypeid); + GetInstance()->GetScripts()->RunScript("_onobjectcreate", &Set); + } + // if our own character got finally created, we have successfully entered the world, // and should have gotten all info about our char already. - // TODO: make called script function like "_enterworld" - //if(uguid==GetGuid()) - // _OnCharCreate(); } break; @@ -172,6 +180,16 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket) { uguid = recvPacket.GetPackedGuid(); // not 100% sure if this is correct logdebug("GUID "I64FMT" out of range",uguid); + + // call script just before object removal + if(GetInstance()->GetScripts()->ScriptExists("_onobjectdelete")) + { + CmdSet Set; + Set.defaultarg = toString(uguid); + Set.arg[0] = "true"; // out of range = true + GetInstance()->GetScripts()->RunScript("_onobjectdelete", &Set); + } + objmgr.Remove(uguid); } } diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index c7cdd67..1a415fc 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -254,7 +254,7 @@ void WorldSession::_OnEnterWorld(void) { _logged=true; GetInstance()->GetScripts()->variables.Set("@inworld","true"); - GetInstance()->GetScripts()->RunScript("_enterworld",NULL); + GetInstance()->GetScripts()->RunScriptIfExists("_enterworld"); } } @@ -264,7 +264,7 @@ void WorldSession::_OnLeaveWorld(void) if(InWorld()) { _logged=false; - GetInstance()->GetScripts()->RunScript("_leaveworld",NULL); + GetInstance()->GetScripts()->RunScriptIfExists("_leaveworld"); GetInstance()->GetScripts()->variables.Set("@inworld","false"); } } @@ -589,6 +589,8 @@ void WorldSession::_HandleMessageChatOpcode(WorldPacket& recvPacket) } } + + // TODO: remove this block soon, its obsoelete and has to be done via scripting! if(type==CHAT_MSG_WHISPER && (!isCmd) && target_guid!=GetGuid()) { GetInstance()->GetScripts()->variables.Set("@thiswhisper_name",plrname); @@ -729,6 +731,13 @@ void WorldSession::_HandleTelePortAckOpcode(WorldPacket& recvPacket) SendWorldPacket(response); if(_world) _world->UpdatePos(x,y); + + if(GetInstance()->GetScripts()->ScriptExists("_onteleport")) + { + CmdSet Set; + Set.defaultarg = "false"; // teleported to other map = false + GetInstance()->GetScripts()->RunScriptIfExists("_onteleport"); + } } void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket) @@ -747,6 +756,13 @@ void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket) delete _world; _world = new World(this); _world->UpdatePos(x,y,mapid); + + if(GetInstance()->GetScripts()->ScriptExists("_onteleport")) + { + CmdSet Set; + Set.defaultarg = "true"; // teleported to other map = false + GetInstance()->GetScripts()->RunScriptIfExists("_onteleport"); + } } void WorldSession::_HandleChannelNotifyOpcode(WorldPacket& recvPacket)