Example #1
0
	virtual CFixedVector3D GetPreviousPosition() 
	{ 
		if (!m_InWorld) 
		{ 
			LOGERROR(L"CCmpPosition::GetPreviousPosition called on entity when IsInWorld is false"); 
			return CFixedVector3D(); 
		} 

		entity_pos_t baseY; 
		if (m_RelativeToGround) 
		{ 
			CmpPtr<ICmpTerrain> cmpTerrain(GetSimContext(), SYSTEM_ENTITY); 
			if (cmpTerrain) 
				baseY = cmpTerrain->GetGroundLevel(m_PrevX, m_PrevZ); 

			if (m_Floating) 
			{ 
				CmpPtr<ICmpWaterManager> cmpWaterMan(GetSimContext(), SYSTEM_ENTITY); 
				if (cmpWaterMan) 
					baseY = std::max(baseY, cmpWaterMan->GetWaterLevel(m_PrevX, m_PrevZ)); 
			} 
		} 

		return CFixedVector3D(m_PrevX, baseY + m_YOffset, m_PrevZ); 
	} 
Example #2
0
	virtual std::vector<entity_id_t> GetConstructionCollisions()
	{
		std::vector<entity_id_t> ret;

		CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), GetEntityId());
		if (cmpPosition.null())
			return ret; // error

		if (!cmpPosition->IsInWorld())
			return ret; // no obstruction

		CFixedVector2D pos = cmpPosition->GetPosition2D();

		CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
		if (cmpObstructionManager.null())
			return ret; // error

		// Ignore collisions with self, or with non-construction-blocking obstructions
		SkipTagFlagsObstructionFilter filter(m_Tag, ICmpObstructionManager::FLAG_BLOCK_CONSTRUCTION);

		if (m_Type == STATIC)
			cmpObstructionManager->TestStaticShape(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, &ret);
		else
			cmpObstructionManager->TestUnitShape(filter, pos.X, pos.Y, m_Size0, &ret);

		return ret;
	}
Example #3
0
	/*
	 * Must be called whenever the size of m_Sprites changes,
	 * to determine whether we need to respond to rendering messages.
	 */
	void UpdateMessageSubscriptions()
	{
		bool needRender = !m_Sprites.empty();

		GetSimContext().GetComponentManager().DynamicSubscriptionNonsync(MT_Interpolate, this, needRender);
		GetSimContext().GetComponentManager().DynamicSubscriptionNonsync(MT_RenderSubmit, this, needRender);
	}
Example #4
0
	virtual bool CheckFoundation(std::string className)
	{
		CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), GetEntityId());
		if (cmpPosition.null())
			return false; // error

		if (!cmpPosition->IsInWorld())
			return false; // no obstruction

		CFixedVector2D pos = cmpPosition->GetPosition2D();

		CmpPtr<ICmpPathfinder> cmpPathfinder(GetSimContext(), SYSTEM_ENTITY);
		if (cmpPathfinder.null())
			return false; // error

		// Get passability class
		ICmpPathfinder::pass_class_t passClass = cmpPathfinder->GetPassabilityClass(className);

		// Ignore collisions with self, or with non-foundation-blocking obstructions
		SkipTagFlagsObstructionFilter filter(m_Tag, ICmpObstructionManager::FLAG_BLOCK_FOUNDATION);

		if (m_Type == STATIC)
			return cmpPathfinder->CheckBuildingPlacement(filter, pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, GetEntityId(), passClass);
		else
			return cmpPathfinder->CheckUnitPlacement(filter, pos.X, pos.Y, m_Size0, passClass);
	}
