summaryrefslogtreecommitdiff
path: root/src/game-server/item.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/game-server/item.h')
-rw-r--r--src/game-server/item.h273
1 files changed, 273 insertions, 0 deletions
diff --git a/src/game-server/item.h b/src/game-server/item.h
new file mode 100644
index 00000000..215b738f
--- /dev/null
+++ b/src/game-server/item.h
@@ -0,0 +1,273 @@
+/*
+ * The Mana Server
+ * Copyright (C) 2004-2010 The Mana World Development Team
+ *
+ * This file is part of The Mana Server.
+ *
+ * The Mana Server 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.
+ *
+ * The Mana Server 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 The Mana Server. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ITEM_H
+#define ITEM_H
+
+#include <vector>
+
+#include "game-server/actor.h"
+
+class Being;
+
+typedef std::list< std::pair< unsigned int, unsigned int> > ItemEquipInfo;
+typedef std::list< ItemEquipInfo > ItemEquipsInfo;
+
+/**
+ * State effects to beings, and actors.
+ * States can be multiple for the same being.
+ */
+enum
+{
+ SET_STATE_NORMAL = 0,
+ SET_STATE_POISONED,
+ SET_STATE_STONED,
+ SET_STATE_STUNNED,
+ SET_STATE_SLOWED,
+ SET_STATE_TIRED,
+ SET_STATE_MAD,
+ SET_STATE_BERSERK,
+ SET_STATE_HASTED,
+ SET_STATE_FLOATING,
+
+ SET_STATE_NOT_POISONED,
+ SET_STATE_NOT_STONED,
+ SET_STATE_NOT_STUNNED,
+ SET_STATE_NOT_SLOWED,
+ SET_STATE_NOT_TIRED,
+ SET_STATE_NOT_MAD,
+ SET_STATE_NOT_BERSERK,
+ SET_STATE_NOT_HASTED,
+ SET_STATE_NOT_FLOATING
+};
+
+struct ItemAutoAttackInfo {
+ unsigned int base;
+ unsigned int range;
+ unsigned int baseSpeed;
+ unsigned int skillId;
+ /// attribute id -> damage bonus per point
+ std::map< unsigned int, double > attrBonus;
+};
+
+enum ItemTriggerType {
+ ITT_NULL = 0,
+ ITT_IN_INVY, // Associated effects apply when the item is in the inventory
+ ITT_ACTIVATE, // Associated effects apply when the item is activated
+ ITT_EQUIP, // Assosciated effects apply when the item is equipped
+ ITT_LEAVE_INVY, // Associated effects apply when the item leaves the inventory
+ ITT_UNEQUIP, // Associated effects apply when the item is unequipped
+ ITT_EQUIPCHG // When the item is still equipped, but in a different way
+};
+
+enum ItemEffectType {
+ // Effects that are removed automatically when the trigger ends
+ // (ie. item no longer exists in invy, unequipped)
+ IET_ATTR_MOD = 0, // Modify a given attribute with a given value
+ IET_AUTOATTACK, // Give the associated being an autoattack
+ // Effects that do not need any automatic removal
+ IET_COOLDOWN, // Set a cooldown to this item, preventing activation for n ticks
+ IET_G_COOLDOWN, // Set a cooldown to all items of this type for this being
+ IET_SCRIPT // Call an associated lua script with given variables
+};
+
+class ItemEffectInfo
+{
+ public:
+ virtual bool apply(Being *itemUser);
+ virtual void dispell(Being *itemUser) {}
+};
+
+class ItemEffectAttrMod : public ItemEffectInfo
+{
+ public:
+ ItemEffectAttrMod(unsigned int attrId, unsigned int layer, double value,
+ unsigned int id, unsigned int duration = 0) :
+ mAttributeId(attrId), mAttributeLayer(layer),
+ mMod(value), mDuration(duration), mId(id) {}
+
+ bool apply(Being *itemUser);
+ void dispell(Being *itemUser);
+
+ private:
+ unsigned int mAttributeId;
+ unsigned int mAttributeLayer;
+ double mMod;
+ unsigned int mDuration;
+ unsigned int mId;
+};
+
+class ItemEffectAutoAttack : public ItemEffectInfo
+{
+ public:
+ bool apply(Being *itemUser);
+ void dispell(Being *itemUser);
+};
+
+class ItemEffectConsumes : public ItemEffectInfo
+{
+ public:
+ bool apply(Being *itemUser) { return true; }
+ void dispell(Being *itemUser) {}
+};
+
+class ItemEffectScript : public ItemEffectInfo
+{
+ public:
+ bool apply(Being *itemUser);
+ void dispell(Being *itemUser);
+};
+
+
+/**
+ * Class for simple reference to item information.
+ */
+class ItemClass
+{
+ public:
+ ItemClass(int id, unsigned int maxperslot)
+ : mDatabaseID(id)
+ , mSpriteID(0)
+ , mCost(0)
+ , mMaxPerSlot(maxperslot)
+ {}
+
+ ~ItemClass() { resetEffects(); }
+
+ /**
+ * Applies the modifiers of an item to a given user.
+ * @return true if item should be removed.
+ */
+ bool useTrigger(Being *itemUser, ItemTriggerType trigger);
+
+ /**
+ * Gets unit cost of these items.
+ */
+ int getCost() const
+ { return mCost; }
+
+ /**
+ * Gets max item per slot.
+ */
+ unsigned int getMaxPerSlot() const
+ { return mMaxPerSlot; }
+
+ bool hasTrigger(ItemTriggerType id)
+ { return mEffects.count(id); }
+
+ /**
+ * Gets database ID.
+ */
+ int getDatabaseID() const
+ { return mDatabaseID; }
+
+ /**
+ * Gets the sprite ID.
+ * @note At present this is only a stub, and will always return zero.
+ * When you would want to extend serializeLooks to be more
+ * efficient, keep track of a sprite id here.
+ */
+ int getSpriteID() const
+ { return mSpriteID; }
+
+ /**
+ * Returns equip requirements.
+ */
+ const ItemEquipsInfo &getItemEquipData() const { return mEquip; }
+
+
+ private:
+
+ /**
+ * Add an effect to a trigger
+ * @param effect The effect to be run when the trigger is hit.
+ * @param id The trigger type.
+ * @param dispell The trigger that the effect should be dispelled on.
+ * @note FIXME: Should be more than one trigger that an effect
+ * can be dispelled from.
+ */
+ void addEffect(ItemEffectInfo *effect,
+ ItemTriggerType id,
+ ItemTriggerType dispell = ITT_NULL)
+ {
+ mEffects.insert(std::make_pair(id, effect));
+ if (dispell)
+ mDispells.insert(std::make_pair(dispell, effect));
+ }
+
+ void resetEffects()
+ {
+ while (mEffects.begin() != mEffects.end())
+ {
+ delete mEffects.begin()->second;
+ mEffects.erase(mEffects.begin());
+ }
+ while (mDispells.begin() != mDispells.end())
+ {
+ delete mDispells.begin()->second;
+ mDispells.erase(mDispells.begin());
+ }
+ }
+
+ unsigned short mDatabaseID; /**< Item reference information */
+ /** The sprite that should be shown to the character */
+ unsigned short mSpriteID;
+ unsigned short mCost; /**< Unit cost the item. */
+ /** Max item amount per slot in inventory. */
+ unsigned int mMaxPerSlot;
+
+ std::multimap< ItemTriggerType, ItemEffectInfo * > mEffects;
+ std::multimap< ItemTriggerType, ItemEffectInfo * > mDispells;
+
+ /**
+ * List of list of requirements for equipping. Only one inner list
+ * need be satisfied to sucessfully equip. Checks occur in order
+ * from outer front to back.
+ * All conditions in an inner list must be met for success.
+ */
+ ItemEquipsInfo mEquip;
+
+ friend class ItemManager;
+};
+
+/**
+* Class for an item stack laying on the floor in the game world
+*/
+
+class Item : public Actor
+{
+ public:
+ Item(ItemClass *type, int amount);
+
+ ItemClass *getItemClass() const
+ { return mType; }
+
+ int getAmount() const
+ { return mAmount; }
+
+ virtual void update();
+
+ private:
+ ItemClass *mType;
+ unsigned char mAmount;
+ int mLifetime;
+};
+
+#endif