/*
* Copyright (C) 2002-2025 by the Widelands Development Team
*
* 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, see .
*
*/
#ifndef WL_ECONOMY_REQUEST_H
#define WL_ECONOMY_REQUEST_H
#include "base/times.h"
#include "economy/trackptr.h"
#include "logic/map_objects/tribes/requirements.h"
#include "logic/map_objects/tribes/wareworker.h"
#include "logic/widelands.h"
namespace Widelands {
class Economy;
struct Flag;
class Game;
struct PlayerImmovable;
class RequestList;
struct Supply;
struct Transfer;
class Worker;
class Building;
class ProductionSite;
class Warehouse;
class ConstructionSite;
/**
* A Request is issued whenever some object (road or building) needs a ware.
*
* Requests are always created and destroyed by their owner, i.e. the target
* player immovable. The owner is also responsible for calling set_economy()
* when its economy changes.
*
* Idle Requests need not be fulfilled; however, when there's a matching Supply
* left, a transfer may be initiated.
* The required time has no meaning for idle requests.
*/
class Request : public Trackable {
public:
friend class Economy;
friend class RequestList;
using CallbackFn = void (*)(Game&, Request&, DescriptionIndex, Worker*, PlayerImmovable&);
using TransferList = std::vector;
Request(PlayerImmovable& target, DescriptionIndex, CallbackFn, WareWorker);
~Request() override;
[[nodiscard]] PlayerImmovable& target() const {
return target_;
}
[[nodiscard]] DescriptionIndex get_index() const {
return index_;
}
[[nodiscard]] WareWorker get_type() const {
return type_;
}
[[nodiscard]] Quantity get_count() const {
return count_;
}
[[nodiscard]] uint32_t get_open_count() const {
return count_ - transfers_.size();
}
[[nodiscard]] bool get_exact_match() const {
return exact_match_;
}
[[nodiscard]] bool is_open() const {
return transfers_.size() < count_;
}
[[nodiscard]] Economy* get_economy() const {
return economy_;
}
[[nodiscard]] Time get_required_time() const;
[[nodiscard]] const Time& get_last_request_time() const {
return last_request_time_;
}
[[nodiscard]] uint32_t get_priority(int32_t cost) const;
[[nodiscard]] uint32_t get_normalized_transfer_priority() const;
[[nodiscard]] uint32_t get_num_transfers() const {
return transfers_.size();
}
[[nodiscard]] const TransferList& get_transfers() const {
return transfers_;
}
[[nodiscard]] Flag& target_flag() const;
void set_economy(Economy*);
void set_count(Quantity);
void set_exact_match(bool match);
void set_required_time(const Time& time);
void set_required_interval(const Duration& interval);
void set_last_request_time(const Time& time) {
last_request_time_ = time;
}
void start_transfer(Game&, Supply&);
void read(FileRead&, Game&, MapObjectLoader&);
void write(FileWrite&, Game&, MapObjectSaver&) const;
Worker* get_transfer_worker();
// callbacks for WareInstance/Worker code
void transfer_finish(Game&, Transfer&);
void transfer_fail(Game&, Transfer&);
void cancel_transfer(uint32_t idx);
void set_requirements(const Requirements& r) {
requirements_ = r;
}
[[nodiscard]] const Requirements& get_requirements() const {
return requirements_;
}
private:
[[nodiscard]] Time get_base_required_time(const EditorGameBase&, uint32_t nr) const;
void remove_transfer(uint32_t idx);
uint32_t find_transfer(Transfer&);
WareWorker type_;
PlayerImmovable& target_; // who requested it?
// Copies of target_ of various pointer types, to avoid expensive
// dynamic casting at runtime. Variables with an incompatible type
// are filled with nulls.
Building* target_building_;
ProductionSite* target_productionsite_;
Warehouse* target_warehouse_;
ConstructionSite* target_constructionsite_;
Economy* economy_;
DescriptionIndex index_; // the index of the ware descr
Quantity count_{1}; // how many do we need in total
bool exact_match_{false}; // Whether a worker supply has to match exactly
// or if a can_act_as() comparison is good enough
CallbackFn callbackfn_; // called on request success
// when do we need the first ware (can be in the past)
Time required_time_;
Duration required_interval_{0U}; // time between wares
Time last_request_time_;
TransferList transfers_; // maximum size is count_
Requirements requirements_;
};
} // namespace Widelands
#endif // end of include guard: WL_ECONOMY_REQUEST_H