Example #5
0
	void ConstructShape(float frameOffset)
	{
		CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), GetEntityId());
		if (!cmpPosition)
			return;

		if (!cmpPosition->IsInWorld())
			return;

		float x, z, rotY;
		cmpPosition->GetInterpolatedPosition2D(frameOffset, x, z, rotY);

		CmpPtr<ICmpFootprint> cmpFootprint(GetSimContext(), GetEntityId());
		if (!cmpFootprint)
		{
			// Default (this probably shouldn't happen) - just render an arbitrary-sized circle
			SimRender::ConstructCircleOnGround(GetSimContext(), x, z, 2.f, m_Overlay, cmpPosition->IsFloating());
		}
		else
		{
			ICmpFootprint::EShape shape;
			entity_pos_t size0, size1, height;
			cmpFootprint->GetShape(shape, size0, size1, height);

			if (shape == ICmpFootprint::SQUARE)
				SimRender::ConstructSquareOnGround(GetSimContext(), x, z, size0.ToFloat(), size1.ToFloat(), rotY, m_Overlay, cmpPosition->IsFloating());
			else
				SimRender::ConstructCircleOnGround(GetSimContext(), x, z, size0.ToFloat(), m_Overlay, cmpPosition->IsFloating());
		}
	}
Example #6
0
ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckBuildingPlacement(const IObstructionTestFilter& filter,
	entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w,
	entity_pos_t h, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint)
{
	// Check unit obstruction
	CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
	if (!cmpObstructionManager)
		return ICmpObstruction::FOUNDATION_CHECK_FAIL_ERROR;

	if (cmpObstructionManager->TestStaticShape(filter, x, z, a, w, h, NULL))
		return ICmpObstruction::FOUNDATION_CHECK_FAIL_OBSTRUCTS_FOUNDATION;

	// Test against terrain:

	UpdateGrid();

	ICmpObstructionManager::ObstructionSquare square;
	CmpPtr<ICmpObstruction> cmpObstruction(GetSimContext(), id);
	if (!cmpObstruction || !cmpObstruction->GetObstructionSquare(square))
		return ICmpObstruction::FOUNDATION_CHECK_FAIL_NO_OBSTRUCTION;

	if (onlyCenterPoint)
	{
		u16 i, j;
		NearestTile(x, z, i, j);

		if (IS_TERRAIN_PASSABLE(m_Grid->get(i,j), passClass))
			return ICmpObstruction::FOUNDATION_CHECK_SUCCESS;

		return ICmpObstruction::FOUNDATION_CHECK_FAIL_TERRAIN_CLASS;
	}

	// Expand bounds by 1/sqrt(2) tile (multiply by TERRAIN_TILE_SIZE since we want world coordinates)
	entity_pos_t expand = entity_pos_t::FromInt(2).Sqrt().Multiply(entity_pos_t::FromInt(TERRAIN_TILE_SIZE / 2));
	CFixedVector2D halfSize(square.hw + expand, square.hh + expand);
	CFixedVector2D halfBound = Geometry::GetHalfBoundingBox(square.u, square.v, halfSize);

	u16 i0, j0, i1, j1;
	NearestTile(square.x - halfBound.X, square.z - halfBound.Y, i0, j0);
	NearestTile(square.x + halfBound.X, square.z + halfBound.Y, i1, j1);
	for (u16 j = j0; j <= j1; ++j)
	{
		for (u16 i = i0; i <= i1; ++i)
		{
			entity_pos_t x, z;
			TileCenter(i, j, x, z);
			if (Geometry::PointIsInSquare(CFixedVector2D(x - square.x, z - square.z), square.u, square.v, halfSize)
				&& !IS_TERRAIN_PASSABLE(m_Grid->get(i,j), passClass))
			{
				return ICmpObstruction::FOUNDATION_CHECK_FAIL_TERRAIN_CLASS;
			}
		}
	}

	return ICmpObstruction::FOUNDATION_CHECK_SUCCESS;
}
Example #7
0
	// Check whether the entity is either a settlement or territory influence;
	// ignore any others
	void MakeDirtyIfRelevantEntity(entity_id_t ent)
	{
		CmpPtr<ICmpSettlement> cmpSettlement(GetSimContext(), ent);
		if (cmpSettlement)
			MakeDirty();

		CmpPtr<ICmpTerritoryInfluence> cmpTerritoryInfluence(GetSimContext(), ent);
		if (cmpTerritoryInfluence)
			MakeDirty();
	}
