1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
use bitflags::bitflags;
use super::write as write_action0;
use super::super::{ActionTrait, Feature, Output, vec_list, write_string};
bitflags! {
pub struct Flags : u32 {
const ON_WATER = 0x04;
const IN_LARGE_TOWN = 0x08;
const IN_TOWN = 0x10;
const NEAR_TOWN = 0x20;
}
}
bitflags! {
pub struct CallbackFlags : u16 {
const PRODUCTION_CARGO_ARRIVAL = 0x0002;
const PRODUCTION_EVERY_256_TICKS = 0x0004;
const PLACEMENT = 0x0008;
const PRODUCTION_CHANGE_RANDOM = 0x0010;
const PRODUCTION_CHANGE_MONTHLY = 0x0020;
const PRODUCTION_INITIAL = 0x4000;
}
}
pub enum Industry<'a> {
Disable { id: u8 }, // 08 (shared with Enable)
Enable { id: u8 }, // 08 (shared with Disable)
// 09 (unused)
Layout { id: u8, layouts: &'a Vec<Vec<u8>> }, // 0a
Type { id: u8, r#type: u8 }, // 0b
// 0c, 0d, 0e (TODO)
FundCostMultiplier { id: u8, multiplier: u8 }, // 0f
// 10, 11, 12, 13 (deprecated by 25, 26, 27, 28)
// 14 (won't implement)
// 15 (won't implement)
// 16 (won't implement)
Probability { id: u8, map_gen: u8, in_game: u8 }, // 17, 18
Colour { id: u8, colour: u8 }, // 19
Flags { id: u8, flags: Flags }, // 1a
// 1b (TODO)
// 1c, 1d, 1e (deprecated by 28)
Name { id: u8, name: &'a str }, // 1f
ProspectChance { id: u8, chance: u32 }, // 20
CallbackFlags { id: u8, flags: CallbackFlags }, // 21, 22
// 23 (won't implement)
// 24 (TODO)
Production { id: u8, production: &'a Vec<u8>, multiplier: &'a Vec<u8> }, // 25, 27
Acceptance { id: u8, acceptance: &'a Vec<u8>, multiplier: &'a Vec<u16> }, // 26, 28
}
impl<'a> ActionTrait for Industry<'a> {
fn write(&self, output: &mut Output) {
let (id, properties) = match self {
Industry::Disable { id } => {
(*id, vec![
vec_list!([0x08], [0xff]),
])
}
Industry::Enable { id } => {
/* 'Enable' creates an industry based on the built-in Coal Mine. */
(*id, vec![
vec_list!([0x08], [0x00]),
/* Minimal amount of cargo distributed is always 1. */
vec_list!([0x14], [0x01]),
/* We disable sound effects. */
vec_list!([0x15], [0x00]),
])
}
Industry::Layout { id, layouts } => {
let mut layout_data = Vec::new();
for layout in *layouts {
layout_data.extend(layout);
}
(*id, vec![
vec_list!([0x0a], [layouts.len() as u8], &(layout_data.len() as u32).to_le_bytes(), &layout_data),
])
}
Industry::Type { id, r#type } => {
(*id, vec![
vec_list!([0x0b], [r#type]),
])
}
Industry::FundCostMultiplier { id, multiplier } => {
(*id, vec![
vec_list!([0x0f], [*multiplier]),
])
}
Industry::Probability { id, map_gen, in_game } => {
(*id, vec![
vec_list!([0x17], [*map_gen]),
vec_list!([0x18], [*in_game]),
])
}
Industry::Colour { id, colour } => {
(*id, vec![
vec_list!([0x19], [*colour]),
])
}
Industry::Flags { id, flags } => {
let mut flags = flags.bits;
flags |= 0x40000; // Always enable bit 18 (new format for callbacks).
(*id, vec![
vec_list!([0x1a], &flags.to_le_bytes()),
])
}
Industry::Name { id, name } => {
let string_id = write_string(output, Feature::Industries, name);
(*id, vec![
vec_list!([0x1f], &string_id.to_le_bytes()),
])
}
Industry::ProspectChance { id, chance } => {
(*id, vec![
vec_list!([0x20], &chance.to_le_bytes()),
])
}
Industry::CallbackFlags { id, flags } => {
(*id, vec![
vec_list!([0x21], [(flags.bits & 0xff) as u8]),
vec_list!([0x22], [(flags.bits >> 8) as u8]),
])
}
Industry::Production { id, production, multiplier } => {
(*id, vec![
vec_list!([0x25], [production.len() as u8], *production),
vec_list!([0x27], [multiplier.len() as u8], *multiplier),
])
}
Industry::Acceptance { id, acceptance, multiplier } => {
let production_len = if !acceptance.is_empty() { multiplier.len() / acceptance.len() } else { 0 };
let mut multiplier_u8 = Vec::new();
for m in *multiplier {
multiplier_u8.extend(m.to_le_bytes());
}
(*id, vec![
vec_list!([0x26], [acceptance.len() as u8], *acceptance),
vec_list!([0x28], [acceptance.len() as u8, production_len as u8], &multiplier_u8),
])
}
};
write_action0(output, Feature::Industries, id, &properties);
}
}