reactor: Make CreatureAttributes a class

This commit is contained in:
Vsevolod Kremianskii 2020-11-15 17:08:52 +07:00
parent 20dcb93eae
commit 28168f9a23
10 changed files with 160 additions and 73 deletions

View file

@ -415,6 +415,7 @@ set(GAME_HEADERS
src/game/player.h src/game/player.h
src/game/portraits.h src/game/portraits.h
src/game/room.h src/game/room.h
src/game/rp/attributes.h
src/game/rp/classes.h src/game/rp/classes.h
src/game/rp/types.h src/game/rp/types.h
src/game/savedgame.h src/game/savedgame.h
@ -497,6 +498,7 @@ set(GAME_SOURCES
src/game/player.cpp src/game/player.cpp
src/game/portraits.cpp src/game/portraits.cpp
src/game/room.cpp src/game/room.cpp
src/game/rp/attributes.cpp
src/game/rp/classes.cpp src/game/rp/classes.cpp
src/game/savedgame.cpp src/game/savedgame.cpp
src/game/script/routines.cpp src/game/script/routines.cpp

View file

@ -62,27 +62,26 @@ void CreatureBlueprint::loadAttributes(const GffStruct &utc) {
for (auto &classGff : utc.getList("ClassList")) { for (auto &classGff : utc.getList("ClassList")) {
int clazz = classGff.getInt("Class"); int clazz = classGff.getInt("Class");
int level = classGff.getInt("ClassLevel"); int level = classGff.getInt("ClassLevel");
_attributes.classLevels.push_back(make_pair(static_cast<ClassType>(clazz), level)); _attributes.addClassLevels(static_cast<ClassType>(clazz), level);
} }
loadAbilities(utc); loadAbilities(utc);
loadSkills(utc); loadSkills(utc);
_attributes.computeHitDice();
} }
void CreatureBlueprint::loadAbilities(const GffStruct &utc) { void CreatureBlueprint::loadAbilities(const GffStruct &utc) {
_attributes.abilities[Ability::Strength] = utc.getInt("Str"); _attributes.setAbilityScore(Ability::Strength, utc.getInt("Str"));
_attributes.abilities[Ability::Dexterity] = utc.getInt("Dex"); _attributes.setAbilityScore(Ability::Dexterity, utc.getInt("Dex"));
_attributes.abilities[Ability::Constitution] = utc.getInt("Con"); _attributes.setAbilityScore(Ability::Constitution, utc.getInt("Con"));
_attributes.abilities[Ability::Intelligence] = utc.getInt("Int"); _attributes.setAbilityScore(Ability::Intelligence, utc.getInt("Int"));
_attributes.abilities[Ability::Wisdom] = utc.getInt("Wis"); _attributes.setAbilityScore(Ability::Wisdom, utc.getInt("Wis"));
_attributes.abilities[Ability::Charisma] = utc.getInt("Cha"); _attributes.setAbilityScore(Ability::Charisma, utc.getInt("Cha"));
} }
void CreatureBlueprint::loadSkills(const GffStruct &utc) { void CreatureBlueprint::loadSkills(const GffStruct &utc) {
const vector<GffStruct> &skills = utc.getList("SkillList"); const vector<GffStruct> &skills = utc.getList("SkillList");
for (int i = 0; i < static_cast<int>(skills.size()); ++i) { for (int i = 0; i < static_cast<int>(skills.size()); ++i) {
Skill skill = static_cast<Skill>(i); Skill skill = static_cast<Skill>(i);
_attributes.skills[skill] = skills[i].getInt("Rank"); _attributes.setSkillRank(skill, skills[i].getInt("Rank"));
} }
} }

View file

@ -23,7 +23,7 @@
#include "../../resource/gfffile.h" #include "../../resource/gfffile.h"
#include "../rp/types.h" #include "../rp/attributes.h"
namespace reone { namespace reone {

View file

@ -284,9 +284,7 @@ void Creature::load(const CreatureConfiguration &config) {
shared_ptr<TwoDaTable> appearance(Resources::instance().get2DA("appearance")); shared_ptr<TwoDaTable> appearance(Resources::instance().get2DA("appearance"));
loadAppearance(*appearance, config.appearance); loadAppearance(*appearance, config.appearance);
loadPortrait(config.appearance); loadPortrait(config.appearance);
_attributes.addClassLevels(config.clazz, 1);
_attributes.classLevels.push_back(make_pair(config.clazz, 1));
_attributes.computeHitDice();
} }
for (auto &item : config.equipment) { for (auto &item : config.equipment) {
equip(item); equip(item);

View file

@ -24,6 +24,8 @@
#include "../../resource/gfffile.h" #include "../../resource/gfffile.h"
#include "../../script/types.h" #include "../../script/types.h"
#include "../rp/attributes.h"
#include "item.h" #include "item.h"
#include "spatial.h" #include "spatial.h"

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2020 Vsevolod Kremianskii
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "attributes.h"
#include <algorithm>
using namespace std;
namespace reone {
namespace game {
void CreatureAttributes::addClassLevels(ClassType clazz, int levels) {
for (int i = 0; i < static_cast<int>(_classLevels.size()); ++i) {
if (_classLevels[i].first == clazz) {
_classLevels[i].second += levels;
return;
}
}
_classLevels.push_back(make_pair(clazz, levels));
computeHitDice();
}
void CreatureAttributes::computeHitDice() {
_hitDice = 0;
for (auto &classLevel : _classLevels) {
_hitDice += classLevel.second;
}
}
void CreatureAttributes::setAbilityScore(Ability ability, int score) {
_abilities[ability] = score;
}
void CreatureAttributes::setSkillRank(Skill skill, int rank) {
_skills[skill] = rank;
}
ClassType CreatureAttributes::getClassByPosition(int position) const {
return (position - 1) < static_cast<int>(_classLevels.size()) ?
_classLevels[static_cast<size_t>(position) - 1].first :
ClassType::Invalid;
}
int CreatureAttributes::getClassLevel(ClassType clazz) const {
auto maybeClassLevel = find_if(
_classLevels.begin(), _classLevels.end(),
[&clazz](auto &classLevel) { return classLevel.first == clazz; });
return maybeClassLevel != _classLevels.end() ? maybeClassLevel->second : 0;
}
} // namespace game
} // namespace reone

69
src/game/rp/attributes.h Normal file
View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2020 Vsevolod Kremianskii
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <map>
#include <utility>
#include <vector>
#include "types.h"
namespace reone {
namespace game {
class CreatureAttributes {
public:
void addClassLevels(ClassType clazz, int levels);
void setAbilityScore(Ability ability, int score);
void setSkillRank(Skill ability, int rank);
ClassType getClassByPosition(int position) const;
int getClassLevel(ClassType clazz) const;
int getHitDice() const { return _hitDice; }
int strength() const { return _abilities.find(Ability::Strength)->second; }
int dexterity() const { return _abilities.find(Ability::Dexterity)->second; }
int constitution() const { return _abilities.find(Ability::Constitution)->second; }
int intelligence() const { return _abilities.find(Ability::Intelligence)->second; }
int wisdom() const { return _abilities.find(Ability::Wisdom)->second; }
int charisma() const { return _abilities.find(Ability::Charisma)->second; }
bool hasSkill(Skill skill) const { return _skills.find(skill)->second > 0; }
int computerUse() const { return _skills.find(Skill::ComputerUse)->second; }
int demolitions() const { return _skills.find(Skill::Demolitions)->second; }
int stealth() const { return _skills.find(Skill::Stealth)->second; }
int awareness() const { return _skills.find(Skill::Awareness)->second; }
int persuade() const { return _skills.find(Skill::Persuade)->second; }
int repair() const { return _skills.find(Skill::Repair)->second; }
int security() const { return _skills.find(Skill::Security)->second; }
int treatInjury() const { return _skills.find(Skill::TreatInjury)->second; }
private:
std::vector<std::pair<ClassType, int>> _classLevels;
int _hitDice { 0 };
std::map<Ability, int> _abilities;
std::map<Skill, int> _skills;
void computeHitDice();
};
} // namespace game
} // namespace reone

View file

@ -48,12 +48,12 @@ CreatureAttributes getClassAttributes(ClassType clazz) {
int row = static_cast<int>(clazz); int row = static_cast<int>(clazz);
CreatureAttributes attrs; CreatureAttributes attrs;
attrs.abilities.insert(make_pair(Ability::Strength, classes->getInt(row, "str"))); attrs.setAbilityScore(Ability::Strength, classes->getInt(row, "str"));
attrs.abilities.insert(make_pair(Ability::Dexterity, classes->getInt(row, "dex"))); attrs.setAbilityScore(Ability::Dexterity, classes->getInt(row, "dex"));
attrs.abilities.insert(make_pair(Ability::Constitution, classes->getInt(row, "con"))); attrs.setAbilityScore(Ability::Constitution, classes->getInt(row, "con"));
attrs.abilities.insert(make_pair(Ability::Intelligence, classes->getInt(row, "int"))); attrs.setAbilityScore(Ability::Intelligence, classes->getInt(row, "int"));
attrs.abilities.insert(make_pair(Ability::Wisdom, classes->getInt(row, "wis"))); attrs.setAbilityScore(Ability::Wisdom, classes->getInt(row, "wis"));
attrs.abilities.insert(make_pair(Ability::Charisma, classes->getInt(row, "cha"))); attrs.setAbilityScore(Ability::Charisma, classes->getInt(row, "cha"));
return move(attrs); return move(attrs);
} }

View file

@ -19,6 +19,7 @@
#include <string> #include <string>
#include "attributes.h"
#include "types.h" #include "types.h"
namespace reone { namespace reone {

View file

@ -17,10 +17,6 @@
#pragma once #pragma once
#include <map>
#include <utility>
#include <vector>
namespace reone { namespace reone {
namespace game { namespace game {
@ -75,56 +71,6 @@ enum class Skill {
TreatInjury = 7 TreatInjury = 7
}; };
struct CreatureAttributes {
std::vector<std::pair<ClassType, int>> classLevels;
int hitDice { 0 };
std::map<Ability, int> abilities;
std::map<Skill, int> skills;
void computeHitDice() {
hitDice = 0;
for (auto &classLevel : classLevels) {
hitDice += classLevel.second;
}
}
ClassType getClassByPosition(int position) const {
return (position - 1) < static_cast<int>(classLevels.size()) ?
classLevels[static_cast<size_t>(position) - 1].first :
ClassType::Invalid;
}
int getClassLevel(ClassType clazz) const {
auto maybeClassLevel = find_if(
classLevels.begin(), classLevels.end(),
[&clazz](auto &classLevel) { return classLevel.first == clazz; });
return maybeClassLevel != classLevels.end() ? maybeClassLevel->second : 0;
}
int getHitDice() const { return hitDice; }
int strength() const { return abilities.find(Ability::Strength)->second; }
int dexterity() const { return abilities.find(Ability::Dexterity)->second; }
int constitution() const { return abilities.find(Ability::Constitution)->second; }
int intelligence() const { return abilities.find(Ability::Intelligence)->second; }
int wisdom() const { return abilities.find(Ability::Wisdom)->second; }
int charisma() const { return abilities.find(Ability::Charisma)->second; }
bool hasSkill(Skill skill) const {
return skills.find(skill)->second > 0;
}
int computerUse() const { return skills.find(Skill::ComputerUse)->second; }
int demolitions() const { return skills.find(Skill::Demolitions)->second; }
int stealth() const { return skills.find(Skill::Stealth)->second; }
int awareness() const { return skills.find(Skill::Awareness)->second; }
int persuade() const { return skills.find(Skill::Persuade)->second; }
int repair() const { return skills.find(Skill::Repair)->second; }
int security() const { return skills.find(Skill::Security)->second; }
int treatInjury() const { return skills.find(Skill::TreatInjury)->second; }
};
} // namespace game } // namespace game
} // namespace reone } // namespace reone