Example #8
0
	virtual void HandleMessage(const CMessage& msg, bool UNUSED(global))
	{
		switch (msg.GetType())
		{
		case MT_PositionChanged:
		{
			if (!m_Active)
				break;

			const CMessagePositionChanged& data = static_cast<const CMessagePositionChanged&> (msg);

			if (!data.inWorld && !m_Tag.valid())
				break; // nothing needs to change

			CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
			if (!cmpObstructionManager)
				break; // error

			if (data.inWorld && m_Tag.valid())
			{
				cmpObstructionManager->MoveShape(m_Tag, data.x, data.z, data.a);
			}
			else if (data.inWorld && !m_Tag.valid())
			{
				// Need to create a new pathfinder shape:
				if (m_Type == STATIC)
					m_Tag = cmpObstructionManager->AddStaticShape(GetEntityId(),
						data.x, data.z, data.a, m_Size0, m_Size1, m_Flags, m_ControlGroup, m_ControlGroup2);
				else
					m_Tag = cmpObstructionManager->AddUnitShape(GetEntityId(),
						data.x, data.z, m_Size0, (flags_t)(m_Flags | (m_Moving ? ICmpObstructionManager::FLAG_MOVING : 0)), m_ControlGroup);
			}
			else if (!data.inWorld && m_Tag.valid())
			{
				cmpObstructionManager->RemoveShape(m_Tag);
				m_Tag = tag_t();
			}
			break;
		}
		case MT_Destroy:
		{
			if (m_Tag.valid())
			{
				CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
				if (!cmpObstructionManager)
					break; // error

				cmpObstructionManager->RemoveShape(m_Tag);
				m_Tag = tag_t();
			}
			break;
		}
		}
	}
Example #9
0
	virtual void Init(const CParamNode& paramNode)
	{
		m_PreviouslyRendered = false;
		m_Unit = NULL;
		m_Visibility = ICmpRangeManager::VIS_HIDDEN;

		m_R = m_G = m_B = fixed::FromInt(1);

		if (!GetSimContext().HasUnitManager())
			return; // do nothing further if graphics are disabled

		// TODO: we should do some fancy animation of under-construction buildings rising from the ground,
		// but for now we'll just use the foundation actor and ignore the normal one
		if (paramNode.GetChild("Foundation").IsOk() && paramNode.GetChild("FoundationActor").IsOk())
			m_ActorName = paramNode.GetChild("FoundationActor").ToString();
		else
			m_ActorName = paramNode.GetChild("Actor").ToString();

		std::set<CStr> selections;
		m_Unit = GetSimContext().GetUnitManager().CreateUnit(m_ActorName, GetActorSeed(), selections);
		if (m_Unit)
		{
			CModelAbstract& model = m_Unit->GetModel();
			if (model.ToCModel())
			{
				u32 modelFlags = 0;

				if (paramNode.GetChild("SilhouetteDisplay").ToBool())
					modelFlags |= MODELFLAG_SILHOUETTE_DISPLAY;

				if (paramNode.GetChild("SilhouetteOccluder").ToBool())
					modelFlags |= MODELFLAG_SILHOUETTE_OCCLUDER;

				CmpPtr<ICmpVision> cmpVision(GetSimContext(), GetEntityId());
				if (cmpVision && cmpVision->GetAlwaysVisible())
					modelFlags |= MODELFLAG_IGNORE_LOS;

				model.ToCModel()->AddFlagsRec(modelFlags);
			}

			// Initialize the model's selection shape descriptor. This currently relies on the component initialization order; the 
			// Footprint component must be initialized before this component (VisualActor) to support the ability to use the footprint
			// shape for the selection box (instead of the default recursive bounding box). See TypeList.h for the order in
			// which components are initialized; if for whatever reason you need to get rid of this dependency, you can always just
			// initialize the selection shape descriptor on-demand.
			InitSelectionShapeDescriptor(model, paramNode);

			m_Unit->SetID(GetEntityId());
		}

		SelectAnimation("idle", false, fixed::FromInt(1), L"");
	}
