1/**
2 * The Forgotten Server - a free and open-source MMORPG server emulator
3 * Copyright (C) 2019 Mark Samman <mark.samman@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#ifndef FS_ACTIONS_H_87F60C5F587E4B84948F304A6451E6E6
21#define FS_ACTIONS_H_87F60C5F587E4B84948F304A6451E6E6
22
23#include "baseevents.h"
24#include "enums.h"
25#include "luascript.h"
26
27class Action;
28using Action_ptr = std::unique_ptr<Action>;
29using ActionFunction = std::function<bool(Player* player, Item* item, const Position& fromPosition, Thing* target, const Position& toPosition, bool isHotkey)>;
30
31class Action : public Event
32{
33 public:
34 explicit Action(LuaScriptInterface* interface);
35
36 bool configureEvent(const pugi::xml_node& node) override;
37 bool loadFunction(const pugi::xml_attribute& attr, bool isScripted) override;
38
39 //scripting
40 virtual bool executeUse(Player* player, Item* item, const Position& fromPosition,
41 Thing* target, const Position& toPosition, bool isHotkey);
42
43 bool getAllowFarUse() const {
44 return allowFarUse;
45 }
46 void setAllowFarUse(bool v) {
47 allowFarUse = v;
48 }
49
50 bool getCheckLineOfSight() const {
51 return checkLineOfSight;
52 }
53 void setCheckLineOfSight(bool v) {
54 checkLineOfSight = v;
55 }
56
57 bool getCheckFloor() const {
58 return checkFloor;
59 }
60 void setCheckFloor(bool v) {
61 checkFloor = v;
62 }
63
64 std::vector<uint16_t> getItemIdRange() {
65 return ids;
66 }
67 void addItemId(uint16_t id) {
68 ids.emplace_back(id);
69 }
70
71 std::vector<uint16_t> getUniqueIdRange() {
72 return uids;
73 }
74 void addUniqueId(uint16_t id) {
75 uids.emplace_back(id);
76 }
77
78 std::vector<uint16_t> getActionIdRange() {
79 return aids;
80 }
81 void addActionId(uint16_t id) {
82 aids.emplace_back(id);
83 }
84
85 virtual ReturnValue canExecuteAction(const Player* player, const Position& toPos);
86 virtual bool hasOwnErrorHandler() {
87 return false;
88 }
89 virtual Thing* getTarget(Player* player, Creature* targetCreature, const Position& toPosition, uint8_t toStackPos) const;
90
91 ActionFunction function;
92
93 private:
94 std::string getScriptEventName() const override;
95
96 bool allowFarUse = false;
97 bool checkFloor = true;
98 bool checkLineOfSight = true;
99 std::vector<uint16_t> ids;
100 std::vector<uint16_t> uids;
101 std::vector<uint16_t> aids;
102};
103
104class Actions final : public BaseEvents
105{
106 public:
107 Actions();
108 ~Actions();
109
110 // non-copyable
111 Actions(const Actions&) = delete;
112 Actions& operator=(const Actions&) = delete;
113
114 bool useItem(Player* player, const Position& pos, uint8_t index, Item* item, bool isHotkey);
115 bool useItemEx(Player* player, const Position& fromPos, const Position& toPos, uint8_t toStackPos, Item* item, bool isHotkey, Creature* creature = nullptr);
116
117 ReturnValue canUse(const Player* player, const Position& pos);
118 ReturnValue canUse(const Player* player, const Position& pos, const Item* item);
119 ReturnValue canUseFar(const Creature* creature, const Position& toPos, bool checkLineOfSight, bool checkFloor);
120
121 bool registerLuaEvent(Action* event);
122 void clear(bool fromLua) override final;
123
124 private:
125 ReturnValue internalUseItem(Player* player, const Position& pos, uint8_t index, Item* item, bool isHotkey);
126 static void showUseHotkeyMessage(Player* player, const Item* item, uint32_t count);
127
128 LuaScriptInterface& getScriptInterface() override;
129 std::string getScriptBaseName() const override;
130 Event_ptr getEvent(const std::string& nodeName) override;
131 bool registerEvent(Event_ptr event, const pugi::xml_node& node) override;
132
133 using ActionUseMap = std::map<uint16_t, Action>;
134 ActionUseMap useItemMap;
135 ActionUseMap uniqueItemMap;
136 ActionUseMap actionItemMap;
137
138 Action* getAction(const Item* item);
139 void clearMap(ActionUseMap& map, bool fromLua);
140
141 LuaScriptInterface scriptInterface;
142};
143
144#endif
145