summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2016-08-03 22:10:59 +0300
committerAndrei Karas <akaras@inbox.ru>2016-08-03 22:10:59 +0300
commit6a0345c70155f9ff00e52f8952c1e79f61e0d445 (patch)
tree80d7fc2390c2a0103b10c508c317b5c9b40f2248
parentabeecf1255d28a7870aef9f70dc3353d9b5f4f2d (diff)
downloadmv-6a0345c70155f9ff00e52f8952c1e79f61e0d445.tar.gz
mv-6a0345c70155f9ff00e52f8952c1e79f61e0d445.tar.bz2
mv-6a0345c70155f9ff00e52f8952c1e79f61e0d445.tar.xz
mv-6a0345c70155f9ff00e52f8952c1e79f61e0d445.zip
Add support for elemental db and draw elementals sprites.
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/actormanager.cpp5
-rw-r--r--src/being/being.cpp56
-rw-r--r--src/client.cpp3
-rw-r--r--src/defaults.cpp3
-rw-r--r--src/net/eathena/beingrecv.cpp4
-rw-r--r--src/resources/db/elementaldb.cpp156
-rw-r--r--src/resources/db/elementaldb.h50
9 files changed, 262 insertions, 19 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c173c726a..09d7b0113 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -635,6 +635,8 @@ SET(SRCS
resources/delayedmanager.h
resources/db/deaddb.cpp
resources/db/deaddb.h
+ resources/db/elementaldb.cpp
+ resources/db/elementaldb.h
resources/dye/dye.cpp
resources/dye/dye.h
resources/dye/dyecolor.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 7ec48c7fe..f84508526 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1237,6 +1237,8 @@ manaplus_SOURCES += main.cpp \
resources/db/commandsdb.h \
resources/db/deaddb.cpp \
resources/db/deaddb.h \
+ resources/db/elementaldb.cpp \
+ resources/db/elementaldb.h \
resources/db/emotedb.cpp \
resources/db/emotedb.h \
resources/db/homunculusdb.cpp \
diff --git a/src/actormanager.cpp b/src/actormanager.cpp
index b557f3e36..59bfb9708 100644
--- a/src/actormanager.cpp
+++ b/src/actormanager.cpp
@@ -301,8 +301,11 @@ Being *ActorManager::createBeing(const BeingId id,
beingHandler->requestNameById(id);
}
break;
- case ActorType::SkillUnit:
case ActorType::Elemental:
+ if (beingHandler)
+ beingHandler->requestNameById(id);
+ break;
+ case ActorType::SkillUnit:
break;
default:
case ActorType::FloorItem:
diff --git a/src/being/being.cpp b/src/being/being.cpp
index 35e9356bc..9a4cc2be3 100644
--- a/src/being/being.cpp
+++ b/src/being/being.cpp
@@ -79,6 +79,7 @@
#include "resources/db/avatardb.h"
#include "resources/db/badgesdb.h"
+#include "resources/db/elementaldb.h"
#include "resources/db/emotedb.h"
#include "resources/db/homunculusdb.h"
#include "resources/db/horsedb.h"
@@ -270,32 +271,42 @@ Being::Being(const BeingId id,
setMap(map);
setSubtype(subtype, 0);
- if (mType == ActorType::Player
- || mType == ActorType::Mercenary
- || mType == ActorType::Pet
- || mType == ActorType::Homunculus)
- {
- mShowName = config.getBoolValue("visiblenames");
- }
- else if (mType != ActorType::Npc)
- {
- mGotComment = true;
- }
+ bool showName = false;
- if (mType == ActorType::Portal ||
- mType == ActorType::SkillUnit)
+ switch (mType)
{
- mShowName = false;
+ case ActorType::Player:
+ case ActorType::Mercenary:
+ case ActorType::Pet:
+ case ActorType::Homunculus:
+ case ActorType::Elemental:
+ showName = config.getBoolValue("visiblenames");
+ break;
+ case ActorType::Portal:
+ case ActorType::SkillUnit:
+ showName = false;
+ break;
+ default:
+ case ActorType::Unknown:
+ case ActorType::Npc:
+ case ActorType::Monster:
+ case ActorType::FloorItem:
+ case ActorType::LocalPet:
+ case ActorType::Avatar:
+ break;
}
+ if (mType != ActorType::Npc)
+ mGotComment = true;
+
config.addListener("visiblenames", this);
reReadConfig();
if (mType == ActorType::Npc)
setShowName(true);
- else
- setShowName(mShowName);
+ else if (showName)
+ setShowName(showName);
updateColors();
updatePercentHP();
@@ -430,6 +441,18 @@ void Being::setSubtype(const BeingTypeId subtype,
mYDiff = mInfo->getSortOffsetY();
}
break;
+ case ActorType::Elemental:
+ mInfo = ElementalDb::get(mSubType);
+ if (mInfo)
+ {
+ setName(mInfo->getName());
+ setupSpriteDisplay(mInfo->getDisplay(),
+ ForceDisplay_false,
+ 0,
+ mInfo->getColor(fromInt(mLook, ItemColor)));
+ mYDiff = mInfo->getSortOffsetY();
+ }
+ break;
case ActorType::Npc:
mInfo = NPCDB::get(mSubType);
if (mInfo)
@@ -498,7 +521,6 @@ void Being::setSubtype(const BeingTypeId subtype,
break;
case ActorType::Unknown:
case ActorType::FloorItem:
- case ActorType::Elemental:
default:
reportAlways("Wrong being type %d in setSubType",
CAST_S32(mType));
diff --git a/src/client.cpp b/src/client.cpp
index 9cd427ab8..930446140 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -105,6 +105,7 @@
#include "resources/db/chardb.h"
#include "resources/db/colordb.h"
#include "resources/db/deaddb.h"
+#include "resources/db/elementaldb.h"
#include "resources/db/emotedb.h"
#include "resources/db/homunculusdb.h"
#include "resources/db/horsedb.h"
@@ -609,6 +610,7 @@ void Client::gameClear()
{
MercenaryDB::unload();
HomunculusDB::unload();
+ ElementalDb::unload();
SkillUnitDb::unload();
HorseDB::unload();
}
@@ -1336,6 +1338,7 @@ int Client::gameExec()
{
MercenaryDB::load();
HomunculusDB::load();
+ ElementalDb::load();
SkillUnitDb::load();
HorseDB::load();
}
diff --git a/src/defaults.cpp b/src/defaults.cpp
index 3dab5c6d1..8a0a1c103 100644
--- a/src/defaults.cpp
+++ b/src/defaults.cpp
@@ -605,6 +605,9 @@ DefaultsData* getPathsDefaults()
AddDEF("skillUnitsFile", "skillunits.xml");
AddDEF("skillUnitsPatchFile", "skillunits_patch.xml");
AddDEF("skillUnitsPatchDir", "skillunits.d");
+ AddDEF("elementalsFile", "elementals.xml");
+ AddDEF("elementalsPatchFile", "elementals_patch.xml");
+ AddDEF("elementalsPatchDir", "elementals.d");
AddDEF("mapsRemapFile", "maps/remap.xml");
AddDEF("mapsRemapPatchFile", "maps/remap_patch.xml");
AddDEF("mapsRemapPatchDir", "maps/remap.d");
diff --git a/src/net/eathena/beingrecv.cpp b/src/net/eathena/beingrecv.cpp
index 4885e3c05..a9d5f380d 100644
--- a/src/net/eathena/beingrecv.cpp
+++ b/src/net/eathena/beingrecv.cpp
@@ -1985,8 +1985,10 @@ Being *BeingRecv::createBeing2(Net::MessageIn &msg,
case BeingType::SKILL:
type = ActorType::SkillUnit;
break;
- case BeingType::ITEM:
case BeingType::ELEMENTAL:
+ type = ActorType::Elemental;
+ break;
+ case BeingType::ITEM:
logger->log("not supported object type: %d, job: %d",
CAST_S32(beingType), CAST_S32(job));
break;
diff --git a/src/resources/db/elementaldb.cpp b/src/resources/db/elementaldb.cpp
new file mode 100644
index 000000000..ecfbbcef3
--- /dev/null
+++ b/src/resources/db/elementaldb.cpp
@@ -0,0 +1,156 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2016 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * 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 2 of the License, or
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "resources/db/elementaldb.h"
+
+#include "configuration.h"
+
+#include "resources/beingcommon.h"
+#include "resources/beinginfo.h"
+
+#include "utils/checkutils.h"
+#include "utils/dtor.h"
+
+#include "debug.h"
+
+namespace
+{
+ BeingInfos mElementalInfos;
+ bool mLoaded = false;
+}
+
+void ElementalDb::load()
+{
+ if (mLoaded)
+ unload();
+
+ logger->log1("Initializing elemental database...");
+ loadXmlFile(paths.getStringValue("elementalsFile"), SkipError_false);
+ loadXmlFile(paths.getStringValue("elementalsPatchFile"), SkipError_true);
+ loadXmlDir("elementalsPatchDir", loadXmlFile);
+
+ mLoaded = true;
+}
+
+void ElementalDb::loadXmlFile(const std::string &fileName,
+ const SkipError skipError)
+{
+ XML::Document doc(fileName, UseResman_true, skipError);
+ const XmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlNameEqual(rootNode, "elementals"))
+ {
+ logger->log("Elemental Database: Error while loading %s!",
+ paths.getStringValue("elementalsFile").c_str());
+ mLoaded = true;
+ return;
+ }
+
+ const int offset = XML::getProperty(rootNode, "offset", 0);
+
+ // iterate <elemental>s
+ for_each_xml_child_node(elementalNode, rootNode)
+ {
+ if (xmlNameEqual(elementalNode, "include"))
+ {
+ const std::string name = XML::getProperty(
+ elementalNode, "name", "");
+ if (!name.empty())
+ loadXmlFile(name, skipError);
+ continue;
+ }
+ if (!xmlNameEqual(elementalNode, "elemental"))
+ continue;
+
+ const int id = XML::getProperty(elementalNode, "id", 0);
+ BeingInfo *currentInfo = nullptr;
+ if (mElementalInfos.find(fromInt(id + offset, BeingTypeId))
+ != mElementalInfos.end())
+ {
+ logger->log("ElementalDb: Redefinition of elemental ID %d", id);
+ currentInfo = mElementalInfos[fromInt(id + offset, BeingTypeId)];
+ }
+ if (!currentInfo)
+ currentInfo = new BeingInfo;
+
+ currentInfo->setBlockType(BlockType::NONE);
+ BeingCommon::readBasicAttributes(currentInfo,
+ elementalNode, "attack");
+
+ currentInfo->setMaxHP(XML::getProperty(elementalNode, "maxHP", 0));
+
+ currentInfo->setDeadSortOffsetY(XML::getProperty(
+ elementalNode, "deadSortOffsetY", 31));
+
+ currentInfo->setColorsList(XML::getProperty(elementalNode,
+ "colors", ""));
+
+ if (currentInfo->getMaxHP())
+ currentInfo->setStaticMaxHP(true);
+
+ SpriteDisplay display;
+
+ // iterate <sprite>s and <sound>s
+ for_each_xml_child_node(spriteNode, elementalNode)
+ {
+ BeingCommon::readObjectNodes(spriteNode, display,
+ currentInfo, "ElementalDb");
+ }
+ currentInfo->setDisplay(display);
+
+ mElementalInfos[fromInt(id + offset, BeingTypeId)] = currentInfo;
+ }
+}
+
+void ElementalDb::unload()
+{
+ delete_all(mElementalInfos);
+ mElementalInfos.clear();
+
+ mLoaded = false;
+}
+
+
+BeingInfo *ElementalDb::get(const BeingTypeId id)
+{
+ BeingInfoIterator i = mElementalInfos.find(id);
+
+ if (i == mElementalInfos.end())
+ {
+ i = mElementalInfos.find(id);
+ if (i == mElementalInfos.end())
+ {
+ reportAlways("ElementalDb: Warning, unknown elemental ID "
+ "%d requested",
+ toInt(id, int));
+ return BeingInfo::unknown;
+ }
+ else
+ {
+ return i->second;
+ }
+ }
+ else
+ {
+ return i->second;
+ }
+}
diff --git a/src/resources/db/elementaldb.h b/src/resources/db/elementaldb.h
new file mode 100644
index 000000000..97953a32f
--- /dev/null
+++ b/src/resources/db/elementaldb.h
@@ -0,0 +1,50 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2016 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * 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 2 of the License, or
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RESOURCES_DB_ELEMENTALDB_H
+#define RESOURCES_DB_ELEMENTALDB_H
+
+#include "enums/simpletypes/beingtypeid.h"
+#include "enums/simpletypes/skiperror.h"
+
+#include "localconsts.h"
+
+#include <string>
+
+class BeingInfo;
+
+/**
+ * Elemental information database.
+ */
+namespace ElementalDb
+{
+ void load();
+
+ void unload();
+
+ void loadXmlFile(const std::string &fileName,
+ const SkipError skipError);
+
+ BeingInfo *get(const BeingTypeId id) A_WARN_UNUSED;
+} // namespace ElementalDb
+
+#endif // RESOURCES_DB_ELEMENTALDB_H