1 /*
2  * Fabrikfunktionen und Fabrikbau
3  *
4  * Hansj�rg Malthaner
5  *
6  *
7  * 25.03.00 Anpassung der Lagerkapazit�ten: min. 5 normale Lieferungen
8  *          sollten an Lager gehalten werden.
9  */
10 
11 #include <math.h>
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 
17 #include "simdebug.h"
18 #include "display/simimg.h"
19 #include "simcolor.h"
20 #include "boden/grund.h"
21 #include "boden/boden.h"
22 #include "boden/fundament.h"
23 #include "simfab.h"
24 #include "simcity.h"
25 #include "simhalt.h"
26 #include "simware.h"
27 #include "simworld.h"
28 #include "descriptor/building_desc.h"
29 #include "descriptor/goods_desc.h"
30 #include "descriptor/sound_desc.h"
31 #include "player/simplay.h"
32 
33 #include "simintr.h"
34 
35 #include "obj/wolke.h"
36 #include "obj/gebaeude.h"
37 #include "obj/field.h"
38 #include "obj/leitung2.h"
39 
40 #include "dataobj/settings.h"
41 #include "dataobj/environment.h"
42 #include "dataobj/translator.h"
43 #include "dataobj/loadsave.h"
44 
45 #include "descriptor/factory_desc.h"
46 #include "bauer/hausbauer.h"
47 #include "bauer/goods_manager.h"
48 #include "bauer/fabrikbauer.h"
49 
50 #include "gui/fabrik_info.h"
51 
52 #include "utils/simrandom.h"
53 #include "utils/cbuffer_t.h"
54 
55 #include "gui/simwin.h"
56 #include "display/simgraph.h"
57 
58 // Fabrik_t
59 
60 
61 static const int FAB_MAX_INPUT = 15000;
62 // Half a display unit (0.5).
63 static const sint64 FAB_DISPLAY_UNIT_HALF = ((sint64)1 << (fabrik_t::precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS - 1));
64 // Half a production factor unit (0.5).
65 static const sint32 FAB_PRODFACT_UNIT_HALF = ((sint32)1 << (DEFAULT_PRODUCTION_FACTOR_BITS - 1));
66 
67 karte_ptr_t fabrik_t::welt;
68 
69 
70 /**
71  * Convert internal values to displayed values
72  */
convert_goods(sint64 value)73 sint64 convert_goods(sint64 value) { return ((value + FAB_DISPLAY_UNIT_HALF) >> (fabrik_t::precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS) ); }
convert_power(sint64 value)74 sint64 convert_power(sint64 value) { return ( value >> POWER_TO_MW ); }
convert_boost(sint64 value)75 sint64 convert_boost(sint64 value) { return ( (value * 100 + (DEFAULT_PRODUCTION_FACTOR>>1)) >> DEFAULT_PRODUCTION_FACTOR_BITS ); }
76 
77 
78 /**
79  * Ordering based on relative distance to a fixed point `origin'.
80  */
81 class RelativeDistanceOrdering
82 {
83 private:
84 	const koord m_origin;
85 public:
RelativeDistanceOrdering(const koord & origin)86 	RelativeDistanceOrdering(const koord& origin)
87 		: m_origin(origin)
88 	{ /* nothing */ }
89 
90 	/**
91 	 * Returns true if `a' is closer to the origin than `b', otherwise false.
92 	 */
operator ()(const koord & a,const koord & b) const93 	bool operator()(const koord& a, const koord& b) const
94 	{
95 		return koord_distance(m_origin, a) < koord_distance(m_origin, b);
96 	}
97 };
98 
99 /**
100  * Produce a scaled production amount from a production amount and work factor.
101  */
work_scale_production(sint64 prod,sint64 work)102 sint32 work_scale_production(sint64 prod, sint64 work){
103 	// compute scaled production, rounding up
104 	return ((prod * work) + (1 << WORK_BITS) - 1) >> WORK_BITS;
105 }
106 
107 /**
108  * Produce a work factor from a production amount and scaled production amount.
109  */
work_from_production(sint64 prod,sint64 scaled)110 sint32 work_from_production(sint64 prod, sint64 scaled){
111 	// compute work, rounding up
112 	return prod ? ((scaled << WORK_BITS) + prod - 1) / prod : 0;
113 }
114 
init_stats()115 void ware_production_t::init_stats()
116 {
117 	for(  int m=0;  m<MAX_MONTH;  ++m  ) {
118 		for(  int s=0;  s<MAX_FAB_GOODS_STAT;  ++s  ) {
119 			statistics[m][s] = 0;
120 		}
121 	}
122 	weighted_sum_storage = 0;
123 }
124 
125 
roll_stats(uint32 factor,sint64 aggregate_weight)126 void ware_production_t::roll_stats(uint32 factor, sint64 aggregate_weight)
127 {
128 	// calculate weighted average storage first
129 	if(  aggregate_weight>0  ) {
130 		set_stat( weighted_sum_storage / aggregate_weight, FAB_GOODS_STORAGE );
131 	}
132 
133 	for(  int s=0;  s<MAX_FAB_GOODS_STAT;  ++s  ) {
134 		for(  int m=MAX_MONTH-1;  m>0;  --m  ) {
135 			statistics[m][s] = statistics[m-1][s];
136 		}
137 		if(  s==FAB_GOODS_TRANSIT  ) {
138 			// keep the current amount in transit
139 			statistics[0][s] = statistics[1][s];
140 		}
141 		else {
142 			statistics[0][s] = 0;
143 		}
144 	}
145 	weighted_sum_storage = 0;
146 
147 	// restore current storage level
148 	set_stat( (sint64)menge * (sint64)factor, FAB_GOODS_STORAGE );
149 }
150 
151 
rdwr(loadsave_t * file)152 void ware_production_t::rdwr(loadsave_t *file)
153 {
154 	if(  file->is_loading()  ) {
155 		init_stats();
156 	}
157 
158 	// we use a temporary variable to save/load old data correctly
159 	sint64 statistics_buf[MAX_MONTH][MAX_FAB_GOODS_STAT];
160 	memcpy( statistics_buf, statistics, sizeof(statistics_buf) );
161 	if(  file->is_saving()  &&  file->is_version_less(120, 1)  ) {
162 		for(  int m=0;  m<MAX_MONTH;  ++m  ) {
163 			statistics_buf[m][0] = (statistics[m][FAB_GOODS_STORAGE] >> DEFAULT_PRODUCTION_FACTOR_BITS);
164 			statistics_buf[m][2] = (statistics[m][2] >> DEFAULT_PRODUCTION_FACTOR_BITS);
165 		}
166 	}
167 
168 	if(  file->is_version_atleast(112, 1)  ) {
169 		for(  int s=0;  s<MAX_FAB_GOODS_STAT;  ++s  ) {
170 			for(  int m=0;  m<MAX_MONTH;  ++m  ) {
171 				file->rdwr_longlong( statistics_buf[m][s] );
172 			}
173 		}
174 		file->rdwr_longlong( weighted_sum_storage );
175 	}
176 	else if(  file->is_version_atleast(110, 5)  ) {
177 		// save/load statistics
178 		for(  int s=0;  s<3;  ++s  ) {
179 			for(  int m=0;  m<MAX_MONTH;  ++m  ) {
180 				file->rdwr_longlong( statistics_buf[m][s] );
181 			}
182 		}
183 		file->rdwr_longlong( weighted_sum_storage );
184 	}
185 
186 	if(  file->is_loading()  ) {
187 		memcpy( statistics, statistics_buf, sizeof(statistics_buf) );
188 
189 		// Apply correction for output production graphs which have had their precision changed for factory normalization.
190 		// Also apply a fix for corrupted in-transit values caused by a logical error.
191 		if(file->is_version_less(120, 1)){
192 			for(  int m=0;  m<MAX_MONTH;  ++m  ) {
193 				statistics[m][0] = (statistics[m][FAB_GOODS_STORAGE] & 0xffffffff) << DEFAULT_PRODUCTION_FACTOR_BITS;
194 				statistics[m][2] = (statistics[m][2] & 0xffffffff) << DEFAULT_PRODUCTION_FACTOR_BITS;
195 			}
196 		}
197 
198 		// recalc transit always on load
199 		statistics[0][FAB_GOODS_TRANSIT] = 0;
200 	}
201 }
202 
203 
book_weighted_sum_storage(uint32 factor,sint64 delta_time)204 void ware_production_t::book_weighted_sum_storage(uint32 factor, sint64 delta_time)
205 {
206 	const sint64 amount = (sint64)menge * (sint64)factor;
207 	weighted_sum_storage += amount * delta_time;
208 	set_stat( amount, FAB_GOODS_STORAGE );
209 }
210 
calculate_output_production_rate() const211 sint32 ware_production_t::calculate_output_production_rate() const {
212 	return fabrik_t::calculate_work_rate_ramp(menge, min_shipment * OUTPUT_SCALE_RAMPDOWN_MULTIPLYER, max);
213 }
214 
calculate_demand_production_rate() const215 sint32 ware_production_t::calculate_demand_production_rate() const {
216 	return fabrik_t::calculate_work_rate_ramp(demand_buffer, max / 2, max);
217 }
218 
init()219 void fabrik_t::arrival_statistics_t::init()
220 {
221 	for(  uint32 s=0;  s<SLOT_COUNT;  ++s  ) {
222 		slots[s] = 0;
223 	}
224 	current_slot = 0;
225 	active_slots = 0;
226 	aggregate_arrival = 0;
227 	scaled_demand = 0;
228 }
229 
230 
rdwr(loadsave_t * file)231 void fabrik_t::arrival_statistics_t::rdwr(loadsave_t *file)
232 {
233 	if(  file->is_version_atleast(110, 5)  ) {
234 		if(  file->is_loading()  ) {
235 			aggregate_arrival = 0;
236 			for(  uint32 s=0;  s<SLOT_COUNT;  ++s  ) {
237 				file->rdwr_short( slots[s] );
238 				aggregate_arrival += slots[s];
239 			}
240 			scaled_demand = 0;
241 		}
242 		else {
243 			for(  uint32 s=0;  s<SLOT_COUNT;  ++s  ) {
244 				file->rdwr_short( slots[s] );
245 			}
246 		}
247 		file->rdwr_short( current_slot );
248 		file->rdwr_short( active_slots );
249 	}
250 	else if(  file->is_loading()  ) {
251 		init();
252 	}
253 }
254 
255 
advance_slot()256 sint32 fabrik_t::arrival_statistics_t::advance_slot()
257 {
258 	sint32 result = 0;
259 	// advance to the next slot
260 	++current_slot;
261 	if(  current_slot>=SLOT_COUNT  ) {
262 		current_slot = 0;
263 	}
264 	// handle expiration of past arrivals and reset slot to 0
265 	if(  slots[current_slot]>0  ) {
266 		aggregate_arrival -= slots[current_slot];
267 		slots[current_slot] = 0;
268 		if(  aggregate_arrival==0  ) {
269 			// reset slot count to 0 as all previous arrivals have expired
270 			active_slots = 0;
271 		}
272 		result |= ARRIVALS_CHANGED;
273 	}
274 	// count the number of slots covered since aggregate arrival last increased from 0 to +ve
275 	if(  active_slots>0  &&  active_slots<SLOT_COUNT  ) {
276 		++active_slots;
277 		result |= ACTIVE_SLOTS_INCREASED;
278 	}
279 	return result;
280 }
281 
282 
book_arrival(const uint16 amount)283 void fabrik_t::arrival_statistics_t::book_arrival(const uint16 amount)
284 {
285 	if(  aggregate_arrival==0  ) {
286 		// new arrival after complete inactivity -> start counting slots
287 		active_slots = 1;
288 	}
289 	// increment current slot and aggregate arrival
290 	slots[current_slot] += amount;
291 	aggregate_arrival += amount;
292 }
293 
294 
update_transit(const ware_t * ware,bool add)295 void fabrik_t::update_transit( const ware_t *ware, bool add )
296 {
297 	if(  ware->index > goods_manager_t::INDEX_NONE  ) {
298 		// only for freights
299 		fabrik_t *fab = get_fab( ware->get_zielpos() );
300 		if(  fab  ) {
301 			fab->update_transit_intern( ware, add );
302 		}
303 	}
304 }
305 
apply_transit(const ware_t * ware)306 void fabrik_t::apply_transit( const ware_t *ware )
307 {
308 	if(  ware->index > goods_manager_t::INDEX_NONE  ) {
309 		// only for freights
310 		fabrik_t *fab = get_fab( ware->get_zielpos() );
311 		if(  fab  ) {
312 			for(  uint32 input = 0;  input < fab->input.get_count();  input++  ){
313 				ware_production_t& w = fab->input[input];
314 				if(  w.get_typ()->get_index() == ware->index  ) {
315 					// It is now in transit.
316 					w.book_stat((sint64)ware->menge, FAB_GOODS_TRANSIT );
317 					// If using JIT2, must decrement demand buffers, activating if required.
318 					if( welt->get_settings().get_just_in_time() >= 2 ){
319 						const uint32 prod_factor = fab->desc->get_supplier(input)->get_consumption();
320 						const sint32 prod_delta = (sint32)((((sint64)(ware->menge) << (DEFAULT_PRODUCTION_FACTOR_BITS + precision_bits)) + (sint64)(prod_factor - 1)) / (sint64)prod_factor);
321 						const sint32 demand = w.demand_buffer;
322 						w.demand_buffer -= prod_delta;
323 						if(  demand >= w.max  &&  w.demand_buffer < w.max  ) {
324 							fab->inactive_demands --;
325 						}
326 					}
327 					// ours is on its way, no need to handle the other
328 					return;
329 				}
330 			}
331 		}
332 	}
333 }
334 
335 
336 // just for simplicity ...
update_transit_intern(const ware_t * ware,bool add)337 void fabrik_t::update_transit_intern( const ware_t *ware, bool add )
338 {
339 	FOR(  array_tpl<ware_production_t>,  &w,  input ) {
340 		if(  w.get_typ()->get_index() == ware->index  ) {
341 			w.book_stat(add ? (sint64)ware->menge : -(sint64)ware->menge, FAB_GOODS_TRANSIT );
342 			return;
343 		}
344 	}
345 }
346 
347 
init_stats()348 void fabrik_t::init_stats()
349 {
350 	for(  int m=0;  m<MAX_MONTH;  ++m  ) {
351 		for(  int s=0;  s<MAX_FAB_STAT;  ++s  ) {
352 			statistics[m][s] = 0;
353 		}
354 	}
355 	weighted_sum_production = 0;
356 	weighted_sum_boost_electric = 0;
357 	weighted_sum_boost_pax = 0;
358 	weighted_sum_boost_mail = 0;
359 	weighted_sum_power = 0;
360 	aggregate_weight = 0;
361 }
362 
363 
book_weighted_sums(sint64 delta_time)364 void fabrik_t::book_weighted_sums(sint64 delta_time)
365 {
366 	aggregate_weight += delta_time;
367 
368 	// storage level of input/output stores
369 	for( uint32 in = 0;  in < input.get_count();  in++  ){
370 		input[in].book_weighted_sum_storage(desc->get_supplier(in)->get_consumption(), delta_time);
371 	}
372 	for( uint32 out = 0;  out < output.get_count();  out++  ){
373 		output[out].book_weighted_sum_storage(desc->get_product(out)->get_factor(), delta_time);
374 	}
375 
376 	// production level
377 	const sint32 current_prod = get_current_production();
378 	weighted_sum_production += current_prod * delta_time;
379 	set_stat( current_prod, FAB_PRODUCTION );
380 
381 	// electricity, pax and mail boosts
382 	weighted_sum_boost_electric += prodfactor_electric * delta_time;
383 	set_stat( prodfactor_electric, FAB_BOOST_ELECTRIC );
384 	weighted_sum_boost_pax += prodfactor_pax * delta_time;
385 	weighted_sum_boost_mail += prodfactor_mail * delta_time;
386 
387 	// power produced or consumed
388 	sint64 power = get_power();
389 	weighted_sum_power += power * delta_time;
390 	set_stat( power, FAB_POWER );
391 }
392 
393 
update_scaled_electric_demand()394 void fabrik_t::update_scaled_electric_demand()
395 {
396 	if(  desc->get_electric_demand()==65535  ) {
397 		// demand not specified in pak, use old fixed demands
398 		scaled_electric_demand = prodbase * PRODUCTION_DELTA_T;
399 		if(  desc->is_electricity_producer()  ) {
400 			scaled_electric_demand *= 4;
401 		}
402 		return;
403 	}
404 
405 	const sint64 prod = desc->get_productivity();
406 	scaled_electric_demand = (uint32)( (( (sint64)(desc->get_electric_demand()) * (sint64)prodbase + (prod >> 1) ) / prod) << POWER_TO_MW );
407 
408 	if(  scaled_electric_demand == 0  ) {
409 		prodfactor_electric = 0;
410 	}
411 }
412 
413 
update_scaled_pax_demand()414 void fabrik_t::update_scaled_pax_demand()
415 {
416 	// first, scaling based on current production base
417 	const sint64 prod = desc->get_productivity();
418 	const sint64 desc_pax_demand = ( desc->get_pax_demand()==65535 ? desc->get_pax_level() : desc->get_pax_demand() );
419 	// formula : desc_pax_demand * (current_production_base / desc_production_base); (prod >> 1) is for rounding
420 	const uint32 pax_demand = (uint32)( ( desc_pax_demand * (sint64)prodbase + (prod >> 1) ) / prod );
421 	// then, scaling based on month length
422 	scaled_pax_demand = (uint32)welt->scale_with_month_length(pax_demand);
423 	if(  scaled_pax_demand == 0  &&  desc_pax_demand > 0  ) {
424 		scaled_pax_demand = 1;	// since desc pax demand > 0 -> ensure no less than 1
425 	}
426 	// pax demand for fixed period length
427 	arrival_stats_pax.set_scaled_demand( pax_demand );
428 }
429 
430 
update_scaled_mail_demand()431 void fabrik_t::update_scaled_mail_demand()
432 {
433 	// first, scaling based on current production base
434 	const sint64 prod = desc->get_productivity();
435 	const sint64 desc_mail_demand = ( desc->get_mail_demand()==65535 ? (desc->get_pax_level()>>2) : desc->get_mail_demand() );
436 	// formula : desc_mail_demand * (current_production_base / desc_production_base); (prod >> 1) is for rounding
437 	const uint32 mail_demand = (uint32)( ( desc_mail_demand * (sint64)prodbase + (prod >> 1) ) / prod );
438 	// then, scaling based on month length
439 	scaled_mail_demand = (uint32)welt->scale_with_month_length(mail_demand);
440 	if(  scaled_mail_demand == 0  &&  desc_mail_demand > 0  ) {
441 		scaled_mail_demand = 1;	// since desc mail demand > 0 -> ensure no less than 1
442 	}
443 	// mail demand for fixed period length
444 	arrival_stats_mail.set_scaled_demand( mail_demand );
445 }
446 
447 
update_prodfactor_pax()448 void fabrik_t::update_prodfactor_pax()
449 {
450 	// calculate pax boost based on arrival data and demand of the fixed-length period
451 	const uint32 periods = welt->get_settings().get_factory_arrival_periods();
452 	const uint32 slots = arrival_stats_pax.get_active_slots();
453 	const uint32 pax_demand = ( periods==1 || slots*periods<=(uint32)SLOT_COUNT ?
454 									arrival_stats_pax.get_scaled_demand() :
455 									( slots==(uint32)SLOT_COUNT ?
456 										arrival_stats_pax.get_scaled_demand() * periods :
457 										(arrival_stats_pax.get_scaled_demand() * periods * slots) >> SLOT_BITS ) );
458 	const uint32 pax_arrived = arrival_stats_pax.get_aggregate_arrival();
459 	if(  pax_demand==0  ||  pax_arrived==0  ||  desc->get_pax_boost()==0  ) {
460 		prodfactor_pax = 0;
461 	}
462 	else if(  pax_arrived>=pax_demand  ) {
463 		// maximum boost
464 		prodfactor_pax = desc->get_pax_boost();
465 	}
466 	else {
467 		// pro-rata boost : (pax_arrived / pax_demand) * desc_pax_boost; (pax_demand >> 1) is for rounding
468 		prodfactor_pax = (sint32)( ( (sint64)pax_arrived * (sint64)(desc->get_pax_boost()) + (sint64)(pax_demand >> 1) ) / (sint64)pax_demand );
469 	}
470 	set_stat(prodfactor_pax, FAB_BOOST_PAX);
471 }
472 
473 
update_prodfactor_mail()474 void fabrik_t::update_prodfactor_mail()
475 {
476 	// calculate mail boost based on arrival data and demand of the fixed-length period
477 	const uint32 periods = welt->get_settings().get_factory_arrival_periods();
478 	const uint32 slots = arrival_stats_mail.get_active_slots();
479 	const uint32 mail_demand = ( periods==1 || slots*periods<=(uint32)SLOT_COUNT ?
480 									arrival_stats_mail.get_scaled_demand() :
481 									( slots==(uint32)SLOT_COUNT ?
482 										arrival_stats_mail.get_scaled_demand() * periods :
483 										(arrival_stats_mail.get_scaled_demand() * periods * slots) >> SLOT_BITS ) );
484 	const uint32 mail_arrived = arrival_stats_mail.get_aggregate_arrival();
485 	if(  mail_demand==0  ||  mail_arrived==0  ||  desc->get_mail_boost()==0  ) {
486 		prodfactor_mail = 0;
487 	}
488 	else if(  mail_arrived>=mail_demand  ) {
489 		// maximum boost
490 		prodfactor_mail = desc->get_mail_boost();
491 	}
492 	else {
493 		// pro-rata boost : (mail_arrived / mail_demand) * desc_mail_boost; (mail_demand >> 1) is for rounding
494 		prodfactor_mail = (sint32)( ( (sint64)mail_arrived * (sint64)(desc->get_mail_boost()) + (sint64)(mail_demand >> 1) ) / (sint64)mail_demand );
495 	}
496 	set_stat(prodfactor_mail, FAB_BOOST_MAIL);
497 }
498 
499 
recalc_demands_at_target_cities()500 void fabrik_t::recalc_demands_at_target_cities()
501 {
502 	if (!welt->get_settings().get_factory_enforce_demand()) {
503 		// demand not enforced -> no splitting of demands
504 		FOR(vector_tpl<stadt_t*>, const c, target_cities) {
505 			c->access_target_factories_for_pax().update_factory( this, scaled_pax_demand  << DEMAND_BITS);
506 			c->access_target_factories_for_mail().update_factory(this, scaled_mail_demand << DEMAND_BITS);
507 		}
508 		return;
509 	}
510 	if (target_cities.empty()) {
511 		// nothing to do
512 		return;
513 	}
514 	else if(  target_cities.get_count()==1  ) {
515 		// only 1 target city -> no need to apportion pax/mail demand
516 		target_cities[0]->access_target_factories_for_pax().update_factory(this, (scaled_pax_demand << DEMAND_BITS));
517 		target_cities[0]->access_target_factories_for_mail().update_factory(this, (scaled_mail_demand << DEMAND_BITS));
518 	}
519 	else {
520 		// more than 1 target cities -> need to apportion pax/mail demand among the cities
521 		static vector_tpl<uint32> weights(8);
522 		weights.clear();
523 		uint32 sum_of_weights = 0;
524 		// first, calculate the weights
525 		for(  uint32 c=0;  c<target_cities.get_count();  ++c  ) {
526 			weights.append( weight_by_distance( target_cities[c]->get_einwohner(), shortest_distance( get_pos().get_2d(), target_cities[c]->get_center() ) ) );
527 			sum_of_weights += weights[c];
528 		}
529 		// finally, apportion the pax/mail demand; formula : demand * (city_weight / aggregate_city_weight); (sum_of_weights >> 1) is for rounding
530 		for(  uint32 c=0;  c<target_cities.get_count();  ++c  ) {
531 			const uint32 pax_amount = (uint32)(( (sint64)(scaled_pax_demand << DEMAND_BITS) * (sint64)weights[c] + (sint64)(sum_of_weights >> 1) ) / (sint64)sum_of_weights);
532 			target_cities[c]->access_target_factories_for_pax().update_factory(this, pax_amount);
533 			const uint32 mail_amount = (uint32)(( (sint64)(scaled_mail_demand << DEMAND_BITS) * (sint64)weights[c] + (sint64)(sum_of_weights >> 1) ) / (sint64)sum_of_weights);
534 			target_cities[c]->access_target_factories_for_mail().update_factory(this, mail_amount);
535 		}
536 	}
537 }
538 
539 
recalc_storage_capacities()540 void fabrik_t::recalc_storage_capacities()
541 {
542 	if(  desc->get_field_group()  ) {
543 		// with fields -> calculate based on capacities contributed by fields
544 		const uint32 ware_types = input.get_count() + output.get_count();
545 		if(  ware_types>0  ) {
546 			// calculate total storage capacity contributed by fields
547 			const field_group_desc_t *const field_group = desc->get_field_group();
548 			sint32 field_capacities = 0;
549 			FOR(vector_tpl<field_data_t>, const& f, fields) {
550 				field_capacities += field_group->get_field_class(f.field_class_index)->get_storage_capacity();
551 			}
552 			const sint32 share = (sint32)( ( (sint64)field_capacities << precision_bits ) / (sint64)ware_types );
553 			// first, for input goods
554 			FOR(array_tpl<ware_production_t>, & g, input) {
555 				for(  int b=0;  b<desc->get_supplier_count();  ++b  ) {
556 					const factory_supplier_desc_t *const input = desc->get_supplier(b);
557 					if (g.get_typ() == input->get_input_type()) {
558 						// Inputs are now normalized to factory production.
559 						uint32 prod_factor = input->get_consumption();
560 						g.max = (sint32)((((sint64)((input->get_capacity() << precision_bits) + share) << DEFAULT_PRODUCTION_FACTOR_BITS) + (sint64)(prod_factor - 1)) / (sint64)prod_factor);
561 					}
562 				}
563 			}
564 			// then, for output goods
565 			FOR(array_tpl<ware_production_t>, & g, output) {
566 				for(  uint b=0;  b<desc->get_product_count();  ++b  ) {
567 					const factory_product_desc_t *const output = desc->get_product(b);
568 					if (g.get_typ() == output->get_output_type()) {
569 						// Outputs are now normalized to factory production.
570 						uint32 prod_factor = output->get_factor();
571 						g.max = (sint32)((((sint64)((output->get_capacity() << precision_bits) + share) << DEFAULT_PRODUCTION_FACTOR_BITS) + (sint64)(prod_factor - 1)) / (sint64)prod_factor);
572 					}
573 				}
574 			}
575 		}
576 	}
577 	else {
578 		// without fields -> scaling based on prodbase
579 		// first, for input goods
580 		FOR(array_tpl<ware_production_t>, & g, input) {
581 			for(  int b=0;  b<desc->get_supplier_count();  ++b  ) {
582 				const factory_supplier_desc_t *const input = desc->get_supplier(b);
583 				if (g.get_typ() == input->get_input_type()) {
584 					// Inputs are now normalized to factory production.
585 					uint32 prod_factor = input->get_consumption();
586 					g.max = (sint32)(((((sint64)input->get_capacity() * (sint64)prodbase) << (precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS)) + (sint64)(prod_factor - 1)) / ((sint64)desc->get_productivity() * (sint64)prod_factor));
587 				}
588 			}
589 		}
590 		// then, for output goods
591 		FOR(array_tpl<ware_production_t>, & g, output) {
592 			for(  uint b=0;  b<desc->get_product_count();  ++b  ) {
593 				const factory_product_desc_t *const output = desc->get_product(b);
594 				if (g.get_typ() == output->get_output_type()) {
595 					// Outputs are now normalized to factory production.
596 					uint32 prod_factor = output->get_factor();
597 					g.max = (sint32)(((((sint64)output->get_capacity() * (sint64)prodbase) << (precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS)) + (sint64)(prod_factor - 1)) / ((sint64)desc->get_productivity() * (sint64)prod_factor));
598 				}
599 			}
600 		}
601 	}
602 
603 	// Now that the maximum is known, work out the recommended shipment size for outputs in normalized units.
604 	for(  uint32 out = 0;  out < output.get_count();  out++  ){
605 		const uint32 prod_factor = desc->get_product(out)->get_factor();
606 
607 		// Determine the maximum number of whole units the out can store.
608 		const uint32 unit_size = (uint32)(((sint64)output[out].max * (sint64)prod_factor) >> ( precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS ));
609 
610 		// Determine the number of units to ship. Prefer 10 units although in future a more dynamic choice may be appropiate.
611 		uint32 shipment_size;
612 		// Maximum shipment size.
613 		if( unit_size >= SHIPMENT_MAX_SIZE * SHIPMENT_NUM_MIN ) {
614 			shipment_size = SHIPMENT_MAX_SIZE;
615 		}
616 		// Dynamic shipment size.
617 		else if( unit_size > SHIPMENT_NUM_MIN ) {
618 			shipment_size = unit_size / SHIPMENT_NUM_MIN;
619 		}
620 		// Minimum shipment size.
621 		else {
622 			shipment_size = 1;
623 		}
624 
625 		// Now convert it into the prefered shipment size. Always round up to prevent "off by 1" error.
626 		output[out].min_shipment = (sint32)((((sint64)shipment_size << (precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS)) + (sint64)(prod_factor - 1)) / (sint64)prod_factor);
627 	}
628 
629 	if(  welt->get_settings().get_just_in_time() >= 2  ) {
630 		rebuild_inactive_cache();
631 	}
632 }
633 
634 
add_target_city(stadt_t * const city)635 void fabrik_t::add_target_city(stadt_t *const city)
636 {
637 	if(  target_cities.append_unique(city)  ) {
638 		recalc_demands_at_target_cities();
639 	}
640 }
641 
642 
remove_target_city(stadt_t * const city)643 void fabrik_t::remove_target_city(stadt_t *const city)
644 {
645 	if(  target_cities.is_contained(city)  ) {
646 		target_cities.remove(city);
647 		city->access_target_factories_for_pax().remove_factory(this);
648 		city->access_target_factories_for_mail().remove_factory(this);
649 		recalc_demands_at_target_cities();
650 	}
651 }
652 
653 
clear_target_cities()654 void fabrik_t::clear_target_cities()
655 {
656 	FOR(vector_tpl<stadt_t*>, const c, target_cities) {
657 		c->access_target_factories_for_pax().remove_factory(this);
658 		c->access_target_factories_for_mail().remove_factory(this);
659 	}
660 	target_cities.clear();
661 }
662 
663 
set_base_production(sint32 p)664 void fabrik_t::set_base_production(sint32 p)
665 {
666 	prodbase = p;
667 	recalc_storage_capacities();
668 	update_scaled_electric_demand();
669 	update_scaled_pax_demand();
670 	update_scaled_mail_demand();
671 	update_prodfactor_pax();
672 	update_prodfactor_mail();
673 	recalc_demands_at_target_cities();
674 }
675 
676 
get_fab(const koord & pos)677 fabrik_t *fabrik_t::get_fab(const koord &pos)
678 {
679 	const grund_t *gr = welt->lookup_kartenboden(pos);
680 	if(gr) {
681 		gebaeude_t *gb = gr->find<gebaeude_t>();
682 		if(gb) {
683 			return gb->get_fabrik();
684 		}
685 	}
686 	return NULL;
687 }
688 
689 
link_halt(halthandle_t halt)690 void fabrik_t::link_halt(halthandle_t halt)
691 {
692 	welt->access(pos.get_2d())->add_to_haltlist(halt);
693 }
694 
695 
unlink_halt(halthandle_t halt)696 void fabrik_t::unlink_halt(halthandle_t halt)
697 {
698 	planquadrat_t *plan=welt->access(pos.get_2d());
699 	if(plan) {
700 		plan->remove_from_haltlist(halt);
701 	}
702 }
703 
704 
add_lieferziel(koord ziel)705 void fabrik_t::add_lieferziel(koord ziel)
706 {
707 	if(  !lieferziele.is_contained(ziel)  ) {
708 		lieferziele.insert_ordered( ziel, RelativeDistanceOrdering(pos.get_2d()) );
709 		// now tell factory too
710 		fabrik_t * fab = fabrik_t::get_fab(ziel);
711 		if (fab) {
712 			fab->add_supplier(get_pos().get_2d());
713 		}
714 	}
715 }
716 
717 
rem_lieferziel(koord ziel)718 void fabrik_t::rem_lieferziel(koord ziel)
719 {
720 	lieferziele.remove(ziel);
721 }
722 
723 
fabrik_t(loadsave_t * file)724 fabrik_t::fabrik_t(loadsave_t* file)
725 {
726 	owner = NULL;
727 	prodfactor_electric = 0;
728 	lieferziele_active_last_month = 0;
729 	pos = koord3d::invalid;
730 
731 	rdwr(file);
732 
733 	if(  desc == NULL  ) {
734 		dbg->warning( "fabrik_t::fabrik_t()", "No pak-file for factory at (%s) - will not be built!", pos_origin.get_str() );
735 		return;
736 	}
737 	else if(  !welt->is_within_limits(pos_origin.get_2d())  ) {
738 		dbg->warning( "fabrik_t::fabrik_t()", "%s is not a valid position! (Will not be built!)", pos_origin.get_str() );
739 		desc = NULL; // to get rid of this broken factory later...
740 	}
741 	else {
742 		build(rotate, false, false);
743 		// now get rid of construction image
744 		for(  sint16 y=0;  y<desc->get_building()->get_y(rotate);  y++  ) {
745 			for(  sint16 x=0;  x<desc->get_building()->get_x(rotate);  x++  ) {
746 				gebaeude_t *gb = welt->lookup_kartenboden( pos_origin.get_2d()+koord(x,y) )->find<gebaeude_t>();
747 				if(  gb  ) {
748 					gb->add_alter(10000);
749 				}
750 			}
751 		}
752 	}
753 
754 	delta_sum = 0;
755 	delta_menge = 0;
756 	menge_remainder = 0;
757 	total_input = total_transit = total_output = 0;
758 	status = nothing;
759 	currently_producing = false;
760 	transformer = NULL;
761 	last_sound_ms = welt->get_ticks();
762 }
763 
764 
fabrik_t(koord3d pos_,player_t * owner,const factory_desc_t * factory_desc,sint32 initial_prod_base)765 fabrik_t::fabrik_t(koord3d pos_, player_t* owner, const factory_desc_t* factory_desc, sint32 initial_prod_base) :
766 	desc(factory_desc),
767 	pos(pos_)
768 {
769 	this->pos.z = welt->max_hgt(pos.get_2d());
770 	pos_origin = pos;
771 
772 	this->owner = owner;
773 	prodfactor_electric = 0;
774 	prodfactor_pax = 0;
775 	prodfactor_mail = 0;
776 	if (initial_prod_base < 0) {
777 		prodbase = desc->get_productivity() + simrand(desc->get_range());
778 	}
779 	else {
780 		prodbase = initial_prod_base;
781 	}
782 
783 	delta_sum = 0;
784 	delta_menge = 0;
785 	menge_remainder = 0;
786 	activity_count = 0;
787 	currently_producing = false;
788 	transformer = NULL;
789 	total_input = total_transit = total_output = 0;
790 	status = nothing;
791 	lieferziele_active_last_month = 0;
792 
793 	// create input information
794 	input.resize( factory_desc->get_supplier_count() );
795 	for(  int g=0;  g<factory_desc->get_supplier_count();  ++g  ) {
796 		const factory_supplier_desc_t *const supp = factory_desc->get_supplier(g);
797 		input[g].set_typ( supp->get_input_type() );
798 	}
799 
800 	// create output information
801 	output.resize( factory_desc->get_product_count() );
802 	for(  uint g=0;  g<factory_desc->get_product_count();  ++g  ) {
803 		const factory_product_desc_t *const product = factory_desc->get_product(g);
804 		output[g].set_typ( product->get_output_type() );
805 	}
806 
807 	recalc_storage_capacities();
808 	if( welt->get_settings().get_just_in_time() >= 2 ){
809 		inactive_inputs = inactive_outputs = inactive_demands = 0;
810 		if(  input.empty()  ){
811 			// All sources start out with maximum product.
812 			for(  uint32 out = 0;  out < output.get_count();  out++  ){
813 				output[out].menge = output[out].max;
814 				inactive_outputs ++;
815 			}
816 		}
817 		else {
818 			for(  uint32 out = 0;  out < output.get_count();  out++  ){
819 				output[out].menge = 0;
820 			}
821 
822 			// A consumer of sorts so output and input starts out empty but with a full demand buffer.
823 			for(  uint32 in = 0;  in < input.get_count();  in++  ){
824 				input[in].menge = 0;
825 				input[in].demand_buffer = input[in].max;
826 				inactive_inputs++;
827 				inactive_demands++;
828 			}
829 		}
830 	}
831 	else {
832 		if(  input.empty()  ) {
833 			FOR( array_tpl<ware_production_t>, & g, output ) {
834 				if(  g.max > 0  ) {
835 					// if source then start with full storage, so that AI will build line(s) immediately
836 					g.menge = g.max - 1;
837 				}
838 			}
839 		}
840 	}
841 
842 	last_sound_ms = welt->get_ticks();
843 	init_stats();
844 	arrival_stats_pax.init();
845 	arrival_stats_mail.init();
846 
847 	delta_slot = 0;
848 	times_expanded = 0;
849 	update_scaled_electric_demand();
850 	update_scaled_pax_demand();
851 	update_scaled_mail_demand();
852 }
853 
854 
~fabrik_t()855 fabrik_t::~fabrik_t()
856 {
857 	while(!fields.empty()) {
858 		planquadrat_t *plan = welt->access( fields.back().location );
859 		// if destructor is called when world is destroyed, plan is already invalid
860 		if (plan) {
861 			grund_t *gr = plan->get_kartenboden();
862 			if (field_t* f = gr->find<field_t>()) {
863 				delete f; // implicitly removes the field from fields
864 				plan->boden_ersetzen( gr, new boden_t(gr->get_pos(), slope_t::flat ) );
865 				plan->get_kartenboden()->calc_image();
866 				continue;
867 			}
868 		}
869 		fields.pop_back();
870 	}
871 	// destroy chart window, if present
872 	destroy_win((ptrdiff_t)this);
873 }
874 
875 
build(sint32 rotate,bool build_fields,bool force_initial_prodbase)876 void fabrik_t::build(sint32 rotate, bool build_fields, bool force_initial_prodbase)
877 {
878 	this->rotate = rotate;
879 	pos_origin = welt->lookup_kartenboden(pos_origin.get_2d())->get_pos();
880 	gebaeude_t *gb = hausbauer_t::build(owner, pos_origin, rotate, desc->get_building(), this);
881 	pos = gb->get_pos();
882 	pos_origin.z = pos.z;
883 
884 	if(desc->get_field_group()) {
885 		// if there are fields
886 		if(  !fields.empty()  ) {
887 			for(  uint16 i=0;  i<fields.get_count();  i++   ) {
888 				const koord k = fields[i].location;
889 				grund_t *gr=welt->lookup_kartenboden(k);
890 				if(  gr->ist_natur()  ) {
891 					// first make foundation below
892 					grund_t *gr2 = new fundament_t(gr->get_pos(), gr->get_grund_hang());
893 					welt->access(k)->boden_ersetzen(gr, gr2);
894 					gr2->obj_add( new field_t(gr2->get_pos(), owner, desc->get_field_group()->get_field_class( fields[i].field_class_index ), this ) );
895 				}
896 				else {
897 					// there was already a building at this position => do not restore!
898 					fields.remove_at(i);
899 					i--;
900 				}
901 			}
902 		}
903 		else if(  build_fields  ) {
904 			// make sure not to exceed initial prodbase too much
905 			sint32 org_prodbase = prodbase;
906 			// we will start with a minimum number and try to get closer to start_fields
907 			const uint16 spawn_fields = desc->get_field_group()->get_min_fields() + simrand( desc->get_field_group()->get_start_fields()-desc->get_field_group()->get_min_fields() );
908 			while(  fields.get_count() < spawn_fields  &&  add_random_field(10000u)  ) {
909 				if (fields.get_count() > desc->get_field_group()->get_min_fields()  &&  prodbase >= 2*org_prodbase) {
910 					// too much productivity, no more fields needed
911 					break;
912 				}
913 			}
914 			sint32 field_prod = prodbase - org_prodbase;
915 			// adjust prodbase
916 			if (force_initial_prodbase) {
917 				set_base_production( max(field_prod, org_prodbase) );
918 			}
919 		}
920 	}
921 	else {
922 		fields.clear();
923 	}
924 
925 	/// Determine control logic
926 	if( welt->get_settings().get_just_in_time() >= 2 ) {
927 		// Does it both consume and produce?
928 		if(  !output.empty() && !input.empty()  ) {
929 			control_type = CL_FACT_MANY;
930 		}
931 		// Does it produce?
932 		else if( !output.empty() ) {
933 			control_type = CL_PROD_MANY;
934 		}
935 		// Does it consume?
936 		else if( !input.empty() ) {
937 			control_type = CL_CONS_MANY;
938 		}
939 		// No I/O?
940 		else {
941 			control_type = desc->is_electricity_producer() ? CL_ELEC_PROD : CL_NONE;
942 		}
943 	}
944 	else{
945 		// Classic logic.
946 		if(  !output.empty() && !input.empty()  ) {
947 			control_type = CL_FACT_CLASSIC;
948 		}
949 		else if( !output.empty() ) {
950 			control_type = CL_PROD_CLASSIC;
951 		}
952 		else if( !input.empty() ) {
953 			control_type = CL_CONS_CLASSIC;
954 		}
955 		else {
956 			control_type = CL_ELEC_CLASSIC;
957 		}
958 	}
959 
960 	// Boost logic determines what factors boost factory production.
961 	if( welt->get_settings().get_just_in_time() >= 2 ) {
962 		if(  !desc->is_electricity_producer()  &&  desc->get_electric_demand() > 0  ) {
963 			boost_type = BL_POWER;
964 		}
965 		else if(  desc->get_pax_demand() ||  desc->get_mail_demand()  ) {
966 			boost_type = BL_PAXM;
967 		}
968 		else {
969 			boost_type = BL_NONE;
970 		}
971 	}
972 	else {
973 		boost_type = BL_CLASSIC;
974 	}
975 
976 	if(  welt->get_settings().get_just_in_time() >= 2  ) {
977 		if( input.empty() ) {
978 			demand_type = DL_NONE;
979 		}
980 		else if( output.empty() ) {
981 			demand_type = DL_ASYNC;
982 		}
983 		else {
984 			demand_type = DL_SYNC;
985 		}
986 	}
987 	else {
988 		demand_type =  input.empty() ? DL_NONE : DL_OLD;
989 	}
990 }
991 
992 
993 /* field generation code
994  * @author Kieron Green
995  */
add_random_field(uint16 probability)996 bool fabrik_t::add_random_field(uint16 probability)
997 {
998 	// has fields, and not yet too many?
999 	const field_group_desc_t *fd = desc->get_field_group();
1000 	if(fd==NULL  ||  fd->get_max_fields() <= fields.get_count()) {
1001 		return false;
1002 	}
1003 	// we are lucky and are allowed to generate a field
1004 	if(  simrand(10000)>=probability  ) {
1005 		return false;
1006 	}
1007 
1008 	// we start closest to the factory, and check for valid tiles as we move out
1009 	uint8 radius = 1;
1010 
1011 	// pick a coordinate to use - create a list of valid locations and choose a random one
1012 	slist_tpl<grund_t *> build_locations;
1013 	do {
1014 		for(sint32 xoff = -radius; xoff < radius + get_desc()->get_building()->get_size().x ; xoff++) {
1015 			for(sint32 yoff =-radius ; yoff < radius + get_desc()->get_building()->get_size().y; yoff++) {
1016 				// if we can build on this tile then add it to the list
1017 				grund_t *gr = welt->lookup_kartenboden(pos.get_2d()+koord(xoff,yoff));
1018 				if (gr != NULL &&
1019 						gr->get_typ()        == grund_t::boden &&
1020 						get_desc()->get_building()->is_allowed_climate(welt->get_climate(pos.get_2d()+koord(xoff,yoff))) &&
1021 						gr->get_grund_hang() == slope_t::flat &&
1022 						gr->ist_natur() &&
1023 						(gr->find<leitung_t>() || gr->kann_alle_obj_entfernen(NULL) == NULL)) {
1024 					// only on same height => climate will match!
1025 					build_locations.append(gr);
1026 					assert(gr->find<field_t>() == NULL);
1027 				}
1028 				// skip inside of rectangle (already checked earlier)
1029 				if(radius > 1 && yoff == -radius && (xoff > -radius && xoff < radius + get_desc()->get_building()->get_size().x - 1)) {
1030 					yoff = radius + get_desc()->get_building()->get_size().y - 2;
1031 				}
1032 			}
1033 		}
1034 		if (build_locations.empty()) {
1035 			radius++;
1036 		}
1037 	} while (radius < 10 && build_locations.empty());
1038 	// built on one of the positions
1039 	if (!build_locations.empty()) {
1040 		grund_t *gr = build_locations.at(simrand(build_locations.get_count()));
1041 		leitung_t* lt = gr->find<leitung_t>();
1042 		if(lt) {
1043 			gr->obj_remove(lt);
1044 		}
1045 		gr->obj_loesche_alle(NULL);
1046 		// first make foundation below
1047 		const koord k = gr->get_pos().get_2d();
1048 		field_data_t new_field(k);
1049 		assert(!fields.is_contained(new_field));
1050 		// Knightly : fetch a random field class desc based on spawn weights
1051 		const weighted_vector_tpl<uint16> &field_class_indices = fd->get_field_class_indices();
1052 		new_field.field_class_index = pick_any_weighted(field_class_indices);
1053 		const field_class_desc_t *const field_class = fd->get_field_class( new_field.field_class_index );
1054 		fields.append(new_field);
1055 		grund_t *gr2 = new fundament_t(gr->get_pos(), gr->get_grund_hang());
1056 		welt->access(k)->boden_ersetzen(gr, gr2);
1057 		gr2->obj_add( new field_t(gr2->get_pos(), owner, field_class, this ) );
1058 		// Knightly : adjust production base and storage capacities
1059 		set_base_production( prodbase + field_class->get_field_production() );
1060 		if(lt) {
1061 			gr2->obj_add( lt );
1062 		}
1063 		gr2->calc_image();
1064 		return true;
1065 	}
1066 	return false;
1067 }
1068 
1069 
remove_field_at(koord pos)1070 void fabrik_t::remove_field_at(koord pos)
1071 {
1072 	field_data_t field(pos);
1073 	assert(fields.is_contained( field ));
1074 	field = fields[ fields.index_of(field) ];
1075 	const field_class_desc_t *const field_class = desc->get_field_group()->get_field_class( field.field_class_index );
1076 	fields.remove(field);
1077 	// Knightly : revert the field's effect on production base and storage capacities
1078 	set_base_production( prodbase - field_class->get_field_production() );
1079 }
1080 
1081 
sind_da_welche(koord min_pos,koord max_pos)1082 vector_tpl<fabrik_t *> &fabrik_t::sind_da_welche(koord min_pos, koord max_pos)
1083 {
1084 	static vector_tpl <fabrik_t*> factory_list(16);
1085 	factory_list.clear();
1086 
1087 	for(int y=min_pos.y; y<=max_pos.y; y++) {
1088 		for(int x=min_pos.x; x<=max_pos.x; x++) {
1089 			fabrik_t *fab=get_fab(koord(x,y));
1090 			if(fab) {
1091 				if (factory_list.append_unique(fab)) {
1092 //DBG_MESSAGE("fabrik_t::sind_da_welche()","appended factory %s at (%i,%i)",gr->first_obj()->get_fabrik()->get_desc()->get_name(),x,y);
1093 				}
1094 			}
1095 		}
1096 	}
1097 	return factory_list;
1098 }
1099 
1100 
1101 /**
1102  * if name==NULL translate desc factory name in game language
1103  */
get_name() const1104 char const* fabrik_t::get_name() const
1105 {
1106 	return name ? name.c_str() : translator::translate(desc->get_name(), welt->get_settings().get_name_language_id());
1107 }
1108 
1109 
set_name(const char * new_name)1110 void fabrik_t::set_name(const char *new_name)
1111 {
1112 	if(new_name==NULL  ||  strcmp(new_name, translator::translate(desc->get_name(), welt->get_settings().get_name_language_id()))==0) {
1113 		// new name is equal to name given by descriptor/translation -> set name to NULL
1114 		name = NULL;
1115 	}
1116 	else {
1117 		name = new_name;
1118 	}
1119 
1120 	fabrik_info_t *win = dynamic_cast<fabrik_info_t*>(win_get_magic((ptrdiff_t)this));
1121 	if (win) {
1122 		win->update_info();
1123 	}
1124 }
1125 
1126 
rdwr(loadsave_t * file)1127 void fabrik_t::rdwr(loadsave_t *file)
1128 {
1129 	xml_tag_t f( file, "fabrik_t" );
1130 	sint32 i;
1131 	sint32 owner_n;
1132 	sint32 input_count;
1133 	sint32 output_count;
1134 	sint32 anz_lieferziele;
1135 
1136 	if(  file->is_saving()  ) {
1137 		input_count = input.get_count();
1138 		output_count = output.get_count();
1139 		anz_lieferziele = lieferziele.get_count();
1140 		const char *s = desc->get_name();
1141 		file->rdwr_str(s);
1142 	}
1143 	else {
1144 		char s[256];
1145 		file->rdwr_str(s, lengthof(s));
1146 DBG_DEBUG("fabrik_t::rdwr()","loading factory '%s'",s);
1147 		desc = factory_builder_t::get_desc(s);
1148 		if(  desc==NULL  ) {
1149 			//  maybe it was only renamed?
1150 			desc = factory_builder_t::get_desc(translator::compatibility_name(s));
1151 		}
1152 		if(  desc==NULL  ) {
1153 			dbg->warning( "fabrik_t::rdwr()", "Pak-file for factory '%s' missing!", s );
1154 			// we continue loading even if desc==NULL
1155 			welt->add_missing_paks( s, karte_t::MISSING_FACTORY );
1156 		}
1157 	}
1158 	pos_origin.rdwr(file);
1159 	// pos will be assigned after call to hausbauer_t::build
1160 	file->rdwr_byte(rotate);
1161 
1162 	// now rebuilt information for received goods
1163 	file->rdwr_long(input_count);
1164 	if(  file->is_loading()  ) {
1165 		input.resize( input_count );
1166 	}
1167 	bool mismatch = false;
1168 	for(  i=0;  i<input_count;  i++  ) {
1169 		ware_production_t &ware = input[i];
1170 		const char *ware_name = NULL;
1171 		sint32 menge = ware.menge;
1172 		if(  file->is_saving()  ) {
1173 			ware_name = ware.get_typ()->get_name();
1174 			if(  file->is_version_less(120, 1)  ) {
1175 				// correct for older saves
1176 				menge = (sint32)(((sint64)ware.menge  * (sint64)desc->get_supplier(i)->get_consumption() )  >> DEFAULT_PRODUCTION_FACTOR_BITS);
1177 			}
1178 		}
1179 		file->rdwr_str(ware_name);
1180 		file->rdwr_long(menge);
1181 		if(  file->is_version_less(110, 5)  ) {
1182 			// max storage is only loaded/saved for older versions
1183 			file->rdwr_long(ware.max);
1184 		}
1185 		//  JIT2 needs to store input demand buffer
1186 		if(  welt->get_settings().get_just_in_time() >= 2  &&  file->is_version_atleast(120, 1)  ){
1187 			file->rdwr_long(ware.demand_buffer);
1188 		}
1189 
1190 		ware.rdwr( file );
1191 
1192 		if(  file->is_loading()  ) {
1193 
1194 			ware.set_typ( goods_manager_t::get_info(ware_name) );
1195 
1196 			// Maximum in-transit is always 0 on load.
1197 			if(  welt->get_settings().get_just_in_time() < 2  ) {
1198 				ware.max_transit = 0;
1199 			}
1200 
1201 			if(  !desc  ||  !desc->get_supplier(i)  ) {
1202 				if (desc) dbg->warning( "fabrik_t::rdwr()", "Factory at %s requested producer for %s but has none!", pos_origin.get_fullstr(), ware_name);
1203 				ware.menge = 0;
1204 			}
1205 			else {
1206 
1207 				// Inputs used to be with respect to actual units of production. They now are normalized with respect to factory production so require conversion.
1208 				const uint32 prod_factor = desc ? desc->get_supplier(i)->get_consumption() : 1;
1209 				if(  file->is_version_less(120, 1)  ) {
1210 					ware.menge = (sint32)(((sint64)menge << DEFAULT_PRODUCTION_FACTOR_BITS) / (sint64)prod_factor);
1211 				}
1212 				else {
1213 					ware.menge = menge;
1214 				}
1215 
1216 				// Hajo: repair files that have 'insane' values
1217 				const sint32 max = (sint32)((((sint64)FAB_MAX_INPUT << (precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS)) + (sint64)(prod_factor - 1)) / (sint64)prod_factor);
1218 				if(  ware.menge < 0  ) {
1219 					ware.menge = 0;
1220 				}
1221 				if(  ware.menge > max  ) {
1222 					ware.menge = max;
1223 				}
1224 
1225 				if (ware.get_typ() != desc->get_supplier(i)->get_input_type()) {
1226 					mismatch = true;
1227 					dbg->warning("fabrik_t::rdwr", "Factory at %s: producer[%d] mismatch in savegame=%s/%s, in pak=%s",
1228 							 pos_origin.get_fullstr(), i, ware_name, ware.get_typ()->get_name(), desc->get_supplier(i)->get_input_type()->get_name());
1229 				}
1230 			}
1231 			guarded_free(const_cast<char *>(ware_name));
1232 		}
1233 	}
1234 	if(  desc  &&  input_count != desc->get_supplier_count() ) {
1235 		dbg->warning("fabrik_t::rdwr", "Mismatch of input slot count for factory %s at %s: savegame = %d, pak = %d", get_name(), pos_origin.get_fullstr(), input_count, desc->get_supplier_count());
1236 		// resize input to match the descriptor
1237 		input.resize( desc->get_supplier_count() );
1238 		mismatch = true;
1239 	}
1240 	if (mismatch) {
1241 		array_tpl<ware_production_t> dummy;
1242 		dummy.resize(desc->get_supplier_count());
1243 		for(uint16 i=0; i<desc->get_supplier_count(); i++) {
1244 			dummy[i] = input[i];
1245 		}
1246 		for(uint16 i=0; i<desc->get_supplier_count(); i++) {
1247 			// search for matching type
1248 			bool missing = true;
1249 			const goods_desc_t* goods = desc->get_supplier(i)->get_input_type();
1250 			for(uint16 j=0; j<desc->get_supplier_count()  &&  missing; j++) {
1251 				if (dummy[j].get_typ() == goods) {
1252 					input[i] = dummy[j];
1253 					dummy[j].set_typ(NULL);
1254 					missing = false;
1255 				}
1256 			}
1257 			if (missing) {
1258 				input[i].set_typ(goods);
1259 			}
1260 		}
1261 	}
1262 
1263 	// now rebuilt information for produced goods
1264 	file->rdwr_long(output_count);
1265 	if(  file->is_loading()  ) {
1266 		output.resize( output_count );
1267 	}
1268 	mismatch = false;
1269 	for(  i=0;  i<output_count;  ++i  ) {
1270 		ware_production_t &ware = output[i];
1271 		const char *ware_name = NULL;
1272 		sint32 menge = ware.menge;
1273 		if(  file->is_saving()  ) {
1274 			ware_name = ware.get_typ()->get_name();
1275 			// correct scaling for older saves
1276 			if(  file->is_version_less(120, 1)  ){
1277 				menge = (sint32)(((sint64)ware.menge * desc->get_product(i)->get_factor() ) >> DEFAULT_PRODUCTION_FACTOR_BITS);
1278 			}
1279 		}
1280 		file->rdwr_str(ware_name);
1281 		file->rdwr_long(menge);
1282 		if(  file->is_version_less(110, 5)  ) {
1283 			// max storage is only loaded/saved for older versions
1284 			file->rdwr_long(ware.max);
1285 			// obsolete variables -> statistics already contain records on goods delivered
1286 			sint32 abgabe_sum = (sint32)(ware.get_stat(0, FAB_GOODS_DELIVERED));
1287 			sint32 abgabe_letzt = (sint32)(ware.get_stat(1, FAB_GOODS_DELIVERED));
1288 			file->rdwr_long(abgabe_sum);
1289 			file->rdwr_long(abgabe_letzt);
1290 		}
1291 		ware.rdwr( file );
1292 		if(  file->is_loading()  ) {
1293 			ware.set_typ( goods_manager_t::get_info(ware_name) );
1294 
1295 			if(  !desc  ||  !desc->get_product(i)  ) {
1296 				if (desc) dbg->warning( "fabrik_t::rdwr()", "Factory at %s requested consumer for %s but has none!", pos_origin.get_fullstr(), ware_name );
1297 				ware.menge = 0;
1298 			}
1299 			else {
1300 				// Outputs used to be with respect to actual units of production. They now are normalized with respect to factory production so require conversion.
1301 				if(  file->is_version_less(120, 1)  ){
1302 					const uint32 prod_factor = desc ? desc->get_product(i)->get_factor() : 1;
1303 					ware.menge = (sint32)(((sint64)menge << DEFAULT_PRODUCTION_FACTOR_BITS) / (sint64)prod_factor);
1304 				}
1305 				else {
1306 					ware.menge = menge;
1307 				}
1308 
1309 				// Hajo: repair files that have 'insane' values
1310 				if(  ware.menge < 0  ) {
1311 					ware.menge = 0;
1312 				}
1313 
1314 				if (ware.get_typ() != desc->get_product(i)->get_output_type()) {
1315 					mismatch = true;
1316 					dbg->warning("fabrik_t::rdwr", "Factory at %s: consumer[%d] mismatch in savegame=%s/%s, in pak=%s",
1317 							 pos_origin.get_fullstr(), i, ware_name, ware.get_typ()->get_name(), desc->get_product(i)->get_output_type()->get_name());
1318 				}
1319 			}
1320 			guarded_free(const_cast<char *>(ware_name));
1321 		}
1322 	}
1323 	if(  desc  &&  output_count != desc->get_product_count()) {
1324 		dbg->warning("fabrik_t::rdwr", "Mismatch of output slot count for factory %s at %s: savegame = %d, pak = %d", get_name(), pos_origin.get_fullstr(), output_count, desc->get_product_count());
1325 		// resize output to match the descriptor
1326 		output.resize( desc->get_product_count() );
1327 		mismatch = true;
1328 	}
1329 	if (mismatch) {
1330 		array_tpl<ware_production_t> dummy;
1331 		dummy.resize(desc->get_product_count());
1332 		for(uint16 i=0; i<desc->get_product_count(); i++) {
1333 			dummy[i] = output[i];
1334 		}
1335 		for(uint16 i=0; i<desc->get_product_count(); i++) {
1336 			// search for matching type
1337 			bool missing = true;
1338 			const goods_desc_t* goods = desc->get_product(i)->get_output_type();
1339 			for(uint16 j=0; j<desc->get_product_count()  &&  missing; j++) {
1340 				if (dummy[j].get_typ() == goods) {
1341 					output[i] = dummy[j];
1342 					dummy[j].set_typ(NULL);
1343 					missing = false;
1344 				}
1345 			}
1346 			if (missing) {
1347 				output[i].set_typ(goods);
1348 			}
1349 		}
1350 	}
1351 
1352 	// restore other information
1353 	owner_n = welt->sp2num(owner);
1354 	file->rdwr_long(owner_n);
1355 	file->rdwr_long(prodbase);
1356 	if(  file->is_version_less(110, 5)  ) {
1357 		// TurfIt : prodfactor saving no longer required
1358 		sint32 adjusted_value = (prodfactor_electric / 16) + 16;
1359 		file->rdwr_long(adjusted_value);
1360 	}
1361 
1362 	// no longer save power at factories
1363 	if(  file->is_version_atleast(99, 17) && file->is_version_less(120, 4)  ) {
1364 		sint32 power = 0;
1365 		file->rdwr_long(power);
1366 	}
1367 	if(  file->is_version_atleast(120, 1) && file->is_version_less(120, 4)  ) {
1368 		sint32 power_demand = 0;
1369 		file->rdwr_long(power_demand);
1370 	}
1371 
1372 	// owner stuff
1373 	if(  file->is_loading()  ) {
1374 		// take care of old files
1375 		if(  file->is_version_less(86, 1)  ) {
1376 			koord k = desc ? desc->get_building()->get_size() : koord(1,1);
1377 			DBG_DEBUG("fabrik_t::rdwr()","correction of production by %i",k.x*k.y);
1378 			// since we step from 86.01 per factory, not per tile!
1379 			prodbase *= k.x*k.y*2;
1380 		}
1381 		// Hajo: restore factory owner
1382 		// Due to a omission in Volkers changes, there might be savegames
1383 		// in which factories were saved without an owner. In this case
1384 		// set the owner to the default of player 1
1385 		if(owner_n == -1) {
1386 			// Use default
1387 			owner = welt->get_public_player();
1388 		}
1389 		else {
1390 			// Restore owner pointer
1391 			owner = welt->get_player(owner_n);
1392 		}
1393 	}
1394 
1395 	file->rdwr_long(anz_lieferziele);
1396 
1397 	// connect/save consumer
1398 	for(int i=0; i<anz_lieferziele; i++) {
1399 		if(file->is_loading()) {
1400 			lieferziele.append(koord::invalid);
1401 		}
1402 		lieferziele[i].rdwr(file);
1403 	}
1404 
1405 	if(  file->is_version_atleast(112, 2)  ) {
1406 		file->rdwr_long( lieferziele_active_last_month );
1407 	}
1408 
1409 	// suppliers / consumers will be recalculated in finish_rd
1410 	if (file->is_loading()  &&  welt->get_settings().is_crossconnect_factories()) {
1411 		lieferziele.clear();
1412 	}
1413 
1414 	// information on fields ...
1415 	if(  file->is_version_atleast(99, 10)  ) {
1416 		if(  file->is_saving()  ) {
1417 			uint16 nr=fields.get_count();
1418 			file->rdwr_short(nr);
1419 			if(  file->is_version_atleast(102, 3)  ) {
1420 				// each field stores location and a field class index
1421 				for(  uint16 i=0  ;  i<nr  ;  ++i  ) {
1422 					koord k = fields[i].location;
1423 					k.rdwr(file);
1424 					uint16 idx = fields[i].field_class_index;
1425 					file->rdwr_short(idx);
1426 				}
1427 			}
1428 			else {
1429 				// each field only stores location
1430 				for(  uint16 i=0  ;  i<nr  ;  ++i  ) {
1431 					koord k = fields[i].location;
1432 					k.rdwr(file);
1433 				}
1434 			}
1435 		}
1436 		else {
1437 			uint16 nr=0;
1438 			koord k;
1439 			file->rdwr_short(nr);
1440 			fields.resize(nr);
1441 			if(  file->is_version_atleast(102, 3)  ) {
1442 				// each field stores location and a field class index
1443 				for(  uint16 i=0  ;  i<nr  ;  ++i  ) {
1444 					k.rdwr(file);
1445 					uint16 idx;
1446 					file->rdwr_short(idx);
1447 					if(  desc  &&  desc->get_field_group()  ) {
1448 						// set class index to 0 if it is out of range, if there fields at all
1449 						fields.append( field_data_t(k, idx >= desc->get_field_group()->get_field_class_count() ? 0 : idx ) );
1450 					}
1451 				}
1452 			}
1453 			else {
1454 				// each field only stores location
1455 				for(  uint16 i=0  ;  i<nr  ;  ++i  ) {
1456 					k.rdwr(file);
1457 					if(  desc  &&  desc->get_field_group()  ) {
1458 						// oald add fields if there are any defined
1459 						fields.append( field_data_t(k, 0) );
1460 					}
1461 				}
1462 			}
1463 		}
1464 	}
1465 
1466 	// restore city pointer here
1467 	if(  file->is_version_atleast(99, 14)  ) {
1468 		sint32 nr = target_cities.get_count();
1469 		file->rdwr_long(nr);
1470 		for(  int i=0;  i<nr;  i++  ) {
1471 			sint32 city_index = -1;
1472 			if(file->is_saving()) {
1473 				city_index = welt->get_cities().index_of( target_cities[i] );
1474 			}
1475 			file->rdwr_long(city_index);
1476 			if(  file->is_loading()  ) {
1477 				// will also update factory information
1478 				target_cities.append( welt->get_cities()[city_index] );
1479 			}
1480 		}
1481 	}
1482 	else if(  file->is_loading()  ) {
1483 		// will be handled by the city after reloading
1484 		target_cities.clear();
1485 	}
1486 
1487 	if(  file->is_version_atleast(110, 5)  ) {
1488 		file->rdwr_short(times_expanded);
1489 		// statistics
1490 		for(  int s=0;  s<MAX_FAB_STAT;  ++s  ) {
1491 			for(  int m=0;  m<MAX_MONTH;  ++m  ) {
1492 				file->rdwr_longlong( statistics[m][s] );
1493 			}
1494 		}
1495 		file->rdwr_longlong( weighted_sum_production );
1496 		file->rdwr_longlong( weighted_sum_boost_electric );
1497 		file->rdwr_longlong( weighted_sum_boost_pax );
1498 		file->rdwr_longlong( weighted_sum_boost_mail );
1499 		file->rdwr_longlong( weighted_sum_power );
1500 		file->rdwr_longlong( aggregate_weight );
1501 		file->rdwr_long( delta_slot );
1502 	}
1503 	else if(  file->is_loading()  ) {
1504 		times_expanded = 0;
1505 		init_stats();
1506 		delta_slot = 0;
1507 	}
1508 	arrival_stats_pax.rdwr( file );
1509 	arrival_stats_mail.rdwr( file );
1510 
1511 	if(  file->is_version_atleast(110, 7)  ) {
1512 		file->rdwr_byte(activity_count);
1513 	}
1514 	else if(  file->is_loading()  ) {
1515 		activity_count = 0;
1516 	}
1517 
1518 	// save name
1519 	if(  file->is_version_atleast(110, 7)  ) {
1520 		if(  file->is_saving() &&  !name  ) {
1521 			char const* fullname = desc->get_name();
1522 			file->rdwr_str(fullname);
1523 		}
1524 		else {
1525 			file->rdwr_str(name);
1526 			if(  file->is_loading()  &&  desc != NULL  &&  name == desc->get_name()  ) {
1527 				// equal to desc name
1528 				name = 0;
1529 			}
1530 		}
1531 	}
1532 }
1533 
1534 
1535 /**
1536  * let the chimney smoke, if there is something to produce
1537  * @author Hj. Malthaner
1538  */
smoke() const1539 void fabrik_t::smoke() const
1540 {
1541 	const smoke_desc_t *rada = desc->get_smoke();
1542 	if(rada) {
1543 		const koord size = desc->get_building()->get_size(0)-koord(1,1);
1544 		const uint8 rot = (4-rotate)%desc->get_building()->get_all_layouts();
1545 		koord ro = rada->get_pos_off(size,rot);
1546 		grund_t *gr = welt->lookup_kartenboden(pos_origin.get_2d()+ro);
1547 		// to get same random order on different compilers
1548 		const sint8 offsetx =  ((rada->get_xy_off(rot).x+sim_async_rand(7)-3)*OBJECT_OFFSET_STEPS)/16;
1549 		const sint8 offsety =  ((rada->get_xy_off(rot).y+sim_async_rand(7)-3)*OBJECT_OFFSET_STEPS)/16;
1550 		wolke_t *smoke =  new wolke_t(gr->get_pos(), offsetx, offsety, rada->get_images() );
1551 		gr->obj_add(smoke);
1552 		welt->sync_way_eyecandy.add( smoke );
1553 	}
1554 	// maybe sound?
1555 	if(  desc->get_sound()!=NO_SOUND  &&  welt->get_ticks()>last_sound_ms+desc->get_sound_interval_ms()  ) {
1556 		welt->play_sound_area_clipped( get_pos().get_2d(), desc->get_sound() );
1557 	}
1558 }
1559 
1560 
scale_output_production(const uint32 product,uint32 menge) const1561 uint32 fabrik_t::scale_output_production(const uint32 product, uint32 menge) const
1562 {
1563 	// prorate production based upon amount of product in storage
1564 	// but allow full production rate for storage amounts less than twice the minimum shipment size.
1565 	const uint32 maxi = output[product].max;
1566 	const uint32 actu = output[product].menge;
1567 	if(  actu<maxi  ) {
1568 		if(  actu >= (uint32)(2 * output[product].min_shipment) ) {
1569 			if(  menge>(0x7FFFFFFFu/maxi)  ) {
1570 				// avoid overflow
1571 				menge = (((maxi-actu)>>5)*(menge>>5))/(maxi>>10);
1572 			}
1573 			else {
1574 				// and that is the simple formula
1575 				menge = (menge*(maxi-actu)) / maxi;
1576 			}
1577 		}
1578 	}
1579 	else {
1580 		// overfull? No production
1581 		menge = 0;
1582 	}
1583 	return menge;
1584 }
1585 
set_power_supply(uint32 supply)1586 void fabrik_t::set_power_supply(uint32 supply)
1587 {
1588 	pumpe_t *const trans = dynamic_cast<pumpe_t *>(transformer);
1589 	if(  trans == NULL  ) {
1590 		return;
1591 	}
1592 	trans->set_power_supply(supply);
1593 }
1594 
get_power_supply() const1595 uint32 fabrik_t::get_power_supply() const
1596 {
1597 	pumpe_t *const trans = dynamic_cast<pumpe_t *>(transformer);
1598 	if(  trans == NULL  ) {
1599 		return 0;
1600 	}
1601 	return trans->get_power_supply();
1602 }
1603 
get_power_consumption() const1604 sint32 fabrik_t::get_power_consumption() const
1605 {
1606 	pumpe_t *const trans = dynamic_cast<pumpe_t *>(transformer);
1607 	if(  trans == NULL  ) {
1608 		return 0;
1609 	}
1610 	return trans->get_power_consumption();
1611 }
1612 
set_power_demand(uint32 demand)1613 void fabrik_t::set_power_demand(uint32 demand)
1614 {
1615 	senke_t *const trans = dynamic_cast<senke_t *>(transformer);
1616 	if(  trans == NULL  ) {
1617 		return;
1618 	}
1619 	trans->set_power_demand(demand);
1620 }
1621 
get_power_demand() const1622 uint32 fabrik_t::get_power_demand() const
1623 {
1624 	senke_t *const trans = dynamic_cast<senke_t *>(transformer);
1625 	if(  trans == NULL  ) {
1626 		return 0;
1627 	}
1628 	return trans->get_power_demand();
1629 }
1630 
get_power_satisfaction() const1631 sint32 fabrik_t::get_power_satisfaction() const
1632 {
1633 	senke_t *const trans = dynamic_cast<senke_t *>(transformer);
1634 	if(  trans == NULL  ) {
1635 		return 0;
1636 	}
1637 	return trans->get_power_satisfaction();
1638 }
1639 
get_power() const1640 sint64 fabrik_t::get_power() const
1641 {
1642 	sint64 power;
1643 	if(  desc->is_electricity_producer()  ) {
1644 		power = ((sint64)get_power_supply() * (sint64)get_power_consumption()) >> leitung_t::FRACTION_PRECISION;
1645 	}
1646 	else {
1647 		power = -(((sint64)get_power_demand() * (sint64)get_power_satisfaction() + (((sint64)1 << leitung_t::FRACTION_PRECISION) - 1)) >> leitung_t::FRACTION_PRECISION);
1648 	}
1649 	return power;
1650 }
1651 
1652 
input_vorrat_an(const goods_desc_t * typ)1653 sint32 fabrik_t::input_vorrat_an(const goods_desc_t *typ)
1654 {
1655 	sint32 menge = -1;
1656 
1657 	FOR(array_tpl<ware_production_t>, const& i, input) {
1658 		if (typ == i.get_typ()) {
1659 			menge = i.menge >> precision_bits;
1660 			break;
1661 		}
1662 	}
1663 
1664 	return menge;
1665 }
1666 
1667 
vorrat_an(const goods_desc_t * typ)1668 sint32 fabrik_t::vorrat_an(const goods_desc_t *typ)
1669 {
1670 	sint32 menge = -1;
1671 
1672 	FOR(array_tpl<ware_production_t>, const& i, output) {
1673 		if (typ == i.get_typ()) {
1674 			menge = i.menge >> precision_bits;
1675 			break;
1676 		}
1677 	}
1678 
1679 	return menge;
1680 }
1681 
1682 
liefere_an(const goods_desc_t * typ,sint32 menge)1683 sint32 fabrik_t::liefere_an(const goods_desc_t *typ, sint32 menge)
1684 {
1685 	if(  typ==goods_manager_t::passengers  ) {
1686 		// book pax arrival and recalculate pax boost
1687 		book_stat(menge, FAB_PAX_ARRIVED);
1688 		arrival_stats_pax.book_arrival(menge);
1689 		update_prodfactor_pax();
1690 		return menge;
1691 	}
1692 	else if(  typ==goods_manager_t::mail  ) {
1693 		// book mail arrival and recalculate mail boost
1694 		book_stat(menge, FAB_MAIL_ARRIVED);
1695 		arrival_stats_mail.book_arrival(menge);
1696 		update_prodfactor_mail();
1697 		return menge;
1698 	}
1699 	else {
1700 		// case : freight
1701 		for(  uint32 in = 0;  in < input.get_count();  in++  ){
1702 			ware_production_t& ware = input[in];
1703 			if(  ware.get_typ() == typ  ) {
1704 				ware.book_stat( -menge, FAB_GOODS_TRANSIT );
1705 
1706 				// Resolve how much normalized production arrived, rounding up (since we rounded up when we removed it).
1707 				const uint32 prod_factor = desc->get_supplier(in)->get_consumption();
1708 				const sint32 prod_delta = (sint32)((((sint64)menge << (DEFAULT_PRODUCTION_FACTOR_BITS + precision_bits)) + (sint64)(prod_factor - 1)) / (sint64)prod_factor);
1709 
1710 				// Activate inactive inputs.
1711 				if( ware.menge <= 0 ) {
1712 					inactive_inputs --;
1713 				}
1714 				ware.menge+= prod_delta;
1715 
1716 				if( welt->get_settings().get_just_in_time() >= 2 ){
1717 					// In JIT2 it is illegal to exceed input storage limit. All production that does so is discarded.
1718 					if( ware.menge > ware.max ){
1719 						const sint32 prod_comp = ware.menge - ware.max;
1720 						ware.menge = ware.max;
1721 
1722 						// Apply demand penalty. Reactivate inactive demands.
1723 						sint32 demand_old = ware.demand_buffer;
1724 						ware.demand_buffer-= prod_comp;
1725 						if( demand_old >= ware.max && ware.demand_buffer < ware.max ) inactive_demands-= 1;
1726 
1727 						// Resolve how many goods we actually used (rounding to nearest)
1728 						menge -= (sint32)(((sint64)prod_comp * (sint64)prod_factor + (1 << (DEFAULT_PRODUCTION_FACTOR_BITS + precision_bits - 1))) >> (DEFAULT_PRODUCTION_FACTOR_BITS + precision_bits));
1729 					}
1730 				}
1731 				else{
1732 					// Hajo: avoid overflow
1733 					const sint32 max = (sint32)((((sint64)FAB_MAX_INPUT << (precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS)) + (sint64)(prod_factor - 1)) / (sint64)prod_factor);
1734 					if( ware.menge >= max ) {
1735 						menge -= (sint32)(((sint64)menge * (sint64)(ware.menge - max) + (sint64)(prod_delta >> 1)) / (sint64)prod_delta);
1736 						ware.menge = max - 1;
1737 					}
1738 				}
1739 				ware.book_stat(menge, FAB_GOODS_RECEIVED);
1740 				return menge;
1741 			}
1742 		}
1743 	}
1744 	// ware "typ" wird hier nicht verbraucht
1745 	return -1;
1746 }
1747 
1748 
is_needed(const goods_desc_t * typ) const1749 sint8 fabrik_t::is_needed(const goods_desc_t *typ) const
1750 {
1751 	FOR(array_tpl<ware_production_t>, const& i, input) {
1752 		if(  i.get_typ() == typ  ) {
1753 			// Ordering logic is done in ticks. This means that every supplier is given a chance to fulfill an order (which they do so fairly).
1754 			return i.placing_orders;
1755 		}
1756 	}
1757 	return -1;  // not needed here
1758 }
1759 
1760 
is_active_lieferziel(koord k) const1761 bool fabrik_t::is_active_lieferziel( koord k ) const
1762 {
1763 	assert( lieferziele.is_contained(k) );
1764 	return 0 < ( ( 1 << lieferziele.index_of(k) ) & lieferziele_active_last_month );
1765 }
1766 
get_jit2_power_boost() const1767 sint32 fabrik_t::get_jit2_power_boost() const
1768 {
1769 	// transformer boost amount
1770 	sint32 boost = 0;
1771 
1772 	// compute power boost
1773 	if(  is_transformer_connected()  ) {
1774 		sint32 const power_satisfaction = get_power_satisfaction();
1775 		if(  power_satisfaction >= ((sint32)1 << leitung_t::FRACTION_PRECISION)  ) {
1776 			// all demand fulfilled
1777 			boost = (sint32)desc->get_electric_boost();
1778 		}
1779 		else {
1780 			// calculate bonus, rounding down
1781 			boost = (sint32)(((sint64)desc->get_electric_boost() * (sint64)power_satisfaction) >> leitung_t::FRACTION_PRECISION);
1782 		}
1783 	}
1784 
1785 	return boost;
1786 }
1787 
step(uint32 delta_t)1788 void fabrik_t::step(uint32 delta_t)
1789 {
1790 	// Only do something if advancing in time.
1791 	if(  delta_t==0  ) {
1792 		return;
1793 	}
1794 
1795 	/// Declare production control variables.
1796 
1797 	// The production effort of the factory.
1798 	sint32 prod;
1799 
1800 	// Actual production effort done.
1801 	sint32 work = 0;
1802 
1803 	// Desired production effort of factory.
1804 	sint32 want = 0;
1805 
1806 	/// Boost logic.
1807 
1808 	// Solve boosts.
1809 	switch(  boost_type  ) {
1810 		case BL_CLASSIC: {
1811 			// JIT1 implementation for power bonus.
1812 			if(  !desc->is_electricity_producer()  &&  scaled_electric_demand > 0  ) {
1813 				// one may be thinking of linking this to actual production only
1814 				prodfactor_electric = (sint32)(((sint64)desc->get_electric_boost() * (sint64)get_power_satisfaction() + (sint64)((sint64)1 << (leitung_t::FRACTION_PRECISION - 1))) >> leitung_t::FRACTION_PRECISION);
1815 			}
1816 			break;
1817 		}
1818 		case BL_POWER: {
1819 			// get desired power boost amount
1820 			sint32 const prodfactor_want = get_jit2_power_boost();
1821 
1822 			// calculate maximum change delta from change rate scaled by time
1823 			const sint32 prodfactor_change = max(BOOST_POWER_CHANGE_RATE * delta_t / PRODUCTION_DELTA_T, 1);
1824 
1825 			// limit rate of change of electricity boost (improve stability)
1826 			const sint32 prodfactor_delta = prodfactor_want - prodfactor_electric;
1827 			if(  prodfactor_delta  >  prodfactor_change  ) {
1828 				// limit increase rate
1829 				prodfactor_electric += prodfactor_change;
1830 			}
1831 			//else if(  prodfactor_delta  <  -prodfactor_change  ) {
1832 				// limit decrease rate, off because of possible exploit
1833 			//	prodfactor_electric -= prodfactor_change;
1834 			//}
1835 			else {
1836 				// no limit
1837 				prodfactor_electric = prodfactor_want;
1838 			}
1839 
1840 			break;
1841 		}
1842 		default: {
1843 			// No boost amounts to solve.
1844 			break;
1845 		}
1846 	};
1847 
1848 	// Compute boost amount.
1849 	const sint32 boost = get_prodfactor();
1850 
1851 	/// Compute base production.
1852 	{
1853 		// Calculate actual production. A remainder is used for extra precision.
1854 		const uint64 want_prod_long = (uint64)prodbase * (uint64)boost * (uint64)delta_t + (uint64)menge_remainder;
1855 		prod = (uint32)(want_prod_long >> (PRODUCTION_DELTA_T_BITS + DEFAULT_PRODUCTION_FACTOR_BITS + DEFAULT_PRODUCTION_FACTOR_BITS - fabrik_t::precision_bits));
1856 		menge_remainder = (uint32)(want_prod_long & ((1 << (PRODUCTION_DELTA_T_BITS + DEFAULT_PRODUCTION_FACTOR_BITS + DEFAULT_PRODUCTION_FACTOR_BITS - fabrik_t::precision_bits)) - 1 ));
1857 	}
1858 
1859 	/// Perform the control logic.
1860 	{
1861 		// Common logic locals go here.
1862 
1863 		// Amount of production change.
1864 		sint32 prod_delta;
1865 		// The amount of production available.
1866 		sint32 prod_comp;
1867 		// The amount of consumption available.
1868 		sint32 cons_comp = 0;
1869 
1870 		switch(  control_type  ) {
1871 			case CL_PROD_CLASSIC: {
1872 				// Classic producer logic.
1873 				currently_producing = false;
1874 
1875 				// produces something
1876 				for(  uint32 product = 0;  product < output.get_count();  product++  ) {
1877 					// source producer
1878 					const uint32 menge_out = scale_output_production( product, prod );
1879 
1880 					if(  menge_out > 0  ) {
1881 						const sint32 p = (sint32)menge_out;
1882 
1883 						// compute work factor
1884 						const sint32 work_fact = work_from_production(prod, p);
1885 
1886 						// work done is work done of maximum output
1887 						if(  work_fact  >  work  ) {
1888 							work = work_fact;
1889 						}
1890 
1891 						// produce
1892 						if(  output[product].menge < output[product].max  ) {
1893 							// to find out, if storage changed
1894 							delta_menge += p;
1895 							output[product].menge += p;
1896 							output[product].book_stat((sint64)p * (sint64)desc->get_product(0)->get_factor(), FAB_GOODS_PRODUCED);
1897 							// if less than 3/4 filled we neary always consume power
1898 							currently_producing |= (output[product].menge*4 < output[product].max*3);
1899 						}
1900 						else {
1901 							output[product].book_stat((sint64)(output[product].max - 1 - output[product].menge) * (sint64)desc->get_product(product)->get_factor(), FAB_GOODS_PRODUCED);
1902 							output[product].menge = output[product].max - 1;
1903 						}
1904 					}
1905 				}
1906 
1907 				break;
1908 			}
1909 			case CL_PROD_MANY: {
1910 				// A producer with many outputs.
1911 				if(  inactive_outputs == output.get_count()  ) {
1912 					break;
1913 				}
1914 
1915 				currently_producing = true;
1916 
1917 				for(  uint32 product = 0;  product < output.get_count();  product++  ) {
1918 					prod_comp = output[product].max - output[product].menge;
1919 
1920 					// Ignore inactive outputs.
1921 					if(  prod_comp <= 0  ) {
1922 						continue;
1923 					}
1924 
1925 					// get desired work factor
1926 					const sint32 work_fact = output[product].calculate_output_production_rate();
1927 
1928 					// compute desired production
1929 					prod_delta = work_scale_production(prod, work_fact);
1930 
1931 					// Cannot produce more than can be stored.
1932 					if(  prod_delta >= prod_comp  ) {
1933 						prod_delta = prod_comp;
1934 						inactive_outputs++;
1935 						if(  inactive_outputs == output.get_count()  ) {
1936 							currently_producing = false;
1937 						}
1938 					}
1939 
1940 					delta_menge += prod_delta;
1941 					output[product].menge += prod_delta;
1942 					output[product].book_stat((sint64)prod_delta * (sint64)desc->get_product(product)->get_factor(), FAB_GOODS_PRODUCED);
1943 
1944 					work += work_fact;
1945 				}
1946 
1947 				// normalize work with respect to output number
1948 				work /= output.get_count();
1949 
1950 				break;
1951 			}
1952 			case CL_FACT_CLASSIC: {
1953 				// Classic factory logic, work and want determined by the maximum output production rate.
1954 				currently_producing = false;
1955 
1956 				// ok, calulate maximum allowed consumption.
1957 				{
1958 					sint32 min_menge = input[0].menge;
1959 					sint32 consumed_menge = 0;
1960 					for(  uint32 index = 1;  index < input.get_count();  index++  ) {
1961 						if(  input[index].menge < min_menge  ) {
1962 							min_menge = input[index].menge;
1963 						}
1964 					}
1965 
1966 					// produces something
1967 					for(  uint32 product = 0;  product < output.get_count();  product++  ) {
1968 						// calculate production
1969 						const sint32 p_menge = (sint32)scale_output_production( product, prod );
1970 
1971 						// Want the maximum production rate, this is so correct amount is ordered.
1972 						if(  p_menge > want  ) {
1973 							want = p_menge;
1974 						}
1975 
1976 						const sint32 menge_out = p_menge < min_menge ? p_menge : min_menge;  // production smaller than possible due to consumption
1977 						if(  menge_out > consumed_menge  ) {
1978 							consumed_menge = menge_out;
1979 						}
1980 
1981 						if(  menge_out > 0  ) {
1982 							const sint32 p = menge_out;
1983 
1984 							// produce
1985 							if(  output[product].menge < output[product].max  ) {
1986 								// to find out, if storage changed
1987 								delta_menge += p;
1988 								output[product].menge += p;
1989 								output[product].book_stat((sint64)p * (sint64)desc->get_product(product)->get_factor(), FAB_GOODS_PRODUCED);
1990 								// if less than 3/4 filled we neary always consume power
1991 								currently_producing |= (output[product].menge*4 < output[product].max*3);
1992 							}
1993 							else {
1994 								output[product].book_stat((sint64)(output[product].max - 1 - output[product].menge) * (sint64)desc->get_product(product)->get_factor(), FAB_GOODS_PRODUCED);
1995 								output[product].menge = output[product].max - 1;
1996 							}
1997 						}
1998 					}
1999 
2000 					// and finally consume stock
2001 					for(  uint32 index = 0;  index < input.get_count();  index++  ) {
2002 						const uint32 v = consumed_menge;
2003 
2004 						if(  (uint32)input[index].menge > v + 1  ) {
2005 							input[index].menge -= v;
2006 							input[index].book_stat((sint64)v * (sint64)desc->get_supplier(index)->get_consumption(), FAB_GOODS_CONSUMED);
2007 						}
2008 						else {
2009 							input[index].book_stat((sint64)input[index].menge * (sint64)desc->get_supplier(index)->get_consumption(), FAB_GOODS_CONSUMED);
2010 							input[index].menge = 0;
2011 						}
2012 					}
2013 
2014 					// work done is consumption rate
2015 					work = work_from_production(prod, consumed_menge);
2016 				}
2017 
2018 				break;
2019 			}
2020 			case CL_FACT_MANY: {
2021 				// Logic for a factory with many outputs. Work and want are based on weighted output rate so is more complicated.
2022 				if(  inactive_outputs == output.get_count()  ) {
2023 					break;
2024 				}
2025 				{
2026 					const bool no_input = inactive_inputs > 0;
2027 
2028 					// Determine minimum input in form of production from all outputs. This limits production.
2029 					// Determine minimum demand work rate from all inputs. This limits production rate.
2030 					sint32 demand_work_limt = input[0].calculate_demand_production_rate();
2031 					cons_comp = input[0].menge;
2032 					for(  uint32 index = 1;  index < input.get_count();  index++  ) {
2033 						if(  input[index].menge < cons_comp  ) {
2034 							cons_comp = input[index].menge;
2035 						}
2036 						sint32 const work_limit = input[index].calculate_demand_production_rate();
2037 						if(  work_limit < demand_work_limt  ) {
2038 							demand_work_limt = work_limit;
2039 						}
2040 
2041 					}
2042 					cons_comp *= output.get_count();
2043 
2044 					if(  !no_input  ) {
2045 						currently_producing = true;
2046 					}
2047 
2048 					for(  uint32 product = 0;  product < output.get_count();  product++  ) {
2049 						prod_comp = output[product].max - output[product].menge;
2050 
2051 						// Ignore inactive outputs.
2052 						if(  prod_comp <= 0  ) {
2053 							continue;
2054 						}
2055 
2056 						// get desired work factor
2057 						const sint32 work_fact = min(output[product].calculate_output_production_rate(), demand_work_limt);
2058 
2059 						// compute desired production
2060 						prod_delta = work_scale_production(prod, work_fact);
2061 
2062 						// limit to maximum storage
2063 						if(  prod_delta > prod_comp  ) {
2064 							prod_delta = prod_comp;
2065 						}
2066 
2067 						// credit desired production for want
2068 						want += prod_delta;
2069 
2070 						// skip producing anything if no input
2071 						if(  no_input  ) {
2072 							continue;
2073 						}
2074 
2075 						// enforce input limits on production
2076 						if(  prod_delta > cons_comp  ) {
2077 							// not enough input
2078 							prod_delta = cons_comp;
2079 							cons_comp = 0;
2080 						}
2081 						else {
2082 							// enough input
2083 							cons_comp -= prod_delta;
2084 						}
2085 
2086 						// register inactive outputs
2087 						if(  prod_delta == prod_comp  ) {
2088 							inactive_outputs++;
2089 							if(  inactive_outputs == output.get_count()  ) {
2090 								currently_producing = false;
2091 							}
2092 						}
2093 
2094 						// credit output work done
2095 						work += prod_delta;
2096 
2097 						// Produce output
2098 						delta_menge += prod_delta;
2099 						output[product].menge += prod_delta;
2100 						output[product].book_stat((sint64)prod_delta * (sint64)desc->get_product(product)->get_factor(), FAB_GOODS_PRODUCED);
2101 					}
2102 
2103 					// normalize want with respect to output number
2104 					want /= output.get_count();
2105 
2106 					// skip consuming anything if no input
2107 					if(  no_input  ) {
2108 						break;
2109 					}
2110 
2111 					// compute work done
2112 					const sint32 consumed = work / output.get_count();
2113 					work = work_from_production(prod, consumed);
2114 
2115 					// consume inputs
2116 					for(  uint32 index = 0;  index < input.get_count();  index++  ) {
2117 						input[index].menge -= consumed;
2118 						input[index].book_stat((sint64)consumed * (sint64)desc->get_supplier(index)->get_consumption(), FAB_GOODS_CONSUMED);
2119 
2120 						// register inactive inputs
2121 						if(  input[index].menge <= 0  ) {
2122 							currently_producing = false;
2123 							input[index].menge = 0;
2124 							inactive_inputs ++;
2125 						}
2126 					}
2127 				}
2128 				break;
2129 			}
2130 			case CL_CONS_CLASSIC: {
2131 				uint32 power = 0;
2132 
2133 				// Classic consumer logic.
2134 				currently_producing = false;
2135 
2136 				if(  desc->is_electricity_producer()  ) {
2137 					// power station => start with no production
2138 					power = 0;
2139 				}
2140 
2141 				// Always want to consume at rate of prod.
2142 				want = prod;
2143 
2144 				// finally consume stock
2145 				for(  uint32 index = 0;  index < input.get_count();  index++  ) {
2146 					const uint32 v = prod;
2147 
2148 					if(  (uint32)input[index].menge > v + 1  ) {
2149 						input[index].menge -= v;
2150 						input[index].book_stat((sint64)v * (sint64)desc->get_supplier(index)->get_consumption(), FAB_GOODS_CONSUMED);
2151 						currently_producing = true;
2152 						if(  desc->is_electricity_producer()  ) {
2153 							// power station => produce power
2154 							power += (uint32)( ((sint64)scaled_electric_demand * (sint64)(DEFAULT_PRODUCTION_FACTOR + prodfactor_pax + prodfactor_mail)) >> DEFAULT_PRODUCTION_FACTOR_BITS );
2155 						}
2156 						work += 1 << WORK_BITS;
2157 						// to find out, if storage changed
2158 						delta_menge += v;
2159 					}
2160 					else {
2161 						if(  desc->is_electricity_producer()  ) {
2162 							// power station => produce power
2163 							power += (uint32)( (((sint64)scaled_electric_demand * (sint64)(DEFAULT_PRODUCTION_FACTOR + prodfactor_pax + prodfactor_mail)) >> DEFAULT_PRODUCTION_FACTOR_BITS) * input[index].menge / (v + 1) );
2164 						}
2165 						delta_menge += input[index].menge;
2166 						work += work_from_production(prod, input[index].menge);
2167 						input[index].book_stat((sint64)input[index].menge * (sint64)desc->get_supplier(index)->get_consumption(), FAB_GOODS_CONSUMED);
2168 						input[index].menge = 0;
2169 					}
2170 				}
2171 
2172 				// normalize work with respect to input number
2173 				work /= input.get_count();
2174 				set_power_supply(power);
2175 
2176 				break;
2177 			}
2178 			case CL_CONS_MANY: {
2179 				// Consumer logic for many inputs. Work done is based on the average consumption of all inputs.
2180 
2181 				// always consume prod
2182 				want = prod;
2183 
2184 				// Do nothing if we cannot consume anything.
2185 				if(  inactive_inputs == input.get_count()  ) {
2186 					break;
2187 				}
2188 
2189 				currently_producing = true;
2190 
2191 				for(  uint32 index = 0;  index < input.get_count();  index++  ) {
2192 					// Only process active inputs;
2193 					if(  input[index].menge <= 0  ) {
2194 						continue;
2195 					}
2196 
2197 					sint32 const consumption_prod = work_scale_production(prod, input[index].calculate_demand_production_rate());
2198 
2199 					// limit consumption to minimum of production or storage
2200 					prod_delta = input[index].menge > consumption_prod ? consumption_prod : input[index].menge;
2201 
2202 					// add to work done
2203 					work += prod_delta;
2204 
2205 					// consume input
2206 					delta_menge += prod_delta;
2207 					input[index].menge -= prod_delta;
2208 					input[index].book_stat((sint64)prod_delta * (sint64)desc->get_supplier(index)->get_consumption(), FAB_GOODS_CONSUMED);
2209 
2210 					// register inactive input
2211 					if(  input[index].menge <= 0  ) {
2212 						inactive_inputs++;
2213 						if(  inactive_inputs == input.get_count()  ) {
2214 							currently_producing = false;
2215 						}
2216 					}
2217 				}
2218 
2219 				// normalise and convert work into work factor
2220 				work = work_from_production(prod, work / input.get_count());
2221 
2222 				if(  desc->is_electricity_producer()  ) {
2223 					// compute power production
2224 					uint64 pp = ((uint64)scaled_electric_demand * (uint64)boost * (uint64)work) >> (DEFAULT_PRODUCTION_FACTOR_BITS + WORK_BITS);
2225 					set_power_supply((uint32)pp);
2226 				}
2227 
2228 				break;
2229 			}
2230 			case CL_ELEC_PROD: {
2231 				// A simple no input electricity producer, like a solar array.
2232 
2233 				// always maximum work
2234 				currently_producing = true;
2235 				work = 1 << WORK_BITS;
2236 				delta_menge += prod;
2237 
2238 				// compute power production
2239 				uint64 pp = ((uint64)scaled_electric_demand * (uint64)boost) >> DEFAULT_PRODUCTION_FACTOR_BITS;
2240 				set_power_supply((uint32)pp);
2241 
2242 				break;
2243 			}
2244 			case CL_ELEC_CLASSIC: {
2245 				// Classic no input power producer.
2246 				currently_producing = false;
2247 				work = 1 << WORK_BITS;
2248 
2249 				// power station? => produce power
2250 				if(  desc->is_electricity_producer()  ) {
2251 					currently_producing = true;
2252 					set_power_supply((uint32)( ((sint64)scaled_electric_demand * (sint64)(DEFAULT_PRODUCTION_FACTOR + prodfactor_pax + prodfactor_mail)) >> DEFAULT_PRODUCTION_FACTOR_BITS ));
2253 				}
2254 				break;
2255 			}
2256 			case CL_NONE:
2257 			default: {
2258 				// None always produces maximum for whatever reason. Also default.
2259 				work = 1 << WORK_BITS;
2260 				break;
2261 			}
2262 		}
2263 	}
2264 
2265 	/// Ordering logic.
2266 	switch(  demand_type  ) {
2267 		case DL_SYNC: {
2268 			// Synchronous ordering. All buffers are filled the same amount in parallel based on desired work factor.
2269 
2270 			if(  want == 0  ||  inactive_demands > 0  ) {
2271 				// No ordering if any are overfull or there is no want.
2272 				break;
2273 			}
2274 
2275 			for(  uint32 index = 0;  index < input.get_count();  index++  ) {
2276 				input[index].demand_buffer += want;
2277 
2278 				// register inactive demand buffer
2279 				if(  input[index].demand_buffer >= input[index].max  ) {
2280 					inactive_demands++;
2281 				}
2282 			}
2283 			break;
2284 		}
2285 		case DL_ASYNC: {
2286 			// Asynchronous ordering. Each buffer tries to order scaled back by the demand work factor.
2287 
2288 			if(  want == 0  ||  inactive_demands == input.get_count()  ) {
2289 				// No ordering if all are overfull or no want.
2290 				break;
2291 			}
2292 
2293 			for(  uint32 index = 0;  index < input.get_count();  index++  ) {
2294 				// Skip inactive demand buffers.
2295 				if(  input[index].demand_buffer >= input[index].max  ) {
2296 					continue;
2297 				}
2298 				input[index].demand_buffer +=  max(work_scale_production(want, input[index].calculate_demand_production_rate()), 1);
2299 
2300 				// register inactive demand buffer
2301 				if(  input[index].demand_buffer >= input[index].max  ) {
2302 					inactive_demands++;
2303 				}
2304 			}
2305 			break;
2306 		}
2307 		default: {
2308 			// Nothing to order.
2309 			break;
2310 		}
2311 	}
2312 
2313 	/// Book the weighted sums for statistics.
2314 
2315 	book_weighted_sums( delta_t );
2316 
2317 	/// Power ordering logic.
2318 
2319 	switch(  boost_type  ) {
2320 		case BL_CLASSIC: {
2321 			// draw a fixed amount of power when working sufficiently, otherwise draw no power
2322 			if(  !desc->is_electricity_producer()  ) {
2323 				if(  currently_producing  ) {
2324 					set_power_demand(scaled_electric_demand);
2325 				}
2326 				else {
2327 					set_power_demand(0);
2328 				}
2329 			}
2330 			break;
2331 		}
2332 		case BL_POWER: {
2333 			// compute power demand
2334 			uint64 pd = ((uint64)scaled_electric_demand * (uint64)boost * (uint64)work) >> (DEFAULT_PRODUCTION_FACTOR_BITS + WORK_BITS);
2335 			set_power_demand((uint32)pd);
2336 
2337 			break;
2338 		}
2339 		default: {
2340 			// No power is ordered.
2341 			break;
2342 		}
2343 	};
2344 
2345 	/// Periodic tasks.
2346 
2347 	delta_sum += delta_t;
2348 	if(  delta_sum > PRODUCTION_DELTA_T  ) {
2349 		delta_sum = delta_sum % PRODUCTION_DELTA_T;
2350 
2351 		// distribute, if  min shipment waiting.
2352 		for(  uint32 product = 0;  product < output.get_count();  product++  ) {
2353 			// either more than ten or nearly full (if there are less than ten output)
2354 			if(  output[product].menge >= output[product].min_shipment  ) {
2355 				verteile_waren( product );
2356 				INT_CHECK("simfab 636");
2357 			}
2358 		}
2359 
2360 		// Order required inputs.
2361 		for(  uint32 index = 0;  index < input.get_count();  index++  ) {
2362 			switch(  demand_type  ) {
2363 				case DL_SYNC:
2364 				case DL_ASYNC: {
2365 					// Orders based on demand buffer.
2366 					input[index].placing_orders = (input[index].demand_buffer > 0);
2367 					break;
2368 				}
2369 				case DL_OLD: {
2370 					// Orders based on storage and maximum transit.
2371 					input[index].placing_orders = (input[index].menge < input[index].max  &&  (input[index].max_transit == 0  ||  input[index].get_in_transit() < input[index].max_transit) );
2372 					break;
2373 				}
2374 				default: {
2375 					// Unknown order logic?
2376 					break;
2377 				}
2378 			}
2379 		}
2380 
2381 		recalc_factory_status();
2382 
2383 		// rescale delta_menge here: all products should be produced at least once
2384 		// (if consumer only: all supplements should be consumed once)
2385 		const uint32 min_change = output.empty() ? input.get_count() : output.get_count();
2386 
2387 		if(  (delta_menge >> fabrik_t::precision_bits) > min_change  ) {
2388 			// we produced some real quantity => smoke
2389 			smoke();
2390 
2391 			// Knightly : chance to expand every 256 rounds of activities, after which activity count will return to 0 (overflow behaviour)
2392 			if(  (++activity_count)==0  ) {
2393 				if(  desc->get_field_group()  ) {
2394 					if(  fields.get_count()<desc->get_field_group()->get_max_fields()  ) {
2395 						// spawn new field with given probability
2396 						add_random_field(desc->get_field_group()->get_probability());
2397 					}
2398 				}
2399 				else {
2400 					if(  times_expanded < desc->get_expand_times()  ) {
2401 						if(  simrand(10000) < desc->get_expand_probability()  ) {
2402 							set_base_production( prodbase + desc->get_expand_minimum() + simrand( desc->get_expand_range() ) );
2403 							++times_expanded;
2404 						}
2405 					}
2406 				}
2407 			}
2408 
2409 			INT_CHECK("simfab 558");
2410 			// reset for next cycle
2411 			delta_menge = 0;
2412 		}
2413 	}
2414 
2415 	/// Knightly : advance arrival slot at calculated interval and recalculate boost where necessary
2416 	delta_slot += delta_t;
2417 	const sint32 periods = welt->get_settings().get_factory_arrival_periods();
2418 	const sint32 slot_interval = (1 << (PERIOD_BITS - SLOT_BITS)) * periods;
2419 	while(  delta_slot>slot_interval  ) {
2420 		delta_slot -= slot_interval;
2421 		const sint32 pax_result = arrival_stats_pax.advance_slot();
2422 		if(  pax_result&ARRIVALS_CHANGED  ||  (periods>1  &&  pax_result&ACTIVE_SLOTS_INCREASED  &&  arrival_stats_pax.get_active_slots()*periods>SLOT_COUNT  )  ) {
2423 			update_prodfactor_pax();
2424 		}
2425 		const sint32 mail_result = arrival_stats_mail.advance_slot();
2426 		if(  mail_result&ARRIVALS_CHANGED  ||  (periods>1  &&  mail_result&ACTIVE_SLOTS_INCREASED  &&  arrival_stats_mail.get_active_slots()*periods>SLOT_COUNT  )  ) {
2427 			update_prodfactor_mail();
2428 		}
2429 	}
2430 }
2431 
2432 
2433 class distribute_ware_t
2434 {
2435 public:
2436 	ware_t ware;             /// goods to be routed to consumer
2437 	halthandle_t halt;       /// potential start halt
2438 	sint32 space_left;       /// free space at halt
2439 	sint32 amount_waiting;   /// waiting goods at halt for same destination as ware
2440 private:
2441 	sint32 ratio_free_space; /// ratio of free space at halt (=0 for overflowing station)
2442 
2443 public:
distribute_ware_t(halthandle_t h,sint32 l,sint32 t,sint32 a,ware_t w)2444 	distribute_ware_t( halthandle_t h, sint32 l, sint32 t, sint32 a, ware_t w )
2445 	{
2446 		halt = h;
2447 		space_left = l;
2448 		amount_waiting = a;
2449 		ware = w;
2450 		// ensure overfull stations compare equal allowing tie breaker clause (amount waiting)
2451 		sint32 space_total = t > 0 ? t : 1;
2452 		ratio_free_space = space_left > 0 ? ((sint64)space_left << fabrik_t::precision_bits) / space_total : 0;
2453 	}
distribute_ware_t()2454 	distribute_ware_t() {}
2455 
compare(const distribute_ware_t & dw1,const distribute_ware_t & dw2)2456 	static bool compare(const distribute_ware_t &dw1, const distribute_ware_t &dw2)
2457 	{
2458 		return  (dw1.ratio_free_space > dw2.ratio_free_space)
2459 				||  (dw1.ratio_free_space == dw2.ratio_free_space  &&  dw1.amount_waiting <= dw2.amount_waiting);
2460 	}
2461 };
2462 
2463 
2464 /**
2465  * distribute stuff to all best destination
2466  * @author Hj. Malthaner
2467  */
verteile_waren(const uint32 product)2468 void fabrik_t::verteile_waren(const uint32 product)
2469 {
2470 	// wohin liefern ?
2471 	if(  lieferziele.empty()  ) {
2472 		return;
2473 	}
2474 
2475 	// not connected?
2476 	const planquadrat_t *plan = welt->access(pos.get_2d());
2477 	if(  plan == NULL  ) {
2478 		dbg->fatal("fabrik_t::verteile_waren", "%s has not distribution target", get_name() );
2479 	}
2480 	if(  plan->get_haltlist_count() == 0  ) {
2481 		return;
2482 	}
2483 
2484 	static vector_tpl<distribute_ware_t> dist_list(16);
2485 	dist_list.clear();
2486 
2487 	// to distribute to all target equally, we use this counter, for the source hald, and target factory, to try first
2488 	output[product].index_offset++;
2489 
2490 	/* prissi: distribute goods to factory
2491 	 * that has not an overflowing input storage
2492 	 * also prevent stops from overflowing, if possible
2493 	 * Since we can called with menge>max/2 are at least 10 are there, we must first limit the amount we distribute
2494 	 */
2495 	//sint32 menge = min( (prodbase > 640 ? (prodbase>>6) : 10), output[product].menge >> precision_bits );
2496 
2497 	// We already know the distribution amount. However it has to be converted from factory units into real units.
2498 	const uint32 prod_factor = desc->get_product(product)->get_factor();
2499 	sint32 menge = (sint32)(((sint64)output[product].min_shipment * (sint64)(prod_factor)) >> (DEFAULT_PRODUCTION_FACTOR_BITS + precision_bits));
2500 
2501 	// ok, first generate list of possible destinations
2502 	const halthandle_t *haltlist = plan->get_haltlist();
2503 	for(  unsigned i=0;  i<plan->get_haltlist_count();  i++  ) {
2504 		halthandle_t halt = haltlist[(i + output[product].index_offset) % plan->get_haltlist_count()];
2505 
2506 		if(  !halt->get_ware_enabled()  ) {
2507 			continue;
2508 		}
2509 
2510 		// �ber alle Ziele iterieren
2511 		for(  uint32 n=0;  n<lieferziele.get_count();  n++  ) {
2512 			// prissi: this way, the halt, that is tried first, will change. As a result, if all destinations are empty, it will be spread evenly
2513 			const koord lieferziel = lieferziele[(n + output[product].index_offset) % lieferziele.get_count()];
2514 			fabrik_t * ziel_fab = get_fab(lieferziel);
2515 
2516 			if(  ziel_fab  ) {
2517 				const sint8 needed = ziel_fab->is_needed(output[product].get_typ());
2518 				if(  needed>=0  ) {
2519 					ware_t ware(output[product].get_typ());
2520 					ware.menge = menge;
2521 					ware.to_factory = 1;
2522 					ware.set_zielpos( lieferziel );
2523 
2524 					unsigned w;
2525 					// find the index in the target factory
2526 					for(  w = 0;  w < ziel_fab->get_input().get_count()  &&  ziel_fab->get_input()[w].get_typ() != ware.get_desc();  w++  ) {
2527 						// empty
2528 					}
2529 
2530 					// if only overflown factories found => deliver to first
2531 					// else deliver to non-overflown factory
2532 					if(  !(welt->get_settings().get_just_in_time() != 0)  ) {
2533 						// without production stop when target overflowing, distribute to least overflow target
2534 						const sint32 fab_left = ziel_fab->get_input()[w].max - ziel_fab->get_input()[w].menge;
2535 						dist_list.insert_ordered( distribute_ware_t( halt, fab_left, ziel_fab->get_input()[w].max, (sint32)halt->get_ware_fuer_zielpos(output[product].get_typ(),ware.get_zielpos()), ware ), distribute_ware_t::compare );
2536 
2537 					}
2538 					else if(  needed > 0  ) {
2539 						// we are not overflowing: Station can only store up to a maximum amount of goods per square
2540 						const sint32 halt_left = (sint32)halt->get_capacity(2) - (sint32)halt->get_ware_summe(ware.get_desc());
2541 						dist_list.insert_ordered( distribute_ware_t( halt, halt_left, halt->get_capacity(2), (sint32)halt->get_ware_fuer_zielpos(output[product].get_typ(),ware.get_zielpos()), ware ), distribute_ware_t::compare );
2542 					}
2543 				}
2544 			}
2545 		}
2546 	}
2547 
2548 	// Auswertung der Ergebnisse
2549 	if(  !dist_list.empty()  ) {
2550 		distribute_ware_t *best = NULL;
2551 		FOR(vector_tpl<distribute_ware_t>, & i, dist_list) {
2552 			// now search route
2553 			int const result = haltestelle_t::search_route(&i.halt, 1U, welt->get_settings().is_no_routing_over_overcrowding(), i.ware);
2554 			if(  result == haltestelle_t::ROUTE_OK  ||  result == haltestelle_t::ROUTE_WALK  ) {
2555 				// we can deliver to this destination
2556 				best = &i;
2557 				break;
2558 			}
2559 		}
2560 
2561 		if(  best == NULL  ) {
2562 			return; // no route for any destination
2563 		}
2564 
2565 		halthandle_t &best_halt = best->halt;
2566 		ware_t       &best_ware = best->ware;
2567 
2568 		// now process found route
2569 		const sint32 space_left = (welt->get_settings().get_just_in_time() != 0 ) ? best->space_left : (sint32)best_halt->get_capacity(2) - (sint32)best_halt->get_ware_summe(best_ware.get_desc());
2570 		menge = min( menge, 9 + space_left );
2571 		// ensure amount is not negative ...
2572 		if(  menge<0  ) {
2573 			menge = 0;
2574 		}
2575 		// since it is assigned here to an unsigned variable!
2576 		best_ware.menge = menge;
2577 
2578 		if(  space_left<0  ) {
2579 			// find, what is most waiting here from us
2580 			ware_t most_waiting(output[product].get_typ());
2581 			most_waiting.menge = 0;
2582 			FOR(vector_tpl<koord>, const& n, lieferziele) {
2583 				uint32 const amount = best_halt->get_ware_fuer_zielpos(output[product].get_typ(), n);
2584 				if(  amount > most_waiting.menge  ) {
2585 					most_waiting.set_zielpos(n);
2586 					most_waiting.menge = amount;
2587 				}
2588 			}
2589 
2590 			//  we will reroute some goods
2591 			if(  best->amount_waiting==0  &&  most_waiting.menge>0  ) {
2592 				// remove something from the most waiting goods
2593 				if(  best_halt->recall_ware( most_waiting, min((sint32)(most_waiting.menge/2), 1 - space_left) )  ) {
2594 					best_ware.menge += most_waiting.menge;
2595 				}
2596 				else {
2597 					// overcrowded with other stuff (not from us)
2598 					return;
2599 				}
2600 
2601 				// refund JIT2 demand buffers for rerouted goods
2602 				if(  welt->get_settings().get_just_in_time() >= 2  ) {
2603 					// locate destination factory
2604 					fabrik_t *fab = get_fab( most_waiting.get_zielpos() );
2605 
2606 					if(  fab  ) {
2607 						for(  uint32 input = 0;  input < fab->input.get_count();  input++  ) {
2608 							ware_production_t& w = fab->input[input];
2609 							if (  w.get_typ()->get_index() == most_waiting.get_index()  ) {
2610 								// correct ware to refund found
2611 
2612 								// refund demand buffers, deactivating if required
2613 								const uint32 prod_factor = fab->desc->get_supplier(input)->get_consumption();
2614 								const sint32 prod_delta = (sint32)((((sint64)(most_waiting.menge) << (DEFAULT_PRODUCTION_FACTOR_BITS + precision_bits)) + (sint64)(prod_factor - 1)) / (sint64)prod_factor);
2615 								const sint32 demand = w.demand_buffer;
2616 								w.demand_buffer += prod_delta;
2617 								if(  demand < w.max  &&  w.demand_buffer >= w.max  ) {
2618 									fab->inactive_demands++;
2619 								}
2620 							}
2621 
2622 							// refund successful
2623 							break;
2624 						}
2625 					}
2626 				}
2627 			}
2628 			else {
2629 				// overflowed with our own ware and we have still nearly full stock
2630 //				if(  output[product].menge>= (3 * output[product].max) >> 2  ) {
2631 					/* Station too full, notify player */
2632 //					best_halt->bescheid_station_voll();
2633 //				}
2634 // for now report only serious overcrowding on transfer stops
2635 				return;
2636 			}
2637 		}
2638 
2639 		// Since menge might have been mutated, it must be converted back. This might introduce some error with some prod factors which is always rounded up.
2640 		const sint32 prod_delta = (sint32)((((sint64)menge << (DEFAULT_PRODUCTION_FACTOR_BITS + precision_bits)) + (sint64)(prod_factor - 1)) / (sint64)prod_factor);
2641 
2642 		// If the output is inactive, reactivate it
2643 		if( output[product].menge == output[product].max && prod_delta > 0 ) inactive_outputs-= 1;
2644 
2645 		output[product].menge -= prod_delta;
2646 
2647 		best_halt->starte_mit_route(best_ware);
2648 		best_halt->recalc_status();
2649 		fabrik_t::apply_transit( &best_ware );
2650 		// add as active destination
2651 		lieferziele_active_last_month |= (1 << lieferziele.index_of(best_ware.get_zielpos()));
2652 		output[product].book_stat(best_ware.menge, FAB_GOODS_DELIVERED);
2653 	}
2654 }
2655 
2656 
new_month()2657 void fabrik_t::new_month()
2658 {
2659 	// calculate weighted averages
2660 	if(  aggregate_weight > 0  ) {
2661 		set_stat( weighted_sum_production / aggregate_weight, FAB_PRODUCTION );
2662 		set_stat( weighted_sum_boost_electric / aggregate_weight, FAB_BOOST_ELECTRIC );
2663 		set_stat( weighted_sum_boost_pax / aggregate_weight, FAB_BOOST_PAX );
2664 		set_stat( weighted_sum_boost_mail / aggregate_weight, FAB_BOOST_MAIL );
2665 		set_stat( weighted_sum_power / aggregate_weight, FAB_POWER );
2666 	}
2667 
2668 	// update statistics for input and output goods
2669 	for(  uint32 in = 0;  in < input.get_count();  in++  ){
2670 		input[in].roll_stats( desc->get_supplier(in)->get_consumption(), aggregate_weight );
2671 	}
2672 	for(  uint32 out = 0;  out < output.get_count();  out++  ){
2673 		output[out].roll_stats( desc->get_product(out)->get_factor(), aggregate_weight );
2674 	}
2675 	lieferziele_active_last_month = 0;
2676 
2677 	// advance statistics a month
2678 	for(  int s = 0;  s < MAX_FAB_STAT;  ++s  ) {
2679 		for(  int m = MAX_MONTH - 1;  m > 0;  --m  ) {
2680 			statistics[m][s] = statistics[m-1][s];
2681 		}
2682 		statistics[0][s] = 0;
2683 	}
2684 
2685 	weighted_sum_production = 0;
2686 	weighted_sum_boost_electric = 0;
2687 	weighted_sum_boost_pax = 0;
2688 	weighted_sum_boost_mail = 0;
2689 	weighted_sum_power = 0;
2690 	aggregate_weight = 0;
2691 
2692 	// restore the current values
2693 	set_stat( get_current_production(), FAB_PRODUCTION );
2694 	set_stat( prodfactor_electric, FAB_BOOST_ELECTRIC );
2695 	set_stat( prodfactor_pax, FAB_BOOST_PAX );
2696 	set_stat( prodfactor_mail, FAB_BOOST_MAIL );
2697 	set_stat( get_power(), FAB_POWER );
2698 
2699 	// since target cities' population may be increased -> re-apportion pax/mail demand
2700 	recalc_demands_at_target_cities();
2701 }
2702 
2703 
2704 // static !
2705 uint8 fabrik_t::status_to_color[5] = {COL_RED, COL_ORANGE, COL_GREEN, COL_YELLOW, COL_WHITE };
2706 
2707 #define FL_WARE_NULL           1
2708 #define FL_WARE_ALLENULL       2
2709 #define FL_WARE_LIMIT          4
2710 #define FL_WARE_ALLELIMIT      8
2711 #define FL_WARE_UEBER75        16
2712 #define FL_WARE_ALLEUEBER75    32
2713 #define FL_WARE_FEHLT_WAS      64
2714 
2715 
2716 /* returns the status of the current factory, as well as output */
recalc_factory_status()2717 void fabrik_t::recalc_factory_status()
2718 {
2719 	uint64 warenlager;
2720 	char status_ein;
2721 	char status_aus;
2722 
2723 	int haltcount=welt->access(pos.get_2d())->get_haltlist_count();
2724 
2725 	// set bits for input
2726 	warenlager = 0;
2727 	total_transit = 0;
2728 	status_ein = FL_WARE_ALLELIMIT;
2729 	uint32 i = 0;
2730 	FOR( array_tpl<ware_production_t>, const& j, input ) {
2731 		if(  j.menge >= j.max  ) {
2732 			status_ein |= FL_WARE_LIMIT;
2733 		}
2734 		else {
2735 			status_ein &= ~FL_WARE_ALLELIMIT;
2736 		}
2737 		warenlager+= (uint64)j.menge * (uint64)(desc->get_supplier(i++)->get_consumption());
2738 		total_transit += j.get_in_transit();
2739 		if(  (j.menge >> fabrik_t::precision_bits) == 0  ) {
2740 			status_ein |= FL_WARE_FEHLT_WAS;
2741 		}
2742 
2743 	}
2744 	warenlager >>= fabrik_t::precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS;
2745 	if(  warenlager==0  ) {
2746 		status_ein |= FL_WARE_ALLENULL;
2747 	}
2748 	total_input = (uint32)warenlager;
2749 
2750 	// one ware missing, but producing
2751 	if(  status_ein & FL_WARE_FEHLT_WAS  &&  !output.empty()  &&  haltcount > 0  ) {
2752 		status = bad;
2753 		return;
2754 	}
2755 
2756 	// set bits for output
2757 	warenlager = 0;
2758 	status_aus = FL_WARE_ALLEUEBER75|FL_WARE_ALLENULL;
2759 	i = 0;
2760 	FOR( array_tpl<ware_production_t>, const& j, output ) {
2761 		if(  j.menge > 0  ) {
2762 
2763 			status_aus &= ~FL_WARE_ALLENULL;
2764 			if(  j.menge >= 0.75 * j.max  ) {
2765 				status_aus |= FL_WARE_UEBER75;
2766 			}
2767 			else {
2768 				status_aus &= ~FL_WARE_ALLEUEBER75;
2769 			}
2770 			warenlager += (uint64)j.menge * (uint64)(desc->get_product(i)->get_factor());
2771 			status_aus &= ~FL_WARE_ALLENULL;
2772 		}
2773 		else {
2774 			// menge = 0
2775 			status_aus &= ~FL_WARE_ALLEUEBER75;
2776 		}
2777 	}
2778 	warenlager >>= fabrik_t::precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS;
2779 	total_output = (uint32)warenlager;
2780 
2781 	// now calculate status bar
2782 	if(  input.empty()  ) {
2783 		// does not consume anything, should just produce
2784 
2785 		if(  output.empty()  ) {
2786 			// does also not produce anything
2787 			status = nothing;
2788 		}
2789 		else if(  status_aus&FL_WARE_ALLEUEBER75  ||  status_aus&FL_WARE_UEBER75  ) {
2790 			status = inactive;	// not connected?
2791 			if(haltcount>0) {
2792 				if(status_aus&FL_WARE_ALLEUEBER75) {
2793 					status = bad;	// connect => needs better service
2794 				}
2795 				else {
2796 					status = medium;	// connect => needs better service for at least one product
2797 				}
2798 			}
2799 		}
2800 		else {
2801 			status = good;
2802 		}
2803 	}
2804 	else if(  output.empty()  ) {
2805 		// nothing to produce
2806 
2807 		if(status_ein&FL_WARE_ALLELIMIT) {
2808 			// we assume not served
2809 			status = bad;
2810 		}
2811 		else if(status_ein&FL_WARE_LIMIT) {
2812 			// served, but still one at limit
2813 			status = medium;
2814 		}
2815 		else if(status_ein&FL_WARE_ALLENULL) {
2816 			status = inactive;	// assume not served
2817 			if(haltcount>0) {
2818 				// there is a halt => needs better service
2819 				status = bad;
2820 			}
2821 		}
2822 		else {
2823 			status = good;
2824 		}
2825 	}
2826 	else {
2827 		// produces and consumes
2828 		if((status_ein&FL_WARE_ALLELIMIT)!=0  &&  (status_aus&FL_WARE_ALLEUEBER75)!=0) {
2829 			status = bad;
2830 		}
2831 		else if((status_ein&FL_WARE_ALLELIMIT)!=0  ||  (status_aus&FL_WARE_ALLEUEBER75)!=0) {
2832 			status = medium;
2833 		}
2834 		else if((status_ein&FL_WARE_ALLENULL)!=0  &&  (status_aus&FL_WARE_ALLENULL)!=0) {
2835 			// not producing
2836 			status = inactive;
2837 		}
2838 		else if(haltcount>0  &&  ((status_ein&FL_WARE_ALLENULL)!=0  ||  (status_aus&FL_WARE_ALLENULL)!=0)) {
2839 			// not producing but out of supply
2840 			status = medium;
2841 		}
2842 		else {
2843 			status = good;
2844 		}
2845 	}
2846 }
2847 
2848 
open_info_window()2849 void fabrik_t::open_info_window()
2850 {
2851 	gebaeude_t *gb = welt->lookup(pos)->find<gebaeude_t>();
2852 	create_win(new fabrik_info_t(this, gb), w_info, (ptrdiff_t)this );
2853 }
2854 
2855 
info_prod(cbuffer_t & buf) const2856 void fabrik_t::info_prod(cbuffer_t& buf) const
2857 {
2858 	buf.clear();
2859 	buf.append( translator::translate("Durchsatz") );
2860 	buf.append(get_current_production(), 0);
2861 	buf.append( translator::translate("units/day") );
2862 	buf.append("\n");
2863 	buf.printf(translator::translate("Produces: %.1f units/minute"),
2864 		get_production_per_second() * 60.0
2865 	);
2866 
2867 	if (!output.empty()) {
2868 		buf.append("\n\n");
2869 		buf.append(translator::translate("Produktion"));
2870 
2871 		for (uint32 index = 0; index < output.get_count(); index++) {
2872 			goods_desc_t const *const type = output[index].get_typ();
2873 			sint64 const pfactor = (sint64)desc->get_product(index)->get_factor();
2874 
2875 			buf.append("\n - ");
2876 			if(  welt->get_settings().get_just_in_time() >= 2  ) {
2877 				double const pfraction = (double)pfactor / (double)DEFAULT_PRODUCTION_FACTOR;
2878 				double const storage_unit = (double)(1 << fabrik_t::precision_bits);
2879 				buf.printf(translator::translate("%s %.0f%% : %.0f/%.0f @ %.1f%%"),
2880 					translator::translate(type->get_name()),
2881 					pfraction * 100.0,
2882 					(double)output[index].menge * pfraction / storage_unit,
2883 					(double)output[index].max * pfraction / storage_unit,
2884 					(double)output[index].calculate_output_production_rate() * 100.0 / (double)(1 << 16)
2885 				);
2886 			}
2887 			else {
2888 				buf.printf("%s %u/%u%s",
2889 					translator::translate(type->get_name()),
2890 					(uint32)((FAB_DISPLAY_UNIT_HALF + (sint64)output[index].menge * pfactor) >> (fabrik_t::precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS)),
2891 					(uint32)((FAB_DISPLAY_UNIT_HALF + (sint64)output[index].max * pfactor) >> (fabrik_t::precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS)),
2892 					translator::translate(type->get_mass())
2893 				);
2894 
2895 				if(type->get_catg() != 0) {
2896 					buf.append(", ");
2897 					buf.append(translator::translate(type->get_catg_name()));
2898 				}
2899 
2900 				buf.printf(", %u%%", (uint32)((FAB_PRODFACT_UNIT_HALF + (sint32)pfactor * 100) >> DEFAULT_PRODUCTION_FACTOR_BITS));
2901 			}
2902 		}
2903 	}
2904 
2905 	if (!input.empty()) {
2906 		buf.append("\n\n");
2907 		buf.append(translator::translate("Verbrauch"));
2908 
2909 		for (uint32 index = 0; index < input.get_count(); index++) {
2910 			sint64 const pfactor = (sint64)desc->get_supplier(index)->get_consumption();
2911 
2912 			buf.append("\n - ");
2913 			if(  welt->get_settings().get_just_in_time() >= 2  ) {
2914 				double const pfraction = (double)pfactor / (double)DEFAULT_PRODUCTION_FACTOR;
2915 				double const storage_unit = (double)(1 << fabrik_t::precision_bits);
2916 				buf.printf(translator::translate("%s %.0f%% : %.0f+%u/%.0f @ %.1f%%"),
2917 					translator::translate(input[index].get_typ()->get_name()),
2918 					pfraction * 100.0,
2919 					(double)input[index].menge * pfraction / storage_unit,
2920 					(uint32)input[index].get_in_transit(),
2921 					(double)input[index].max * pfraction / storage_unit,
2922 					(double)input[index].calculate_demand_production_rate() * 100.0 / (double)(1 << 16)
2923 				);
2924 			}
2925 			else if(  welt->get_settings().get_factory_maximum_intransit_percentage()  ) {
2926 				buf.printf("%s %u/%i(%i)/%u%s, %u%%",
2927 					translator::translate(input[index].get_typ()->get_name()),
2928 					(uint32)((FAB_DISPLAY_UNIT_HALF + (sint64)input[index].menge * pfactor) >> (fabrik_t::precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS)),
2929 					input[index].get_in_transit(),
2930 					input[index].max_transit,
2931 					(uint32)((FAB_DISPLAY_UNIT_HALF + (sint64)input[index].max * pfactor) >> (fabrik_t::precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS)),
2932 					translator::translate(input[index].get_typ()->get_mass()),
2933 					(uint32)((FAB_PRODFACT_UNIT_HALF + (sint32)pfactor * 100) >> DEFAULT_PRODUCTION_FACTOR_BITS)
2934 				);
2935 			}
2936 			else {
2937 				buf.printf("%s %u/%i/%u%s, %u%%",
2938 					translator::translate(input[index].get_typ()->get_name()),
2939 					(uint32)((FAB_DISPLAY_UNIT_HALF + (sint64)input[index].menge * pfactor) >> (fabrik_t::precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS)),
2940 					input[index].get_in_transit(),
2941 					(uint32)((FAB_DISPLAY_UNIT_HALF + (sint64)input[index].max * pfactor) >> (fabrik_t::precision_bits + DEFAULT_PRODUCTION_FACTOR_BITS)),
2942 					translator::translate(input[index].get_typ()->get_mass()),
2943 					(uint32)((FAB_PRODFACT_UNIT_HALF + (sint32)pfactor * 100) >> DEFAULT_PRODUCTION_FACTOR_BITS)
2944 				);
2945 			}
2946 		}
2947 	}
2948 }
2949 
2950 
info_conn(cbuffer_t & buf) const2951 void fabrik_t::info_conn(cbuffer_t& buf) const
2952 {
2953 	buf.clear();
2954 	const planquadrat_t *plan = welt->access(get_pos().get_2d());
2955 	if(plan  &&  plan->get_haltlist_count()>0) {
2956 		buf.append(translator::translate("Connected stops"));
2957 
2958 		for(  uint i=0;  i<plan->get_haltlist_count();  i++  ) {
2959 			buf.printf("\n - %s", plan->get_haltlist()[i]->get_name() );
2960 		}
2961 	}
2962 }
2963 
2964 
finish_rd()2965 void fabrik_t::finish_rd()
2966 {
2967 	// adjust production base to be at least as large as fields productivity
2968 	uint32 prodbase_adjust = 1;
2969 	const field_group_desc_t *fd = desc->get_field_group();
2970 	if(fd) {
2971 		for(uint32 i=0; i<fields.get_count(); i++) {
2972 			const field_class_desc_t *fc = fd->get_field_class( fields[i].field_class_index );
2973 			if (fc) {
2974 				prodbase_adjust += fc->get_field_production();
2975 			}
2976 		}
2977 	}
2978 
2979 	// set production, update all production related numbers
2980 	set_base_production( max(prodbase, prodbase_adjust) );
2981 
2982 	// now we have a valid storage limit
2983 	if(  welt->get_settings().is_crossconnect_factories()  ) {
2984 		FOR(  slist_tpl<fabrik_t*>,  const fab,  welt->get_fab_list()  ) {
2985 			fab->add_supplier(this);
2986 		}
2987 	}
2988 	else {
2989 		// add as supplier to target(s)
2990 		for(uint32 i=0; i<lieferziele.get_count(); i++) {
2991 			fabrik_t * fab2 = fabrik_t::get_fab(lieferziele[i]);
2992 			if(fab2) {
2993 				fab2->add_supplier(pos.get_2d());
2994 				lieferziele[i] = fab2->get_pos().get_2d();
2995 			}
2996 			else {
2997 				// remove this ...
2998 				dbg->warning( "fabrik_t::finish_rd()", "No factory at expected position %s!", lieferziele[i].get_str() );
2999 				lieferziele.remove_at(i);
3000 				i--;
3001 			}
3002 		}
3003 	}
3004 
3005 	// Now rebuild input/output activity information.
3006 	if( welt->get_settings().get_just_in_time() >= 2 ){
3007 		inactive_inputs = inactive_outputs = inactive_demands = 0;
3008 		for(  uint32 in = 0;  in < input.get_count();  in++  ){
3009 			if( input[in].menge > input[in].max ) {
3010 				input[in].menge = input[in].max;
3011 			}
3012 			input[in].placing_orders = (input[in].demand_buffer > 0);
3013 
3014 			// Also do a sanity check. People might try and force their saves to JIT2 mode via reloading so we need to catch any massive values.
3015 			if( welt->get_settings().get_just_in_time() >= 2 && welt->get_settings().get_factory_maximum_intransit_percentage() != 0 ){
3016 				const sint32 demand_minmax = (sint32)((sint64)input[in].max * (sint64)welt->get_settings().get_factory_maximum_intransit_percentage() / (sint64)100);
3017 				if( input[in].demand_buffer < (-demand_minmax) ) {
3018 					input[in].demand_buffer = -demand_minmax;
3019 				}
3020 				else if( input[in].demand_buffer > (input[in].max + demand_minmax) ) {
3021 					input[in].demand_buffer = input[in].max;
3022 				}
3023 			}
3024 		}
3025 		for( uint32 out = 0 ; out < output.get_count() ; out++ ){
3026 			if( output[out].menge >= output[out].max ) {
3027 				output[out].menge = output[out].max;
3028 			}
3029 		}
3030 
3031 		rebuild_inactive_cache();
3032 	}
3033 	else {
3034 		// Classic order logic.
3035 		for(  uint32 in = 0;  in < input.get_count();  in++  ){
3036 			input[in].placing_orders = (input[in].menge < input[in].max  &&  input[in].get_in_transit() < input[in].max_transit);
3037 		}
3038 	}
3039 
3040 	// set initial power boost
3041 	if (  boost_type == BL_POWER  ) {
3042 		prodfactor_electric = get_jit2_power_boost();
3043 	}
3044 }
3045 
3046 
rotate90(const sint16 y_size)3047 void fabrik_t::rotate90( const sint16 y_size )
3048 {
3049 	rotate = (rotate+3)%desc->get_building()->get_all_layouts();
3050 	pos_origin.rotate90( y_size );
3051 	pos_origin.x -= desc->get_building()->get_x(rotate)-1;
3052 	pos.rotate90( y_size );
3053 
3054 	FOR(vector_tpl<koord>, & i, lieferziele) {
3055 		i.rotate90(y_size);
3056 	}
3057 	FOR(vector_tpl<koord>, & i, suppliers) {
3058 		i.rotate90(y_size);
3059 	}
3060 	FOR(vector_tpl<field_data_t>, & i, fields) {
3061 		i.location.rotate90(y_size);
3062 	}
3063 }
3064 
3065 
add_supplier(koord ziel)3066 void fabrik_t::add_supplier(koord ziel)
3067 {
3068 	// Updated maximum in-transit. Only used for classic support.
3069 	if(  welt->get_settings().get_factory_maximum_intransit_percentage()  &&  !suppliers.is_contained(ziel) && welt->get_settings().get_just_in_time() < 2  ) {
3070 		if(  fabrik_t *fab = get_fab( ziel )  ) {
3071 			for(  uint32 i=0;  i < fab->get_output().get_count();  i++   ) {
3072 				const ware_production_t &w_out = fab->get_output()[i];
3073 				// now update transit limits
3074 				FOR(  array_tpl<ware_production_t>,  &w,  input ) {
3075 					if(  w_out.get_typ() == w.get_typ()  ) {
3076 #ifdef TRANSIT_DISTANCE
3077 						sint64 distance = koord_distance( fab->get_pos(), get_pos() );
3078 						// calculate next mean by the following formula: average + (next - average)/(n+1)
3079 						w.count_suppliers ++;
3080 						sint64 next = 1 + ( distance * welt->get_settings().get_factory_maximum_intransit_percentage() * (w.max >> fabrik_t::precision_bits) ) / 131072;
3081 						w.max_transit += (next - w.max_transit)/(w.count_suppliers);
3082 #else
3083 						const sint32 max_storage = (sint32)(1 + ( ((sint64)w_out.max * (sint64)welt->get_settings().get_factory_maximum_intransit_percentage() ) >> fabrik_t::precision_bits) / 100);
3084 						const sint32 old_max_transit = w.max_transit;
3085 						w.max_transit += max_storage;
3086 						if(  w.max_transit < old_max_transit  ) {
3087 							// we have overflown, so we use the max value
3088 							w.max_transit = 0x7fffffff;
3089 						}
3090 #endif
3091 						break;
3092 					}
3093 				}
3094 			}
3095 			// since there could be more than one good, we have to iterate over all of them
3096 		}
3097 	}
3098 	suppliers.insert_unique_ordered( ziel, RelativeDistanceOrdering(pos.get_2d()) );
3099 }
3100 
3101 
rem_supplier(koord pos)3102 void fabrik_t::rem_supplier(koord pos)
3103 {
3104 	suppliers.remove(pos);
3105 
3106 	// Updated maximum in-transit. Only used for classic support.
3107 	if( welt->get_settings().get_factory_maximum_intransit_percentage() && welt->get_settings().get_just_in_time() < 2 ) {
3108 		// set to zero
3109 		FOR(  array_tpl<ware_production_t>,  &w,  input ) {
3110 			w.max_transit = 0;
3111 		}
3112 
3113 		// unfourtunately we have to bite the bullet and recalc the values from scratch ...
3114 		FOR( vector_tpl<koord>, ziel, suppliers ) {
3115 			if(  fabrik_t *fab = get_fab( ziel )  ) {
3116 				for(  uint32 i=0;  i < fab->get_output().get_count();  i++   ) {
3117 					const ware_production_t &w_out = fab->get_output()[i];
3118 					// now update transit limits
3119 					FOR(  array_tpl<ware_production_t>,  &w,  input ) {
3120 						if(  w_out.get_typ() == w.get_typ()  ) {
3121 #ifdef TRANSIT_DISTANCE
3122 							sint64 distance = koord_distance( fab->get_pos(), get_pos() );
3123 							// calculate next mean by the following formula: average + (next - average)/(n+1)
3124 							w.count_suppliers ++;
3125 							sint64 next = 1 + ( distance * welt->get_settings().get_factory_maximum_intransit_percentage() * (w.max >> fabrik_t::precision_bits) ) / 131072;
3126 							w.max_transit += (next - w.max_transit)/(w.count_suppliers);
3127 #else
3128 							const sint32 max_storage = (sint32)(1 + ( ((sint64)w_out.max * (sint64)welt->get_settings().get_factory_maximum_intransit_percentage() ) >> fabrik_t::precision_bits) / 100);
3129 							const sint32 old_max_transit = w.max_transit;
3130 							w.max_transit += max_storage;
3131 							if(  w.max_transit < old_max_transit  ) {
3132 								// we have overflown, so we use the max value
3133 								w.max_transit = 0x7fffffff;
3134 							}
3135 #endif
3136 							break;
3137 						}
3138 					}
3139 				}
3140 				// since there could be more than one good, we have to iterate over all of them
3141 			}
3142 		}
3143 	}
3144 }
3145 
3146 
3147 /** crossconnect everything possible */
add_all_suppliers()3148 void fabrik_t::add_all_suppliers()
3149 {
3150 	for(int i=0; i < desc->get_supplier_count(); i++) {
3151 		const factory_supplier_desc_t *supplier = desc->get_supplier(i);
3152 		const goods_desc_t *ware = supplier->get_input_type();
3153 
3154 		FOR(slist_tpl<fabrik_t*>, const fab, welt->get_fab_list()) {
3155 			// connect to an existing one, if this is an producer
3156 			if(fab!=this  &&  fab->vorrat_an(ware) > -1) {
3157 				// add us to this factory
3158 				// will also add to our suppliers list
3159 				fab->add_lieferziel(pos.get_2d());
3160 			}
3161 		}
3162 	}
3163 }
3164 
3165 
3166 /* adds a new supplier to this factory
3167  * fails if no matching goods are there
3168  */
add_supplier(fabrik_t * fab)3169 bool fabrik_t::add_supplier(fabrik_t* fab)
3170 {
3171 	for(int i=0; i < desc->get_supplier_count(); i++) {
3172 		const factory_supplier_desc_t *supplier = desc->get_supplier(i);
3173 		const goods_desc_t *ware = supplier->get_input_type();
3174 
3175 			// connect to an existing one, if this is an producer
3176 			if(  fab!=this  &&  fab->vorrat_an(ware) > -1  ) {
3177 				// add us to this factory
3178 				fab->add_lieferziel(pos.get_2d());
3179 				return true;
3180 			}
3181 	}
3182 	return false;
3183 }
3184 
3185 
get_tile_list(vector_tpl<koord> & tile_list) const3186 void fabrik_t::get_tile_list( vector_tpl<koord> &tile_list ) const
3187 {
3188 	tile_list.clear();
3189 
3190 	koord pos_2d = pos.get_2d();
3191 	koord size = this->get_desc()->get_building()->get_size(this->get_rotate());
3192 	koord test;
3193 	// Which tiles belong to the fab?
3194 	for( test.x = 0; test.x < size.x; test.x++ ) {
3195 		for( test.y = 0; test.y < size.y; test.y++ ) {
3196 			if( fabrik_t::get_fab( pos_2d+test ) == this ) {
3197 				tile_list.append( pos_2d+test );
3198 			}
3199 		}
3200 	}
3201 }
3202 
3203 // Returns a list of goods produced by this factory. The caller must delete
3204 // the list when done
get_produced_goods() const3205 slist_tpl<const goods_desc_t*> *fabrik_t::get_produced_goods() const
3206 {
3207 	slist_tpl<const goods_desc_t*> *goods = new slist_tpl<const goods_desc_t*>();
3208 
3209 	FOR(array_tpl<ware_production_t>, const& i, output) {
3210 		goods->append(i.get_typ());
3211 	}
3212 
3213 	return goods;
3214 }
3215 
rebuild_inactive_cache()3216 void fabrik_t::rebuild_inactive_cache()
3217 {
3218 	inactive_inputs = inactive_outputs = inactive_demands = 0;
3219 
3220 	for(  uint32 i = 0;  i < input.get_count();  i++  ){
3221 		if(  input[i].menge <= 0  ) {
3222 			inactive_inputs++;
3223 		}
3224 		if(  input[i].demand_buffer >= input[i].max  ) {
3225 			inactive_demands++;
3226 		}
3227 	}
3228 
3229 	for(  uint32 i = 0 ; i < output.get_count() ; i++  ){
3230 		if(  output[i].menge >= output[i].max  ) {
3231 			inactive_outputs++;
3232 		}
3233 	}
3234 }
3235 
get_production_per_second() const3236 double fabrik_t::get_production_per_second() const {
3237 	return (double)prodbase * (double)get_prodfactor() / (double)DEFAULT_PRODUCTION_FACTOR / (double)DEFAULT_PRODUCTION_FACTOR;
3238 }
3239 
calculate_work_rate_ramp(sint32 const amount,sint32 const minimum,sint32 const maximum,uint32 const precision)3240 sint32 fabrik_t::calculate_work_rate_ramp(sint32 const amount, sint32 const minimum, sint32 const maximum, uint32 const precision)
3241 {
3242 	sint32 production_rate;
3243 	if(  minimum >= maximum  ||  minimum >= amount  ) {
3244 		// full production
3245 		production_rate = 1 << precision;
3246 	}
3247 	else if(  amount < maximum  ) {
3248 		// reduction production
3249 		production_rate = (sint32)(((sint64)(maximum - amount) << precision) / (sint64)(maximum - minimum));
3250 		// apply work factor minimum limit
3251 		if(  production_rate < WORK_SCALE_MINIMUM_FRACTION  ){
3252 			production_rate = WORK_SCALE_MINIMUM_FRACTION;
3253 		}
3254 	}
3255 	else {
3256 		// no production
3257 		production_rate = 0;
3258 	}
3259 	return production_rate;
3260 }
3261