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"
22 #include "Catalogue.h"
23 #include "CreatureAgent.h"
25 #include "Engine.h" // version
27 #include <boost/format.hpp>
29 historyevent::historyevent(unsigned int eno
, CreatureAgent
*c
) {
30 timestamp
= time(NULL
);
32 worldtick
= world
.tickcount
;
33 // TODO: worldname = world.name;
34 // TODO: worldmoniker = world.moniker;
35 // TODO: networkid = world.username;
38 tage
= c
->getCreature()->getAge();
39 stage
= c
->getCreature()->getStage();
42 stage
= baby
; // TODO: correct?
46 void monikerData::init(std::string m
, shared_ptr
<genomeFile
> f
) {
48 status
= unreferenced
;
52 no_crossover_points
= 0;
53 no_point_mutations
= 0;
58 for (vector
<gene
*>::iterator i
= f
->genes
.begin(); i
!= f
->genes
.end(); i
++) {
59 if (typeid(*(*i
)) == typeid(creatureGenusGene
)) {
61 creatureGenusGene
*g
= (creatureGenusGene
*)(*i
);
68 historyevent
&monikerData::addEvent(unsigned int event
, std::string moniker1
, std::string moniker2
) {
70 if (owner
) c
= dynamic_cast<CreatureAgent
*>(owner
.get());
72 events
.push_back(historyevent(event
, c
));
73 events
.back().monikers
[0] = moniker1
;
74 events
.back().monikers
[1] = moniker2
;
76 for (std::list
<boost::shared_ptr
<Agent
> >::iterator i
= world
.agents
.begin(); i
!= world
.agents
.end(); i
++) {
79 (*i
)->queueScript(127, 0, moniker
, (int)(events
.size() - 1)); // new life event
85 void monikerData::moveToAgent(AgentRef a
) {
86 assert(status
== referenced
|| status
== unreferenced
);
90 status
= unreferenced
;
96 void monikerData::moveToCreature(AgentRef a
) {
99 CreatureAgent
*c
= dynamic_cast<CreatureAgent
*>(owner
.get());
104 void monikerData::wasBorn() {
105 assert(status
== creature
);
106 CreatureAgent
*c
= dynamic_cast<CreatureAgent
*>(owner
.get());
109 status
= borncreature
;
110 gender
= (c
->getCreature()->isFemale() ? 2 : 1);
111 variant
= c
->getCreature()->getVariant();
114 void monikerData::hasDied() {
115 CreatureAgent
*c
= dynamic_cast<CreatureAgent
*>(owner
.get());
123 monikerstatus
monikerData::getStatus() {
135 return deadandkilled
; // we missed it?! TODO: what's correct behaviour here?
141 return deadandkilled
;
144 assert(false); // explode!
149 std::string
historyManager::newMoniker(shared_ptr
<genomeFile
> genome
) {
150 unsigned int genus
= 0;
152 for (vector
<gene
*>::iterator i
= genome
->genes
.begin(); i
!= genome
->genes
.end(); i
++) {
153 if (typeid(*(*i
)) == typeid(creatureGenusGene
)) {
155 creatureGenusGene
*g
= (creatureGenusGene
*)(*i
);
156 genus
= g
->genus
+ 1;
161 std::string basename
= "xxxx";
163 if (engine
.version
> 2) {
164 const std::vector
<std::string
> *extensions
= 0;
165 std::string tagname
= boost::str(boost::format("Moniker Friendly Names %i") % genus
);
167 if (catalogue
.hasTag(tagname
)) {
168 extensions
= &catalogue
.getTag(tagname
);
169 } else if (catalogue
.hasTag("Moniker Friendly Names")) {
170 extensions
= &catalogue
.getTag("Moniker Friendly Names");
172 std::cout
<< "Warning: No \"Moniker Friendly Names\" in catalogue for genus " << genus
<<
173 ", defaulting to 'xxxx' for a moniker friendly name." << std::endl
;
177 unsigned int i
= (int) (extensions
->size() * (rand() / (RAND_MAX
+ 1.0)));
178 basename
= (*extensions
)[i
];
182 std::string newmoniker
= world
.generateMoniker(basename
);
184 while (hasMoniker(newmoniker
)) { // last-moment sanity check..
185 std::string newmoniker
= world
.generateMoniker(basename
);
187 if (i
> 100) // emergency "don't go into an infinite loop handling"
188 throw creaturesException("Couldn't generate a moniker we don't already have!");
191 if (engine
.version
> 2)
192 newmoniker
= "001-" + newmoniker
; // TODO: bad hack we should use the generation number here!
194 monikers
[newmoniker
].init(newmoniker
, genome
);
198 bool historyManager::hasMoniker(std::string s
) {
199 std::map
<std::string
, monikerData
>::iterator i
= monikers
.find(s
);
200 if (i
== monikers
.end()) return false;
204 monikerData
&historyManager::getMoniker(std::string s
) {
205 std::map
<std::string
, monikerData
>::iterator i
= monikers
.find(s
);
206 if (i
== monikers
.end()) throw creaturesException("getMoniker was called with a non-existant moniker");
210 std::string
historyManager::findMoniker(shared_ptr
<genomeFile
> g
) {
211 for (std::map
<std::string
, monikerData
>::iterator i
= monikers
.begin(); i
!= monikers
.end(); i
++) {
212 if (i
->second
.genome
.lock() == g
) return i
->first
;
218 std::string
historyManager::findMoniker(AgentRef a
) {
219 for (std::map
<std::string
, monikerData
>::iterator i
= monikers
.begin(); i
!= monikers
.end(); i
++) {
220 if (i
->second
.owner
== a
) return i
->first
;
226 void historyManager::delMoniker(std::string s
) {
227 std::map
<std::string
, monikerData
>::iterator i
= monikers
.find(s
);
228 if (i
== monikers
.end()) throw creaturesException("getMoniker was called with a non-existant moniker");