cPopulation: try to make the monsters more persistent to simplify

other code...
This commit is contained in:
Laurent Alonso(fr)
2020-05-21 09:33:41 +02:00
committed by Celtic Minstrel
parent 98de45e496
commit f7a4ef0727
2 changed files with 89 additions and 34 deletions

View File

@@ -14,26 +14,44 @@
#include <sstream> #include <sstream>
#include "oldstructs.hpp" #include "oldstructs.hpp"
#include "strdlog.hpp"
cCreature cPopulation::dummyDude;
void cPopulation::import_legacy(legacy::creature_list_type old){ void cPopulation::import_legacy(legacy::creature_list_type old){
dudes.resize(60); dudes.resize(60);
for(int i = 0; i < 60; i++) for(int i = 0; i < 60; i++) {
dudes[i].import_legacy(old.dudes[i]); dudes[i]=std::make_shared<cCreature>();
dudes[i]->import_legacy(old.dudes[i]);
}
which_town = old.which_town; which_town = old.which_town;
hostile = old.hostile; hostile = old.hostile;
} }
const cCreature& cPopulation::operator[](size_t n) const { const cCreature& cPopulation::operator[](size_t n) const {
return dudes[n]; if (n>=dudes.size() || dudes[n].get()==nullptr) {
showError("Monster does not exist\n");
return dummyDude;
}
return *dudes[n];
} }
cCreature& cPopulation::operator[](size_t n){ cCreature& cPopulation::operator[](size_t n){
return dudes[n]; if (n>=dudes.size() || dudes[n].get()==nullptr) {
showError("Monster does not exist\n");
return dummyDude;
}
return *dudes[n];
} }
void cPopulation::init(size_t n) { void cPopulation::init(size_t n) {
if(n >= dudes.size()) dudes.resize(n + 1); if(n >= dudes.size()) {
dudes[n].active = 1; size_t old_n=dudes.size();
dudes.resize(n + 1);
for (size_t i=old_n; i<=n; ++i)
dudes[i]=std::make_shared<cCreature>();
}
dudes[n]->active = 1;
} }
// This function combines a cTownperson from a scenario town record with a cMonster from the scenario record // This function combines a cTownperson from a scenario town record with a cMonster from the scenario record
@@ -41,30 +59,30 @@ void cPopulation::init(size_t n) {
// replaces return_monster_template() from boe.monsters.cpp // replaces return_monster_template() from boe.monsters.cpp
void cPopulation::assign(size_t n, const cTownperson& other, const cMonster& base, bool easy, int difficulty_adjust){ void cPopulation::assign(size_t n, const cTownperson& other, const cMonster& base, bool easy, int difficulty_adjust){
// Make sure the space exists // Make sure the space exists
if(n >= dudes.size()) dudes.resize(n + 1); init(n);
// First copy over the superclass fields // First copy over the superclass fields
static_cast<cTownperson&>(dudes[n]) = other; static_cast<cTownperson&>(*dudes[n]) = other;
static_cast<cMonster&>(dudes[n]) = base; static_cast<cMonster&>(*dudes[n]) = base;
// Now set up extra stuff // Now set up extra stuff
dudes[n].active = 1; // TODO: Is this right? // TODO: active=1 is set by init, is this right?
if(dudes[n].invisible) dudes[n].picture_num = 0; if(dudes[n]->invisible) dudes[n]->picture_num = 0;
dudes[n].m_health /= easy ? 2 : 1; dudes[n]->m_health /= easy ? 2 : 1;
dudes[n].m_health *= difficulty_adjust; dudes[n]->m_health *= difficulty_adjust;
dudes[n].health = dudes[n].m_health; dudes[n]->health = dudes[n]->m_health;
dudes[n].ap = 0; dudes[n]->ap = 0;
if(dudes[n].mu > 0 || dudes[n].cl > 0) if(dudes[n]->mu > 0 || dudes[n]->cl > 0)
dudes[n].max_mp = dudes[n].mp = 12 * dudes[n].level; dudes[n]->max_mp = dudes[n]->mp = 12 * dudes[n]->level;
else dudes[n].max_mp = dudes[n].mp = 0; else dudes[n]->max_mp = dudes[n]->mp = 0;
dudes[n].m_morale = 10 * dudes[n].level; dudes[n]->m_morale = 10 * dudes[n]->level;
if(dudes[n].level > 20) if(dudes[n]->level > 20)
dudes[n].m_morale += 10 * (dudes[n].level - 20); dudes[n]->m_morale += 10 * (dudes[n]->level - 20);
dudes[n].morale = dudes[n].m_morale; dudes[n]->morale = dudes[n]->m_morale;
dudes[n].direction = DIR_HERE; dudes[n]->direction = DIR_HERE;
dudes[n].status.clear(); dudes[n]->status.clear();
dudes[n].attitude = dudes[n].start_attitude; dudes[n]->attitude = dudes[n]->start_attitude;
dudes[n].cur_loc = dudes[n].start_loc; dudes[n]->cur_loc = dudes[n]->start_loc;
dudes[n].target = 6; // No target dudes[n]->target = 6; // No target
dudes[n].summon_time = 0; dudes[n]->summon_time = 0;
} }
void cPopulation::swap(cPopulation& other) { void cPopulation::swap(cPopulation& other) {
@@ -74,6 +92,15 @@ void cPopulation::swap(cPopulation& other) {
} }
void cPopulation::readFrom(std::istream& in, size_t n) { void cPopulation::readFrom(std::istream& in, size_t n) {
if(n >= dudes.size()) dudes.resize(n + 1); init(n);
dudes[n].readFrom(in); dudes[n]->active = 0; // TODO: I reset active to default, is this needed ?
dudes[n]->readFrom(in);
}
cCreature &cPopulation::iterator::operator*() {
if ((*it).get()==nullptr) {
showError("Monster does not exists\n");
return dummyDude;
}
return **it;
} }

View File

@@ -9,8 +9,8 @@
#ifndef BOE_DATA_CREATLIST_H #ifndef BOE_DATA_CREATLIST_H
#define BOE_DATA_CREATLIST_H #define BOE_DATA_CREATLIST_H
#include "monster.hpp"
#include <iosfwd> #include <iosfwd>
#include <memory>
#include "creature.hpp" #include "creature.hpp"
namespace legacy { namespace legacy {
@@ -19,8 +19,11 @@ namespace legacy {
}; };
class cPopulation { class cPopulation {
std::vector<cCreature> dudes; std::vector<std::shared_ptr<cCreature> > dudes;
static cCreature dummyDude;
public: public:
class iterator;
short which_town; short which_town;
bool hostile; bool hostile;
@@ -34,11 +37,36 @@ public:
const cCreature& operator[](size_t n) const; const cCreature& operator[](size_t n) const;
// ASAN hostile copied but unset // ASAN hostile copied but unset
cPopulation() : which_town(200), hostile(false) {} cPopulation() : which_town(200), hostile(false) {}
std::vector<cCreature>::iterator begin() {return dudes.begin();} iterator begin() {return iterator(dudes.begin());}
std::vector<cCreature>::iterator end() {return dudes.end();} iterator end() {return iterator(dudes.end());}
// Apparently Visual Studio needs this to work // Apparently Visual Studio needs this to work
cPopulation& operator=(const cPopulation& other) = default; cPopulation& operator=(const cPopulation& other) = default;
void swap(cPopulation& other); void swap(cPopulation& other);
class iterator {
public:
explicit iterator(std::vector<std::shared_ptr<cCreature>>::iterator it_)
: it(it_) {
}
iterator(const iterator&) = default;
~iterator() = default;
iterator& operator=(const iterator&) = default;
iterator& operator++() { //postfix increment
++it;
return *this;
}
iterator operator++(int) { //prefix increment
auto rIt=*this;
it++;
return rIt;
}
cCreature &operator*();
bool operator==(const iterator& other) const { return it == other.it; }
bool operator!=(const iterator& other) const { return !(*this == other); }
std::vector<std::shared_ptr<cCreature>>::iterator it;
};
}; };
#endif #endif