Example #10
0
	virtual CMatrix3D GetInterpolatedTransform(float frameOffset, bool forceFloating)
	{
		if (!m_InWorld)
		{
			LOGERROR(L"CCmpPosition::GetInterpolatedTransform called on entity when IsInWorld is false");
			CMatrix3D m;
			m.SetIdentity();
			return m;
		}

		float x, z, rotY;
		GetInterpolatedPosition2D(frameOffset, x, z, rotY);

		float baseY = 0;
		if (m_RelativeToGround)
		{
			CmpPtr<ICmpTerrain> cmpTerrain(GetSimContext(), SYSTEM_ENTITY);
			if (cmpTerrain)
				baseY = cmpTerrain->GetExactGroundLevel(x, z);

			if (m_Floating || forceFloating)
			{
				CmpPtr<ICmpWaterManager> cmpWaterManager(GetSimContext(), SYSTEM_ENTITY);
				if (cmpWaterManager)
					baseY = std::max(baseY, cmpWaterManager->GetExactWaterLevel(x, z));
			}
		}

		float y = baseY + m_YOffset.ToFloat();

		// TODO: do something with m_AnchorType

		CMatrix3D m;
		CMatrix3D mXZ;
		float Cos = cosf(rotY);
		float Sin = sinf(rotY);

		m.SetIdentity();
		m._11 = -Cos;
		m._13 = -Sin;
		m._31 = Sin;
		m._33 = -Cos;

		mXZ.SetIdentity();
		mXZ.SetXRotation(m_RotX.ToFloat());
		mXZ.RotateZ(m_RotZ.ToFloat());
		// TODO: is this all done in the correct order?
		mXZ = m * mXZ;
		mXZ.Translate(CVector3D(x, y, z));

		return mXZ;
	}
Example #11
0
void CCmpPathfinder::ComputeTerrainPassabilityGrid(const Grid<u16>& shoreGrid)
{
	PROFILE3("terrain passability");

	CmpPtr<ICmpWaterManager> cmpWaterManager(GetSimContext(), SYSTEM_ENTITY);

	CTerrain& terrain = GetSimContext().GetTerrain();

	// Compute initial terrain-dependent passability
	for (int j = 0; j < m_MapSize * Pathfinding::NAVCELLS_PER_TILE; ++j)
	{
		for (int i = 0; i < m_MapSize * Pathfinding::NAVCELLS_PER_TILE; ++i)
		{
			// World-space coordinates for this navcell
			fixed x, z;
			Pathfinding::NavcellCenter(i, j, x, z);

			// Terrain-tile coordinates for this navcell
			int itile = i / Pathfinding::NAVCELLS_PER_TILE;
			int jtile = j / Pathfinding::NAVCELLS_PER_TILE;

			// Gather all the data potentially needed to determine passability:

			fixed height = terrain.GetExactGroundLevelFixed(x, z);

			fixed water;
			if (cmpWaterManager)
				water = cmpWaterManager->GetWaterLevel(x, z);

			fixed depth = water - height;

			//fixed slope = terrain.GetExactSlopeFixed(x, z);
			// Exact slopes give kind of weird output, so just use rough tile-based slopes
			fixed slope = terrain.GetSlopeFixed(itile, jtile);

			// Get world-space coordinates from shoreGrid (which uses terrain tiles)
			fixed shoredist = fixed::FromInt(shoreGrid.get(itile, jtile)).MultiplyClamp(TERRAIN_TILE_SIZE);

			// Compute the passability for every class for this cell:

			NavcellData t = 0;
			for (PathfinderPassability& passability : m_PassClasses)
			{
				if (!passability.IsPassable(depth, slope, shoredist))
					t |= passability.m_Mask;
			}

			m_Grid->set(i, j, t);
		}
	}
}
Example #12
0
    virtual void PlaySoundGroup(std::wstring name, entity_id_t source)
    {
#if CONFIG2_AUDIO
        // Make sure the sound group is loaded
        CSoundGroup* group;
        if (m_SoundGroups.find(name) == m_SoundGroups.end())
        {
            group = new CSoundGroup();
            if (!group->LoadSoundGroup(L"audio/" + name))
            {
                LOGERROR(L"Failed to load sound group '%ls'", name.c_str());
                delete group;
                group = NULL;
            }
            // Cache the sound group (or the null, if it failed)
            m_SoundGroups[name] = group;
        }
        else
        {
            group = m_SoundGroups[name];
        }

        // Failed to load group -> do nothing
        if (!group)
            return;

        // Only play the sound if the entity is visible
        CmpPtr<ICmpRangeManager> cmpRangeManager(GetSimContext(), SYSTEM_ENTITY);
        ICmpRangeManager::ELosVisibility vis = cmpRangeManager->GetLosVisibility(source, GetSimContext().GetCurrentDisplayedPlayer());

        if (vis == ICmpRangeManager::VIS_VISIBLE)
        {
            // Find the source's position, if possible
            // (TODO: we should do something more sensible if there's no position available)
            CVector3D sourcePos(0, 0, 0);
            if (source != INVALID_ENTITY)
            {
                CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), source);
                if (cmpPosition && cmpPosition->IsInWorld())
                    sourcePos = CVector3D(cmpPosition->GetPosition());
            }

            group->PlayNext(sourcePos);
        }
