|
1 /* $Id$ */ |
|
2 |
|
3 /** @file newgrf_industrytiles.cpp */ |
|
4 |
|
5 #include "stdafx.h" |
|
6 #include "openttd.h" |
|
7 #include "functions.h" |
|
8 #include "variables.h" |
|
9 #include "debug.h" |
|
10 #include "viewport.h" |
|
11 #include "landscape.h" |
|
12 #include "newgrf.h" |
|
13 #include "industry.h" |
|
14 #include "newgrf_commons.h" |
|
15 #include "newgrf_spritegroup.h" |
|
16 #include "newgrf_callbacks.h" |
|
17 #include "newgrf_industries.h" |
|
18 #include "industry_map.h" |
|
19 #include "clear_map.h" |
|
20 #include "table/sprites.h" |
|
21 #include "sprite.h" |
|
22 |
|
23 /** |
|
24 * Based on newhouses equivalent, but adapted for newindustries |
|
25 * @param parameter from callback. It's in fact a pair of coordinates |
|
26 * @param tile TileIndex from which the callback was initiated |
|
27 * @param index of the industry been queried for |
|
28 * @return a construction of bits obeying the newgrf format |
|
29 */ |
|
30 static uint32 GetNearbyIndustryTileInformation(byte parameter, TileIndex tile, IndustryID index) |
|
31 { |
|
32 byte tile_type; |
|
33 bool is_same_industry; |
|
34 |
|
35 tile = GetNearbyTile(parameter, tile); |
|
36 is_same_industry = (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == index); |
|
37 tile_type = GetTerrainType(tile) << 2 | (IsTileType(tile, MP_WATER) ? 1 : 0) << 1 | (is_same_industry ? 1 : 0); |
|
38 |
|
39 return GetTileType(tile) << 24 | (TileHeight(tile) * 8) << 16 | tile_type << 8 | GetTileSlope(tile, NULL); |
|
40 } |
|
41 |
|
42 /** This is the position of the tile relative to the northernmost tile of the industry. |
|
43 * Format: 00yxYYXX |
|
44 * Variable Content |
|
45 * x the x offset from the northernmost tile |
|
46 * XX same, but stored in a byte instead of a nibble |
|
47 * y the y offset from the northernmost tile |
|
48 * YY same, but stored in a byte instead of a nibble |
|
49 * @param tile TileIndex of the tile to evaluate |
|
50 * @param ind_tile northernmost tile of the industry |
|
51 */ |
|
52 static uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile) |
|
53 { |
|
54 byte x = TileX(tile) - TileX(ind_tile); |
|
55 byte y = TileY(tile) - TileY(ind_tile); |
|
56 |
|
57 return ((y & 0xF) << 20) | ((x & 0xF) << 16) | (y << 8) | x; |
|
58 } |
|
59 |
|
60 static uint32 IndustryTileGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) |
|
61 { |
|
62 const Industry *inds = object->u.industry.ind; |
|
63 TileIndex tile = object->u.industry.tile; |
|
64 |
|
65 if (object->scope == VSG_SCOPE_PARENT) { |
|
66 return IndustryGetVariable(object, variable, parameter, available); |
|
67 } |
|
68 |
|
69 switch (variable) { |
|
70 /* Construction state of the tile: a value between 0 and 3 */ |
|
71 case 0x40 : return (IsTileType(tile, MP_INDUSTRY)) ? GetIndustryConstructionStage(tile) : 0; |
|
72 |
|
73 case 0x41 : return GetTerrainType(tile); |
|
74 |
|
75 /* Current town zone of the tile in the nearest town */ |
|
76 /** @todo Maybe use GetRadiusGroupForTile? */ |
|
77 case 0x42 : return ClosestTownFromTile(tile, (uint)-1)->GetRadiusGroup(tile); |
|
78 |
|
79 /* Relative position */ |
|
80 case 0x43 : return GetRelativePosition(tile, inds->xy); |
|
81 |
|
82 /* Animation frame. Like house variable 46 but can contain anything 0..FF. */ |
|
83 case 0x44 : return (IsTileType(tile, MP_INDUSTRY)) ? GetIndustryAnimationState(tile) : 0; |
|
84 |
|
85 /* Land info of nearby tiles */ |
|
86 case 0x60 : return GetNearbyIndustryTileInformation(parameter, tile, inds->index); |
|
87 |
|
88 case 0x61 : {/* Animation stage of nearby tiles */ |
|
89 tile = GetNearbyTile(parameter, tile); |
|
90 if (IsTileType(tile, MP_INDUSTRY) && GetIndustryByTile(tile) == inds) { |
|
91 return GetIndustryAnimationState(tile); |
|
92 } |
|
93 return 0xFFFFFFFF; |
|
94 } |
|
95 |
|
96 /* Get industry tile ID at offset */ |
|
97 case 0x62 : return GetIndustryIDAtOffset(GetNearbyTile(parameter, tile), tile, inds); |
|
98 } |
|
99 |
|
100 return 0; |
|
101 } |
|
102 |
|
103 static const SpriteGroup *IndustryTileResolveReal(const ResolverObject *object, const SpriteGroup *group) |
|
104 { |
|
105 /* IndustryTile do not have 'real' groups. Or do they?? */ |
|
106 return NULL; |
|
107 } |
|
108 |
|
109 uint32 IndustryTileGetRandomBits(const ResolverObject *object) |
|
110 { |
|
111 const TileIndex tile = object->u.industry.tile; |
|
112 return (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) ? 0 : GetIndustryRandomBits(tile); |
|
113 } |
|
114 |
|
115 uint32 IndustryTileGetTriggers(const ResolverObject *object) |
|
116 { |
|
117 const TileIndex tile = object->u.industry.tile; |
|
118 return (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) ? 0 : GetIndustryTriggers(tile); |
|
119 } |
|
120 |
|
121 void IndustryTileSetTriggers(const ResolverObject *object, int triggers) |
|
122 { |
|
123 const TileIndex tile = object->u.industry.tile; |
|
124 if (IsTileType(tile, MP_INDUSTRY)) SetIndustryTriggers(tile, triggers); |
|
125 } |
|
126 |
|
127 static void NewIndustryTileResolver(ResolverObject *res, IndustryGfx gfx, TileIndex tile, Industry *indus) |
|
128 { |
|
129 res->GetRandomBits = IndustryTileGetRandomBits; |
|
130 res->GetTriggers = IndustryTileGetTriggers; |
|
131 res->SetTriggers = IndustryTileSetTriggers; |
|
132 res->GetVariable = IndustryTileGetVariable; |
|
133 res->ResolveReal = IndustryTileResolveReal; |
|
134 |
|
135 res->u.industry.tile = tile; |
|
136 res->u.industry.ind = indus; |
|
137 res->u.industry.gfx = gfx; |
|
138 |
|
139 res->callback = 0; |
|
140 res->callback_param1 = 0; |
|
141 res->callback_param2 = 0; |
|
142 res->last_value = 0; |
|
143 res->trigger = 0; |
|
144 res->reseed = 0; |
|
145 } |
|
146 |
|
147 uint16 GetIndustryTileCallback(uint16 callback, uint32 param1, uint32 param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile) |
|
148 { |
|
149 ResolverObject object; |
|
150 const SpriteGroup *group; |
|
151 |
|
152 NewIndustryTileResolver(&object, gfx_id, tile, industry); |
|
153 object.callback = callback; |
|
154 object.callback_param1 = param1; |
|
155 object.callback_param2 = param2; |
|
156 |
|
157 group = Resolve(GetIndustryTileSpec(gfx_id)->grf_prop.spritegroup, &object); |
|
158 if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED; |
|
159 |
|
160 return group->g.callback.result; |
|
161 } |