int CPhysicsServer::GetEntitiesInShape(PShape Shape, const CFilterSet& ExcludeSet, nArray<PEntity>& Result) { n_assert(CurrLevel); Shape->Attach(CurrLevel->GetODEDynamicSpaceID()); Contacts.Reset(); Shape->Collide(ExcludeSet, Contacts); Shape->Detach(); int OldResultSize = Result.Size(); //???stamp? uint Stamp = GetUniqueStamp(); for (int i = 0; i < Contacts.Size(); i++) { CEntity* pEnt = Contacts[i].GetEntity(); if (pEnt && pEnt->GetStamp() != Stamp) { pEnt->SetStamp(Stamp); Result.Append(pEnt); } } return Result.Size() - OldResultSize; }
void IdEntities::saveIdEntity(CHandle entity, int entity_id) { if (entity_id >= 0) { identified_entities[entity_id] = entity; CEntity* e = entity; e->setId(entity_id); } }
void test_member_archive() { CEntityQueue entity_queue; CEntity &entity = entity_queue.get_head(); entity.mod_hp(100); entity.mod_mp(50); CEntity &entity2 = entity_queue.get_end(); entity2.mod_hp(1000); entity2.mod_mp(30); CEntity *pentity = entity_queue.get_middle(); if (pentity) { pentity->mod_hp(3576); pentity->mod_mp(876); } std::cout << "head hp is " << entity_queue.get_head().get_hp() << "head mp is " << entity_queue.get_head().get_mp() << std::endl; std::cout << "head hp is " << entity_queue.get_end().get_hp() << "head mp is " << entity_queue.get_end().get_mp() << std::endl; std::cout << "head hp is " << entity_queue.get_middle()->get_hp() << "head mp is " << entity_queue.get_middle()->get_mp() << std::endl; std::stringstream ss; boost::archive::binary_oarchive oa(ss); oa << entity_queue; CEntityQueue entity_queue2; boost::archive::binary_iarchive ia(ss); ia >> entity_queue2; std::cout << "head hp is " << entity_queue2.get_head().get_hp() << "head mp is " << entity_queue2.get_head().get_mp() << std::endl; std::cout << "head hp is " << entity_queue2.get_end().get_hp() << "head mp is " << entity_queue2.get_end().get_mp() << std::endl; std::cout << "head hp is " << entity_queue.get_middle()->get_hp() << "head mp is " << entity_queue.get_middle()->get_mp() << std::endl; }
int moveTo(lua_State *l) { LUA_BRIDGE_START; LOGV("Lua call: textMessage"); if (lua_gettop(l) < 2) { LOGW("Less argument count for moveTo call"); return -1; } const std::string id(lua_tostring(l, 1)); const Ogre::Vector3 position(Ogre::StringConverter::parseVector3(lua_tostring(l, 2))); CEntity *pEntity = CGameStateManager::getSingleton().getChildRecursive(id); if (!pEntity) { LOGW("Entity '%s' was not found in entity tree.", id.c_str()); return 0; } luaHelper::CMoveToWait waiter(pEntity); pEntity->moveToTarget(position); while (true) { LUA_WAIT(50); if (waiter.hasReached()) { break; } } return 0; // 0 return values }
int CEntitiesDialog::EditEntity( CEntityArray& Entities, int CurrentEntity, CFusionDoc* Doc) { // If more than one entity selected, make sure they're all the same type. int nSel = 0; CString EntityClassname; int i; pDoc = Doc; mEntityArray = &Entities; for (i = 0; i < mEntityArray->GetSize(); ++i) { CEntity *pEnt; pEnt = &Entities[i]; if (pEnt->IsSelected ()) { if (nSel == 0) { EntityClassname = pEnt->GetClassname (); mCurrentEntity = i; } else { if (pEnt->GetClassname () != EntityClassname) { AfxMessageBox ("To edit multiple entities, they must all be of the same type."); return CurrentEntity; } } ++nSel; } } MultiEntityFlag = (nSel > 1); if (MultiEntityFlag) { } else { if (CurrentEntity != -1) { mCurrentEntity = CurrentEntity; } else { // Let's set entity 0 as selected if it exists... mCurrentEntity = 0; if (mEntityArray->GetSize() > 0) { pDoc->ResetAllSelectedEntities(); pDoc->SelectEntity (&(*mEntityArray)[mCurrentEntity]); pDoc->mCurrentEntity = mCurrentEntity; } } } DoModal(); return mCurrentEntity; }
void CGrenadeControllerClient::process(const std::shared_ptr<CMessage>& message) { if(!_explotionActive) { switch( message->getMessageType() ) { case Message::CONTACT_ENTER: { std::shared_ptr<CMessageContactEnter> contactMsg = std::static_pointer_cast<CMessageContactEnter>(message); Logic::TEntityID idPlayerHit = contactMsg->getEntity(); CEntity * playerHit = CServer::getSingletonPtr()->getMap()->getEntityByID(idPlayerHit); _explotionActive=true; // Si es el escudo del screamer mandar directamente esos daños a la // entidad contra la que hemos golpeado (el escudo), sino, crear explosion if(playerHit->getType() == "ScreamerShield") { // Crear efecto y sonido de absorcion // Eliminamos la entidad en diferido CEntityFactory::getSingletonPtr()->deferredDeleteEntity(_entity,false); } else { // Eliminamos la entidad en diferido CEntityFactory::getSingletonPtr()->deferredDeleteEntity(_entity,false); // Creamos la explosion createExplotion(); } break; } case Message::CONTACT_EXIT: { std::cout << "CONTACT EXIT DE LA GRANADA, no deberia entrar nunca" << std::endl; } } } } // process
CTimer* sq_totimer(SQVM* pVM, int idx) { CEntity* pEntity = sq_toentity(pVM, idx); if( pEntity && pEntity->GetType() == ENTITY_TYPE_TIMER ) return dynamic_cast< CTimer* >( pEntity ); return NULL; }
int CEntityNatives::Create(SQVM* pVM) { CResource* pResource = g_pResourceManager->Get(pVM); assert( pResource ); const char* szName; sq_getstring(pVM,2,&szName); if(CEntity::GetType(szName) == ENTITY_TYPE_CUSTOM) { CEntity* pEntity = new CEntity(ENTITY_TYPE_CUSTOM, pResource, szName); if(pEntity->GetID() != INVALID_ENTITY_ID_LONG) { sq_pushentity(pVM,pEntity); } else { delete pEntity; sq_pushnull(pVM); } } else sq_pushnull(pVM); return 1; }
void CIARunAway::process(const std::shared_ptr<Logic::IMessage> &message) { if (message->getType() == "CHANGE_TARGET") { CEntity* ent = dynamic_cast<CHANGE_TARGET*>(message.get())->getLogicEntity(); if(ent != NULL) { if(!ent->getIsDead()) { _target = ent; if (_target->getCenterPosition().x > _entity->getCenterPosition().x) { _direction = -1; } else { _direction = 1; } std::shared_ptr<Logic::TURN> m(new Logic::TURN()); m->setInt(_direction); _entity->emitMessage(m); } } } } // process
void CLifeModifier::process(CMessage *message) { CMessageUInt* rxMsg = static_cast<CMessageUInt*>(message); CEntity* entity = _entity->getMap()->getEntityByID( rxMsg->getUInt() ); CMessageUInt *txMsg = new CMessageUInt(); //LifeModifier manda un mensaje al componente LIFE.cpp // mensaje TIPO LIFE_MODIFIER. Action = DAMAGE, HEAL txMsg->setType(Message::LIFE_MODIFIER); //PT. se carga en el entero el modificador de vida (negativo o positivo) //txMsg->setUInt( abs(_LIFE_MODIFIER) ); txMsg->setUInt(_LIFE_MODIFIER ); if (_LIFE_MODIFIER < 0) txMsg->setAction(Message::DAMAGE); else if(_LIFE_MODIFIER > 0) txMsg->setAction(Message::HEAL); //PT. It just worth sending message when it hurts or heals, when is 0 doesnt worthy if(_LIFE_MODIFIER != 0 && _entity!=NULL) entity->emitMessage(txMsg, this); } // process
void CEnemyMeleeAttack::process(const std::shared_ptr<Logic::IMessage> &message) { if(message->getType() == "CONTROLLER_TOUCHED") { CEntity* other = dynamic_cast<CONTROLLER_TOUCHED*>(message.get())->getEntidad(); if(other->getEntityID() == _targetID && _entity->getTag() == "enemy" && canDoDamage()) { ApplyDamage(other); } } else if (message->getType() == "CHANGE_TARGET") { // Si no encuentra la palabra "Minion" en el tipo de entidad, entonces puede canibalizar if (_entity->getType().find("Minion") == std::string::npos) { _target = dynamic_cast<CHANGE_TARGET*>(message.get())->getLogicEntity(); if (_target) _targetID = _target->getEntityID(); } } } // process
//AVO: directly set entity health instead of going throuhg normal health property which operates on delta void CScriptGameObject::SetHealthEx(float hp) { CEntity *obj = smart_cast<CEntity*>(&object()); if (!obj) return; clamp(hp, -0.01f, 1.0f); obj->SetfHealth(hp); }
void CBank::StartATM() { double time1, sim_time = executive->SimulationTime(); CDistribution dist; CEntity * client; if(atm_free){ if(!atm_queue->EhVazia()){ // Get call from queue client = (CEntity *) atm_queue->ObterInfo(); atm_queue->Remover(); client->SetActivity(STARTATM); // Collect stats on call waiting client_wait.Add(time - client->start); atm_wait.Add(time - client->start); client->start = time; if(_DEBUG_) printf("ATM Starts %f \n", time); // Calculate call ending time time1 = sim_time + dist.NormalLimited(atm_service_mean, atm_service_stddev, min_service, max_service); // Schedule end of conversation time executive->AddActivity(time1, ENDATM, client); // atm isn't free atm_free = false; } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CUICreateChar::Reset() { Lock(FALSE); m_iSelectedJob = 0; m_fZDelta = 0.0f; m_fRotDelta = 0.0f; m_ebCharName.ResetString(); // 카메라 설정, 캐릭터 위치 설정. for(int i = 0; i < MAXJOB; ++i) { const int iMarker = _aiMarkerEntities[i]; CEntity *penMarker = m_pWorld->EntityFromID(iMarker); penMarker->SetSkaModel(JobInfo().GetFileName(i)); g_CharacterAngle[i] = penMarker->GetPlacement().pl_OrientationAngle(1); CModelInstance* pMI = penMarker->GetModelInstance(); if(pMI) { INDEX idAttackIdle = ska_GetIDFromStringTable( JobInfo().GetAnimationName( i, ANIM_IDLE ) ); pMI->AddAnimation(idAttackIdle, AN_LOOPING|AN_NORESTART|AN_CLEAR, 1, 0); } } #if defined(G_BRAZIL) CharWearing(); #endif ChangeSelJob(); m_bIsShowMessageInfo = _pGameState->IsCreatableNightShadow(); }
void CGameWorld::Tick() { if(m_ResetRequested) Reset(); if(!m_Paused) { if(GameServer()->m_pController->IsForceBalanced()) GameServer()->SendChat(-1, CGameContext::CHAT_ALL, "Teams have been balanced"); // update all objects for(int i = 0; i < NUM_ENTTYPES; i++) for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; ) { m_pNextTraverseEntity = pEnt->m_pNextTypeEntity; pEnt->Tick(); pEnt = m_pNextTraverseEntity; } for(int i = 0; i < NUM_ENTTYPES; i++) for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; ) { m_pNextTraverseEntity = pEnt->m_pNextTypeEntity; pEnt->TickDefered(); pEnt = m_pNextTraverseEntity; } } RemoveEntities(); }
BOOL CEntitiesDialog::NeedTextNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult ) { TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR; const char *pDocField; CString EntityClassname; CString FieldName; int Index; CEntity *pEnt; // default return value is nothing... pTTT->szText[0] = '\0'; // Fill the szText field with the documentation string for the current field. // Get current entity selection and retrieve its name Index = m_EntityCombo.GetCurSel (); if (Index == CB_ERR) { return FALSE; } Index = m_EntityCombo.GetItemData (Index); pEnt = &((*mEntityArray)[Index]); EntityClassname = pEnt->GetClassname (); m_PropertiesList.GetText (UglyGlobalItemId, FieldName); pDocField = EntityTable_GetEntityFieldDoc (Level_GetEntityDefs (pDoc->pLevel), EntityClassname, FieldName); if (pDocField != NULL) { strncpy (pTTT->szText, pDocField, sizeof (pTTT->szText)); pTTT->szText[sizeof (pTTT->szText)-1] = '\0'; } return FALSE; }
PLAYER_CLASS* sq_toplayer(SQVM* pVM, int idx) { CEntity* pEntity = sq_toentity(pVM, idx); if( pEntity && pEntity->GetType() == ENTITY_TYPE_PLAYER ) return dynamic_cast< PLAYER_CLASS* >( pEntity ); return NULL; }
void CMap::createProjectile(const std::string entityName, const CLogicalPosition pos,const CEntity* father) { // [PT] Creamos un proyectil, flecha. Lo hago tal como crea los aliados Pablo std::ostringstream eName, eBase, eRing, eDegrees, eSense; eName << entityName; //bullet es un contador eBase << pos.getBase(); eRing << (unsigned short) pos.getRing(); eDegrees << (float)pos.getDegree(); eSense << (unsigned short) pos.getSense(); Map::CEntity bulletInfo(eName.str()); bulletInfo.setType(entityName); //Atributos bulletInfo.setAttribute("base", eBase.str()); bulletInfo.setAttribute("ring", eRing.str()); bulletInfo.setAttribute("sense", eSense.str()); bulletInfo.setAttribute("degrees", eDegrees.str()); CEntity* newBullet = CEntityFactory::getSingletonPtr()->createMergedEntity(&bulletInfo, this, father); //activate the new entity //newBullet->getLogicalPosition()->setSense(eSense); newBullet->activate(); bullet++; //newAlied->setPosition(newAlied->getPosition() + (rand()%50-25) * Vector3(1, 0, 1) ); }
CResource* sq_toresource(SQVM* pVM, int idx) { CEntity* pEntity = sq_toentity(pVM, idx); if( pEntity && pEntity->GetType() == ENTITY_TYPE_RESOURCE ) return dynamic_cast< CResource* >( pEntity ); return NULL; }
bool CAI_Senses::WaitingUntilSeen( CBaseEntity *pSightEnt ) { CEntity *cent = CEntity::Instance(pSightEnt); if ( GetOuter()->m_spawnflags & SF_NPC_WAIT_TILL_SEEN ) { if ( cent->IsPlayer() ) { CPlayer *pPlayer = ToBasePlayer( cent ); Vector zero = Vector(0,0,0); // don't link this client in the list if the npc is wait till seen and the player isn't facing the npc if ( pPlayer // && pPlayer->FVisible( GetOuter() ) && pPlayer->FInViewCone_Entity( GetOuter()->BaseEntity() ) && FBoxVisible( cent, static_cast<CEntity*>(GetOuter()), zero ) ) { // player sees us, become normal now. GetOuter()->m_spawnflags &= ~SF_NPC_WAIT_TILL_SEEN; return false; } } return true; } return false; }
void CCameraFeedbackNotifier::process(const std::shared_ptr<CMessage>& message) { //Ambas hacen lo mismo de momento, pero lo dejo separado por si luego queremos poner //comportamientos distintos en función del daño switch( message->getMessageType() ) { case Message::DAMAGED: { std::shared_ptr<CMessageDamaged> damageMess = std::static_pointer_cast<CMessageDamaged>(message); CEntity* enemy = damageMess->getEnemy(); if(enemy != NULL) damaged( enemy->getPosition() ); break; } /*case Message::SET_REDUCED_DAMAGE: { damaged(); break; }*/ case Message::FLASH: { std::shared_ptr<CMessageFlash> flashMsg = std::static_pointer_cast<CMessageFlash>(message); _flashFactor = flashMsg->getFlashFactor(); _flashVisible = true; _scene->setCompositorVisible(_flashEffect, true); break; } } } // process
EStatus ActionShoot(const float frametime, CBot* bot, bool shotgun) { bot->SetSpeed( 0.0f ); bot->SetState(ai::EBotState::BotStateShooting); if ( bot->Aim(frametime) ) { CEntityList* entList = CEntityList::GetInstance(); CEntity* ent = entList->GetEntity( bot->GetTargetID() ); if ( ent != NULL ) { XMFLOAT3 ray = utl::Normalise( utl::Subtract( bot->GetPosition(), ent->GetPosition() ) ); if (CheckLOS(bot, ray, entList) && bot->GetAmmo(shotgun) != 0) { bot->Shoot( frametime, shotgun ); return Pass; } else { return Fail; } } } else { return Running; } return Fail; }
int CEventNatives::RemoveHandler(SQVM* pVM) { // get the event name const char* szEventName; sq_getstring(pVM, 2, &szEventName); // get the entity which it should effect CEntity* pEntity = sq_toentity(pVM, 3); // get the function to execute upon calling the event SQObject o; sq_getstackobj(pVM, 4, &o); // if we have a valid entity, use it if(pEntity) { sEventData event; event.pFunction = o; // get the resource calling this function event.pResource = g_pResourceManager->Get(pVM); assert(event.pResource); // pass the result to the script sq_pushbool(pVM, pEntity->RemoveEvent(szEventName, event)); } else sq_pushbool(pVM, false); return 1; }
VEHICLE_CLASS* sq_tovehicle(SQVM* pVM, int idx) { CEntity* pEntity = sq_toentity(pVM, idx); if( pEntity && pEntity->GetType() == ENTITY_TYPE_VEHICLE ) return dynamic_cast< VEHICLE_CLASS* >( pEntity ); return NULL; }
//----------------------------------------------------------------------------- // Purpose: 모든 생성 캐릭터의 기본 장비 착용 //----------------------------------------------------------------------------- void CUICreateChar::CharWearing() { for(int i = 0 ; i < MAXJOB; ++i) { // 카메라 설정, 캐릭터 위치 설정. const int iMarker = _aiMarkerEntities[i]; CEntity *penMarker = m_pWorld->EntityFromID(iMarker); CModelInstance* pMI = penMarker->GetModelInstance(); // 슬롯의 캐릭터에 장비를 장착한 모습을 보여줘야 하는 부분... // 상의 무기 하의 방패 장갑 신발 if(pMI) { for(int j = 0; j < 6; ++j) { const SLONG lWear = _aiBasicWearing[i][j]; if(lWear > 0) { CItemData* pID = _pNetwork->GetItemData(lWear); _pGameState->DeleteDefaultArmor(pMI, pID->GetWearingPosition(), i); _pGameState->WearingArmor(pMI, *pID); } } } } }
void CBank::ArriveClient() // Arrival activity handling { double time1, sim_time = executive->SimulationTime(); if (activity == ARRIVE && time == sim_time) { CEntity *client = new CEntity(); CDistribution dist; // Current client arrival entity->arrive = time; entity->start = time; if(_DEBUG_) printf("Client Arrives %f \n", time); // Next client arrival time calculation time1 = sim_time + dist.Exponential(arrival_mean); client->SetActivity(ARRIVE); // Schedule next client arrival executive->AddActivity(time1, ARRIVE, client); // decide where the client goes double r = dist.Random(); if(r < arrival_teller_prob){ teller_queue->InserirFim(entity); }else if(r < arrival_teller_prob + arrival_manager_prob){ manager_queue->InserirFim(entity); }else{ atm_queue->InserirFim(entity); } } }
void CApp::OnLoop() { CFPS::FPSControl.OnLoop(); for(int i=0; i<CEntity::EntityList.size(); i++) { if(!CEntity::EntityList[i]) continue; CEntity::EntityList[i]->OnLoop(); } // handle collision events for(int i=0; i<CEntityCol::entityColList.size(); i++) { CEntity* entityA = CEntityCol::entityColList[i].entityA; CEntity* entityB = CEntityCol::entityColList[i].entityB; if(entityA == NULL || entityB == NULL) continue; // call 2nd only if desired (timesaving) if(entityA->OnCollision(entityB)) entityB->OnCollision(entityA); } CEntityCol::entityColList.clear(); }
void CBank::StartManager() // service Start handling { double time1, sim_time = executive->SimulationTime(); CDistribution dist; CEntity *client; if(manager_free) { // Manager is free if (call_queue->EhVazia() && !manager_queue->EhVazia()) { // There is client in the queue // Get client from client queue client = (CEntity*) manager_queue->ObterInfo(); manager_queue->Remover(); client->SetActivity(ENDMANAGER); // Collect statistics on client waiting client_wait.Add(time - client->start); manager_wait.Add(time - client->start); client->start = time; if(_DEBUG_) printf("Service Starts %f \n", time); // Calculate service ending time time1 = sim_time + dist.NormalLimited(manager_service_mean, manager_service_stddev, min_service, max_service); executive->AddActivity(time1, ENDMANAGER, client); manager_free = false; } } }
void CAppStateGame::OnLoop() { for(int i = 0;i < CEntity::EntityList.size();i++) { if(!CEntity::EntityList[i]) continue; CEntity::EntityList[i]->OnLoop(); if (CEntity::EntityList[i]->Type == ENTITY_TYPE_ENEMY) { if(!Player.Dead) { CEntity::EntityList[i]->Shoot(Player.X + (Player.Width / 2),Player.Y + (Player.Height / 2)); } } } //Collision Events for(int i = 0;i < CEntityCol::EntityColList.size();i++) { CEntity* EntityA = CEntityCol::EntityColList[i].EntityA; CEntity* EntityB = CEntityCol::EntityColList[i].EntityB; if(EntityA == NULL || EntityB == NULL) continue; if(EntityA->Dead == true || EntityB->Dead == true) continue; if(EntityA->OnCollision(EntityB)) { EntityB->OnCollision(EntityA); } } CEntityCol::EntityColList.clear(); if (Player.Dead) { WinMessage.boolMessage = false; CAppStateManager::SendMessage(APPSTATE_END, &WinMessage); CAppStateManager::SetActiveAppState(APPSTATE_END); } // if (Archer.Dead) { // WinMessage.boolMessage = true; // CAppStateManager::SendMessage(APPSTATE_END,&WinMessage); // CAppStateManager::SetActiveAppState(APPSTATE_END); // } if(Player.Money > 0) { WinMessage.boolMessage = true; CAppStateManager::SendMessage(APPSTATE_END,&WinMessage); CAppStateManager::SetActiveAppState(APPSTATE_END); } for(std::vector<CEntity*>::iterator it = CEntity::EntityList.begin(); it != CEntity::EntityList.end();) { if(!(*it)) continue; if((*it)->Dead == true) { (*it)->OnCleanup(); delete (*it); it = CEntity::EntityList.erase(it); } else { it++; } } char Buffer[255]; sprintf(Buffer,"Player Health: %d ||| Enemy Health: %d ||| Money: %d", Player.Health, Archer.Health, Player.Money); SDL_WM_SetCaption(Buffer,Buffer); }
Logic::CEntity *CEntityFactory::createEntity(/*const*/ Map::CEntity *entityInfo, Logic::CMap *map) { /** En este punto tenemos en entityInfo la información para construir la entidad. Dependiendo del tipo se ensanblará con unos componentes u otros (assembleEntity usa blueprints). Nosotros debemos tratar el objeto entityInfo para que use siempre y cuando pueda la información de _archetypes. Por ello el entityInfo nuevo tendra todo lo que venga en _archetypes + los atributos extras del entityInfo (sobreescribiendo si es necesario). El type de entrada y salida han de ser el mismo. TODO ESTO SE REALIZA A NIVEL DE MAP::CENTITY */ //buscamos el arquetipo que coincida con la entidad que se esta creando //En caso de no haber arquetipo coincidente el entityInfo no se modifica //entityInfo->setName(entityInfo->getName()+std::to_string(EntityID::_nextId)); ArchetypeMap::iterator find = _archetypes.find(entityInfo->getType()); if(find != _archetypes.end())//Hay coincidencia de arquetipo, por lo tanto hacemos un merge de la informacion { entityInfo->mergeArchetype(find->second); } //Llamo al metodo instanciate del spawner, para ver si hay alguna entidad desactivada en el pull y activarla CEntity *ret = Logic::CPoolManager::getSingletonPtr()->instanciate(entityInfo); //Si no encontro ninguna entidad del tipo en el pull if(ret == 0) { //llamo al assembleEntity para añadirle sus componentes y crear la entidad ret = assembleEntity(entityInfo->getType()); } //Si en el pull no ha encontrado ninguna entidad del tipo, y el assembleEntity no fue capaz de crear la entidad, devolvemos null if (!ret) return 0; // Añadimos la nueva entidad en el mapa. map->addEntity(ret); // Y lo inicializamos if (ret->spawn(map, entityInfo)) { if(!map->activarEntidad(ret)) { BaseSubsystems::Log::Debug("Spawneo de la entidad "+entityInfo->getName()+" fallido"); return 0; } return ret; } else { map->removeEntity(ret); delete ret; return 0; } } // createEntity