summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/net/ea/generalhandler.cpp21
-rw-r--r--src/net/tmwserv/generalhandler.cpp19
-rw-r--r--src/resources/itemdb.cpp24
-rw-r--r--src/resources/itemdb.h8
-rw-r--r--src/resources/resourcemanager.cpp26
-rw-r--r--src/resources/resourcemanager.h11
-rw-r--r--src/sound.cpp19
7 files changed, 122 insertions, 6 deletions
diff --git a/src/net/ea/generalhandler.cpp b/src/net/ea/generalhandler.cpp
index 7d5a7d40..25987b8e 100644
--- a/src/net/ea/generalhandler.cpp
+++ b/src/net/ea/generalhandler.cpp
@@ -46,12 +46,16 @@
#include "net/messagein.h"
#include "net/messageout.h"
+#include "resources/itemdb.h"
+
#include "configuration.h"
#include "log.h"
#include "main.h"
#include "utils/gettext.h"
+#include <list>
+
Net::GeneralHandler *generalHandler;
namespace EAthena {
@@ -80,6 +84,23 @@ GeneralHandler::GeneralHandler():
};
handledMessages = _messages;
generalHandler = this;
+
+ std::list<ItemDB::Stat*> stats;
+ ItemDB::Stat stat;
+ stat.tag = "str"; stat.tag = N_("Strength: %d");
+ stats.push_back(&stat);
+ stat.tag = "agi"; stat.tag = N_("Agility: %d");
+ stats.push_back(&stat);
+ stat.tag = "vit"; stat.tag = N_("Vitality: %d");
+ stats.push_back(&stat);
+ stat.tag = "int"; stat.tag = N_("Intelligence: %d");
+ stats.push_back(&stat);
+ stat.tag = "dex"; stat.tag = N_("Dexterity: %d");
+ stats.push_back(&stat);
+ stat.tag = "luck"; stat.tag = N_("Luck: %d");
+ stats.push_back(&stat);
+
+ ItemDB::setStatsList(stats);
}
GeneralHandler::~GeneralHandler()
diff --git a/src/net/tmwserv/generalhandler.cpp b/src/net/tmwserv/generalhandler.cpp
index 98c764c5..be05fa91 100644
--- a/src/net/tmwserv/generalhandler.cpp
+++ b/src/net/tmwserv/generalhandler.cpp
@@ -40,6 +40,8 @@
#include "net/tmwserv/playerhandler.h"
#include "net/tmwserv/tradehandler.h"
+#include <list>
+
Net::GeneralHandler *generalHandler;
Net::Connection *gameServerConnection = 0;
@@ -70,6 +72,23 @@ GeneralHandler::GeneralHandler():
chatServerConnection = Net::getConnection();
generalHandler = this;
+
+ std::list<ItemDB::Stat*> stats;
+ ItemDB::Stat stat;
+ stat.tag = "str"; stat.tag = N_("Strength: %d");
+ stats.push_back(&stat);
+ stat.tag = "agi"; stat.tag = N_("Agility: %d");
+ stats.push_back(&stat);
+ stat.tag = "dex"; stat.tag = N_("Dexterity: %d");
+ stats.push_back(&stat);
+ stat.tag = "vit"; stat.tag = N_("Vitality: %d");
+ stats.push_back(&stat);
+ stat.tag = "int"; stat.tag = N_("Intelligence: %d");
+ stats.push_back(&stat);
+ stat.tag = "will"; stat.tag = N_("Willpower: %d");
+ stats.push_back(&stat);
+
+ ItemDB::setStatsList(stats);
}
void GeneralHandler::load()
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index 50eba33d..807fa0a4 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -56,6 +56,13 @@ static char const *const fields[][2] =
{ "mp", N_("MP %+d") }
};
+static std::list<ItemDB::Stat*> extraStats;
+
+void ItemDB::setStatsList(std::list<ItemDB::Stat*> stats)
+{
+ extraStats = stats;
+}
+
static ItemType itemTypeFromString(const std::string &name, int id = 0)
{
if (name=="generic") return ITEM_UNUSABLE;
@@ -149,7 +156,6 @@ void ItemDB::load()
itemInfo->setWeaponType(weaponType);
itemInfo->setAttackRange(attackRange);
-#ifdef TMWSERV_SUPPORT
std::string effect;
for (int i = 0; i < int(sizeof(fields) / sizeof(fields[0])); ++i)
{
@@ -158,12 +164,20 @@ void ItemDB::load()
if (!effect.empty()) effect += " / ";
effect += strprintf(gettext(fields[i][1]), value);
}
-#else
- std::string effect = XML::getProperty(node, "effect", "");
-#endif
+ for (std::list<Stat*>::iterator it = extraStats.begin();
+ it != extraStats.end(); it++)
+ {
+ int value = XML::getProperty(node, (*it)->tag.c_str(), 0);
+ if (!value) continue;
+ if (!effect.empty()) effect += " / ";
+ effect += strprintf((*it)->format.c_str(), value);
+ }
+ std::string temp = XML::getProperty(node, "effect", "");
+ if (!effect.empty() && !temp.empty())
+ effect += " / ";
+ effect += temp;
itemInfo->setEffect(effect);
-
for_each_xml_child_node(itemChild, node)
{
if (xmlStrEqual(itemChild->name, BAD_CAST "sprite"))
diff --git a/src/resources/itemdb.h b/src/resources/itemdb.h
index 770f32dd..2bb8fd5e 100644
--- a/src/resources/itemdb.h
+++ b/src/resources/itemdb.h
@@ -22,6 +22,7 @@
#ifndef ITEM_MANAGER_H
#define ITEM_MANAGER_H
+#include <list>
#include <map>
#include <string>
@@ -45,6 +46,13 @@ namespace ItemDB
const ItemInfo &get(int id);
const ItemInfo &get(const std::string &name);
+ struct Stat {
+ std::string tag;
+ std::string format;
+ };
+
+ void setStatsList(std::list<Stat*> stats);
+
// Items database
typedef std::map<int, ItemInfo*> ItemInfos;
typedef std::map<std::string, ItemInfo*> NamedItemInfos;
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index 33d5e3e5..f7a2586e 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -419,6 +419,32 @@ void *ResourceManager::loadFile(const std::string &fileName, int &fileSize)
return buffer;
}
+bool ResourceManager::copyFile(const std::string &src, const std::string &dst)
+{
+ PHYSFS_file *srcFile = PHYSFS_openRead(src.c_str());
+ if (!srcFile)
+ {
+ logger->log("Read error: %s", PHYSFS_getLastError());
+ return false;
+ }
+ PHYSFS_file *dstFile = PHYSFS_openWrite(dst.c_str());
+ if (!dstFile)
+ {
+ logger->log("Write error: %s", PHYSFS_getLastError());
+ PHYSFS_close(srcFile);
+ return false;
+ }
+
+ int fileSize = PHYSFS_fileLength(srcFile);
+ void *buf = malloc(fileSize);
+ PHYSFS_read(srcFile, buf, 1, fileSize);
+ PHYSFS_write(dstFile, buf, 1, fileSize);
+
+ PHYSFS_close(srcFile);
+ PHYSFS_close(dstFile);
+ return true;
+}
+
std::vector<std::string> ResourceManager::loadTextFile(const std::string &fileName)
{
int contentsLength;
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index ec60fa9a..b2ad3069 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -125,6 +125,17 @@ class ResourceManager
Resource *load(const std::string &path, loader fun);
/**
+ * Copies a file from one place to another (useful for extracting
+ * raw files from a zip archive, for example)
+ *
+ * @param src Source file name
+ * @param dst Destination file name
+ * @return true on success, false on failure. An error message should be
+ * in the log file.
+ */
+ bool copyFile(const std::string &src, const std::string &dst);
+
+ /**
* Convenience wrapper around ResourceManager::get for loading
* images.
*/
diff --git a/src/sound.cpp b/src/sound.cpp
index a366f28d..6fb75d84 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -20,6 +20,7 @@
*/
#include <SDL.h>
+#include <physfs.h>
#include "log.h"
#include "sound.h"
@@ -141,7 +142,23 @@ static Mix_Music *loadMusic(const std::string &filename)
ResourceManager *resman = ResourceManager::getInstance();
std::string path = resman->getPath("music/" + filename);
- logger->log("Loading music \"%s\"", path.c_str());
+ if (path.find(".zip/") != std::string::npos ||
+ path.find(".zip\\") != std::string::npos)
+ {
+ // Music file is a virtual file inside a zip archive - we have to copy
+ // it to a temporary physical file so that SDL_mixer can stream it.
+ logger->log("Loading music \"%s\" from temporary file tempMusic.ogg",
+ path.c_str());
+ bool success = resman->copyFile("music/" + filename, "tempMusic.ogg");
+ if (success)
+ {
+ path = resman->getPath("tempMusic.ogg");
+ } else {
+ return NULL;
+ }
+ } else {
+ logger->log("Loading music \"%s\"", path.c_str());
+ }
Mix_Music *music = Mix_LoadMUS(path.c_str());