virtual void Reset() { m_Sprites.clear(); m_SpriteOffsets.clear(); UpdateMessageSubscriptions(); }
virtual void TurnTo(entity_angle_t y) { if (m_TurretParent != INVALID_ENTITY) { CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent); if (cmpPosition) y -= cmpPosition->GetRotation().Y; } m_RotY = y; AdvertisePositionChanges(); UpdateMessageSubscriptions(); }
virtual void AddSprite(VfsPath textureName, CFixedVector2D corner0, CFixedVector2D corner1, CFixedVector3D position) { CTextureProperties textureProps(textureName); SOverlaySprite sprite; sprite.m_Texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); sprite.m_X0 = corner0.X.ToFloat(); sprite.m_Y0 = corner0.Y.ToFloat(); sprite.m_X1 = corner1.X.ToFloat(); sprite.m_Y1 = corner1.Y.ToFloat(); m_Sprites.push_back(sprite); m_SpriteOffsets.push_back(CVector3D(position)); UpdateMessageSubscriptions(); }
virtual void AddSprite(const VfsPath& textureName, const CFixedVector2D& corner0, const CFixedVector2D& corner1, const CFixedVector3D& position, const std::string& color) { CColor colorObj(1.0f, 1.0f, 1.0f, 1.0f); if (!colorObj.ParseString(color, 1)) LOGERROR("OverlayRenderer: Error parsing '%s'", color); CTextureProperties textureProps(textureName); SOverlaySprite sprite; sprite.m_Texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); sprite.m_X0 = corner0.X.ToFloat(); sprite.m_Y0 = corner0.Y.ToFloat(); sprite.m_X1 = corner1.X.ToFloat(); sprite.m_Y1 = corner1.Y.ToFloat(); sprite.m_Color = colorObj; m_Sprites.push_back(sprite); m_SpriteOffsets.push_back(CVector3D(position)); UpdateMessageSubscriptions(); }
virtual void SetYRotation(entity_angle_t y) { if (m_TurretParent != INVALID_ENTITY) { CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent); if (cmpPosition) y -= cmpPosition->GetRotation().Y; } m_RotY = y; m_InterpolatedRotY = m_RotY.ToFloat(); if (m_InWorld) { UpdateXZRotation(); m_LastInterpolatedRotX = m_InterpolatedRotX; m_LastInterpolatedRotZ = m_InterpolatedRotZ; } AdvertisePositionChanges(); UpdateMessageSubscriptions(); }
virtual void Deserialize(const CParamNode& paramNode, IDeserializer& deserialize) { Init(paramNode); deserialize.Bool("in world", m_InWorld); if (m_InWorld) { deserialize.NumberFixed_Unbounded("x", m_X); deserialize.NumberFixed_Unbounded("y", m_Y); deserialize.NumberFixed_Unbounded("z", m_Z); deserialize.NumberFixed_Unbounded("last x", m_LastX); deserialize.NumberFixed_Unbounded("last y diff", m_LastYDifference); deserialize.NumberFixed_Unbounded("last z", m_LastZ); } deserialize.NumberI32_Unbounded("territory", m_Territory); deserialize.NumberFixed_Unbounded("rot x", m_RotX); deserialize.NumberFixed_Unbounded("rot y", m_RotY); deserialize.NumberFixed_Unbounded("rot z", m_RotZ); deserialize.NumberFixed_Unbounded("altitude", m_Y); deserialize.Bool("relative", m_RelativeToGround); deserialize.Bool("floating", m_Floating); deserialize.NumberFixed_Unbounded("constructionprogress", m_ConstructionProgress); // TODO: should there be range checks on all these values? m_InterpolatedRotY = m_RotY.ToFloat(); deserialize.NumberU32_Unbounded("turret parent", m_TurretParent); if (m_TurretParent != INVALID_ENTITY) { deserialize.NumberFixed_Unbounded("x", m_TurretPosition.X); deserialize.NumberFixed_Unbounded("y", m_TurretPosition.Y); deserialize.NumberFixed_Unbounded("z", m_TurretPosition.Z); } if (m_InWorld) UpdateXZRotation(); UpdateMessageSubscriptions(); }
virtual void HandleMessage(const CMessage& msg, bool UNUSED(global)) { switch (msg.GetType()) { case MT_Interpolate: { PROFILE("Position::Interpolate"); const CMessageInterpolate& msgData = static_cast<const CMessageInterpolate&> (msg); float rotY = m_RotY.ToFloat(); if (rotY != m_InterpolatedRotY) { float delta = rotY - m_InterpolatedRotY; // Wrap delta to -M_PI..M_PI delta = fmodf(delta + (float)M_PI, 2*(float)M_PI); // range -2PI..2PI if (delta < 0) delta += 2*(float)M_PI; // range 0..2PI delta -= (float)M_PI; // range -M_PI..M_PI // Clamp to max rate float deltaClamped = clamp(delta, -m_RotYSpeed*msgData.deltaSimTime, +m_RotYSpeed*msgData.deltaSimTime); // Calculate new orientation, in a peculiar way in order to make sure the // result gets close to m_orientation (rather than being n*2*M_PI out) m_InterpolatedRotY = rotY + deltaClamped - delta; // update the visual XZ rotation if (m_InWorld) { m_LastInterpolatedRotX = m_InterpolatedRotX; m_LastInterpolatedRotZ = m_InterpolatedRotZ; UpdateXZRotation(); } UpdateMessageSubscriptions(); } break; } case MT_TurnStart: { m_LastInterpolatedRotX = m_InterpolatedRotX; m_LastInterpolatedRotZ = m_InterpolatedRotZ; if (m_InWorld && (m_LastX != m_X || m_LastZ != m_Z)) UpdateXZRotation(); // Store the positions from the turn before m_PrevX = m_LastX; m_PrevZ = m_LastZ; m_LastX = m_X; m_LastZ = m_Z; m_LastYDifference = entity_pos_t::Zero(); // warn when a position change also causes a territory change under the entity if (m_InWorld) { player_id_t newTerritory; CmpPtr<ICmpTerritoryManager> cmpTerritoryManager(GetSystemEntity()); if (cmpTerritoryManager) newTerritory = cmpTerritoryManager->GetOwner(m_X, m_Z); else newTerritory = INVALID_PLAYER; if (newTerritory != m_Territory) { m_Territory = newTerritory; CMessageTerritoryPositionChanged msg(GetEntityId(), m_Territory); GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg); } } else if (m_Territory != INVALID_PLAYER) { m_Territory = INVALID_PLAYER; CMessageTerritoryPositionChanged msg(GetEntityId(), m_Territory); GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg); } break; } case MT_TerrainChanged: case MT_WaterChanged: { AdvertiseInterpolatedPositionChanges(); break; } case MT_Deserialized: { Deserialized(); break; } } }