CEntity* CEntityFactory::createEntityByType(const std::string &type, Vector3 position, CMap *map) { //solo hacemos creamos algo a partir de un arquetipo así que nos aseguramos de que exista ArchetypeMap::iterator find = _archetypes.find(type); if( find == _archetypes.end()) { return NULL; } //nos aseguramos de construir un nombre unico //int id = EntityID::_nextId; std::string uniqueName = type; //Hacer un new para que no se desreferencie en el futuro Map::CEntity *entityInfo = new Map::CEntity(uniqueName); entityInfo->setType(type); std::string pos = std::to_string(position.x)+','+std::to_string(position.y)+','+std::to_string(position.z); entityInfo->setAttribute("position", pos ); entityInfo->setName(entityInfo->getName()+std::to_string(EntityID::_nextId)); //meterlo en la cola de entidades del parser para que se borren al recargar mapas Map::CMapParser::getSingletonPtr()->addEntityInfo(entityInfo); return createEntity(entityInfo, map); }
void CGridMap::FillTileData( CMap * _map, Map::CMapParser::TTileMatrix tileMatrix ) { for (int row = 0; row < _nMapRows; ++row) for (int col = 0; col < _nMapCols; ++col) { CTerrainTile* t_tile = new CTerrainTile(tileMatrix[row][col]->getType()); t_tile->FillData(tileMatrix[row][col]); getTileFromCoord(row, col)->SetTerrain(t_tile); if (t_tile->isObstacle()) { //@TODO: spawn Obstacle entity on this position. Vector2 pos = getRelativeMapPos(row, col); std::stringstream vecPos, name; // Creamos una nueva entidad con su entidad trigger sacada de los arquetipos Map::CEntity * obstacleInfo = Map::CMapParser::getSingletonPtr()->getEntityInfo("Obstacle"); name << "Obstacle_" << row << "_" << col; vecPos << pos.x << " 0 " << pos.y; // Le ponemos un nuevo nombre para poder hacer spawn y la posición del edificio fantasma obstacleInfo->setName(name.str()); obstacleInfo->setAttribute("position", vecPos.str()); Logic::CEntityFactory::getSingletonPtr()->createEntity(obstacleInfo, _map); } } }
bool IWeaponFeedback::spawn(CEntity *entity, CMap *map, const Map::CEntity *entityInfo) { if( !IComponent::spawn(entity,map,entityInfo) ) return false; Map::CEntity *tempEntity = CEntityFactory::getSingletonPtr()->getInfo(_weaponName); _weaponSound = tempEntity->getStringAttribute("Audio"); /* if(tempEntity->hasAttribute("PrimaryFireParticle")) _primaryFireParticle = tempEntity->getStringAttribute("PrimaryFireParticle"); else _primaryFireParticle = "fogonazo"; if(tempEntity->hasAttribute("SecondaryFireParticle")) _secondaryFireParticle = tempEntity->getStringAttribute("SecondaryFireParticle"); else _secondaryFireParticle = "fogonazo"; */ if(tempEntity->hasAttribute("ParticlePosition")) _particlePosition = tempEntity->getVector3Attribute("ParticlePosition"); else _particlePosition = Vector3(0, 0, 0); _hudWeapon = _entity->getComponent<CHudWeapons>("CHudWeapons"); assert(_hudWeapon != NULL && "Error: El cliente necesita tener un componente de grafico del arma"); assert( entityInfo->hasAttribute("heightShoot") ); _heightShoot = entityInfo->getFloatAttribute("heightShoot"); return true; }
bool ISpell::spawn(CEntity *entity, CMap *map, const Map::CEntity *entityInfo) { if( !IComponent::spawn(entity,map,entityInfo) ) return false; Map::CEntity *tempEntity = CEntityFactory::getSingletonPtr()->getInfo(_spellName); // Comprobamos que los atributos obligatorios existen assert( tempEntity->hasAttribute("ID") && "Debe tener id, mirar archivo spellType"); // Leemos los atributos obligatorios de arma _spellID = (SpellType::Enum)tempEntity->getIntAttribute("ID"); _duration = tempEntity->getFloatAttribute("Duration")*1000; return true; } // spawn+
void CScreamer::secondarySkill() { _secondarySkillIsActive = true; Map::CEntity* screamerShieldInfo = CEntityFactory::getSingletonPtr()->getInfo("ScreamerShield"); float screamerShieldRadius = screamerShieldInfo->getFloatAttribute("physic_radius"); // Creamos una entidad ScreamerShield // Obtenemos la informacion asociada al arquetipo del escudo del screamer Vector3 shootPosition = _entity->getPosition() + ( (_entity->getOrientation() * Vector3::NEGATIVE_UNIT_Z ) * (_capsuleRadius + screamerShieldRadius) ); shootPosition.y += _heightShoot; // Creamos la entidad y la activamos _screamerShield = CEntityFactory::getSingletonPtr()->createEntity( screamerShieldInfo, Logic::CServer::getSingletonPtr()->getMap(), shootPosition, _entity->getOrientation() ); // Activamos la entidad creada _screamerShield->activate(); _screamerShield->start(); // Enviamos el mensaje SET_OWNER para que el escudo se mueva // acorde a los movimientos del player shared_ptr<CMessageSetOwner> setOwnerMsg = make_shared<CMessageSetOwner>(); setOwnerMsg->setOwner(_entity); _screamerShield->emitMessage(setOwnerMsg); // Sonido del escudo std::shared_ptr<CMessageAudio> audioMsg = std::make_shared<CMessageAudio>(); audioMsg->setAudioName("character/screamerShield.wav"); audioMsg->isLoopable(true); audioMsg->is3dSound(true); _screamerShield->emitMessage(audioMsg); // Enviamos un mensaje para indicar que se bloquee el disparo shared_ptr<CMessageBlockShoot> canShootMsg = make_shared<CMessageBlockShoot>(); canShootMsg->canShoot(false); _entity->emitMessage(canShootMsg); // Mandamos al jugador que tiene la habilidad disponible std::shared_ptr<CMessageHud> hudMsg = std::make_shared<CMessageHud>(); hudMsg->setType(CMessageHud::HudType::SECONDARY_ACTIVE); _entity->emitMessage(hudMsg); } // secondarySkill
bool CSoulReaperAmmo::spawn(CEntity* entity, CMap *map, const Map::CEntity *entityInfo) { Map::CEntity* weapon = CEntityFactory::getSingletonPtr()->getInfo(_weaponName); if( !IWeaponAmmo::spawn(entity, map, weapon) ) return false; // Nos aseguramos de tener todos los atributos que necesitamos assert( weapon->hasAttribute("PrimaryFireCooldown") ); // Cooldown del disparo principal _defaultPrimaryFireCooldown = _primaryFireCooldown = weapon->getFloatAttribute("PrimaryFireCooldown") * 1000; _friend[_friends] = _entity->getComponent<Logic::CSoulReaper>("CSoulReaper"); if(_friend[_friends]) ++_friends; _friend[_friends] = _entity->getComponent<Logic::CSoulReaperFeedback>("CSoulReaperFeedback"); if(_friend[_friends]) ++_friends; if(_friends == 0) assert("\nTiene que tenes alguno de los dos componentes"); return true; }
void CGridMap::ShowDebugTiles( CMap * _map ) { for (int i = 0; i < _nMapRows; ++i) { for (int j = 0; j < _nMapCols; ++j) { //Vector2 tilePos = getRelativeMapPos(i, j); std::stringstream vecPos, name; // Creamos una nueva entidad con su entidad trigger sacada de los arquetipos Map::CEntity * waypointInfo = Map::CMapParser::getSingletonPtr()->getEntityInfo("Waypoint"); name << "Tile_" << i << "_" << j; vecPos << i << " " << j; // Le ponemos un nuevo nombre para poder hacer spawn y la posición del edificio fantasma waypointInfo->setName(name.str()); waypointInfo->setAttribute("grid_position", vecPos.str()); Logic::CEntityFactory::getSingletonPtr()->createEntity(waypointInfo, _map); } } }
void CScreamer::createExplotion() { Map::CEntity* screamerInfo = CEntityFactory::getSingletonPtr()->getInfo("Screamer"); float height = screamerInfo->getFloatAttribute("heightShoot"); // EntitiesHit sera el buffer que contendra la lista de entidades que ha colisionado // con el overlap vector<CEntity*> entitiesHit; // Hacemos una query de overlap con la geometria de una esfera en la posicion // en la que se encuentra la granada con el radio que se indique de explosion Physics::SphereGeometry explotionGeom = Physics::CGeometryFactory::getSingletonPtr()->createSphere(_screamerExplotionRadius); Vector3 explotionPos = _entity->getPosition(); explotionPos.y += height; Physics::CServer::getSingletonPtr()->overlapMultiple(explotionGeom, explotionPos, entitiesHit); int nbHits = entitiesHit.size(); // Mandamos el mensaje de daño a cada una de las entidades que hayamos golpeado // Además aplicamos un desplazamiento al jugador for(int i = 0; i < nbHits; ++i) { // Si la entidad golpeada es valida y es un player if( entitiesHit[i] != NULL && entitiesHit[i]->isPlayer() ) { // Emitimos el mensaje de instakill // @todo mandar un mensaje de instakill en vez de un mensaje de daño shared_ptr<CMessageDamaged> dmgMsg = make_shared<CMessageDamaged>(); dmgMsg->setDamage(_screamerExplotionDamage); dmgMsg->setEnemy(_entity); entitiesHit[i]->emitMessage(dmgMsg); } } // Creamos las particulas de la explosion Map::CEntity* entityInfo = CEntityFactory::getSingletonPtr()->getInfo("ScreamerExplotion"); CEntity* explotion = CEntityFactory::getSingletonPtr()->createEntity(entityInfo, _entity->getMap(), explotionPos, Quaternion::IDENTITY ); explotion->activate(); explotion->start(); } // createExplotion
void AddMapEntity(const Map::CEntity &entity) { #ifdef _DEBUG assert(entity.getType().compare("") && "No se ha establecido tipo a la entidad"); std::list<Map::CEntity*> entityList = Map::CMapParser::getSingletonPtr()->getEntityList(); std::list<Map::CEntity*>::const_iterator it = entityList.begin(); if(!entityList.empty()) { for(; it != entityList.end(); ++it) { assert((*it)->getName().compare(entity.getName()) && "Ya existe una entidad con este nombre."); } } #endif // _DEBUG // La que recibimos ES DE LUA Map::CEntity *newEntity = new Map::CEntity(entity.getName()); *newEntity = entity; Map::CMapParser::getSingletonPtr()->addEntityInfo(newEntity); }
bool CCoolDownServer::spawn(CEntity* entity, CMap *map, const Map::CEntity *entityInfo) { if(!ISpell::spawn(entity,map,entityInfo)) return false; Map::CEntity *tempEntity = CEntityFactory::getSingletonPtr()->getInfo(_spellName); // Nos aseguramos de tener todos los atributos que necesitamos assert( tempEntity->hasAttribute("PercentageCooldown") ); _percentage = tempEntity->getFloatAttribute("PercentageCooldown"); _weaponryAmmo.resize(WeaponType::eSIZE); // Rellenamos el vector con los punteros a los componentes correspondientes _weaponryAmmo[WeaponType::eSOUL_REAPER] = _entity->getComponent<Logic::CSoulReaperAmmo>("CSoulReaperAmmo"); _weaponryAmmo[WeaponType::eSNIPER]= _entity->getComponent<Logic::CSniperAmmo>("CSniperAmmo"); _weaponryAmmo[WeaponType::eSHOTGUN]= _entity->getComponent<Logic::CShotGunAmmo>("CShotGunAmmo"); _weaponryAmmo[WeaponType::eMINIGUN]= _entity->getComponent<Logic::CMiniGunAmmo>("CMiniGunAmmo"); _weaponryAmmo[WeaponType::eIRON_HELL_GOAT]= _entity->getComponent<Logic::CIronHellGoatAmmo>("CIronHellGoatAmmo"); _weaponryShoot.push_back( _entity->getComponent<Logic::CIronHellGoat>("CIronHellGoat")); _weaponryShoot.push_back( _entity->getComponent<Logic::CMiniGun>("CMiniGun")); return true; } // spawn
CEntity* CEntityFactory::createEntityByTypeTransform(const std::string &type, Matrix4 transform, CMap *map) { //solo hacemos creamos algo a partir de un arquetipo así que nos aseguramos de que exista ArchetypeMap::iterator find = _archetypes.find(type); if( find == _archetypes.end()) { return NULL; } //nos aseguramos de construir un nombre unico //int id = EntityID::_nextId; std::string uniqueName = type; //Hacer un new para que no se desreferencie en el futuro Map::CEntity *entityInfo = new Map::CEntity(uniqueName); //El tipo entityInfo->setType(type); //La posicion Vector3 pos; Vector3 scale; Quaternion quat; transform.decomposition(pos, scale, quat); std::string string = std::to_string(pos.x)+','+std::to_string(pos.y)+','+std::to_string(pos.z); entityInfo->setAttribute("position", string ); //El nombre unico entityInfo->setName(entityInfo->getName()+std::to_string(EntityID::_nextId)); //La orientacion Vector3 axis; Ogre::Degree angle; quat.ToAngleAxis(angle, axis); string = std::to_string(axis.x) +","+std::to_string(axis.y)+","+std::to_string(axis.z); entityInfo->setAttribute("orientation",string); //std::cout<<string<<std::endl; string = std::to_string(angle.valueDegrees()); //std::cout<<string<<std::endl; entityInfo->setAttribute("orientation_angle", string); //meterlo en la cola de entidades del parser para que se borren al recargar mapas Map::CMapParser::getSingletonPtr()->addEntityInfo(entityInfo); return createEntity(entityInfo, map); }
bool CHudWeapons::spawn(CEntity *entity, CMap *map, const Map::CEntity *entityInfo) { if(!IComponent::spawn(entity,map,entityInfo)) return false; _scene = _entity->getMap()->getScene(); _graphicsEntities = new TGraphicsWeapon[WeaponType::eSIZE]; // Por ahora leo a mano cada una de las armas que tiene el usuario for(int i = WeaponType::eSOUL_REAPER; i < WeaponType::eSIZE; ++i){ WeaponType::Enum current = (WeaponType::Enum)i; std::string strWeapon = WeaponType::toString(current); Map::CEntity* weapon = CEntityFactory::getSingletonPtr()->getInfo(strWeapon); //_graphicsEntities[i]._graphicsEntity = createGraphicsEntity(weapon, entityInfo->getStringAttribute(weapon+"Model")); _graphicsEntities[current].defaultYaw = _graphicsEntities[current].defaultPitch = _graphicsEntities[current].defaultRoll = 0; if(weapon->hasAttribute("ModelYaw")) _graphicsEntities[current].defaultYaw = weapon->getFloatAttribute("ModelYaw"); if(weapon->hasAttribute("ModelPitch")) _graphicsEntities[current].defaultPitch = weapon->getFloatAttribute("ModelPitch"); if(weapon->hasAttribute("ModelRoll")) _graphicsEntities[current].defaultRoll = weapon->getFloatAttribute("ModelRoll"); //Esto puede petar si no esta, pero creo q es obligatorio if(!weapon->hasAttribute("Offset")) assert("seguro que no tiene offset?"); _graphicsEntities[current].offset = weapon->getVector3Attribute("Offset"); /* // Ahora voy a crear los overlays por cada arma en 3D Graphics::CServer *server = Graphics::CServer::getSingletonPtr(); _overlayWeapon3D[current] = server->createOverlay( "_overlay3D"+strWeapon, _scene ); std::string modelWeapon = weapon->getStringAttribute("Model"); _graphicsEntities[current].graphicsEntity = _overlayWeapon3D[current]->add3D(strWeapon, modelWeapon,_graphicsEntities[current].offset); assert(_graphicsEntities[current].graphicsEntity != 0 && "error al cargar la entidad grafica"); //_weaponsEntities[current] = _overlayWeapon3D[current]->add3D(currentOnText, modelWeapon, &offsetPositionWeapon); _graphicsEntities[current].graphicsEntity->setOrientation(Math::setQuaternion(_graphicsEntities[current].defaultYaw, _graphicsEntities[current].defaultPitch, _graphicsEntities[current].defaultRoll)); _overlayWeapon3D[current]->setVisible(false); _overlayWeapon3D[current]->setZBuffer(15); /*/ std::string modelWeapon = weapon->getStringAttribute("Model"); _graphicsEntities[current].graphicsEntity = _scene->getCamera()->addEntityChild(strWeapon, modelWeapon, _graphicsEntities[current].offset); // Este render queue se usa para simular los overlays. Poner en esta cola solo lo que queramos // que se renderice como un overlay!! _graphicsEntities[current].graphicsEntity->setRenderQueue(95); // Esta mascara se utiliza para excluir el elemento del efecto de motion blur _graphicsEntities[current].graphicsEntity->setVisibilityMask(1 << 0); _graphicsEntities[current].graphicsEntity->setOrientation(Math::setQuaternion(_graphicsEntities[current].defaultYaw, _graphicsEntities[current].defaultPitch, _graphicsEntities[current].defaultRoll)); _graphicsEntities[current].graphicsEntity->setVisible(false); /* */ } //_overlayWeapon3D[WeaponType::eSOUL_REAPER]->setVisible(true); _graphicsEntities[WeaponType::eSOUL_REAPER].graphicsEntity->setVisible(true); if(!_graphicsEntities) return false; // Usamos un pequeño truco para calcular a la velocidad a la que tiene que incrementar // el ruido de carga // Primero obtenemos el tiempo máximo de carga del Iron Hell Goat Map::CEntity* info = CEntityFactory::getSingletonPtr()->getInfo("ironHellGoat"); assert( info->hasAttribute("PrimaryFireLoadTime") ); // Una vez conocido el tiempo de carga, como sabemos que vamos a utilizar fixed ticks // de 16 msecs, calculamos cuantos ticks van a pasar (aproximadamente) hasta que se // tiene el arma cargada. unsigned int nbTicks = (info->getIntAttribute("PrimaryFireLoadTime") * 1000) / 16; // Calculamos el incremento de la velocidad distribuyendola uniformemente entre los // ticks de carga _unstableLoadAnim.speedInc = (_unstableLoadAnim.maxVerticalSpeed - _unstableLoadAnim.initVerticalSpeed) / (float)nbTicks; _unstableLoadAnim.noiseInc = (_unstableLoadAnim.maxNoiseSpeed - _unstableLoadAnim.initNoiseSpeed) / (float)nbTicks; return true; } // spawn