try to make build portable: remove SDL_mixer dependency, remove -f from cp command...
[openc2e.git] / historyManager.cpp
blobf929a30d12d832c17828773fa1559dee130f2238
1 /*
2 * historyManager.cpp
3 * openc2e
5 * Created by Alyssa Milburn on Wed 26 Apr 2006.
6 * Copyright (c) 2006 Alyssa Milburn. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
20 #include "historyManager.h"
21 #include "World.h"
22 #include "Catalogue.h"
23 #include "CreatureAgent.h"
24 #include "Creature.h"
26 #include <boost/format.hpp>
28 historyevent::historyevent(unsigned int eno, CreatureAgent *c) {
29 timestamp = time(NULL);
30 eventno = eno;
31 worldtick = world.tickcount;
32 // TODO: worldname = world.name;
33 // TODO: worldmoniker = world.moniker;
34 // TODO: networkid = world.username;
36 if (c) {
37 tage = c->getCreature()->getAge();
38 stage = c->getCreature()->getStage();
39 } else {
40 tage = -1;
41 stage = baby; // TODO: correct?
45 void monikerData::init(std::string m, shared_ptr<genomeFile> f) {
46 moniker = m;
47 status = unreferenced;
48 warpveteran = false;
49 variant = -1;
50 gender = -1;
51 no_crossover_points = 0;
52 no_point_mutations = 0;
54 assert(f);
55 genome = f;
57 for (vector<gene *>::iterator i = f->genes.begin(); i != f->genes.end(); i++) {
58 if (typeid(*(*i)) == typeid(creatureGenusGene)) {
59 // initialize genus
60 creatureGenusGene *g = (creatureGenusGene *)(*i);
61 genus = g->genus + 1;
62 break;
67 historyevent &monikerData::addEvent(unsigned int event, std::string moniker1, std::string moniker2) {
68 CreatureAgent *c = 0;
69 if (owner) c = dynamic_cast<CreatureAgent *>(owner.get());
71 events.push_back(historyevent(event, c));
72 events.back().monikers[0] = moniker1;
73 events.back().monikers[1] = moniker2;
75 for (std::list<boost::shared_ptr<Agent> >::iterator i = world.agents.begin(); i != world.agents.end(); i++) {
76 if (!*i) continue;
78 (*i)->queueScript(127, 0, moniker, (int)(events.size() - 1)); // new life event
81 return events.back();
84 void monikerData::moveToAgent(AgentRef a) {
85 assert(status == referenced || status == unreferenced);
87 owner = a;
88 if (!owner) {
89 status = unreferenced;
90 } else {
91 status = referenced;
95 void monikerData::moveToCreature(AgentRef a) {
96 moveToAgent(a);
98 CreatureAgent *c = dynamic_cast<CreatureAgent *>(owner.get());
99 assert(c);
100 status = creature;
103 void monikerData::wasBorn() {
104 assert(status == creature);
105 CreatureAgent *c = dynamic_cast<CreatureAgent *>(owner.get());
106 assert(c);
108 status = borncreature;
109 gender = (c->getCreature()->isFemale() ? 2 : 1);
110 variant = c->getCreature()->getVariant();
113 void monikerData::hasDied() {
114 CreatureAgent *c = dynamic_cast<CreatureAgent *>(owner.get());
115 assert(c);
117 // TODO
119 status = dead;
122 monikerstatus monikerData::getStatus() {
123 switch (status) {
124 case referenced:
125 case exported:
126 case unreferenced:
127 return status;
129 case creature:
130 case borncreature:
131 if (owner)
132 return status;
133 else
134 return deadandkilled; // we missed it?! TODO: what's correct behaviour here?
136 case dead:
137 if (owner)
138 return dead;
139 else
140 return deadandkilled;
142 default:
143 assert(false); // explode!
148 std::string historyManager::newMoniker(shared_ptr<genomeFile> genome) {
149 unsigned int genus = 0;
151 for (vector<gene *>::iterator i = genome->genes.begin(); i != genome->genes.end(); i++) {
152 if (typeid(*(*i)) == typeid(creatureGenusGene)) {
153 // initialize genus
154 creatureGenusGene *g = (creatureGenusGene *)(*i);
155 genus = g->genus + 1;
156 break;
160 std::string basename = "xxxx";
162 const std::vector<std::string> *extensions = 0;
163 std::string tagname = boost::str(boost::format("Moniker Friendly Names %i") % genus);
165 if (catalogue.hasTag(tagname)) {
166 extensions = &catalogue.getTag(tagname);
167 } else if (catalogue.hasTag("Moniker Friendly Names")) {
168 extensions = &catalogue.getTag("Moniker Friendly Names");
169 } else {
170 std::cout << "Warning: No \"Moniker Friendly Names\" in catalogue for genus " << genus <<
171 ", defaulting to 'xxxx' for a moniker friendly name." << std::endl;
174 if (extensions) {
175 unsigned int i = (int) (extensions->size() * (rand() / (RAND_MAX + 1.0)));
176 basename = (*extensions)[i];
179 std::string newmoniker = world.generateMoniker(basename);
180 unsigned int i = 0;
181 while (hasMoniker(newmoniker)) { // last-moment sanity check..
182 std::string newmoniker = world.generateMoniker(basename);
183 i++;
184 if (i > 100) // emergency "don't go into an infinite loop handling"
185 throw creaturesException("Couldn't generate a moniker we don't already have!");
188 newmoniker = "001-" + newmoniker; // TODO: bad hack we should use the generation number here!
190 monikers[newmoniker].init(newmoniker, genome);
191 return newmoniker;
194 bool historyManager::hasMoniker(std::string s) {
195 std::map<std::string, monikerData>::iterator i = monikers.find(s);
196 if (i == monikers.end()) return false;
197 else return true;
200 monikerData &historyManager::getMoniker(std::string s) {
201 std::map<std::string, monikerData>::iterator i = monikers.find(s);
202 if (i == monikers.end()) throw creaturesException("getMoniker was called with a non-existant moniker");
203 return i->second;
206 std::string historyManager::findMoniker(shared_ptr<genomeFile> g) {
207 for (std::map<std::string, monikerData>::iterator i = monikers.begin(); i != monikers.end(); i++) {
208 if (i->second.genome.lock() == g) return i->first;
211 return "";
214 std::string historyManager::findMoniker(AgentRef a) {
215 for (std::map<std::string, monikerData>::iterator i = monikers.begin(); i != monikers.end(); i++) {
216 if (i->second.owner == a) return i->first;
219 return "";
222 void historyManager::delMoniker(std::string s) {
223 std::map<std::string, monikerData>::iterator i = monikers.find(s);
224 if (i == monikers.end()) throw creaturesException("getMoniker was called with a non-existant moniker");
225 monikers.erase(i);
228 /* vim: set noet: */