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 "spells/SpellEyeEvil.h"
19 
20 #include "entities/Creature.h"
21 #include "entities/Tile.h"
22 #include "game/Player.h"
23 #include "game/Seat.h"
24 #include "gamemap/GameMap.h"
25 #include "modes/InputCommand.h"
26 #include "modes/InputManager.h"
27 #include "network/ODClient.h"
28 #include "spells/SpellManager.h"
29 #include "utils/ConfigManager.h"
30 #include "utils/Helper.h"
31 #include "utils/LogManager.h"
32 
33 const std::string SpellEyeEvilName = "eyeEvil";
34 const std::string SpellEyeEvilNameDisplay = "Eye of Evil";
35 const std::string SpellEyeEvilCooldownKey = "EyeEvilCooldown";
36 const SpellType SpellEyeEvil::mSpellType = SpellType::eyeEvil;
37 
38 namespace
39 {
40 class SpellEyeEvilFactory : public SpellFactory
41 {
getSpellType() const42     SpellType getSpellType() const override
43     { return SpellEyeEvil::mSpellType; }
44 
getName() const45     const std::string& getName() const override
46     { return SpellEyeEvilName; }
47 
getCooldownKey() const48     const std::string& getCooldownKey() const override
49     { return SpellEyeEvilCooldownKey; }
50 
getNameReadable() const51     const std::string& getNameReadable() const override
52     { return SpellEyeEvilNameDisplay; }
53 
checkSpellCast(GameMap * gameMap,const InputManager & inputManager,InputCommand & inputCommand) const54     virtual void checkSpellCast(GameMap* gameMap, const InputManager& inputManager, InputCommand& inputCommand) const override
55     { SpellEyeEvil::checkSpellCast(gameMap, inputManager, inputCommand); }
56 
castSpell(GameMap * gameMap,Player * player,ODPacket & packet) const57     virtual bool castSpell(GameMap* gameMap, Player* player, ODPacket& packet) const override
58     { return SpellEyeEvil::castSpell(gameMap, player, packet); }
59 
getSpellFromStream(GameMap * gameMap,std::istream & is) const60     Spell* getSpellFromStream(GameMap* gameMap, std::istream &is) const override
61     { return SpellEyeEvil::getSpellFromStream(gameMap, is); }
62 
getSpellFromPacket(GameMap * gameMap,ODPacket & is) const63     Spell* getSpellFromPacket(GameMap* gameMap, ODPacket &is) const override
64     { return SpellEyeEvil::getSpellFromPacket(gameMap, is); }
65 };
66 
67 // Register the factory
68 static SpellRegister reg(new SpellEyeEvilFactory);
69 }
70 
SpellEyeEvil(GameMap * gameMap)71 SpellEyeEvil::SpellEyeEvil(GameMap* gameMap) :
72     Spell(gameMap, SpellManager::getSpellNameFromSpellType(getSpellType()), "FlyingSkull", 0.0,
73         ConfigManager::getSingleton().getSpellConfigInt32("EyeEvilNbTurns"))
74 {
75     mPrevAnimationState = "Triggered";
76     mPrevAnimationStateLoop = true;
77 }
78 
~SpellEyeEvil()79 SpellEyeEvil::~SpellEyeEvil()
80 {
81 }
82 
computeVisibleTiles()83 void SpellEyeEvil::computeVisibleTiles()
84 {
85     uint32_t radius = ConfigManager::getSingleton().getSpellConfigUInt32("EyeEvilRadiusTiles");
86     Tile* posTile = getPositionTile();
87     if(posTile == nullptr)
88     {
89         OD_LOG_ERR("name=" + getName() + ", position=" + Helper::toString(getPosition()));
90         return;
91     }
92 
93     std::vector<Tile*> tiles = getGameMap()->circularRegion(posTile->getX(), posTile->getY(), radius);
94     for(Tile* tile : tiles)
95         tile->notifyVision(getSeat());
96 }
97 
checkSpellCast(GameMap * gameMap,const InputManager & inputManager,InputCommand & inputCommand)98 void SpellEyeEvil::checkSpellCast(GameMap* gameMap, const InputManager& inputManager, InputCommand& inputCommand)
99 {
100     Player* player = gameMap->getLocalPlayer();
101 
102     Tile* tile = gameMap->getTile(inputManager.mXPos, inputManager.mYPos);
103     if(tile == nullptr)
104         return;
105 
106     int32_t playerMana = static_cast<int32_t>(player->getSeat()->getMana());
107     int32_t price = ConfigManager::getSingleton().getSpellConfigInt32("EyeEvilPrice");
108     if(inputManager.mCommandState == InputCommandState::infoOnly)
109     {
110         if(playerMana < price)
111         {
112             std::string txt = formatCastSpell(SpellType::eyeEvil, price);
113             inputCommand.displayText(Ogre::ColourValue::Red, txt);
114         }
115         else
116         {
117             std::string txt = formatCastSpell(SpellType::eyeEvil, price);
118             inputCommand.displayText(Ogre::ColourValue::White, txt);
119         }
120         inputCommand.selectSquaredTiles(inputManager.mXPos, inputManager.mYPos, inputManager.mXPos,
121             inputManager.mYPos);
122         return;
123     }
124 
125     if(inputManager.mCommandState == InputCommandState::building)
126     {
127         std::string txt = formatCastSpell(SpellType::eyeEvil, price);
128         inputCommand.displayText(Ogre::ColourValue::White, txt);
129         std::vector<Tile*> tiles;
130         tiles.push_back(tile);
131         inputCommand.selectTiles(tiles);
132         return;
133     }
134 
135     inputCommand.unselectAllTiles();
136 
137     ClientNotification *clientNotification = SpellManager::createSpellClientNotification(SpellType::eyeEvil);
138     gameMap->tileToPacket(clientNotification->mPacket, tile);
139 
140     ODClient::getSingleton().queueClientNotification(clientNotification);
141 }
142 
castSpell(GameMap * gameMap,Player * player,ODPacket & packet)143 bool SpellEyeEvil::castSpell(GameMap* gameMap, Player* player, ODPacket& packet)
144 {
145     Tile* tile = gameMap->tileFromPacket(packet);
146     if(tile == nullptr)
147         return false;
148 
149     int32_t playerMana = static_cast<int32_t>(player->getSeat()->getMana());
150     int32_t manaCost = ConfigManager::getSingleton().getSpellConfigInt32("EyeEvilPrice");
151     if(playerMana < manaCost)
152         return false;
153 
154     if(!player->getSeat()->takeMana(manaCost))
155         return false;
156 
157     SpellEyeEvil* spell = new SpellEyeEvil(gameMap);
158     spell->setSeat(player->getSeat());
159     spell->addToGameMap();
160     Ogre::Vector3 spawnPosition(static_cast<Ogre::Real>(tile->getX()),
161                                 static_cast<Ogre::Real>(tile->getY()),
162                                 static_cast<Ogre::Real>(3.0));
163     spell->createMesh();
164     spell->setPosition(spawnPosition);
165 
166     return true;
167 }
168 
getSpellFromStream(GameMap * gameMap,std::istream & is)169 Spell* SpellEyeEvil::getSpellFromStream(GameMap* gameMap, std::istream &is)
170 {
171     SpellEyeEvil* spell = new SpellEyeEvil(gameMap);
172     spell->importFromStream(is);
173     return spell;
174 }
175 
getSpellFromPacket(GameMap * gameMap,ODPacket & is)176 Spell* SpellEyeEvil::getSpellFromPacket(GameMap* gameMap, ODPacket &is)
177 {
178     SpellEyeEvil* spell = new SpellEyeEvil(gameMap);
179     spell->importFromPacket(is);
180     return spell;
181 }
182 
183