Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Unit.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2013 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "precompiled.h"
19 
20 #include "Unit.h"
21 #include "Model.h"
22 #include "ObjectBase.h"
23 #include "ObjectEntry.h"
24 #include "ObjectManager.h"
25 #include "SkeletonAnim.h"
26 #include "SkeletonAnimDef.h"
27 #include "UnitAnimation.h"
28 
29 CUnit::CUnit(CObjectEntry* object, CObjectManager& objectManager,
30  const std::set<CStr>& actorSelections, uint32_t seed)
31 : m_Object(object), m_Model(object->m_Model->Clone()),
32  m_ID(INVALID_ENTITY), m_ActorSelections(actorSelections),
33  m_ObjectManager(objectManager), m_Seed(seed)
34 {
35  if (m_Model->ToCModel())
37  else
38  m_Animation = NULL;
39 }
40 
42 {
43  delete m_Animation;
44  delete m_Model;
45 }
46 
47 CUnit* CUnit::Create(const CStrW& actorName, uint32_t seed, const std::set<CStr>& selections, CObjectManager& objectManager)
48 {
49  CObjectBase* base = objectManager.FindObjectBase(actorName);
50 
51  if (! base)
52  return NULL;
53 
54  std::set<CStr> actorSelections = base->CalculateRandomVariation(seed, selections);
55 
56  std::vector<std::set<CStr> > selectionsVec;
57  selectionsVec.push_back(actorSelections);
58 
59  CObjectEntry* obj = objectManager.FindObjectVariation(base, selectionsVec);
60 
61  if (! obj)
62  return NULL;
63 
64  return new CUnit(obj, objectManager, actorSelections, seed);
65 }
66 
67 void CUnit::UpdateModel(float frameTime)
68 {
69  if (m_Animation)
70  m_Animation->Update(frameTime*1000.0f);
71 }
72 
74 {
75  m_ID = id;
76  if (m_Animation)
78 }
79 
80 void CUnit::SetEntitySelection(const CStr& selection)
81 {
82  CStr selection_lc = selection.LowerCase();
83 
84  // If we've already selected this, don't do anything
85  if (m_EntitySelections.find(selection_lc) != m_EntitySelections.end())
86  return;
87 
88  // Just allow one selection at a time
89  m_EntitySelections.clear();
90  m_EntitySelections.insert(selection_lc);
91 
92  ReloadObject();
93 }
94 
95 void CUnit::SetActorSelections(const std::set<CStr>& selections)
96 {
97  m_ActorSelections = selections;
98  ReloadObject();
99 }
100 
102 {
103  std::vector<std::set<CStr> > selections;
104  // TODO: push world selections (seasons, etc) (and reload whenever they're changed)
105  selections.push_back(m_EntitySelections);
106  selections.push_back(m_ActorSelections);
107 
108  // randomly select any remain selections necessary to completely identify a variation (e.g., the new selection
109  // made might define some additional props that require a random variant choice). Also, FindObjectVariation
110  // expects the selectors passed to it to be complete.
111  // see http://trac.wildfiregames.com/ticket/979
112 
113  // Use the entity ID as randomization seed (same as when the unit was first created)
114  std::set<CStr> remainingSelections = m_Object->m_Base->CalculateRandomRemainingSelections(m_Seed, selections);
115  if (!remainingSelections.empty())
116  selections.push_back(remainingSelections);
117 
118  // If these selections give a different object, change this unit to use it
120  if (newObject && newObject != m_Object)
121  {
122  // Clone the new object's base (non-instance) model
123  CModelAbstract* newModel = newObject->m_Model->Clone();
124 
125  // Copy the old instance-specific settings from the old model to the new instance
126  newModel->SetTransform(m_Model->GetTransform());
127  newModel->SetPlayerID(m_Model->GetPlayerID());
128  if (newModel->ToCModel() && m_Model->ToCModel())
129  {
130  newModel->ToCModel()->CopyAnimationFrom(m_Model->ToCModel());
131 
132  // Copy flags that belong to this model instance (not those defined by the actor XML)
134  newModel->ToCModel()->AddFlagsRec(instanceFlags);
135  }
136 
137  delete m_Model;
138  m_Model = newModel;
139  m_Object = newObject;
140 
141  if (m_Model->ToCModel())
142  {
143  if (m_Animation)
144  m_Animation->ReloadUnit(m_Model->ToCModel(), m_Object); // TODO: maybe this should try to preserve animation state?
145  else
147  }
148  else
149  {
151  }
152  }
153 }
virtual void SetPlayerID(player_id_t id)
~CUnit()
Definition: Unit.cpp:41
void SetEntitySelection(const CStr &selection)
Definition: Unit.cpp:80
std::set< CStr > m_ActorSelections
Definition: Unit.h:96
CObjectBase * FindObjectBase(const CStrW &objname)
CObjectBase * m_Base
Definition: ObjectEntry.h:52
void ReloadObject()
Definition: Unit.cpp:101
virtual void SetTransform(const CMatrix3D &transform)
Definition: Unit.h:35
virtual CModelAbstract * Clone() const =0
#define MODELFLAG_IGNORE_LOS
Definition: Model.h:44
void SetEntityID(entity_id_t ent)
Change the entity ID associated with this animation (currently used for playing locational sound effe...
uint32_t m_Seed
Definition: Unit.h:93
CUnit(CObjectEntry *object, CObjectManager &objectManager, const std::set< CStr > &actorSelections, uint32_t seed)
Definition: Unit.cpp:29
CObjectEntry * FindObjectVariation(const CStrW &objname, const std::vector< std::set< CStr > > &selections)
void Update(float time)
Advance the animation state.
entity_id_t m_ID
Definition: Unit.h:90
CObjectManager & m_ObjectManager
Definition: Unit.h:101
void SetActorSelections(const std::set< CStr > &selections)
Definition: Unit.cpp:95
void ReloadUnit(CModel *model, const CObjectEntry *object)
Regenerate internal animation state from the models in the current unit.
#define SAFE_DELETE(p)
delete memory ensuing from new and set the pointer to zero (thus making double-frees safe / a no-op) ...
std::set< CStr > m_EntitySelections
Definition: Unit.h:98
static CUnit * Create(const CStrW &actorName, uint32_t seed, const std::set< CStr > &selections, CObjectManager &objectManager)
Definition: Unit.cpp:47
CModelAbstract * m_Model
Definition: Unit.h:84
virtual player_id_t GetPlayerID() const
#define MODELFLAG_SILHOUETTE_DISPLAY
Definition: Model.h:42
CObjectEntry * m_Object
Definition: Unit.h:82
Abstract base class for graphical objects that are used by units, or as props attached to other CMode...
Definition: ModelAbstract.h:36
std::set< CStr > CalculateRandomVariation(uint32_t seed, const std::set< CStr > &initialSelections)
Definition: ObjectBase.cpp:467
unsigned int uint32_t
Definition: wposix_types.h:53
CModelAbstract * m_Model
Definition: ObjectEntry.h:74
virtual CModel * ToCModel()
Dynamic cast.
Definition: ModelAbstract.h:76
const CMatrix3D & GetTransform() const
void SetID(entity_id_t id)
Definition: Unit.cpp:73
#define MODELFLAG_SILHOUETTE_OCCLUDER
Definition: Model.h:43
const entity_id_t INVALID_ENTITY
Invalid entity ID.
Definition: Entity.h:36
CUnitAnimation * m_Animation
Definition: Unit.h:86
u32 entity_id_t
Entity ID type.
Definition: Entity.h:24
void UpdateModel(float frameTime)
Update the model&#39;s animation.
Definition: Unit.cpp:67
int GetFlags() const
Definition: Model.h:123
std::set< CStr > CalculateRandomRemainingSelections(uint32_t seed, const std::vector< std::set< CStr > > &initialSelections)
Definition: ObjectBase.cpp:478
void CopyAnimationFrom(CModel *source)
Definition: Model.cpp:496
friend class CUnitAnimation
Definition: Unit.h:105
void AddFlagsRec(int flags)
Definition: Model.cpp:624