#else // !CONFIG2_AUDIO
        UNUSED2(name);
        UNUSED2(source);
#endif // !CONFIG2_AUDIO
    }
Example #13
0
	virtual void PostNetworkCommand(JS::HandleValue cmd1)
	{
		JSContext* cx = GetSimContext().GetScriptInterface().GetContext();
		JSAutoRequest rq(cx);
		
		// TODO: This is a workaround because we need to pass a MutableHandle to StringifyJSON.
		JS::RootedValue cmd(cx, cmd1.get());

		PROFILE2_EVENT("post net command");
		PROFILE2_ATTR("command: %s", GetSimContext().GetScriptInterface().StringifyJSON(&cmd, false).c_str());

		// TODO: would be nicer to not use globals
		if (g_Game && g_Game->GetTurnManager())
			g_Game->GetTurnManager()->PostCommand(cmd);
	}
Example #14
0
	virtual void HandleMessage(const CMessage& msg, bool UNUSED(global))
	{
		switch (msg.GetType())
		{
		case MT_PositionChanged:
		{
			const CMessagePositionChanged& data = static_cast<const CMessagePositionChanged&> (msg);

			if (data.inWorld)
			{
				m_Active = true;
				m_X = data.x;
				m_Z = data.z;
			}
			else
			{
				m_Active = false;
			}

			break;
		}
		case MT_OwnershipChanged:
		{
			if (!m_UsePlayerColour)
				break;

			const CMessageOwnershipChanged& msgData = static_cast<const CMessageOwnershipChanged&> (msg);

			// If there's no new owner (e.g. the unit is dying) then don't try updating the colour
			if (msgData.to == -1)
				break;

			// Find the new player's colour
			CmpPtr<ICmpPlayerManager> cmpPlayerManager(GetSimContext(), SYSTEM_ENTITY);
			if (cmpPlayerManager.null())
				break;
			CmpPtr<ICmpPlayer> cmpPlayer(GetSimContext(), cmpPlayerManager->GetPlayerByID(msgData.to));
			if (cmpPlayer.null())
				break;
			CColor colour = cmpPlayer->GetColour();
			m_R = (int)(colour.r*255.0);
			m_G = (int)(colour.g*255.0);
			m_B = (int)(colour.b*255.0);

			break;
		}
		}
	}
Example #15
0
	virtual void PushLocalCommand(player_id_t player, JS::HandleValue cmd)
	{
		JSContext* cx = GetSimContext().GetScriptInterface().GetContext();
		JSAutoRequest rq(cx);

		m_LocalQueue.emplace_back(SimulationCommand(player, cx, cmd));
	}
Example #16
0
	virtual void UpdateTurretPosition()
	{
		if (m_TurretParent == INVALID_ENTITY)
			return;
		CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent);
		if (!cmpPosition)
		{
			LOGERROR("Turret with parent without position component");
			return;
		}
		if (!cmpPosition->IsInWorld())
			MoveOutOfWorld();
		else
		{
			CFixedVector2D rotatedPosition = CFixedVector2D(m_TurretPosition.X, m_TurretPosition.Z);
			rotatedPosition = rotatedPosition.Rotate(cmpPosition->GetRotation().Y);
			CFixedVector2D rootPosition = cmpPosition->GetPosition2D();
			entity_pos_t x = rootPosition.X + rotatedPosition.X;
			entity_pos_t z = rootPosition.Y + rotatedPosition.Y;
			if (!m_InWorld || m_X != x || m_Z != z)
				MoveTo(x, z);
			entity_pos_t y = cmpPosition->GetHeightOffset() + m_TurretPosition.Y;
			if (!m_InWorld || GetHeightOffset() != y)
				SetHeightOffset(y);
			m_InWorld = true;
		}
	}
