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 "oldstructs.hpp"
#include "strdlog.hpp"
cCreature cPopulation::dummyDude;
void cPopulation::import_legacy(legacy::creature_list_type old){
dudes.resize(60);
for(int i = 0; i < 60; i++)
dudes[i].import_legacy(old.dudes[i]);
for(int i = 0; i < 60; i++) {
dudes[i]=std::make_shared<cCreature>();
dudes[i]->import_legacy(old.dudes[i]);
}
which_town = old.which_town;
hostile = old.hostile;
}
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){
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) {
if(n >= dudes.size()) dudes.resize(n + 1);
dudes[n].active = 1;
if(n >= dudes.size()) {
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
@@ -41,30 +59,30 @@ void cPopulation::init(size_t n) {
// 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){
// Make sure the space exists
if(n >= dudes.size()) dudes.resize(n + 1);
init(n);
// First copy over the superclass fields
static_cast<cTownperson&>(dudes[n]) = other;
static_cast<cMonster&>(dudes[n]) = base;
static_cast<cTownperson&>(*dudes[n]) = other;
static_cast<cMonster&>(*dudes[n]) = base;
// Now set up extra stuff
dudes[n].active = 1; // TODO: Is this right?
if(dudes[n].invisible) dudes[n].picture_num = 0;
dudes[n].m_health /= easy ? 2 : 1;
dudes[n].m_health *= difficulty_adjust;
dudes[n].health = dudes[n].m_health;
dudes[n].ap = 0;
if(dudes[n].mu > 0 || dudes[n].cl > 0)
dudes[n].max_mp = dudes[n].mp = 12 * dudes[n].level;
else dudes[n].max_mp = dudes[n].mp = 0;
dudes[n].m_morale = 10 * dudes[n].level;
if(dudes[n].level > 20)
dudes[n].m_morale += 10 * (dudes[n].level - 20);
dudes[n].morale = dudes[n].m_morale;
dudes[n].direction = DIR_HERE;
dudes[n].status.clear();
dudes[n].attitude = dudes[n].start_attitude;
dudes[n].cur_loc = dudes[n].start_loc;
dudes[n].target = 6; // No target
dudes[n].summon_time = 0;
// TODO: active=1 is set by init, is this right?
if(dudes[n]->invisible) dudes[n]->picture_num = 0;
dudes[n]->m_health /= easy ? 2 : 1;
dudes[n]->m_health *= difficulty_adjust;
dudes[n]->health = dudes[n]->m_health;
dudes[n]->ap = 0;
if(dudes[n]->mu > 0 || dudes[n]->cl > 0)
dudes[n]->max_mp = dudes[n]->mp = 12 * dudes[n]->level;
else dudes[n]->max_mp = dudes[n]->mp = 0;
dudes[n]->m_morale = 10 * dudes[n]->level;
if(dudes[n]->level > 20)
dudes[n]->m_morale += 10 * (dudes[n]->level - 20);
dudes[n]->morale = dudes[n]->m_morale;
dudes[n]->direction = DIR_HERE;
dudes[n]->status.clear();
dudes[n]->attitude = dudes[n]->start_attitude;
dudes[n]->cur_loc = dudes[n]->start_loc;
dudes[n]->target = 6; // No target
dudes[n]->summon_time = 0;
}
void cPopulation::swap(cPopulation& other) {
@@ -74,6 +92,15 @@ void cPopulation::swap(cPopulation& other) {
}
void cPopulation::readFrom(std::istream& in, size_t n) {
if(n >= dudes.size()) dudes.resize(n + 1);
dudes[n].readFrom(in);
init(n);
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
#define BOE_DATA_CREATLIST_H
#include "monster.hpp"
#include <iosfwd>
#include <memory>
#include "creature.hpp"
namespace legacy {
@@ -19,8 +19,11 @@ namespace legacy {
};
class cPopulation {
std::vector<cCreature> dudes;
std::vector<std::shared_ptr<cCreature> > dudes;
static cCreature dummyDude;
public:
class iterator;
short which_town;
bool hostile;
@@ -34,11 +37,36 @@ public:
const cCreature& operator[](size_t n) const;
// ASAN hostile copied but unset
cPopulation() : which_town(200), hostile(false) {}
std::vector<cCreature>::iterator begin() {return dudes.begin();}
std::vector<cCreature>::iterator end() {return dudes.end();}
iterator begin() {return iterator(dudes.begin());}
iterator end() {return iterator(dudes.end());}
// Apparently Visual Studio needs this to work
cPopulation& operator=(const cPopulation& other) = default;
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