From: Manuel A. F. M. <ma...@us...> - 2005-06-30 19:12:46
|
Update of /cvsroot/once/oncecode/src/client In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28293/d/d Added Files: ocentitymgr.h ocentitymgr.cpp Log Message: Splitting entity message handlers and the manipulation itself, as it's done with the rest of messages --- NEW FILE: ocentitymgr.h --- /* * ochdlentities.h * Copyright (C) 2003-2005 by The Once developement team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OCENTITYMGR_H #define OCENTITYMGR_H struct iCelBlLayer; struct iCelPlLayer; struct iCelEntity; struct iPcDefaultCamera; class ocEntityCreateMsg; class ocEntityChangeMsg; class ocEntityDestroyMsg; /** * This class takes care of managing the entities received through network */ class ocEntityHandler { private: /// Link to the physical layer csRef<iCelPlLayer> pl; /// Link to the behaviour layer csRef<iCelBlLayer> bl; /// Get the behaviour name from the entity type and the ID. const char* GetBehaviourName(uint id, const char* entity_name); /// Destroy given entity and remove it from the entity registry void DestroyEntity(iCelEntity* entity); /// Register an entity into the entity registry void RegisterEntity(iCelEntity* entity); /// The camera we use (probably should be accessable via clientsys-> csRef<iPcDefaultCamera> pccamera; bool CreateMainPlayer(iCelEntity* entity, ocEntityCreateMsg* msg); bool CreatePlayer(iCelEntity* entity, ocEntityCreateMsg* msg); bool CreateMovableObject(iCelEntity* entity, ocEntityCreateMsg* msg); bool CreateStaticObject(iCelEntity* entity, ocEntityCreateMsg* msg); bool CreateSector(iCelEntity* entity, ocEntityCreateMsg* msg); public: ocEntityHandler(csRef<iCelPlLayer> pl, csRef<iCelBlLayer> bl); ~ocEntityHandler(); /// Handle a 'Entity New' msg bool ReadEntityCreate(ocEntityCreateMsg* msg); /// Handle a 'Entity Change' msg bool ReadEntityChange(ocEntityChangeMsg* msg); /// Handle a 'Entity Destroy' msg bool ReadEntityDestroy(ocEntityDestroyMsg* msg); }; #endif --- NEW FILE: ocentitymgr.cpp --- /* * ochdlentities.cpp * Copyright (C) 2003-2005 by The Once developement team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "common/oclogger.h" #include <iengine/engine.h> #include <iengine/mesh.h> #include <iengine/region.h> #include <iengine/sector.h> #include <ivaria/reporter.h> #include <behaviourlayer/bl.h> #include <behaviourlayer/behave.h> #include <physicallayer/pl.h> #include <physicallayer/entity.h> #include <physicallayer/propclas.h> #include <propclass/actormove.h> #include <propclass/defcam.h> #include <propclass/input.h> #include <propclass/inv.h> #include <propclass/linmove.h> #include <propclass/mesh.h> #include <propclass/meshsel.h> #include <propclass/prop.h> #include <propclass/region.h> #include <propclass/timer.h> #include <propclass/tooltip.h> #include <propclass/zone.h> #include <celtool/stdparams.h> #include "common/ocentityreg.h" #include "common/ocloader.h" #include "common/netmsg/ocentitymsgs.h" #include "client/ocstatemgr.h" #include "client/occlient.h" #include "ocentitymgr.h" //----------------------------- ocEntityHandler ------------------------------ ocEntityHandler::ocEntityHandler(csRef<iCelPlLayer> p, csRef<iCelBlLayer> b) : pl(p), bl(b) { OCTRACE("ocEntityHandler"); } ocEntityHandler::~ocEntityHandler() { OCTRACE("~ocEntityHandler"); } const char* ocEntityHandler::GetBehaviourName(uint, const char* entity_name) { OCTRACE("ocEntityHandler::GetBehaviourName"); if (strcmp(entity_name, "Player") == 0) return "ocPlayerBehaviour"; else if (strcmp(entity_name, "Area") == 0) return "ocAreaBehaviour"; else if (strcmp(entity_name, "Object") == 0) return "ocObjectBehaviour"; else if (strcmp(entity_name, "StaticObject") == 0) return "ocStaticObjectBehaviour"; else clientsys->Report(CS_REPORTER_SEVERITY_ERROR, "ERROR: GetBehaviourName: '%s' unknown", entity_name); return 0; } void ocEntityHandler::DestroyEntity(iCelEntity* entity) { OCTRACE("ocEntityHandler::DestroyEntity"); /* OCLOG(ocLogger::WARNING, "ocEntityHandler::DestroyEntity", "id %d, name %s", entity->GetID(), entity->GetName()); */ clientsys->GetEntityRegistry()->Unregister(entity->GetID()); pl->RemoveEntity(entity); /* OCLOG(ocLogger::WARNING, "ocEntityHandler::DestroyEntity", "Reference count: %d", entity->GetRefCount()); */ } void ocEntityHandler::RegisterEntity(iCelEntity* entity) { OCTRACE("ocEntityHandler::RegisterEntity"); clientsys->Report(CS_REPORTER_SEVERITY_WARNING, "Info: RegisterEntity: id %d, name %s", entity->GetID(), entity->GetName()); clientsys->GetEntityRegistry()->Register(entity->GetID(), entity); } bool ocEntityHandler::CreateMainPlayer(iCelEntity* entity, ocEntityCreateMsg* msg) { OCTRACE("ocEntityHandler::CreateMainPlayer"); CS_ASSERT(entity); if (!pl->CreatePropertyClass(entity, "pcmesh")) return false; if (!pl->CreatePropertyClass(entity, "pclinearmovement")) return false; if (!pl->CreatePropertyClass(entity, "pcinventory")) return false; if (!pl->CreatePropertyClass(entity, "pccommandinput")) return false; if (!pl->CreatePropertyClass(entity, "pcdefaultcamera")) return false; if (!pl->CreatePropertyClass(entity, "pctooltip")) return false; if (!pl->CreatePropertyClass(entity, "pcmeshselect")) return false; if (!pl->CreatePropertyClass(entity, "pctimer")) return false; pccamera = CEL_QUERY_PROPCLASS_ENT(entity, iPcDefaultCamera); CS_ASSERT(pccamera); //pccamera->SetAutoDraw(true); csRef<iPcTimer> pctime = CEL_QUERY_PROPCLASS_ENT(entity, iPcTimer); // We use WakeUpFrame() rather than WakeUp(interval, repeat) because it // ties in well with extrapolating other player meshes, providing smooth // animation as opposed to jerky motion. pctime->WakeUpFrame(); csRef<iPcMesh> pcmesh = CEL_QUERY_PROPCLASS_ENT(entity, iPcMesh); CS_ASSERT(pcmesh); csRef<iPcLinearMovement> pclinmove = CEL_QUERY_PROPCLASS_ENT(entity, iPcLinearMovement); CS_ASSERT(pclinmove); csRef<iPcCommandInput> pcinp = CEL_QUERY_PROPCLASS_ENT(entity, iPcCommandInput); CS_ASSERT(pcinp); if (pcinp!= 0) { // Bind the keys here pcinp->Bind ("up", "forward"); pcinp->Bind ("down", "backward"); pcinp->Bind ("shift", "run"); pcinp->Bind ("r", "autorun"); pcinp->Bind ("space", "jump"); pcinp->Bind ("left", "rot_left"); pcinp->Bind ("right", "rot_right"); pcinp->Bind ("z", "zoomIn"); pcinp->Bind ("a", "zoomOut"); pcinp->Bind ("w", "pitchUp"); pcinp->Bind ("x", "pitchDown"); pcinp->Bind ("m", "cameraMode"); pcinp->Bind ("d", "drop"); pcinp->Bind ("h", "handle"); pcinp->Bind ("s", "showinventory"); pcinp->Bind ("h", "handle"); } csRef<iPcMeshSelect> pcmeshsel = CEL_QUERY_PROPCLASS_ENT(entity, iPcMeshSelect); CS_ASSERT(pcmeshsel); pcmeshsel->SetCamera (pccamera); pcmeshsel->SetMouseButtons (CEL_MOUSE_BUTTON1|CEL_MOUSE_BUTTON2); // tooltip to know the position /* csRef<iPcTooltip> pctooltip = CEL_QUERY_PROPCLASS_ENT(entity, iPcTooltip); CS_ASSERT(pctooltip); pctooltip->SetText(entity->GetName()); pctooltip->SetTextColor(191, 191, 191); pctooltip->SetFont(clientsys->GetMainFont()); pctooltip->SetBackgroundColor(-1, -1, -1); pctooltip->Show(400, 0); */ ///Set main player id (used for objects). clientsys->GetStateMgr()->SetPlayerID(entity->GetID()); return CreatePlayer(entity, msg); } bool ocEntityHandler::CreatePlayer(iCelEntity* entity, ocEntityCreateMsg* msg) { OCTRACE("ocEntityHandler::CreatePlayer"); CS_ASSERT(entity); if (!pl->CreatePropertyClass(entity, "pcmesh")) return false; if (!pl->CreatePropertyClass(entity, "pcactormove")) return false; if (!pl->CreatePropertyClass(entity, "pclinearmovement")) return false; if (!pl->CreatePropertyClass(entity, "pctooltip")) return false; if (!pl->CreatePropertyClass(entity, "pcmeshselect")) return false; /// \todo: make sure this is created after the main player. CS_ASSERT(pccamera); // mesh csRef<iPcMesh> pcmesh = CEL_QUERY_PROPCLASS_ENT(entity, iPcMesh); CS_ASSERT(pcmesh); bool success = clientsys->GetLoader()->LoadMesh(pcmesh, msg->mesh_factory); if (!success) { printf("ERROR: Couldn't create mesh for this new entity\n"); return false; } if (!pcmesh->GetMesh()) { printf("ERROR: Couldn't get the mesh of this new entity\n"); return false; } /* if (pczonemgr->PointMesh (pcmesh, "main", "Camera")) return false; */ // Get iPcLinearMovement so we can setup the movement system. csRef<iPcLinearMovement> pclinmove = CEL_QUERY_PROPCLASS_ENT (entity, iPcLinearMovement); CS_ASSERT(pclinmove); /* csRef<iEngine> engine = GetApplication()->GetEngine(); CS_ASSERT(engine); int sectnumb = engine->GetSectors()->GetCount(); printf("sectnumb: %d\n", sectnumb); csRef<iSector> sector = engine->FindSector("feld"); CS_ASSERT(sector); */ csRef<iSector> sector = clientsys->GetEngine()->FindSector(msg->area); CS_ASSERT(sector); pclinmove->SetPosition (msg->position, msg->yrot, sector); pclinmove->InitCD (csVector3 (0.5f,0.8f,0.5f), csVector3 (0.5f,0.4f,0.5f), csVector3 (0,0,0)); // actor movement: just dummy action to set the idle animation csRef<iPcActorMove> pcactormove = CEL_QUERY_PROPCLASS_ENT(entity, iPcActorMove); CS_ASSERT(pcactormove); pcactormove->Jump(); csRef<iPcMeshSelect> pcmeshselect = CEL_QUERY_PROPCLASS_ENT (entity, iPcMeshSelect); CS_ASSERT(pcmeshselect); pcmeshselect->SetCamera (pccamera); pcmeshselect->SetMouseButtons (CEL_MOUSE_BUTTON1|CEL_MOUSE_BUTTON2); return true; } bool ocEntityHandler::CreateMovableObject(iCelEntity* entity, ocEntityCreateMsg* msg) { OCTRACE("ocEntityHandler::CreateMovableObject"); CS_ASSERT(entity); if (!pl->CreatePropertyClass(entity, "pcmesh")) return false; if (!pl->CreatePropertyClass(entity, "pclinearmovement")) return false; if (!pl->CreatePropertyClass(entity, "pcproperties")) return false; if (!pl->CreatePropertyClass(entity, "pcmeshselect")) return false; // mesh csRef<iPcMesh> pcmesh = CEL_QUERY_PROPCLASS_ENT(entity, iPcMesh); CS_ASSERT(pcmesh); bool success = clientsys->GetLoader()->LoadMesh(pcmesh, msg->mesh_factory); if (!success) return false; if (!pcmesh->GetMesh ()) return false; printf(" - Mesh OK\n"); // linear movement csRef<iPcLinearMovement> pclinmove = CEL_QUERY_PROPCLASS_ENT (entity, iPcLinearMovement); CS_ASSERT(pclinmove); csRef<iSector> sector = clientsys->GetEngine()->FindSector(msg->area); CS_ASSERT(sector); pclinmove->SetPosition (msg->position, msg->yrot, sector); pclinmove->InitCD (csVector3 (1.0, 1.0, 1.0), csVector3 (1.0, 1.0, 1.0), csVector3 (0, 0, 0)); CS_ASSERT(pccamera); // add properties csRef<iPcProperties> pcprop = CEL_QUERY_PROPCLASS_ENT(entity, iPcProperties); CS_ASSERT(pcprop); pcprop->SetProperty("type", msg->mesh_factory.GetData()); // mesh selection csRef<iPcMeshSelect> pcmeshselect = CEL_QUERY_PROPCLASS_ENT (entity, iPcMeshSelect); CS_ASSERT(pcmeshselect); pcmeshselect->SetCamera (pccamera); pcmeshselect->SetMouseButtons (CEL_MOUSE_BUTTON1|CEL_MOUSE_BUTTON2); return true; } bool ocEntityHandler::CreateStaticObject(iCelEntity* entity, ocEntityCreateMsg* msg) { OCTRACE("ocEntityHandler::CreateStaticObject"); CS_ASSERT(entity); if (!pl->CreatePropertyClass(entity, "pcmesh")) return false; if (!pl->CreatePropertyClass(entity, "pcsolid")) return false; if (!pl->CreatePropertyClass(entity, "pcproperties")) return false; if (!pl->CreatePropertyClass(entity, "pcmeshselect")) return false; // mesh csRef<iPcMesh> pcmesh = CEL_QUERY_PROPCLASS_ENT(entity, iPcMesh); CS_ASSERT(pcmesh); bool success = clientsys->GetLoader()->LoadMesh(pcmesh, msg->mesh_factory); if (!success) return false; if (!pcmesh->GetMesh ()) return false; // linear movement csRef<iPcLinearMovement> pclinmove = CEL_QUERY_PROPCLASS_ENT (entity, iPcLinearMovement); CS_ASSERT(pclinmove); CS_ASSERT(pccamera); // add properties csRef<iPcProperties> pcprop = CEL_QUERY_PROPCLASS_ENT(entity, iPcProperties); CS_ASSERT(pcprop); pcprop->SetProperty("type", msg->mesh_factory.GetData()); // mesh selection csRef<iPcMeshSelect> pcmeshselect = CEL_QUERY_PROPCLASS_ENT (entity, iPcMeshSelect); CS_ASSERT(pcmeshselect); pcmeshselect->SetCamera (pccamera); pcmeshselect->SetMouseButtons (CEL_MOUSE_BUTTON1|CEL_MOUSE_BUTTON2); return true; } bool ocEntityHandler::CreateSector(iCelEntity* entity, ocEntityCreateMsg* msg) { OCTRACE("ocEntityHandler::CreateSector"); CS_ASSERT(entity); if (!pl->CreatePropertyClass(entity, "pcregion")) return false; // zonemanager /* csRef<iPcZoneManager> zonemgr = CEL_QUERY_PROPCLASS_ENT (entity, iPcZoneManager); iCelZone* zone = zonemgr->CreateZone ("mainzone"); iCelRegion* region = zonemgr->CreateRegion ("mainreg"); // initialsector = zone->FindRegion("feld"); zone->LinkRegion (region); iCelMapFile* mapfile = region->CreateMapFile (); mapfile->SetPath ("/once/content/maps/feld/"); mapfile->SetFile ("world"); return true; */ csRef<iPcRegion> pcregion = CEL_QUERY_PROPCLASS_ENT(entity, iPcRegion); CS_ASSERT (pcregion); /* bool success = clientsys->GetLoader()->LoadRegion(pcregion); if (!success) return false; */ pcregion->SetWorldFile("/once/content/maps/feld/", "world"); pcregion->SetRegionName("feld"); pcregion->Load(); iSector* existsector = pcregion->FindSector("feld"); CS_ASSERT(existsector); /* csRef<iEngine> engine = GetApplication()->GetEngine(); iRegion* region = engine->GetRegions()->FindByName(mesh_factory); iSector* sector = engine->FindSector(mesh_factory, region); if (!sector) { printf("Error: loading map: world doesn't contain the required sector\n"); pcregion->Unload(); return false; } */ return true; } bool ocEntityHandler::ReadEntityCreate(ocEntityCreateMsg* msg) { OCTRACE("ocEntityHandler::ReadEntityCreate"); clientsys->Report(CS_REPORTER_SEVERITY_WARNING, " - id: '%d', name: '%s', type: '%s', mesh: '%s', position & rot: %f %f %f %f", msg->entity_id, msg->entity_name.GetData(), msg->entity_type.GetData(), msg->mesh_factory.GetData(), msg->position.x, msg->position.y, msg->position.z, msg->yrot); // creating the entity and setting basic data iCelEntity* entity = csRef<iCelEntity>(pl->GetEntity(msg->entity_id)); if (entity) { printf(" ! entity already exists (name: %s, trying to create: %s)\n", entity->GetName(), msg->entity_name.GetData()); return false; } entity = csRef<iCelEntity>(pl->CreateEntity(msg->entity_id)); CS_ASSERT(entity); entity->SetName(msg->entity_name); RegisterEntity(entity); // creating behaviour depending on the entity type if (msg->entity_type.Compare("MainPlayer")) { iCelBehaviour* behave = bl->CreateBehaviour(entity, "ocMainPlayerBehaviour"); if (behave) { clientsys->SetMainPlayerBehaviour(behave); entity->SetBehaviour(behave); return CreateMainPlayer(entity, msg); } else return false; } else if (msg->entity_type.Compare("Player")) { iCelBehaviour* behave = bl->CreateBehaviour(entity, "ocPlayerBehaviour"); if (behave) { entity->SetBehaviour(behave); return CreatePlayer(entity, msg); } else { printf(" - Failed setting player behaviour\n"); return false; } } else if (msg->entity_type.Compare("Area")) { iCelBehaviour* behave = bl->CreateBehaviour(entity, "ocAreaBehaviour"); if (behave) { entity->SetBehaviour(behave); return CreateSector(entity, msg); } else return false; } else if (msg->entity_type.Compare("Object")) { iCelBehaviour* behave = bl->CreateBehaviour(entity, "ocObjectBehaviour"); if (behave) { entity->SetBehaviour(behave); return CreateMovableObject(entity, msg); } else return false; } else if (msg->entity_type.Compare("StaticObject")) { iCelBehaviour* behave = bl->CreateBehaviour(entity, "ocStaticObjectBehaviour"); if (behave) { entity->SetBehaviour(behave); return CreateStaticObject(entity, msg); } else return false; } else return false; return true; } bool ocEntityHandler::ReadEntityChange(ocEntityChangeMsg* msg) { OCTRACE("ocEntityHandler::ReadEntityChange"); // checking autenticity csRef<iCelEntity> entity = clientsys->GetEntityRegistry()->Get(msg->entity_id); if (!entity) { clientsys->Report(CS_REPORTER_SEVERITY_ERROR, "ERROR: Received entity change notification but entity " "unknown! (id: %d)", msg->entity_id); return false; } csRef<iPcLinearMovement> pclinmove = CEL_QUERY_PROPCLASS_ENT(entity, iPcLinearMovement); csRef<iPcActorMove> pcactormove = CEL_QUERY_PROPCLASS_ENT(entity, iPcActorMove); csRef<iSector> sector = clientsys->GetEngine()->FindSector(msg->area.GetData()); if (!(pclinmove && pcactormove && sector)) { printf("ERROR: Received entity change notification but " "couldn't get properties of entity (id: %d)", msg->entity_id); return false; } // position + linear movement csVector3 world_vel_dummy = csVector3(0.0f, 0.0f, 0.0f); pclinmove->SetSoftDRData(msg->on_ground, msg->speed, msg->position, msg->yrot, sector, msg->velocity, world_vel_dummy, msg->yrot_vel); // action if (msg->mov_fwd) { pcactormove->Forward(true); pcactormove->Backward(false); } else if (msg->mov_bwd) { pcactormove->Forward(false); pcactormove->Backward(true); } else { pcactormove->Backward(false); pcactormove->Forward(false); } pcactormove->Run(msg->run); if (msg->jump) pcactormove->Jump(); if (msg->rot_left) { pcactormove->RotateLeft(true); pcactormove->RotateRight(false); } else if (msg->rot_right) { pcactormove->RotateLeft(false); pcactormove->RotateRight(true); } else { pcactormove->RotateLeft(false); pcactormove->RotateRight(false); } return true; } bool ocEntityHandler::ReadEntityDestroy(ocEntityDestroyMsg* msg) { OCTRACE("ocEntityHandler::ReadEntityDestroy"); clientsys->Report(CS_REPORTER_SEVERITY_WARNING, " - ReadEntityDestroy: id='%d', name='%s'\n", msg->entity_id, msg->entity_name.GetData()); csRef<iCelEntity> entity = clientsys->GetEntityRegistry()->Get(msg->entity_id); if (!entity) { clientsys->Report(CS_REPORTER_SEVERITY_ERROR, "ERROR: Received entity deletion notification but entity " "unknown! (id: %d)", msg->entity_id); return false; } DestroyEntity(entity); /// \todo mafm: quick, dirty fix to remove the entities of other /// players; should be fixed finding the "offending" function adding /// references without freeing them clientsys->Report(CS_REPORTER_SEVERITY_ERROR, " refcount =%d", entity->GetRefCount()); int i; for (i = 0; entity->GetRefCount() > 1; i++) entity->DecRef(); clientsys->Report(CS_REPORTER_SEVERITY_ERROR, " refcount decreased i=%d", i); return true; } |