* better error handling with missing/ not loaded MapTiles

* added some more hookable script events (_onobjectcreate, _onobjectdelete, _onteleport)
This commit is contained in:
False.Genesis 2007-11-28 18:09:53 +00:00
parent 7264398476
commit cf9fcb3d20
8 changed files with 94 additions and 10 deletions

View File

@ -1163,3 +1163,12 @@ std::string DefScriptPackage::GetUnescapedVar(std::string n)
{ {
return UnescapeString(variables.Get(n)); return UnescapeString(variables.Get(n));
} }
bool DefScriptPackage::RunScriptIfExists(std::string name,CmdSet *pSet)
{
if(ScriptExists(name))
{
return BoolRunScript(name,pSet);
}
return false;
}

View File

@ -120,6 +120,7 @@ public:
bool LoadScriptFromFile(std::string); bool LoadScriptFromFile(std::string);
DefReturnResult RunScript(std::string name,CmdSet* pSet,std::string override_name=""); DefReturnResult RunScript(std::string name,CmdSet* pSet,std::string override_name="");
bool BoolRunScript(std::string,CmdSet*); bool BoolRunScript(std::string,CmdSet*);
bool RunScriptIfExists(std::string name, CmdSet *pSet = NULL);
unsigned int GetScriptID(std::string); unsigned int GetScriptID(std::string);
DefReturnResult RunSingleLine(std::string); DefReturnResult RunSingleLine(std::string);
bool ScriptExists(std::string); bool ScriptExists(std::string);

View File

@ -51,6 +51,13 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g)
MapMgr *mapmgr = g->GetInstance()->GetWSession()->GetWorld()->GetMapMgr(); 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] // TODO: better to do this with some ZThread Condition or FastMutex, but dont know how to. help plz! [FG]
if(!mapmgr->Loaded()) if(!mapmgr->Loaded())
{ {
@ -59,6 +66,15 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g)
device->sleep(50); 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. // something is not good here. we have terrain, but the chunks are read incorrectly.
// need to find out where which formula is wrong // 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. // 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++) for(uint32 chx = 0; chx < 16; chx++)
{ {
MapChunk *chunk = maptile->GetChunk(chx, chy); MapChunk *chunk = maptile->GetChunk(chx, chy);
std::stringstream ss; //std::stringstream ss;
DEBUG(logdebug("Apply MapChunk (%u, %u)",chx,chy)); //DEBUG(logdebug("Apply MapChunk (%u, %u)",chx,chy));
for(uint32 hy = 0; hy < 9; hy++) for(uint32 hy = 0; hy < 9; hy++)
{ {
for(uint32 hx = 0; hx < 9; hx++) 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 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 h *= -1; // as suggested by bLuma
ss.precision(3); //ss.precision(3);
ss << h << '\t'; //ss << h << '\t';
terrain->setHeight((144 * tiley) + (9 * chx) + hx, (144 * tilex) + (9 * chy) + hy, h); 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())); //DEBUG(logdebug("\n%s\n",ss.str().c_str()));
} }

View File

@ -145,6 +145,19 @@ uint32 MapMgr::GetGridCoord(float f)
return (ZEROPOINT - f) / TILESIZE; 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) float MapMgr::GetZ(float x, float y)
{ {
uint32 xg,yg; // MapTile IDs. Range 0..64 uint32 xg,yg; // MapTile IDs. Range 0..64

View File

@ -17,6 +17,7 @@ public:
MapTile *GetCurrentTile(void); MapTile *GetCurrentTile(void);
MapTile *GetNearTile(int32, int32); MapTile *GetNearTile(int32, int32);
inline bool Loaded(void) { return _mapsLoaded; } inline bool Loaded(void) { return _mapsLoaded; }
uint32 GetLoadedMapsCount(void);
private: private:
MapTileStorage *_tiles; MapTileStorage *_tiles;

View File

@ -62,6 +62,16 @@ void WorldSession::_HandleDestroyObjectOpcode(WorldPacket& recvPacket)
uint64 guid; uint64 guid;
recvPacket >> guid; recvPacket >> guid;
logdebug("Destroy Object "I64FMT,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); objmgr.Remove(guid);
} }

View File

@ -79,6 +79,7 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
{ {
logdev("- already exists, deleting old , creating new object"); logdev("- already exists, deleting old , creating new object");
objmgr.Remove(uguid); objmgr.Remove(uguid);
// do not call script here, since the object does not really get deleted
} }
else else
{ {
@ -157,11 +158,18 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
// ...and ask the server for eventually missing data. // ...and ask the server for eventually missing data.
_QueryObjectInfo(uguid); _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, // if our own character got finally created, we have successfully entered the world,
// and should have gotten all info about our char already. // and should have gotten all info about our char already.
// TODO: make called script function like "_enterworld"
//if(uguid==GetGuid())
// _OnCharCreate();
} }
break; break;
@ -172,6 +180,16 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
{ {
uguid = recvPacket.GetPackedGuid(); // not 100% sure if this is correct uguid = recvPacket.GetPackedGuid(); // not 100% sure if this is correct
logdebug("GUID "I64FMT" out of range",uguid); 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); objmgr.Remove(uguid);
} }
} }

View File

@ -254,7 +254,7 @@ void WorldSession::_OnEnterWorld(void)
{ {
_logged=true; _logged=true;
GetInstance()->GetScripts()->variables.Set("@inworld","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()) if(InWorld())
{ {
_logged=false; _logged=false;
GetInstance()->GetScripts()->RunScript("_leaveworld",NULL); GetInstance()->GetScripts()->RunScriptIfExists("_leaveworld");
GetInstance()->GetScripts()->variables.Set("@inworld","false"); 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()) if(type==CHAT_MSG_WHISPER && (!isCmd) && target_guid!=GetGuid())
{ {
GetInstance()->GetScripts()->variables.Set("@thiswhisper_name",plrname); GetInstance()->GetScripts()->variables.Set("@thiswhisper_name",plrname);
@ -729,6 +731,13 @@ void WorldSession::_HandleTelePortAckOpcode(WorldPacket& recvPacket)
SendWorldPacket(response); SendWorldPacket(response);
if(_world) if(_world)
_world->UpdatePos(x,y); _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) void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket)
@ -747,6 +756,13 @@ void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket)
delete _world; delete _world;
_world = new World(this); _world = new World(this);
_world->UpdatePos(x,y,mapid); _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) void WorldSession::_HandleChannelNotifyOpcode(WorldPacket& recvPacket)