* 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));
}
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);
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);

View File

@ -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()));
}

View File

@ -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

View File

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

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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)