Changeset 25182
- Timestamp:
- Apr 2, 2021, 6:30:59 PM (3 years ago)
- Location:
- ps/trunk
- Files:
-
- 2 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
ps/trunk/binaries/data/mods/public/simulation/components/Foundation.js
r25089 r25182 304 304 // (via CCmpTemplateManager). Now we need to remove that temporary 305 305 // blocker-disabling, so that we'll perform standard unit blocking instead. 306 if (cmpObstruction && cmpObstruction.GetBlockMovementFlag())306 if (cmpObstruction) 307 307 cmpObstruction.SetDisableBlockMovementPathfinding(false, false, -1); 308 308 -
ps/trunk/binaries/data/mods/public/simulation/templates/special/formations/testudo.xml
r23694 r25182 9 9 <FormationShape>square</FormationShape> 10 10 <UnitSeparationWidthMultiplier>0.50</UnitSeparationWidthMultiplier> 11 <UnitSeparationDepthMultiplier>0. 35</UnitSeparationDepthMultiplier>11 <UnitSeparationDepthMultiplier>0.</UnitSeparationDepthMultiplier> 12 12 <SortingOrder>fillFromTheSides</SortingOrder> 13 13 <WidthDepthRatio>0.8</WidthDepthRatio> -
ps/trunk/source/simulation2/MessageTypes.h
r24511 r25182 1 /* Copyright (C) 20 19Wildfire Games.1 /* Copyright (C) 20 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * … … 391 391 392 392 /** 393 394 395 396 397 398 399 400 401 402 403 404 405 406 393 407 * Sent when ObstructionManager's view of the shape of the world has changed 394 408 * (changing the TILE_OUTOFBOUNDS tiles returned by Rasterise). -
ps/trunk/source/simulation2/TypeList.h
r25071 r25182 51 51 MESSAGE(VisibilityChanged) 52 52 MESSAGE(WaterChanged) 53 53 54 MESSAGE(ObstructionMapShapeChanged) 54 55 MESSAGE(TerritoriesChanged) -
ps/trunk/source/simulation2/components/CCmpObstruction.cpp
r24894 r25182 1 /* Copyright (C) 202 0Wildfire Games.1 /* Copyright (C) 202 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * … … 410 410 else 411 411 AddClusterShapes(pos.X, pos.Y, cmpPosition->GetRotation().Y); 412 413 414 415 416 417 418 412 419 } 413 420 else if (!active && m_Active) … … 428 435 if (m_Type == CLUSTER) 429 436 RemoveClusterShapes(); 437 438 439 440 441 442 443 430 444 } 431 445 } … … 463 477 } 464 478 465 virtual bool GetBlockMovementFlag( ) const466 { 467 return (m_TemplateFlags& ICmpObstructionManager::FLAG_BLOCK_MOVEMENT) != 0;479 virtual bool GetBlockMovementFlag() const 480 { 481 return & ICmpObstructionManager::FLAG_BLOCK_MOVEMENT) != 0; 468 482 } 469 483 … … 528 542 virtual void SetUnitClearance(const entity_pos_t& clearance) 529 543 { 544 545 530 546 if (m_Type == UNIT) 531 547 m_Clearance = clearance; -
ps/trunk/source/simulation2/components/CCmpUnitMotion.h
r25150 r25182 56 56 * NB: keep the max-range in sync with the vertex pathfinder "move the search space" heuristic. 57 57 */ 58 static const entity_pos_t SHORT_PATH_MIN_SEARCH_RANGE = entity_pos_t::FromInt(TERRAIN_TILE_SIZE*3) /2;58 static const entity_pos_t SHORT_PATH_MIN_SEARCH_RANGE = entity_pos_t::FromInt(TERRAIN_TILE_SIZE*3); 59 59 static const entity_pos_t SHORT_PATH_MAX_SEARCH_RANGE = entity_pos_t::FromInt(TERRAIN_TILE_SIZE*14); 60 60 static const entity_pos_t SHORT_PATH_SEARCH_RANGE_INCREMENT = entity_pos_t::FromInt(TERRAIN_TILE_SIZE*1); 61 static const u8 SHORT_PATH_SEARCH_RANGE_INCREASE_DELAY = 2;61 static const u8 SHORT_PATH_SEARCH_RANGE_INCREASE_DELAY = ; 62 62 63 63 /** … … 101 101 * TODO: when unit pushing is implemented, this number can probably be lowered. 102 102 */ 103 static const u8 MAX_FAILED_MOVEMENTS = 40;103 static const u8 MAX_FAILED_MOVEMENTS = ; 104 104 105 105 /** … … 130 130 componentManager.SubscribeToMessageType(MT_OwnershipChanged); 131 131 componentManager.SubscribeToMessageType(MT_ValueModification); 132 132 133 componentManager.SubscribeToMessageType(MT_Deserialized); 133 134 } … … 156 157 bool m_FacePointAfterMove; 157 158 158 // Number of turns since we last managed to move successfully. 159 // Whether the unit participates in pushing. 160 bool m_Pushing = true; 161 162 // Internal counter used when recovering from obstructed movement. 163 // Most notably, increases the search range of the vertex pathfinder. 159 164 // See HandleObstructedMove() for more details. 160 165 u8 m_FailedMovements = 0; … … 259 264 CmpPtr<ICmpObstruction> cmpObstruction(GetEntityHandle()); 260 265 if (cmpObstruction) 266 261 267 cmpObstruction->SetUnitClearance(m_Clearance); 268 269 270 262 271 } 263 272 … … 292 301 293 302 serialize.Bool("facePointAfterMove", m_FacePointAfterMove); 303 294 304 295 305 Serializer(serialize, "long path", m_LongPath.m_Waypoints); … … 340 350 if (!ENTITY_IS_LOCAL(GetEntityId())) 341 351 CmpPtr<ICmpUnitMotionManager>(GetSystemEntity())->Unregister(GetEntityId()); 352 353 354 355 356 357 358 342 359 break; 343 360 } … … 508 525 509 526 private: 510 bool ShouldAvoidMovingUnits() const511 {512 return !m_FormationController;513 }514 515 527 bool IsFormationMember() const 516 528 { … … 722 734 ControlGroupMovementObstructionFilter GetObstructionFilter() const 723 735 { 724 return ControlGroupMovementObstructionFilter( ShouldAvoidMovingUnits(), GetGroup());736 return ControlGroupMovementObstructionFilter(, GetGroup()); 725 737 } 726 738 /** 727 739 * Filter a specific tag on top of the existing control groups. 728 740 */ 729 Skip MovingTagAndControlGroupObstructionFilter GetObstructionFilter(const ICmpObstructionManager::tag_t& tag) const730 { 731 return Skip MovingTagAndControlGroupObstructionFilter(tag, GetGroup());741 SkipTagAndControlGroupObstructionFilter GetObstructionFilter(const ICmpObstructionManager::tag_t& tag) const 742 { 743 return Skip, GetGroup()); 732 744 } 733 745 … … 918 930 void CCmpUnitMotion::PreMove(CCmpUnitMotionManager::MotionState& state) 919 931 { 932 933 920 934 // If we were idle and will still be, no need for an update. 921 935 state.needUpdate = state.cmpPosition->IsInWorld() && 922 936 (m_CurSpeed != fixed::Zero() || m_MoveRequest.m_Type != MoveRequest::NONE); 937 938 939 940 941 942 943 944 945 946 947 948 923 949 } 924 950 … … 947 973 { 948 974 // Update the Position component after our movement (if we actually moved anywhere) 949 // When moving always set the angle in the direction of the movement.950 975 CFixedVector2D offset = state.pos - state.initialPos; 951 state.angle = atan2_approx(offset.X, offset.Y); 976 // When moving always set the angle in the direction of the movement, 977 // if we are not trying to move, assume this is pushing-related movement, 978 // and maintain the current angle instead. 979 if (IsMoveRequested()) 980 state.angle = atan2_approx(offset.X, offset.Y); 952 981 state.cmpPosition->MoveAndTurnTo(state.pos.X, state.pos.Y, state.angle); 953 982 … … 960 989 else if (!state.wasObstructed && state.pos != state.initialPos) 961 990 m_FailedMovements = 0; 991 992 993 994 962 995 963 996 // We may need to recompute our path sometimes (e.g. if our target moves). … … 1133 1166 void CCmpUnitMotion::UpdateMovementState(entity_pos_t speed) 1134 1167 { 1135 CmpPtr<ICmpObstruction> cmpObstruction(GetEntityHandle());1136 1168 CmpPtr<ICmpVisual> cmpVisual(GetEntityHandle()); 1137 // Idle this turn. 1138 if (speed == fixed::Zero()) 1139 { 1140 // Update moving flag if we moved last turn. 1141 if (m_CurSpeed > fixed::Zero() && cmpObstruction) 1142 cmpObstruction->SetMovingFlag(false); 1143 if (cmpVisual) 1169 if (cmpVisual) 1170 { 1171 if (speed == fixed::Zero()) 1144 1172 cmpVisual->SelectMovementAnimation("idle", fixed::FromInt(1)); 1145 } 1146 // Moved this turn 1147 else 1148 { 1149 // Update moving flag if we didn't move last turn. 1150 if (m_CurSpeed == fixed::Zero() && cmpObstruction) 1151 cmpObstruction->SetMovingFlag(true); 1152 if (cmpVisual) 1173 else 1153 1174 cmpVisual->SelectMovementAnimation(speed > (m_WalkSpeed / 2).Multiply(m_RunMultiplier + fixed::FromInt(1)) ? "run" : "walk", speed); 1154 1175 } … … 1299 1320 bool CCmpUnitMotion::TryGoingStraightToTarget(const CFixedVector2D& from) 1300 1321 { 1322 1323 1324 1325 1326 1327 1301 1328 CFixedVector2D targetPos; 1302 1329 if (!ComputeTargetPosition(targetPos)) … … 1333 1360 } 1334 1361 1362 1335 1363 if (specificIgnore.valid()) 1336 1364 { 1337 if (!cmpPathfinder->CheckMovement( SkipTagObstructionFilter(specificIgnore), from.X, from.Y, goalPos.X, goalPos.Y, m_Clearance, m_PassClass))1365 if (!cmpPathfinder->CheckMovement(ObstructionFilter(specificIgnore), from.X, from.Y, goalPos.X, goalPos.Y, m_Clearance, m_PassClass)) 1338 1366 return false; 1339 1367 } 1340 1368 else if (!cmpPathfinder->CheckMovement(GetObstructionFilter(), from.X, from.Y, goalPos.X, goalPos.Y, m_Clearance, m_PassClass)) 1341 1369 return false; 1342 1343 1370 1344 1371 // That route is okay, so update our path -
ps/trunk/source/simulation2/components/CCmpUnitMotionManager.h
r25125 r25182 23 23 24 24 #include "simulation2/MessageTypes.h" 25 26 25 27 #include "simulation2/system/EntityMap.h" 26 28 … … 32 34 static void ClassInit(CComponentManager& componentManager) 33 35 { 36 34 37 componentManager.SubscribeToMessageType(MT_TurnStart); 35 38 componentManager.SubscribeToMessageType(MT_Update_Final); … … 43 46 struct MotionState 44 47 { 48 49 45 50 // Component references - these must be kept alive for the duration of motion. 46 51 // NB: this is generally not something one should do, but because of the tight coupling here it's doable. … … 53 58 CFixedVector2D pos; 54 59 60 61 62 55 63 fixed initialAngle; 56 64 fixed angle; 57 65 66 67 68 69 70 71 72 73 58 74 // If true, the entity needs to be handled during movement. 59 bool needUpdate ;75 bool needUpdate; 60 76 61 // 'Leak' from UnitMotion. 62 bool wentStraight; 63 bool wasObstructed; 77 bool wentStraight = false; 78 bool wasObstructed = false; 79 80 // Clone of the obstruction manager flag for efficiency 81 bool isMoving = false; 64 82 }; 65 83 … … 67 85 EntityMap<MotionState> m_FormationControllers; 68 86 69 // T emporary vector, reconstructed each turn (stored here to avoid memory reallocations).70 std::vector<EntityMap<MotionState>::iterator> m_MovingUnits;87 // T. 88 > m_MovingUnits; 71 89 72 90 bool m_ComputingMotion; … … 79 97 virtual void Init(const CParamNode& UNUSED(paramNode)) 80 98 { 81 m_MovingUnits.reserve(40);82 99 } 83 100 … … 93 110 { 94 111 Init(paramNode); 112 95 113 } 96 114 … … 99 117 switch (msg.GetType()) 100 118 { 119 120 121 122 123 124 125 101 126 case MT_TurnStart: 102 127 { … … 131 156 } 132 157 158 159 133 160 void OnTurnStart(); 134 161 … … 136 163 void MoveFormations(fixed dt); 137 164 void Move(EntityMap<MotionState>& ents, fixed dt); 165 166 138 167 }; 168 169 170 171 172 173 174 175 176 177 139 178 140 179 REGISTER_COMPONENT_TYPE(UnitMotionManager) -
ps/trunk/source/simulation2/components/CCmpUnitMotion_System.cpp
r25126 r25182 21 21 #include "CCmpUnitMotionManager.h" 22 22 23 23 24 #include "ps/CLogger.h" 24 25 #include "ps/Profile.h" 26 27 25 28 26 29 // NB: this TU contains the CCmpUnitMotion/CCmpUnitMotionManager couple. … … 29 32 // To avoid inclusion issues, implementation of UnitMotionManager that uses UnitMotion is here. 30 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 31 62 void CCmpUnitMotionManager::Register(CCmpUnitMotion* component, entity_id_t ent, bool formationController) 32 63 { 33 MotionState state = { 34 CmpPtr<ICmpPosition>(GetSimContext(), ent), 35 component, 36 CFixedVector2D(), 37 CFixedVector2D(), 38 fixed::Zero(), 39 fixed::Zero(), 40 false, 41 false 42 }; 64 MotionState state(CmpPtr<ICmpPosition>(GetSimContext(), ent), component); 43 65 if (!formationController) 44 66 m_Units.insert(ent, state); … … 81 103 void CCmpUnitMotionManager::Move(EntityMap<MotionState>& ents, fixed dt) 82 104 { 83 m_MovingUnits.clear(); 105 PROFILE2("MotionMgr_Move"); 106 std::unordered_set<std::vector<EntityMap<MotionState>::iterator>*> assigned; 84 107 for (EntityMap<MotionState>::iterator it = ents.begin(); it != ents.end(); ++it) 85 108 { 86 it->second.cmpUnitMotion->PreMove(it->second); 87 if (!it->second.needUpdate) 109 if (!it->second.cmpPosition->IsInWorld()) 110 { 111 it->second.needUpdate = false; 88 112 continue; 89 m_MovingUnits.push_back(it); 113 } 114 else 115 it->second.cmpUnitMotion->PreMove(it->second); 90 116 it->second.initialPos = it->second.cmpPosition->GetPosition2D(); 91 117 it->second.initialAngle = it->second.cmpPosition->GetRotation().Y; 92 118 it->second.pos = it->second.initialPos; 93 119 it->second.angle = it->second.initialAngle; 94 } 95 96 for (EntityMap<MotionState>::iterator& it : m_MovingUnits) 97 { 98 it->second.cmpUnitMotion->Move(it->second, dt); 99 it->second.cmpUnitMotion->PostMove(it->second, dt); 100 } 101 } 120 ENSURE(it->second.pos.X.ToInt_RoundToZero() / PUSHING_GRID_SIZE < m_MovingUnits.width() && 121 it->second.pos.Y.ToInt_RoundToZero() / PUSHING_GRID_SIZE < m_MovingUnits.height()); 122 std::vector<EntityMap<MotionState>::iterator>& subdiv = m_MovingUnits.get( 123 it->second.pos.X.ToInt_RoundToZero() / PUSHING_GRID_SIZE, 124 it->second.pos.Y.ToInt_RoundToZero() / PUSHING_GRID_SIZE 125 ); 126 subdiv.emplace_back(it); 127 assigned.emplace(&subdiv); 128 } 129 130 for (std::vector<EntityMap<MotionState>::iterator>* vec : assigned) 131 for (EntityMap<MotionState>::iterator& it : *vec) 132 if (it->second.needUpdate) 133 it->second.cmpUnitMotion->Move(it->second, dt); 134 135 if (&ents == &m_Units) 136 { 137 PROFILE2("MotionMgr_Pushing"); 138 for (std::vector<EntityMap<MotionState>::iterator>* vec : assigned) 139 { 140 ENSURE(!vec->empty()); 141 142 std::vector<EntityMap<MotionState>::iterator>::iterator cit1 = vec->begin(); 143 do 144 { 145 if ((*cit1)->second.ignore) 146 continue; 147 std::vector<EntityMap<MotionState>::iterator>::iterator cit2 = cit1; 148 while(++cit2 != vec->end()) 149 if (!(*cit2)->second.ignore) 150 Push(**cit1, **cit2, dt); 151 } 152 while(++cit1 != vec->end()); 153 } 154 } 155 156 { 157 PROFILE2("MotionMgr_PushAdjust"); 158 CmpPtr<ICmpPathfinder> cmpPathfinder(GetSystemEntity()); 159 for (std::vector<EntityMap<MotionState>::iterator>* vec : assigned) 160 { 161 for (EntityMap<MotionState>::iterator& it : *vec) 162 { 163 164 if (!it->second.needUpdate || it->second.ignore) 165 continue; 166 167 // Prevent pushed units from crossing uncrossable boundaries 168 // (we can assume that normal movement didn't push units into impassable terrain). 169 if ((it->second.push.X != entity_pos_t::Zero() || it->second.push.Y != entity_pos_t::Zero()) && 170 !cmpPathfinder->CheckMovement(it->second.cmpUnitMotion->GetObstructionFilter(), 171 it->second.pos.X, it->second.pos.Y, 172 it->second.pos.X + it->second.push.X, it->second.pos.Y + it->second.push.Y, 173 it->second.cmpUnitMotion->m_Clearance, 174 it->second.cmpUnitMotion->m_PassClass)) 175 { 176 // Mark them as obstructed - this could possibly be optimised 177 // perhaps it'd make more sense to mark the pushers as blocked. 178 it->second.wasObstructed = true; 179 it->second.wentStraight = false; 180 it->second.push = CFixedVector2D(); 181 } 182 // Only apply pushing if the effect is significant enough. 183 if (it->second.push.CompareLength(MINIMAL_PUSHING) > 0) 184 { 185 // If there was an attempt at movement, and the pushed movement is in a sufficiently different direction 186 // (measured by an extremely arbitrary dot product) 187 // then mark the unit as obstructed still. 188 if (it->second.pos != it->second.initialPos && 189 (it->second.pos - it->second.initialPos).Dot(it->second.pos + it->second.push - it->second.initialPos) < entity_pos_t::FromInt(1)/2) 190 { 191 it->second.wasObstructed = true; 192 it->second.wentStraight = false; 193 // Push anyways. 194 } 195 it->second.pos += it->second.push; 196 } 197 it->second.push = CFixedVector2D(); 198 } 199 } 200 } 201 { 202 PROFILE2("MotionMgr_PostMove"); 203 for (EntityMap<MotionState>::value_type& data : ents) 204 { 205 if (!data.second.needUpdate) 206 continue; 207 data.second.cmpUnitMotion->PostMove(data.second, dt); 208 } 209 } 210 for (std::vector<EntityMap<MotionState>::iterator>* vec : assigned) 211 vec->clear(); 212 } 213 214 // TODO: ought to better simulate in-flight pushing, e.g. if units would cross in-between turns. 215 void CCmpUnitMotionManager::Push(EntityMap<MotionState>::value_type& a, EntityMap<MotionState>::value_type& b, fixed dt) 216 { 217 // The hard problem for pushing is knowing when to actually use the pathfinder to go around unpushable obstacles. 218 // For simplicitly, the current logic separates moving & stopped entities: 219 // moving entities will push moving entities, but not stopped ones, and vice-versa. 220 // this still delivers most of the value of pushing, without a lot of the complexity. 221 int movingPush = a.second.isMoving + b.second.isMoving; 222 223 // Exception: units in the same control group (i.e. the same formation) never push farther than themselves 224 // and are also allowed to push idle units (obstructions are ignored within formations, 225 // so pushing idle units makes one member crossing the formation look better). 226 if (a.second.controlGroup != INVALID_ENTITY && a.second.controlGroup == b.second.controlGroup) 227 movingPush = 0; 228 229 if (movingPush == 1) 230 return; 231 232 // Treat the clearances as a circle - they're defined as squares, so we'll slightly overcompensate the diagonal 233 // (they're also full-width instead of half, so we want to divide by two. sqrt(2)/2 is about 0.71 < 5/7). 234 entity_pos_t combinedClearance = (a.second.cmpUnitMotion->m_Clearance + b.second.cmpUnitMotion->m_Clearance) * 5 / 7; 235 entity_pos_t maxDist = combinedClearance; 236 if (movingPush) 237 maxDist += PUSHING_MOVING_INFLUENCE_EXTENSION; 238 239 CFixedVector2D offset = a.second.pos - b.second.pos; 240 if (offset.CompareLength(maxDist) > 0) 241 return; 242 243 entity_pos_t offsetLength = offset.Length(); 244 // If the offset is small enough that precision would be problematic, pick an arbitrary vector instead. 245 if (offsetLength <= entity_pos_t::Epsilon() * 10) 246 { 247 // Throw in some 'randomness' so that clumped units unclump more naturally. 248 bool dir = a.first % 2; 249 offset.X = entity_pos_t::FromInt(dir ? 1 : 0); 250 offset.Y = entity_pos_t::FromInt(dir ? 0 : 1); 251 offsetLength = entity_pos_t::FromInt(1); 252 } 253 else 254 { 255 offset.X = offset.X / offsetLength; 256 offset.Y = offset.Y / offsetLength; 257 } 258 259 // If the units are moving in opposite direction, check if they might have phased through each other. 260 // If it looks like yes, move them perpendicularily so it looks like they avoid each other. 261 // NB: this isn't very precise, nor will it catch 100% of intersections - it's meant as a cheap improvement. 262 if (movingPush && (a.second.pos - a.second.initialPos).Dot(b.second.pos - b.second.initialPos) < entity_pos_t::Zero()) 263 // Perform some finer checking. 264 if (Geometry::TestRayAASquare(a.second.initialPos - b.second.initialPos, a.second.pos - b.second.initialPos, 265 CFixedVector2D(combinedClearance, combinedClearance)) 266 || 267 Geometry::TestRayAASquare(a.second.initialPos - b.second.pos, a.second.pos - b.second.pos, 268 CFixedVector2D(combinedClearance, combinedClearance))) 269 { 270 offset = offset.Perpendicular(); 271 offsetLength = fixed::Zero(); 272 } 273 274 275 276 // The formula expects 'normal' pushing if the two entities edges are touching. 277 entity_pos_t distanceFactor = movingPush ? (maxDist - offsetLength) / (maxDist - combinedClearance) : combinedClearance - offsetLength + entity_pos_t::FromInt(1); 278 distanceFactor = Clamp(distanceFactor, entity_pos_t::Zero(), entity_pos_t::FromInt(2)); 279 280 // Mark both as needing an update so they actually get moved. 281 a.second.needUpdate = true; 282 b.second.needUpdate = true; 283 284 CFixedVector2D pushingDir = offset.Multiply(distanceFactor); 285 286 // Divide by an arbitrary constant to avoid pushing too much. 287 a.second.push += pushingDir.Multiply(movingPush ? dt : dt / PUSHING_REDUCTION_FACTOR); 288 b.second.push -= pushingDir.Multiply(movingPush ? dt : dt / PUSHING_REDUCTION_FACTOR); 289 } -
ps/trunk/source/simulation2/components/ICmpObstruction.cpp
r24010 r25182 1 /* Copyright (C) 202 0Wildfire Games.1 /* Copyright (C) 202 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * … … 56 56 DEFINE_INTERFACE_METHOD_1("SetActive", void, ICmpObstruction, SetActive, bool) 57 57 DEFINE_INTERFACE_METHOD_3("SetDisableBlockMovementPathfinding", void, ICmpObstruction, SetDisableBlockMovementPathfinding, bool, bool, int32_t) 58 DEFINE_INTERFACE_METHOD_CONST_ 0("GetBlockMovementFlag", bool, ICmpObstruction, GetBlockMovementFlag)58 DEFINE_INTERFACE_METHOD_CONST_) 59 59 DEFINE_INTERFACE_METHOD_1("SetControlGroup", void, ICmpObstruction, SetControlGroup, entity_id_t) 60 60 DEFINE_INTERFACE_METHOD_CONST_0("GetControlGroup", entity_id_t, ICmpObstruction, GetControlGroup) -
ps/trunk/source/simulation2/components/ICmpObstruction.h
r24010 r25182 1 /* Copyright (C) 202 0Wildfire Games.1 /* Copyright (C) 202 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * … … 139 139 virtual void SetDisableBlockMovementPathfinding(bool movementDisabled, bool pathfindingDisabled, int32_t shape) = 0; 140 140 141 virtual bool GetBlockMovementFlag() const = 0; 141 /** 142 * @param templateOnly - whether to return the raw template value or the current value. 143 */ 144 virtual bool GetBlockMovementFlag(bool templateOnly) const = 0; 142 145 143 146 /** -
ps/trunk/source/simulation2/components/ICmpObstructionManager.h
r24798 r25182 1 /* Copyright (C) 202 0Wildfire Games.1 /* Copyright (C) 202 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * … … 93 93 FLAG_BLOCK_CONSTRUCTION = (1 << 2), // prevents buildings being constructed on this shape 94 94 FLAG_BLOCK_PATHFINDING = (1 << 3), // prevents the tile pathfinder choosing paths through this shape 95 FLAG_MOVING = (1 << 4), // indicates this unit is currently moving95 FLAG_MOVING = (1 << 4), // 96 96 FLAG_DELETE_UPON_CONSTRUCTION = (1 << 5) // this entity is deleted when construction of a building placed on top of this entity starts 97 97 }; … … 531 531 532 532 /** 533 * Obstruction test filter that reject shapes in a given control group or with the given tag (if that tag is moving), 534 * and rejects shapes that don't block unit movement. See D3482 for why this exists. 535 */ 536 class SkipMovingTagAndControlGroupObstructionFilter : public IObstructionTestFilter 533 * Similar to ControlGroupMovementObstructionFilter, but also ignoring a specific tag. See D3482 for why this exists. 534 */ 535 class SkipTagAndControlGroupObstructionFilter : public IObstructionTestFilter 537 536 { 538 537 entity_id_t m_Group; 539 538 tag_t m_Tag; 540 541 public: 542 SkipMovingTagAndControlGroupObstructionFilter(tag_t tag, entity_id_t group) : 543 m_Tag(tag), m_Group(group) 539 bool m_AvoidMoving; 540 541 public: 542 SkipTagAndControlGroupObstructionFilter(tag_t tag, bool avoidMoving, entity_id_t group) : 543 m_Tag(tag), m_Group(group), m_AvoidMoving(avoidMoving) 544 544 {} 545 545 546 546 virtual bool TestShape(tag_t tag, flags_t flags, entity_id_t group, entity_id_t group2) const 547 547 { 548 if (tag.n == m_Tag.n && (flags & ICmpObstructionManager::FLAG_MOVING))548 if (tag.n == m_Tag.n) 549 549 return false; 550 550 551 551 if (group == m_Group || (group2 != INVALID_ENTITY && group2 == m_Group)) 552 553 554 552 555 return false; 553 556 -
ps/trunk/source/simulation2/components/tests/test_ObstructionManager.h
r24268 r25182 1 /* Copyright (C) 202 0Wildfire Games.1 /* Copyright (C) 202 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * … … 48 48 virtual void SetMovingFlag(bool UNUSED(enabled)) { } 49 49 virtual void SetDisableBlockMovementPathfinding(bool UNUSED(movementDisabled), bool UNUSED(pathfindingDisabled), int32_t UNUSED(shape)) { } 50 virtual bool GetBlockMovementFlag( ) const { return true; }50 virtual bool GetBlockMovementFlag() const { return true; } 51 51 virtual void SetControlGroup(entity_id_t UNUSED(group)) { } 52 52 virtual entity_id_t GetControlGroup() const { return INVALID_ENTITY; } -
ps/trunk/source/simulation2/components/tests/test_RangeManager.h
r24980 r25182 1 /* Copyright (C) 202 0Wildfire Games.1 /* Copyright (C) 202 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * … … 104 104 virtual void SetMovingFlag(bool) {}; 105 105 virtual void SetDisableBlockMovementPathfinding(bool, bool, int32_t) {}; 106 virtual bool GetBlockMovementFlag( ) const { return {}; };106 virtual bool GetBlockMovementFlag() const { return {}; }; 107 107 virtual void SetControlGroup(entity_id_t) {}; 108 108 virtual entity_id_t GetControlGroup() const { return {}; }; -
ps/trunk/source/simulation2/helpers/LongPathfinder.h
r24352 r25182 1 /* Copyright (C) 202 0Wildfire Games.1 /* Copyright (C) 202 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * … … 261 261 /** 262 262 * Given a path with an arbitrary collection of waypoints, updates the 263 * waypoints to be nicer. Calls "Testline" between waypoints 264 * so that bended paths can become straight if there's nothing in between 265 * (this happens because A* is 8-direction, and the map isn't actually a grid). 263 * waypoints to be nicer. 266 264 * If @param maxDist is non-zero, path waypoints will be espaced by at most @param maxDist. 267 265 * In that case the distance between (x0, z0) and the first waypoint will also be made less than maxDist. -
ps/trunk/source/simulation2/scripting/MessageTypeConversions.cpp
r24511 r25182 1 /* Copyright (C) 202 0Wildfire Games.1 /* Copyright (C) 202 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * … … 357 357 //////////////////////////////// 358 358 359 360 361 362 363 364 365 366 367 368 369 370 371 359 372 JS::Value CMessageObstructionMapShapeChanged::ToJSVal(const ScriptInterface& scriptInterface) const 360 373 {
Note:
See TracChangeset
for help on using the changeset viewer.