void EffectSystem::OnEntityRemoved(Entity* _e) { auto flags = _e->GetComponent<EffectComponent>()->m_effects; //SHATTER if ((flags.OnRemoved & EffectFlags::SHATTER) == EffectFlags::SHATTER) { Entity* e = m_world->CreateEntity(); EntityFactory::GetInstance()->CreateEntity(e, EntityFactory::SHATTER); e->GetComponent<ModelComponent>()->m_modelPath = _e->GetComponent<ModelComponent>()->m_modelPath; e->GetComponent<PositionComponent>()->SetPosition(_e->GetComponent<PositionComponent>()->GetPosition()); m_effects[e->GetId()] = e; m_world->AddEntity(e); } //EXPLODE if ((flags.OnRemoved & EffectFlags::EXPLODE) == EffectFlags::EXPLODE) { Entity* e = m_world->CreateEntity(); EntityFactory::GetInstance()->CreateEntity(e, EntityFactory::EXPLOSION); e->GetComponent<PositionComponent>()->SetPosition(_e->GetComponent<PositionComponent>()->GetPosition()); m_effects[e->GetId()] = e; m_world->AddEntity(e); auto position = e->GetComponent<PositionComponent>(); GraphicsManager::GetInstance()->AddParticleEffect(GetMemoryID(e), "fire", &position->GetPosition(), 0); } if (EntityContains(flags, EffectFlags::TRAIL)) { GraphicsManager::GetInstance()->RemoveParticleEffect(GetMemoryID(_e)); } }
void MapSystem::OnSpawnEntity(const Message& msg) { const SpawnEntityMessage& m = static_cast<const SpawnEntityMessage&>(msg); Entity* entity; GetEntityManager().CreateEntity(entity); std::string spawnerName = m.GetSpawnerName(); bool success = Spawn(spawnerName, *entity); if(!success) { LOG_ERROR("Could not spawn entity: spawner not found: " + spawnerName); return; } MapComponent* comp; if(!entity->GetComponent(comp)) { entity->CreateComponent(comp); } comp->SetUniqueId(m.GetUniqueId()); comp->SetEntityName(m.GetEntityName()); EntitySpawnedMessage smsg; smsg.SetSpawnerName(spawnerName); smsg.SetAboutEntityId(entity->GetId()); GetEntityManager().EmitMessage(smsg); if(m.GetAddToScene()) { GetEntityManager().AddToScene(entity->GetId()); } }
AUEntityId EntitySystem::Create(const char * sName) { Entity *pEntity = new Entity(m_nextId++); pEntity->SetName(sName); m_Entities[pEntity->GetId()] = pEntity; return pEntity->GetId(); }
void SystemBulletDamage::collisionHandler(const IEventData& evt) { const EnterColliderEvent & castedEvent = static_cast<const EnterColliderEvent &>(evt); Entity* pEntity = castedEvent.entity1; if (!IsMyEntity(pEntity)) return; Entity* pOtherEntity = castedEvent.entity2; if (nullptr == pOtherEntity) return; auto myAgent = agentMapper.get(pEntity); bool isEnemy = EntityUtility::IsEnemy(pEntity, pOtherEntity); if (myAgent->pBulletData->moveType == BulletMoveType::BMT_Line) { // 召唤类子弹,不关心碰撞。 } else if (myAgent->pBulletData->moveType == BulletMoveType::BMT_Bezier) { if (myAgent && isEnemy) { EventManager::GetSingleton()->FireEvent(BulletHitEvent(pEntity)); EventManager::GetSingleton()->FireEvent(StopMoveEvent(pEntity)); // 这里也是不合适,因为不一定碰撞之后就会触发buff。 ComPawnAgent* bulletAgent = agentMapper.get(pEntity); if (bulletAgent) { const Bullet_cfg* bulletInfo = bulletAgent->pBulletData; for (int i = 0; i < 3; ++i) { if (bulletInfo->buffs[i] != 0) BuffManager::GetSingleton()->AddBuff(pEntity->GetId(), pOtherEntity->GetId(), bulletInfo->buffs[i]); } } } } else if (myAgent->pBulletData->moveType == BulletMoveType::BMT_Tracking) { /*if (myAgent->GetBlackboard()->targetType == Target_Entity) { if (myAgent->GetBlackboard()->targetID == pOtherEntity->GetId()) { EventManager::GetSingleton()->FireEvent(BulletHitEvent(pEntity)); } } else if (myAgent->GetBlackboard()->targetType == Target_Location) { ; }*/ } }
int EntityUtility::FindNearestTarget(Entity* pEntity, bool sameTeam, bool includeSelf) { ComTransform* myPosCom = pEntity->GetComponent<ComTransform>(); ComPawnAgent* myTempCom = pEntity->GetComponent<ComPawnAgent>(); int enemyId = Entity::InvalidID; float minDist = 0; std::string targetTag; if (sameTeam) { bool isTagged = EntityUtility::IsTagged(GameDefine::Tag_Soldier, pEntity); targetTag = isTagged ? GameDefine::Tag_Soldier : GameDefine::Tag_Monster; } else { bool isTagged = EntityUtility::IsTagged(GameDefine::Tag_Soldier, pEntity); targetTag = isTagged ? GameDefine::Tag_Monster : GameDefine::Tag_Soldier; } entity_map& activities = ECSWorld::GetSingleton()->GetEntitiesByTag(targetTag); if (activities.size() == 0) return Entity::InvalidID; for (auto& it : activities) { Entity* pEnemyEntity = it.second; if ((!includeSelf) && pEnemyEntity->GetId() == pEntity->GetId()) continue; /*if (enemyAttCom && enemyAttCom->GetBlackboard()->GetAttr(AttrType::HP)<= 0) continue;*/ ComTransform* enePosCom = pEnemyEntity->GetComponent<ComTransform>(); Point2D vecBetween(myPosCom->x - enePosCom->x, myPosCom->y - enePosCom->y); float len = vecBetween.Length(); if (len < myTempCom->m_roleCfg->viewRange) { if (enemyId == Entity::InvalidID) { enemyId = pEnemyEntity->GetId(); minDist = len; } else if (len < minDist) { enemyId = pEnemyEntity->GetId(); minDist = len; } } } return enemyId; }
void MapSystem::OnDeleteEntity(const Message& msg) { const DeleteEntityMessage& m = static_cast<const DeleteEntityMessage&>(msg); Entity* entity; bool success = GetEntityByUniqueId(m.GetUniqueId(), entity); if(!success) { LOG_ERROR("Cannot delete: Entity with unique id not found: " + m.GetUniqueId()); return; } GetEntityManager().RemoveFromScene(entity->GetId()); GetEntityManager().KillEntity(entity->GetId()); }
bool SystemBulletDamage::TriggerBulletBuff(IEventData const &evt) { const BulletTriggerEvent & castedEvent = static_cast<const BulletTriggerEvent &>(evt); Entity* pOwnerEntity = castedEvent.entity; if (!IsMyEntity(pOwnerEntity)) return false; ComBulletDamage* pAttackCom = damageMapper.get(pOwnerEntity); auto agentCom = agentMapper.get(pOwnerEntity); if (agentCom->pBulletData->moveType == BulletMoveType::BMT_Tracking) { const Bullet_cfg* bulletInfo = agentCom->pBulletData; std::vector<Entity*> targets; FindTargetsInScope(pOwnerEntity, bulletInfo->buffTargetRadius, false, targets); for (auto iter = targets.begin(); iter != targets.end(); ++iter) { for (int i = 0; i < 3; ++i) { if (bulletInfo->buffs[i] != 0) BuffManager::GetSingleton()->AddBuff(pOwnerEntity->GetId(), (*iter)->GetId(), bulletInfo->buffs[i]); } } } return true; }
// TODO: Test remove function bool Octree::Remove( const Entity& e ) { e.GetPosition(); u32 id = e.GetId(); for ( auto& ent : objects ) { if ( ent->GetId() == id) { delete ent; ent = nullptr; return true; } } if ( children[0] != nullptr ) { for ( Octree* o : children ) { if( o->Remove(e) ) { return true; } } } return false; }
void EntityUtility::FindTargetsInScope(int entityID, int scopeSize, bool sameTeam, bool includeSelf, std::vector<int>& eneityIDList) { Entity* pEntity = ECSWorld::GetSingleton()->GetEntity(entityID); ComTransform* myPosCom = pEntity->GetComponent<ComTransform>(); std::string targetTag; if (sameTeam) { bool isTagged = EntityUtility::IsTagged(GameDefine::Tag_Soldier, pEntity); targetTag = isTagged ? GameDefine::Tag_Soldier : GameDefine::Tag_Monster; } else { bool isTagged = EntityUtility::IsTagged(GameDefine::Tag_Soldier, pEntity); targetTag = isTagged ? GameDefine::Tag_Monster : GameDefine::Tag_Soldier; } entity_map& activities = ECSWorld::GetSingleton()->GetEntitiesByTag(targetTag); for (auto& it : activities) { Entity* pEnemyEntity = it.second; ComPawnAgent* enemyAttCom = pEnemyEntity->GetComponent<ComPawnAgent>(); ComTransform* enePosCom = pEnemyEntity->GetComponent<ComTransform>(); Point2D vecBetween(myPosCom->x - enePosCom->x, myPosCom->y - enePosCom->y); float len = vecBetween.Length(); if (len < scopeSize) { eneityIDList.push_back(pEnemyEntity->GetId()); } } }
void SaveXmlComponentVisitor::Visit(Entity &entity) { (*file) << " " << XmlTag::startTagEntity << "\n" << " " << XmlTag::startTagId << entity.GetId() << XmlTag::endTagId << "\n" << " " << XmlTag::startTagText << entity.GetName() << XmlTag::endTagText << "\n" << " " << XmlTag::startTagPrimaryKey; FindAttribute(entity.GetConnectComponents()); (*file) << XmlTag::endTagPrimaryKey << "\n" << " " << XmlTag::startTagPointX << entity.GetPointX() << XmlTag::endTagPointX << "\n" << " " << XmlTag::startTagPointY << entity.GetPointY() << XmlTag::endTagPointY << "\n" << " " << XmlTag::endTagAttribute << "\n"; }
void PhysicsSystem::Update(float _dt) { for (auto it = m_entityMap.begin(); it != m_entityMap.end(); ++it) { Entity* e = it->second; if (e->GetState() != Entity::ALIVE) continue; auto collision = e->GetComponent<CollisionComponent>(); auto stats = e->GetComponent<CollisionStatsComponent>(); auto position = e->GetComponent<PositionComponent>(); auto velocity = e->GetComponent<VelocityComponent>(); auto rotation = e->GetComponent<RotationComponent>(); b2Body* b2Body = collision->GetBody(); // Update position, velocity and rotation after the components if (position && rotation) { const b2Vec2 b2Pos = b2Vec2(position->GetPosition().x, position->GetPosition().y); if (collision->GetBody()->GetPosition().x != b2Pos.x || collision->GetBody()->GetPosition().y != b2Pos.y || collision->GetBody()->GetAngle() != rotation->GetRotation().z) collision->GetBody()->SetTransform(b2Pos, rotation->GetRotation().z); } else if (position) { const b2Vec2 b2Pos = b2Vec2(position->GetPosition().x, position->GetPosition().y); if (collision->GetBody()->GetPosition().x != b2Pos.x || collision->GetBody()->GetPosition().y != b2Pos.y) collision->GetBody()->SetTransform(b2Pos, collision->GetBody()->GetAngle()); } else if (rotation) { if (collision->GetBody()->GetAngle() != rotation->GetRotation().z) collision->GetBody()->SetTransform(collision->GetBody()->GetPosition(), rotation->GetRotation().z); } if (velocity) { const b2Vec2 b2Velocity = b2Vec2(velocity->m_velocity.x, velocity->m_velocity.y); if (collision->GetBody()->GetLinearVelocity().x != b2Velocity.x || collision->GetBody()->GetLinearVelocity().y != b2Velocity.y) collision->GetBody()->SetLinearVelocity(b2Velocity); } // Update velocity min/max and deacceleration if (velocity && stats) { if (b2Body->GetLinearVelocity().y <= 0.5f && b2Body->GetLinearVelocity().y >= -0.5f) b2Body->SetLinearVelocity(b2Vec2(b2Body->GetLinearVelocity().x, -3.0f)); float speed = b2Body->GetLinearVelocity().Length(); // Speed cant be 0 if (speed == 0) continue; // Set speed between min/max if (speed < stats->GetMinSpeed()) { b2Body->SetLinearVelocity(b2Vec2((b2Body->GetLinearVelocity().x / speed) * stats->GetMinSpeed(), (b2Body->GetLinearVelocity().y / speed) * stats->GetMinSpeed())); } if (speed > stats->GetMaxSpeed()) { b2Body->SetLinearVelocity(b2Vec2((b2Body->GetLinearVelocity().x / speed) * stats->GetMaxSpeed(), (b2Body->GetLinearVelocity().y / speed) * stats->GetMaxSpeed())); } // Deaccelerate if (speed > stats->GetMaxDampingSpeed()) { float newSpeed = speed - (stats->GetDampingAcceleration() * _dt); if (speed < stats->GetMaxDampingSpeed()) newSpeed = stats->GetMaxDampingSpeed(); b2Body->SetLinearVelocity(b2Vec2((b2Body->GetLinearVelocity().x / speed) * newSpeed, (b2Body->GetLinearVelocity().y / speed) * newSpeed)); } } } // Simulate worlds physics m_b2World->Step(_dt, VELOCITYITERATIONS, POSITIONITERATIONS); // Update position, velocity and rotation components for (auto it = m_entityMap.begin(); it != m_entityMap.end(); ++it) { Entity* e = it->second; if (e->GetState() != Entity::ALIVE) continue; auto collision = e->GetComponent<CollisionComponent>(); auto position = e->GetComponent<PositionComponent>(); auto velocity = e->GetComponent<VelocityComponent>(); auto rotation = e->GetComponent<RotationComponent>(); b2Body* b2Body = collision->GetBody(); collision->ResetCollisions(); if (position) { b2Vec2 b2Pos = b2Body->GetPosition(); position->SetPosition(VECTOR3(b2Pos.x, b2Pos.y, position->GetPosition().z)); } if (velocity) { b2Vec2 b2Velocity = b2Body->GetLinearVelocity(); velocity->m_velocity = VECTOR3(b2Velocity.x, b2Velocity.y, velocity->m_velocity.z); } if (rotation) { QUAT rot = rotation->GetRotation(); //rotation->SetRotation(QUAT(rot.x, rot.y, b2Body->GetAngle(), rot.w)); } } // Do collisions checks for (b2Contact* contact = m_b2World->GetContactList(); contact; contact = contact->GetNext()) { if (!contact->IsTouching()) continue; b2Fixture* fixtureA = contact->GetFixtureA(); b2Fixture* fixtureB = contact->GetFixtureB(); Entity* entityA = 0; Entity* entityB = 0; for (auto it = m_entityMap.begin(); it != m_entityMap.end(); ++it) { Entity* e = it->second; if (e->GetState() != Entity::ALIVE) continue; if (!entityA && e->GetComponent<CollisionComponent>()->HasBody(fixtureA->GetBody())) entityA = e; else if (!entityB && e->GetComponent<CollisionComponent>()->HasBody(fixtureB->GetBody())) entityB = e; if (entityA && entityB) break; } if (entityA && entityB) { CollisionContact collisionContact = CollisionContact(contact, fixtureA, fixtureB, entityB->GetId()); entityA->GetComponent<CollisionComponent>()->CollidingWith(collisionContact); collisionContact = CollisionContact(contact, fixtureB, fixtureA, entityA->GetId()); entityB->GetComponent<CollisionComponent>()->CollidingWith(collisionContact); } } }