mirror of
https://github.com/ErikasKontenis/SabrehavenServer.git
synced 2025-04-30 17:49:20 +02:00
323 lines
8.8 KiB
C++
323 lines
8.8 KiB
C++
/**
|
|
* Tibia GIMUD Server - a free and open-source MMORPG server emulator
|
|
* Copyright (C) 2019 Sabrehaven and Mark Samman <mark.samman@gmail.com>
|
|
*
|
|
* 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
|
|
* (at your option) 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, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#ifndef FS_SPELLS_H_D78A7CCB7080406E8CAA6B1D31D3DA71
|
|
#define FS_SPELLS_H_D78A7CCB7080406E8CAA6B1D31D3DA71
|
|
|
|
#include "luascript.h"
|
|
#include "player.h"
|
|
#include "actions.h"
|
|
#include "talkaction.h"
|
|
#include "baseevents.h"
|
|
|
|
class InstantSpell;
|
|
class ConjureSpell;
|
|
class RuneSpell;
|
|
class Spell;
|
|
|
|
typedef std::map<uint16_t, bool> VocSpellMap;
|
|
|
|
class Spells final : public BaseEvents
|
|
{
|
|
public:
|
|
Spells();
|
|
~Spells();
|
|
|
|
// non-copyable
|
|
Spells(const Spells&) = delete;
|
|
Spells& operator=(const Spells&) = delete;
|
|
|
|
Spell* getSpellByName(const std::string& name);
|
|
RuneSpell* getRuneSpell(uint32_t id);
|
|
RuneSpell* getRuneSpellByName(const std::string& name);
|
|
|
|
InstantSpell* getInstantSpell(const std::string& words);
|
|
InstantSpell* getInstantSpellByName(const std::string& name);
|
|
|
|
uint32_t getInstantSpellCount(const Player* player) const;
|
|
InstantSpell* getInstantSpellByIndex(const Player* player, uint32_t index);
|
|
|
|
TalkActionResult_t playerSaySpell(Player* player, std::string& words);
|
|
|
|
static Position getCasterPosition(Creature* creature, Direction dir);
|
|
std::string getScriptBaseName() const override;
|
|
|
|
protected:
|
|
void clear() final;
|
|
LuaScriptInterface& getScriptInterface() final;
|
|
Event* getEvent(const std::string& nodeName) final;
|
|
bool registerEvent(Event* event, const pugi::xml_node& node) final;
|
|
|
|
std::map<uint16_t, RuneSpell*> runes;
|
|
std::map<std::string, InstantSpell*> instants;
|
|
|
|
friend class CombatSpell;
|
|
LuaScriptInterface scriptInterface { "Spell Interface" };
|
|
};
|
|
|
|
typedef bool (InstantSpellFunction)(const InstantSpell* spell, Creature* creature, const std::string& param);
|
|
typedef bool (RuneSpellFunction)(const RuneSpell* spell, Player* player, const Position& posTo);
|
|
|
|
class BaseSpell
|
|
{
|
|
public:
|
|
constexpr BaseSpell() = default;
|
|
virtual ~BaseSpell() = default;
|
|
|
|
virtual bool castSpell(Creature* creature) = 0;
|
|
virtual bool castSpell(Creature* creature, Creature* target) = 0;
|
|
};
|
|
|
|
class CombatSpell final : public Event, public BaseSpell
|
|
{
|
|
public:
|
|
CombatSpell(Combat* combat, bool needTarget, bool needDirection);
|
|
~CombatSpell();
|
|
|
|
// non-copyable
|
|
CombatSpell(const CombatSpell&) = delete;
|
|
CombatSpell& operator=(const CombatSpell&) = delete;
|
|
|
|
bool castSpell(Creature* creature) override;
|
|
bool castSpell(Creature* creature, Creature* target) override;
|
|
bool configureEvent(const pugi::xml_node&) override {
|
|
return true;
|
|
}
|
|
|
|
//scripting
|
|
bool executeCastSpell(Creature* creature, const LuaVariant& var);
|
|
|
|
bool loadScriptCombat();
|
|
Combat* getCombat() {
|
|
return combat;
|
|
}
|
|
|
|
protected:
|
|
std::string getScriptEventName() const override {
|
|
return "onCastSpell";
|
|
}
|
|
|
|
Combat* combat;
|
|
|
|
bool needDirection;
|
|
bool needTarget;
|
|
};
|
|
|
|
class Spell : public BaseSpell
|
|
{
|
|
public:
|
|
Spell() = default;
|
|
|
|
bool configureSpell(const pugi::xml_node& node);
|
|
const std::string& getName() const {
|
|
return name;
|
|
}
|
|
|
|
void postCastSpell(Player* player, bool finishedSpell = true, bool payCost = true) const;
|
|
static void postCastSpell(Player* player, uint32_t manaCost, uint32_t soulCost);
|
|
|
|
uint32_t getManaCost(const Player* player) const;
|
|
uint32_t getSoulCost() const {
|
|
return soul;
|
|
}
|
|
uint32_t getLevel() const {
|
|
return level;
|
|
}
|
|
uint32_t getMagicLevel() const {
|
|
return magLevel;
|
|
}
|
|
uint32_t getManaPercent() const {
|
|
return manaPercent;
|
|
}
|
|
bool isPremium() const {
|
|
return premium;
|
|
}
|
|
|
|
virtual bool isInstant() const = 0;
|
|
bool isLearnable() const {
|
|
return learnable;
|
|
}
|
|
|
|
static ReturnValue CreateIllusion(Creature* creature, const Outfit_t& outfit, int32_t time);
|
|
static ReturnValue CreateIllusion(Creature* creature, const std::string& name, int32_t time);
|
|
static ReturnValue CreateIllusion(Creature* creature, uint32_t itemId, int32_t time);
|
|
|
|
const VocSpellMap& getVocMap() const {
|
|
return vocSpellMap;
|
|
}
|
|
|
|
protected:
|
|
bool playerSpellCheck(Player* player) const;
|
|
bool playerInstantSpellCheck(Player* player, const Position& toPos);
|
|
bool playerRuneSpellCheck(Player* player, const Position& toPos);
|
|
|
|
uint8_t spellId = 0;
|
|
|
|
uint32_t mana = 0;
|
|
uint32_t manaPercent = 0;
|
|
uint32_t soul = 0;
|
|
uint32_t cooldown = 0;
|
|
uint32_t level = 0;
|
|
uint32_t magLevel = 0;
|
|
int32_t range = -1;
|
|
|
|
bool needTarget = false;
|
|
bool needWeapon = false;
|
|
bool selfTarget = false;
|
|
bool blockingSolid = false;
|
|
bool blockingCreature = false;
|
|
bool aggressive = true;
|
|
bool learnable = false;
|
|
bool enabled = true;
|
|
bool premium = false;
|
|
|
|
VocSpellMap vocSpellMap;
|
|
|
|
private:
|
|
std::string name;
|
|
};
|
|
|
|
class InstantSpell : public TalkAction, public Spell
|
|
{
|
|
public:
|
|
explicit InstantSpell(LuaScriptInterface* interface) : TalkAction(interface) {}
|
|
|
|
bool configureEvent(const pugi::xml_node& node) override;
|
|
bool loadFunction(const pugi::xml_attribute& attr) override;
|
|
|
|
virtual bool playerCastInstant(Player* player, std::string& param);
|
|
|
|
bool castSpell(Creature* creature) override;
|
|
bool castSpell(Creature* creature, Creature* target) override;
|
|
|
|
//scripting
|
|
bool executeCastSpell(Creature* creature, const LuaVariant& var);
|
|
|
|
bool isInstant() const override {
|
|
return true;
|
|
}
|
|
bool getHasParam() const {
|
|
return hasParam;
|
|
}
|
|
bool getHasPlayerNameParam() const {
|
|
return hasPlayerNameParam;
|
|
}
|
|
bool canCast(const Player* player) const;
|
|
bool canThrowSpell(const Creature* creature, const Creature* target) const;
|
|
|
|
protected:
|
|
std::string getScriptEventName() const override;
|
|
|
|
static InstantSpellFunction HouseGuestList;
|
|
static InstantSpellFunction HouseSubOwnerList;
|
|
static InstantSpellFunction HouseDoorList;
|
|
static InstantSpellFunction HouseKick;
|
|
static InstantSpellFunction SearchPlayer;
|
|
static InstantSpellFunction SummonMonster;
|
|
static InstantSpellFunction Levitate;
|
|
static InstantSpellFunction Illusion;
|
|
|
|
static House* getHouseFromPos(Creature* creature);
|
|
|
|
bool internalCastSpell(Creature* creature, const LuaVariant& var);
|
|
|
|
InstantSpellFunction* function = nullptr;
|
|
|
|
bool needDirection = false;
|
|
bool hasParam = false;
|
|
bool hasPlayerNameParam = false;
|
|
bool checkLineOfSight = true;
|
|
bool casterTargetOrDirection = false;
|
|
};
|
|
|
|
class ConjureSpell final : public InstantSpell
|
|
{
|
|
public:
|
|
explicit ConjureSpell(LuaScriptInterface* interface) : InstantSpell(interface) {
|
|
aggressive = false;
|
|
}
|
|
|
|
bool configureEvent(const pugi::xml_node& node) final;
|
|
bool loadFunction(const pugi::xml_attribute& attr) final;
|
|
|
|
bool playerCastInstant(Player* player, std::string& param) final;
|
|
|
|
bool castSpell(Creature*) final {
|
|
return false;
|
|
}
|
|
bool castSpell(Creature*, Creature*) final {
|
|
return false;
|
|
}
|
|
|
|
protected:
|
|
std::string getScriptEventName() const final;
|
|
|
|
bool conjureItem(Creature* creature) const;
|
|
|
|
uint32_t conjureId = 0;
|
|
uint32_t conjureCount = 1;
|
|
uint32_t reagentId = 0;
|
|
};
|
|
|
|
class RuneSpell final : public Action, public Spell
|
|
{
|
|
public:
|
|
explicit RuneSpell(LuaScriptInterface* interface) : Action(interface) {}
|
|
|
|
bool configureEvent(const pugi::xml_node& node) final;
|
|
bool loadFunction(const pugi::xml_attribute& attr) final;
|
|
|
|
ReturnValue canExecuteAction(const Player* player, const Position& toPos) final;
|
|
bool hasOwnErrorHandler() final {
|
|
return true;
|
|
}
|
|
Thing* getTarget(Player*, Creature* targetCreature, const Position&, uint8_t) const final {
|
|
return targetCreature;
|
|
}
|
|
|
|
bool executeUse(Player* player, Item* item, const Position& fromPosition, Thing* target, const Position& toPosition, bool isHotkey) override;
|
|
|
|
bool castSpell(Creature* creature) final;
|
|
bool castSpell(Creature* creature, Creature* target) final;
|
|
|
|
//scripting
|
|
bool executeCastSpell(Creature* creature, const LuaVariant& var, bool isHotkey);
|
|
|
|
bool isInstant() const final {
|
|
return false;
|
|
}
|
|
uint16_t getRuneItemId() const {
|
|
return runeId;
|
|
}
|
|
|
|
protected:
|
|
std::string getScriptEventName() const final;
|
|
|
|
static RuneSpellFunction Illusion;
|
|
static RuneSpellFunction Convince;
|
|
|
|
bool internalCastSpell(Creature* creature, const LuaVariant& var, bool isHotkey);
|
|
|
|
RuneSpellFunction* runeFunction = nullptr;
|
|
uint16_t runeId = 0;
|
|
bool hasCharges = true;
|
|
};
|
|
|
|
#endif
|