void OnMouseDown(UINT button, int x, int y) { XOrientation camOrient; cameraEntity->GetOrientation(&camOrient); if (button == 0) cameraControl = true; //shoot a cube else if (button == 1) { Entity* pCube = g_pScene->CreateEntity(); g_pSelectedEntity = pCube; pCube->SetPosition(cameraEntity->GetPosition() + camOrient.z); pCube->SetVelocity(0.1f * camOrient.z); //pCube->SetMaxLifeTime(5.0f); MeshComponent* pMesh = new MeshComponent(pCube); pMesh->SetMeshResource("cube.nfm"); BodyComponent* pBody = new BodyComponent(pCube); pBody->SetMass(10.0f); pBody->EnablePhysics((CollisionShape*)EngineGetResource(ResourceType::COLLISION_SHAPE, "shape_box")); OmniLightDesc lightDesc; lightDesc.radius = 4.0f; lightDesc.shadowFadeStart = 20.0; lightDesc.shadowFadeEnd = 30.0; Entity* pLightEntity = g_pScene->CreateEntity(); pCube->Attach(pLightEntity); //pLightEntity->SetLocalPosition(Vector(0.0f, 1.0f, 0.0f)); LightComponent* pLight = new LightComponent(pLightEntity); pLight->SetOmniLight(&lightDesc); pLight->SetColor(Float3(1.0f, 1.0f, 10.0f)); pLight->SetShadowMap(0); } else { Entity* pBarrel = g_pScene->CreateEntity(); g_pSelectedEntity = pBarrel; pBarrel->SetPosition(cameraEntity->GetPosition() + camOrient.z); pBarrel->SetVelocity(30.0f * camOrient.z); MeshComponent* pMesh = new MeshComponent(pBarrel); pMesh->SetMeshResource("barrel.nfm"); BodyComponent* pBody = new BodyComponent(pBarrel); pBody->SetMass(20.0f); pBody->EnablePhysics((CollisionShape*)EngineGetResource(ResourceType::COLLISION_SHAPE, "shape_barrel")); } }
void OnKeyPress(int key) { if (key == VK_F1) { BOOL fullscreen = getFullscreenMode(); setFullscreenMode(!fullscreen); } XOrientation orient; //place spot light if (key == 'T') { Entity* pLightEntity = g_pScene->CreateEntity(); cameraEntity->GetOrientation(&orient); pLightEntity->SetOrientation(&orient); pLightEntity->SetPosition(cameraEntity->GetPosition()); LightComponent* pLight = new LightComponent(pLightEntity); SpotLightDesc lightDesc; lightDesc.nearDist = 0.1f; lightDesc.farDist = 500.0f; lightDesc.cutoff = NFE_MATH_PI / 4.0f; lightDesc.maxShadowDistance = 60.0; pLight->SetSpotLight(&lightDesc); pLight->SetColor(Float3(600, 200, 50)); pLight->SetLightMap("flashlight.jpg"); pLight->SetShadowMap(1024); g_pSelectedEntity = pLightEntity; } //place omni light if (key == 'O') { OmniLightDesc lightDesc; lightDesc.radius = 10.0f; lightDesc.shadowFadeStart = 20.0; lightDesc.shadowFadeEnd = 30.0; Entity* pLightEntity = g_pScene->CreateEntity(); pLightEntity->SetPosition(cameraEntity->GetPosition()); LightComponent* pLight = new LightComponent(pLightEntity); pLight->SetOmniLight(&lightDesc); pLight->SetColor(Float3(600, 600, 600)); pLight->SetShadowMap(512); g_pSelectedEntity = pLightEntity; } }
void PhysicsComponent::CreatePlatform() { btCollisionShape* boxShape = new btBoxShape(btVector3(0.5,0.5,0.5)); Entity* entOwner = GetOwner(); EVector3f pos = entOwner->GetPosition(); btDefaultMotionState* fallMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(pos.x, pos.y, pos.z))); btScalar mass = 1; btVector3 fallInertia(0, 0, 0); boxShape->calculateLocalInertia(mass, fallInertia); btRigidBody::btRigidBodyConstructionInfo boxRigidBodyCI(mass, fallMotionState, boxShape,fallInertia); btRigidBody* boxRigidBody = new btRigidBody(boxRigidBodyCI); m_rigidBody = boxRigidBody; m_rigidBody->setUserPointer(this); //add physicsbody to world PhysicsManager::GetInstance()->AddPhysicsComponent(this); }
Status EvadeBehavior::Execute(void) { // get target const TargetData &targetdata = Database::targetdata.Get(mId); // get target entity Entity *targetEntity = Database::entity.Get(targetdata.mTarget); if (!targetEntity) return runningTask; // get owner entity Entity *entity = Database::entity.Get(mId); // get evade behavior template const EvadeBehaviorTemplate &evade = Database::evadebehaviortemplate.Get(mId); // target entity transform const Transform2 &targetTransform = targetEntity->GetTransform(); // evade target's front vector Vector2 local(targetTransform.Untransform(entity->GetPosition())); if (local.y > 0) { local *= InvSqrt(local.LengthSq()); float dir = local.x > 0 ? 1.0f : -1.0f; mController->mMove += evade.mStrength * dir * local.y * local.y * local.y * targetTransform.Rotate(Vector2(local.y, -local.x)); } return runningTask; }
bool Engine::IsEntityWalkable(size_t x, size_t y) { bool is_walkable = true; float center_x, center_y = 0.f; m_world->GetBlockToPixel(x, y, center_x, center_y); // found entity present float entity_x, entity_y = 0.f; for(entities_t::iterator it = m_entities.begin(); it != m_entities.end(); ++it) { Entity* entity = (*it); entity->GetPosition(entity_x, entity_y); if(entity_x == center_x && entity_y == center_y) { // found an entity in the block is_walkable = entity->IsWalkable(); break; } } return is_walkable; }
// 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 SceneRegionManager::AddSceneEntity(Entity& rEntity) { if (SceneRegion* pInRegion = GetBelongRegion(rEntity.GetPosition())) { // 添加到所在区域 pInRegion->AddEntity(rEntity); // 注册相关区域监听 // 计算相交区域 set<SceneRegion*> collisionRegions; GetCollisionRegion(rEntity.InViewRange(), collisionRegions); if (rEntity.IsListen()) { set<SceneRegion*>::iterator it = collisionRegions.begin(); set<SceneRegion*>::iterator itEnd = collisionRegions.end(); for (; it != itEnd; ++it) { (*it)->RegistReceiveChannels(rEntity); } } // 添加管理信息 m_umapEntityRegions.insert(make_pair(&rEntity, pair<SceneRegion*, set<SceneRegion*> >(pInRegion, collisionRegions))); } }
void Unit::OnCollide(Entity& entity, const sf::FloatRect& overlap) { if (IsDying() || entity.IsDying()) { return; } switch (entity.GetCollideEffect()) { case FX_REJECTION: // repoussement horizontal ? if (overlap.GetHeight() < overlap.GetWidth()) { // vers le haut ou le bas knocked_dir_ = entity.GetPosition().y > GetPosition().y ? UP : DOWN; } else // vertical { // vers la gauche ou la droite knocked_dir_ = entity.GetPosition().x > GetPosition().x ? LEFT : RIGHT; } knocked_start_ = Game::GetInstance().GetElapsedTime(); knocked_speed_ = KNOCK_INITIAL_SPEED; is_knocked_ = true; break; case FX_STOP: { Direction dir; float dist; if (overlap.GetHeight() < overlap.GetWidth()) { dir = entity.GetPosition().y > GetPosition().y ? UP : DOWN; dist = overlap.GetHeight(); } else { dir = entity.GetPosition().x > GetPosition().x ? LEFT : RIGHT; dist = overlap.GetWidth(); } Move(dir, dist); } break; case FX_NOTING: break; } }
// Gunner Constructor Gunner::Gunner(const GunnerTemplate &aTemplate, unsigned int aId) : Updatable(aId) { SetAction(Action(this, &Gunner::Update)); Entity *entity = Database::entity.Get(mId); #ifdef GUNNER_TRACK_DEQUE mTrackPos.push_back(entity->GetPosition()); mTrackPos.push_back(entity->GetPosition()); #else mTrackCount = xs_CeilToInt(aTemplate.mFollowLength/GUNNER_TRACK_GRANULARITY) + 1; mTrackPos = new Vector2[mTrackCount]; mTrackFirst = mTrackLast = 0; mTrackPos[0] = entity->GetPosition(); #endif mTrackLength = 0.0f; }
TetherBurn(unsigned int aId, unsigned int aSourceId, unsigned int aOwnerId, float aDamage, int aCombo) : Updatable(aId), mOwnerId(aOwnerId), mDamage(aDamage), mCombo(aCombo) { DebugPrint("%s <- %s\n", Database::name.Get(aId).c_str(), Database::name.Get(aSourceId).c_str()); Renderable::mId = aId; Updatable::SetAction(Updatable::Action(this, &TetherBurn::Update)); Updatable::Activate(); Renderable::SetAction(Renderable::Action(this, &TetherBurn::Render)); Renderable::Show(); Entity *entity = Database::entity.Get(aId); Entity *source = Database::entity.Get(aSourceId); mSourcePos = source->GetPosition(); mEnd = mStart + int(entity->GetPosition().Dist(mSourcePos) * sim_rate / 240.0f); }
Status RangeBehavior::Execute(void) { // get target const TargetData &targetdata = Database::targetdata.Get(mId); // get target entity Entity *targetEntity = Database::entity.Get(targetdata.mTarget); if (!targetEntity) return runningTask; // get owner entity Entity *entity = Database::entity.Get(mId); // get range behavior templates const CloseBehaviorTemplate &closebehavior = Database::closebehaviortemplate.Get(mId); const FarBehaviorTemplate &farbehavior = Database::farbehaviortemplate.Get(mId); // get direction and distance to target Vector2 dir = targetEntity->GetPosition() - entity->GetPosition(); float dist = dir.Length(); dir /= dist; // get target relative speed Vector2 vel = targetEntity->GetVelocity() - entity->GetVelocity(); float speed = vel.Dot(dir); // apply close-repel force float repel = (dist - closebehavior.mRange) * closebehavior.mScaleDist + speed * closebehavior.mScaleSpeed; if (repel < 0.0f) { mController->mMove += dir * repel; } // apply far-attract force float attract = (dist - farbehavior.mRange) * farbehavior.mScaleDist + speed * farbehavior.mScaleSpeed; if (attract > 0.0f) { mController->mMove += dir * attract; } return runningTask; }
// .GetDistance(ent, ent) - Returns distance between GetPosition() points of both entities. Error if either entity is invalid. int entity_GetDistance(lua_State* ls) { DEBUGOUT("entity_GetDistance"); luaCountArgs(ls, 2); Entity* e = _getReferencedEntity(ls); Entity* e2 = _getReferencedEntity(ls, 2); lua_pushnumber( ls, getDistance(e->GetPosition(), e2->GetPosition()) ); return 1; }
// x, y = .GetPosition(entity) int entity_GetPosition(lua_State* ls) { DEBUGOUT("entity_GetPosition"); luaCountArgs(ls, 1); Entity* e = _getReferencedEntity(ls); point2d p = e->GetPosition(); lua_pushnumber(ls, p.x); lua_pushnumber(ls, p.y); return 2; }
//Adds an entity to the level from its XML file. void Level::AddEntity(rapidxml::xml_node<>* root) { if(!root) throw "Entity XML missing"; Entity* entity = new Entity(root, textureManager); int x = entity->GetPosition().x; int y = entity->GetPosition().y; Tile* occupied = map[x][y]; if(!occupied) throw "Entity placed on non-tile"; occupied->SetOccupant(entity); entities.resize(++entCount); entities[entCount - 1] = entity; }
bool Octree::Collides( const Entity &e ) const { glm::vec3 p = e.GetPosition(); const Octree* node = GetNodeContaining( p.x, p.y, p.z); for( auto& obj : node->objects ) { return obj->Collide( e ); } /* Entity* obj = node->FindNearest(p.x, p.y, p.z); if (obj != nullptr) { return obj->collider->Collide( ( const Collider & ) e.collider ); } */ return false; }
bool D3D10Renderer::Render() { D3DXMATRIX viewMatrix; BeginScene(0.1f, 0.1f, 0.1f, 1.0f); m_camera->Render(); m_camera->GetViewMatrix(viewMatrix); std::set<IntrusivePtr<Entity> > entitySet = m_scene->GetEntitySet(); Entity* ent = 0; POSITION modelPosition; DX10Model* model; for(std::set<IntrusivePtr<Entity> > ::const_iterator it = entitySet.begin(); it != entitySet.end(); ++it) { ent = it->GetPtr(); modelPosition = ent->GetPosition(); D3DXMatrixTranslation(&m_worldMatrix, modelPosition.x, modelPosition.y, modelPosition.z); model = m_modelFactory->GetModelByName(ent->GetName()); model->Render(m_device); m_colorShader->Render(m_device, model->GetIndexCount(), m_worldMatrix, viewMatrix, m_projectionMatrix); } EndScene(); return true; }
void Pickup::Kill(float aFraction) { const PickupTemplate &pickup = Database::pickuptemplate.Get(mId); // if spawning on pickup... if (pickup.mSpawnOnCollect) { // get the entity Entity *entity = Database::entity.Get(mId); if (entity) { // spawn template at entity location unsigned int spawnId = Database::Instantiate(pickup.mSpawnOnCollect, Database::owner.Get(mId), mId, entity->GetAngle(), entity->GetPosition(), entity->GetVelocity(), entity->GetOmega()); if (Renderable *renderable = Database::renderable.Get(spawnId)) renderable->SetFraction(aFraction); } } // if switching on pickup... if (pickup.mSwitchOnCollect) { // change dynamic type unsigned int aId = mId; Database::Switch(aId, pickup.mSwitchOnCollect); if (Renderable *renderable = Database::renderable.Get(aId)) renderable->SetFraction(aFraction); } else { // delete the entity Database::Delete(mId); } return; }
// 更新频道注册、更新区域中的实体集合 void SceneRegionManager::Update() { EntitySceneRegionCollectUMapType::iterator it = m_umapEntityRegions.begin(); EntitySceneRegionCollectUMapType::iterator it_end = m_umapEntityRegions.end(); // 根据实体位置更新,以及所属的矩形指针 for (;it!=it_end;++it) { Entity* pEntity = it->first; SceneRegion* pLastBelongRegion = it->second.first; set<SceneRegion*>& rOldCollistionRegions = it->second.second; // 检查所属区域指向是否改变,若改变则更新 if (!pLastBelongRegion->InScope(pEntity->GetPosition())) { // 添加到新区域中 if (SceneRegion* pNewBelongRegion = GetBelongRegion(pEntity->GetPosition())) { // 从旧区域中删除 pLastBelongRegion->DelEntity(*pEntity); std::cout << "[SceneRegion]Entity Leave :" << pEntity->ID() << "xy(" << pLastBelongRegion->m_sScope.sTopLeft.nX << "," << pLastBelongRegion->m_sScope.sTopLeft.nY << "),(" << pLastBelongRegion->m_sScope.sBottomRight.nX << "," << pLastBelongRegion->m_sScope.sBottomRight.nY << ")" << std::endl; // 加入新的所属区域 pNewBelongRegion->AddEntity(*pEntity); std::cout << "[SceneRegion]Entiry Enter:" << pEntity->ID() << "xy(" << pNewBelongRegion->m_sScope.sTopLeft.nX << "," << pNewBelongRegion->m_sScope.sTopLeft.nY << "),(" << pNewBelongRegion->m_sScope.sBottomRight.nX << "," << pNewBelongRegion->m_sScope.sBottomRight.nY << ")" << std::endl; // 离开相关区域操作 { // 计算相交区域 set<SceneRegion*> newCollisionRegions; GetCollisionRegion(pEntity->OutViewRange(), newCollisionRegions); static vector<SceneRegion*> vecLeaveRegions; vecLeaveRegions.resize(rOldCollistionRegions.size()); vector<SceneRegion*>::iterator retEndPosTmp; retEndPosTmp = set_difference(rOldCollistionRegions.begin(), rOldCollistionRegions.end(), newCollisionRegions.begin(), newCollisionRegions.end(), vecLeaveRegions.begin()); for (vector<SceneRegion*>::iterator iter = vecLeaveRegions.begin(); iter != retEndPosTmp; ++iter) { (*iter)->CancelReceiveChannels(*pEntity); } } {// 求新增区域 // 计算相交区域 set<SceneRegion*> newCollisionRegions; GetCollisionRegion(pEntity->OutViewRange(), newCollisionRegions); static vector<SceneRegion*> vecNewRegions; vecNewRegions.resize(newCollisionRegions.size()); vector<SceneRegion*>::iterator retEndPosTmp; retEndPosTmp = set_difference(newCollisionRegions.begin(), newCollisionRegions.end(), rOldCollistionRegions.begin(), rOldCollistionRegions.end(), vecNewRegions.begin()); for (vector<SceneRegion*>::iterator iter = vecNewRegions.begin(); iter != retEndPosTmp; ++iter) { (*iter)->RegistReceiveChannels(*pEntity); } // 更新管理信息 it->second.first = pNewBelongRegion; it->second.second = newCollisionRegions; } } } } }
void Capturable::Capture(void) { const CapturableTemplate &capturable = Database::capturabletemplate.Get(mId); // if spawning on capture... if (capturable.mSpawnOnCapture) { // get the entity Entity *entity = Database::entity.Get(mId); if (entity) { // instantiate the template Database::Instantiate(capturable.mSpawnOnCapture, Database::owner.Get(mId), mId, entity->GetAngle(), entity->GetPosition(), entity->GetVelocity(), entity->GetOmega()); } } // if switching on capture... if (capturable.mSwitchOnCapture) { // change dynamic type Database::Switch(mId, capturable.mSwitchOnCapture); } else { // delete the entity Database::Delete(mId); } }
// Gunner Update void Gunner::Update(float aStep) { // get the owner unsigned int aOwnerId = Database::backlink.Get(mId); // get the owner entity Entity *owner = Database::entity.Get(aOwnerId); // if the owner does not exist... if (!owner) { // self-destruct Database::Delete(mId); return; } // gunner template const GunnerTemplate &gunner = Database::gunnertemplate.Get(mId); // get owner movement const Vector2 &posP = owner->GetPosition(); #ifdef GUNNER_TRACK_DEQUE const Vector2 &posL0 = mTrackPos.back(); #else const Vector2 &posL0 = mTrackPos[mTrackLast]; #endif float movement = posP.DistSq(posL0); // if the owner has moved... if (movement > FLT_EPSILON) { #ifdef GUNNER_TRACK_DEQUE // get the last segment const Vector2 &posL1 = mTrackPos[mTrackPos.size()-2]; float lastsegment = posL0.Dist(posL1); // if the last segment isn't long enough... if (lastsegment < GUNNER_TRACK_GRANULARITY) { // replace the last segment mTrackPos.pop_back(); mTrackLength -= lastsegment; } // add new position mTrackPos.push_back(posP); mTrackLength += posP.Dist(mTrackPos[mTrackPos.size()-2]); #else // get the last segment size_t mTrackPrev = (mTrackLast > 0) ? (mTrackLast - 1) : (mTrackCount - 1); const Vector2 &posL1 = mTrackPos[mTrackPrev]; float lastsegment = posL0.Dist(posL1); // if the last segment is long enough... if (lastsegment >= GUNNER_TRACK_GRANULARITY) { // start a new segment mTrackPrev = mTrackLast; mTrackLast = (mTrackLast < mTrackCount - 1) ? (mTrackLast + 1) : 0; } else { // replace the last segment mTrackLength -= lastsegment; } // add new position mTrackPos[mTrackLast] = posP; mTrackLength += posP.Dist(mTrackPos[mTrackPrev]); #endif // while there is excess track length... while (mTrackLength > gunner.mFollowLength) { // get the excess length float excess = mTrackLength - gunner.mFollowLength; // get the first segment length #ifdef GUNNER_TRACK_DEQUE Vector2 &pos0 = mTrackPos[0]; const Vector2 &pos1 = mTrackPos[1]; #else size_t mTrackNext = (mTrackFirst < mTrackCount - 1) ? (mTrackFirst + 1) : 0; Vector2 &pos0 = mTrackPos[mTrackFirst]; const Vector2 &pos1 = mTrackPos[mTrackNext]; #endif float firstsegment = pos0.Dist(pos1); // if the segment is longer than the excess... if (firstsegment > excess) { // shorten the segment pos0 += excess / firstsegment * (pos1 - pos0); mTrackLength -= excess; break; } else { // remove the segment mTrackLength -= firstsegment; #ifdef GUNNER_TRACK_DEQUE mTrackPos.pop_front(); #else mTrackFirst = mTrackNext; #endif } } } // move to new position Entity *entity = Database::entity.Get(mId); entity->Step(); #ifdef GUNNER_TRACK_DEQUE entity->SetPosition(mTrackPos.front()); #else entity->SetPosition(mTrackPos[mTrackFirst]); #endif entity->SetAngle(owner->GetAngle()); entity->SetVelocity(owner->GetVelocity()); // <-- HACK! entity->SetOmega(owner->GetOmega()); }
// cancel void Cancelable::Cancel(unsigned int aId, unsigned int aSourceId) { const CancelableTemplate &cancelable = Database::cancelabletemplate.Get(mId); // set owner to source damage owner unsigned int aOwnerId = Database::owner.Get(aSourceId); Database::owner.Put(mId, aOwnerId); // bump the hit combo counter int &combo = Database::hitcombo.Open(mId); combo = std::max<int>(combo, Database::hitcombo.Get(aSourceId) + 1); Database::hitcombo.Close(mId); if (cancelable.mBacklash) { for (unsigned int creator = Database::creator.Get(aId); creator != 0; creator = Database::backlink.Get(creator)) { if (Damagable *damagable = Database::damagable.Get(creator)) { Damagable::DeathSignal &signal = Database::deathsignal.Open(creator); signal.Disconnect(this, &Cancelable::CreatorDeath); Database::deathsignal.Close(creator); // damagable->Damage(mId, cancelable.mBacklash); // burn tether from the cancelable to the creator new TetherBurn(creator, mId, aOwnerId, cancelable.mBacklash, combo); break; } } } // if spawning on cancelable... if (cancelable.mSpawn) { // get the entity Entity *entity = Database::entity.Get(mId); if (entity) { // spawn template at the entity location Database::Instantiate(cancelable.mSpawn, Database::owner.Get(mId), mId, entity->GetAngle(), entity->GetPosition(), entity->GetVelocity(), entity->GetOmega()); } } // if switching on cancelable... if (cancelable.mSwitch) { // get the entity Entity *entity = Database::entity.Get(mId); if (entity) { // change dynamic type Database::Switch(mId, cancelable.mSwitch); } } else { // delete the entity Database::Delete(mId); } }
void Explosion::Update(float aStep) { // get explosion template properties const ExplosionTemplate &explosion = Database::explosiontemplate.Get(mId); // set up query callback ExplosionQueryCallback callback; callback.mId = mId; callback.mExplosion = explosion; // default radius and damage callback.mCurRadius[0] = 0.0f; callback.mCurRadius[1] = 0.0f; callback.mCurDamage[0] = 0.0f; callback.mCurDamage[1] = 0.0f; // evaluate properties if (!explosion.mRadius.empty()) { //int index = 0; //ApplyInterpolator(callback.mCurRadius, 2, mRadius[0], reinterpret_cast<const float * __restrict>(&mRadius[1]), explosion.mLifeSpan - mLife, index); EntityContext context(&explosion.mRadius[0], explosion.mRadius.size(), explosion.mLifeSpan - mLife, mId); __m128 value = Expression::Evaluate<__m128>(context); memcpy(callback.mCurRadius, &value, sizeof(callback.mCurRadius)); } if (!explosion.mDamage.empty()) { //int index = 0; //ApplyInterpolator(callback.mCurDamage, 2, mDamage[0], reinterpret_cast<const float * __restrict>(&mDamage[1]), explosion.mLifeSpan - mLife, index); EntityContext context(&explosion.mDamage[0], explosion.mDamage.size(), explosion.mLifeSpan - mLife, mId); __m128 value = Expression::Evaluate<__m128>(context); memcpy(callback.mCurDamage, &value, sizeof(callback.mCurDamage)); } // if applying damage... if ((callback.mCurDamage[0] != 0.0f) || (callback.mCurDamage[1] != 0.0f)) { // if applying damage over time... if (explosion.mLifeSpan > 0.0f) { // scale by time step callback.mCurDamage[0] *= aStep; callback.mCurDamage[1] *= aStep; } // get parent entity Entity *entity = Database::entity.Get(mId); // world-to-local transform callback.mTransform = entity->GetTransform().Inverse(); // get shapes within the radius Collidable::QueryRadius(entity->GetPosition(), callback.mCurRadius[1], explosion.mFilter, Collidable::QueryRadiusDelegate(&callback, &ExplosionQueryCallback::Report)); } // advance life timer mLife -= aStep; // if expired... if (mLife <= 0) { // deactivate Deactivate(); } }
//Returns true if the chessboard distance of the entity is less than or equal to <+range> bool Creature::IsInRange(const Entity& entity, int range) { int dx, dy; entity.GetPosition(dx, dy); return (std::abs(dx - x) <= range && std::abs(dy - y) <= range); }