Changeset 25071
- Timestamp:
- Mar 17, 2021, 6:04:51 PM (3 years ago)
- Location:
- ps/trunk/source/simulation2
- Files:
-
- 3 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
ps/trunk/source/simulation2/TypeList.h
r24161 r25071 1 /* Copyright (C) 202 0Wildfire Games.1 /* Copyright (C) 202 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * … … 197 197 COMPONENT(UnitMotionScripted) 198 198 199 200 201 199 202 INTERFACE(UnitRenderer) 200 203 COMPONENT(UnitRenderer) -
ps/trunk/source/simulation2/components/CCmpUnitMotion.cpp
r25017 r25071 120 120 static void ClassInit(CComponentManager& componentManager) 121 121 { 122 componentManager.SubscribeToMessageType(MT_TurnStart); 123 componentManager.SubscribeToMessageType(MT_Update_MotionFormation); 124 componentManager.SubscribeToMessageType(MT_Update_MotionUnit); 122 componentManager.SubscribeToMessageType(MT_Create); 123 componentManager.SubscribeToMessageType(MT_Destroy); 125 124 componentManager.SubscribeToMessageType(MT_PathResult); 126 125 componentManager.SubscribeToMessageType(MT_OwnershipChanged); … … 207 206 WaypointPath m_LongPath; 208 207 WaypointPath m_ShortPath; 209 210 // Hack - units move one-at-a-time, so they may need to interplate their target position.211 // However, some computations are not doing during the motion messages, and those shouldn't (e.g. turn start).212 // This is true if and only if the calls take place during handling of the entity's MT_Motion* messages.213 // NB: this won't be true if we end up in UnitMotion because of another entity's motion messages,214 // but I think it fixes the issue of interpolating target position OK for current needs,215 // without having to add parameters everywhere.216 // No need for serialisation, it's just a transient boolean.217 bool m_InMotionMessage = false;218 208 219 209 static std::string GetSchema() … … 322 312 switch (msg.GetType()) 323 313 { 324 case MT_TurnStart:325 {326 TurnStart();327 break;328 }329 case MT_Update_MotionFormation:330 {331 if (m_FormationController)332 {333 m_InMotionMessage = true;334 fixed dt = static_cast<const CMessageUpdate_MotionFormation&> (msg).turnLength;335 Move(dt);336 m_InMotionMessage = false;337 }338 break;339 }340 case MT_Update_MotionUnit:341 {342 if (!m_FormationController)343 {344 m_InMotionMessage = true;345 fixed dt = static_cast<const CMessageUpdate_MotionUnit&> (msg).turnLength;346 Move(dt);347 m_InMotionMessage = false;348 }349 break;350 }351 314 case MT_RenderSubmit: 352 315 { … … 362 325 break; 363 326 } 327 328 329 330 331 332 333 334 335 336 337 338 364 339 case MT_ValueModification: 365 340 { … … 370 345 } 371 346 case MT_OwnershipChanged: 347 348 349 350 372 351 case MT_Deserialized: 373 352 { 374 CmpPtr<ICmpValueModificationManager> cmpValueModificationManager(GetSystemEntity()); 375 if (!cmpValueModificationManager) 376 break; 377 378 m_WalkSpeed = cmpValueModificationManager->ApplyModifications(L"UnitMotion/WalkSpeed", m_TemplateWalkSpeed, GetEntityId()); 379 m_RunMultiplier = cmpValueModificationManager->ApplyModifications(L"UnitMotion/RunMultiplier", m_TemplateRunMultiplier, GetEntityId()); 380 381 // For MT_Deserialize compute m_Speed from the serialized m_SpeedMultiplier. 382 // For MT_ValueModification and MT_OwnershipChanged, adjust m_SpeedMultiplier if needed 383 // (in case then new m_RunMultiplier value is lower than the old). 384 SetSpeedMultiplier(m_SpeedMultiplier); 385 353 OnValueModification(); 354 if (!ENTITY_IS_LOCAL(GetEntityId())) 355 CmpPtr<ICmpUnitMotionManager>(GetSystemEntity())->Register(GetEntityId(), m_FormationController); 386 356 break; 387 357 } … … 652 622 void PathResult(u32 ticket, const WaypointPath& path); 653 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 654 639 /** 655 640 * Check if we are at destination early in the turn, this both lets units react faster … … 657 642 * (otherwise they won't be commutative). 658 643 */ 659 void TurnStart(); 660 661 /** 662 * Do the per-turn movement and other updates. 663 */ 664 void Move(fixed dt); 644 virtual void OnTurnStart(); 645 646 virtual void PreMove(ICmpUnitMotionManager::MotionState& state); 647 648 virtual void Move(ICmpUnitMotionManager::MotionState& state, fixed dt); 649 650 virtual void PostMove(ICmpUnitMotionManager::MotionState& state, fixed dt); 665 651 666 652 /** … … 909 895 } 910 896 911 void CCmpUnitMotion:: TurnStart()897 void CCmpUnitMotion::TurnStart() 912 898 { 913 899 if (PossiblyAtDestination()) … … 927 913 } 928 914 929 void CCmpUnitMotion::Move(fixed dt) 915 void CCmpUnitMotion::PreMove(ICmpUnitMotionManager::MotionState& state) 916 { 917 // If we were idle and will still be, no need for an update. 918 state.needUpdate = m_CurSpeed != fixed::Zero() || m_MoveRequest.m_Type != MoveRequest::NONE; 919 } 920 921 void CCmpUnitMotion::Move(ICmpUnitMotionManager::MotionState& state, fixed dt) 930 922 { 931 923 PROFILE("Move"); 932 933 // If we were idle and will still be, we can return.934 // TODO: this will need to be removed if pushing is implemented.935 if (m_CurSpeed == fixed::Zero() && m_MoveRequest.m_Type == MoveRequest::NONE)936 return;937 938 CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle());939 if (!cmpPosition || !cmpPosition->IsInWorld())940 return;941 942 CFixedVector2D initialPos = cmpPosition->GetPosition2D();943 entity_angle_t initialAngle = cmpPosition->GetRotation().Y;944 945 // Keep track of the current unit's position and rotation during the update.946 CFixedVector2D pos = initialPos;947 entity_angle_t angle = initialAngle;948 924 949 925 // If we're chasing a potentially-moving unit and are currently close 950 926 // enough to its current position, and we can head in a straight line 951 // to it, then throw away our current path and go straight to it 952 bool wentStraight = TryGoingStraightToTarget(initialPos); 953 954 bool wasObstructed = PerformMove(dt, cmpPosition->GetTurnRate(), m_ShortPath, m_LongPath, pos, angle); 955 927 // to it, then throw away our current path and go straight to it. 928 state.wentStraight = TryGoingStraightToTarget(state.initialPos); 929 930 state.wasObstructed = PerformMove(dt, state.cmpPosition->GetTurnRate(), m_ShortPath, m_LongPath, state.pos, state.angle); 931 } 932 933 void CCmpUnitMotion::PostMove(ICmpUnitMotionManager::MotionState& state, fixed dt) 934 { 956 935 // Update our speed over this turn so that the visual actor shows the correct animation. 957 if ( pos ==initialPos)958 { 959 if ( angle !=initialAngle)960 cmpPosition->TurnTo(angle);936 if (initialPos) 937 { 938 if (initialAngle) 939 angle); 961 940 UpdateMovementState(fixed::Zero()); 962 941 } … … 965 944 // Update the Position component after our movement (if we actually moved anywhere) 966 945 // When moving always set the angle in the direction of the movement. 967 CFixedVector2D offset = pos -initialPos;968 angle = atan2_approx(offset.X, offset.Y);969 cmpPosition->MoveAndTurnTo(pos.X, pos.Y,angle);946 CFixedVector2D offset = initialPos; 947 angle = atan2_approx(offset.X, offset.Y); 948 angle); 970 949 971 950 // Calculate the mean speed over this past turn. … … 973 952 } 974 953 975 if ( wasObstructed && HandleObstructedMove(pos !=initialPos))954 if (initialPos)) 976 955 return; 977 else if (! wasObstructed && pos !=initialPos)956 else if (!initialPos) 978 957 m_FailedMovements = 0; 979 958 980 959 // We may need to recompute our path sometimes (e.g. if our target moves). 981 960 // Since we request paths asynchronously anyways, this does not need to be done before moving. 982 if (! wentStraight && PathingUpdateNeeded(pos))961 if (!pos)) 983 962 { 984 963 PathGoal goal; 985 964 if (ComputeGoal(goal, m_MoveRequest)) 986 ComputePathToGoal( pos, goal);965 ComputePathToGoal(pos, goal); 987 966 } 988 967 else if (m_FollowKnownImperfectPathCountdown > 0) … … 1277 1256 // TODO: This does not really aim many turns in advance, with orthogonal trajectories it probably should. 1278 1257 CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetSimContext(), moveRequest.m_Entity); 1279 bool needInterpolation = cmpUnitMotion && cmpUnitMotion->IsMoveRequested() && m_InMotionMessage; 1258 CmpPtr<ICmpUnitMotionManager> cmpUnitMotionManager(GetSystemEntity()); 1259 bool needInterpolation = cmpUnitMotion && cmpUnitMotion->IsMoveRequested() && cmpUnitMotionManager->ComputingMotion(); 1280 1260 if (needInterpolation && GetEntityId() < moveRequest.m_Entity) 1281 1261 { -
ps/trunk/source/simulation2/components/ICmpUnitMotion.cpp
r24707 r25071 48 48 public: 49 49 DEFAULT_SCRIPT_WRAPPER(UnitMotionScripted) 50 51 52 53 54 55 56 57 50 58 51 59 virtual bool MoveToPointRange(entity_pos_t x, entity_pos_t z, entity_pos_t minRange, entity_pos_t maxRange) -
ps/trunk/source/simulation2/components/ICmpUnitMotion.h
r24701 r25071 23 23 #include "simulation2/components/ICmpPathfinder.h" // for pass_class_t 24 24 #include "simulation2/components/ICmpPosition.h" // for entity_pos_t 25 26 27 25 28 26 29 /** … … 34 37 class ICmpUnitMotion : public IComponent 35 38 { 39 40 41 42 43 44 45 46 47 48 49 36 50 public: 37 51 -
ps/trunk/source/simulation2/system/ComponentManager.cpp
r24969 r25071 678 678 AddComponent(m_SystemEntity, CID_Terrain, noParam); 679 679 AddComponent(m_SystemEntity, CID_TerritoryManager, noParam); 680 680 681 AddComponent(m_SystemEntity, CID_UnitRenderer, noParam); 681 682 AddComponent(m_SystemEntity, CID_WaterManager, noParam);
Note:
See TracChangeset
for help on using the changeset viewer.