/
procedures_alternative_var_41.pynml
91 lines (83 loc) · 4.97 KB
/
procedures_alternative_var_41.pynml
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
<!--!
Var 41 only checks consecutive chains for a single ID
This provides an alternative checking consecutive chains using up to 16 IDs
This checks var 61 many many times in graphics chains, and var 61 is not cached, so this _may_ introduce performance problems
To use:
* switch_initialise_alt_var_41() at start of graphics chain
* read appropriate temp registers to use the alt var
* the available values are similar to var 41: position from start of chain, position from end of chain, num vehicles in chain
* LOAD_TEMP(${temp_storage_ids.position_in_vehid_chain_multiple_ids})
* LOAD_TEMP(${temp_storage_ids.position_in_vehid_chain_from_end_multiple_ids})
* LOAD_TEMP(${temp_storage_ids.num_vehs_in_vehid_chain_multiple_ids})
-->
<!--!
Utility switches to check if vehicle ID is in list
Up to 16 items in list - arbitrary limit, should be enough for most cases)
There's no obvious alternative to having one switch per range of IDs to check
Be aware that this might match vehicle ID 0 incorrectly, as OpenTTD will retun 0 when checking var 61 beyond consist length - edge case TBH
-->
<tal:switches repeat="pseudo_list_index range(15, -1, -1)">
<tal:block define="temp_storage_id python:temp_storage_ids['id_to_match_' + str(pseudo_list_index + 1)]">
switch (FEAT_TRAINS, SELF, switch_alt_var_41_match_ids_${pseudo_list_index}, [LOAD_TEMP(${temp_storage_ids.id_of_neighbouring_vehicle}) == LOAD_TEMP(${temp_storage_id})]) {
1: return 1;
<tal:last condition="repeat.pseudo_list_index.start">return 0;</tal:last>
<tal:not_last condition="not:repeat.pseudo_list_index.start">return switch_alt_var_41_match_ids_${pseudo_list_index + 1};</tal:not_last>
}
</tal:block>
</tal:switches>
switch (FEAT_TRAINS, SELF, switch_alt_var_41_match_ids, STORE_TEMP(var[0x61, 0, 0x0000FFFF, 0xC6], ${temp_storage_ids.id_of_neighbouring_vehicle})) {
return switch_alt_var_41_match_ids_0;
}
<!--!
Position from start of consecutive IDs chain
Walks forward from vehicle towards engine, checking if the ID is matched for each 'next vehicle', if matched continues, otherwise return the count of vehicles matched (this represents position in chain)
-->
<tal:switches repeat="counter range(127, 0, -1)">
switch (FEAT_TRAINS, SELF, switch_alt_var_41_position_in_vehid_chain_multiple_ids_${counter}, [STORE_TEMP(${-1 * counter}, 0x10F), switch_alt_var_41_match_ids()]) {
<tal:block condition="not:repeat.counter.start">1: switch_alt_var_41_position_in_vehid_chain_multiple_ids_${counter + 1};</tal:block>
return ${counter - 1};
}
</tal:switches>
<!--!
Position from end of consecutive IDs chain
Walks backward from vehicle away from engine, checking if the ID is matched for each 'next vehicle', if matched continues, otherwise return the count of vehicles matched (this represents position in chain)
-->
<tal:switches repeat="counter range(127, 0, -1)">
switch (FEAT_TRAINS, SELF, switch_alt_var_41_position_in_vehid_chain_from_end_multiple_ids_${counter}, [STORE_TEMP(${1 * counter}, 0x10F), switch_alt_var_41_match_ids()]) {
<tal:block condition="not:repeat.counter.start">1: switch_alt_var_41_position_in_vehid_chain_from_end_multiple_ids_${counter + 1};</tal:block>
return ${counter - 1};
}
</tal:switches>
<!--!
Num vehicles in consecutive ID chain
Sum of positions from start and end, plus 1 for current vehicle
-->
switch (FEAT_TRAINS, SELF, switch_alt_var_41_num_vehs_in_vehid_chain_multiple_ids, 1) {
return 1 + LOAD_TEMP(${temp_storage_ids.position_in_vehid_chain_multiple_ids}) + LOAD_TEMP(${temp_storage_ids.position_in_vehid_chain_from_end_multiple_ids});
}
<!--!
Store 3 results in temp storage mimicking what built-in var 41 provides
-->
switch (FEAT_TRAINS, SELF, switch_initialise_alt_var_41_store_temps, [
STORE_TEMP(switch_alt_var_41_position_in_vehid_chain_multiple_ids_1(),
${temp_storage_ids.position_in_vehid_chain_multiple_ids}),
STORE_TEMP(switch_alt_var_41_position_in_vehid_chain_from_end_multiple_ids_1(),
${temp_storage_ids.position_in_vehid_chain_from_end_multiple_ids}),
STORE_TEMP(switch_alt_var_41_num_vehs_in_vehid_chain_multiple_ids(),
${temp_storage_ids.num_vehs_in_vehid_chain_multiple_ids}),
]) {
return;
}
<!--!
To be called at start of graphics chain for current vehicle, with 16 params containing vehicle IDs to match
No params can be missing, pass -1 for any 'empty' params where no real ID is passed
-->
switch (FEAT_TRAINS, SELF, switch_initialise_alt_var_41,
${','.join(['id_' + str(i) for i in range(1, 17)])}, [
<tal:store_temp repeat="counter range(1, 17)">
STORE_TEMP(${'id_' + str(counter)}, ${str(temp_storage_ids['id_to_match_' + str(counter)])})
${',' if not repeat.counter.end else ''}
</tal:store_temp>
]){
return switch_initialise_alt_var_41_store_temps;
}