1 /*
2  * Copyright (c) 1997 - 2001 Hansj�rg Malthaner
3  *
4  * This file is part of the Simutrans project under the artistic license.
5  * (see license.txt)
6  */
7 
8 #ifndef simfab_h
9 #define simfab_h
10 
11 #include "dataobj/koord3d.h"
12 #include "dataobj/translator.h"
13 
14 #include "tpl/slist_tpl.h"
15 #include "tpl/vector_tpl.h"
16 #include "tpl/array_tpl.h"
17 #include "descriptor/factory_desc.h"
18 #include "halthandle_t.h"
19 #include "simworld.h"
20 #include "utils/plainstring.h"
21 
22 
23 class player_t;
24 class stadt_t;
25 class ware_t;
26 class leitung_t;
27 
28 
29 /**
30  * Factory statistics
31  * @author Knightly
32  */
33 #define MAX_MONTH                  (12)
34 #define FAB_PRODUCTION              (0)
35 #define FAB_POWER                   (1)
36 #define FAB_BOOST_ELECTRIC          (2)
37 #define FAB_BOOST_PAX               (3)
38 #define FAB_BOOST_MAIL              (4)
39 #define FAB_PAX_GENERATED           (5)
40 #define FAB_PAX_DEPARTED            (6)
41 #define FAB_PAX_ARRIVED             (7)
42 #define FAB_MAIL_GENERATED          (8)
43 #define FAB_MAIL_DEPARTED           (9)
44 #define FAB_MAIL_ARRIVED           (10)
45 #define MAX_FAB_STAT               (11)
46 
47 // reference lines
48 #define FAB_REF_MAX_BOOST_ELECTRIC  (0)
49 #define FAB_REF_MAX_BOOST_PAX       (1)
50 #define FAB_REF_MAX_BOOST_MAIL      (2)
51 #define FAB_REF_DEMAND_ELECTRIC     (3)
52 #define FAB_REF_DEMAND_PAX          (4)
53 #define FAB_REF_DEMAND_MAIL         (5)
54 #define MAX_FAB_REF_LINE            (6)
55 
56 // statistics for goods
57 #define MAX_FAB_GOODS_STAT          (4)
58 // common to both input and output goods
59 #define FAB_GOODS_STORAGE           (0)
60 // input goods
61 #define FAB_GOODS_RECEIVED          (1)
62 #define FAB_GOODS_CONSUMED          (2)
63 #define FAB_GOODS_TRANSIT           (3)
64 // output goods
65 #define FAB_GOODS_DELIVERED         (1)
66 #define FAB_GOODS_PRODUCED          (2)
67 
68 
69 // production happens in every second
70 #define PRODUCTION_DELTA_T_BITS (10)
71 #define PRODUCTION_DELTA_T (1 << PRODUCTION_DELTA_T_BITS)
72 // default production factor
73 #define DEFAULT_PRODUCTION_FACTOR_BITS (8)
74 #define DEFAULT_PRODUCTION_FACTOR (1 << DEFAULT_PRODUCTION_FACTOR_BITS)
75 // precision of apportioned demand (i.e. weights of factories at target cities)
76 #define DEMAND_BITS (4)
77 
78 /**
79  * JIT2 output scale constants.
80  */
81 // The fixed point precision for work done fraction.
82 static const uint32 WORK_BITS = 16;
83 // The minimum allowed production rate for a factory. This is to limit the time outputs take to fill completly (so factories idle sooner).
84 // Fixed point form range must be between 0.0 and 1.0.
85 static const sint32 WORK_SCALE_MINIMUM_FRACTION = (5 << WORK_BITS) / 100; // ~5%, 1/20 of the full production rate.
86 // The number of times minimum_shipment must be in current storage before rampdown starts.
87 // Must be at least 2 to allow for full production as shipment is not instant.
88 static const sint32 OUTPUT_SCALE_RAMPDOWN_MULTIPLYER = 2; // Two shipments must be ready.
89 // The maximum rate at which power boost change change per second.
90 // This limit is required to help stiffen overloaded networks to combat oscilations caused by feedback.
91 static const sint32 BOOST_POWER_CHANGE_RATE = (5 << DEFAULT_PRODUCTION_FACTOR_BITS) / 100; // ~5%
92 
93 
94 /**
95  * Shipment size constants.
96  */
97 // The maximum shipment size in whole units.
98 // Must be greater than 0.
99 static const uint32 SHIPMENT_MAX_SIZE = 10; // Traditional value.
100 // The minimum number of whole shipments a facotry can store.
101 // Must be greater than 0 to prevent division by 0.
102 static const uint32 SHIPMENT_NUM_MIN = 4; // Quarters should allow reasonably fair distribution.
103 
104 
105 /**
106  * Convert internal values to displayed values
107  */
108 sint64 convert_goods(sint64 value);
109 sint64 convert_power(sint64 value);
110 sint64 convert_boost(sint64 value);
111 
112 class ware_production_t
113 {
114 private:
115 	const goods_desc_t *type;
116 	// Knightly : statistics for each goods
117 	sint64 statistics[MAX_MONTH][MAX_FAB_GOODS_STAT];
118 	sint64 weighted_sum_storage;
119 
120 	/// clears statistics, transit, and weighted_sum_storage
121 	void init_stats();
122 public:
ware_production_t()123 	ware_production_t() : type(NULL), menge(0), max(0)/*, transit(statistics[0][FAB_GOODS_TRANSIT])*/,
124 	                      max_transit(0), placing_orders(false), index_offset(0)
125 	{
126 #ifdef TRANSIT_DISTANCE
127 		count_suppliers = 0;
128 #endif
129 		init_stats();
130 	}
131 
get_typ()132 	const goods_desc_t* get_typ() const { return type; }
set_typ(const goods_desc_t * t)133 	void set_typ(const goods_desc_t *t) { type=t; }
134 
135 	// Knightly : functions for manipulating goods statistics
136 	void roll_stats(uint32 factor, sint64 aggregate_weight);
137 	void rdwr(loadsave_t *file);
get_stats()138 	const sint64* get_stats() const { return *statistics; }
book_stat(sint64 value,int stat_type)139 	void book_stat(sint64 value, int stat_type) { assert(stat_type<MAX_FAB_GOODS_STAT); statistics[0][stat_type] += value; }
set_stat(sint64 value,int stat_type)140 	void set_stat(sint64 value, int stat_type) { assert(stat_type<MAX_FAB_GOODS_STAT); statistics[0][stat_type] = value; }
get_stat(int month,int stat_type)141 	sint64 get_stat(int month, int stat_type) const { assert(stat_type<MAX_FAB_GOODS_STAT); return statistics[month][stat_type]; }
142 
143 	/**
144 	 * convert internal units to displayed values
145 	 */
get_stat_converted(int month,int stat_type)146 	sint64 get_stat_converted(int month, int stat_type) const {
147 		assert(stat_type<MAX_FAB_GOODS_STAT);
148 		sint64 value = statistics[month][stat_type];
149 		if (stat_type==FAB_GOODS_STORAGE  ||  stat_type==FAB_GOODS_CONSUMED) {
150 			value = convert_goods(value);
151 		}
152 		return value;
153 	}
154 	void book_weighted_sum_storage(uint32 factor, sint64 delta_time);
155 
156 	sint32 menge;	// in internal units shifted by precision_bits (see step)
157 	sint32 max;
158 	/// Cargo currently in transit from/to this slot. Equivalent to statistics[0][FAB_GOODS_TRANSIT].
get_in_transit()159 	sint32 get_in_transit() const { return (sint32)statistics[0][FAB_GOODS_TRANSIT]; }
160 
161 	/// Annonmyous union used to save memory and readability. Contains supply flow control limiters.
162 	union{
163 		// Classic : Current limit on cargo in transit (maximum network capacity), depending on sum of all supplier output storage.
164 		sint32 max_transit; //JIT<2 Input
165 
166 		// JIT Version 2 : Current demand for the good. Orders when greater than 0.
167 		sint32 demand_buffer; //JIT2 Input
168 
169 		// The minimum shipment size. Used to control delivery to stops and for production ramp-down.
170 		sint32 min_shipment; // Output
171 	};
172 
173 	// Ordering lasts at least 1 tick period to allow all suppliers time to send (fair). Used by inputs.
174 	bool placing_orders;
175 
176 #ifdef TRANSIT_DISTANCE
177 	sint32 count_suppliers;	// only needed for averaging
178 #endif
179 	uint32 index_offset; // used for haltlist and lieferziele searches in verteile_waren to produce round robin results
180 
181 	// Production rate for outputs. Returns fixed point with WORK_BITS fractional bits.
182 	sint32 calculate_output_production_rate() const;
183 
184 	// Production rate for JIT2 demands. Returns fixed point with WORK_BITS fractional bits.
185 	sint32 calculate_demand_production_rate() const;
186 };
187 
188 
189 /**
190  * Eine Klasse f�r Fabriken in Simutrans. Fabriken produzieren und
191  * verbrauchen Waren und beliefern nahe Haltestellen.
192  *
193  * @date 1998
194  * @see haltestelle_t
195  * @author Hj. Malthaner
196  */
197 class fabrik_t
198 {
199 public:
200 	/**
201 	 * Constants
202 	 * @author Hj. Malthaner
203 	 */
204 	enum { precision_bits = 10, old_precision_bits = 10, precision_mask = 1023 };
205 
206 private:
207 	/**
208 	 * Factory statistics
209 	 * @author Knightly
210 	 */
211 	sint64 statistics[MAX_MONTH][MAX_FAB_STAT];
212 	sint64 weighted_sum_production;
213 	sint64 weighted_sum_boost_electric;
214 	sint64 weighted_sum_boost_pax;
215 	sint64 weighted_sum_boost_mail;
216 	sint64 weighted_sum_power;
217 	sint64 aggregate_weight;
218 
219 	// Control logic type determines how a factory behaves with regards to inputs and outputs.
220 	enum CL_TYPE {
221 		CL_NONE,         // This factory does nothing! (might be useful for scenarios)
222 		// Producers are at the bottom of every supply chain.
223 		CL_PROD_CLASSIC, // Classic producer logic.
224 		CL_PROD_MANY,    // Producer of many outputs.
225 		// Factories are in the middle of every supply chain.
226 		CL_FACT_CLASSIC, // Classic factory logic, consume at maximum output rate or minimum input.
227 		CL_FACT_MANY,    // Enhanced factory logic, consume at average of output rate or minimum input averaged.
228 		// Consumers are at the top of every supply chain.
229 		CL_CONS_CLASSIC, // Classic consumer logic. Can generate power.
230 		CL_CONS_MANY,    // Consumer that consumes multiple inputs, possibly produces power.
231 		// Electricity producers provide power.
232 		CL_ELEC_PROD,    // Simple electricity source. (green energy)
233 		CL_ELEC_CLASSIC, // Classic electricity producer behaviour with no inputs.
234 	} control_type;
235 
236 	// Demand buffer order logic;
237 	enum DL_TYPE {
238 		DL_NONE,    // Has no inputs to demand.
239 		DL_SYNC,    // All inputs ordered together.
240 		DL_ASYNC,   // All inputs ordered separatly.
241 		DL_OLD      // Use maximum in-transit and storage to determine demand.
242 	} demand_type;
243 
244 	// Boost logic determines what factors boost factory production.
245 	enum BL_TYPE {
246 		BL_NONE,    // Production cannot be boosted.
247 		BL_PAXM,    // Production boosted only using passengers/mail.
248 		BL_POWER,   // Production boosted with power as well. Needs aditional logic for correct ordering.
249 		BL_CLASSIC, // Production boosted in classic way.
250 	} boost_type;
251 
252 	// Knightly : Functions for manipulating factory statistics
253 	void init_stats();
set_stat(sint64 value,int stat_type)254 	void set_stat(sint64 value, int stat_type) { assert(stat_type<MAX_FAB_STAT); statistics[0][stat_type] = value; }
255 
256 	// Knightly : For accumulating weighted sums for average statistics
257 	void book_weighted_sums(sint64 delta_time);
258 
259 	/**
260 	 * Die m�glichen Lieferziele
261 	 * @author Hj. Malthaner
262 	 */
263 	vector_tpl <koord> lieferziele;
264 	uint32 lieferziele_active_last_month;
265 
266 	/**
267 	 * suppliers to this factory
268 	 * @author hsiegeln
269 	 */
270 	vector_tpl <koord> suppliers;
271 
272 	/**
273 	 * fields of this factory (only for farms etc.)
274 	 * @author prissi/Knightly
275 	 */
276 	struct field_data_t
277 	{
278 		koord location;
279 		uint16 field_class_index;
280 
field_data_tfield_data_t281 		field_data_t() : field_class_index(0) {}
field_data_tfield_data_t282 		explicit field_data_t(const koord loc) : location(loc), field_class_index(0) {}
field_data_tfield_data_t283 		field_data_t(const koord loc, const uint16 class_index) : location(loc), field_class_index(class_index) {}
284 
285 		bool operator==(const field_data_t &other) const { return location==other.location; }
286 	};
287 	vector_tpl <field_data_t> fields;
288 
289 	/**
290 	 * Distribute products to connected stops
291 	 * @author Hj. Malthaner
292 	 */
293 	void verteile_waren(const uint32 product);
294 
295 	// List of target cities
296 	vector_tpl<stadt_t *> target_cities;
297 
298 	player_t *owner;
299 	static karte_ptr_t welt;
300 
301 	const factory_desc_t *desc;
302 
303 	/**
304 	 * Is construction site rotated?
305 	 * @author V.Meyer
306 	 */
307 	uint8 rotate;
308 
309 	/**
310 	 * production base amount
311 	 * @author Hj. Malthaner
312 	 */
313 	sint32 prodbase;
314 
315 	/**
316 	 * multipliers for the production base amount
317 	 * @author Hj. Malthaner
318 	 */
319 	sint32 prodfactor_electric;
320 	sint32 prodfactor_pax;
321 	sint32 prodfactor_mail;
322 
323 	array_tpl<ware_production_t> input;  ///< array for input/consumed goods
324 	array_tpl<ware_production_t> output; ///< array for output/produced goods
325 
326 	/**
327 	 * Zeitakkumulator f�r Produktion
328 	 * @author Hj. Malthaner
329 	 */
330 	sint32 delta_sum;
331 	uint32 delta_menge;
332 
333 	// production remainder when scaled to PRODUCTION_DELTA_T. added back next step to eliminate cumulative error
334 	uint32 menge_remainder;
335 
336 	// Knightly : number of rounds where there is active production or consumption
337 	uint8 activity_count;
338 
339 	// The adjacent connected transformer, if any.
340 	leitung_t *transformer;
341 
342 	// true, if the factory did produce enough in the last step to require power
343 	bool currently_producing;
344 
345 	uint32 last_sound_ms;
346 
347 	uint32 total_input, total_transit, total_output;
348 	uint8 status;
349 
350 	/**
351 	 * Inactive caches, used to speed up logic when dealing with inputs and outputs.
352 	 */
353 	uint8 inactive_outputs;
354 	uint8 inactive_inputs;
355 	uint8 inactive_demands;
356 
357 	/// Position of a building of the factory.
358 	koord3d pos;
359 
360 	/// Position of the nw-corner tile of the factory.
361 	koord3d pos_origin;
362 
363 	/**
364 	 * Number of times the factory has expanded so far
365 	 * Only for factories without fields
366 	 * @author Knightly
367 	 */
368 	uint16 times_expanded;
369 
370 	/**
371 	 * Electricity amount scaled with prodbase
372 	 * @author TurfIt
373 	 */
374 	uint32 scaled_electric_demand;
375 
376 	/**
377 	 * Pax/mail demand scaled with prodbase and month length
378 	 * @author Knightly
379 	 */
380 	uint32 scaled_pax_demand;
381 	uint32 scaled_mail_demand;
382 
383 	/**
384 	 * Update scaled electricity amount
385 	 * @author TurfIt
386 	 */
387 	void update_scaled_electric_demand();
388 
389 	/**
390 	 * Update scaled pax/mail demand
391 	 * @author Knightly
392 	 */
393 	void update_scaled_pax_demand();
394 	void update_scaled_mail_demand();
395 
396 	/**
397 	 * Update production multipliers for pax and mail
398 	 * @author Knightly
399 	 */
400 	void update_prodfactor_pax();
401 	void update_prodfactor_mail();
402 
403 	/**
404 	 * Re-calculate the pax/mail demands of factory at target cities
405 	 * @author Knightly
406 	 */
407 	void recalc_demands_at_target_cities();
408 
409 	/**
410 	 * Recalculate storage capacities based on prodbase or capacities contributed by fields
411 	 * @author Knightly
412 	 */
413 	void recalc_storage_capacities();
414 
415 	/**
416 	 * Class for collecting arrival data and calculating pax/mail boost with fixed period length
417 	 * @author Knightly
418 	 */
419 	#define PERIOD_BITS   (18)				// determines period length on which boost calculation is based
420 	#define SLOT_BITS     (6)				// determines the number of time slots available
421 	#define SLOT_COUNT    (1<<SLOT_BITS)	// number of time slots for accumulating arrived pax/mail
422 	class arrival_statistics_t
423 	{
424 	private:
425 		uint16 slots[SLOT_COUNT];
426 		uint16 current_slot;
427 		uint16 active_slots;		// number of slots covered since aggregate arrival last increased from 0 to +ve
428 		uint32 aggregate_arrival;
429 		uint32 scaled_demand;
430 	public:
431 		void init();
432 		void rdwr(loadsave_t *file);
set_scaled_demand(const uint32 demand)433 		void set_scaled_demand(const uint32 demand) { scaled_demand = demand; }
434 		#define ARRIVALS_CHANGED (1)
435 		#define ACTIVE_SLOTS_INCREASED (2)
436 		sint32 advance_slot();
437 		void book_arrival(const uint16 amount);
get_active_slots()438 		uint16 get_active_slots() const { return active_slots; }
get_aggregate_arrival()439 		uint32 get_aggregate_arrival() const { return aggregate_arrival; }
get_scaled_demand()440 		uint32 get_scaled_demand() const { return scaled_demand; }
441 	};
442 
443 	void update_transit_intern( const ware_t *ware, bool add );
444 
445 	/**
446 	 * Arrival data for calculating pax/mail boost
447 	 * @author Knightly
448 	 */
449 	arrival_statistics_t arrival_stats_pax;
450 	arrival_statistics_t arrival_stats_mail;
451 
452 	plainstring name;
453 
454 	/**
455 	 * For advancement of slots for boost calculation
456 	 * @author Knightly
457 	 */
458 	sint32 delta_slot;
459 
460 	void recalc_factory_status();
461 
462 	// create some smoke on the map
463 	void smoke() const;
464 
465 	// scales the amount of production based on the amount already in storage
466 	uint32 scale_output_production(const uint32 product, uint32 menge) const;
467 
468 	/**
469 	 * Convenience method that deals with casting.
470 	 */
471 	void set_power_supply(uint32 supply);
472 
473 	/**
474 	 * Convenience method that deals with casting.
475 	 */
476 	uint32 get_power_supply() const;
477 
478 	/**
479 	 * Convenience method that deals with casting.
480 	 */
481 	sint32 get_power_consumption() const;
482 
483 	/**
484 	 * Convenience method that deals with casting.
485 	 */
486 	void set_power_demand(uint32 demand);
487 
488 	/**
489 	 * Convenience method that deals with casting.
490 	 */
491 	uint32 get_power_demand() const;
492 
493 	/**
494 	 * Convenience method that deals with casting.
495 	 */
496 	sint32 get_power_satisfaction() const;
497 
498 	/**
499 	 *
500 	 */
501 	 sint64 get_power() const;
502 
503 public:
504 	fabrik_t(loadsave_t *file);
505 	fabrik_t(koord3d pos, player_t* owner, const factory_desc_t* factory_desc, sint32 initial_prod_base);
506 	~fabrik_t();
507 
508 	/**
509 	 * Return/book statistics
510 	 * @author Knightly
511 	 */
get_stats()512 	const sint64* get_stats() const { return *statistics; }
get_stat(int month,int stat_type)513 	sint64 get_stat(int month, int stat_type) const { assert(stat_type<MAX_FAB_STAT); return statistics[month][stat_type]; }
book_stat(sint64 value,int stat_type)514 	void book_stat(sint64 value, int stat_type) { assert(stat_type<MAX_FAB_STAT); statistics[0][stat_type] += value; }
515 
516 	// This updates maximum in-transit. Important for loading.
517 	static void update_transit( const ware_t *ware, bool add );
518 
519 	// This updates transit stats for freshly produced goods. Includes logic to decrement demand counters.
520 	static void apply_transit( const ware_t *ware );
521 
522 	/**
523 	 * convert internal units to displayed values
524 	 */
get_stat_converted(int month,int stat_type)525 	sint64 get_stat_converted(int month, int stat_type) const {
526 		assert(stat_type<MAX_FAB_STAT);
527 		sint64 value = statistics[month][stat_type];
528 		switch(stat_type) {
529 			case FAB_POWER:
530 				value = convert_power(value);
531 				break;
532 			case FAB_BOOST_ELECTRIC:
533 			case FAB_BOOST_PAX:
534 			case FAB_BOOST_MAIL:
535 				value = convert_boost(value);
536 				break;
537 			default: ;
538 		}
539 		return value;
540 	}
541 
542 	static fabrik_t * get_fab(const koord &pos);
543 
544 	/**
545 	 * @return vehicle description object
546 	 * @author Hj. Malthaner
547 	 */
get_desc()548 	const factory_desc_t *get_desc() const {return desc; }
549 
550 	void finish_rd();
551 
552 	/// gets position of a building belonging to factory
get_pos()553 	koord3d get_pos() const { return pos; }
554 
555 	void rotate90( const sint16 y_size );
556 
557 	void link_halt(halthandle_t halt);
558 	void unlink_halt(halthandle_t halt);
559 
get_lieferziele()560 	const vector_tpl<koord>& get_lieferziele() const { return lieferziele; }
561 	bool is_active_lieferziel( koord k ) const;
562 
get_suppliers()563 	const vector_tpl<koord>& get_suppliers() const { return suppliers; }
564 
565 	/**
566 	 * Functions for manipulating the list of connected cities
567 	 * @author Hj. Malthaner/prissi/Knightly
568 	 */
569 	void add_target_city(stadt_t *const city);
570 	void remove_target_city(stadt_t *const city);
571 	void clear_target_cities();
get_target_cities()572 	const vector_tpl<stadt_t *>& get_target_cities() const { return target_cities; }
573 
574 	/**
575 	 * F�gt ein neues Lieferziel hinzu
576 	 * @author Hj. Malthaner
577 	 */
578 	void  add_lieferziel(koord ziel);
579 	void  rem_lieferziel(koord pos);
580 
581 	/**
582 	 * adds a supplier
583 	 * @author Hj. Malthaner
584 	 */
585 	void  add_supplier(koord pos);
586 	void  rem_supplier(koord pos);
587 
588 	/**
589 	 * @return menge der ware typ
590 	 *   -1 wenn typ nicht produziert wird
591 	 *   sonst die gelagerte menge
592 	 */
593 	sint32 input_vorrat_an(const goods_desc_t *ware);        // Vorrat von Warentyp
594 	sint32 vorrat_an(const goods_desc_t *ware);        // Vorrat von Warentyp
595 
596 	// true, if there was production requiring power in the last step
is_currently_producing()597 	bool is_currently_producing() const { return currently_producing; }
598 
599 	/**
600 	 * True if a transformer is connected to this factory.
601 	 */
is_transformer_connected()602 	bool is_transformer_connected() const { return transformer != NULL; }
603 
604 	/**
605 	 * Connect transformer to this factory.
606 	 */
set_transformer_connected(leitung_t * transformer)607 	void set_transformer_connected(leitung_t *transformer) { this->transformer = transformer; }
608 
609 	/**
610 	 * @return 1 wenn consumption,
611 	 * 0 wenn Produktionsstopp,
612 	 * -1 wenn Ware nicht verarbeitet wird
613 	 */
614 	sint8 is_needed(const goods_desc_t *) const;
615 
616 	sint32 liefere_an(const goods_desc_t *, sint32 menge);
617 
618 	/**
619 	 * Calculate the JIT2 logic power boost amount using the currently attached transformer.
620 	 */
621 	sint32 get_jit2_power_boost() const;
622 
623 	void step(uint32 delta_t);                  // factory muss auch arbeiten
624 	void new_month();
625 
626 	char const* get_name() const;
627 	void set_name( const char *name );
628 
get_color()629 	PIXVAL get_color() const { return desc->get_color(); }
630 
get_owner()631 	player_t *get_owner() const
632 	{
633 		grund_t const* const p = welt->lookup(pos);
634 		return p ? p->first_obj()->get_owner() : 0;
635 	}
636 
637 	void open_info_window();
638 
639 	// infostring on production
640 	void info_prod(cbuffer_t& buf) const;
641 
642 	// infostring on targets/sources
643 	void info_conn(cbuffer_t& buf) const;
644 
645 	void rdwr(loadsave_t *file);
646 
647 	/*
648 	 * Fills the vector with the koords of the tiles.
649 	 */
650 	void get_tile_list( vector_tpl<koord> &tile_list ) const;
651 
652 	/**
653 	 * gibt eine NULL-Terminierte Liste von Fabrikpointern zur�ck
654 	 *
655 	 * @author Hj. Malthaner
656 	 */
657 	static vector_tpl<fabrik_t *> & sind_da_welche(koord min, koord max);
658 
659 
660 	// hier die methoden zum parametrisieren der Fabrik
661 
662 	/**
663 	 * Baut die Geb�ude f�r die Fabrik
664 	 *
665 	 * @author Hj. Malthaner, V. Meyer
666 	 */
667 	void build(sint32 rotate, bool build_fields, bool force_initial_prodbase);
668 
get_rotate()669 	sint16 get_rotate() const { return rotate; }
670 
671 	/* field generation code
672 	 * spawns a field for sure if probability>=1000
673 	 * @author Kieron Green
674 	 */
675 	bool add_random_field(uint16 probability);
676 
677 	void remove_field_at(koord pos);
678 
get_field_count()679 	uint32 get_field_count() const { return fields.get_count(); }
680 
681 	/**
682 	 * total and current procduction/storage values
683 	 * @author Hj. Malthaner
684 	 */
get_input()685 	const array_tpl<ware_production_t>& get_input() const { return input; }
get_output()686 	const array_tpl<ware_production_t>& get_output() const { return output; }
687 
688 	/**
689 	 * Production multipliers
690 	 * @author Hj. Malthaner
691 	 */
get_prodfactor_electric()692 	sint32 get_prodfactor_electric() const { return prodfactor_electric; }
get_prodfactor_pax()693 	sint32 get_prodfactor_pax() const { return prodfactor_pax; }
get_prodfactor_mail()694 	sint32 get_prodfactor_mail() const { return prodfactor_mail; }
get_prodfactor()695 	sint32 get_prodfactor() const { return DEFAULT_PRODUCTION_FACTOR + prodfactor_electric + prodfactor_pax + prodfactor_mail; }
696 
697 	/* does not takes month length into account */
get_base_production()698 	sint32 get_base_production() const { return prodbase; }
699 	void set_base_production(sint32 p);
700 
get_current_production()701 	sint32 get_current_production() const { return (sint32)welt->scale_with_month_length( ((sint64)prodbase * (sint64)get_prodfactor())>>8 ); }
702 
703 	/* prissi: returns the status of the current factory, as well as output */
704 	enum { bad, medium, good, inactive, nothing };
705 	static uint8 status_to_color[5];
706 
get_status()707 	uint8  get_status() const { return status; }
get_total_in()708 	uint32 get_total_in() const { return total_input; }
get_total_transit()709 	uint32 get_total_transit() const { return total_transit; }
get_total_out()710 	uint32 get_total_out() const { return total_output; }
711 
712 	/**
713 	 * Crossconnects all factories
714 	 * @author prissi
715 	 */
716 	void add_all_suppliers();
717 
718 	/* adds a new supplier to this factory
719 	 * fails if no matching goods are there
720 	 */
721 	bool add_supplier(fabrik_t* fab);
722 
723 	/**
724 	 * Return the scaled electricity amount and pax/mail demand
725 	 * @author Knightly
726 	 */
get_scaled_electric_demand()727 	uint32 get_scaled_electric_demand() const { return scaled_electric_demand; }
get_scaled_pax_demand()728 	uint32 get_scaled_pax_demand() const { return scaled_pax_demand; }
get_scaled_mail_demand()729 	uint32 get_scaled_mail_demand() const { return scaled_mail_demand; }
730 
is_end_consumer()731 	bool is_end_consumer() const { return (output.empty() && !desc->is_electricity_producer()); }
732 
733 	// Returns a list of goods produced by this factory.
734 	slist_tpl<const goods_desc_t*> *get_produced_goods() const;
735 
736 	// Rebuild the factory inactive caches.
737 	void rebuild_inactive_cache();
738 
739 	double get_production_per_second() const;
740 
741 	/* Calculate work rate using a ramp function.
742 	 * amount: The current amount.
743 	 * minimum: Minimum amount before work rate starts ramp down.
744 	 * maximum: Maximum before production stops.
745 	 * (opt) precision: Work rate fixed point fractional precision.
746 	 * returns: Work rate in fixed point form.
747 	 */
748 	static sint32 calculate_work_rate_ramp(sint32 const amount, sint32 const minimum, sint32 const maximum, uint32 const precision = WORK_BITS);
749 };
750 
751 #endif
752