From 6a0345c70155f9ff00e52f8952c1e79f61e0d445 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 3 Aug 2016 22:10:59 +0300 Subject: Add support for elemental db and draw elementals sprites. --- src/CMakeLists.txt | 2 + src/Makefile.am | 2 + src/actormanager.cpp | 5 +- src/being/being.cpp | 56 +++++++++----- src/client.cpp | 3 + src/defaults.cpp | 3 + src/net/eathena/beingrecv.cpp | 4 +- src/resources/db/elementaldb.cpp | 156 +++++++++++++++++++++++++++++++++++++++ src/resources/db/elementaldb.h | 50 +++++++++++++ 9 files changed, 262 insertions(+), 19 deletions(-) create mode 100644 src/resources/db/elementaldb.cpp create mode 100644 src/resources/db/elementaldb.h 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 . + */ + +#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 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 s and 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 . + */ + +#ifndef RESOURCES_DB_ELEMENTALDB_H +#define RESOURCES_DB_ELEMENTALDB_H + +#include "enums/simpletypes/beingtypeid.h" +#include "enums/simpletypes/skiperror.h" + +#include "localconsts.h" + +#include + +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 -- cgit v1.2.3-70-g09d2