From 9dd811b55587aeb76344b835006cb4a01601bb5d Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Sun, 23 Mar 2008 01:27:13 +0000 Subject: Merged revisions 3823,3825-3826,3829,3831-3839,3841-3842 via svnmerge from https://themanaworld.svn.sourceforge.net/svnroot/themanaworld/tmw/branches/0.0 ........ r3823 | crush_tmw | 2007-12-28 19:36:58 +0100 (Fri, 28 Dec 2007) | 1 line Added the possibility to assign particle effects to monsters in the monster database. Added flame particle effect to fire goblin as a proof of concept. ........ r3826 | crush_tmw | 2007-12-30 01:02:14 +0100 (Sun, 30 Dec 2007) | 1 line Added a key for targeting the nearest player character based on patches by Trinexx. Some mapping fixes at snake dungeon map. ........ r3839 | the_enemy | 2008-01-13 17:28:50 +0100 (Sun, 13 Jan 2008) | 1 line Fixed non-default location music loading ........ r3842 | crush_tmw | 2008-01-14 11:48:13 +0100 (Mon, 14 Jan 2008) | 1 line ixed an error in Davids last commit (couldn't compile that way). ........ --- ChangeLog | 16 ++++++++++ src/being.cpp | 3 +- src/beingmanager.cpp | 27 +++++++++++++++++ src/beingmanager.h | 15 ++++++++-- src/engine.cpp | 3 +- src/game.cpp | 15 ++++++++-- src/keyboardconfig.cpp | 1 + src/keyboardconfig.h | 1 + src/main.cpp | 2 +- src/monster.cpp | 11 ++++++- src/resources/monsterdb.cpp | 26 ++++++++++------ src/resources/monsterinfo.cpp | 63 ++++++++++++++------------------------- src/resources/monsterinfo.h | 18 +++++++---- src/resources/resourcemanager.cpp | 21 +++++++++++++ src/resources/resourcemanager.h | 8 +++++ src/sound.cpp | 5 +++- 16 files changed, 170 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8eabea7..755ad5d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -228,6 +228,14 @@ * data/maps/new_10-1.tmx, data/maps/new_11-1.tmx: Added new versions of snow maps by 5t3v3. + * src/sound.cpp: Fixed an error in Davids last commit (couldn't compile + that way). + +2008-01-13 David Athay + + * src/resources/resourcemanager.h, src/resources/resourcemanager.cpp, + src/main.cpp, src/sound.cpp, src/engine.cpp: Fixed music loading from + non-default location. 2008-01-10 Philipp Sehmisch @@ -269,6 +277,9 @@ 2007-12-30 Philipp Sehmisch * data/maps/new_22-1.tmx: Some mapping fixes at snake dungeon map. + * src/game.cpp, src/beingmanager.cpp, src/beingmanager.h, + src/keyboardconfig.cpp, src/keyboardconfig.h: Added a key for targeting + the nearest player character based on patches by Trinexx. 2007-12-28 Philipp Sehmisch @@ -276,6 +287,11 @@ 5t3v3 (east desert cave) and enhanced version of eastern desert by Len. * data/maps/new_3-1.tmx: Some mapping errors fixed by Zipon. + * src/being.cpp, src/monster.cpp, src/resources/monsterinfo.cpp, + src/resources/monsterinfo.h: Added the possibility to assign particle + effects to monsters in the monster database. + * data/monsters.xml: Added flame particle effect to fire goblin as a + proof of concept. 2007-12-25 Bjørn Lindeijer diff --git a/src/being.cpp b/src/being.cpp index 55530080..b187d28a 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -82,7 +82,6 @@ Being::~Being() { std::for_each(mSprites.begin(), mSprites.end(), make_dtor(mSprites)); clearPath(); - setMap(NULL); for ( std::list::iterator i = mChildParticleEffects.begin(); i != mChildParticleEffects.end(); @@ -91,6 +90,8 @@ Being::~Being() (*i)->kill(); } + setMap(NULL); + instances--; if (instances == 0) diff --git a/src/beingmanager.cpp b/src/beingmanager.cpp index 8ef3de1e..214a1995 100644 --- a/src/beingmanager.cpp +++ b/src/beingmanager.cpp @@ -180,3 +180,30 @@ Being* BeingManager::findNearestLivingBeing(Uint16 x, Uint16 y, int maxdist, return (maxdist >= dist) ? closestBeing : NULL; } + +Being* BeingManager::findNearestLivingBeing(Being *aroundBeing, int maxdist, + Being::Type type) +{ + Being *closestBeing = NULL; + int dist = 0; + int x = aroundBeing->mX; + int y = aroundBeing->mY; + + for (BeingIterator i = mBeings.begin(); i != mBeings.end(); i++) + { + Being *being = (*i); + int d = abs(being->mX - x) + abs(being->mY - y); + + if ((being->getType() == type || type == Being::UNKNOWN) + && (d < dist || closestBeing == NULL) // it is closer + && being->mAction != Being::DEAD // no dead beings + && being != aroundBeing + ) + { + dist = d; + closestBeing = being; + } + } + + return (maxdist >= dist) ? closestBeing : NULL; +} diff --git a/src/beingmanager.h b/src/beingmanager.h index 81f85622..6792ed0e 100644 --- a/src/beingmanager.h +++ b/src/beingmanager.h @@ -56,17 +56,17 @@ class BeingManager void destroyBeing(Being *being); /** - * Return a specific id Being. + * Returns a specific id Being. */ Being* findBeing(Uint16 id); /** - * Return a being at specific coordinates. + * Returns a being at specific coordinates. */ Being* findBeing(Uint16 x, Uint16 y, Being::Type type = Being::UNKNOWN); /** - * Return a being nearest to specific coordinates. + * Returns a being nearest to specific coordinates. * * @param x X coordinate. * @param y Y coordinate. @@ -77,6 +77,15 @@ class BeingManager Being* findNearestLivingBeing(Uint16 x, Uint16 y, int maxdist, Being::Type type = Being::UNKNOWN); + /** + * Returns a being nearest to another being. + * + * \param maxdist maximal distance. If minimal distance is larger, + * no being is returned + */ + Being* findNearestLivingBeing(Being *aroundBeing, int maxdist, + Being::Type type = Being::UNKNOWN); + /** * Returns the whole list of beings */ diff --git a/src/engine.cpp b/src/engine.cpp index 31a13b9f..b38ca0a8 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -111,8 +111,7 @@ void Engine::changeMap(const std::string &mapPath) std::string newMusic = newMap->getProperty("music"); if (newMusic != oldMusic) { - newMusic = std::string(TMW_DATADIR) + "data/music/" + newMusic; - sound.playMusic(newMusic.c_str(), -1); + sound.playMusic(newMusic, -1); } mCurrentMap = newMap; diff --git a/src/game.cpp b/src/game.cpp index e07a70bd..985b7ddc 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -767,9 +767,20 @@ void Game::handleInput() player_node->setWalkingDir(direction); + // Target the nearest player if 'q' is pressed + if (keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER)) + { + Being *target = + beingManager->findNearestLivingBeing(player_node, 20, Being::PLAYER); + + if (target) + { + player_node->setTarget(target); + } + } + // Target the nearest monster if 'a' pressed - if ( keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) ) - //if (keys[SDLK_a]) + if (keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST)) { Being *target = beingManager->findNearestLivingBeing(x, y, 20, Being::MONSTER); diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp index 271961c8..a959e244 100644 --- a/src/keyboardconfig.cpp +++ b/src/keyboardconfig.cpp @@ -45,6 +45,7 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = { {"keyAttack", SDLK_LCTRL, "Attack"}, {"keyTarget", SDLK_LSHIFT, "Target"}, {"keyTargetClosest", SDLK_a, "Target Closest"}, + {"keyTargetPlayer", SDLK_q, "Target Player"}, {"keyPickup", SDLK_z, "Pickup"}, {"keyHideWindows", SDLK_h, "Hide Windows"}, {"keyBeingSit", SDLK_s, "Sit"}, diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h index 46394fa5..53a5c96d 100644 --- a/src/keyboardconfig.h +++ b/src/keyboardconfig.h @@ -153,6 +153,7 @@ class KeyboardConfig KEY_ATTACK, KEY_TARGET, KEY_TARGET_CLOSEST, + KEY_TARGET_PLAYER, KEY_PICKUP, KEY_HIDE_WINDOWS, KEY_SIT, diff --git a/src/main.cpp b/src/main.cpp index 9c69b203..eea47394 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -722,7 +722,7 @@ int main(int argc, char *argv[]) top->add(versionLabel, 2, 2); #endif - sound.playMusic(TMW_DATADIR "data/music/Magick - Real.ogg"); + sound.playMusic("Magick - Real.ogg"); // Server choice if (options.serverName.empty()) { diff --git a/src/monster.cpp b/src/monster.cpp index abc7946f..1561b2ea 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -36,12 +36,21 @@ Monster::Monster(Uint16 id, Uint16 job, Map *map): Being(id, job, map) { - std::string filename = getInfo().getSprite(); + const MonsterInfo& info = getInfo(); + std::string filename = info.getSprite(); if (filename.empty()) filename = "error.xml"; mSprites[BASE_SPRITE] = AnimatedSprite::load("graphics/sprites/" + filename); + + const std::list &particleEffects = info.getParticleEffects(); + for (std::list::const_iterator i = particleEffects.begin(); + i != particleEffects.end(); + i++) + { + controlParticle(particleEngine->addEffect((*i), 0, 0)); + } } Monster::~Monster() diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp index fd200e4e..e7e855fa 100644 --- a/src/resources/monsterdb.cpp +++ b/src/resources/monsterdb.cpp @@ -78,13 +78,11 @@ MonsterDB::load() for_each_xml_child_node(monsterNode, rootNode) { if (!xmlStrEqual(monsterNode->name, BAD_CAST "monster")) - { continue; - } MonsterInfo *currentInfo = new MonsterInfo(); - currentInfo->setName (XML::getProperty(monsterNode, "name", "unnamed")); + currentInfo->setName(XML::getProperty(monsterNode, "name", "unnamed")); std::string targetCursor; targetCursor = XML::getProperty(monsterNode, "targetCursor", "medium"); @@ -102,7 +100,8 @@ MonsterDB::load() } else { - logger->log("MonsterDB: Unknown target cursor type \"%s\" for %s - using medium sized one", + logger->log("MonsterDB: Unknown target cursor type \"%s\" for %s " + "- using medium sized one", targetCursor.c_str(), currentInfo->getName().c_str()); currentInfo->setTargetCursorSize(Being::TC_MEDIUM); } @@ -138,17 +137,26 @@ MonsterDB::load() } else { - logger->log("MonsterDB: Warning, sound effect %s for unknown event %s of monster %s", - filename, event.c_str(), currentInfo->getName().c_str()); + logger->log("MonsterDB: Warning, sound effect %s for " + "unknown event %s of monster %s", + filename, event.c_str(), + currentInfo->getName().c_str()); } } else if (xmlStrEqual(spriteNode->name, BAD_CAST "attack")) { - int id = XML::getProperty(spriteNode, "id", 0); - std::string particleEffect = XML::getProperty(spriteNode, "particle-effect", ""); - SpriteAction spriteAction = SpriteDef::makeSpriteAction(XML::getProperty(spriteNode, "action", "attack")); + const int id = XML::getProperty(spriteNode, "id", 0); + const std::string particleEffect = XML::getProperty( + spriteNode, "particle-effect", ""); + SpriteAction spriteAction = SpriteDef::makeSpriteAction( + XML::getProperty(spriteNode, "action", "attack")); currentInfo->addMonsterAttack(id, particleEffect, spriteAction); } + else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx")) + { + currentInfo->addParticleEffect( + (const char*) spriteNode->xmlChildrenNode->content); + } } mMonsterInfos[XML::getProperty(monsterNode, "id", 0)] = currentInfo; } diff --git a/src/resources/monsterinfo.cpp b/src/resources/monsterinfo.cpp index a7ad51a3..0af09c53 100644 --- a/src/resources/monsterinfo.cpp +++ b/src/resources/monsterinfo.cpp @@ -30,20 +30,17 @@ MonsterInfo::MonsterInfo(): mSprite("error.xml") { - } MonsterInfo::~MonsterInfo() { // kill vectors in mSoundEffects - for_each (mSounds.begin(), mSounds.end(), - make_dtor(mSounds)); + for_each(mSounds.begin(), mSounds.end(), make_dtor(mSounds)); mSounds.clear(); } - void -MonsterInfo::addSound(MonsterSoundEvent event, std::string filename) +MonsterInfo::addSound(MonsterSoundEvent event, const std::string &filename) { if (mSounds.find(event) == mSounds.end()) { @@ -53,59 +50,45 @@ MonsterInfo::addSound(MonsterSoundEvent event, std::string filename) mSounds[event]->push_back("sfx/" + filename); } - const std::string & MonsterInfo::getSound(MonsterSoundEvent event) const { - static std::string nothing(""); - std::map* >::const_iterator i; - i = mSounds.find(event); - if (i == mSounds.end()) - { - return nothing; - } - else - { - return i->second->at(rand()%i->second->size()); - } + static std::string empty(""); + std::map* >::const_iterator i = + mSounds.find(event); + return (i == mSounds.end()) ? empty : + i->second->at(rand() % i->second->size()); } const std::string & MonsterInfo::getAttackParticleEffect(int attackType) const { - static std::string nothing(""); - std::map::const_iterator i; - i = mMonsterAttacks.find(attackType); - if (i == mMonsterAttacks.end()) - { - return nothing; - } - else - { - return (*i).second->particleEffect; - } + static std::string empty(""); + std::map::const_iterator i = + mMonsterAttacks.find(attackType); + return (i == mMonsterAttacks.end()) ? empty : (*i).second->particleEffect; } SpriteAction MonsterInfo::getAttackAction(int attackType) const { - std::map::const_iterator i; - i = mMonsterAttacks.find(attackType); - if (i == mMonsterAttacks.end()) - { - return ACTION_ATTACK; - } - else - { - return (*i).second->action; - } + std::map::const_iterator i = + mMonsterAttacks.find(attackType); + return (i == mMonsterAttacks.end()) ? ACTION_ATTACK : (*i).second->action; } void -MonsterInfo::addMonsterAttack (int id, const std::string &particleEffect, SpriteAction action) +MonsterInfo::addMonsterAttack(int id, + const std::string &particleEffect, + SpriteAction action) { - MonsterAttack* a = new MonsterAttack; + MonsterAttack *a = new MonsterAttack; a->particleEffect = particleEffect; a->action = action; mMonsterAttacks[id] = a; } + +void MonsterInfo::addParticleEffect(const std::string &filename) +{ + mParticleEffects.push_back(filename); +} diff --git a/src/resources/monsterinfo.h b/src/resources/monsterinfo.h index 840f37be..f34a3ea9 100644 --- a/src/resources/monsterinfo.h +++ b/src/resources/monsterinfo.h @@ -27,6 +27,7 @@ #include #include #include +#include #include "../being.h" @@ -65,17 +66,20 @@ class MonsterInfo ~MonsterInfo(); void - setName(std::string name) { mName = name; } + setName(const std::string &name) { mName = name; } void - setSprite(std::string filename) { mSprite = filename; } + setSprite(const std::string &filename) { mSprite = filename; } void setTargetCursorSize(Being::TargetCursorSize targetCursorSize) { mTargetCursorSize = targetCursorSize; } void - addSound(MonsterSoundEvent event, std::string filename); + addSound(MonsterSoundEvent event, const std::string &filename); + + void + addParticleEffect(const std::string &filename); const std::string& getName() const { return mName; } @@ -89,7 +93,9 @@ class MonsterInfo const std::string& getSound(MonsterSoundEvent event) const; - void addMonsterAttack (int id, const std::string &particleEffect, SpriteAction action); + void addMonsterAttack(int id, + const std::string &particleEffect, + SpriteAction action); const std::string& getAttackParticleEffect(int attackType) const; @@ -97,7 +103,8 @@ class MonsterInfo SpriteAction getAttackAction(int attackType) const; - + const std::list& + getParticleEffects() const { return mParticleEffects; } private: std::string mName; @@ -105,6 +112,7 @@ class MonsterInfo Being::TargetCursorSize mTargetCursorSize; std::map* > mSounds; std::map mMonsterAttacks; + std::list mParticleEffects; }; #endif diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index fb9da9d7..59202ad8 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -200,6 +200,27 @@ ResourceManager::isDirectory(const std::string &path) return PHYSFS_isDirectory(path.c_str()); } +std::string +ResourceManager::getPath(const std::string &file) +{ + // get the real path to the file + const char* tmp = PHYSFS_getRealDir(file.c_str()); + std::string path; + + // if the file is not in the search path, then its NULL + if (tmp) + { + path = std::string(tmp) + "/" + file; + } + else + { + // if not found in search path return the default path + path = std::string(TMW_DATADIR) + std::string("data") + "/" + file; + } + + return path; +} + Resource *ResourceManager::get(std::string const &idPath, generator fun, void *data) { // Check if the id exists, and return the value if it does. diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h index abfd629a..da85e2f9 100644 --- a/src/resources/resourcemanager.h +++ b/src/resources/resourcemanager.h @@ -104,6 +104,14 @@ class ResourceManager */ bool isDirectory(const std::string &path); + + /** + * Returns the real path to a file + * + * @param file The file to get the real path to. + * @return The real path. + */ + std::string getPath(const std::string &file); /** * Creates a resource and adds it to the resource map. diff --git a/src/sound.cpp b/src/sound.cpp index cf77cfab..063195ae 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -126,7 +126,7 @@ void Sound::setSfxVolume(int volume) Mix_Volume(-1, volume); } -void Sound::playMusic(const std::string &path, int loop) +void Sound::playMusic(const std::string &filename, int loop) { if (!mInstalled) return; @@ -134,6 +134,9 @@ void Sound::playMusic(const std::string &path, int loop) stopMusic(); } + ResourceManager *resman = ResourceManager::getInstance(); + std::string path = resman->getPath("music/" + filename); + logger->log("Sound::startMusic() Playing \"%s\" %i times", path.c_str(), loop); -- cgit v1.2.3-60-g2f50