Ticket #4270: fix-visualactor-save-reload.3.patch
File fix-visualactor-save-reload.3.patch, 8.9 KB (added by , 8 years ago) |
---|
-
source/simulation2/components/CCmpUnitMotion.cpp
339 339 serialize.NumberFixed_Unbounded("target max range", m_TargetMaxRange); 340 340 341 341 serialize.NumberFixed_Unbounded("speed", m_Speed); 342 serialize.NumberFixed_Unbounded("current speed", m_CurSpeed); 342 343 343 344 serialize.Bool("moving", m_Moving); 344 345 serialize.Bool("facePointAfterMove", m_FacePointAfterMove); -
source/simulation2/components/CCmpVisualActor.cpp
81 81 std::wstring m_SoundGroup; 82 82 fixed m_AnimDesync; 83 83 fixed m_AnimSyncRepeatTime; // 0.0 if not synced 84 fixed m_AnimSyncOffsetTime; 84 85 85 86 std::map<CStr, CStr> m_VariantSelections; 86 87 … … 205 206 206 207 InitModel(paramNode); 207 208 208 // We need to select animation even if graphics are disabled, as this modifies serialized state209 209 SelectAnimation("idle", false, fixed::FromInt(1), L""); 210 210 } 211 211 … … 225 225 serialize.NumberFixed_Unbounded("g", m_G); 226 226 serialize.NumberFixed_Unbounded("b", m_B); 227 227 228 SerializeMap<SerializeString, SerializeString>()(serialize, "anim overrrides", m_AnimOverride); 229 228 230 serialize.NumberFixed_Unbounded("anim run threshold", m_AnimRunThreshold); 229 231 serialize.StringASCII("anim name", m_AnimName, 0, 256); 230 232 serialize.Bool("anim once", m_AnimOnce); … … 232 234 serialize.String("sound group", m_SoundGroup, 0, 256); 233 235 serialize.NumberFixed_Unbounded("anim desync", m_AnimDesync); 234 236 serialize.NumberFixed_Unbounded("anim sync repeat time", m_AnimSyncRepeatTime); 237 serialize.NumberFixed_Unbounded("anim sync offset time", m_AnimSyncOffsetTime); 235 238 236 239 SerializeMap<SerializeString, SerializeString>()(serialize, "variation", m_VariantSelections); 237 240 … … 264 267 // If we serialized a different seed or different actor, reload actor 265 268 if (oldSeed != GetActorSeed() || m_BaseActorName != m_ActorName) 266 269 ReloadActor(); 267 else if (m_Unit)268 m_Unit->SetEntitySelection(m_VariantSelections);269 270 fixed repeattime = m_AnimSyncRepeatTime; // save because SelectAnimation overwrites it271 272 if (m_AnimRunThreshold.IsZero())273 SelectAnimation(m_AnimName, m_AnimOnce, m_AnimSpeed, m_SoundGroup);274 270 else 275 SelectMovementAnimation(m_AnimRunThreshold);271 ReloadUnitAnimation(); 276 272 277 SetAnimationSyncRepeat(repeattime);278 279 273 if (m_Unit) 280 274 { 281 275 CmpPtr<ICmpOwnership> cmpOwnership(GetEntityHandle()); … … 287 281 virtual void HandleMessage(const CMessage& msg, bool UNUSED(global)) 288 282 { 289 283 // Quick exit for running in non-graphical mode 290 if (m_Unit == NULL)291 return;284 //if (!m_Unit) 285 // return; 292 286 293 287 switch (msg.GetType()) 294 288 { … … 301 295 case MT_OwnershipChanged: 302 296 { 303 297 const CMessageOwnershipChanged& msgData = static_cast<const CMessageOwnershipChanged&> (msg); 304 m_Unit->GetModel().SetPlayerID(msgData.to);298 if (m_Unit) { m_Unit->GetModel().SetPlayerID(msgData.to); } 305 299 break; 306 300 } 307 301 case MT_TerrainChanged: 308 302 { 309 303 const CMessageTerrainChanged& msgData = static_cast<const CMessageTerrainChanged&> (msg); 310 m_Unit->GetModel().SetTerrainDirty(msgData.i0, msgData.j0, msgData.i1, msgData.j1);304 if (m_Unit) { m_Unit->GetModel().SetTerrainDirty(msgData.i0, msgData.j0, msgData.i1, msgData.j1); } 311 305 break; 312 306 } 313 307 case MT_ValueModification: … … 435 429 m_AnimDesync = fixed::FromInt(1)/20; // TODO: make this an argument 436 430 m_AnimSyncRepeatTime = fixed::Zero(); 437 431 432 SetVariant("animation", m_AnimName); 433 438 434 if (m_Unit) 439 435 { 440 SetVariant("animation", m_AnimName);441 436 if (m_Unit->GetAnimation()) 442 437 m_Unit->GetAnimation()->SetAnimationState(m_AnimName, m_AnimOnce, m_AnimSpeed.ToFloat(), m_AnimDesync.ToFloat(), m_SoundGroup.c_str()); 443 438 } … … 457 452 458 453 virtual void SelectMovementAnimation(fixed runThreshold) 459 454 { 455 SelectAnimation("walk", false, fixed::FromFloat(1.f), L""); 460 456 m_AnimRunThreshold = runThreshold; 461 462 if (m_Unit)463 {464 SetVariant("animation", "walk");465 if (m_Unit->GetAnimation())466 m_Unit->GetAnimation()->SetAnimationState("walk", false, 1.f, 0.f, L"");467 }468 457 } 469 458 470 459 virtual void SetAnimationSyncRepeat(fixed repeattime) … … 480 469 481 470 virtual void SetAnimationSyncOffset(fixed actiontime) 482 471 { 472 m_AnimSyncOffsetTime = actiontime; 473 483 474 if (m_Unit) 484 475 { 485 476 if (m_Unit->GetAnimation()) 486 m_Unit->GetAnimation()->SetAnimationSyncOffset( actiontime.ToFloat());477 m_Unit->GetAnimation()->SetAnimationSyncOffset(m_AnimSyncOffsetTime.ToFloat()); 487 478 } 488 479 } 489 480 … … 546 537 /// Helper method; initializes the model selection shape descriptor from XML. Factored out for readability of @ref Init. 547 538 void InitSelectionShapeDescriptor(const CParamNode& paramNode); 548 539 540 // ReloadActor is used when the actor or seed changes. 549 541 void ReloadActor(); 542 // ReloadUnitAnimation is used for a minimal reloading upon deserialization, when the actor and seed are identical. 543 // It is also used by ReloadActor. 544 void ReloadUnitAnimation(); 550 545 551 546 void Update(fixed turnLength); 552 547 }; … … 720 715 721 716 InitModel(node->GetChild("VisualActor")); 722 717 723 m_Unit->SetEntitySelection(m_VariantSelections);718 ReloadUnitAnimation(); 724 719 725 if (m_Unit->GetAnimation())726 m_Unit->GetAnimation()->SetAnimationState(m_AnimName, m_AnimOnce, m_AnimSpeed.ToFloat(), m_AnimDesync.ToFloat(), m_SoundGroup.c_str());727 728 // We'll lose the exact synchronisation but we should at least make sure it's going at the correct rate729 if (!m_AnimSyncRepeatTime.IsZero())730 if (m_Unit->GetAnimation())731 m_Unit->GetAnimation()->SetAnimationSyncRepeat(m_AnimSyncRepeatTime.ToFloat());732 733 720 m_Unit->GetModel().SetShadingColor(shading); 734 721 735 722 m_Unit->GetModel().SetPlayerID(playerID); … … 743 730 } 744 731 } 745 732 746 void CCmpVisualActor:: Update(fixed UNUSED(turnLength))733 void CCmpVisualActor::ReloadUnitAnimation() 747 734 { 748 735 if (!m_Unit) 749 736 return; 750 737 751 // If we're in the special movement mode, select an appropriate animation 752 if (!m_AnimRunThreshold.IsZero()) 753 { 754 CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle()); 755 if (!cmpPosition || !cmpPosition->IsInWorld()) 756 return; 738 m_Unit->SetEntitySelection(m_VariantSelections); 757 739 758 CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetEntityHandle()); 759 if (!cmpUnitMotion) 760 return; 740 if (!m_Unit->GetAnimation()) 741 return; 761 742 762 float speed = cmpUnitMotion->GetCurrentSpeed().ToFloat();743 m_Unit->GetAnimation()->SetAnimationState(m_AnimName, m_AnimOnce, m_AnimSpeed.ToFloat(), m_AnimDesync.ToFloat(), m_SoundGroup.c_str()); 763 744 764 std::string name; 765 if (speed == 0.0f) 766 name = "idle"; 767 else 768 name = (speed < m_AnimRunThreshold.ToFloat()) ? "walk" : "run"; 745 // We'll lose the exact synchronisation but we should at least make sure it's going at the correct rate 746 if (!m_AnimSyncRepeatTime.IsZero()) 747 m_Unit->GetAnimation()->SetAnimationSyncRepeat(m_AnimSyncRepeatTime.ToFloat()); 748 if (!m_AnimSyncOffsetTime.IsZero()) 749 m_Unit->GetAnimation()->SetAnimationSyncOffset(m_AnimSyncOffsetTime.ToFloat()); 750 } 769 751 770 std::map<std::string, std::string>::const_iterator it = m_AnimOverride.find(name); 771 if (it != m_AnimOverride.end()) 772 name = it->second; 752 void CCmpVisualActor::Update(fixed UNUSED(turnLength)) 753 { 754 // This function is currently only used to update the animation if the speed in 755 // CCmpUnitMotion changes. This also only happens in the "special movement mode" 756 // triggered by SelectMovementAnimation. 773 757 774 SetVariant("animation", name); 775 if (m_Unit->GetAnimation()) 776 { 777 if (speed == 0.0f) 778 m_Unit->GetAnimation()->SetAnimationState(name, false, 1.f, 0.f, L""); 779 else 780 m_Unit->GetAnimation()->SetAnimationState(name, false, speed, 0.f, L""); 781 } 758 // TODO: This should become event based, in order to save performance and to make the code 759 // far less hacky. We should also take into account the speed when the animation is different 760 // from the "special movement mode" walking animation. 761 762 // If we're not in the special movement mode, nothing to do. 763 if (m_AnimRunThreshold.IsZero()) 764 return; 765 766 CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle()); 767 if (!cmpPosition || !cmpPosition->IsInWorld()) 768 return; 769 770 CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetEntityHandle()); 771 if (!cmpUnitMotion) 772 return; 773 774 fixed speed = cmpUnitMotion->GetCurrentSpeed(); 775 std::string name; 776 777 if (speed.IsZero()) 778 { 779 speed = fixed::FromFloat(1.f); 780 name = "idle"; 782 781 } 782 else 783 name = (speed < m_AnimRunThreshold) ? "walk" : "run"; 784 785 std::map<std::string, std::string>::const_iterator it = m_AnimOverride.find(name); 786 if (it != m_AnimOverride.end()) 787 name = it->second; 788 789 // Selecting the animation is going to reset the anim run threshold, so save it 790 fixed runThreshold = m_AnimRunThreshold; 791 SelectAnimation(name, false, speed, L""); 792 m_AnimRunThreshold = runThreshold; 783 793 }