diff --git a/CMakeLists.txt b/CMakeLists.txt
index d3d6567dd..d5ed9ddd9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -180,7 +180,6 @@ set(OD_SOURCEFILES
${SRC}/CullingManager.cpp
${SRC}/CullingQuad.cpp
${SRC}/DummyArrayClass.cpp
- ${SRC}/DirectionalTrap.cpp
${SRC}/EditorMode.cpp
${SRC}/FppMode.cpp
${SRC}/GameEntity.cpp
@@ -207,7 +206,9 @@ set(OD_SOURCEFILES
${SRC}/MenuModeMultiplayerServer.cpp
${SRC}/MenuModeSkirmish.cpp
${SRC}/MiniMap.cpp
+ ${SRC}/MissileBoulder.cpp
${SRC}/MissileObject.cpp
+ ${SRC}/MissileOneHit.cpp
${SRC}/ModeManager.cpp
${SRC}/MortuaryQuad.cpp
${SRC}/MovableGameEntity.cpp
diff --git a/CREDITS b/CREDITS
index 81e9f2da2..a56cf3b0f 100644
--- a/CREDITS
+++ b/CREDITS
@@ -116,7 +116,8 @@ textures/
-> TentacleBed.png West CC0 http://forum.freegamedev.net/viewtopic.php?p=60091#p60091
-> TrainingDummy2_texture.png Danimal CC-BY-SA 3.0 http://forum.freegamedev.net/viewtopic.php?p=59239#p59239
-> TrainingDummy3.png P0ss CC-BY 3.0 http://forum.freegamedev.net/viewtopic.php?p=59351#p59351
--> TrainingDummy4.png Nobiax CC0 http://forum.freegamedev.net/viewtopic.php?p=59621#p59621p=59621#p59621
+-> TrainingDummy4.png Nobiax CC0 http://forum.freegamedev.net/viewtopic.php?p=59621#p59621
+-> Boulder.png Nobiax CC0 http://forum.freegamedev.net/viewtopic.php?p=59832#p59832
======================
@@ -210,6 +211,7 @@ Troll_Rock.mesh Dm3d CC-BY-SA 3.0
Water* Skorpio CC-BY-SA 3.0, GPL 3.0
Wizard.* Skorpio CC-BY-SA 3.0, GPL 3.0
Wyvern.* Andrew Buck, Skorpio CC-BY-SA 3.0, GPL 3.0
+Boulder.* Danimal CC-BY-SA 3.0 http://forum.freegamedev.net/viewtopic.php?p=59832#p59832
====================
diff --git a/gui/OpenDungeonsIcons.imageset b/gui/OpenDungeonsIcons.imageset
index 20cec7a3f..c9c9b48f3 100644
--- a/gui/OpenDungeonsIcons.imageset
+++ b/gui/OpenDungeonsIcons.imageset
@@ -19,5 +19,6 @@
+
\ No newline at end of file
diff --git a/gui/OpenDungeonsIcons.png b/gui/OpenDungeonsIcons.png
index 1363811ec..9b45e517a 100644
Binary files a/gui/OpenDungeonsIcons.png and b/gui/OpenDungeonsIcons.png differ
diff --git a/gui/OpenDungeonsMenuTraps.layout b/gui/OpenDungeonsMenuTraps.layout
index 4e470f6af..6ef4d152f 100644
--- a/gui/OpenDungeonsMenuTraps.layout
+++ b/gui/OpenDungeonsMenuTraps.layout
@@ -19,6 +19,12 @@
+
+
+
+
+
+
diff --git a/materials/scripts/Boulder.material b/materials/scripts/Boulder.material
new file mode 100644
index 000000000..cd31bb8d2
--- /dev/null
+++ b/materials/scripts/Boulder.material
@@ -0,0 +1,42 @@
+// Boulder genrated by blender2ogre 0.6.0
+
+material Boulder
+{
+ receive_shadows on
+
+ technique
+ {
+ pass Boulder
+ {
+ ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0
+ diffuse 0.6400000190734865 0.6400000190734865 0.6400000190734865 1.0
+ specular 0.0 0.0 0.0 1.0 12.5
+ emissive 0.0 0.0 0.0 1.0
+
+ alpha_to_coverage off
+ colour_write on
+ cull_hardware clockwise
+ depth_check on
+ depth_func less_equal
+ depth_write on
+ illumination_stage
+ light_clip_planes off
+ light_scissor off
+ lighting on
+ normalise_normals off
+ polygon_mode solid
+ scene_blend one zero
+ scene_blend_op add
+ shading gouraud
+ transparent_sorting on
+
+ texture_unit
+ {
+ texture Boulder.png
+ tex_address_mode wrap
+ scale 1.0 1.0
+ colour_op modulate
+ }
+ }
+ }
+}
diff --git a/materials/textures/Boulder.png b/materials/textures/Boulder.png
new file mode 100644
index 000000000..d5ab3e5ae
Binary files /dev/null and b/materials/textures/Boulder.png differ
diff --git a/models/Boulder.mesh b/models/Boulder.mesh
new file mode 100644
index 000000000..16547f112
Binary files /dev/null and b/models/Boulder.mesh differ
diff --git a/source/ChickenEntity.cpp b/source/ChickenEntity.cpp
index 65e650efb..ceb081349 100644
--- a/source/ChickenEntity.cpp
+++ b/source/ChickenEntity.cpp
@@ -18,7 +18,6 @@
#include "ChickenEntity.h"
#include "ODPacket.h"
#include "GameMap.h"
-#include "RoomTreasury.h"
#include "Random.h"
#include "LogManager.h"
@@ -30,16 +29,18 @@ const int32_t NB_TURNS_DIE_BEFORE_REMOVE = 5;
ChickenEntity::ChickenEntity(GameMap* gameMap, const std::string& hatcheryName) :
RenderedMovableEntity(gameMap, hatcheryName, "Chicken", 0.0f),
mChickenState(ChickenState::free),
- nbTurnOutsideHatchery(0),
- nbTurnDie(0)
+ mNbTurnOutsideHatchery(0),
+ mNbTurnDie(0),
+ mIsDropped(false)
{
}
ChickenEntity::ChickenEntity(GameMap* gameMap) :
RenderedMovableEntity(gameMap),
mChickenState(ChickenState::free),
- nbTurnOutsideHatchery(0),
- nbTurnDie(0)
+ mNbTurnOutsideHatchery(0),
+ mNbTurnDie(0),
+ mIsDropped(false)
{
setMeshName("Chicken");
}
@@ -52,7 +53,7 @@ void ChickenEntity::doUpkeep()
return;
Tile* tile = getPositionTile();
- OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(tile));
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "entityName=" + getName());
if(tile == nullptr)
return;
@@ -61,9 +62,9 @@ void ChickenEntity::doUpkeep()
if(mChickenState == ChickenState::dying)
{
- if(nbTurnDie < NB_TURNS_DIE_BEFORE_REMOVE)
+ if(mNbTurnDie < NB_TURNS_DIE_BEFORE_REMOVE)
{
- nbTurnDie++;
+ ++mNbTurnDie;
return;
}
mChickenState = ChickenState::dead;
@@ -82,19 +83,19 @@ void ChickenEntity::doUpkeep()
Room* currentHatchery = tile->getCoveringRoom();
if((currentHatchery != nullptr) && (currentHatchery->getType() == Room::RoomType::hatchery))
{
- nbTurnOutsideHatchery = 0;
+ mNbTurnOutsideHatchery = 0;
}
else
{
// If we are outside a hatchery for too long, we die
- if(nbTurnOutsideHatchery >= NB_TURNS_OUTSIDE_HATCHERY_BEFORE_DIE)
+ if(mNbTurnOutsideHatchery >= NB_TURNS_OUTSIDE_HATCHERY_BEFORE_DIE)
{
mChickenState = ChickenState::dying;
tile->removeChickenEntity(this);
setAnimationState("Die", false);
return;
}
- ++nbTurnOutsideHatchery;
+ ++mNbTurnOutsideHatchery;
}
// Handle normal behaviour : move or pick (if not already moving)
@@ -173,8 +174,8 @@ bool ChickenEntity::tryPickup(Seat* seat, bool isEditorMode)
return false;
Tile* tile = getPositionTile();
- OD_ASSERT_TRUE_MSG(tile != NULL, "tile=" + Tile::displayAsString(tile));
- if(tile == NULL)
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "entityName=" + getName());
+ if(tile == nullptr)
return false;
if(!tile->isClaimedForSeat(seat) && !isEditorMode)
@@ -187,7 +188,7 @@ void ChickenEntity::pickup()
{
Tile* tile = getPositionTile();
RenderedMovableEntity::pickup();
- OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(tile));
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "entityName=" + getName());
if(tile == nullptr)
return;
OD_ASSERT_TRUE(tile->removeChickenEntity(this));
@@ -209,6 +210,13 @@ bool ChickenEntity::tryDrop(Seat* seat, Tile* tile, bool isEditorMode)
return false;
}
+void ChickenEntity::drop(const Ogre::Vector3& v)
+{
+ mIsDropped = true;
+ RenderedMovableEntity::drop(v);
+ mIsDropped = false;
+}
+
void ChickenEntity::setPosition(const Ogre::Vector3& v)
{
if(!getIsOnMap())
@@ -220,21 +228,22 @@ void ChickenEntity::setPosition(const Ogre::Vector3& v)
Tile* oldTile = getPositionTile();
RenderedMovableEntity::setPosition(v);
Tile* tile = getPositionTile();
- OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(tile));
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "entityName=" + getName());
if(tile == nullptr)
return;
- if(tile == oldTile)
+ if(!mIsDropped && (tile == oldTile))
return;
+
if(oldTile != nullptr)
oldTile->removeChickenEntity(this);
- tile->addChickenEntity(this);
+ OD_ASSERT_TRUE(tile->addChickenEntity(this));
}
bool ChickenEntity::eatChicken(Creature* creature)
{
Tile* tile = getPositionTile();
- OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(tile));
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "entityName=" + getName());
if(tile == nullptr)
return false;
@@ -246,72 +255,20 @@ bool ChickenEntity::eatChicken(Creature* creature)
return true;
}
-const char* ChickenEntity::getFormat()
-{
- // TODO : implement saving/loading in the level file
- return "position";
-}
-
ChickenEntity* ChickenEntity::getChickenEntityFromStream(GameMap* gameMap, std::istream& is)
{
ChickenEntity* obj = new ChickenEntity(gameMap);
- Ogre::Vector3 position;
- Ogre::Real x, y, z;
- OD_ASSERT_TRUE(is >> x >> y >> z);
- obj->setPosition(Ogre::Vector3(x, y, z));
- Tile* tile = obj->getPositionTile();
- OD_ASSERT_TRUE(tile != nullptr);
- if(tile != nullptr)
- tile->addChickenEntity(obj);
return obj;
-
}
-ChickenEntity* ChickenEntity::getChickenEntityFromPacket(GameMap* gameMap, ODPacket& packet)
+ChickenEntity* ChickenEntity::getChickenEntityFromPacket(GameMap* gameMap, ODPacket& is)
{
ChickenEntity* obj = new ChickenEntity(gameMap);
- OD_ASSERT_TRUE(packet >> obj);
- Tile* tile = obj->getPositionTile();
- OD_ASSERT_TRUE(tile != nullptr);
- if(tile != nullptr)
- tile->addChickenEntity(obj);
-
return obj;
}
-void ChickenEntity::exportToPacket(ODPacket& packet)
-{
- packet << this;
-}
-
-std::ostream& operator<<(std::ostream& os, ChickenEntity* obj)
-{
- std::string name = obj->getName();
- Ogre::Vector3 position = obj->getPosition();
- os << name;
- os << position.x;
- os << position.y;
- os << position.z;
- return os;
-}
-
-ODPacket& operator>>(ODPacket& is, ChickenEntity* obj)
-{
- std::string name;
- OD_ASSERT_TRUE(is >> name);
- obj->setName(name);
- Ogre::Vector3 position;
- OD_ASSERT_TRUE(is >> position);
- obj->setPosition(position);
- return is;
-}
-
-ODPacket& operator<<(ODPacket& os, ChickenEntity* obj)
+const char* ChickenEntity::getFormat()
{
- std::string name = obj->getName();
- std::string meshName = obj->getMeshName();
- Ogre::Vector3 position = obj->getPosition();
- os << name;
- os << position;
- return os;
+ // TODO : implement saving/loading in the level file
+ return "position";
}
diff --git a/source/ChickenEntity.h b/source/ChickenEntity.h
index eea54bbfa..30a21492f 100644
--- a/source/ChickenEntity.h
+++ b/source/ChickenEntity.h
@@ -42,19 +42,16 @@ class ChickenEntity: public RenderedMovableEntity
{ return RenderedMovableEntityType::chickenEntity; }
virtual bool tryPickup(Seat* seat, bool isEditorMode);
+ virtual void pickup();
virtual bool tryDrop(Seat* seat, Tile* tile, bool isEditorMode);
+ virtual void drop(const Ogre::Vector3& v);
- virtual void exportToPacket(ODPacket& packet);
- virtual void pickup();
virtual void setPosition(const Ogre::Vector3& v);
bool eatChicken(Creature* creature);
- static const char* getFormat();
static ChickenEntity* getChickenEntityFromStream(GameMap* gameMap, std::istream& is);
- static ChickenEntity* getChickenEntityFromPacket(GameMap* gameMap, ODPacket& packet);
- friend ODPacket& operator<<(ODPacket& os, ChickenEntity* obj);
- friend ODPacket& operator>>(ODPacket& os, ChickenEntity* obj);
- friend std::ostream& operator<<(std::ostream& os, ChickenEntity* obj);
+ static ChickenEntity* getChickenEntityFromPacket(GameMap* gameMap, ODPacket& is);
+ static const char* getFormat();
private:
enum ChickenState
{
@@ -64,8 +61,9 @@ class ChickenEntity: public RenderedMovableEntity
dead
};
ChickenState mChickenState;
- int32_t nbTurnOutsideHatchery;
- int32_t nbTurnDie;
+ int32_t mNbTurnOutsideHatchery;
+ int32_t mNbTurnDie;
+ bool mIsDropped;
void addTileToListIfPossible(int x, int y, Room* currentHatchery, std::vector& possibleTileMove);
};
diff --git a/source/Creature.cpp b/source/Creature.cpp
index a18797638..2937e8c17 100644
--- a/source/Creature.cpp
+++ b/source/Creature.cpp
@@ -1695,7 +1695,7 @@ bool Creature::handleDepositGoldAction()
popAction();
Tile* tile = getPositionTile();
- OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(tile));
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "entityName=" + getName());
if(tile == nullptr)
return true;
TreasuryObject* obj = new TreasuryObject(getGameMap(), mGold);
@@ -1955,6 +1955,15 @@ bool Creature::handleEatingAction(bool isForced)
return false;
}
+ if ((isForced && mHunger < 5.0) ||
+ (!isForced && mHunger <= Random::Double(0.0, 15.0)))
+ {
+ popAction();
+
+ stopEating();
+ return true;
+ }
+
// If we are in a hatchery, we go to the closest chicken in it. If we are not
// in a hatchery, we check if there is a free chicken and eat it if we see it
Tile* closestChickenTile = nullptr;
@@ -2026,15 +2035,6 @@ bool Creature::handleEatingAction(bool isForced)
}
}
- if ((isForced && mHunger < 5.0) ||
- (!isForced && mHunger <= Random::Double(0.0, 25.0)))
- {
- popAction();
-
- stopEating();
- return true;
- }
-
if(mEatRoom != nullptr)
return false;
diff --git a/source/DirectionalTrap.cpp b/source/DirectionalTrap.cpp
deleted file mode 100644
index c5b835bd9..000000000
--- a/source/DirectionalTrap.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2011-2014 OpenDungeons Team
- *
- * 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 .
- */
-
-#include "DirectionalTrap.h"
-
-#include "Tile.h"
-#include "GameMap.h"
-
-DirectionalTrap::DirectionalTrap(GameMap* gameMap, int xdir, int ydir):
- Trap(gameMap)
-{
- mDir = std::pair(xdir, ydir);
-}
-
-DirectionalTrap::DirectionalTrap(GameMap* gameMap):
- Trap(gameMap)
-{
- mDir = std::pair(0, 0);
-}
-
-std::pair DirectionalTrap::projectionOnBorder(int xdir, int ydir)
-{
- GameMap* gm = getGameMap();
- int a = (ydir - mCoveredTiles[0]->y) / (xdir - mCoveredTiles[0]->x);
- int b = ydir - a * xdir;
-
- if(b >= 0 && b < gm->getMapSizeY())
- {
- return std::pair(0, b);
- }
- else if(-(b/a) >= 0 && -(b/a) < gm->getMapSizeX())
- {
- return std::pair((-b)/a, 0);
- }
-
- int tmp = a * (gm->getMapSizeY() - 1) + b;
- if(tmp >= 0 && tmp < gm->getMapSizeY())
- return std::pair(gm->getMapSizeX() - 1, tmp);
-
- return std::pair((gm->getMapSizeY() - b - 1)/a, gm->getMapSizeY() - 1);
-}
diff --git a/source/DirectionalTrap.h b/source/DirectionalTrap.h
deleted file mode 100644
index 67b5ca369..000000000
--- a/source/DirectionalTrap.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2011-2014 OpenDungeons Team
- *
- * 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 .
- */
-
-#ifndef DIRECTIONAL_TRAP_H
-#define DIRECTIONAL_TRAP_H
-
-#include
-#include "Trap.h"
-
-class DirectionalTrap : public Trap
-{
-public:
- DirectionalTrap(GameMap* gameMap, int xdir, int ydir);
-
-protected:
- DirectionalTrap(GameMap* gameMap);
- std::pair mDir;
- std::pair projectionOnBorder(int, int);
-};
-
-#endif // DIRECTIONAL_TRAP_H
diff --git a/source/GameEntity.h b/source/GameEntity.h
index 64b4974a7..80fa14fb4 100644
--- a/source/GameEntity.h
+++ b/source/GameEntity.h
@@ -57,7 +57,7 @@ class GameEntity
public:
enum ObjectType
{
- unknown, creature, room, trap, weapon, renderedMovableEntity, missileobject, tile
+ unknown, creature, room, trap, weapon, renderedMovableEntity, tile
};
//! \brief Default constructor with default values
diff --git a/source/GameMap.cpp b/source/GameMap.cpp
index a188c697b..46ff71d8d 100644
--- a/source/GameMap.cpp
+++ b/source/GameMap.cpp
@@ -36,7 +36,6 @@
#include "Seat.h"
#include "MapLight.h"
#include "TileCoordinateMap.h"
-#include "MissileObject.h"
#include "Weapon.h"
#include "MapLoader.h"
#include "LogManager.h"
@@ -211,7 +210,6 @@ void GameMap::clearAll()
clearCreatures();
clearClasses();
clearTraps();
- clearMissileObjects();
clearMapLights();
clearRooms();
@@ -292,7 +290,7 @@ void GameMap::resetUniqueNumbers()
mUniqueNumberFloodFilling = 0;
mUniqueNumberMissileObj = 0;
mUniqueNumberRoom = 0;
- mUniqueNumberRoomObj = 0;
+ mUniqueNumberRenderedMovableEntity = 0;
mUniqueNumberTrap = 0;
mUniqueNumberMapLight = 0;
}
@@ -431,10 +429,9 @@ void GameMap::addRenderedMovableEntity(RenderedMovableEntity *obj)
try
{
- RenderedMovableEntity::RenderedMovableEntityType objType = obj->getRenderedMovableEntityType();
ServerNotification *serverNotification = new ServerNotification(
- ServerNotification::addRenderedMovableEntity, NULL);
- serverNotification->mPacket << objType;
+ ServerNotification::addRenderedMovableEntity, nullptr);
+ obj->exportHeadersToPacket(serverNotification->mPacket);
obj->exportToPacket(serverNotification->mPacket);
ODServer::getSingleton().queueServerNotification(serverNotification);
}
@@ -1287,102 +1284,62 @@ Player* GameMap::getPlayerBySeat(Seat* seat)
return NULL;
}
-std::list GameMap::lineOfSight(int x0, int y0, int x1, int y1)
+std::list GameMap::tilesBetween(int x1, int y1, int x2, int y2)
{
std::list path;
- // Calculate the components of the 'manhattan distance'
- int Dx = x1 - x0;
- int Dy = y1 - y0;
-
- // Determine if the slope of the line is greater than 1
- int steep = (abs(Dy) >= abs(Dx));
- if (steep)
+ if(x2 == x1)
{
- std::swap(x0, y0);
- std::swap(x1, y1);
- // recompute Dx, Dy after swap
- Dx = x1 - x0;
- Dy = y1 - y0;
- }
+ // Vertical line, no need to compute
+ int diffY = 1;
+ if(y1 > y2)
+ diffY = -1;
- // Determine whether the x component is increasing or decreasing
- int xstep = 1;
- if (Dx < 0)
- {
- xstep = -1;
- Dx = -Dx;
- }
+ for(int y = y1; y != y2; y += diffY)
+ {
+ Tile* tile = getTile(x1, y);
+ if(tile == nullptr)
+ break;
- // Determine whether the y component is increasing or decreasing
- int ystep = 1;
- if (Dy < 0)
- {
- ystep = -1;
- Dy = -Dy;
+ path.push_back(tile);
+ }
}
-
- // Loop over the pixels on the line and add them to the return list
- int TwoDy = 2 * Dy;
- int TwoDyTwoDx = TwoDy - 2 * Dx; // 2*Dy - 2*Dx
- int E = TwoDy - Dx; //2*Dy - Dx
- int y = y0;
- int xDraw, yDraw;
- for (int x = x0; x != x1; x += xstep)
+ else
{
- // Treat a steep line as if it were actually its inverse
- if (steep)
- {
- xDraw = y;
- yDraw = x;
- }
- else
- {
- xDraw = x;
- yDraw = y;
- }
+ double deltax = x2 - x1;
+ double deltay = y2 - y1;
+ double error = 0;
+ double deltaerr = std::abs(deltay / deltax);
+ int diffX = 1;
+ if(x1 > x2)
+ diffX = -1;
- // If the tile exists, add it to the path.
- Tile *currentTile = getTile(xDraw, yDraw);
- if (currentTile != NULL)
- {
- path.push_back(currentTile);
- }
- else
- {
- // This should fix a bug where creatures "cut across" null sections of the map if they can see the other side.
- path.clear();
- return path;
- }
+ int diffY = 1;
+ if(y1 > y2)
+ diffY = -1;
- // If the error has accumulated to the next tile, "increment" the y coordinate
- if (E > 0)
+ int y = y1;
+ for(int x = x1; x != x2; x += diffX)
{
- // Also add the tile for this y-value for the next row over so that the line of sight consists of a 4-connected
- // path (i.e. you can traverse the path without ever having to move "diagonal" on the square grid).
- currentTile = getTile(xDraw + 1, y);
- if (currentTile != NULL)
- {
- path.push_back(currentTile);
- }
- else
+ Tile* tile = getTile(x, y);
+ if(tile == nullptr)
+ break;
+
+ path.push_back(tile);
+ error += deltaerr;
+ if(error >= 0.5)
{
- // This should fix a bug where creatures "cut across" null sections of the map if they can see the other side.
- path.clear();
- return path;
+ y += diffY;
+ error = error - 1.0;
}
-
- // Now increment y to the value it will be for the next x-value.
- E += TwoDyTwoDx; //E += 2*Dy - 2*Dx;
- y = y + ystep;
-
- }
- else
- {
- E += TwoDy; //E += 2*Dy;
}
}
+ // We add the last tile
+ Tile* tile = getTile(x2, y2);
+ if(tile != nullptr)
+ path.push_back(tile);
+
return path;
}
@@ -1488,10 +1445,32 @@ std::vector GameMap::getVisibleForce(std::vector visibleTile
OD_ASSERT_TRUE(tile != NULL);
if(tile == NULL)
continue;
- tile->fillAttackableObjects(returnList, seat, invert);
+
+ tile->fillAttackableCreatures(returnList, seat, invert);
+ tile->fillAttackableRoom(returnList, seat, invert);
+ tile->fillAttackableTrap(returnList, seat, invert);
+ }
+
+ return returnList;
+}
+
+std::vector GameMap::getVisibleCreatures(std::vector visibleTiles, Seat* seat, bool invert)
+{
+ std::vector returnList;
+
+ // Loop over the visible tiles
+ for (std::vector::iterator itr = visibleTiles.begin(); itr != visibleTiles.end(); ++itr)
+ {
+ Tile* tile = *itr;
+ OD_ASSERT_TRUE(tile != NULL);
+ if(tile == NULL)
+ continue;
+
+ tile->fillAttackableCreatures(returnList, seat, invert);
}
return returnList;
+
}
void GameMap::clearRooms()
@@ -1511,13 +1490,12 @@ void GameMap::addRoom(Room *r)
{
if(isServerGameMap())
{
- Room::RoomType type = r->getType();
int nbTiles = r->getCoveredTiles().size();
LogManager::getSingleton().logMessage("Adding room " + r->getName() + ", nbTiles="
+ Ogre::StringConverter::toString(nbTiles) + ", seatId=" + Ogre::StringConverter::toString(r->getSeat()->getId()));
ServerNotification notif(ServerNotification::buildRoom, getPlayerBySeat(r->getSeat()));
- notif.mPacket << type;
+ r->exportHeadersToPacket(notif.mPacket);
r->exportToPacket(notif.mPacket);
ODServer::getSingleton().sendAsyncMsgToAllClients(notif);
}
@@ -1663,13 +1641,12 @@ void GameMap::addTrap(Trap *trap)
{
if(isServerGameMap())
{
- Trap::TrapType type = trap->getType();
int nbTiles = trap->getCoveredTiles().size();
LogManager::getSingleton().logMessage("Adding trap " + trap->getName() + ", nbTiles="
+ Ogre::StringConverter::toString(nbTiles) + ", seatId=" + Ogre::StringConverter::toString(trap->getSeat()->getId()));
ServerNotification notif(ServerNotification::buildTrap, getPlayerBySeat(trap->getSeat()));
- notif.mPacket << type;
+ trap->exportHeadersToPacket(notif.mPacket);
trap->exportToPacket(notif.mPacket);
ODServer::getSingleton().sendAsyncMsgToAllClients(notif);
}
@@ -2007,106 +1984,6 @@ void GameMap::clearGoalsForAllSeats()
}
}
-void GameMap::clearMissileObjects()
-{
- for (unsigned int i = 0; i < missileObjects.size(); ++i)
- {
- MissileObject* mo = missileObjects[i];
- removeActiveObject(mo);
-
- for (std::vector::iterator it = animatedObjects.begin(); it != animatedObjects.end(); ++it)
- {
- MovableGameEntity* ao = *it;
- if (mo == ao)
- {
- animatedObjects.erase(it);
- break;
- }
- }
- mo->deleteYourself();
- }
-
- missileObjects.clear();
-}
-
-void GameMap::addMissileObject(MissileObject *m)
-{
- if(isServerGameMap())
- {
- LogManager::getSingleton().logMessage("Adding MissileObject " + m->getName());
- try
- {
- ServerNotification *serverNotification = new ServerNotification(
- ServerNotification::addMissileObject, NULL);
- serverNotification->mPacket << m;
- ODServer::getSingleton().queueServerNotification(serverNotification);
- }
- catch (std::bad_alloc&)
- {
- Ogre::LogManager::getSingleton().logMessage("ERROR: bad alloc in GameMap::addMissileObject", Ogre::LML_CRITICAL);
- exit(1);
- }
- }
-
- missileObjects.push_back(m);
- addActiveObject(m);
- addAnimatedObject(m);
-}
-
-void GameMap::removeMissileObject(MissileObject *m)
-{
- if(isServerGameMap())
- {
- LogManager::getSingleton().logMessage("Removing MissileObject " + m->getName());
- try
- {
- ServerNotification *serverNotification = new ServerNotification(
- ServerNotification::removeMissileObject, NULL);
- std::string name = m->getName();
- serverNotification->mPacket << name;
- ODServer::getSingleton().queueServerNotification(serverNotification);
- }
- catch (std::bad_alloc&)
- {
- Ogre::LogManager::getSingleton().logMessage("ERROR: bad alloc in GameMap::removeMissileObject", Ogre::LML_CRITICAL);
- exit(1);
- }
- }
-
- for (unsigned int i = 0; i < missileObjects.size(); ++i)
- {
- if (m == missileObjects[i])
- {
- missileObjects.erase(missileObjects.begin() + i);
- break;
- }
- }
-
- removeActiveObject(m);
- removeAnimatedObject(m);
-}
-
-MissileObject* GameMap::getMissileObject(int index)
-{
- return missileObjects[index];
-}
-
-MissileObject* GameMap::getMissileObject(const std::string& name)
-{
- for(std::vector::iterator it = missileObjects.begin(); it != missileObjects.end(); ++it)
- {
- MissileObject* mo = *it;
- if(mo->getName().compare(name) == 0)
- return mo;
- }
- return NULL;
-}
-
-unsigned int GameMap::numMissileObjects()
-{
- return missileObjects.size();
-}
-
Ogre::Real GameMap::crowDistance(Tile *t1, Tile *t2)
{
if (t1 != NULL && t2 != NULL)
@@ -2586,17 +2463,6 @@ int GameMap::nextUniqueNumberFloodFilling()
return ++mUniqueNumberFloodFilling;
}
-std::string GameMap::nextUniqueNameMissileObj()
-{
- std::string ret;
- do
- {
- ++mUniqueNumberMissileObj;
- ret = MissileObject::MISSILEOBJECT_NAME_PREFIX + Ogre::StringConverter::toString(mUniqueNumberMissileObj);
- } while(getAnimatedObject(ret) != NULL);
- return ret;
-}
-
std::string GameMap::nextUniqueNameRoom(const std::string& meshName)
{
std::string ret;
@@ -2608,13 +2474,13 @@ std::string GameMap::nextUniqueNameRoom(const std::string& meshName)
return ret;
}
-std::string GameMap::nextUniqueNameRoomObj(const std::string& baseName)
+std::string GameMap::nextUniqueNameRenderedMovableEntity(const std::string& baseName)
{
std::string ret;
do
{
- ++mUniqueNumberRoomObj;
- ret = RenderedMovableEntity::RENDEREDMOVABLEENTITY_PREFIX + baseName + "_" + Ogre::StringConverter::toString(mUniqueNumberRoomObj);
+ ++mUniqueNumberRenderedMovableEntity;
+ ret = RenderedMovableEntity::RENDEREDMOVABLEENTITY_PREFIX + baseName + "_" + Ogre::StringConverter::toString(mUniqueNumberRenderedMovableEntity);
} while(getAnimatedObject(ret) != NULL);
return ret;
}
@@ -2648,7 +2514,9 @@ void GameMap::logFloodFileTiles()
for(int xx = 0; xx < getMapSizeX(); ++xx)
{
Tile* tile = getTile(xx, yy);
- std::string str = "Tile floodfill : " + Tile::displayAsString(tile) + " - fullness=" + Ogre::StringConverter::toString(tile->getFullness());
+ std::string str = "Tile floodfill : " + Tile::displayAsString(tile)
+ + " - fullness=" + Ogre::StringConverter::toString(tile->getFullness())
+ + " - seatId=" + std::string(tile->getSeat() == nullptr ? "0" : Ogre::StringConverter::toString(tile->getSeat()->getId()));
for(int i = 0; i < Tile::FloodFillTypeMax; ++i)
{
str += ", [" + Ogre::StringConverter::toString(i) + "]=" +
diff --git a/source/GameMap.h b/source/GameMap.h
index 260aae546..d3df08f23 100644
--- a/source/GameMap.h
+++ b/source/GameMap.h
@@ -42,7 +42,6 @@ class Trap;
class Seat;
class Goal;
class MapLight;
-class MissileObject;
class MovableGameEntity;
class CreatureDefinition;
@@ -182,13 +181,6 @@ friend class ODServer;
Trap* getTrap(int index);
unsigned int numTraps();
- void clearMissileObjects();
- void addMissileObject(MissileObject *m);
- void removeMissileObject(MissileObject *m);
- MissileObject* getMissileObject(int index);
- MissileObject* getMissileObject(const std::string& name);
- unsigned int numMissileObjects();
-
//! \brief Map Lights related functions.
void clearMapLights();
void addMapLight(MapLight *m);
@@ -340,21 +332,24 @@ friend class ODServer;
std::list path(Creature *c1, Creature *c2, const CreatureDefinition* creatureDef, Seat* seat, bool throughDiggableTiles = false);
std::list path(Tile *t1, Tile *t2, const CreatureDefinition* creatureDef, Seat* seat, bool throughDiggableTiles = false);
- /*! \brief Returns a list of valid tiles along a straight line from (x1, y1) to (x2, y2), NOTE: in spite of
- * the name, you do not need to be able to see through the tiles returned by this method.
+ /*! \brief Returns a list of valid tiles along a straight line from (x1, y1) to (x2, y2)
+ * independently from their fullness or type.
*
* This algorithm is from
- * http://en.wikipedia.org/w/index.php?title=Bresenham%27s_line_algorithm&oldid=295047020
+ * http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
* A more detailed description of how it works can be found there.
*/
- std::list lineOfSight(int x1, int y1, int x2, int y2);
+ std::list tilesBetween(int x1, int y1, int x2, int y2);
//! \brief Returns the tiles visible from the given start tile out to the specified sight radius.
std::vector visibleTiles(Tile *startTile, double sightRadius);
- //! \brief Loops over the visibleTiles and returns any creatures in those tiles allied with the given seat (or if invert is true, is not allied)
+ //! \brief Loops over the visibleTiles and returns any creature/room/trap in those tiles allied with the given seat (or if invert is true, is not allied)
std::vector getVisibleForce(std::vector visibleTiles, Seat* seat, bool invert);
+ //! \brief Loops over the visibleTiles and returns any creature in those tiles allied with the given seat (or if invert is true, is not allied)
+ std::vector getVisibleCreatures(std::vector visibleTiles, Seat* seat, bool invert);
+
/** \brief Returns the as the crow flies distance between tiles located at the two coordinates given.
* If tiles do not exist at these locations the function returns -1.0.
*/
@@ -437,9 +432,9 @@ friend class ODServer;
//! \brief This functions create unique names. They check that there
//! is no entity with the same name before returning
std::string nextUniqueNameCreature(const std::string& className);
- std::string nextUniqueNameMissileObj();
+ std::string nextUniqueNameMissileObj(const std::string& baseName);
std::string nextUniqueNameRoom(const std::string& meshName);
- std::string nextUniqueNameRoomObj(const std::string& baseName);
+ std::string nextUniqueNameRenderedMovableEntity(const std::string& baseName);
std::string nextUniqueNameTrap(const std::string& meshName);
std::string nextUniqueNameMapLight();
@@ -479,7 +474,7 @@ friend class ODServer;
int mUniqueNumberFloodFilling;
int mUniqueNumberMissileObj;
int mUniqueNumberRoom;
- int mUniqueNumberRoomObj;
+ int mUniqueNumberRenderedMovableEntity;
int mUniqueNumberTrap;
int mUniqueNumberMapLight;
@@ -506,7 +501,6 @@ friend class ODServer;
std::vector rooms;
std::vector traps;
std::vector mapLights;
- std::vector missileObjects;
//! \brief Players and available game player slots (Seats)
std::vector players;
diff --git a/source/Gui.cpp b/source/Gui.cpp
index f737fcd76..596ed216c 100644
--- a/source/Gui.cpp
+++ b/source/Gui.cpp
@@ -188,6 +188,10 @@ void Gui::assignEventHandlers()
CEGUI::PushButton::EventClicked,
CEGUI::Event::Subscriber(&spikeTrapButtonPressed));
+ sheets[inGameMenu]->getChild(BUTTON_TRAP_BOULDER)->subscribeEvent(
+ CEGUI::PushButton::EventClicked,
+ CEGUI::Event::Subscriber(&boulderTrapButtonPressed));
+
sheets[inGameMenu]->getChild(BUTTON_DESTROY_TRAP)->subscribeEvent(
CEGUI::PushButton::EventClicked,
CEGUI::Event::Subscriber(&destroyTrapButtonPressed));
@@ -265,6 +269,10 @@ void Gui::assignEventHandlers()
CEGUI::PushButton::EventClicked,
CEGUI::Event::Subscriber(&spikeTrapButtonPressed));
+ sheets[editorModeGui]->getChild(BUTTON_TRAP_BOULDER)->subscribeEvent(
+ CEGUI::PushButton::EventClicked,
+ CEGUI::Event::Subscriber(&boulderTrapButtonPressed));
+
sheets[editorModeGui]->getChild(BUTTON_DESTROY_TRAP)->subscribeEvent(
CEGUI::PushButton::EventClicked,
CEGUI::Event::Subscriber(&destroyTrapButtonPressed));
@@ -476,6 +484,16 @@ bool Gui::spikeTrapButtonPressed(const CEGUI::EventArgs& e)
return true;
}
+bool Gui::boulderTrapButtonPressed(const CEGUI::EventArgs& e)
+{
+ GameMap* gameMap = ODFrameListener::getSingleton().getClientGameMap();
+ gameMap->getLocalPlayer()->setNewRoomType(Room::nullRoomType);
+ gameMap->getLocalPlayer()->setNewTrapType(Trap::boulder);
+ gameMap->getLocalPlayer()->setCurrentAction(Player::SelectedAction::buildTrap);
+ SoundEffectsManager::getSingleton().playInterfaceSound(SoundEffectsManager::BUTTONCLICK);
+ return true;
+}
+
bool Gui::destroyTrapButtonPressed(const CEGUI::EventArgs& e)
{
GameMap* gameMap = ODFrameListener::getSingleton().getClientGameMap();
@@ -789,6 +807,7 @@ const std::string Gui::BUTTON_DESTROY_ROOM = "MainTabControl/Rooms/DestroyRoomBu
const std::string Gui::TAB_TRAPS = "MainTabControl/Traps";
const std::string Gui::BUTTON_TRAP_CANNON = "MainTabControl/Traps/CannonButton";
const std::string Gui::BUTTON_TRAP_SPIKE = "MainTabControl/Traps/SpikeTrapButton";
+const std::string Gui::BUTTON_TRAP_BOULDER = "MainTabControl/Traps/BoulderTrapButton";
const std::string Gui::BUTTON_DESTROY_TRAP = "MainTabControl/Traps/DestroyTrapButton";
const std::string Gui::TAB_SPELLS = "MainTabControl/Spells";
const std::string Gui::TAB_CREATURES = "MainTabControl/Creatures";
diff --git a/source/Gui.h b/source/Gui.h
index a46800c85..15f3e1bd9 100644
--- a/source/Gui.h
+++ b/source/Gui.h
@@ -91,6 +91,7 @@ class Gui : public Ogre::Singleton
static const std::string TAB_TRAPS;
static const std::string BUTTON_TRAP_CANNON;
static const std::string BUTTON_TRAP_SPIKE;
+ static const std::string BUTTON_TRAP_BOULDER;
static const std::string BUTTON_DESTROY_TRAP;
static const std::string TAB_SPELLS;
static const std::string TAB_CREATURES;
@@ -206,6 +207,7 @@ class Gui : public Ogre::Singleton
static bool hatcheryButtonPressed (const CEGUI::EventArgs& e);
static bool cannonButtonPressed (const CEGUI::EventArgs& e);
static bool spikeTrapButtonPressed (const CEGUI::EventArgs& e);
+ static bool boulderTrapButtonPressed(const CEGUI::EventArgs& e);
static bool destroyTrapButtonPressed(const CEGUI::EventArgs& e);
static bool confirmExitYesButtonPressed (const CEGUI::EventArgs& e);
static bool confirmExitNoButtonPressed (const CEGUI::EventArgs& e);
diff --git a/source/MissileBoulder.cpp b/source/MissileBoulder.cpp
new file mode 100644
index 000000000..fcfbb497e
--- /dev/null
+++ b/source/MissileBoulder.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011-2014 OpenDungeons Team
+ *
+ * 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 .
+ */
+
+#include "MissileBoulder.h"
+#include "ODPacket.h"
+#include "GameMap.h"
+#include "Random.h"
+#include "LogManager.h"
+
+#include
+
+MissileBoulder::MissileBoulder(GameMap* gameMap, Seat* seat, const std::string& senderName, const std::string& meshName,
+ const Ogre::Vector3& direction, double damage) :
+ MissileObject(gameMap, seat, senderName, meshName, direction, true),
+ mDamage(damage),
+ nbHits(0)
+{
+}
+
+MissileBoulder::MissileBoulder(GameMap* gameMap) :
+ MissileObject(gameMap),
+ mDamage(0.0),
+ nbHits(0)
+{
+}
+
+bool MissileBoulder::hitCreature(GameEntity* entity)
+{
+ std::vector tiles = entity->getCoveredTiles();
+ if(tiles.empty())
+ return true;
+
+ Tile* hitTile = tiles[0];
+ entity->takeDamage(this, mDamage, hitTile);
+ ++nbHits;
+ if(Random::Uint(0, 10 - nbHits) <= 0)
+ return false;
+
+ return true;
+}
+
+bool MissileBoulder::wallHitNextDirection(const Ogre::Vector3& actDirection, Tile* tile, Ogre::Vector3& nextDirection)
+{
+ // When we hit a wall, we might break
+ if(Random::Uint(1, 2) == 1)
+ return false;
+
+ if(Random::Uint(1, 2) == 1)
+ {
+ nextDirection.x = actDirection.y;
+ nextDirection.y = actDirection.x;
+ nextDirection.z = actDirection.z;
+ }
+ else
+ {
+ nextDirection.x = -actDirection.y;
+ nextDirection.y = -actDirection.x;
+ nextDirection.z = actDirection.z;
+ }
+ return true;
+}
+
+MissileBoulder* MissileBoulder::getMissileBoulderFromStream(GameMap* gameMap, std::istream& is)
+{
+ MissileBoulder* obj = new MissileBoulder(gameMap);
+ return obj;
+}
+
+MissileBoulder* MissileBoulder::getMissileBoulderFromPacket(GameMap* gameMap, ODPacket& packet)
+{
+ MissileBoulder* obj = new MissileBoulder(gameMap);
+ return obj;
+}
diff --git a/source/MissileBoulder.h b/source/MissileBoulder.h
new file mode 100644
index 000000000..c3d8c8a1e
--- /dev/null
+++ b/source/MissileBoulder.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011-2014 OpenDungeons Team
+ *
+ * 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 .
+ */
+
+#ifndef MISSILEBOULDER_H
+#define MISSILEBOULDER_H
+
+#include "MissileObject.h"
+
+#include
+#include
+#include
+
+class Creature;
+class Room;
+class GameMap;
+class Tile;
+class ODPacket;
+
+class MissileBoulder: public MissileObject
+{
+public:
+ MissileBoulder(GameMap* gameMap, Seat* seat, const std::string& senderName, const std::string& meshName,
+ const Ogre::Vector3& direction, double damage);
+ MissileBoulder(GameMap* gameMap);
+
+ virtual MissileType getMissileType()
+ { return MissileType::boulder; }
+
+ virtual bool hitCreature(GameEntity* entity);
+ virtual bool wallHitNextDirection(const Ogre::Vector3& actDirection, Tile* tile, Ogre::Vector3& nextDirection);
+
+ static MissileBoulder* getMissileBoulderFromStream(GameMap* gameMap, std::istream& is);
+ static MissileBoulder* getMissileBoulderFromPacket(GameMap* gameMap, ODPacket& packet);
+private:
+ double mDamage;
+ int nbHits;
+};
+
+#endif // MISSILEBOULDER_H
diff --git a/source/MissileObject.cpp b/source/MissileObject.cpp
index 2b28c90e8..fab130b2b 100644
--- a/source/MissileObject.cpp
+++ b/source/MissileObject.cpp
@@ -16,122 +16,233 @@
*/
#include "MissileObject.h"
-
-#include "RenderRequest.h"
-#include "RenderManager.h"
#include "ODPacket.h"
#include "GameMap.h"
+#include "MissileBoulder.h"
+#include "MissileOneHit.h"
+#include "LogManager.h"
#include
-#include
-
-const std::string MissileObject::MISSILEOBJECT_NAME_PREFIX = "Missile_Object_";
-MissileObject::MissileObject(GameMap* gameMap, const std::string& nMeshName, const Ogre::Vector3& nPosition) :
- MovableGameEntity(gameMap)
+MissileObject::MissileObject(GameMap* gameMap, Seat* seat, const std::string& senderName,
+ const std::string& meshName, const Ogre::Vector3& direction, bool damageAllies) :
+ RenderedMovableEntity(gameMap, senderName, meshName, 0.0f),
+ mDirection(direction),
+ mIsMissileAlive(true),
+ mDamageAllies(damageAllies)
{
- setObjectType(GameEntity::missileobject);
-
- setName(gameMap->nextUniqueNameMissileObj());
-
- setMeshName(nMeshName);
- setMeshExisting(false);
- setPosition(nPosition);
+ setSeat(seat);
}
MissileObject::MissileObject(GameMap* gameMap) :
- MovableGameEntity(gameMap)
+ RenderedMovableEntity(gameMap),
+ mDirection(Ogre::Vector3::ZERO),
+ mIsMissileAlive(true),
+ mDamageAllies(false)
{
- setObjectType(GameEntity::missileobject);
- setMeshExisting(false);
}
-void MissileObject::createMeshLocal()
+void MissileObject::doUpkeep()
{
- MovableGameEntity::createMeshLocal();
+ if(!getIsOnMap())
+ return;
- if(getGameMap()->isServerGameMap())
+ if(!mIsMissileAlive)
+ {
+ if(!isMoving())
+ {
+ getGameMap()->removeRenderedMovableEntity(this);
+ deleteYourself();
+ }
return;
+ }
- RenderRequest* request = new RenderRequest;
- request->type = RenderRequest::createMissileObject;
- request->p = static_cast(this);
- RenderManager::queueRenderRequest(request);
-}
+ Tile* tile = getPositionTile();
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "entityName=" + getName());
+ if(tile == nullptr)
+ return;
-void MissileObject::destroyMeshLocal()
-{
- MovableGameEntity::destroyMeshLocal();
+ // We check if a creature is in our way. We start by taking the tile we will be on
+ Ogre::Vector3 position = getPosition();
+ double moveDist = getMoveSpeed();
+ Ogre::Vector3 destination = position + (moveDist * mDirection);
- if(getGameMap()->isServerGameMap())
+ std::list tiles = getGameMap()->tilesBetween(static_cast(position.x),
+ static_cast(position.y), static_cast(destination.x), static_cast(destination.y));
+
+ OD_ASSERT_TRUE(!tiles.empty());
+ if(tiles.empty())
+ {
+ getGameMap()->removeRenderedMovableEntity(this);
+ deleteYourself();
return;
+ }
- RenderRequest* request = new RenderRequest;
- request->type = RenderRequest::destroyMissileObject;
- request->p = static_cast(this);
- RenderManager::queueRenderRequest(request);
+ Tile* lastTile = nullptr;
+ while(!tiles.empty() && mIsMissileAlive)
+ {
+ Tile* tmpTile = tiles.front();
+ tiles.pop_front();
+
+ if(tmpTile->getFullness() > 0.0)
+ {
+ Ogre::Vector3 nextDirection;
+ mIsMissileAlive = wallHitNextDirection(mDirection, lastTile, nextDirection);
+ if(!mIsMissileAlive)
+ {
+ destination -= moveDist * mDirection;
+ break;
+ }
+ else
+ {
+ position.x = static_cast(lastTile->getX());
+ position.y = static_cast(lastTile->getY());
+ addDestination(position.x, position.y, position.z);
+ // We compute next position
+ mDirection = nextDirection;
+ destination = position + (moveDist * mDirection);
+ tiles = getGameMap()->tilesBetween(static_cast(position.x),
+ static_cast(position.y), static_cast(destination.x), static_cast(destination.y));
+
+ continue;
+ }
+ }
+
+ if(lastTile != nullptr)
+ {
+ Ogre::Vector3 lastPos;
+ lastPos.x = static_cast(lastTile->getX());
+ lastPos.y = static_cast(lastTile->getY());
+ lastPos.z = position.z;
+ Ogre::Vector3 curPos;
+ curPos.x = static_cast(tmpTile->getX());
+ curPos.y = static_cast(tmpTile->getY());
+ curPos.z = position.z;
+ moveDist -= lastPos.distance(curPos);
+ }
+ lastTile = tmpTile;
+
+ std::vector tileVector;
+ tileVector.push_back(tmpTile);
+ std::vector enemyCreatures = getGameMap()->getVisibleCreatures(tileVector, getSeat(), true);
+ for(std::vector::iterator it = enemyCreatures.begin(); it != enemyCreatures.end(); ++it)
+ {
+ GameEntity* creature = *it;
+ if(!hitCreature(creature))
+ {
+ destination -= moveDist * mDirection;
+ mIsMissileAlive = false;
+ break;
+ }
+ }
+
+ if(!mDamageAllies || !mIsMissileAlive)
+ continue;
+
+ std::vector alliedCreatures = getGameMap()->getVisibleCreatures(tileVector, getSeat(), false);
+ for(std::vector::iterator it = alliedCreatures.begin(); it != alliedCreatures.end(); ++it)
+ {
+ GameEntity* creature = *it;
+ if(!hitCreature(creature))
+ {
+ destination -= moveDist * mDirection;
+ mIsMissileAlive = false;
+ break;
+ }
+ }
+ }
+
+ addDestination(destination.x, destination.y, destination.z);
}
-void MissileObject::deleteYourselfLocal()
+void MissileObject::exportHeadersToStream(std::ostream& os)
{
- MovableGameEntity::deleteYourselfLocal();
- if(getGameMap()->isServerGameMap())
- return;
+ RenderedMovableEntity::exportHeadersToStream(os);
+ os << getMissileType() << "\t";
+}
- RenderRequest* request = new RenderRequest;
- request->type = RenderRequest::deleteMissileObject;
- request->p = static_cast(this);
- RenderManager::queueRenderRequest(request);
+void MissileObject::exportHeadersToPacket(ODPacket& os)
+{
+ RenderedMovableEntity::exportHeadersToPacket(os);
+ os << getMissileType();
}
-void MissileObject::doUpkeep()
+MissileObject* MissileObject::getMissileObjectFromStream(GameMap* gameMap, std::istream& is)
{
- // TODO: check if we collide with a creature, if yes, do some damage and delete ourselves
- if(!isMoving())
+ MissileObject* obj = nullptr;
+ MissileType type;
+ OD_ASSERT_TRUE(is >> type);
+ switch(type)
{
- getGameMap()->removeMissileObject(this);
- deleteYourself();
- return;
+ case MissileType::oneHit:
+ {
+ obj = MissileOneHit::getMissileOneHitFromStream(gameMap, is);
+ break;
+ }
+ case MissileType::boulder:
+ {
+ obj = MissileBoulder::getMissileBoulderFromStream(gameMap, is);
+ break;
+ }
+ default:
+ OD_ASSERT_TRUE_MSG(false, "Unknown enum value : " + Ogre::StringConverter::toString(
+ static_cast(type)));
+ break;
}
+ return obj;
}
-void MissileObject::setPosition(const Ogre::Vector3& v)
+MissileObject* MissileObject::getMissileObjectFromPacket(GameMap* gameMap, ODPacket& is)
{
- MovableGameEntity::setPosition(v);
- if(getGameMap()->isServerGameMap())
- return;
+ MissileObject* obj = nullptr;
+ MissileType type;
+ OD_ASSERT_TRUE(is >> type);
+ switch(type)
+ {
+ case MissileType::oneHit:
+ {
+ obj = MissileOneHit::getMissileOneHitFromPacket(gameMap, is);
+ break;
+ }
+ case MissileType::boulder:
+ {
+ obj = MissileBoulder::getMissileBoulderFromPacket(gameMap, is);
+ break;
+ }
+ default:
+ OD_ASSERT_TRUE_MSG(false, "Unknown enum value : " + Ogre::StringConverter::toString(
+ static_cast(type)));
+ break;
+ }
+ return obj;
+}
- RenderRequest* request = new RenderRequest;
- request->type = RenderRequest::moveSceneNode;
- request->str = getOgreNamePrefix() + "_node";
- request->vec = v;
- RenderManager::queueRenderRequest(request);
+ODPacket& operator<<(ODPacket& os, const MissileObject::MissileType& type)
+{
+ uint32_t intType = static_cast(type);
+ os << intType;
+ return os;
}
-ODPacket& operator<<(ODPacket& os, MissileObject *mo)
+ODPacket& operator>>(ODPacket& is, MissileObject::MissileType& type)
{
- std::string name = mo->getName();
- std::string meshName = mo->getMeshName();
- double moveSpeed = mo->getMoveSpeed();
- Ogre::Vector3 position = mo->getPosition();
- os << meshName << position << name << moveSpeed;
+ uint32_t intType;
+ is >> intType;
+ type = static_cast(intType);
+ return is;
+}
+std::ostream& operator<<(std::ostream& os, const MissileObject::MissileType& type)
+{
+ uint32_t intType = static_cast(type);
+ os << intType;
return os;
}
-ODPacket& operator>>(ODPacket& is, MissileObject *mo)
+std::istream& operator>>(std::istream& is, MissileObject::MissileType& type)
{
- std::string name;
- std::string meshName;
- Ogre::Vector3 position;
- double moveSpeed;
- is >> meshName;
- mo->setMeshName(meshName);
- is >> position;
- mo->setPosition(position);
- is >> name;
- mo->setName(name);
- is >> moveSpeed;
- mo->setMoveSpeed(moveSpeed);
+ uint32_t intType;
+ is >> intType;
+ type = static_cast(intType);
return is;
}
diff --git a/source/MissileObject.h b/source/MissileObject.h
index 0a2223e7c..d3d6261be 100644
--- a/source/MissileObject.h
+++ b/source/MissileObject.h
@@ -18,61 +18,64 @@
#ifndef MISSILEOBJECT_H
#define MISSILEOBJECT_H
-#include "MovableGameEntity.h"
+#include "RenderedMovableEntity.h"
-#include
#include
+#include
+#include
-#include
-
+class Creature;
+class Room;
class GameMap;
+class Tile;
class ODPacket;
-//! \brief This class implements missile object launched by traps when they're triggered.
-class MissileObject: public MovableGameEntity
+class MissileObject: public RenderedMovableEntity
{
-friend class ODClient;
-
public:
- MissileObject(GameMap* gameMap, const std::string& nMeshName, const Ogre::Vector3& nPosition);
-
- static const std::string MISSILEOBJECT_NAME_PREFIX;
-
- /*! \brief Changes the missile's position to a new position.
- * Moves the creature to a new location in 3d space. This function is
- * responsible for informing OGRE anything it needs to know.
- */
- void setPosition(const Ogre::Vector3& v);
-
- std::string getOgreNamePrefix() const { return "MissileObject_"; }
+ enum MissileType
+ {
+ oneHit,
+ boulder
+ };
+ MissileObject(GameMap* gameMap, Seat* seat, const std::string& senderName,
+ const std::string& meshName, const Ogre::Vector3& direction, bool damageAllies);
+ MissileObject(GameMap* gameMap);
virtual void doUpkeep();
- void receiveExp(double experience)
- {}
+ /*! brief Function called when the missile hits a wall. If it returns true, the missile direction
+ * will be set to nextDirection.
+ * If it returns false, the missile will be destroyed
+ */
+ virtual bool wallHitNextDirection(const Ogre::Vector3& actDirection, Tile* tile, Ogre::Vector3& nextDirection)
+ { return false; }
- void takeDamage(GameEntity* attacker, double damage, Tile* tileTakingDamage)
- {}
+ /*! brief Function called when the missile hits a creature. If it returns true, the missile continues
+ * If it returns false, the missile will be destroyed
+ */
+ virtual bool hitCreature(GameEntity* entity)
+ { return false; }
- double getDefense() const
- { return 0.0; }
+ virtual RenderedMovableEntityType getRenderedMovableEntityType()
+ { return RenderedMovableEntityType::missileObject; }
- double getHP(Tile* tile) const
- { return 0; }
+ virtual MissileType getMissileType() = 0;
- std::vector getCoveredTiles()
- { return std::vector(); }
+ virtual void exportHeadersToStream(std::ostream& os);
+ virtual void exportHeadersToPacket(ODPacket& os);
- friend ODPacket& operator<<(ODPacket& os, MissileObject *mo);
- friend ODPacket& operator>>(ODPacket& is, MissileObject *mo);
+ static MissileObject* getMissileObjectFromStream(GameMap* gameMap, std::istream& is);
+ static MissileObject* getMissileObjectFromPacket(GameMap* gameMap, ODPacket& is);
-protected:
- virtual void createMeshLocal();
- virtual void destroyMeshLocal();
- virtual void deleteYourselfLocal();
+ friend ODPacket& operator<<(ODPacket& os, const MissileObject::MissileType& rot);
+ friend ODPacket& operator>>(ODPacket& is, MissileObject::MissileType& rot);
+ friend std::ostream& operator<<(std::ostream& os, const MissileObject::MissileType& rot);
+ friend std::istream& operator>>(std::istream& is, MissileObject::MissileType& rot);
private:
- //!\brief For copy in ODClient
- MissileObject(GameMap* gameMap);
+ Ogre::Vector3 mDirection;
+ bool mIsMissileAlive;
+ bool mDamageAllies;
};
#endif // MISSILEOBJECT_H
diff --git a/source/MissileOneHit.cpp b/source/MissileOneHit.cpp
new file mode 100644
index 000000000..28758c41c
--- /dev/null
+++ b/source/MissileOneHit.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011-2014 OpenDungeons Team
+ *
+ * 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 .
+ */
+
+#include "MissileOneHit.h"
+#include "ODPacket.h"
+#include "GameMap.h"
+#include "Random.h"
+#include "LogManager.h"
+
+#include
+
+MissileOneHit::MissileOneHit(GameMap* gameMap, Seat* seat, const std::string& senderName, const std::string& meshName,
+ const Ogre::Vector3& direction, double damage, bool damageAllies) :
+ MissileObject(gameMap, seat, senderName, meshName, direction, damageAllies),
+ mDamage(damage)
+{
+}
+
+MissileOneHit::MissileOneHit(GameMap* gameMap) :
+ MissileObject(gameMap),
+ mDamage(0.0)
+{
+}
+
+bool MissileOneHit::hitCreature(GameEntity* entity)
+{
+ std::vector tiles = entity->getCoveredTiles();
+ if(tiles.empty())
+ return true;
+
+ Tile* hitTile = tiles[0];
+ entity->takeDamage(this, mDamage, hitTile);
+ return false;
+}
+
+MissileOneHit* MissileOneHit::getMissileOneHitFromStream(GameMap* gameMap, std::istream& is)
+{
+ MissileOneHit* obj = new MissileOneHit(gameMap);
+ return obj;
+}
+
+MissileOneHit* MissileOneHit::getMissileOneHitFromPacket(GameMap* gameMap, ODPacket& packet)
+{
+ MissileOneHit* obj = new MissileOneHit(gameMap);
+ return obj;
+}
diff --git a/source/MissileOneHit.h b/source/MissileOneHit.h
new file mode 100644
index 000000000..87aba1152
--- /dev/null
+++ b/source/MissileOneHit.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011-2014 OpenDungeons Team
+ *
+ * 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 .
+ */
+
+#ifndef MISSILEONEHIT_H
+#define MISSILEONEHIT_H
+
+#include "MissileObject.h"
+
+#include
+#include
+#include
+
+class Creature;
+class Room;
+class GameMap;
+class Tile;
+class ODPacket;
+
+class MissileOneHit: public MissileObject
+{
+public:
+ MissileOneHit(GameMap* gameMap, Seat* seat, const std::string& senderName, const std::string& meshName,
+ const Ogre::Vector3& direction, double damage, bool damageAllies);
+ MissileOneHit(GameMap* gameMap);
+
+ virtual MissileType getMissileType()
+ { return MissileType::oneHit; }
+
+ virtual bool hitCreature(GameEntity* entity);
+
+ static MissileOneHit* getMissileOneHitFromStream(GameMap* gameMap, std::istream& is);
+ static MissileOneHit* getMissileOneHitFromPacket(GameMap* gameMap, ODPacket& packet);
+private:
+ double mDamage;
+};
+
+#endif // MISSILEONEHIT_H
diff --git a/source/ODApplication.cpp b/source/ODApplication.cpp
index c6f6284e1..713f095d4 100644
--- a/source/ODApplication.cpp
+++ b/source/ODApplication.cpp
@@ -37,7 +37,6 @@
#include "GameMap.h"
#include "Random.h"
#include "MapLight.h"
-#include "MissileObject.h"
#include "ODServer.h"
#include "ODClient.h"
diff --git a/source/ODClient.cpp b/source/ODClient.cpp
index e2eb9f4da..ab209f813 100644
--- a/source/ODClient.cpp
+++ b/source/ODClient.cpp
@@ -30,7 +30,6 @@
#include "Weapon.h"
#include "ODApplication.h"
#include "RoomTreasury.h"
-#include "MissileObject.h"
#include "TreasuryObject.h"
#include "RenderedMovableEntity.h"
#include "LogManager.h"
@@ -343,7 +342,7 @@ bool ODClient::processOneClientSocketMessage()
MovableGameEntity *tempAnimatedObject = gameMap->getAnimatedObject(objName);
OD_ASSERT_TRUE_MSG(tempAnimatedObject != NULL, "objName=" + objName);
if (tempAnimatedObject != NULL)
- tempAnimatedObject->addDestination(vect.x, vect.y);
+ tempAnimatedObject->addDestination(vect.x, vect.y, vect.z);
break;
}
@@ -403,12 +402,12 @@ bool ODClient::processOneClientSocketMessage()
Tile tmpTile(gameMap);
OD_ASSERT_TRUE(packetReceived >> seatId >> &tmpTile);
Player *tempPlayer = gameMap->getPlayerBySeatId(seatId);
- OD_ASSERT_TRUE_MSG(tempPlayer != NULL, "seatId=" + Ogre::StringConverter::toString(seatId));
+ OD_ASSERT_TRUE_MSG(tempPlayer != nullptr, "seatId=" + Ogre::StringConverter::toString(seatId));
Tile* tile = gameMap->getTile(tmpTile.getX(), tmpTile.getY());
- OD_ASSERT_TRUE_MSG(tile != NULL, "tile=" + Tile::displayAsString(&tmpTile));
- if (tempPlayer != NULL && tile != NULL)
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(&tmpTile));
+ if (tempPlayer != nullptr && tile != nullptr)
{
- OD_ASSERT_TRUE(tempPlayer->dropHand(tile) != NULL);
+ OD_ASSERT_TRUE(tempPlayer->dropHand(tile) != nullptr);
}
break;
}
@@ -553,10 +552,10 @@ bool ODClient::processOneClientSocketMessage()
Tile tmpTile(gameMap);
OD_ASSERT_TRUE(packetReceived >> roomName>> &tmpTile);
Room* room = gameMap->getRoomByName(roomName);
- OD_ASSERT_TRUE_MSG(room != NULL, "roomName=" + roomName);
+ OD_ASSERT_TRUE_MSG(room != nullptr, "roomName=" + roomName);
Tile* tile = gameMap->getTile(tmpTile.getX(), tmpTile.getY());
- OD_ASSERT_TRUE_MSG(tile != NULL, "tile=" + Tile::displayAsString(&tmpTile));
- if((room != NULL) && (tile != NULL))
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(&tmpTile));
+ if((room != nullptr) && (tile != nullptr))
{
room->removeCoveredTile(tile);
// If no more tiles, the room is removed
@@ -578,10 +577,10 @@ bool ODClient::processOneClientSocketMessage()
Tile tmpTile(gameMap);
OD_ASSERT_TRUE(packetReceived >> trapName>> &tmpTile);
Trap* trap = gameMap->getTrapByName(trapName);
- OD_ASSERT_TRUE_MSG(trap != NULL, "trapName=" + trapName);
+ OD_ASSERT_TRUE_MSG(trap != nullptr, "trapName=" + trapName);
Tile* tile = gameMap->getTile(tmpTile.getX(), tmpTile.getY());
- OD_ASSERT_TRUE_MSG(tile != NULL, "tile=" + Tile::displayAsString(&tmpTile));
- if((trap != NULL) && (tile != NULL))
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(&tmpTile));
+ if((trap != nullptr) && (tile != nullptr))
{
trap->removeCoveredTile(tile);
// If no more tiles, the room is removed
@@ -644,31 +643,6 @@ bool ODClient::processOneClientSocketMessage()
break;
}
- case ServerNotification::addMissileObject:
- {
- MissileObject* missile = new MissileObject(gameMap);
- OD_ASSERT_TRUE(packetReceived >> missile);
- gameMap->addMissileObject(missile);
- missile->createMesh();
- SoundEffectsManager::getSingleton().playInterfaceSound(SoundEffectsManager::CANNONFIRING,
- missile->getPosition());
- break;
- }
-
- case ServerNotification::removeMissileObject:
- {
- std::string name;
- OD_ASSERT_TRUE(packetReceived >> name);
- MissileObject* missile = gameMap->getMissileObject(name);
- OD_ASSERT_TRUE_MSG(missile != NULL, "name=" + name);
- if(missile != NULL)
- {
- gameMap->removeMissileObject(missile);
- missile->deleteYourself();
- }
- break;
- }
-
case ServerNotification::addRenderedMovableEntity:
{
RenderedMovableEntity* tempRenderedMovableEntity = RenderedMovableEntity::getRenderedMovableEntityFromPacket(gameMap, packetReceived);
diff --git a/source/ODServer.cpp b/source/ODServer.cpp
index af71fe709..529034f58 100644
--- a/source/ODServer.cpp
+++ b/source/ODServer.cpp
@@ -691,7 +691,7 @@ bool ODServer::processClientNotifications(ODSocketClient* clientSocket)
OD_ASSERT_TRUE(packetReceived >> &tmpTile);
Player *player = clientSocket->getPlayer();
Tile* tile = gameMap->getTile(tmpTile.getX(), tmpTile.getY());
- OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(tile));
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(&tmpTile));
if(tile != nullptr)
{
if(player->isDropHandPossible(tile, 0, mServerMode == ServerMode::ModeEditor))
@@ -752,7 +752,7 @@ bool ODServer::processClientNotifications(ODSocketClient* clientSocket)
std::vector tiles;
int goldRequired;
- gameMap->fillBuildableTilesAndPriceForPlayerInArea(x1, y1, x2, y2, player, Room::RoomType::dormitory, tiles, goldRequired);
+ gameMap->fillBuildableTilesAndPriceForPlayerInArea(x1, y1, x2, y2, player, type, tiles, goldRequired);
if(tiles.empty())
break;
@@ -941,9 +941,7 @@ bool ODServer::processClientNotifications(ODSocketClient* clientSocket)
}
case Trap::TrapType::boulder:
{
- int x, y;
- OD_ASSERT_TRUE(packetReceived >> x >> y);
- trap = new TrapBoulder(gameMap, x, y);
+ trap = new TrapBoulder(gameMap);
break;
}
default:
@@ -1297,9 +1295,7 @@ bool ODServer::processClientNotifications(ODSocketClient* clientSocket)
}
case Trap::TrapType::boulder:
{
- int x, y;
- OD_ASSERT_TRUE(packetReceived >> x >> y);
- trap = new TrapBoulder(gameMap, x, y);
+ trap = new TrapBoulder(gameMap);
break;
}
default:
diff --git a/source/RenderManager.cpp b/source/RenderManager.cpp
index 6216142ef..cf4ba381b 100644
--- a/source/RenderManager.cpp
+++ b/source/RenderManager.cpp
@@ -29,7 +29,6 @@
#include "MapLight.h"
#include "Creature.h"
#include "Weapon.h"
-#include "MissileObject.h"
#include "Trap.h"
#include "Player.h"
#include "ResourceManager.h"
@@ -275,14 +274,6 @@ bool RenderManager::handleRenderRequest(const RenderRequest& renderRequest)
rrDestroyWeapon(renderRequest);
break;
- case RenderRequest::createMissileObject:
- rrCreateMissileObject(renderRequest);
- break;
-
- case RenderRequest::destroyMissileObject:
- rrDestroyMissileObject(renderRequest);
- break;
-
case RenderRequest::createMapLight:
rrCreateMapLight(renderRequest);
break;
@@ -333,13 +324,6 @@ bool RenderManager::handleRenderRequest(const RenderRequest& renderRequest)
break;
}
- case RenderRequest::deleteMissileObject:
- {
- MissileObject* curMissileObject = static_cast(renderRequest.p);
- delete curMissileObject;
- break;
- }
-
case RenderRequest::moveSceneNode:
rrMoveSceneNode(renderRequest);
break;
@@ -863,34 +847,6 @@ void RenderManager::rrDestroyWeapon(const RenderRequest& renderRequest)
}
}
-void RenderManager::rrCreateMissileObject(const RenderRequest& renderRequest)
-{
- MissileObject* curMissileObject = static_cast(renderRequest.p);
- Ogre::Entity* ent = mSceneManager->createEntity(curMissileObject->getOgreNamePrefix()
- + curMissileObject->getName(), curMissileObject->getMeshName() + ".mesh");
- //TODO: Make a new subroot scene node for these so lookups are faster
- // since only a few missile objects should be onscreen at once.
- Ogre::SceneNode* node = mCreatureSceneNode->createChildSceneNode(
- ent->getName() + "_node");
- node->setPosition(curMissileObject->getPosition());
- node->attachObject(ent);
-}
-
-void RenderManager::rrDestroyMissileObject(const RenderRequest& renderRequest)
-{
- MissileObject* curMissileObject = static_cast(renderRequest.p);
- std::string moName = curMissileObject->getOgreNamePrefix() + curMissileObject->getName();
- if (mSceneManager->hasEntity(moName))
- {
- Ogre::Entity* ent = mSceneManager->getEntity(moName);
- Ogre::SceneNode* node = mSceneManager->getSceneNode(moName + "_node");
- node->detachObject(ent);
- mCreatureSceneNode->removeChild(node);
- mSceneManager->destroyEntity(ent);
- mSceneManager->destroySceneNode(node->getName());
- }
-}
-
void RenderManager::rrCreateMapLight(const RenderRequest& renderRequest)
{
MapLight* curMapLight = static_cast (renderRequest.p);
diff --git a/source/RenderManager.h b/source/RenderManager.h
index f9ef96166..94d1d41d6 100644
--- a/source/RenderManager.h
+++ b/source/RenderManager.h
@@ -118,8 +118,6 @@ class RenderManager: public Ogre::Singleton
void rrScaleSceneNode(const RenderRequest& renderRequest);
void rrCreateWeapon(const RenderRequest& renderRequest);
void rrDestroyWeapon(const RenderRequest& renderRequest);
- void rrCreateMissileObject(const RenderRequest& renderRequest);
- void rrDestroyMissileObject(const RenderRequest& renderRequest);
void rrCreateMapLight(const RenderRequest& renderRequest);
void rrDestroyMapLight(const RenderRequest& renderRequest);
void rrDestroyMapLightVisualIndicator(const RenderRequest& renderRequest);
diff --git a/source/RenderRequest.h b/source/RenderRequest.h
index 478fb2fa3..c53419954 100644
--- a/source/RenderRequest.h
+++ b/source/RenderRequest.h
@@ -73,9 +73,6 @@ class RenderRequest
orientSceneNodeToward,
reorientSceneNode,
scaleSceneNode,
- createMissileObject,
- destroyMissileObject,
- deleteMissileObject, //setMissileObjectAnimationState,
noRequest
};
diff --git a/source/RenderedMovableEntity.cpp b/source/RenderedMovableEntity.cpp
index 83c0c5ac2..da331848b 100644
--- a/source/RenderedMovableEntity.cpp
+++ b/source/RenderedMovableEntity.cpp
@@ -23,6 +23,7 @@
#include "RenderManager.h"
#include "TreasuryObject.h"
#include "ChickenEntity.h"
+#include "MissileObject.h"
#include "LogManager.h"
#include
@@ -38,11 +39,12 @@ RenderedMovableEntity::RenderedMovableEntity(GameMap* gameMap, const std::string
setObjectType(GameEntity::renderedMovableEntity);
setMeshName(nMeshName);
// Set a unique name for the object
- setName(gameMap->nextUniqueNameRoomObj(baseName));
+ setName(gameMap->nextUniqueNameRenderedMovableEntity(baseName));
}
RenderedMovableEntity::RenderedMovableEntity(GameMap* gameMap) :
MovableGameEntity(gameMap),
+ mRotationAngle(0.0),
mIsOnMap(true)
{
setObjectType(GameEntity::renderedMovableEntity);
@@ -108,19 +110,29 @@ const char* RenderedMovableEntity::getFormat()
RenderedMovableEntity* RenderedMovableEntity::getRenderedMovableEntityFromLine(GameMap* gameMap, const std::string& line)
{
RenderedMovableEntity* obj = nullptr;
- std::stringstream ss(line);
+ std::stringstream is(line);
RenderedMovableEntity::RenderedMovableEntityType rot;
- OD_ASSERT_TRUE(ss >> rot);
+ OD_ASSERT_TRUE(is >> rot);
switch(rot)
{
case RenderedMovableEntityType::buildingObject:
{
- // Default type. Used in buildings. Should not be saved in level file
+ obj = new RenderedMovableEntity(gameMap);
break;
}
case RenderedMovableEntityType::treasuryObject:
{
- obj = TreasuryObject::getTreasuryObjectFromStream(gameMap, ss);
+ obj = TreasuryObject::getTreasuryObjectFromStream(gameMap, is);
+ break;
+ }
+ case RenderedMovableEntityType::chickenEntity:
+ {
+ obj = ChickenEntity::getChickenEntityFromStream(gameMap, is);
+ break;
+ }
+ case RenderedMovableEntityType::missileObject:
+ {
+ obj = MissileObject::getMissileObjectFromStream(gameMap, is);
break;
}
default:
@@ -130,6 +142,11 @@ RenderedMovableEntity* RenderedMovableEntity::getRenderedMovableEntityFromLine(G
break;
}
}
+
+ if(obj == nullptr)
+ return nullptr;
+
+ obj->importFromStream(is);
return obj;
}
@@ -143,7 +160,6 @@ RenderedMovableEntity* RenderedMovableEntity::getRenderedMovableEntityFromPacket
case RenderedMovableEntityType::buildingObject:
{
obj = new RenderedMovableEntity(gameMap);
- OD_ASSERT_TRUE(is >> obj);
break;
}
case RenderedMovableEntityType::treasuryObject:
@@ -156,6 +172,11 @@ RenderedMovableEntity* RenderedMovableEntity::getRenderedMovableEntityFromPacket
obj = ChickenEntity::getChickenEntityFromPacket(gameMap, is);
break;
}
+ case RenderedMovableEntityType::missileObject:
+ {
+ obj = MissileObject::getMissileObjectFromPacket(gameMap, is);
+ break;
+ }
default:
{
OD_ASSERT_TRUE_MSG(false, "Unknown enum value : " + Ogre::StringConverter::toString(
@@ -163,36 +184,69 @@ RenderedMovableEntity* RenderedMovableEntity::getRenderedMovableEntityFromPacket
break;
}
}
+
+ if(obj == nullptr)
+ return nullptr;
+
+ obj->importFromPacket(is);
return obj;
}
-void RenderedMovableEntity::exportToPacket(ODPacket& packet)
+void RenderedMovableEntity::exportHeadersToStream(std::ostream& os)
+{
+ os << getRenderedMovableEntityType() << "\t";
+}
+
+void RenderedMovableEntity::exportHeadersToPacket(ODPacket& os)
{
- packet << this;
+ os << getRenderedMovableEntityType();
}
-ODPacket& operator<<(ODPacket& os, RenderedMovableEntity* ro)
+void RenderedMovableEntity::exportToPacket(ODPacket& os)
{
- std::string name = ro->getName();
- std::string meshName = ro->getMeshName();
- Ogre::Vector3 position = ro->getPosition();
+ std::string name = getName();
+ std::string meshName = getMeshName();
+ Ogre::Vector3 position = getPosition();
os << name << meshName;
- os << position << ro->mRotationAngle;
- return os;
+ os << position << mRotationAngle;
}
-ODPacket& operator>>(ODPacket& is, RenderedMovableEntity* ro)
+void RenderedMovableEntity::importFromPacket(ODPacket& is)
{
std::string name;
+ std::string meshName;
Ogre::Vector3 position;
- is >> name;
- ro->setName(name);
- is >> name;
- ro->setMeshName(name);
- is >> position;
- ro->setPosition(position);
- is >> ro->mRotationAngle;
- return is;
+ OD_ASSERT_TRUE(is >> name);
+ setName(name);
+ OD_ASSERT_TRUE(is >> meshName);
+ setMeshName(meshName);
+ OD_ASSERT_TRUE(is >> position);
+ setPosition(position);
+ OD_ASSERT_TRUE(is >> mRotationAngle);
+}
+
+void RenderedMovableEntity::exportToStream(std::ostream& os)
+{
+ std::string name = getName();
+ std::string meshName = getMeshName();
+ Ogre::Vector3 position = getPosition();
+ os << name << "\t" << meshName << "\t";
+ os << position.x << "\t" << position.y << "\t" << position.z << "\t";
+ os << mRotationAngle << "\t";
+}
+
+void RenderedMovableEntity::importFromStream(std::istream& is)
+{
+ std::string name;
+ std::string meshName;
+ Ogre::Vector3 position;
+ OD_ASSERT_TRUE(is >> name);
+ setName(name);
+ OD_ASSERT_TRUE(is >> meshName);
+ setMeshName(meshName);
+ OD_ASSERT_TRUE(is >> position.x >> position.y >> position.z);
+ setPosition(position);
+ OD_ASSERT_TRUE(is >> mRotationAngle);
}
ODPacket& operator<<(ODPacket& os, const RenderedMovableEntity::RenderedMovableEntityType& rot)
diff --git a/source/RenderedMovableEntity.h b/source/RenderedMovableEntity.h
index f80d8f55b..ca5969671 100644
--- a/source/RenderedMovableEntity.h
+++ b/source/RenderedMovableEntity.h
@@ -36,7 +36,8 @@ class RenderedMovableEntity: public MovableGameEntity
{
buildingObject,
treasuryObject,
- chickenEntity
+ chickenEntity,
+ missileObject
};
//! \brief Creates a RenderedMovableEntity. It's name is built from baseName and some unique id from the gamemap.
//! We use baseName to help understand what's this object for when getting a log
@@ -81,13 +82,22 @@ class RenderedMovableEntity: public MovableGameEntity
virtual void pickup();
virtual void drop(const Ogre::Vector3& v);
- virtual void exportToPacket(ODPacket& packet);
+ /*! \brief Exports the headers needed to recreate the RenderedMovableEntity. For example, for
+ * missile objects type cannon, it exports RenderedMovableEntity::missileObject
+ * and MissileType::oneHit. The content of the RenderedMovableEntity will be exported
+ * by exportToPacket
+ */
+ virtual void exportHeadersToStream(std::ostream& os);
+ virtual void exportHeadersToPacket(ODPacket& os);
+ //! \brief Exports the data of the RenderedMovableEntity
+ virtual void exportToStream(std::ostream& os);
+ virtual void importFromStream(std::istream& is);
+ virtual void exportToPacket(ODPacket& os);
+ virtual void importFromPacket(ODPacket& is);
static RenderedMovableEntity* getRenderedMovableEntityFromLine(GameMap* gameMap, const std::string& line);
static RenderedMovableEntity* getRenderedMovableEntityFromPacket(GameMap* gameMap, ODPacket& is);
static const char* getFormat();
- friend ODPacket& operator<<(ODPacket& os, RenderedMovableEntity* o);
- friend ODPacket& operator>>(ODPacket& is, RenderedMovableEntity* o);
friend ODPacket& operator<<(ODPacket& os, const RenderedMovableEntity::RenderedMovableEntityType& rot);
friend ODPacket& operator>>(ODPacket& is, RenderedMovableEntity::RenderedMovableEntityType& rot);
@@ -101,8 +111,8 @@ class RenderedMovableEntity: public MovableGameEntity
virtual void createMeshLocal();
virtual void destroyMeshLocal();
virtual void deleteYourselfLocal();
- Ogre::Real mRotationAngle;
private:
+ Ogre::Real mRotationAngle;
bool mIsOnMap;
};
diff --git a/source/Room.cpp b/source/Room.cpp
index 616fc1cd9..a21f2f4da 100644
--- a/source/Room.cpp
+++ b/source/Room.cpp
@@ -304,41 +304,38 @@ Room* Room::getRoomFromStream(GameMap* gameMap, std::istream& is)
break;
case dormitory:
tempRoom = new RoomDormitory(gameMap);
- is >> tempRoom;
break;
case treasury:
tempRoom = new RoomTreasury(gameMap);
- is >> tempRoom;
break;
case portal:
tempRoom = new RoomPortal(gameMap);
- is >> tempRoom;
break;
case dungeonTemple:
tempRoom = new RoomDungeonTemple(gameMap);
- is >> tempRoom;
break;
case forge:
tempRoom = new RoomForge(gameMap);
- is >> tempRoom;
break;
case trainingHall:
tempRoom = new RoomTrainingHall(gameMap);
- is >> tempRoom;
break;
case library:
tempRoom = new RoomLibrary(gameMap);
- is >> tempRoom;
break;
case hatchery:
tempRoom = new RoomHatchery(gameMap);
- is >> tempRoom;
break;
default:
OD_ASSERT_TRUE_MSG(false, "Unknown enum value : " + Ogre::StringConverter::toString(
static_cast(nType)));
}
+ if(tempRoom == nullptr)
+ return nullptr;
+
+ tempRoom->importFromStream(is);
+
return tempRoom;
}
@@ -355,126 +352,39 @@ Room* Room::getRoomFromPacket(GameMap* gameMap, ODPacket& is)
break;
case dormitory:
tempRoom = new RoomDormitory(gameMap);
- is >> tempRoom;
break;
case treasury:
tempRoom = new RoomTreasury(gameMap);
- is >> tempRoom;
break;
case portal:
tempRoom = new RoomPortal(gameMap);
- is >> tempRoom;
break;
case dungeonTemple:
tempRoom = new RoomDungeonTemple(gameMap);
- is >> tempRoom;
break;
case forge:
tempRoom = new RoomForge(gameMap);
- is >> tempRoom;
break;
case trainingHall:
tempRoom = new RoomTrainingHall(gameMap);
- is >> tempRoom;
break;
case library:
tempRoom = new RoomLibrary(gameMap);
- is >> tempRoom;
break;
case hatchery:
tempRoom = new RoomHatchery(gameMap);
- is >> tempRoom;
break;
default:
OD_ASSERT_TRUE_MSG(false, "Unknown enum value : " + Ogre::StringConverter::toString(
static_cast(nType)));
}
- return tempRoom;
-}
-
-void Room::exportToPacket(ODPacket& packet)
-{
- packet << this;
-}
+ if(tempRoom == nullptr)
+ return nullptr;
-void Room::exportToStream(std::ostream& os)
-{
- os << this;
-}
+ tempRoom->importFromPacket(is);
-std::istream& operator>>(std::istream& is, Room* room)
-{
- int tilesToLoad, tempX, tempY;
- int tempInt = 0;
- is >> tempInt;
- Seat* seat = room->getGameMap()->getSeatById(tempInt);
- OD_ASSERT_TRUE_MSG(seat != NULL, "seatId=" + Ogre::StringConverter::toString(tempInt));
- room->setSeat(seat);
-
- is >> tilesToLoad;
- for (int i = 0; i < tilesToLoad; ++i)
- {
- is >> tempX >> tempY;
- Tile* tempTile = room->getGameMap()->getTile(tempX, tempY);
- if (tempTile != NULL)
- room->addCoveredTile(tempTile, Room::DEFAULT_TILE_HP, false);
- }
-
- return is;
-}
-
-std::ostream& operator<<(std::ostream& os, Room *room)
-{
- int seatId = room->getSeat()->getId();
- int nbTiles = room->mCoveredTiles.size();
- os << seatId << "\t" << nbTiles << "\n";
- for (std::vector::iterator it = room->mCoveredTiles.begin(); it != room->mCoveredTiles.end(); ++it)
- {
- Tile *tempTile = *it;
- os << tempTile->x << "\t" << tempTile->y << "\n";
- }
-
- return os;
-}
-
-ODPacket& operator>>(ODPacket& is, Room* room)
-{
- std::string name;
- int tilesToLoad, tempX, tempY;
- is >> name;
- room->setName(name);
- int tempInt = 0;
- is >> tempInt;
- Seat* seat = room->getGameMap()->getSeatById(tempInt);
- OD_ASSERT_TRUE_MSG(seat != NULL, "seatId=" + Ogre::StringConverter::toString(tempInt));
- room->setSeat(seat);
-
- is >> tilesToLoad;
- for (int i = 0; i < tilesToLoad; ++i)
- {
- is >> tempX >> tempY;
- Tile* tempTile = room->getGameMap()->getTile(tempX, tempY);
- if (tempTile != NULL)
- room->addCoveredTile(tempTile, Room::DEFAULT_TILE_HP, false);
- }
-
- return is;
-}
-
-ODPacket& operator<<(ODPacket& os, Room *room)
-{
- const std::string& name = room->getName();
- int seatId = room->getSeat()->getId();
- int nbTiles = room->mCoveredTiles.size();
- os << name << seatId << nbTiles;
- for (std::vector::iterator it = room->mCoveredTiles.begin(); it != room->mCoveredTiles.end(); ++it)
- {
- Tile* tempTile = *it;
- os << tempTile->x << tempTile->y;
- }
-
- return os;
+ return tempRoom;
}
const char* Room::getRoomNameFromRoomType(RoomType t)
@@ -850,6 +760,84 @@ void Room::notifyActiveSpotRemoved(ActiveSpotPlace place, Tile* tile)
removeBuildingObject(tile);
}
+void Room::exportHeadersToStream(std::ostream& os)
+{
+ os << getType() << "\t";
+}
+
+void Room::exportHeadersToPacket(ODPacket& os)
+{
+ os << getType();
+}
+
+void Room::exportToPacket(ODPacket& os)
+{
+ const std::string& name = getName();
+ int seatId = getSeat()->getId();
+ int nbTiles = mCoveredTiles.size();
+ os << name << seatId << nbTiles;
+ for (std::vector::iterator it = mCoveredTiles.begin(); it != mCoveredTiles.end(); ++it)
+ {
+ Tile* tempTile = *it;
+ os << tempTile->x << tempTile->y;
+ }
+}
+
+void Room::importFromPacket(ODPacket& is)
+{
+ std::string name;
+ int tilesToLoad, tempX, tempY;
+ OD_ASSERT_TRUE(is >> name);
+ setName(name);
+ int tempInt = 0;
+ OD_ASSERT_TRUE(is >> tempInt);
+ Seat* seat = getGameMap()->getSeatById(tempInt);
+ OD_ASSERT_TRUE_MSG(seat != NULL, "seatId=" + Ogre::StringConverter::toString(tempInt));
+ setSeat(seat);
+
+ OD_ASSERT_TRUE(is >> tilesToLoad);
+ for (int i = 0; i < tilesToLoad; ++i)
+ {
+ OD_ASSERT_TRUE(is >> tempX >> tempY);
+ Tile* tempTile = getGameMap()->getTile(tempX, tempY);
+ OD_ASSERT_TRUE_MSG(tempTile != NULL, "tile=" + Ogre::StringConverter::toString(tempX) + "," + Ogre::StringConverter::toString(tempY));
+ if (tempTile != NULL)
+ addCoveredTile(tempTile, Room::DEFAULT_TILE_HP, false);
+ }
+}
+
+void Room::exportToStream(std::ostream& os)
+{
+ int seatId = getSeat()->getId();
+ int nbTiles = mCoveredTiles.size();
+ os << seatId << "\t" << nbTiles << "\n";
+ for (std::vector::iterator it = mCoveredTiles.begin(); it != mCoveredTiles.end(); ++it)
+ {
+ Tile *tempTile = *it;
+ os << tempTile->x << "\t" << tempTile->y << "\n";
+ }
+}
+
+void Room::importFromStream(std::istream& is)
+{
+ int tilesToLoad, tempX, tempY;
+ int tempInt = 0;
+ OD_ASSERT_TRUE(is >> tempInt);
+ Seat* seat = getGameMap()->getSeatById(tempInt);
+ OD_ASSERT_TRUE_MSG(seat != NULL, "seatId=" + Ogre::StringConverter::toString(tempInt));
+ setSeat(seat);
+
+ OD_ASSERT_TRUE(is >> tilesToLoad);
+ for (int i = 0; i < tilesToLoad; ++i)
+ {
+ OD_ASSERT_TRUE(is >> tempX >> tempY);
+ Tile* tempTile = getGameMap()->getTile(tempX, tempY);
+ OD_ASSERT_TRUE_MSG(tempTile != NULL, "tile=" + Ogre::StringConverter::toString(tempX) + "," + Ogre::StringConverter::toString(tempY));
+ if (tempTile != NULL)
+ addCoveredTile(tempTile, Room::DEFAULT_TILE_HP, false);
+ }
+}
+
bool Room::sortForMapSave(Room* r1, Room* r2)
{
// We sort room by seat id then meshName
diff --git a/source/Room.h b/source/Room.h
index 86c6b31f9..72eb280e8 100644
--- a/source/Room.h
+++ b/source/Room.h
@@ -57,16 +57,20 @@ class Room : public Building
virtual void absorbRoom(Room* r);
static std::string getFormat();
- friend std::ostream& operator<<(std::ostream& os, Room *room);
- friend std::istream& operator>>(std::istream& is, Room *room);
- friend ODPacket& operator<<(ODPacket& os, Room *room);
- friend ODPacket& operator>>(ODPacket& is, Room *room);
static Room* getRoomFromStream(GameMap* gameMap, std::istream& is);
static Room* getRoomFromPacket(GameMap* gameMap, ODPacket& is);
+ /*! \brief Exports the headers needed to recreate the Room. It allows to extend Room as much as wanted.
+ * The content of the Room will be exported by exportToPacket.
+ */
+ virtual void exportHeadersToStream(std::ostream& os);
+ virtual void exportHeadersToPacket(ODPacket& os);
+ //! \brief Exports the data of the RenderedMovableEntity
virtual void exportToStream(std::ostream& os);
- virtual void exportToPacket(ODPacket& packet);
+ virtual void importFromStream(std::istream& is);
+ virtual void exportToPacket(ODPacket& os);
+ virtual void importFromPacket(ODPacket& is);
void createBuildingObjectMeshes();
void destroyBuildingObjectMeshes();
diff --git a/source/ServerNotification.cpp b/source/ServerNotification.cpp
index 90dda17a9..98781918c 100644
--- a/source/ServerNotification.cpp
+++ b/source/ServerNotification.cpp
@@ -98,10 +98,6 @@ std::string ServerNotification::typeString(ServerNotificationType type)
return "tileClaimed";
case ServerNotificationType::refreshPlayerSeat:
return "refreshPlayerSeat";
- case ServerNotificationType::addMissileObject:
- return "addMissileObject";
- case ServerNotificationType::removeMissileObject:
- return "removeMissileObject";
case ServerNotificationType::addRenderedMovableEntity:
return "addRenderedMovableEntity";
case ServerNotificationType::removeRenderedMovableEntity:
diff --git a/source/ServerNotification.h b/source/ServerNotification.h
index d75d66264..e2c448ba8 100644
--- a/source/ServerNotification.h
+++ b/source/ServerNotification.h
@@ -79,8 +79,6 @@ class ServerNotification
creatureRefresh,
tileClaimed,
refreshPlayerSeat,
- addMissileObject,
- removeMissileObject,
addRenderedMovableEntity,
removeRenderedMovableEntity,
depositGoldSound, // Makes the client play a deposit gold sound at tile coordinates.
diff --git a/source/Tile.cpp b/source/Tile.cpp
index 695e727db..96101a4f5 100644
--- a/source/Tile.cpp
+++ b/source/Tile.cpp
@@ -1290,7 +1290,7 @@ int Tile::getFloodFill(FloodFillType type)
return mFloodFillColor[type];
}
-void Tile::fillAttackableObjects(std::vector& entities, Seat* seat, bool invert)
+void Tile::fillAttackableCreatures(std::vector& entities, Seat* seat, bool invert)
{
for(std::vector::iterator it = creaturesInCell.begin(); it != creaturesInCell.end(); ++it)
{
@@ -1305,10 +1305,14 @@ void Tile::fillAttackableObjects(std::vector& entities, Seat* seat,
&& creature->getSeat()->isAlliedSeat(seat)))
{
// Add the current creature
- entities.push_back(creature);
+ if (std::find(entities.begin(), entities.end(), creature) == entities.end())
+ entities.push_back(creature);
}
}
+}
+void Tile::fillAttackableRoom(std::vector& entities, Seat* seat, bool invert)
+{
Room *room = getCoveringRoom();
if((room != NULL) && room->isAttackable())
{
@@ -1320,7 +1324,10 @@ void Tile::fillAttackableObjects(std::vector& entities, Seat* seat,
entities.push_back(room);
}
}
+}
+void Tile::fillAttackableTrap(std::vector& entities, Seat* seat, bool invert)
+{
Trap *trap = getCoveringTrap();
if((trap != NULL) && trap->isAttackable())
{
diff --git a/source/Tile.h b/source/Tile.h
index 1573a398a..54cb7cb16 100644
--- a/source/Tile.h
+++ b/source/Tile.h
@@ -291,10 +291,13 @@ friend class ODServer;
std::vector getCoveredTiles() { return std::vector() ;}
void refreshFromTile(const Tile& tile);
- //! \brief Fills entities with all the attackable entities in the Tile. If invert is true,
+ //! \brief Fills entities with all the attackable creatures in the Tile. If invert is true,
//! the list will be filled with the ennemies with the given seat. If invert is false, it will be filled
- //! with allies with the given seat.
- void fillAttackableObjects(std::vector& entities, Seat* seat, bool invert);
+ //! with allies with the given seat. For all theses functions, the list is checked to be sure
+ //! no entity is added twice
+ void fillAttackableCreatures(std::vector& entities, Seat* seat, bool invert);
+ void fillAttackableRoom(std::vector& entities, Seat* seat, bool invert);
+ void fillAttackableTrap(std::vector& entities, Seat* seat, bool invert);
bool addChickenEntity(ChickenEntity* chicken);
bool removeChickenEntity(ChickenEntity* chicken);
diff --git a/source/Trap.cpp b/source/Trap.cpp
index 4a885e335..bfbf34f9f 100644
--- a/source/Trap.cpp
+++ b/source/Trap.cpp
@@ -101,12 +101,10 @@ Trap* Trap::getTrapFromStream(GameMap* gameMap, std::istream &is)
tempTrap = nullptr;
break;
case cannon:
- tempTrap = new TrapCannon(gameMap);
- is >> tempTrap;
+ tempTrap = TrapCannon::getTrapCannonFromStream(gameMap, is);
break;
case spike:
- tempTrap = new TrapSpike(gameMap);
- is >> tempTrap;
+ tempTrap = TrapSpike::getTrapSpikeFromStream(gameMap, is);
break;
case boulder:
tempTrap = TrapBoulder::getTrapBoulderFromStream(gameMap, is);
@@ -116,6 +114,11 @@ Trap* Trap::getTrapFromStream(GameMap* gameMap, std::istream &is)
static_cast(nType)));
}
+ if(tempTrap == nullptr)
+ return nullptr;
+
+ tempTrap->importFromStream(is);
+
return tempTrap;
}
@@ -131,12 +134,10 @@ Trap* Trap::getTrapFromPacket(GameMap* gameMap, ODPacket &is)
tempTrap = nullptr;
break;
case cannon:
- tempTrap = new TrapCannon(gameMap);
- is >> tempTrap;
+ tempTrap = TrapCannon::getTrapCannonFromPacket(gameMap, is);
break;
case spike:
- tempTrap = new TrapSpike(gameMap);
- is >> tempTrap;
+ tempTrap = TrapSpike::getTrapSpikeFromPacket(gameMap, is);
break;
case boulder:
tempTrap = TrapBoulder::getTrapBoulderFromPacket(gameMap, is);
@@ -146,17 +147,12 @@ Trap* Trap::getTrapFromPacket(GameMap* gameMap, ODPacket &is)
static_cast(nType)));
}
- return tempTrap;
-}
+ if(tempTrap == nullptr)
+ return nullptr;
-void Trap::exportToPacket(ODPacket& packet)
-{
- packet << this;
-}
+ tempTrap->importFromPacket(is);
-void Trap::exportToStream(std::ostream& os)
-{
- os << this;
+ return tempTrap;
}
const char* Trap::getTrapNameFromTrapType(TrapType t)
@@ -359,84 +355,85 @@ std::string Trap::getFormat()
return "typeTrap\tseatId\tnumTiles\t\tSubsequent Lines: tileX\ttileY\t\tSubsequent Lines: optional specific data";
}
-std::istream& operator>>(std::istream& is, Trap *t)
+void Trap::exportHeadersToStream(std::ostream& os)
+{
+ os << getType() << "\t";
+}
+
+void Trap::exportHeadersToPacket(ODPacket& os)
+{
+ os << getType();
+}
+
+void Trap::exportToPacket(ODPacket& os)
+{
+ int nbTiles = mCoveredTiles.size();
+ const std::string& name = getName();
+ int seatId = getSeat()->getId();
+ os << name << seatId;
+ os << nbTiles;
+ for(std::vector::iterator it = mCoveredTiles.begin(); it != mCoveredTiles.end(); ++it)
+ {
+ Tile *tempTile = *it;
+ os << tempTile->x << tempTile->y;
+ }
+}
+
+void Trap::importFromPacket(ODPacket& is)
{
int tilesToLoad, tempX, tempY, tempInt;
+ std::string name;
+ OD_ASSERT_TRUE(is >> name);
+ setName(name);
- is >> tempInt;
- t->setSeat(t->getGameMap()->getSeatById(tempInt));
+ OD_ASSERT_TRUE(is >> tempInt);
+ setSeat(getGameMap()->getSeatById(tempInt));
- is >> tilesToLoad;
+ OD_ASSERT_TRUE(is >> tilesToLoad);
for (int i = 0; i < tilesToLoad; ++i)
{
- is >> tempX >> tempY;
- Tile *tempTile = t->getGameMap()->getTile(tempX, tempY);
+ OD_ASSERT_TRUE(is >> tempX >> tempY);
+ Tile *tempTile = getGameMap()->getTile(tempX, tempY);
+ OD_ASSERT_TRUE_MSG(tempTile != NULL, "tile=" + Ogre::StringConverter::toString(tempX) + "," + Ogre::StringConverter::toString(tempY));
if (tempTile != NULL)
{
- t->addCoveredTile(tempTile, Trap::DEFAULT_TILE_HP);
- tempTile->setSeat(t->getSeat());
+ addCoveredTile(tempTile, Trap::DEFAULT_TILE_HP);
+ tempTile->setSeat(getSeat());
}
}
- return is;
}
-std::ostream& operator<<(std::ostream& os, Trap *t)
+void Trap::exportToStream(std::ostream& os)
{
- int32_t nbTiles = t->mCoveredTiles.size();
- int seatId = t->getSeat()->getId();
+ int32_t nbTiles = mCoveredTiles.size();
+ int seatId = getSeat()->getId();
os << seatId << "\t" << nbTiles << "\n";
- for(std::vector::iterator it = t->mCoveredTiles.begin(); it != t->mCoveredTiles.end(); ++it)
+ for(std::vector::iterator it = mCoveredTiles.begin(); it != mCoveredTiles.end(); ++it)
{
Tile *tempTile = *it;
os << tempTile->x << "\t" << tempTile->y << "\n";
}
-
- return os;
}
-ODPacket& operator>>(ODPacket& is, Trap *t)
+void Trap::importFromStream(std::istream& is)
{
int tilesToLoad, tempX, tempY, tempInt;
- std::string name;
- is >> name;
- t->setName(name);
- is >> tempInt;
- t->setSeat(t->getGameMap()->getSeatById(tempInt));
+ OD_ASSERT_TRUE(is >> tempInt);
+ setSeat(getGameMap()->getSeatById(tempInt));
- is >> tilesToLoad;
+ OD_ASSERT_TRUE(is >> tilesToLoad);
for (int i = 0; i < tilesToLoad; ++i)
{
- is >> tempX >> tempY;
- Tile *tempTile = t->getGameMap()->getTile(tempX, tempY);
+ OD_ASSERT_TRUE(is >> tempX >> tempY);
+ Tile *tempTile = getGameMap()->getTile(tempX, tempY);
+ OD_ASSERT_TRUE_MSG(tempTile != NULL, "tile=" + Ogre::StringConverter::toString(tempX) + "," + Ogre::StringConverter::toString(tempY));
if (tempTile != NULL)
{
- t->addCoveredTile(tempTile, Trap::DEFAULT_TILE_HP);
- tempTile->setSeat(t->getSeat());
- }
- else
- {
- LogManager::getSingleton().logMessage("ERROR : trying to add trap on unkown tile "
- + Ogre::StringConverter::toString(tempX) + "," + Ogre::StringConverter::toString(tempY));
+ addCoveredTile(tempTile, Trap::DEFAULT_TILE_HP);
+ tempTile->setSeat(getSeat());
}
}
- return is;
-}
-
-ODPacket& operator<<(ODPacket& os, Trap *t)
-{
- int nbTiles = t->mCoveredTiles.size();
- const std::string& name = t->getName();
- int seatId = t->getSeat()->getId();
- os << name << seatId;
- os << nbTiles;
- for(std::vector::iterator it = t->mCoveredTiles.begin(); it != t->mCoveredTiles.end(); ++it)
- {
- Tile *tempTile = *it;
- os << tempTile->x << tempTile->y;
- }
-
- return os;
}
std::istream& operator>>(std::istream& is, Trap::TrapType& tt)
diff --git a/source/Trap.h b/source/Trap.h
index 236f11061..c5c5818d6 100644
--- a/source/Trap.h
+++ b/source/Trap.h
@@ -56,9 +56,6 @@ class Trap : public Building
static Trap* getTrapFromStream(GameMap* gameMap, std::istream &is);
static Trap* getTrapFromPacket(GameMap* gameMap, ODPacket &is);
- virtual void exportToStream(std::ostream& os);
- virtual void exportToPacket(ODPacket& packet);
-
virtual const TrapType getType() const = 0;
static const char* getTrapNameFromTrapType(TrapType t);
@@ -80,11 +77,18 @@ class Trap : public Building
virtual bool removeCoveredTile(Tile* t);
virtual void updateActiveSpots();
+ /*! \brief Exports the headers needed to recreate the Trap. It allows to extend Traps as much as wanted.
+ * The content of the Trap will be exported by exportToPacket.
+ */
+ virtual void exportHeadersToStream(std::ostream& os);
+ virtual void exportHeadersToPacket(ODPacket& os);
+ //! \brief Exports the data of the RenderedMovableEntity
+ virtual void exportToStream(std::ostream& os);
+ virtual void importFromStream(std::istream& is);
+ virtual void exportToPacket(ODPacket& os);
+ virtual void importFromPacket(ODPacket& is);
+
static std::string getFormat();
- friend std::istream& operator>>(std::istream& is, Trap *t);
- friend std::ostream& operator<<(std::ostream& os, Trap *t);
- friend ODPacket& operator>>(ODPacket& is, Trap *t);
- friend ODPacket& operator<<(ODPacket& os, Trap *t);
friend std::istream& operator>>(std::istream& is, Trap::TrapType& tt);
friend std::ostream& operator<<(std::ostream& os, const Trap::TrapType& tt);
friend ODPacket& operator>>(ODPacket& is, Trap::TrapType& tt);
diff --git a/source/TrapBoulder.cpp b/source/TrapBoulder.cpp
index b29ee72f6..4895cd257 100644
--- a/source/TrapBoulder.cpp
+++ b/source/TrapBoulder.cpp
@@ -18,122 +18,74 @@
#include "TrapBoulder.h"
#include "ODPacket.h"
#include "GameMap.h"
+#include "Random.h"
+#include "MissileBoulder.h"
#include "LogManager.h"
-TrapBoulder::TrapBoulder(GameMap* gameMap, int x, int y) :
- DirectionalTrap(gameMap, x, y)
-{
- mReloadTime = 20;
- mMinDamage = 30;
- mMaxDamage = 40;
- setMeshName("Boulder");
-}
-
TrapBoulder::TrapBoulder(GameMap* gameMap) :
- DirectionalTrap(gameMap)
+ Trap(gameMap)
{
- mReloadTime = 20;
- mMinDamage = 30;
- mMaxDamage = 40;
+ mReloadTime = 100;
+ mMinDamage = 100;
+ mMaxDamage = 120;
setMeshName("Boulder");
}
-TrapBoulder* TrapBoulder::getTrapBoulderFromStream(GameMap* gameMap, std::istream& is)
+TrapBoulder* TrapBoulder::getTrapBoulderFromStream(GameMap* gameMap, std::istream &is)
{
TrapBoulder* trap = new TrapBoulder(gameMap);
- is >> trap;
return trap;
}
-TrapBoulder* TrapBoulder::getTrapBoulderFromPacket(GameMap* gameMap, ODPacket& is)
+TrapBoulder* TrapBoulder::getTrapBoulderFromPacket(GameMap* gameMap, ODPacket &is)
{
TrapBoulder* trap = new TrapBoulder(gameMap);
- is >> trap;
return trap;
}
-std::istream& operator>>(std::istream& is, TrapBoulder *trap)
+bool TrapBoulder::shoot(Tile* tile)
{
- int tilesToLoad, tempX, tempY, tempInt;
-
- is >> tempInt;
- trap->setSeat(trap->getGameMap()->getSeatById(tempInt));
-
- is >> tilesToLoad;
- for (int i = 0; i < tilesToLoad; ++i)
+ std::vector tiles = tile->getAllNeighbors();
+ for(std::vector::iterator it = tiles.begin(); it != tiles.end();)
{
- is >> tempX >> tempY;
- Tile *tempTile = trap->getGameMap()->getTile(tempX, tempY);
- if (tempTile != NULL)
- {
- trap->addCoveredTile(tempTile, Trap::DEFAULT_TILE_HP);
- tempTile->setSeat(trap->getSeat());
- }
- }
- is >> tempX >> tempY;
- trap->mDir = std::pair(tempX, tempY);
-
- return is;
-}
+ Tile* tmpTile = *it;
+ std::vector vecTile;
+ vecTile.push_back(tmpTile);
-std::ostream& operator<<(std::ostream& os, TrapBoulder *trap)
-{
- int32_t nbTiles = trap->mCoveredTiles.size();
- int seatId = trap->getSeat()->getId();
- os << seatId << "\t" << nbTiles << "\n";
- for(std::vector::iterator it = trap->mCoveredTiles.begin(); it != trap->mCoveredTiles.end(); ++it)
- {
- Tile *tempTile = *it;
- os << tempTile->x << "\t" << tempTile->y << "\n";
+ if(getGameMap()->getVisibleCreatures(vecTile, getSeat(), true).empty())
+ it = tiles.erase(it);
+ else
+ ++it;
}
- os << trap->mDir.first << "\t" << trap->mDir.second << "\n";
- return os;
-}
+ if(tiles.empty())
+ return false;
-ODPacket& operator>>(ODPacket& is, TrapBoulder *trap)
-{
- int tilesToLoad, tempX, tempY, tempInt;
- std::string name;
- is >> name;
- trap->setName(name);
+ // We take a random tile and launch boulder it
+ Tile* tileChoosen = tiles[Random::Uint(0, tiles.size() - 1)];
+ // We launch the boulder
+ Ogre::Vector3 direction(static_cast(tileChoosen->getX() - tile->getX()),
+ static_cast(tileChoosen->getY() - tile->getY()),
+ 0);
+ Ogre::Vector3 position;
+ position.x = static_cast(tile->getX());
+ position.y = static_cast(tile->getY());
+ position.z = 0;
+ direction.normalise();
+ MissileBoulder* missile = new MissileBoulder(getGameMap(), getSeat(), getName(), "Boulder",
+ direction, Random::Double(mMinDamage, mMaxDamage));
+ missile->setPosition(position);
+ getGameMap()->addRenderedMovableEntity(missile);
+ missile->setMoveSpeed(1.0);
+ missile->createMesh();
+ // We don't want the missile to stay idle for 1 turn. Because we are in a doUpkeep context,
+ // we can safely call the missile doUpkeep as we know the engine will not call it the turn
+ // it has been added
+ missile->doUpkeep();
- is >> tempInt;
- trap->setSeat(trap->getGameMap()->getSeatById(tempInt));
-
- is >> tilesToLoad;
- for (int i = 0; i < tilesToLoad; ++i)
- {
- is >> tempX >> tempY;
- Tile *tempTile = trap->getGameMap()->getTile(tempX, tempY);
- if (tempTile != NULL)
- {
- trap->addCoveredTile(tempTile, Trap::DEFAULT_TILE_HP);
- tempTile->setSeat(trap->getSeat());
- }
- else
- {
- LogManager::getSingleton().logMessage("ERROR : trying to add trap on unkown tile "
- + Ogre::StringConverter::toString(tempX) + "," + Ogre::StringConverter::toString(tempY));
- }
- }
- is >> tempX >> tempY;
- trap->mDir = std::pair(tempX, tempY);
- return is;
+ return true;
}
-ODPacket& operator<<(ODPacket& os, TrapBoulder *trap)
+RenderedMovableEntity* TrapBoulder::notifyActiveSpotCreated(Tile* tile)
{
- int nbTiles = trap->mCoveredTiles.size();
- const std::string& name = trap->getName();
- int seatId = trap->getSeat()->getId();
- os << name << seatId;
- os << nbTiles;
- for(std::vector::iterator it = trap->mCoveredTiles.begin(); it != trap->mCoveredTiles.end(); ++it)
- {
- Tile *tempTile = *it;
- os << tempTile->x << tempTile->y;
- }
- os << trap->mDir.first << trap->mDir.second;
-
- return os;
+ return loadBuildingObject(getGameMap(), "Boulder", tile, 0.0);
}
diff --git a/source/TrapBoulder.h b/source/TrapBoulder.h
index 97fdb7a6b..57d9022df 100644
--- a/source/TrapBoulder.h
+++ b/source/TrapBoulder.h
@@ -18,25 +18,31 @@
#ifndef TRAPBOULDER_H
#define TRAPBOULDER_H
-#include "DirectionalTrap.h"
+#include "Trap.h"
-class TrapBoulder : public DirectionalTrap
+class TrapBoulder : public Trap
{
public:
- TrapBoulder(GameMap* gameMap, int x, int y);
+ TrapBoulder(GameMap* gameMap);
- static TrapBoulder* getTrapBoulderFromStream(GameMap* gameMap, std::istream& is);
- static TrapBoulder* getTrapBoulderFromPacket(GameMap* gameMap, ODPacket& is);
+ static TrapBoulder* getTrapBoulderFromStream(GameMap* gameMap, std::istream &is);
+ static TrapBoulder* getTrapBoulderFromPacket(GameMap* gameMap, ODPacket &is);
virtual const TrapType getType() const
{ return TrapType::boulder; }
- friend std::istream& operator>>(std::istream& is, TrapBoulder *trap);
- friend std::ostream& operator<<(std::ostream& os, TrapBoulder *trap);
- friend ODPacket& operator>>(ODPacket& is, TrapBoulder *trap);
- friend ODPacket& operator<<(ODPacket& os, TrapBoulder *trap);
-private:
- TrapBoulder(GameMap* gameMap);
+ virtual bool shoot(Tile* tile);
+ virtual bool isAttackable() const
+ {
+ return false;
+ }
+
+ virtual bool shouldDisplayMeshOnGround()
+ {
+ return false;
+ }
+
+ virtual RenderedMovableEntity* notifyActiveSpotCreated(Tile* tile);
};
#endif // TRAPBOULDER_H
diff --git a/source/TrapCannon.cpp b/source/TrapCannon.cpp
index d3867e128..10f321fa9 100644
--- a/source/TrapCannon.cpp
+++ b/source/TrapCannon.cpp
@@ -19,13 +19,15 @@
#include "ODPacket.h"
#include "Tile.h"
#include "GameMap.h"
-#include "MissileObject.h"
+#include "MissileOneHit.h"
#include "Random.h"
#include "LogManager.h"
+const Ogre::Real CANNON_MISSILE_HEIGHT = 0.3;
+const Ogre::Real CANNON_MISSILE_SPEED = 5;
+
TrapCannon::TrapCannon(GameMap* gameMap) :
- ProximityTrap(gameMap),
- mCannonHeight(1.5)
+ ProximityTrap(gameMap)
{
mReloadTime = 5;
mRange = 10;
@@ -37,7 +39,7 @@ TrapCannon::TrapCannon(GameMap* gameMap) :
bool TrapCannon::shoot(Tile* tile)
{
std::vector visibleTiles = getGameMap()->visibleTiles(tile, mRange);
- std::vector enemyObjects = getGameMap()->getVisibleForce(visibleTiles, getSeat(), true);
+ std::vector enemyObjects = getGameMap()->getVisibleCreatures(visibleTiles, getSeat(), true);
if(enemyObjects.empty())
return false;
@@ -45,22 +47,27 @@ bool TrapCannon::shoot(Tile* tile)
// Select an enemy to shoot at.
GameEntity* targetEnemy = enemyObjects[Random::Uint(0, enemyObjects.size()-1)];
- // TODO : instead of dealing damages here, add to MissileObject the needed infos to make it damage the
- // target when hit (to allow pickup before getting hurt or dodging)
- targetEnemy->takeDamage(this, Random::Double(mMinDamage, mMaxDamage), targetEnemy->getCoveredTiles()[0]);
// Create the cannonball to move toward the enemy creature.
- MissileObject *tempMissileObject = new MissileObject(getGameMap(),
- "Cannonball", Ogre::Vector3((Ogre::Real)tile->x, (Ogre::Real)tile->y,
- (Ogre::Real)mCannonHeight));
+ Ogre::Vector3 direction(static_cast(targetEnemy->getCoveredTiles()[0]->x),
+ static_cast(targetEnemy->getCoveredTiles()[0]->y),
+ CANNON_MISSILE_HEIGHT);
- //TODO: Make this a pseudo newtonian mechanics solver which computes a parabola passing through the cannon
- // and the enemy it is shooting at, add this as 10 or so destinations in the queue instead of just one.
- getGameMap()->addMissileObject(tempMissileObject);
- tempMissileObject->setMoveSpeed(8.0);
- tempMissileObject->createMesh();
- tempMissileObject->addDestination((Ogre::Real)targetEnemy->getCoveredTiles()[0]->x,
- (Ogre::Real)targetEnemy->getCoveredTiles()[0]->y,
- (Ogre::Real)mCannonHeight);
+ Ogre::Vector3 position;
+ position.x = static_cast(tile->x);
+ position.y = static_cast(tile->y);
+ position.z = CANNON_MISSILE_HEIGHT;
+ direction = direction - position;
+ direction.normalise();
+ MissileOneHit* missile = new MissileOneHit(getGameMap(), getSeat(), getName(), "Cannonball",
+ direction, Random::Double(mMinDamage, mMaxDamage), false);
+ missile->setPosition(position);
+ getGameMap()->addRenderedMovableEntity(missile);
+ missile->setMoveSpeed(CANNON_MISSILE_SPEED);
+ missile->createMesh();
+ // We don't want the missile to stay idle for 1 turn. Because we are in a doUpkeep context,
+ // we can safely call the missile doUpkeep as we know the engine will not call it the turn
+ // it has been added
+ missile->doUpkeep();
return true;
}
@@ -68,3 +75,15 @@ RenderedMovableEntity* TrapCannon::notifyActiveSpotCreated(Tile* tile)
{
return loadBuildingObject(getGameMap(), "Cannon", tile, 90.0);
}
+
+TrapCannon* TrapCannon::getTrapCannonFromStream(GameMap* gameMap, std::istream &is)
+{
+ TrapCannon* trap = new TrapCannon(gameMap);
+ return trap;
+}
+
+TrapCannon* TrapCannon::getTrapCannonFromPacket(GameMap* gameMap, ODPacket &is)
+{
+ TrapCannon* trap = new TrapCannon(gameMap);
+ return trap;
+}
diff --git a/source/TrapCannon.h b/source/TrapCannon.h
index 544c3ef3a..f3dfe2625 100644
--- a/source/TrapCannon.h
+++ b/source/TrapCannon.h
@@ -27,6 +27,9 @@ class TrapCannon : public ProximityTrap
public:
TrapCannon(GameMap* gameMap);
+ static TrapCannon* getTrapCannonFromStream(GameMap* gameMap, std::istream &is);
+ static TrapCannon* getTrapCannonFromPacket(GameMap* gameMap, ODPacket &is);
+
virtual const TrapType getType() const
{ return TrapType::cannon; }
@@ -36,11 +39,6 @@ class TrapCannon : public ProximityTrap
return false;
}
virtual RenderedMovableEntity* notifyActiveSpotCreated(Tile* tile);
-
- static TrapCannon* getTrapCannonFromPacket(GameMap* gameMap, ODPacket& packet);
-
-private:
- double mCannonHeight;
};
#endif // TRAPCANNON_H
diff --git a/source/TrapSpike.cpp b/source/TrapSpike.cpp
index e8027aa8f..118c14e38 100644
--- a/source/TrapSpike.cpp
+++ b/source/TrapSpike.cpp
@@ -19,7 +19,6 @@
#include "Tile.h"
#include "GameMap.h"
-#include "MissileObject.h"
#include "Random.h"
#include "RenderedMovableEntity.h"
#include "LogManager.h"
@@ -38,36 +37,41 @@ bool TrapSpike::shoot(Tile* tile)
{
std::vector visibleTiles;
visibleTiles.push_back(tile);
- std::vector enemyObjects = getGameMap()->getVisibleForce(visibleTiles, getSeat(), true);
- if(enemyObjects.empty())
+ std::vector enemyCreatures = getGameMap()->getVisibleCreatures(visibleTiles, getSeat(), true);
+ if(enemyCreatures.empty())
return false;
RenderedMovableEntity* spike = getBuildingObjectFromTile(tile);
spike->setAnimationState("Triggered", false);
// We damage every creature standing on the trap
- for(std::vector::iterator it = enemyObjects.begin(); it != enemyObjects.end(); ++it)
+ for(std::vector::iterator it = enemyCreatures.begin(); it != enemyCreatures.end(); ++it)
{
GameEntity* target = *it;
- if(target->getObjectType() != GameEntity::ObjectType::creature)
- continue;
-
target->takeDamage(this, Random::Double(mMinDamage, mMaxDamage), target->getCoveredTiles()[0]);
}
- std::vector alliedObjects = getGameMap()->getVisibleForce(visibleTiles, getSeat(), false);
- for(std::vector::iterator it = alliedObjects.begin(); it != alliedObjects.end(); ++it)
+ std::vector alliedCreatures = getGameMap()->getVisibleCreatures(visibleTiles, getSeat(), false);
+ for(std::vector::iterator it = alliedCreatures.begin(); it != alliedCreatures.end(); ++it)
{
GameEntity* target = *it;
- if(target->getObjectType() != GameEntity::ObjectType::creature)
- continue;
-
target->takeDamage(this, Random::Double(mMinDamage, mMaxDamage), target->getCoveredTiles()[0]);
}
return true;
}
-
RenderedMovableEntity* TrapSpike::notifyActiveSpotCreated(Tile* tile)
{
return loadBuildingObject(getGameMap(), "Spiketrap", tile, 0.0);
}
+
+TrapSpike* TrapSpike::getTrapSpikeFromStream(GameMap* gameMap, std::istream &is)
+{
+ TrapSpike* trap = new TrapSpike(gameMap);
+ return trap;
+}
+
+TrapSpike* TrapSpike::getTrapSpikeFromPacket(GameMap* gameMap, ODPacket &is)
+{
+ TrapSpike* trap = new TrapSpike(gameMap);
+ return trap;
+}
diff --git a/source/TrapSpike.h b/source/TrapSpike.h
index 7a801f63a..a29c5b1a3 100644
--- a/source/TrapSpike.h
+++ b/source/TrapSpike.h
@@ -25,6 +25,9 @@ class TrapSpike : public ProximityTrap
public:
TrapSpike(GameMap* gameMap);
+ static TrapSpike* getTrapSpikeFromStream(GameMap* gameMap, std::istream &is);
+ static TrapSpike* getTrapSpikeFromPacket(GameMap* gameMap, ODPacket &is);
+
virtual const TrapType getType() const
{ return TrapType::spike; }
diff --git a/source/TreasuryObject.cpp b/source/TreasuryObject.cpp
index 07887d10a..2667ed705 100644
--- a/source/TreasuryObject.cpp
+++ b/source/TreasuryObject.cpp
@@ -54,7 +54,7 @@ void TreasuryObject::doUpkeep()
// We check if we are on a tile where there is a treasury room. If so, we add gold there
Tile* tile = getPositionTile();
- OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(tile));
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "entityName=" + getName());
if(tile == nullptr)
return;
@@ -93,8 +93,8 @@ bool TreasuryObject::tryPickup(Seat* seat, bool isEditorMode)
return false;
Tile* tile = getPositionTile();
- OD_ASSERT_TRUE_MSG(tile != NULL, "tile=" + Tile::displayAsString(tile));
- if(tile == NULL)
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "entityName=" + getName());
+ if(tile == nullptr)
return false;
if(!tile->isClaimedForSeat(seat) && !isEditorMode)
@@ -107,7 +107,7 @@ void TreasuryObject::pickup()
{
Tile* tile = getPositionTile();
RenderedMovableEntity::pickup();
- OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(tile));
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "entityName=" + getName());
if(tile == nullptr)
return;
@@ -134,7 +134,7 @@ void TreasuryObject::setPosition(const Ogre::Vector3& v)
{
RenderedMovableEntity::setPosition(v);
Tile* tile = getPositionTile();
- OD_ASSERT_TRUE_MSG(tile != nullptr, "tile=" + Tile::displayAsString(tile));
+ OD_ASSERT_TRUE_MSG(tile != nullptr, "entityName=" + getName());
if(tile == nullptr)
return;
@@ -151,56 +151,35 @@ const char* TreasuryObject::getFormat()
TreasuryObject* TreasuryObject::getTreasuryObjectFromStream(GameMap* gameMap, std::istream& is)
{
TreasuryObject* obj = new TreasuryObject(gameMap);
- Ogre::Vector3 position;
- Ogre::Real x, y, z;
- OD_ASSERT_TRUE(is >> x >> y >> z);
- obj->setPosition(Ogre::Vector3(x, y, z));
- OD_ASSERT_TRUE(is >> obj->mGoldValue);
return obj;
-
}
-TreasuryObject* TreasuryObject::getTreasuryObjectFromPacket(GameMap* gameMap, ODPacket& packet)
+TreasuryObject* TreasuryObject::getTreasuryObjectFromPacket(GameMap* gameMap, ODPacket& is)
{
TreasuryObject* obj = new TreasuryObject(gameMap);
- OD_ASSERT_TRUE(packet >> obj);
return obj;
}
-void TreasuryObject::exportToPacket(ODPacket& packet)
+void TreasuryObject::exportToPacket(ODPacket& os)
{
- packet << this;
+ RenderedMovableEntity::exportToPacket(os);
+ os << mGoldValue;
}
-std::ostream& operator<<(std::ostream& os, TreasuryObject* obj)
+void TreasuryObject::importFromPacket(ODPacket& is)
{
- std::string name = obj->getName();
- Ogre::Vector3 position = obj->getPosition();
- os << name;
- os << position.x;
- os << position.y;
- os << position.z;
- os << obj->mGoldValue;
- return os;
+ RenderedMovableEntity::importFromPacket(is);
+ OD_ASSERT_TRUE(is >> mGoldValue);
}
-ODPacket& operator>>(ODPacket& is, TreasuryObject* obj)
+void TreasuryObject::exportToStream(std::ostream& os)
{
- std::string name;
- OD_ASSERT_TRUE(is >> name);
- obj->setName(name);
- Ogre::Vector3 position;
- OD_ASSERT_TRUE(is >> position);
- obj->setPosition(position);
- return is;
+ RenderedMovableEntity::exportToStream(os);
+ os << mGoldValue << "\t";
}
-ODPacket& operator<<(ODPacket& os, TreasuryObject* obj)
+void TreasuryObject::importFromStream(std::istream& is)
{
- std::string name = obj->getName();
- std::string meshName = obj->getMeshName();
- Ogre::Vector3 position = obj->getPosition();
- os << name;
- os << position;
- return os;
+ RenderedMovableEntity::importFromStream(is);
+ OD_ASSERT_TRUE(is >> mGoldValue);
}
diff --git a/source/TreasuryObject.h b/source/TreasuryObject.h
index a3922409f..e4cd60b28 100644
--- a/source/TreasuryObject.h
+++ b/source/TreasuryObject.h
@@ -44,16 +44,17 @@ class TreasuryObject: public RenderedMovableEntity
void mergeGold(TreasuryObject* obj);
void addGold(int goldValue);
- virtual void exportToPacket(ODPacket& packet);
+ virtual void exportToStream(std::ostream& os);
+ virtual void importFromStream(std::istream& is);
+ virtual void exportToPacket(ODPacket& os);
+ virtual void importFromPacket(ODPacket& is);
+
virtual void pickup();
virtual void setPosition(const Ogre::Vector3& v);
static const char* getFormat();
static TreasuryObject* getTreasuryObjectFromStream(GameMap* gameMap, std::istream& is);
- static TreasuryObject* getTreasuryObjectFromPacket(GameMap* gameMap, ODPacket& packet);
- friend ODPacket& operator<<(ODPacket& os, TreasuryObject* obj);
- friend ODPacket& operator>>(ODPacket& os, TreasuryObject* obj);
- friend std::ostream& operator<<(std::ostream& os, TreasuryObject* obj);
+ static TreasuryObject* getTreasuryObjectFromPacket(GameMap* gameMap, ODPacket& is);
private:
int mGoldValue;
};