1 /*
2 * Copyright (c) 1997 - 2001 Hj. Malthaner
3 *
4 * This file is part of the Simutrans project under the artistic license.
5 * (see license.txt)
6 */
7
8 #include <stdio.h>
9 #include <string.h>
10
11 #include "simmem.h"
12 #include "simdebug.h"
13 #include "simfab.h"
14 #include "simhalt.h"
15 #include "simtypes.h"
16 #include "simware.h"
17 #include "simworld.h"
18 #include "dataobj/loadsave.h"
19 #include "dataobj/koord.h"
20
21 #include "descriptor/goods_desc.h"
22 #include "bauer/goods_manager.h"
23
24
25
26 const goods_desc_t *ware_t::index_to_desc[256];
27
ware_t()28 ware_t::ware_t() : ziel(), zwischenziel(), zielpos(-1, -1)
29 {
30 menge = 0;
31 index = 0;
32 to_factory = 0;
33 }
34
35
ware_t(const goods_desc_t * wtyp)36 ware_t::ware_t(const goods_desc_t *wtyp) : ziel(), zwischenziel(), zielpos(-1, -1)
37 {
38 menge = 0;
39 index = wtyp->get_index();
40 to_factory = 0;
41 }
42
43
ware_t(loadsave_t * file)44 ware_t::ware_t(loadsave_t *file)
45 {
46 rdwr(file);
47 }
48
49
rdwr(loadsave_t * file)50 void ware_t::rdwr(loadsave_t *file)
51 {
52 sint32 amount = menge;
53 file->rdwr_long(amount);
54 menge = amount;
55 if(file->is_version_less(99, 8)) {
56 sint32 max;
57 file->rdwr_long(max);
58 }
59
60 if( file->is_version_atleast(110, 5) ) {
61 uint8 factory_going = to_factory;
62 file->rdwr_byte(factory_going);
63 to_factory = factory_going;
64 }
65 else if( file->is_loading() ) {
66 to_factory = 0;
67 }
68
69 uint8 catg=0;
70 if(file->is_version_atleast(88, 5)) {
71 file->rdwr_byte(catg);
72 }
73
74 if(file->is_saving()) {
75 const char *typ = NULL;
76 typ = get_desc()->get_name();
77 file->rdwr_str(typ);
78 }
79 else {
80 char typ[256];
81 file->rdwr_str(typ, lengthof(typ));
82 const goods_desc_t *type = goods_manager_t::get_info(typ);
83 if(type==NULL) {
84 dbg->warning("ware_t::rdwr()","unknown ware of catg %d!",catg);
85 index = goods_manager_t::get_info_catg(catg)->get_index();
86 menge = 0;
87 }
88 else {
89 index = type->get_index();
90 }
91 }
92 // convert coordinate to halt indices
93 if(file->is_version_atleast(110, 6)) {
94 // save halt id directly
95 if(file->is_saving()) {
96 uint16 halt_id = ziel.is_bound() ? ziel.get_id() : 0;
97 file->rdwr_short(halt_id);
98 halt_id = zwischenziel.is_bound() ? zwischenziel.get_id() : 0;
99 file->rdwr_short(halt_id);
100 }
101 else {
102 uint16 halt_id;
103 file->rdwr_short(halt_id);
104 ziel.set_id(halt_id);
105 file->rdwr_short(halt_id);
106 zwischenziel.set_id(halt_id);
107 }
108
109 }
110 else {
111 // save halthandles via coordinates
112 if(file->is_saving()) {
113 koord ziel_koord = ziel.is_bound() ? ziel->get_basis_pos() : koord::invalid;
114 ziel_koord.rdwr(file);
115 koord zwischenziel_koord = zwischenziel.is_bound() ? zwischenziel->get_basis_pos() : koord::invalid;
116 zwischenziel_koord.rdwr(file);
117 }
118 else {
119 koord ziel_koord;
120 ziel_koord.rdwr(file);
121 ziel = haltestelle_t::get_halt_koord_index(ziel_koord);
122 koord zwischen_ziel_koord;
123 zwischen_ziel_koord.rdwr(file);
124 zwischenziel = haltestelle_t::get_halt_koord_index(zwischen_ziel_koord);
125 }
126 }
127 zielpos.rdwr(file);
128 // restore factory-flag
129 if( file->is_version_less(110, 5) && file->is_loading() ) {
130 if (fabrik_t::get_fab(zielpos)) {
131 to_factory = 1;
132 }
133 }
134 }
135
136
finish_rd(karte_t * welt)137 void ware_t::finish_rd(karte_t *welt)
138 {
139 if( welt->load_version<=111005 ) {
140 // since some halt was referred by with several koordinates
141 // this routine will correct it
142 if(ziel.is_bound()) {
143 ziel = haltestelle_t::get_halt_koord_index(ziel->get_init_pos());
144 }
145 if(zwischenziel.is_bound()) {
146 zwischenziel = haltestelle_t::get_halt_koord_index(zwischenziel->get_init_pos());
147 }
148 }
149 update_factory_target();
150 }
151
152
rotate90(sint16 y_size)153 void ware_t::rotate90(sint16 y_size )
154 {
155 zielpos.rotate90( y_size );
156 update_factory_target();
157 }
158
159
update_factory_target()160 void ware_t::update_factory_target()
161 {
162 if (to_factory) {
163 // assert that target coordinates are unique for cargo going to the same factory
164 // as new cargo will be generated with possibly new factory coordinates
165 fabrik_t *fab = fabrik_t::get_fab(zielpos );
166 if (fab) {
167 zielpos = fab->get_pos().get_2d();
168 }
169 }
170 }
171
172
calc_revenue(const goods_desc_t * desc,waytype_t wt,sint32 speedkmh)173 sint64 ware_t::calc_revenue(const goods_desc_t* desc, waytype_t wt, sint32 speedkmh)
174 {
175 static karte_ptr_t welt;
176
177 const sint32 ref_kmh = welt->get_average_speed( wt );
178 const sint32 kmh_base = (100 * speedkmh) / ref_kmh - 100;
179
180 const sint32 grundwert128 = welt->get_settings().get_bonus_basefactor(); // minimal bonus factor
181 const sint32 grundwert_bonus = 1000+kmh_base*desc->get_speed_bonus(); // speed bonus factor
182 // take the larger of both
183 return desc->get_value() * (grundwert128 > grundwert_bonus ? grundwert128 : grundwert_bonus);
184 }
185
add_goods(goods_amount_t const number)186 ware_t::goods_amount_t ware_t::add_goods(goods_amount_t const number) {
187 goods_amount_t const limit = GOODS_AMOUNT_LIMIT - menge;
188 if (limit < number) {
189 menge = GOODS_AMOUNT_LIMIT;
190 return number - limit;
191 }
192
193 menge+= number;
194 return 0;
195 }
196
remove_goods(goods_amount_t const number)197 ware_t::goods_amount_t ware_t::remove_goods(goods_amount_t const number) {
198 if (menge < number) {
199 goods_amount_t const remainder = number - menge;
200 menge = 0;
201 return remainder;
202 }
203
204 menge-= number;
205 return 0;
206 }
207
is_goods_amount_maxed() const208 bool ware_t::is_goods_amount_maxed() const {
209 return menge == GOODS_AMOUNT_LIMIT;
210 }
211