virtual void Init(const CParamNode& paramNode) { std::wstring anchor = paramNode.GetChild("Anchor").ToString(); if (anchor == L"pitch") m_AnchorType = PITCH; else if (anchor == L"pitch-roll") m_AnchorType = PITCH_ROLL; else if (anchor == L"roll") m_AnchorType = ROLL; else m_AnchorType = UPRIGHT; m_InWorld = false; m_YOffset = paramNode.GetChild("Altitude").ToFixed(); m_RelativeToGround = true; m_Floating = paramNode.GetChild("Floating").ToBool(); m_RotYSpeed = paramNode.GetChild("TurnRate").ToFixed().ToFloat(); m_RotX = m_RotY = m_RotZ = entity_angle_t::FromInt(0); m_InterpolatedRotX = m_InterpolatedRotY = m_InterpolatedRotZ = 0.f; m_LastInterpolatedRotX = m_LastInterpolatedRotZ = 0.f; m_NeedInitialXZRotation = false; }
virtual void Init(const CParamNode& UNUSED(paramNode)) { m_Territories = NULL; m_CostGrid = NULL; m_DebugOverlay = NULL; // m_DebugOverlay = new TerritoryOverlay(*this); m_BoundaryLinesDirty = true; m_TriggerEvent = true; m_EnableLineDebugOverlays = false; m_DirtyID = 1; m_AnimTime = 0.0; m_TerritoryTotalPassableCellCount = 0; // Register Relax NG validator CXeromyces::AddValidator(g_VFS, "territorymanager", "simulation/data/territorymanager.rng"); CParamNode externalParamNode; CParamNode::LoadXML(externalParamNode, L"simulation/data/territorymanager.xml", "territorymanager"); int impassableCost = externalParamNode.GetChild("TerritoryManager").GetChild("ImpassableCost").ToInt(); ENSURE(0 <= impassableCost && impassableCost <= 255); m_ImpassableCost = (u8)impassableCost; m_BorderThickness = externalParamNode.GetChild("TerritoryManager").GetChild("BorderThickness").ToFixed().ToFloat(); m_BorderSeparation = externalParamNode.GetChild("TerritoryManager").GetChild("BorderSeparation").ToFixed().ToFloat(); }
void CTemplateLoader::CopyMirageSubset(CParamNode& out, const CParamNode& in) { // Currently used for mirage entities replacing real ones in fog-of-war std::set<std::string> permittedComponentTypes; permittedComponentTypes.insert("Footprint"); permittedComponentTypes.insert("Minimap"); permittedComponentTypes.insert("Ownership"); permittedComponentTypes.insert("OverlayRenderer"); permittedComponentTypes.insert("Position"); permittedComponentTypes.insert("Selectable"); permittedComponentTypes.insert("StatusBars"); permittedComponentTypes.insert("Visibility"); permittedComponentTypes.insert("VisualActor"); CParamNode::LoadXMLString(out, "<Entity/>"); out.CopyFilteredChildrenOfChild(in, "Entity", permittedComponentTypes); // Select a subset of identity data. We don't want to have, for example, a CC mirage // that has also the CC class and then prevents construction of other CCs std::set<std::string> identitySubset; identitySubset.insert("Civ"); identitySubset.insert("GenericName"); identitySubset.insert("SpecificName"); identitySubset.insert("Tooltip"); identitySubset.insert("History"); identitySubset.insert("Icon"); CParamNode identity; CParamNode::LoadXMLString(identity, "<Identity/>"); identity.CopyFilteredChildrenOfChild(in.GetChild("Entity"), "Identity", identitySubset); CParamNode::LoadXMLString(out, ("<Entity>"+utf8_from_wstring(identity.ToXML())+"</Entity>").c_str()); // Set the entity as mirage entity CParamNode::LoadXMLString(out, "<Entity><Mirage/></Entity>"); }
virtual void Init(const CParamNode& paramNode) { std::wstring anchor = paramNode.GetChild("Anchor").ToString(); if (anchor == L"pitch") m_AnchorType = PITCH; else if (anchor == L"pitch-roll") m_AnchorType = PITCH_ROLL; else if (anchor == L"roll") m_AnchorType = ROLL; else m_AnchorType = UPRIGHT; m_InWorld = false; m_LastYDifference = entity_pos_t::Zero(); m_Y = paramNode.GetChild("Altitude").ToFixed(); m_RelativeToGround = true; m_Floating = paramNode.GetChild("Floating").ToBool(); m_RotYSpeed = paramNode.GetChild("TurnRate").ToFixed().ToFloat(); m_RotX = m_RotY = m_RotZ = entity_angle_t::FromInt(0); m_InterpolatedRotX = m_InterpolatedRotY = m_InterpolatedRotZ = 0.f; m_LastInterpolatedRotX = m_LastInterpolatedRotZ = 0.f; m_Territory = INVALID_PLAYER; m_TurretParent = INVALID_ENTITY; m_TurretPosition = CFixedVector3D(); m_ActorFloating = false; m_EnabledMessageInterpolate = false; }
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); m_ConstructionPreview = paramNode.GetChild("ConstructionPreview").IsOk(); m_ConstructionProgress = fixed::Zero(); m_Seed = GetEntityId(); if (paramNode.GetChild("Foundation").IsOk() && paramNode.GetChild("FoundationActor").IsOk()) m_ActorName = paramNode.GetChild("FoundationActor").ToString(); else m_ActorName = paramNode.GetChild("Actor").ToString(); InitModel(paramNode); // We need to select animation even if graphics are disabled, as this modifies serialized state SelectAnimation("idle", false, fixed::FromInt(1), L""); m_NeedsInterpolation = true; m_PositionChanged = true; }
void CTemplateLoader::CopyFoundationSubset(CParamNode& out, const CParamNode& in) { // TODO: this is all kind of yucky and hard-coded; it'd be nice to have a more generic // extensible scriptable way to define these subsets std::set<std::string> permittedComponentTypes; permittedComponentTypes.insert("Ownership"); permittedComponentTypes.insert("Position"); permittedComponentTypes.insert("VisualActor"); permittedComponentTypes.insert("Identity"); permittedComponentTypes.insert("BuildRestrictions"); permittedComponentTypes.insert("Obstruction"); permittedComponentTypes.insert("Selectable"); permittedComponentTypes.insert("Footprint"); permittedComponentTypes.insert("Fogging"); permittedComponentTypes.insert("Armour"); permittedComponentTypes.insert("Health"); permittedComponentTypes.insert("StatusBars"); permittedComponentTypes.insert("OverlayRenderer"); permittedComponentTypes.insert("Decay"); permittedComponentTypes.insert("Cost"); permittedComponentTypes.insert("Sound"); permittedComponentTypes.insert("Visibility"); permittedComponentTypes.insert("Vision"); permittedComponentTypes.insert("AIProxy"); permittedComponentTypes.insert("RallyPoint"); permittedComponentTypes.insert("RallyPointRenderer"); CParamNode::LoadXMLString(out, "<Entity/>"); out.CopyFilteredChildrenOfChild(in, "Entity", permittedComponentTypes); // Switch the actor to foundation mode CParamNode::LoadXMLString(out, "<Entity><VisualActor><Foundation/></VisualActor></Entity>"); // Add the Foundation component, to deal with the construction process CParamNode::LoadXMLString(out, "<Entity><Foundation/></Entity>"); // Initialise health to 1 CParamNode::LoadXMLString(out, "<Entity><Health><Initial>1</Initial></Health></Entity>"); // Foundations shouldn't initially block unit movement if (out.GetChild("Entity").GetChild("Obstruction").IsOk()) CParamNode::LoadXMLString(out, "<Entity><Obstruction><DisableBlockMovement>true</DisableBlockMovement><DisableBlockPathfinding>true</DisableBlockPathfinding></Obstruction></Entity>"); // Don't provide population bonuses yet (but still do take up population cost) if (out.GetChild("Entity").GetChild("Cost").IsOk()) CParamNode::LoadXMLString(out, "<Entity><Cost><PopulationBonus>0</PopulationBonus></Cost></Entity>"); // Foundations should be visible themselves in fog-of-war if their base template is, // but shouldn't have any vision range if (out.GetChild("Entity").GetChild("Vision").IsOk()) { CParamNode::LoadXMLString(out, "<Entity><Vision><Range>0</Range></Vision></Entity>"); // Foundations should not have special vision capabilities either if (out.GetChild("Entity").GetChild("Vision").GetChild("RevealShore").IsOk()) CParamNode::LoadXMLString(out, "<Entity><Vision><RevealShore>false</RevealShore></Vision></Entity>"); } }
void CTemplateLoader::CopyPreviewSubset(CParamNode& out, const CParamNode& in, bool corpse) { // We only want to include components which are necessary (for the visual previewing of an entity) // and safe (i.e. won't do anything that affects the synchronised simulation state), so additions // to this list should be carefully considered std::set<std::string> permittedComponentTypes; permittedComponentTypes.insert("Identity"); permittedComponentTypes.insert("Ownership"); permittedComponentTypes.insert("Position"); permittedComponentTypes.insert("Visibility"); permittedComponentTypes.insert("VisualActor"); permittedComponentTypes.insert("Footprint"); permittedComponentTypes.insert("Obstruction"); permittedComponentTypes.insert("Decay"); permittedComponentTypes.insert("BuildRestrictions"); // Need these for the Actor Viewer: permittedComponentTypes.insert("Attack"); permittedComponentTypes.insert("UnitMotion"); permittedComponentTypes.insert("Sound"); // (This set could be initialised once and reused, but it's not worth the effort) CParamNode::LoadXMLString(out, "<Entity/>"); out.CopyFilteredChildrenOfChild(in, "Entity", permittedComponentTypes); // Disable the Obstruction component (if there is one) so it doesn't affect pathfinding // (but can still be used for testing this entity for collisions against others) if (out.GetChild("Entity").GetChild("Obstruction").IsOk()) CParamNode::LoadXMLString(out, "<Entity><Obstruction><Active>false</Active></Obstruction></Entity>"); if (!corpse) { // Previews should not cast shadows if (out.GetChild("Entity").GetChild("VisualActor").IsOk()) CParamNode::LoadXMLString(out, "<Entity><VisualActor><DisableShadows/></VisualActor></Entity>"); // Previews should always be visible in fog-of-war/etc CParamNode::LoadXMLString(out, "<Entity><Visibility><AlwaysVisible>true</AlwaysVisible><Preview>true</Preview></Visibility></Entity>"); } if (corpse) { // Corpses should include decay components and activate them if (out.GetChild("Entity").GetChild("Decay").IsOk()) CParamNode::LoadXMLString(out, "<Entity><Decay><Active>true</Active></Decay></Entity>"); // Corpses shouldn't display silhouettes (especially since they're often half underground) if (out.GetChild("Entity").GetChild("VisualActor").IsOk()) CParamNode::LoadXMLString(out, "<Entity><VisualActor><SilhouetteDisplay>false</SilhouetteDisplay></VisualActor></Entity>"); // Corpses should remain visible in fog-of-war (for the owner only) CParamNode::LoadXMLString(out, "<Entity><Visibility><Corpse>true</Corpse></Visibility></Entity>"); } }
virtual void Init(const CParamNode& paramNode) { if (paramNode.GetChild("OverrideCost").IsOk()) m_Cost = paramNode.GetChild("OverrideCost").ToInt(); else m_Cost = -1; m_Root = paramNode.GetChild("Root").ToBool(); m_Weight = paramNode.GetChild("Weight").ToInt(); m_Radius = paramNode.GetChild("Radius").ToInt(); }
void CCmpPathfinder::Init(const CParamNode& UNUSED(paramNode)) { m_MapSize = 0; m_Grid = NULL; m_TerrainOnlyGrid = NULL; m_ObstructionsDirty.Clean(); m_PreserveUpdateInformations = false; m_NextAsyncTicket = 1; m_DebugOverlay = false; m_AtlasOverlay = NULL; m_SameTurnMovesCount = 0; // Register Relax NG validator CXeromyces::AddValidator(g_VFS, "pathfinder", "simulation/data/pathfinder.rng"); // Since this is used as a system component (not loaded from an entity template), // we can't use the real paramNode (it won't get handled properly when deserializing), // so load the data from a special XML file. CParamNode externalParamNode; CParamNode::LoadXML(externalParamNode, L"simulation/data/pathfinder.xml", "pathfinder"); // Previously all move commands during a turn were // queued up and processed asynchronously at the start // of the next turn. Now we are processing queued up // events several times duing the turn. This improves // responsiveness and units move more smoothly especially. // when in formation. There is still a call at the // beginning of a turn to process all outstanding moves - // this will handle any moves above the MaxSameTurnMoves // threshold. // // TODO - The moves processed at the beginning of the // turn do not count against the maximum moves per turn // currently. The thinking is that this will eventually // happen in another thread. Either way this probably // will require some adjustment and rethinking. const CParamNode pathingSettings = externalParamNode.GetChild("Pathfinder"); m_MaxSameTurnMoves = (u16)pathingSettings.GetChild("MaxSameTurnMoves").ToInt(); const CParamNode::ChildrenMap& passClasses = externalParamNode.GetChild("Pathfinder").GetChild("PassabilityClasses").GetChildren(); for (CParamNode::ChildrenMap::const_iterator it = passClasses.begin(); it != passClasses.end(); ++it) { std::string name = it->first; ENSURE((int)m_PassClasses.size() <= PASS_CLASS_BITS); pass_class_t mask = PASS_CLASS_MASK_FROM_INDEX(m_PassClasses.size()); m_PassClasses.push_back(PathfinderPassability(mask, it->second)); m_PassClassMasks[name] = mask; } }
virtual void Init(const CParamNode& paramNode) { m_Active = !paramNode.GetChild("Inactive").IsOk(); m_DelayTime = paramNode.GetChild("DelayTime").ToFixed().ToFloat(); m_SinkRate = paramNode.GetChild("SinkRate").ToFixed().ToFloat(); m_SinkAccel = paramNode.GetChild("SinkAccel").ToFixed().ToFloat(); m_CurrentTime = 0.f; m_TotalSinkDepth = -1.f; // Detect unsafe misconfiguration if (m_Active && !ENTITY_IS_LOCAL(GetEntityId())) { debug_warn(L"CCmpDecay must not be used on non-local (network-synchronised) entities"); m_Active = false; } }
PSRETURN CParamNode::LoadXMLString(CParamNode& ret, const char* xml, const wchar_t* sourceIdentifier /*=NULL*/) { CXeromyces xero; PSRETURN ok = xero.LoadString(xml); if (ok != PSRETURN_OK) return ok; ret.ApplyLayer(xero, xero.GetRoot(), sourceIdentifier); return PSRETURN_OK; }
virtual void Init(const CParamNode& paramNode) { if (paramNode.GetChild("Square").IsOk()) { m_Shape = SQUARE; m_Size0 = paramNode.GetChild("Square").GetChild("@width").ToFixed(); m_Size1 = paramNode.GetChild("Square").GetChild("@depth").ToFixed(); } else if (paramNode.GetChild("Circle").IsOk()) { m_Shape = CIRCLE; m_Size0 = m_Size1 = paramNode.GetChild("Circle").GetChild("@radius").ToFixed(); } else { // Error - pick some default m_Shape = CIRCLE; m_Size0 = m_Size1 = entity_pos_t::FromInt(1); } m_Height = paramNode.GetChild("Height").ToFixed(); }
void CTemplateLoader::CopyConstructionSubset(CParamNode& out, const CParamNode& in) { // Currently used for buildings rising during construction // Mostly serves to filter out components like Vision, UnitAI, etc. std::set<std::string> permittedComponentTypes; permittedComponentTypes.insert("Footprint"); permittedComponentTypes.insert("Ownership"); permittedComponentTypes.insert("Position"); permittedComponentTypes.insert("VisualActor"); CParamNode::LoadXMLString(out, "<Entity/>"); out.CopyFilteredChildrenOfChild(in, "Entity", permittedComponentTypes); }
template<> void ScriptInterface::ToJSVal<CParamNode>(JSContext* cx, JS::MutableHandleValue ret, CParamNode const& val) { JSAutoRequest rq(cx); val.ToJSVal(cx, true, ret); // Prevent modifications to the object, so that it's safe to share between // components and to reconstruct on deserialization if (ret.isObject()) { JS::RootedObject obj(cx, &ret.toObject()); JS_DeepFreezeObject(cx, obj); } }
virtual void Init(const CParamNode& paramNode) { m_EditorOnly = paramNode.GetChild("EditorOnly").IsOk(); // Certain special units always have their selection overlay shown m_AlwaysVisible = paramNode.GetChild("Overlay").GetChild("AlwaysVisible").IsOk(); if (m_AlwaysVisible) { m_AlphaMin = MIN_ALPHA_ALWAYS_VISIBLE; m_Color.a = m_AlphaMin; } else m_AlphaMin = MIN_ALPHA_UNSELECTED; const CParamNode& textureNode = paramNode.GetChild("Overlay").GetChild("Texture"); const CParamNode& outlineNode = paramNode.GetChild("Overlay").GetChild("Outline"); const char* textureBasePath = "art/textures/selection/"; // Save some memory by using interned file paths in these descriptors (almost all actors and // entities have this component, and many use the same textures). if (textureNode.IsOk()) { // textured quad mode (dynamic, for units) m_OverlayDescriptor.m_Type = ICmpSelectable::DYNAMIC_QUAD; m_OverlayDescriptor.m_QuadTexture = CStrIntern(textureBasePath + textureNode.GetChild("MainTexture").ToUTF8()); m_OverlayDescriptor.m_QuadTextureMask = CStrIntern(textureBasePath + textureNode.GetChild("MainTextureMask").ToUTF8()); } else if (outlineNode.IsOk()) { // textured outline mode (static, for buildings) m_OverlayDescriptor.m_Type = ICmpSelectable::STATIC_OUTLINE; m_OverlayDescriptor.m_LineTexture = CStrIntern(textureBasePath + outlineNode.GetChild("LineTexture").ToUTF8()); m_OverlayDescriptor.m_LineTextureMask = CStrIntern(textureBasePath + outlineNode.GetChild("LineTextureMask").ToUTF8()); m_OverlayDescriptor.m_LineThickness = outlineNode.GetChild("LineThickness").ToFloat(); } }
virtual void Init(const CParamNode& paramNode) { if (paramNode.GetChild("Unit").IsOk()) { m_Type = UNIT; m_Size0 = m_Size1 = paramNode.GetChild("Unit").GetChild("@radius").ToFixed(); } else { m_Type = STATIC; m_Size0 = paramNode.GetChild("Static").GetChild("@width").ToFixed(); m_Size1 = paramNode.GetChild("Static").GetChild("@depth").ToFixed(); } m_TemplateFlags = 0; if (paramNode.GetChild("BlockMovement").ToBool()) m_TemplateFlags |= ICmpObstructionManager::FLAG_BLOCK_MOVEMENT; if (paramNode.GetChild("BlockPathfinding").ToBool()) m_TemplateFlags |= ICmpObstructionManager::FLAG_BLOCK_PATHFINDING; if (paramNode.GetChild("BlockFoundation").ToBool()) m_TemplateFlags |= ICmpObstructionManager::FLAG_BLOCK_FOUNDATION; if (paramNode.GetChild("BlockConstruction").ToBool()) m_TemplateFlags |= ICmpObstructionManager::FLAG_BLOCK_CONSTRUCTION; m_Flags = m_TemplateFlags; if (paramNode.GetChild("DisableBlockMovement").ToBool()) m_Flags &= (flags_t)(~ICmpObstructionManager::FLAG_BLOCK_MOVEMENT); if (paramNode.GetChild("DisableBlockPathfinding").ToBool()) m_Flags &= (flags_t)(~ICmpObstructionManager::FLAG_BLOCK_PATHFINDING); m_Active = paramNode.GetChild("Active").ToBool(); m_Tag = tag_t(); m_Moving = false; m_ControlGroup = GetEntityId(); m_ControlGroup2 = INVALID_ENTITY; }
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""); }
virtual void Init(const CParamNode& paramNode) { m_Active = true; const CParamNode& colour = paramNode.GetChild("Colour"); if (colour.IsOk()) { m_UsePlayerColour = false; m_R = colour.GetChild("@r").ToInt(); m_G = colour.GetChild("@g").ToInt(); m_B = colour.GetChild("@b").ToInt(); } else { m_UsePlayerColour = true; // Choose a bogus colour which will get replaced once we have an owner m_R = 255; m_G = 0; m_B = 255; } }
void CTemplateLoader::CopyResourceSubset(CParamNode& out, const CParamNode& in) { // Currently used for animals which die and leave a gatherable corpse. // Mostly serves to filter out components like Vision, UnitAI, etc. std::set<std::string> permittedComponentTypes; permittedComponentTypes.insert("Ownership"); permittedComponentTypes.insert("Position"); permittedComponentTypes.insert("VisualActor"); permittedComponentTypes.insert("Identity"); permittedComponentTypes.insert("Obstruction"); permittedComponentTypes.insert("Minimap"); permittedComponentTypes.insert("ResourceSupply"); permittedComponentTypes.insert("Selectable"); permittedComponentTypes.insert("Footprint"); permittedComponentTypes.insert("StatusBars"); permittedComponentTypes.insert("OverlayRenderer"); permittedComponentTypes.insert("Sound"); permittedComponentTypes.insert("AIProxy"); CParamNode::LoadXMLString(out, "<Entity/>"); out.CopyFilteredChildrenOfChild(in, "Entity", permittedComponentTypes); }
CMiniMap::CMiniMap() : m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), m_TerrainDirty(true), m_MapScale(1.f) { AddSetting(GUIST_CColor, "fov_wedge_color"); AddSetting(GUIST_CStrW, "tooltip"); AddSetting(GUIST_CStr, "tooltip_style"); m_Clicking = false; m_MouseHovering = false; // Get the maximum height for unit passage in water. CParamNode externalParamNode; CParamNode::LoadXML(externalParamNode, L"simulation/data/pathfinder.xml"); const CParamNode pathingSettings = externalParamNode.GetChild("Pathfinder").GetChild("PassabilityClasses"); if (pathingSettings.GetChild("default").IsOk() && pathingSettings.GetChild("default").GetChild("MaxWaterDepth").IsOk()) m_ShallowPassageHeight = pathingSettings.GetChild("default").GetChild("MaxWaterDepth").ToFloat(); else m_ShallowPassageHeight = 0.0f; }
virtual void Init(const CParamNode& paramNode) { m_FormationController = paramNode.GetChild("FormationController").ToBool(); m_WalkSpeed = paramNode.GetChild("WalkSpeed").ToFixed(); m_Speed = m_WalkSpeed; if (paramNode.GetChild("Run").IsOk()) { m_RunSpeed = paramNode.GetChild("Run").GetChild("Speed").ToFixed(); } else { m_RunSpeed = m_WalkSpeed; } CmpPtr<ICmpPathfinder> cmpPathfinder(GetSimContext(), SYSTEM_ENTITY); if (!cmpPathfinder.null()) { m_PassClass = cmpPathfinder->GetPassabilityClass(paramNode.GetChild("PassabilityClass").ToUTF8()); m_CostClass = cmpPathfinder->GetCostClass(paramNode.GetChild("CostClass").ToUTF8()); } CmpPtr<ICmpObstruction> cmpObstruction(GetSimContext(), GetEntityId()); if (!cmpObstruction.null()) m_Radius = cmpObstruction->GetUnitRadius(); m_State = STATE_IDLE; m_PathState = PATHSTATE_NONE; m_ExpectedPathTicket = 0; m_TargetEntity = INVALID_ENTITY; m_FinalGoal.type = ICmpPathfinder::Goal::POINT; m_DebugOverlayEnabled = false; }
virtual void Init(const CParamNode& paramNode) { m_Unit = NULL; if (!GetSimContext().HasUnitManager()) return; // do nothing 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(); m_R = m_G = m_B = fixed::FromInt(1); std::set<CStr> selections; m_Unit = GetSimContext().GetUnitManager().CreateUnit(m_ActorName, GetActorSeed(), selections); if (!m_Unit) { // The error will have already been logged return; } u32 modelFlags = 0; if (paramNode.GetChild("SilhouetteDisplay").ToBool()) modelFlags |= MODELFLAG_SILHOUETTE_DISPLAY; if (paramNode.GetChild("SilhouetteOccluder").ToBool()) modelFlags |= MODELFLAG_SILHOUETTE_OCCLUDER; if (m_Unit->GetModel().ToCModel()) m_Unit->GetModel().ToCModel()->AddFlagsRec(modelFlags); m_Unit->SetID(GetEntityId()); SelectAnimation("idle", false, 0.f, L""); }
void CParamNode::LoadXML(CParamNode& ret, const XMBFile& xmb, const wchar_t* sourceIdentifier /*= NULL*/) { ret.ApplyLayer(xmb, xmb.GetRoot(), sourceIdentifier); }
void CCmpPathfinder::Init(const CParamNode& UNUSED(paramNode)) { m_MapSize = 0; m_Grid = NULL; m_ObstructionGrid = NULL; m_TerrainDirty = true; m_NextAsyncTicket = 1; m_DebugOverlay = NULL; m_DebugGrid = NULL; m_DebugPath = NULL; m_SameTurnMovesCount = 0; // Since this is used as a system component (not loaded from an entity template), // we can't use the real paramNode (it won't get handled properly when deserializing), // so load the data from a special XML file. CParamNode externalParamNode; CParamNode::LoadXML(externalParamNode, L"simulation/data/pathfinder.xml"); // Previously all move commands during a turn were // queued up and processed asynchronously at the start // of the next turn. Now we are processing queued up // events several times duing the turn. This improves // responsiveness and units move more smoothly especially. // when in formation. There is still a call at the // beginning of a turn to process all outstanding moves - // this will handle any moves above the MaxSameTurnMoves // threshold. // // TODO - The moves processed at the beginning of the // turn do not count against the maximum moves per turn // currently. The thinking is that this will eventually // happen in another thread. Either way this probably // will require some adjustment and rethinking. const CParamNode pathingSettings = externalParamNode.GetChild("Pathfinder"); m_MaxSameTurnMoves = (u16)pathingSettings.GetChild("MaxSameTurnMoves").ToInt(); const CParamNode::ChildrenMap& passClasses = externalParamNode.GetChild("Pathfinder").GetChild("PassabilityClasses").GetChildren(); for (CParamNode::ChildrenMap::const_iterator it = passClasses.begin(); it != passClasses.end(); ++it) { std::string name = it->first; ENSURE((int)m_PassClasses.size() <= PASS_CLASS_BITS); pass_class_t mask = (pass_class_t)(1u << (m_PassClasses.size() + 2)); m_PassClasses.push_back(PathfinderPassability(mask, it->second)); m_PassClassMasks[name] = mask; } const CParamNode::ChildrenMap& moveClasses = externalParamNode.GetChild("Pathfinder").GetChild("MovementClasses").GetChildren(); // First find the set of unit classes used by any terrain classes, // and assign unique tags to terrain classes std::set<std::string> unitClassNames; unitClassNames.insert("default"); // must always have costs for default { size_t i = 0; for (CParamNode::ChildrenMap::const_iterator it = moveClasses.begin(); it != moveClasses.end(); ++it) { std::string terrainClassName = it->first; m_TerrainCostClassTags[terrainClassName] = (cost_class_t)i; ++i; const CParamNode::ChildrenMap& unitClasses = it->second.GetChild("UnitClasses").GetChildren(); for (CParamNode::ChildrenMap::const_iterator uit = unitClasses.begin(); uit != unitClasses.end(); ++uit) unitClassNames.insert(uit->first); } } // For each terrain class, set the costs for every unit class, // and assign unique tags to unit classes { size_t i = 0; for (std::set<std::string>::const_iterator nit = unitClassNames.begin(); nit != unitClassNames.end(); ++nit) { m_UnitCostClassTags[*nit] = (cost_class_t)i; ++i; std::vector<u32> costs; std::vector<fixed> speeds; for (CParamNode::ChildrenMap::const_iterator it = moveClasses.begin(); it != moveClasses.end(); ++it) { // Default to the general costs for this terrain class fixed cost = it->second.GetChild("@Cost").ToFixed(); fixed speed = it->second.GetChild("@Speed").ToFixed(); // Check for specific cost overrides for this unit class const CParamNode& unitClass = it->second.GetChild("UnitClasses").GetChild(nit->c_str()); if (unitClass.IsOk()) { cost = unitClass.GetChild("@Cost").ToFixed(); speed = unitClass.GetChild("@Speed").ToFixed(); } costs.push_back((cost * DEFAULT_MOVE_COST).ToInt_RoundToZero()); speeds.push_back(speed); } m_MoveCosts.push_back(costs); m_MoveSpeeds.push_back(speeds); } } }
CMiniMap::CMiniMap() : m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), m_TerrainDirty(true), m_MapScale(1.f), m_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW), m_NextBlinkTime(0.0), m_PingDuration(25.0), m_BlinkState(false) { AddSetting(GUIST_CColor, "fov_wedge_color"); AddSetting(GUIST_CStrW, "tooltip"); AddSetting(GUIST_CStr, "tooltip_style"); m_Clicking = false; m_MouseHovering = false; // Get the maximum height for unit passage in water. CParamNode externalParamNode; CParamNode::LoadXML(externalParamNode, L"simulation/data/pathfinder.xml"); const CParamNode pathingSettings = externalParamNode.GetChild("Pathfinder").GetChild("PassabilityClasses"); if (pathingSettings.GetChild("default").IsOk() && pathingSettings.GetChild("default").GetChild("MaxWaterDepth").IsOk()) m_ShallowPassageHeight = pathingSettings.GetChild("default").GetChild("MaxWaterDepth").ToFloat(); else m_ShallowPassageHeight = 0.0f; m_AttributePos.type = GL_FLOAT; m_AttributePos.elems = 2; m_VertexArray.AddAttribute(&m_AttributePos); m_AttributeColor.type = GL_UNSIGNED_BYTE; m_AttributeColor.elems = 4; m_VertexArray.AddAttribute(&m_AttributeColor); m_VertexArray.SetNumVertices(MAX_ENTITIES_DRAWN); m_VertexArray.Layout(); m_IndexArray.SetNumVertices(MAX_ENTITIES_DRAWN); m_IndexArray.Layout(); VertexArrayIterator<u16> index = m_IndexArray.GetIterator(); for (u16 i = 0; i < MAX_ENTITIES_DRAWN; ++i) { *index++ = i; } m_IndexArray.Upload(); m_IndexArray.FreeBackingStore(); VertexArrayIterator<float[2]> attrPos = m_AttributePos.GetIterator<float[2]>(); VertexArrayIterator<u8[4]> attrColor = m_AttributeColor.GetIterator<u8[4]>(); for (u16 i = 0; i < MAX_ENTITIES_DRAWN; i++) { (*attrColor)[0] = 0; (*attrColor)[1] = 0; (*attrColor)[2] = 0; (*attrColor)[3] = 0; ++attrColor; (*attrPos)[0] = -10000.0f; (*attrPos)[1] = -10000.0f; ++attrPos; } m_VertexArray.Upload(); double blinkDuration = 1.0; // Tests won't have config initialised if (CConfigDB::IsInitialised()) { CFG_GET_VAL("gui.session.minimap.pingduration", Double, m_PingDuration); CFG_GET_VAL("gui.session.minimap.blinkduration", Double, blinkDuration); } m_HalfBlinkDuration = blinkDuration/2; }
virtual void Init(const CParamNode& paramNode) { m_BaseRange = m_Range = paramNode.GetChild("Range").ToFixed(); m_RetainInFog = paramNode.GetChild("RetainInFog").ToBool(); m_AlwaysVisible = paramNode.GetChild("AlwaysVisible").ToBool(); }
virtual void Init(const CParamNode& paramNode) { // The minimum obstruction size is the navcell size * sqrt(2) // This is enforced in the schema as a minimum of 1.5 fixed minObstruction = (Pathfinding::NAVCELL_SIZE.Square() * 2).Sqrt(); m_TemplateFlags = 0; if (paramNode.GetChild("BlockMovement").ToBool()) m_TemplateFlags |= ICmpObstructionManager::FLAG_BLOCK_MOVEMENT; if (paramNode.GetChild("BlockPathfinding").ToBool()) m_TemplateFlags |= ICmpObstructionManager::FLAG_BLOCK_PATHFINDING; if (paramNode.GetChild("BlockFoundation").ToBool()) m_TemplateFlags |= ICmpObstructionManager::FLAG_BLOCK_FOUNDATION; if (paramNode.GetChild("BlockConstruction").ToBool()) m_TemplateFlags |= ICmpObstructionManager::FLAG_BLOCK_CONSTRUCTION; m_Flags = m_TemplateFlags; if (paramNode.GetChild("DisableBlockMovement").ToBool()) m_Flags &= (flags_t)(~ICmpObstructionManager::FLAG_BLOCK_MOVEMENT); if (paramNode.GetChild("DisableBlockPathfinding").ToBool()) m_Flags &= (flags_t)(~ICmpObstructionManager::FLAG_BLOCK_PATHFINDING); if (paramNode.GetChild("Unit").IsOk()) { m_Type = UNIT; m_Size0 = m_Size1 = paramNode.GetChild("Unit").GetChild("@radius").ToFixed(); } else if (paramNode.GetChild("Static").IsOk()) { m_Type = STATIC; m_Size0 = paramNode.GetChild("Static").GetChild("@width").ToFixed(); m_Size1 = paramNode.GetChild("Static").GetChild("@depth").ToFixed(); ENSURE(m_Size0 > minObstruction); ENSURE(m_Size1 > minObstruction); } else { m_Type = CLUSTER; CFixedVector2D max = CFixedVector2D(fixed::FromInt(0), fixed::FromInt(0)); CFixedVector2D min = CFixedVector2D(fixed::FromInt(0), fixed::FromInt(0)); const CParamNode::ChildrenMap& clusterMap = paramNode.GetChild("Obstructions").GetChildren(); for(CParamNode::ChildrenMap::const_iterator it = clusterMap.begin(); it != clusterMap.end(); ++it) { Shape b; b.size0 = it->second.GetChild("@width").ToFixed(); b.size1 = it->second.GetChild("@depth").ToFixed(); ENSURE(b.size0 > minObstruction); ENSURE(b.size1 > minObstruction); b.dx = it->second.GetChild("@x").ToFixed(); b.dz = it->second.GetChild("@z").ToFixed(); b.da = entity_angle_t::FromInt(0); b.flags = m_Flags; m_Shapes.push_back(b); max.X = MAX(max.X, b.dx + b.size0/2); max.Y = MAX(max.Y, b.dz + b.size1/2); min.X = MIN(min.X, b.dx - b.size0/2); min.Y = MIN(min.Y, b.dz - b.size1/2); } m_Size0 = fixed::FromInt(2).Multiply(MAX(max.X, -min.X)); m_Size1 = fixed::FromInt(2).Multiply(MAX(max.Y, -min.Y)); } m_Active = paramNode.GetChild("Active").ToBool(); m_ControlPersist = paramNode.GetChild("ControlPersist").IsOk(); m_Tag = tag_t(); if (m_Type == CLUSTER) m_ClusterTags.clear(); m_Moving = false; m_ControlGroup = GetEntityId(); m_ControlGroup2 = INVALID_ENTITY; }
virtual void Init(const CParamNode& paramNode) { m_EditorOnly = paramNode.GetChild("EditorOnly").IsOk(); }