Example #17
0
	virtual void HandleMessage(const CMessage& msg, bool UNUSED(global))
	{
		switch (msg.GetType())
		{
			case MT_Interpolate:
			{
				const CMessageInterpolate& msgData = static_cast<const CMessageInterpolate&> (msg);
				if (CRenderer::IsInitialised())
					g_Renderer.GetWaterManager()->m_WaterTexTimer += msgData.deltaSimTime;
				break;
			}
			case MT_TerrainChanged:
			{
				// Tell the renderer to redraw the map.
				if (CRenderer::IsInitialised())
				{
					const CMessageTerrainChanged& msgData = static_cast<const CMessageTerrainChanged&> (msg);
					g_Renderer.GetWaterManager()->m_NeedInfoUpdate = true;
					g_Renderer.GetWaterManager()->m_updatei0 = msgData.i0;
					g_Renderer.GetWaterManager()->m_updatej0 = msgData.j0;
					g_Renderer.GetWaterManager()->m_updatei1 = msgData.i1;
					g_Renderer.GetWaterManager()->m_updatej1 = msgData.j1;
					
					GetSimContext().GetTerrain().MakeDirty(msgData.i0,msgData.j0,msgData.i1,msgData.j1,RENDERDATA_UPDATE_VERTICES);
				}
				break;
			}
		}
	}
Example #18
0
	void RenderSubmit(SceneCollector& collector)
	{
		// (This is only called if a > 0)
		collector.Submit(&m_Overlay);

		if (ICmpSelectable::ms_EnableDebugOverlays)
		{
			// allocate debug overlays on-demand
			if (!m_DebugBoundingBoxOverlay) m_DebugBoundingBoxOverlay = new SOverlayLine;
			if (!m_DebugSelectionBoxOverlay) m_DebugSelectionBoxOverlay = new SOverlayLine;

			CmpPtr<ICmpVisual> cmpVisual(GetSimContext(), GetEntityId()); 
			if (cmpVisual) 
			{
				SimRender::ConstructBoxOutline(cmpVisual->GetBounds(), *m_DebugBoundingBoxOverlay);
				m_DebugBoundingBoxOverlay->m_Thickness = 2; 
				m_DebugBoundingBoxOverlay->m_Color = CColor(1.f, 0.f, 0.f, 1.f);

				SimRender::ConstructBoxOutline(cmpVisual->GetSelectionBox(), *m_DebugSelectionBoxOverlay);
				m_DebugSelectionBoxOverlay->m_Thickness = 2;
				m_DebugSelectionBoxOverlay->m_Color = CColor(0.f, 1.f, 0.f, 1.f);

				collector.Submit(m_DebugBoundingBoxOverlay);
				collector.Submit(m_DebugSelectionBoxOverlay);
			}
		}
		else
		{
			// reclaim debug overlay line memory when no longer debugging (and make sure to set to zero after deletion)
			if (m_DebugBoundingBoxOverlay) SAFE_DELETE(m_DebugBoundingBoxOverlay);
			if (m_DebugSelectionBoxOverlay) SAFE_DELETE(m_DebugSelectionBoxOverlay);
		}
	}
Example #19
0
bool CCmpPathfinder::CheckUnitPlacement(const IObstructionTestFilter& filter,
	entity_pos_t x, entity_pos_t z, entity_pos_t r,	pass_class_t passClass)
{
	// Check unit obstruction
	CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
	if (cmpObstructionManager.null())
		return false;

	if (cmpObstructionManager->TestUnitShape(filter, x, z, r, NULL))
		return false;

	// Test against terrain:

	UpdateGrid();

	u16 i0, j0, i1, j1;
	NearestTile(x - r, z - r, i0, j0);
	NearestTile(x + r, z + r, i1, j1);
	for (u16 j = j0; j <= j1; ++j)
	{
		for (u16 i = i0; i <= i1; ++i)
		{
			if (!IS_TERRAIN_PASSABLE(m_Grid->get(i,j), passClass))
			{
				return false;
			}
		}
	}
	return true;
}
Example #20
0
	virtual void SetWaterLevel(entity_pos_t h)
	{
		m_WaterHeight = h;

		// Tell the terrain it'll need to recompute its cached render data
		GetSimContext().GetTerrain().MakeDirty(RENDERDATA_UPDATE_VERTICES);
	}
