1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
|
#pragma once
#include "Objective.h"
#include "Logic.h"
#include "ObjectiveCondition.h"
#include "inode.h"
#include <memory>
#include "wxutil/dataview/TreeModel.h"
// FORWARD DECLS
namespace objectives { class TargetList; }
class Entity;
class wxChoice;
namespace objectives
{
struct ObjectivesListColumns :
public wxutil::TreeModel::ColumnRecord
{
ObjectivesListColumns() :
objNumber(add(wxutil::TreeModel::Column::Integer)),
description(add(wxutil::TreeModel::Column::String)),
difficultyLevel(add(wxutil::TreeModel::Column::String))
{}
wxutil::TreeModel::Column objNumber;
wxutil::TreeModel::Column description;
wxutil::TreeModel::Column difficultyLevel;
};
/**
* Representation of a single objective entity (target_tdm_addobjectives).
*
* In the Dark Mod, objectives are stored as numbered spawnargs on an objective
* entity, e.g. <b>obj3_desc</b>. Each objective entity can contain any number
* of objectives described in this way.
*
* The ObjectiveEntity class provides an object-oriented view of the objective
* information, by wrapping a pointer to an Entity and providing methods to
* retrieve and manipulate objective information without seeing the spawnargs
* directly. When changes are completed, the ObjectiveEntity::writeToEntity()
* method is invoked to save all changes in the form of spawnargs.
*
* @see Entity
* @see objectives::Objective
*/
class ObjectiveEntity
{
public:
// Public typedef
typedef std::map<int, ObjectiveConditionPtr> ConditionMap;
private:
// The actual entity's world node and entity pointer
scene::INodeWeakPtr _entityNode;
// Map of numbered Objective objects
ObjectiveMap _objectives;
// Each difficulty level can have its own mission logic
// The index -1 is reserved for the default logic
typedef std::map<int, LogicPtr> LogicMap;
LogicMap _logics;
// Each objective condition has a certain index
ConditionMap _objConditions;
private:
// Read the mission success/failure logic from the entity
void readMissionLogic(Entity& ent);
// Store the mission logic to the entity
void writeMissionLogic(Entity& ent);
// Read/save objective conditions from/to entity
void readObjectiveConditions(Entity& ent);
void writeObjectiveConditions(Entity& ent);
// Write the Components to the underlying entity
void writeComponents(
Entity* entity, const std::string& keyPrefix, const Objective& objective
);
// Removes all objective-related spawnargs from the given entity
void clearEntity(Entity* entity);
public:
/**
* Construct an ObjectiveEntity wrapper around the given Node.
*/
ObjectiveEntity(const scene::INodePtr& node);
/**
* Return an Objective reference by numeric index.
*
* @param iIndex
* The numberic index of the objective to retrieve.
*
* @return
* A non-const reference to an Objective object, corresponding to the
* given index. If the provided index did not previously exist, a new
* Objective object will be created and returned.
*/
Objective& getObjective(int iIndex) {
return _objectives[iIndex];
}
// Returns the highest used objective index or -1 if none are present
int getHighestObjIndex() {
if (_objectives.empty()) return -1;
return _objectives.rbegin()->first;
}
// Returns the highest used objective index or -1 if none are present
int getLowestObjIndex() {
if (_objectives.empty()) return -1;
return _objectives.begin()->first;
}
/**
* Add a new objective, starting from the first unused objective ID.
*/
void addObjective();
/**
* greebo: Moves the specified objective by the given amount (e.g. +1/-1).
* @returns: the new index.
*/
int moveObjective(int index, int delta);
/**
* Delete a numbered objective. This re-orders all objectives so that the
* numbering is consistent again (deleting obj 2 will re-number 3 => 2, 4 => 3, etc.)
*/
void deleteObjective(int index);
/**
* Clear all objectives.
*/
void clearObjectives() {
_objectives.clear();
}
/**
* Test whether this entity contains objectives or not.
*/
bool isEmpty() const {
return _objectives.empty();
}
/**
* Delete the actual entity node from the map. This will render any further
* operations on this ObjectiveEntity undefined, and it should immediately
* be deleted.
*/
void deleteWorldNode();
/**
* Test whether this Objective Entity is on the provided TargetList, to
* determine whether the entity is a target of another entity (e.g. the
* worldspawn).
*/
bool isOnTargetList(const TargetList& list) const;
/**
* greebo: Returns the mission logic structure for the given difficulty level.
* The level -1 refers to the default logic structure.
*
* @returns: The logic (is never NULL). The logic object will be created if
* it isn't already existing, but the logic structure would be empty in that case.
*/
LogicPtr getMissionLogic(int difficultyLevel);
// Returns the full list of objective conditions by value
ConditionMap getObjectiveConditions() const;
// Replaces the existing set of objective conditions with this new one
void setObjectiveConditions(const ConditionMap& conditions);
// Returns the number of objective conditions present on this entity
std::size_t getNumObjectiveConditions() const;
// Returns the given objective condition, will create if not existing yet
const ObjectiveConditionPtr& getOrCreateObjectiveCondition(int index);
// Remove all objective conditions from this entitiy
void clearObjectiveConditions();
/**
* Populate the given list store with the objectives from this entity.
*
* @param store
* The list store to populate. This must have 2 columns -- an integer
* column for the objective number, and a text column for the description.
*/
void populateListStore(wxutil::TreeModel& store,
const ObjectivesListColumns& columns) const;
/**
* Populate the given choice field.
*/
void populateChoice(wxChoice* choice) const;
/**
* Write all objective data to keyvals on the underlying entity.
*/
void writeToEntity();
};
/**
* Objective entity pointer type.
*/
typedef std::shared_ptr<ObjectiveEntity> ObjectiveEntityPtr;
/**
* Objective entity named map type.
*/
typedef std::map<std::string, ObjectiveEntityPtr> ObjectiveEntityMap;
}
|