Changeset View
Changeset View
Standalone View
Standalone View
source/graphics/Unit.cpp
/* Copyright (C) 2020 Wildfire Games. | /* Copyright (C) 2021 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
Show All 11 Lines | |||||
#include "Model.h" | #include "Model.h" | ||||
#include "ObjectBase.h" | #include "ObjectBase.h" | ||||
#include "ObjectEntry.h" | #include "ObjectEntry.h" | ||||
#include "ObjectManager.h" | #include "ObjectManager.h" | ||||
#include "SkeletonAnim.h" | #include "SkeletonAnim.h" | ||||
#include "SkeletonAnimDef.h" | #include "SkeletonAnimDef.h" | ||||
#include "UnitAnimation.h" | #include "UnitAnimation.h" | ||||
CUnit::CUnit(CObjectEntry* object, CObjectManager& objectManager, | CUnit::CUnit(CObjectManager& objectManager, const CActorDef& actor, uint32_t seed) | ||||
const std::set<CStr>& actorSelections, uint32_t seed) | : m_ID(INVALID_ENTITY), m_ObjectManager(objectManager), m_Actor(actor), m_Seed(seed), m_Animation(nullptr) | ||||
: m_Object(object), m_Model(object->m_Model->Clone()), | |||||
m_ID(INVALID_ENTITY), m_ActorSelections(actorSelections), | |||||
m_ObjectManager(objectManager), m_Seed(seed) | |||||
{ | { | ||||
if (m_Model->ToCModel()) | |||||
m_Animation = new CUnitAnimation(m_ID, m_Model->ToCModel(), m_Object); | |||||
else | |||||
m_Animation = NULL; | |||||
} | } | ||||
CUnit::~CUnit() | CUnit::~CUnit() | ||||
{ | { | ||||
delete m_Animation; | delete m_Animation; | ||||
delete m_Model; | delete m_Model; | ||||
} | } | ||||
CUnit* CUnit::Create(const CStrW& actorName, uint32_t seed, const std::set<CStr>& selections, CObjectManager& objectManager) | CUnit* CUnit::Create(const CStrW& actorName, uint32_t seed, const std::set<CStr>& selections, CObjectManager& objectManager) | ||||
{ | { | ||||
CObjectBase* base = objectManager.FindObjectBase(actorName); | CActorDef* actor = objectManager.FindActorDef(actorName); | ||||
if (! base) | |||||
return NULL; | |||||
std::set<CStr> actorSelections = base->CalculateRandomVariation(seed, selections); | |||||
std::vector<std::set<CStr> > selectionsVec; | if (!actor) | ||||
selectionsVec.push_back(actorSelections); | return nullptr; | ||||
CObjectEntry* obj = objectManager.FindObjectVariation(base, selectionsVec); | CUnit* unit = new CUnit(objectManager, *actor, seed); | ||||
unit->SetActorSelections(selections); // Calls ReloadObject(). | |||||
if (! obj) | if (!unit->m_Model) | ||||
return NULL; | { | ||||
delete unit; | |||||
return new CUnit(obj, objectManager, actorSelections, seed); | return nullptr; | ||||
} | |||||
return unit; | |||||
} | } | ||||
void CUnit::UpdateModel(float frameTime) | void CUnit::UpdateModel(float frameTime) | ||||
{ | { | ||||
if (m_Animation) | if (m_Animation) | ||||
m_Animation->Update(frameTime*1000.0f); | m_Animation->Update(frameTime*1000.0f); | ||||
} | } | ||||
Show All 29 Lines | void CUnit::SetActorSelections(const std::set<CStr>& selections) | ||||
ReloadObject(); | ReloadObject(); | ||||
} | } | ||||
void CUnit::ReloadObject() | void CUnit::ReloadObject() | ||||
{ | { | ||||
std::set<CStr> entitySelections; | std::set<CStr> entitySelections; | ||||
for (const std::pair<const CStr, CStr>& selection : m_EntitySelections) | for (const std::pair<const CStr, CStr>& selection : m_EntitySelections) | ||||
entitySelections.insert(selection.second); | entitySelections.insert(selection.second); | ||||
std::vector<std::set<CStr> > selections; | std::vector<std::set<CStr>> selections; | ||||
selections.push_back(entitySelections); | selections.push_back(entitySelections); | ||||
selections.push_back(m_ActorSelections); | selections.push_back(m_ActorSelections); | ||||
// randomly select any remain selections necessary to completely identify a variation (e.g., the new selection | // randomly select any remain selections necessary to completely identify a variation (e.g., the new selection | ||||
// made might define some additional props that require a random variant choice). Also, FindObjectVariation | // made might define some additional props that require a random variant choice). Also, FindObjectVariation | ||||
// expects the selectors passed to it to be complete. | // expects the selectors passed to it to be complete. | ||||
// see http://trac.wildfiregames.com/ticket/979 | // see http://trac.wildfiregames.com/ticket/979 | ||||
// If these selections give a different object, change this unit to use it | |||||
// Use the entity ID as randomization seed (same as when the unit was first created) | // Use the entity ID as randomization seed (same as when the unit was first created) | ||||
std::set<CStr> remainingSelections = m_Object->m_Base->CalculateRandomRemainingSelections(m_Seed, selections); | CObjectEntry* newObject = m_ObjectManager.FindObjectVariation(&m_Actor, selections, m_Seed); | ||||
if (!remainingSelections.empty()) | if (!newObject) | ||||
selections.push_back(remainingSelections); | { | ||||
LOGERROR("Error loading object variation (actor: %s)", m_Actor.GetPathname().string8()); | |||||
// Don't delete the unit, don't override our current (valid) state. | |||||
return; | |||||
} | |||||
// If these selections give a different object, change this unit to use it | if (!m_Object) | ||||
CObjectEntry* newObject = m_ObjectManager.FindObjectVariation(m_Object->m_Base, selections); | { | ||||
if (newObject && newObject != m_Object) | m_Object = newObject; | ||||
m_Model = newObject->m_Model->Clone(); | |||||
if (m_Model->ToCModel()) | |||||
m_Animation = new CUnitAnimation(m_ID, m_Model->ToCModel(), m_Object); | |||||
} | |||||
else if (m_Object && newObject != m_Object) | |||||
{ | { | ||||
// Clone the new object's base (non-instance) model | // Clone the new object's base (non-instance) model | ||||
CModelAbstract* newModel = newObject->m_Model->Clone(); | CModelAbstract* newModel = newObject->m_Model->Clone(); | ||||
// Copy the old instance-specific settings from the old model to the new instance | // Copy the old instance-specific settings from the old model to the new instance | ||||
newModel->SetTransform(m_Model->GetTransform()); | newModel->SetTransform(m_Model->GetTransform()); | ||||
newModel->SetPlayerID(m_Model->GetPlayerID()); | newModel->SetPlayerID(m_Model->GetPlayerID()); | ||||
if (newModel->ToCModel() && m_Model->ToCModel()) | if (newModel->ToCModel() && m_Model->ToCModel()) | ||||
Show All 25 Lines |
Wildfire Games · Phabricator