Example #21
0
	virtual void Deserialize(const CParamNode& paramNode, IDeserializer& deserialize)
	{
		Init(paramNode);

		u32 oldSeed = GetActorSeed();

		SerializeCommon(deserialize);

		// If we serialized a different seed, reload actor
		if (oldSeed != GetActorSeed())
			ReloadActor();

		fixed repeattime = m_AnimSyncRepeatTime; // save because SelectAnimation overwrites it

		if (m_AnimRunThreshold.IsZero())
			SelectAnimation(m_AnimName, m_AnimOnce, m_AnimSpeed, m_SoundGroup);
		else
			SelectMovementAnimation(m_AnimRunThreshold);

		SetAnimationSyncRepeat(repeattime);

		if (m_Unit)
		{
			CmpPtr<ICmpOwnership> cmpOwnership(GetSimContext(), GetEntityId());
			if (cmpOwnership)
				m_Unit->GetModel().SetPlayerID(cmpOwnership->GetOwner());
		}
	}
Example #22
0
	virtual void SetActive(bool active)
	{
		if (active && !m_Active)
		{
			m_Active = true;

			// Construct the obstruction shape

			CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
			if (!cmpObstructionManager)
				return; // error

			CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), GetEntityId());
			if (!cmpPosition)
				return; // error

			if (!cmpPosition->IsInWorld())
				return; // don't need an obstruction

			// TODO: code duplication from message handlers
			CFixedVector2D pos = cmpPosition->GetPosition2D();
			if (m_Type == STATIC)
				m_Tag = cmpObstructionManager->AddStaticShape(GetEntityId(),
					pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1, m_Flags, m_ControlGroup, m_ControlGroup2);
			else
				m_Tag = cmpObstructionManager->AddUnitShape(GetEntityId(),
					pos.X, pos.Y, m_Size0, (flags_t)(m_Flags | (m_Moving ? ICmpObstructionManager::FLAG_MOVING : 0)), m_ControlGroup);
		}
		else if (!active && m_Active)
		{
			m_Active = false;

			// Delete the obstruction shape

			// TODO: code duplication from message handlers
			if (m_Tag.valid())
			{
				CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
				if (!cmpObstructionManager)
					return; // error

				cmpObstructionManager->RemoveShape(m_Tag);
				m_Tag = tag_t();
			}
		}
		// else we didn't change the active status
	}
Example #23
0
	virtual void Deinit()
	{
		if (m_Unit)
		{
			GetSimContext().GetUnitManager().DeleteUnit(m_Unit);
			m_Unit = NULL;
		}
	}
Example #24
0
    virtual void Init(const CParamNode& UNUSED(paramNode))
    {
        m_DisableValidation = false;

        m_Validator.LoadGrammar(GetSimContext().GetComponentManager().GenerateSchema());
        // TODO: handle errors loading the grammar here?
        // TODO: support hotloading changes to the grammar
    }
Example #25
0
	virtual void HandleMessage(const CMessage& msg, bool UNUSED(global))
	{
		switch (msg.GetType())
		{
		case MT_OwnershipChanged:
		{
			const CMessageOwnershipChanged& msgData = static_cast<const CMessageOwnershipChanged&> (msg);
			MakeDirtyIfRelevantEntity(msgData.entity);
			break;
		}
		case MT_PositionChanged:
		{
			const CMessagePositionChanged& msgData = static_cast<const CMessagePositionChanged&> (msg);
			MakeDirtyIfRelevantEntity(msgData.entity);
			break;
		}
		case MT_ValueModification:
		{
			const CMessageValueModification& msgData = static_cast<const CMessageValueModification&> (msg);
			if (msgData.component == L"TerritoryInfluence")
				MakeDirty();
			break;
		}
		case MT_ObstructionMapShapeChanged:
		case MT_TerrainChanged:
		case MT_WaterChanged:
		{
			// also recalculate the cost grid to support atlas changes
			SAFE_DELETE(m_CostGrid);
			MakeDirty();
			break;
		}
		case MT_Update:
		{
			if (m_TriggerEvent)
			{
				m_TriggerEvent = false;
				CMessageTerritoriesChanged msg;
				GetSimContext().GetComponentManager().BroadcastMessage(msg);
			}
			break;
		}
		case MT_Interpolate:
		{
			const CMessageInterpolate& msgData = static_cast<const CMessageInterpolate&> (msg);
			Interpolate(msgData.deltaSimTime, msgData.offset);
			break;
		}
		case MT_RenderSubmit:
		{
			const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg);
			RenderSubmit(msgData.collector);
			break;
		}
		}
	}
