Client Upload Part 2

RD Core / Commit #5

Commit Client Upload Part 2

Alex Alex committed 19/10/2026 00:06 main Patch
1,244 files +271,215 -0
A RD_Client/src/client/declarations.h +125-0 View file
@@ -0,0 +1,125 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef CLIENT_DECLARATIONS_H
24+#define CLIENT_DECLARATIONS_H
25+
26+#include "global.h"
27+#include <framework/net/declarations.h>
28+#include <framework/ui/declarations.h>
29+
30+// core
31+class Map;
32+class Game;
33+class MapView;
34+class LightView;
35+class Tile;
36+class Thing;
37+class Item;
38+class Container;
39+class Creature;
40+class Monster;
41+class Npc;
42+class Player;
43+class LocalPlayer;
44+class Effect;
45+class Missile;
46+class AnimatedText;
47+class StaticText;
48+class Animator;
49+class ThingType;
50+class ItemType;
51+class House;
52+class Town;
53+class CreatureType;
54+class Spawn;
55+class TileBlock;
56+
57+typedef stdext::shared_object_ptr<MapView> MapViewPtr;
58+typedef stdext::shared_object_ptr<LightView> LightViewPtr;
59+typedef stdext::shared_object_ptr<Tile> TilePtr;
60+typedef stdext::shared_object_ptr<Thing> ThingPtr;
61+typedef stdext::shared_object_ptr<Item> ItemPtr;
62+typedef stdext::shared_object_ptr<Container> ContainerPtr;
63+typedef stdext::shared_object_ptr<Creature> CreaturePtr;
64+typedef stdext::shared_object_ptr<Monster> MonsterPtr;
65+typedef stdext::shared_object_ptr<Npc> NpcPtr;
66+typedef stdext::shared_object_ptr<Player> PlayerPtr;
67+typedef stdext::shared_object_ptr<LocalPlayer> LocalPlayerPtr;
68+typedef stdext::shared_object_ptr<Effect> EffectPtr;
69+typedef stdext::shared_object_ptr<Missile> MissilePtr;
70+typedef stdext::shared_object_ptr<AnimatedText> AnimatedTextPtr;
71+typedef stdext::shared_object_ptr<StaticText> StaticTextPtr;
72+typedef stdext::shared_object_ptr<Animator> AnimatorPtr;
73+typedef stdext::shared_object_ptr<ThingType> ThingTypePtr;
74+typedef stdext::shared_object_ptr<ItemType> ItemTypePtr;
75+typedef stdext::shared_object_ptr<House> HousePtr;
76+typedef stdext::shared_object_ptr<Town> TownPtr;
77+typedef stdext::shared_object_ptr<CreatureType> CreatureTypePtr;
78+typedef stdext::shared_object_ptr<Spawn> SpawnPtr;
79+
80+typedef std::vector<ThingPtr> ThingList;
81+typedef std::vector<ThingTypePtr> ThingTypeList;
82+typedef std::vector<ItemTypePtr> ItemTypeList;
83+typedef std::list<HousePtr> HouseList;
84+typedef std::list<TownPtr> TownList;
85+typedef std::list<ItemPtr> ItemList;
86+typedef std::list<TilePtr> TileList;
87+typedef std::vector<ItemPtr> ItemVector;
88+typedef std::unordered_map<Position, TilePtr, PositionHasher> TileMap;
89+typedef std::unordered_map<Position, CreatureTypePtr, PositionHasher> CreatureMap;
90+typedef std::unordered_map<Position, SpawnPtr, PositionHasher> SpawnMap;
91+
92+// net
93+class ProtocolLogin;
94+class ProtocolGame;
95+
96+typedef stdext::shared_object_ptr<ProtocolGame> ProtocolGamePtr;
97+typedef stdext::shared_object_ptr<ProtocolLogin> ProtocolLoginPtr;
98+
99+// ui
100+class UIItem;
101+class UICreature;
102+class UIGraph;
103+class UIMap;
104+class UIMinimap;
105+class UIProgressRect;
106+class UIMapAnchorLayout;
107+class UIPositionAnchor;
108+class UISprite;
109+
110+typedef stdext::shared_object_ptr<UIItem> UIItemPtr;
111+typedef stdext::shared_object_ptr<UICreature> UICreaturePtr;
112+typedef stdext::shared_object_ptr<UIGraph> UIGraphPtr;
113+typedef stdext::shared_object_ptr<UISprite> UISpritePtr;
114+typedef stdext::shared_object_ptr<UIMap> UIMapPtr;
115+typedef stdext::shared_object_ptr<UIMinimap> UIMinimapPtr;
116+typedef stdext::shared_object_ptr<UIProgressRect> UIProgressRectPtr;
117+typedef stdext::shared_object_ptr<UIMapAnchorLayout> UIMapAnchorLayoutPtr;
118+typedef stdext::shared_object_ptr<UIPositionAnchor> UIPositionAnchorPtr;
119+
120+// custom
121+class HealthBar;
122+
123+typedef stdext::shared_object_ptr<HealthBar> HealthBarPtr;
124+
125+#endif
A RD_Client/src/client/effect.cpp +98-0 View file
@@ -0,0 +1,98 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#include "effect.h"
24+#include "map.h"
25+#include "game.h"
26+#include <framework/core/eventdispatcher.h>
27+#include <framework/util/extras.h>
28+
29+void Effect::draw(const Point& dest, int offsetX, int offsetY, bool animate, LightView* lightView)
30+{
31+ if(m_id == 0)
32+ return;
33+
34+ if(animate) {
35+ if(g_game.getFeature(Otc::GameEnhancedAnimations) && rawGetThingType()->getAnimator()) {
36+ // This requires a separate getPhaseAt method as using getPhase would make all magic effects use the same phase regardless of their appearance time
37+ m_animationPhase = std::max<int>(0, rawGetThingType()->getAnimator()->getPhaseAt(m_animationTimer, m_animationPhase));
38+ } else {
39+ // hack to fix some animation phases duration, currently there is no better solution
40+ int ticks = EFFECT_TICKS_PER_FRAME;
41+ if (m_id == 33) {
42+ ticks <<= 2;
43+ }
44+
45+ m_animationPhase = std::max<int>(0, std::min<int>((int)(m_animationTimer.ticksElapsed() / ticks), getAnimationPhases() - 1));
46+ }
47+ }
48+
49+ int xPattern = m_position.x % getNumPatternX();
50+ if(xPattern < 0)
51+ xPattern += getNumPatternX();
52+
53+ int yPattern = m_position.y % getNumPatternY();
54+ if(yPattern < 0)
55+ yPattern += getNumPatternY();
56+
57+ rawGetThingType()->draw(dest, 0, xPattern, yPattern, 0, m_animationPhase, Color::white, lightView);
58+}
59+
60+void Effect::onAppear()
61+{
62+ m_animationTimer.restart();
63+
64+ int duration = 0;
65+ if(g_game.getFeature(Otc::GameEnhancedAnimations)) {
66+ duration = getThingType()->getAnimator() ? getThingType()->getAnimator()->getTotalDuration() : 1000;
67+ } else {
68+ duration = EFFECT_TICKS_PER_FRAME;
69+
70+ // hack to fix some animation phases duration, currently there is no better solution
71+ if(m_id == 33) {
72+ duration <<= 2;
73+ }
74+
75+ duration *= getAnimationPhases();
76+ }
77+
78+ // schedule removal
79+ auto self = asEffect();
80+ g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, duration);
81+}
82+
83+void Effect::setId(uint32 id)
84+{
85+ if(!g_things.isValidDatId(id, ThingCategoryEffect))
86+ id = 0;
87+ m_id = id;
88+}
89+
90+const ThingTypePtr& Effect::getThingType()
91+{
92+ return g_things.getThingType(m_id, ThingCategoryEffect);
93+}
94+
95+ThingType *Effect::rawGetThingType()
96+{
97+ return g_things.rawGetThingType(m_id, ThingCategoryEffect);
98+}
A RD_Client/src/client/effect.h +59-0 View file
@@ -0,0 +1,59 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef EFFECT_H
24+#define EFFECT_H
25+
26+#include <framework/global.h>
27+#include <framework/core/timer.h>
28+#include "thing.h"
29+
30+// @bindclass
31+class Effect : public Thing
32+{
33+ enum {
34+ EFFECT_TICKS_PER_FRAME = 75
35+ };
36+
37+public:
38+ void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr) override {}
39+ void draw(const Point& dest, int offsetX = 0, int offsetY = 0, bool animate = true, LightView* lightView = nullptr);
40+
41+ void setId(uint32 id) override;
42+ uint32 getId() override { return m_id; }
43+
44+ EffectPtr asEffect() { return static_self_cast<Effect>(); }
45+ bool isEffect() override { return true; }
46+
47+ const ThingTypePtr& getThingType() override;
48+ ThingType *rawGetThingType() override;
49+
50+protected:
51+ void onAppear() override;
52+
53+private:
54+ uint16 m_id;
55+ Timer m_animationTimer;
56+ int m_animationPhase = 0;
57+};
58+
59+#endif
A RD_Client/src/client/game.h +484-0 View file
@@ -0,0 +1,484 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef GAME_H
24+#define GAME_H
25+
26+#include "declarations.h"
27+#include "item.h"
28+#include "animatedtext.h"
29+#include "effect.h"
30+#include "creature.h"
31+#include "container.h"
32+#include "protocolgame.h"
33+#include "localplayer.h"
34+#include "outfit.h"
35+#include <framework/core/timer.h>
36+
37+#include <bitset>
38+
39+struct UnjustifiedPoints {
40+ bool operator==(const UnjustifiedPoints& other) const {
41+ return killsDay == other.killsDay &&
42+ killsDayRemaining == other.killsDayRemaining &&
43+ killsWeek == other.killsWeek &&
44+ killsWeekRemaining == other.killsWeekRemaining &&
45+ killsMonth == other.killsMonth &&
46+ killsMonthRemaining == other.killsMonthRemaining &&
47+ skullTime == other.skullTime;
48+ }
49+ uint8 killsDay;
50+ uint8 killsDayRemaining;
51+ uint8 killsWeek;
52+ uint8 killsWeekRemaining;
53+ uint8 killsMonth;
54+ uint8 killsMonthRemaining;
55+ uint8 skullTime;
56+};
57+
58+typedef std::tuple<std::string, uint, std::string, int, bool> Vip;
59+
60+//@bindsingleton g_game
61+class Game
62+{
63+public:
64+ Game();
65+
66+ void init();
67+ void terminate();
68+
69+private:
70+ void resetGameStates();
71+
72+protected:
73+ void processConnectionError(const boost::system::error_code& error);
74+ void processDisconnect();
75+ void processPing();
76+ void processPingBack();
77+ void processNewPing(uint32_t pingId);
78+
79+ void processUpdateNeeded(const std::string& signature);
80+ void processLoginError(const std::string& error);
81+ void processLoginAdvice(const std::string& message);
82+ void processLoginWait(const std::string& message, int time);
83+ void processLoginToken(bool unknown);
84+ void processLogin();
85+ void processPendingGame();
86+ void processEnterGame();
87+
88+ void processGameStart();
89+ void processGameEnd();
90+ void processDeath(int deathType, int penality);
91+
92+ void processGMActions(const std::vector<uint8>& actions);
93+ void processInventoryChange(int slot, const ItemPtr& item);
94+ void processAttackCancel(uint seq);
95+ void processWalkCancel(Otc::Direction direction);
96+
97+ void processNewWalkCancel(Otc::Direction dir);
98+ void processPredictiveWalkCancel(const Position& pos, Otc::Direction dir);
99+ void processWalkId(uint32_t walkId);
100+
101+ void processPlayerHelpers(int helpers);
102+ void processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode, Otc::PVPModes pvpMode);
103+
104+ // message related
105+ void processTextMessage(Otc::MessageMode mode, const std::string& text);
106+ void processTalk(const std::string& name, int level, Otc::MessageMode mode, const std::string& text, int channelId, const Position& pos);
107+
108+ // container related
109+ void processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items, bool isUnlocked, bool hasPages, int containerSize, int firstIndex);
110+ void processCloseContainer(int containerId);
111+ void processContainerAddItem(int containerId, const ItemPtr& item, int slot);
112+ void processContainerUpdateItem(int containerId, int slot, const ItemPtr& item);
113+ void processContainerRemoveItem(int containerId, int slot, const ItemPtr& lastItem);
114+
115+ // channel related
116+ void processChannelList(const std::vector<std::tuple<int, std::string> >& channelList);
117+ void processOpenChannel(int channelId, const std::string& name);
118+ void processOpenPrivateChannel(const std::string& name);
119+ void processOpenOwnPrivateChannel(int channelId, const std::string& name);
120+ void processCloseChannel(int channelId);
121+
122+ // rule violations
123+ void processRuleViolationChannel(int channelId);
124+ void processRuleViolationRemove(const std::string& name);
125+ void processRuleViolationCancel(const std::string& name);
126+ void processRuleViolationLock();
127+
128+ // vip related
129+ void processVipAdd(uint id, const std::string& name, uint status, const std::string& description, int iconId, bool notifyLogin);
130+ void processVipStateChange(uint id, uint status);
131+
132+ // tutorial hint
133+ void processTutorialHint(int id);
134+ void processAddAutomapFlag(const Position& pos, int icon, const std::string& message);
135+ void processRemoveAutomapFlag(const Position& pos, int icon, const std::string& message);
136+
137+ // outfit
138+ void processOpenOutfitWindow(const Outfit& currentOutfit, const std::vector<std::tuple<int, std::string, int>>& outfitList,
139+ const std::vector<std::tuple<int, std::string>>& mountList,
140+ const std::vector<std::tuple<int, std::string>>& wingList,
141+ const std::vector<std::tuple<int, std::string>>& auraList,
142+ const std::vector<std::tuple<int, std::string>>& shaderList,
143+ const std::vector<std::tuple<int, std::string>>& healthBarList,
144+ const std::vector<std::tuple<int, std::string>>& manaBarList);
145+
146+ // npc trade
147+ void processOpenNpcTrade(const std::vector<std::tuple<ItemPtr, std::string, int, int64_t, int64_t> >& items);
148+ void processPlayerGoods(uint64_t money, const std::vector<std::tuple<ItemPtr, int> >& goods);
149+ void processCloseNpcTrade();
150+
151+ // player trade
152+ void processOwnTrade(const std::string& name, const std::vector<ItemPtr>& items);
153+ void processCounterTrade(const std::string& name, const std::vector<ItemPtr>& items);
154+ void processCloseTrade();
155+
156+ // edit text/list
157+ void processEditText(uint id, int itemId, int maxLength, const std::string& text, const std::string& writer, const std::string& date);
158+ void processEditList(uint id, int doorId, const std::string& text);
159+
160+ // questlog
161+ void processQuestLog(const std::vector<std::tuple<int, std::string, bool> >& questList);
162+ void processQuestLine(int questId, const std::vector<std::tuple<std::string, std::string, int> >& questMissions);
163+
164+ // modal dialogs >= 970
165+ void processModalDialog(uint32 id, std::string title, std::string message, std::vector<std::tuple<int, std::string> > buttonList, int enterButton, int escapeButton, std::vector<std::tuple<int, std::string> > choiceList, bool priority);
166+
167+ friend class ProtocolGame;
168+ friend class Map;
169+
170+public:
171+ // login related
172+ void loginWorld(const std::string& account, const std::string& password, const std::string& worldName, const std::string& worldHost, int worldPort, const std::string& characterName, const std::string& authenticatorToken, const std::string& sessionKey, const std::string& recordTo = "");
173+ void playRecord(const std::string& file);
174+ void cancelLogin();
175+ void forceLogout();
176+ void safeLogout();
177+
178+ // walk related
179+ void walk(Otc::Direction direction, bool withPreWalk);
180+ void autoWalk(const std::vector<Otc::Direction>& dirs, Position startPos);
181+ void turn(Otc::Direction direction);
182+ void stop();
183+
184+ // item related
185+ void look(const ThingPtr& thing, bool isBattleList = false);
186+ void move(const ThingPtr& thing, const Position& toPos, int count);
187+ void moveRaw(const Position& pos, int id, int stackpos, const Position& toPos, int count);
188+ void moveToParentContainer(const ThingPtr& thing, int count);
189+ void rotate(const ThingPtr& thing);
190+ void wrap(const ThingPtr& thing);
191+ void use(const ThingPtr& thing);
192+ void useWith(const ItemPtr& fromThing, const ThingPtr& toThing, int subType = 0);
193+ void useInventoryItem(int itemId, int subType = 0);
194+ void useInventoryItemWith(int itemId, const ThingPtr& toThing, int subType = 0);
195+ ItemPtr findItemInContainers(uint itemId, int subType);
196+
197+ // container related
198+ int open(const ItemPtr& item, const ContainerPtr& previousContainer);
199+ void openParent(const ContainerPtr& container);
200+ void close(const ContainerPtr& container);
201+ void refreshContainer(const ContainerPtr& container);
202+
203+ // attack/follow related
204+ void attack(CreaturePtr creature, bool cancel = false);
205+ void cancelAttack() { attack(nullptr, true); }
206+ void follow(CreaturePtr creature);
207+ void cancelFollow() { follow(nullptr); }
208+ void cancelAttackAndFollow();
209+
210+ // talk related
211+ void talk(const std::string& message);
212+ void talkChannel(Otc::MessageMode mode, int channelId, const std::string& message);
213+ void talkPrivate(Otc::MessageMode mode, const std::string& receiver, const std::string& message);
214+
215+ // channel related
216+ void openPrivateChannel(const std::string& receiver);
217+ void requestChannels();
218+ void joinChannel(int channelId);
219+ void leaveChannel(int channelId);
220+ void closeNpcChannel();
221+ void openOwnChannel();
222+ void inviteToOwnChannel(const std::string& name);
223+ void excludeFromOwnChannel(const std::string& name);
224+
225+ // party related
226+ void partyInvite(int creatureId);
227+ void partyJoin(int creatureId);
228+ void partyRevokeInvitation(int creatureId);
229+ void partyPassLeadership(int creatureId);
230+ void partyLeave();
231+ void partyShareExperience(bool active);
232+
233+ // outfit related
234+ void requestOutfit();
235+ void changeOutfit(const Outfit& outfit);
236+
237+ // vip related
238+ void addVip(const std::string& name);
239+ void removeVip(int playerId);
240+ void editVip(int playerId, const std::string& description, int iconId, bool notifyLogin);
241+
242+ // fight modes related
243+ void setChaseMode(Otc::ChaseModes chaseMode);
244+ void setFightMode(Otc::FightModes fightMode);
245+ void setSafeFight(bool on);
246+ void setPVPMode(Otc::PVPModes pvpMode);
247+ Otc::ChaseModes getChaseMode() { return m_chaseMode; }
248+ Otc::FightModes getFightMode() { return m_fightMode; }
249+ bool isSafeFight() { return m_safeFight; }
250+ Otc::PVPModes getPVPMode() { return m_pvpMode; }
251+
252+ // pvp related
253+ void setUnjustifiedPoints(UnjustifiedPoints unjustifiedPoints);
254+ UnjustifiedPoints getUnjustifiedPoints() { return m_unjustifiedPoints; };
255+ void setOpenPvpSituations(int openPvpSitations);
256+ int getOpenPvpSituations() { return m_openPvpSituations; }
257+
258+ // npc trade related
259+ void inspectNpcTrade(const ItemPtr& item);
260+ void buyItem(const ItemPtr& item, int amount, bool ignoreCapacity, bool buyWithBackpack);
261+ void sellItem(const ItemPtr& item, int amount, bool ignoreEquipped);
262+ void closeNpcTrade();
263+
264+ // player trade related
265+ void requestTrade(const ItemPtr& item, const CreaturePtr& creature);
266+ void inspectTrade(bool counterOffer, int index);
267+ void acceptTrade();
268+ void rejectTrade();
269+
270+ // house window and editable items related
271+ void editText(uint id, const std::string& text);
272+ void editList(uint id, int doorId, const std::string& text);
273+
274+ // rule violations (only gms)
275+ void openRuleViolation(const std::string& reporter);
276+ void closeRuleViolation(const std::string& reporter);
277+ void cancelRuleViolation();
278+
279+ // reports
280+ void reportBug(const std::string& comment);
281+ void reportRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment);
282+ void debugReport(const std::string& a, const std::string& b, const std::string& c, const std::string& d);
283+
284+ // questlog related
285+ void requestQuestLog();
286+ void requestQuestLine(int questId);
287+
288+ // 870 only
289+ void equipItem(const ItemPtr& item);
290+ void equipItemId(int itemId, int subType);
291+ void mount(bool mount);
292+ void setOutfitExtensions(int mount, int wings, int aura, int shader, int healthBar, int manaBar);
293+
294+ // 910 only
295+ void requestItemInfo(const ItemPtr& item, int index);
296+
297+ // >= 970 modal dialog
298+ void answerModalDialog(uint32 dialog, int button, int choice);
299+
300+ // >= 984 browse field
301+ void browseField(const Position& position);
302+ void seekInContainer(int cid, int index);
303+
304+ // >= 1080 ingame store
305+ void buyStoreOffer(int offerId, int productType, const std::string& name = "");
306+ void requestTransactionHistory(int page, int entriesPerPage);
307+ void requestStoreOffers(const std::string& categoryName, int serviceType = 0);
308+ void openStore(int serviceType = 0);
309+ void transferCoins(const std::string& recipient, int amount);
310+ void openTransactionHistory(int entriesPerPage);
311+
312+ // >= 1100
313+ void preyAction(int slot, int actionType, int index);
314+ void preyRequest();
315+
316+ void applyImbuement(uint8_t slot, uint32_t imbuementId, bool protectionCharm);
317+ void clearImbuement(uint8_t slot);
318+ void closeImbuingWindow();
319+
320+ //void reportRuleViolation2();
321+ void ping();
322+ void newPing();
323+ void setPingDelay(int delay) { m_pingDelay = delay; }
324+
325+ // otclient only
326+ void changeMapAwareRange(int xrange, int yrange);
327+
328+ // dynamic support for game features
329+ void resetFeatures() { m_features.reset(); }
330+ void enableFeature(Otc::GameFeature feature) { m_features.set(feature, true); }
331+ void disableFeature(Otc::GameFeature feature) { m_features.set(feature, false); }
332+ void setFeature(Otc::GameFeature feature, bool enabled) { m_features.set(feature, enabled); }
333+ bool getFeature(Otc::GameFeature feature) { return m_features.test(feature); }
334+
335+ void setProtocolVersion(int version);
336+ int getProtocolVersion() { return m_protocolVersion; }
337+ void setCustomProtocolVersion(int version) { m_customProtocolVersion = version; }
338+ int getCustomProtocolVersion() { return m_customProtocolVersion != 0 ? m_customProtocolVersion : m_protocolVersion; }
339+
340+ void setClientVersion(int version);
341+ int getClientVersion() { return m_clientVersion; }
342+
343+ void setCustomOs(int os) { m_clientCustomOs = os; }
344+ int getOs();
345+
346+ bool canPerformGameAction();
347+ bool checkBotProtection();
348+
349+ bool isOnline() { return m_online; }
350+ bool isLogging() { return !m_online && m_protocolGame; }
351+ bool isDead() { return m_dead; }
352+ bool isAttacking() { return !!m_attackingCreature && !m_attackingCreature->isRemoved(); }
353+ bool isFollowing() { return !!m_followingCreature && !m_followingCreature->isRemoved(); }
354+ bool isConnectionOk() { return m_protocolGame && m_protocolGame->getElapsedTicksSinceLastRead() < 5000; }
355+
356+ int getPing() { return m_ping; }
357+ ContainerPtr getContainer(int index) { if (m_containers.find(index) == m_containers.end()) { return nullptr; } return m_containers[index]; }
358+ std::map<int, ContainerPtr> getContainers() { return m_containers; }
359+ std::map<int, Vip> getVips() { return m_vips; }
360+ CreaturePtr getAttackingCreature() { return m_attackingCreature; }
361+ CreaturePtr getFollowingCreature() { return m_followingCreature; }
362+ void setServerBeat(int beat) { m_serverBeat = beat; }
363+ int getServerBeat() { return m_serverBeat; }
364+ void setCanReportBugs(bool enable) { m_canReportBugs = enable; }
365+ bool canReportBugs() { return m_canReportBugs; }
366+ void setExpertPvpMode(bool enable) { m_expertPvpMode = enable; }
367+ bool getExpertPvpMode() { return m_expertPvpMode; }
368+ LocalPlayerPtr getLocalPlayer() { return m_localPlayer; }
369+ ProtocolGamePtr getProtocolGame() { return m_protocolGame; }
370+ std::string getCharacterName() { return m_characterName; }
371+ std::string getWorldName() { return m_worldName; }
372+ std::vector<uint8> getGMActions() { return m_gmActions; }
373+ bool isGM() { return m_gmActions.size() > 0; }
374+ Otc::Direction getLastWalkDir() { return m_lastWalkDir; }
375+
376+ std::string formatCreatureName(const std::string &name);
377+ int findEmptyContainerId();
378+
379+ void setTibiaCoins(int coins, int transferableCoins)
380+ {
381+ m_coins = coins;
382+ m_transferableCoins = transferableCoins;
383+ }
384+ int getTibiaCoins()
385+ {
386+ return m_coins;
387+ }
388+ int getTransferableTibiaCoins()
389+ {
390+ return m_transferableCoins;
391+ }
392+
393+ void setMaxPreWalkingSteps(uint value) { m_maxPreWalkingSteps = value; }
394+ uint getMaxPreWalkingSteps() { return m_maxPreWalkingSteps; }
395+
396+ void showRealDirection(bool value) { m_showRealDirection = value; }
397+ bool shouldShowingRealDirection() { return m_showRealDirection; }
398+
399+ uint getWalkId() { return m_walkId; }
400+ uint getWalkPreditionId() { return m_walkPrediction; }
401+
402+ void ignoreServerDirection(bool value) { m_ignoreServerDirection = value; }
403+ bool isIgnoringServerDirection()
404+ {
405+ return m_ignoreServerDirection;
406+ }
407+
408+ void enableTileThingLuaCallback(bool value) { m_tileThingsLuaCallback = value; }
409+ bool isTileThingLuaCallbackEnabled() { return m_tileThingsLuaCallback; }
410+
411+ int getRecivedPacketsCount()
412+ {
413+ return m_protocolGame ? m_protocolGame->getRecivedPacketsCount() : 0;
414+ }
415+
416+ int getRecivedPacketsSize()
417+ {
418+ return m_protocolGame ? m_protocolGame->getRecivedPacketsSize() : 0;
419+ }
420+
421+protected:
422+ void enableBotCall() { m_denyBotCall = false; }
423+ void disableBotCall() { m_denyBotCall = true; }
424+
425+private:
426+ void setAttackingCreature(const CreaturePtr& creature);
427+ void setFollowingCreature(const CreaturePtr& creature);
428+
429+ LocalPlayerPtr m_localPlayer;
430+ CreaturePtr m_attackingCreature;
431+ CreaturePtr m_followingCreature;
432+ ProtocolGamePtr m_protocolGame;
433+ std::map<int, ContainerPtr> m_containers;
434+ std::map<int, Vip> m_vips;
435+
436+ bool m_online;
437+ bool m_denyBotCall;
438+ bool m_dead;
439+ bool m_expertPvpMode;
440+ int m_serverBeat;
441+ ticks_t m_ping;
442+ uint m_pingSent;
443+ uint m_pingReceived;
444+ uint m_walkId = 0;
445+ uint m_walkPrediction = 0;
446+ uint m_maxPreWalkingSteps = 2;
447+ stdext::timer m_pingTimer;
448+ std::map<uint32_t, stdext::timer> m_newPingIds;
449+ uint m_seq;
450+ int m_pingDelay;
451+ int m_newPingDelay;
452+ Otc::FightModes m_fightMode;
453+ Otc::ChaseModes m_chaseMode;
454+ Otc::PVPModes m_pvpMode;
455+ Otc::Direction m_lastWalkDir;
456+ bool m_waitingForAnotherDir = false;
457+ UnjustifiedPoints m_unjustifiedPoints;
458+ int m_openPvpSituations;
459+ bool m_safeFight;
460+ bool m_canReportBugs;
461+ std::vector<uint8> m_gmActions;
462+ std::string m_characterName;
463+ std::string m_worldName;
464+ std::bitset<Otc::LastGameFeature> m_features;
465+ ScheduledEventPtr m_pingEvent;
466+ ScheduledEventPtr m_newPingEvent;
467+ ScheduledEventPtr m_checkConnectionEvent;
468+ bool m_connectionFailWarned;
469+ int m_protocolVersion;
470+ int m_customProtocolVersion = 0;
471+ int m_clientVersion;
472+ std::string m_clientSignature;
473+ int m_clientCustomOs;
474+ int m_coins;
475+ int m_transferableCoins;
476+
477+ bool m_showRealDirection = false;
478+ bool m_ignoreServerDirection = true;
479+ bool m_tileThingsLuaCallback = false;
480+};
481+
482+extern Game g_game;
483+
484+#endif
A RD_Client/src/client/global.h +32-0 View file
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef CLIENT_GLOBAL_H
24+#define CLIENT_GLOBAL_H
25+
26+#include <framework/global.h>
27+
28+// widely used headers
29+#include "const.h"
30+#include "position.h"
31+
32+#endif
A RD_Client/src/client/healthbars.cpp +146-0 View file
@@ -0,0 +1,146 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#include "healthbars.h"
24+
25+#include <framework/graphics/texturemanager.h>
26+
27+HealthBars g_healthBars;
28+
29+void HealthBars::init()
30+{
31+ m_healthBars.reserve(21);
32+ m_healthBars.push_back(nullptr); // 0 = default bar
33+ m_manaBars.reserve(21);
34+ m_manaBars.push_back(nullptr); // 0 = default bar
35+}
36+
37+void HealthBars::terminate()
38+{
39+ m_healthBars.clear();
40+ m_manaBars.clear();
41+}
42+
43+void HealthBars::addHealthBackground(const std::string& path, int offsetX, int offsetY, int barOffsetX, int barOffsetY, int height) {
44+ HealthBarPtr bar(new HealthBar);
45+ bar->setPath(path);
46+ bar->setTexture(path);
47+ bar->setOffset(offsetX, offsetY);
48+ bar->setBarOffset(barOffsetX, barOffsetY);
49+ bar->setHeight(height);
50+ m_healthBars.push_back(bar);
51+}
52+
53+void HealthBars::addManaBackground(const std::string& path, int offsetX, int offsetY, int barOffsetX, int barOffsetY, int height) {
54+ HealthBarPtr bar(new HealthBar);
55+ bar->setPath(path);
56+ bar->setTexture(path);
57+ bar->setOffset(offsetX, offsetY);
58+ bar->setBarOffset(barOffsetX, barOffsetY);
59+ bar->setHeight(height);
60+ m_manaBars.push_back(bar);
61+}
62+
63+std::string HealthBars::getHealthBarPath(int id)
64+{
65+ HealthBarPtr bar = getHealthBar(id);
66+ if (bar) {
67+ return bar->getPath();
68+ }
69+
70+ return std::string();
71+}
72+
73+std::string HealthBars::getManaBarPath(int id)
74+{
75+ HealthBarPtr bar = getManaBar(id);
76+ if (bar) {
77+ return bar->getPath();
78+ }
79+
80+ return std::string();
81+}
82+
83+Point HealthBars::getHealthBarOffset(int id)
84+{
85+ HealthBarPtr bar = getHealthBar(id);
86+ if (bar) {
87+ return bar->getOffset();
88+ }
89+
90+ return Point();
91+}
92+
93+Point HealthBars::getManaBarOffset(int id)
94+{
95+ HealthBarPtr bar = getManaBar(id);
96+ if (bar) {
97+ return bar->getOffset();
98+ }
99+
100+ return Point();
101+}
102+
103+Point HealthBars::getHealthBarOffsetBar(int id)
104+{
105+ HealthBarPtr bar = getHealthBar(id);
106+ if (bar) {
107+ return bar->getBarOffset();
108+ }
109+
110+ return Point();
111+}
112+
113+Point HealthBars::getManaBarOffsetBar(int id)
114+{
115+ HealthBarPtr bar = getManaBar(id);
116+ if (bar) {
117+ return bar->getBarOffset();
118+ }
119+
120+ return Point();
121+}
122+
123+int HealthBars::getHealthBarHeight(int id)
124+{
125+ HealthBarPtr bar = getHealthBar(id);
126+ if (bar) {
127+ return bar->getHeight();
128+ }
129+
130+ return 0;
131+}
132+
133+int HealthBars::getManaBarHeight(int id)
134+{
135+ HealthBarPtr bar = getManaBar(id);
136+ if (bar) {
137+ return bar->getHeight();
138+ }
139+
140+ return 0;
141+}
142+
143+void HealthBar::setTexture(const std::string& path)
144+{
145+ m_texture = g_textures.getTexture(path);
146+}
A RD_Client/src/client/healthbars.h +99-0 View file
@@ -0,0 +1,99 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef HEALTHBARS_H
24+#define HEALTHBARS_H
25+
26+#include "declarations.h"
27+#include <framework/graphics/declarations.h>
28+
29+class HealthBar : public stdext::shared_object
30+{
31+public:
32+ void setPath(const std::string& path) {
33+ m_path = path;
34+ }
35+ std::string getPath() { return m_path; }
36+
37+ void setTexture(const std::string& path);
38+ TexturePtr getTexture() { return m_texture; }
39+
40+ void setOffset(int x, int y) {
41+ m_offset = Point(x, y);
42+ }
43+ Point getOffset() { return m_offset; }
44+
45+ void setBarOffset(int x, int y) {
46+ m_barOffset = Point(x, y);
47+ }
48+ Point getBarOffset() { return m_barOffset; }
49+
50+ void setHeight(int height) {
51+ m_height = height;
52+ }
53+
54+ int getHeight() { return m_height; }
55+
56+private:
57+ std::string m_path;
58+ TexturePtr m_texture;
59+
60+ Point m_offset;
61+ Point m_barOffset;
62+
63+ int m_height;
64+};
65+
66+//@bindsingleton g_healthBars
67+class HealthBars
68+{
69+public:
70+ void init();
71+ void terminate();
72+
73+ void addHealthBackground(const std::string& path, int offsetX, int offsetY, int barOffsetX, int barOffsetY, int height);
74+ void addManaBackground(const std::string& path, int offsetX, int offsetY, int barOffsetX, int barOffsetY, int height);
75+
76+ HealthBarPtr getHealthBar(int id) { return m_healthBars[id]; }
77+ HealthBarPtr getManaBar(int id) { return m_manaBars[id]; }
78+
79+ std::string getHealthBarPath(int id);
80+ std::string getManaBarPath(int id);
81+
82+ Point getHealthBarOffset(int id);
83+ Point getManaBarOffset(int id);
84+
85+ Point getHealthBarOffsetBar(int id);
86+ Point getManaBarOffsetBar(int id);
87+
88+ int getHealthBarHeight(int id);
89+ int getManaBarHeight(int id);
90+
91+private:
92+ std::vector<HealthBarPtr> m_healthBars;
93+ std::vector<HealthBarPtr> m_manaBars;
94+};
95+
96+extern HealthBars g_healthBars;
97+
98+#endif
99+
A RD_Client/src/client/houses.cpp +210-0 View file
@@ -0,0 +1,210 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#include "map.h"
24+
25+#include <framework/core/resourcemanager.h>
26+
27+HouseManager g_houses;
28+
29+House::House()
30+{
31+}
32+
33+House::House(uint32 hId, const std::string &name, const Position &pos)
34+{
35+ setId(hId);
36+ setName(name);
37+ if(pos.isValid())
38+ setEntry(pos);
39+}
40+
41+void House::setTile(const TilePtr& tile)
42+{
43+ tile->setFlag(TILESTATE_HOUSE);
44+ tile->setHouseId(getId());
45+ m_tiles.insert(std::make_pair(tile->getPosition(), tile));
46+}
47+
48+TilePtr House::getTile(const Position& position)
49+{
50+ TileMap::const_iterator iter = m_tiles.find(position);
51+ if(iter != m_tiles.end())
52+ return iter->second;
53+ return nullptr;
54+}
55+
56+void House::addDoor(const ItemPtr& door)
57+{
58+ if (!door) return;
59+ door->setDoorId(m_lastDoorId);
60+ m_doors[m_lastDoorId++] = door;
61+}
62+
63+void House::removeDoorById(uint32 doorId)
64+{
65+ if(doorId >= m_lastDoorId)
66+ stdext::throw_exception(stdext::format("Failed to remove door of id %d (would overflow), max id: %d",
67+ doorId, m_lastDoorId));
68+ m_doors[doorId] = nullptr;
69+}
70+
71+void House::load(const TiXmlElement *elem)
72+{
73+ std::string name = elem->Attribute("name");
74+ if(name.empty())
75+ name = stdext::format("Unnamed house #%lu", getId());
76+
77+ setName(name);
78+ setRent(elem->readType<uint32>("rent"));
79+ setSize(elem->readType<uint32>("size"));
80+ setTownId(elem->readType<uint32>("townid"));
81+ m_isGuildHall = elem->readType<bool>("guildhall");
82+
83+ Position entryPos;
84+ entryPos.x = elem->readType<int>("entryx");
85+ entryPos.y = elem->readType<int>("entryy");
86+ entryPos.z = elem->readType<int>("entryz");
87+ setEntry(entryPos);
88+}
89+
90+void House::save(TiXmlElement* elem)
91+{
92+ elem->SetAttribute("name", getName());
93+ elem->SetAttribute("houseid", getId());
94+
95+ Position entry = getEntry();
96+ elem->SetAttribute("entryx", entry.x);
97+ elem->SetAttribute("entryy", entry.y);
98+ elem->SetAttribute("entryz", entry.z);
99+
100+ elem->SetAttribute("rent", getRent());
101+ elem->SetAttribute("townid", getTownId());
102+ elem->SetAttribute("size", getSize());
103+ elem->SetAttribute("guildhall", (int)m_isGuildHall);
104+}
105+
106+HouseManager::HouseManager()
107+{
108+}
109+
110+void HouseManager::addHouse(const HousePtr& house)
111+{
112+ if(findHouse(house->getId()) == m_houses.end())
113+ m_houses.push_back(house);
114+}
115+
116+void HouseManager::removeHouse(uint32 houseId)
117+{
118+ auto it = findHouse(houseId);
119+ if(it != m_houses.end())
120+ m_houses.erase(it);
121+}
122+
123+HousePtr HouseManager::getHouse(uint32 houseId)
124+{
125+ auto it = findHouse(houseId);
126+ return it != m_houses.end() ? *it : nullptr;
127+}
128+
129+HousePtr HouseManager::getHouseByName(std::string name)
130+{
131+ auto it = std::find_if(m_houses.begin(), m_houses.end(),
132+ [=] (const HousePtr& house) -> bool { return house->getName() == name; });
133+ return it != m_houses.end() ? *it : nullptr;
134+}
135+
136+void HouseManager::load(const std::string& fileName)
137+{
138+ try {
139+ TiXmlDocument doc;
140+ doc.Parse(g_resources.readFileContents(fileName).c_str());
141+ if(doc.Error())
142+ stdext::throw_exception(stdext::format("failed to load '%s': %s (House XML)", fileName, doc.ErrorDesc()));
143+
144+ TiXmlElement *root = doc.FirstChildElement();
145+ if(!root || root->ValueTStr() != "houses")
146+ stdext::throw_exception("invalid root tag name");
147+
148+ for(TiXmlElement *elem = root->FirstChildElement(); elem; elem = elem->NextSiblingElement()) {
149+ if(elem->ValueTStr() != "house")
150+ stdext::throw_exception("invalid house tag.");
151+
152+ uint32 houseId = elem->readType<uint32>("houseid");
153+ HousePtr house = getHouse(houseId);
154+ if(!house)
155+ house = HousePtr(new House(houseId)), addHouse(house);
156+
157+ house->load(elem);
158+ }
159+ } catch(std::exception& e) {
160+ g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what()));
161+ }
162+ sort();
163+}
164+
165+void HouseManager::save(const std::string& fileName)
166+{
167+ try {
168+ TiXmlDocument doc;
169+ doc.SetTabSize(2);
170+
171+ TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
172+ doc.LinkEndChild(decl);
173+
174+ TiXmlElement* root = new TiXmlElement("houses");
175+ doc.LinkEndChild(root);
176+
177+ for(auto house : m_houses) {
178+ TiXmlElement *elem = new TiXmlElement("house");
179+ house->save(elem);
180+ root->LinkEndChild(elem);
181+ }
182+
183+ if(!doc.SaveFile("data"+fileName))
184+ stdext::throw_exception(stdext::format("failed to save houses XML %s: %s", fileName, doc.ErrorDesc()));
185+ } catch(std::exception& e) {
186+ g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what()));
187+ }
188+}
189+
190+HouseList HouseManager::filterHouses(uint32 townId)
191+{
192+ HouseList ret;
193+ for(const HousePtr& house : m_houses)
194+ if(house->getTownId() == townId)
195+ ret.push_back(house);
196+ return ret;
197+}
198+
199+HouseList::iterator HouseManager::findHouse(uint32 houseId)
200+{
201+ return std::find_if(m_houses.begin(), m_houses.end(),
202+ [=] (const HousePtr& house) -> bool { return house->getId() == houseId; });
203+}
204+
205+void HouseManager::sort()
206+{
207+ m_houses.sort([] (const HousePtr& lhs, const HousePtr& rhs) { return lhs->getName() < rhs->getName(); });
208+}
209+
210+/* vim: set ts=4 sw=4 et: */
Top