1 /*
2  *  Copyright (C) 2011-2016  OpenDungeons Team
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "creaturemood/CreatureMoodManager.h"
19 
20 #include "creaturemood/CreatureMood.h"
21 #include "entities/Creature.h"
22 #include "entities/CreatureDefinition.h"
23 #include "utils/ConfigManager.h"
24 #include "utils/Helper.h"
25 #include "utils/LogManager.h"
26 
27 #include <istream>
28 #include <vector>
29 
30 namespace
31 {
getFactories()32     static std::vector<const CreatureMoodFactory*>& getFactories()
33     {
34         static std::vector<const CreatureMoodFactory*> factory;
35         return factory;
36     }
37 }
38 
registerFactory(const CreatureMoodFactory * factory)39 void CreatureMoodManager::registerFactory(const CreatureMoodFactory* factory)
40 {
41     std::vector<const CreatureMoodFactory*>& factories = getFactories();
42     factories.push_back(factory);
43 }
44 
unregisterFactory(const CreatureMoodFactory * factory)45 void CreatureMoodManager::unregisterFactory(const CreatureMoodFactory* factory)
46 {
47     std::vector<const CreatureMoodFactory*>& factories = getFactories();
48     auto it = std::find(factories.begin(), factories.end(), factory);
49     if(it == factories.end())
50     {
51         OD_LOG_ERR("Trying to unregister unknown factory=" + factory->getCreatureMoodName());
52         return;
53     }
54     factories.erase(it);
55 }
56 
getCreatureMoodLevel(int32_t moodModifiersPoints)57 CreatureMoodLevel CreatureMoodManager::getCreatureMoodLevel(int32_t moodModifiersPoints)
58 {
59     int32_t mood = ConfigManager::getSingleton().getCreatureBaseMood() + moodModifiersPoints;
60     if(mood >= ConfigManager::getSingleton().getCreatureMoodHappy())
61         return CreatureMoodLevel::Happy;
62 
63     if(mood >= ConfigManager::getSingleton().getCreatureMoodUpset())
64         return CreatureMoodLevel::Neutral;
65 
66     if(mood >= ConfigManager::getSingleton().getCreatureMoodAngry())
67         return CreatureMoodLevel::Upset;
68 
69     if(mood >= ConfigManager::getSingleton().getCreatureMoodFurious())
70         return CreatureMoodLevel::Angry;
71 
72     return CreatureMoodLevel::Furious;
73 }
74 
computeCreatureMoodModifiers(const Creature & creature)75 int32_t CreatureMoodManager::computeCreatureMoodModifiers(const Creature& creature)
76 {
77     int32_t moodValue = 0;
78     for(const CreatureMood* mood : creature.getDefinition()->getCreatureMoods())
79     {
80         moodValue += mood->computeMood(creature);
81     }
82 
83     return moodValue;
84 }
85 
clone(const CreatureMood * mood)86 CreatureMood* CreatureMoodManager::clone(const CreatureMood* mood)
87 {
88     return mood->clone();
89 }
90 
load(std::istream & defFile)91 CreatureMood* CreatureMoodManager::load(std::istream& defFile)
92 {
93     if(!defFile.good())
94         return nullptr;
95 
96     std::vector<const CreatureMoodFactory*>& factories = getFactories();
97     std::string nextParam;
98     OD_ASSERT_TRUE(defFile >> nextParam);
99     const CreatureMoodFactory* factoryToUse = nullptr;
100     for(const CreatureMoodFactory* factory : factories)
101     {
102         if(factory == nullptr)
103             continue;
104 
105         if(factory->getCreatureMoodName().compare(nextParam) != 0)
106             continue;
107 
108         factoryToUse = factory;
109         break;
110     }
111 
112     if(factoryToUse == nullptr)
113     {
114         OD_LOG_ERR("Unknown mood modifier=" + nextParam);
115         return nullptr;
116     }
117 
118     CreatureMood* mood = factoryToUse->createCreatureMood();
119     if(!mood->importFromStream(defFile))
120     {
121         OD_LOG_ERR("Couldn't load creature mood modifier=" + nextParam);
122         delete mood;
123         return nullptr;
124     }
125 
126     return mood;
127 }
128 
dispose(const CreatureMood * mood)129 void CreatureMoodManager::dispose(const CreatureMood* mood)
130 {
131     delete mood;
132 }
133 
write(const CreatureMood & mood,std::ostream & os)134 void CreatureMoodManager::write(const CreatureMood& mood, std::ostream& os)
135 {
136     os << mood.getModifierName();
137     mood.exportToStream(os);
138 }
139 
getFormatString(const CreatureMood & mood,std::string & format)140 void CreatureMoodManager::getFormatString(const CreatureMood& mood, std::string& format)
141 {
142     format = "# MoodModifierName";
143     mood.getFormatString(format);
144 }
145 
areEqual(const CreatureMood & mood1,const CreatureMood & mood2)146 bool CreatureMoodManager::areEqual(const CreatureMood& mood1, const CreatureMood& mood2)
147 {
148     return mood1.isEqual(mood2);
149 }
150