Example #26
0
	virtual CMatrix3D GetInterpolatedTransform(float frameOffset, bool forceFloating)
	{
		if (!m_InWorld)
		{
			LOGERROR(L"CCmpPosition::GetInterpolatedTransform called on entity when IsInWorld is false");
			CMatrix3D m;
			m.SetIdentity();
			return m;
		}

		float x, z, rotY;
		GetInterpolatedPosition2D(frameOffset, x, z, rotY);

		float baseY = 0;
		if (m_RelativeToGround)
		{
			CmpPtr<ICmpTerrain> cmpTerrain(GetSimContext(), SYSTEM_ENTITY);
			if (cmpTerrain)
				baseY = cmpTerrain->GetExactGroundLevel(x, z);

			if (m_Floating || forceFloating)
			{
				CmpPtr<ICmpWaterManager> cmpWaterManager(GetSimContext(), SYSTEM_ENTITY);
				if (cmpWaterManager)
					baseY = std::max(baseY, cmpWaterManager->GetExactWaterLevel(x, z));
			}
		}

		float y = baseY + m_YOffset.ToFloat();

		CMatrix3D m;
		
		// linear interpolation is good enough (for RotX/Z). 
		// As you always stay close to zero angle.	
		m.SetXRotation(Interpolate(m_LastInterpolatedRotX, m_InterpolatedRotX, frameOffset));
		m.RotateZ(Interpolate(m_LastInterpolatedRotZ, m_InterpolatedRotZ, frameOffset));
	
		m.RotateY(rotY + (float)M_PI);
		m.Translate(CVector3D(x, y, z));
		
		return m;
	}
Example #27
0
	virtual void SetMovingFlag(bool enabled)
	{
		m_Moving = enabled;

		if (m_Tag.valid() && m_Type == UNIT)
		{
			CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
			if (cmpObstructionManager)
				cmpObstructionManager->SetUnitMovingFlag(m_Tag, m_Moving);
		}
	}
Example #28
0
	virtual void SetTurretParent(entity_id_t id, const CFixedVector3D& offset)
	{
		if (m_TurretParent != INVALID_ENTITY)
		{
			CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent);
			if (cmpPosition)
				cmpPosition->GetTurrets()->erase(GetEntityId());
		}

		m_TurretParent = id;
		m_TurretPosition = offset;

		if (m_TurretParent != INVALID_ENTITY)
		{
			CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent);
			if (cmpPosition)
				cmpPosition->GetTurrets()->insert(GetEntityId());
		}
		UpdateTurretPosition();
	}
Example #29
0
	virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out)
	{
		CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), GetEntityId());
		if (!cmpPosition)
			return false; // error

		CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
		if (!cmpObstructionManager)
			return false; // error

		if (!cmpPosition->IsInWorld())
			return false; // no obstruction square

		CFixedVector2D pos = cmpPosition->GetPosition2D();
		if (m_Type == STATIC)
			out = cmpObstructionManager->GetStaticShapeObstruction(pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1);
		else
			out = cmpObstructionManager->GetUnitShapeObstruction(pos.X, pos.Y, m_Size0);
		return true;
	}
Example #30
0
	virtual CFixedVector3D GetRotation()
	{
		entity_angle_t y = m_RotY;
		if (m_TurretParent != INVALID_ENTITY)
		{
			CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent);
			if (cmpPosition)
				y += cmpPosition->GetRotation().Y;
		}
		return CFixedVector3D(m_RotX, y, m_RotZ);
	}