1 /*
2  * Copyright (C) 2004-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  */
19 
20 #ifndef WL_ECONOMY_ROAD_H
21 #define WL_ECONOMY_ROAD_H
22 
23 #include "base/macros.h"
24 #include "economy/roadbase.h"
25 #include "logic/path.h"
26 
27 namespace Widelands {
28 class Request;
29 
30 class RoadDescr : public RoadBaseDescr {
31 public:
RoadDescr(char const * const init_name,char const * const init_descname)32 	explicit RoadDescr(char const* const init_name, char const* const init_descname)
33 	   : RoadBaseDescr(init_name, init_descname, MapObjectType::ROAD) {
34 	}
~RoadDescr()35 	~RoadDescr() override {
36 	}
37 
38 private:
39 	DISALLOW_COPY_AND_ASSIGN(RoadDescr);
40 };
41 
42 // C++11 allows static constexpr members in the compiler, but the linker can't handle it.
43 // So, we don't have these in the class.
44 // https://stackoverflow.com/questions/40690260/undefined-reference-error-for-static-constexpr-member
45 constexpr int32_t kRoadAnimalPrice = 600;
46 constexpr int32_t kRoadMaxWallet = static_cast<int32_t>(2.5 * kRoadAnimalPrice);
47 /**
48  * Every Road has one or more Carriers attached to it. Carriers are attached
49  * when they arrive via the callback function passed to the request. The
50  * callback then calls assign_carrier which incorporates this carrier on this
51  * Road.
52  */
53 struct Road : public RoadBase {
54 	friend class MapRoaddataPacket;  // For saving
55 	friend class MapRoadPacket;      // For init()
56 
57 	static bool is_road_descr(MapObjectDescr const*);
58 
59 	explicit Road();
60 	~Road() override;
61 
62 	static Road& create(EditorGameBase&, Flag& start, Flag& end, const Path&);
63 
64 	// A CarrierSlot can store a carrier.
65 	struct CarrierSlot {
66 		CarrierSlot();
67 
68 		OPtr<Carrier> carrier;
69 		Request* carrier_request;
70 		bool second_carrier;
71 	};
72 
73 	void postsplit(Game&, Flag&) override;
74 
75 	void update_wallet_chargetime(Game& game);
76 	void charge_wallet(Game& game);
77 	int32_t wallet() const;
78 	void add_to_wallet(int32_t sum);
79 	void pay_for_road(Game& game, uint8_t wares_count);
80 	void pay_for_building();
81 
82 	void set_economy(Economy*, WareWorker) override;
83 
84 	bool notify_ware(Game& game, FlagId flag) override;
85 
86 	void remove_worker(Worker&) override;
87 	void assign_carrier(Carrier&, uint8_t) override;
88 
89 	void log_general_info(const EditorGameBase&) const override;
90 
is_busyRoad91 	bool is_busy() const {
92 		return busy_;
93 	}
94 
95 	// Use in the editor or from Lua scripting only!
96 	void set_busy(EditorGameBase& e, bool);
97 
98 protected:
99 	bool is_bridge(const EditorGameBase&, const FCoords&, uint8_t) const override;
100 	RoadSegment road_type_for_drawing() const override;
101 
102 private:
103 	void cleanup(EditorGameBase&) override;
104 
105 	void link_into_flags(EditorGameBase&, bool = false) override;
106 
107 	bool busy_;
108 	/// Counter that is incremented when a ware does not get a carrier for this
109 	/// road immediately and decremented over time.
110 	int32_t wallet_;
111 
112 	/// holds the gametime when wallet_ was last charged
113 	uint32_t last_wallet_charge_;
114 
115 	void request_carrier(CarrierSlot&);
116 	static void
117 	request_carrier_callback(Game&, Request&, DescriptionIndex, Worker*, PlayerImmovable&);
118 
119 	uint8_t carriers_count() const;
120 
121 	using SlotVector = std::vector<CarrierSlot>;
122 	SlotVector carrier_slots_;
123 };
124 }  // namespace Widelands
125 
126 #endif  // end of include guard: WL_ECONOMY_ROAD_H
127