From d1649dfdf5628fb49d1c2c50085cd318a87a515f Mon Sep 17 00:00:00 2001 From: Philipp Sehmisch Date: Wed, 20 Feb 2008 23:15:54 +0000 Subject: Implemented different monster attacks read from monsters.xml --- src/game-server/item.hpp | 5 ++- src/game-server/itemmanager.cpp | 78 ++++++++++---------------------------- src/game-server/monster.cpp | 45 +++++++++++----------- src/game-server/monster.hpp | 36 ++++++++++++++---- src/game-server/monstermanager.cpp | 43 +++++++++++++++++++++ 5 files changed, 120 insertions(+), 87 deletions(-) (limited to 'src/game-server') diff --git a/src/game-server/item.hpp b/src/game-server/item.hpp index 4f1186be..018cac48 100644 --- a/src/game-server/item.hpp +++ b/src/game-server/item.hpp @@ -47,7 +47,10 @@ enum ItemType ITEM_EQUIPMENT_RING,// 9 ITEM_EQUIPMENT_NECKLACE,// 10 ITEM_EQUIPMENT_FEET,// 11 - ITEM_EQUIPMENT_AMMO// 12 + ITEM_EQUIPMENT_AMMO,// 12 + ITEM_HAIRSPRITE, + ITEM_RACESPRITE, + ITEM_UNKNOWN }; /** diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp index ef3963d4..78c7f04a 100644 --- a/src/game-server/itemmanager.cpp +++ b/src/game-server/itemmanager.cpp @@ -22,6 +22,7 @@ */ #include +#include #include "game-server/itemmanager.hpp" @@ -36,61 +37,6 @@ static ItemClasses itemClasses; /**< Item reference */ static std::string itemReferenceFile; -ItemType itemTypeFromString (std::string name, int id = 0) -{ - if (name=="generic") return ITEM_UNUSABLE; - else if (name=="usable") return ITEM_USABLE; - else if (name=="equip-1hand") return ITEM_EQUIPMENT_ONE_HAND_WEAPON; - else if (name=="equip-2hand") return ITEM_EQUIPMENT_TWO_HANDS_WEAPON; - else if (name=="equip-torso") return ITEM_EQUIPMENT_TORSO; - else if (name=="equip-arms") return ITEM_EQUIPMENT_ARMS; - else if (name=="equip-head") return ITEM_EQUIPMENT_HEAD; - else if (name=="equip-legs") return ITEM_EQUIPMENT_LEGS; - else if (name=="equip-shield") return ITEM_EQUIPMENT_SHIELD; - else if (name=="equip-ring") return ITEM_EQUIPMENT_RING; - else if (name=="equip-necklace") return ITEM_EQUIPMENT_NECKLACE; - else if (name=="equip-feet") return ITEM_EQUIPMENT_FEET; - else if (name=="equip-ammo") return ITEM_EQUIPMENT_AMMO; - else if (name=="") - { - LOG_WARN("No item type defined for item "<getSpeed()); setSize(specy->getSize()); - // Some bogus stats for testing. - // TODO: Get all this stuff from the monster database. - mAttackPreDelay = 10; - mAttackAftDelay = 10; - mAttackRange = 32; - mAttackAngle = 10; - // Set positions relative to target from which the monster can attack - mAttackPositions.push_back(AttackPosition(+32, 0, DIRECTION_LEFT)); - mAttackPositions.push_back(AttackPosition(-32, 0, DIRECTION_RIGHT)); - mAttackPositions.push_back(AttackPosition(0, +32, DIRECTION_DOWN)); - mAttackPositions.push_back(AttackPosition(0, -32, DIRECTION_UP)); + int dist = specy->getAttackDistance(); + mAttackPositions.push_back(AttackPosition(dist, 0, DIRECTION_LEFT)); + mAttackPositions.push_back(AttackPosition(-dist, 0, DIRECTION_RIGHT)); + mAttackPositions.push_back(AttackPosition(0, dist, DIRECTION_DOWN)); + mAttackPositions.push_back(AttackPosition(0, -dist, DIRECTION_UP)); } Monster::~Monster() @@ -110,19 +105,19 @@ Monster::~Monster() void Monster::perform() { - if (mAction == ATTACK) + if (mAction == ATTACK && mCurrentAttack) { - if (mAttackTime == mAttackAftDelay) + if (mAttackTime == mCurrentAttack->aftDelay) { // Hard-coded values for now. Damage damage; - damage.base = getModifiedAttribute(BASE_ATTR_PHY_ATK_MIN); - damage.delta = getModifiedAttribute(BASE_ATTR_PHY_ATK_DELTA); + damage.base = (int) (getModifiedAttribute(BASE_ATTR_PHY_ATK_MIN) * mCurrentAttack->damageFactor); + damage.delta = (int) (getModifiedAttribute(BASE_ATTR_PHY_ATK_DELTA) * mCurrentAttack->damageFactor); damage.cth = getModifiedAttribute(BASE_ATTR_HIT); - damage.element = ELEMENT_NEUTRAL; - damage.type = DAMAGE_PHYSICAL; + damage.element = mCurrentAttack->element; + damage.type = mCurrentAttack->type; damage.usedSkill = 0; - performAttack(damage, mAttackRange, mAttackAngle); + performAttack(damage, mCurrentAttack->range, mCurrentAttack->angle); } if (!mAttackTime) { @@ -222,9 +217,15 @@ void Monster::update() { // We are there - let's beat the crap out of the target setDirection(bestAttackDirection); - setAction(ATTACK); - raiseUpdateFlags(UPDATEFLAG_ATTACK); - mAttackTime = mAttackPreDelay + mAttackAftDelay; + MonsterAttacks allAttacks = mSpecy->getAttacks(); + + if (!allAttacks.empty()) + { + mCurrentAttack = allAttacks.at(rand()%allAttacks.size()); //TODO: this ignores priority -> fix it + mAttackTime = mCurrentAttack->preDelay + mCurrentAttack->aftDelay; + setAction(ATTACK); + raiseUpdateFlags(UPDATEFLAG_ATTACK); + } } else { diff --git a/src/game-server/monster.hpp b/src/game-server/monster.hpp index 36dbbdc3..3f6db5c1 100644 --- a/src/game-server/monster.hpp +++ b/src/game-server/monster.hpp @@ -43,6 +43,24 @@ struct MonsterDrop typedef std::vector< MonsterDrop > MonsterDrops; +/** + * Structure containing different attack types of a monster type + */ +struct MonsterAttack +{ + unsigned id; + int priority; + float damageFactor; + int element; + int type; + int preDelay; + int aftDelay; + int range; + int angle; +}; + +typedef std::vector< MonsterAttack *> MonsterAttacks; + /** * Class describing the characteristics of a generic monster. */ @@ -58,7 +76,8 @@ class MonsterClass mAggressive(false), mTrackRange(1), mStrollRange(0), - mMutation(0) + mMutation(0), + mAttackDistance(0) {} /** @@ -106,6 +125,12 @@ class MonsterClass void setMutation(unsigned factor) { mMutation = factor; } /**< sets mutation factor in percent*/ unsigned getMutation() const { return mMutation; } /**< gets mutation factor in percent*/ + void setAttackDistance(unsigned distance) { mAttackDistance = distance; } /**< sets preferred combat distance in pixels*/ + unsigned getAttackDistance() const { return mAttackDistance; } /**< gets preferred combat distance in pixels*/ + + void addAttack(MonsterAttack *type) { mAttacks.push_back(type); } /**< adds an attack to the monsters repertoire */ + const MonsterAttacks &getAttacks() const { return mAttacks; } /**< gets all attacks of the monster */ + /** * Randomly selects a monster drop (may return NULL). */ @@ -122,6 +147,8 @@ class MonsterClass unsigned mTrackRange; /**< Distance the monster tracks enemies in */ unsigned mStrollRange; /**< Distance the monster strolls around in when not fighting */ unsigned mMutation; /**< Mutation factor in percent*/ + unsigned mAttackDistance; + MonsterAttacks mAttacks; /**< preferred combat distance in pixels*/ }; /** @@ -205,12 +232,7 @@ class Monster : public Being std::set mLegalExpReceivers; /**< List of characters who are entitled to receive exp (killsteal protection)*/ int mAttackTime; /**< Delay until monster can attack */ - // TODO: the following vars should all be the same for all monsters of - // the same type. So they should be stored in mSpecy to save memory - int mAttackPreDelay; /**< time between decision to make an attack and performing the attack */ - int mAttackAftDelay; /**< time it takes to perform an attack */ - int mAttackRange; /**< range of the monsters attacks in pixel */ - int mAttackAngle; /**< angle of the monsters attacks in degree */ + MonsterAttack *mCurrentAttack; /** mAttackPositions; /**< set positions relative to target from which the monster can attack */ friend struct MonsterTargetEventDispatch; diff --git a/src/game-server/monstermanager.cpp b/src/game-server/monstermanager.cpp index 693cd53a..69ad5c08 100644 --- a/src/game-server/monstermanager.cpp +++ b/src/game-server/monstermanager.cpp @@ -196,6 +196,49 @@ void MonsterManager::reload() } monster->setTrackRange(XML::getProperty(subnode, "track-range", 1)); monster->setStrollRange(XML::getProperty(subnode, "stroll-range", 0) * 32); + monster->setAttackDistance(XML::getProperty(subnode, "attack-distance", 0)); + } + else if (xmlStrEqual(subnode->name, BAD_CAST "attack")) + { + MonsterAttack *att = new MonsterAttack; + att->id = XML::getProperty(subnode, "id", 0); + att->priority = XML::getProperty(subnode, "priority", 1); + att->damageFactor = XML::getFloatProperty(subnode, "damage-factor", 1.0f); + att->preDelay = XML::getProperty(subnode, "pre-delay", 1); + att->aftDelay = XML::getProperty(subnode, "aft-delay", 0); + att->range = XML::getProperty(subnode, "range", 1); + att->angle = XML::getProperty(subnode, "angle", 1); + std::string sElement = XML::getProperty(subnode, "element", "neutral"); + att->element = XML::elementFromString(sElement); + std::string sType = XML::getProperty(subnode, "type", "physical"); + if (sType == "physical") {att->type = DAMAGE_PHYSICAL; } + else if (sType == "magical" || sType == "magic") {att->type = DAMAGE_MAGICAL; } + else if (sType == "other") {att->type = DAMAGE_OTHER; } + else { att->type = -1; } + + if (att->id == 0) + { + LOG_WARN(monsterReferenceFile + <<": Attack without ID for monster #" + <element == ELEMENT_ILLEGAL) + { + LOG_WARN(monsterReferenceFile + <<": Attack with unknown element \""<type == -1) + { + LOG_WARN(monsterReferenceFile + <<": Attack with unknown type \""<addAttack(att); + } + } } -- cgit v1.2.3-70-g09d2