00001
00002
00003
00004
00005
00006
00007
00008
00009
00015 #include "stdafx.h"
00016 #include "debug.h"
00017 #include "landscape.h"
00018 #include "house.h"
00019 #include "industrytype.h"
00020 #include "newgrf.h"
00021 #include "newgrf_config.h"
00022 #include "clear_map.h"
00023 #include "station_map.h"
00024 #include "tree_map.h"
00025 #include "tunnelbridge_map.h"
00026 #include "newgrf_object.h"
00027 #include "genworld.h"
00028 #include "newgrf_spritegroup.h"
00029 #include "newgrf_text.h"
00030 #include "livery.h"
00031 #include "company_base.h"
00032 #include "error.h"
00033 #include "strings_func.h"
00034
00035 #include "table/strings.h"
00036
00043 OverrideManagerBase::OverrideManagerBase(uint16 offset, uint16 maximum, uint16 invalid)
00044 {
00045 max_offset = offset;
00046 max_new_entities = maximum;
00047 invalid_ID = invalid;
00048
00049 mapping_ID = CallocT<EntityIDMapping>(max_new_entities);
00050 entity_overrides = MallocT<uint16>(max_offset);
00051 for (size_t i = 0; i < max_offset; i++) entity_overrides[i] = invalid;
00052 grfid_overrides = CallocT<uint32>(max_offset);
00053 }
00054
00059 OverrideManagerBase::~OverrideManagerBase()
00060 {
00061 free(mapping_ID);
00062 free(entity_overrides);
00063 free(grfid_overrides);
00064 }
00065
00074 void OverrideManagerBase::Add(uint8 local_id, uint32 grfid, uint entity_type)
00075 {
00076 assert(entity_type < max_offset);
00077
00078 if (entity_overrides[entity_type] != invalid_ID) return;
00079 entity_overrides[entity_type] = local_id;
00080 grfid_overrides[entity_type] = grfid;
00081 }
00082
00084 void OverrideManagerBase::ResetMapping()
00085 {
00086 memset(mapping_ID, 0, (max_new_entities - 1) * sizeof(EntityIDMapping));
00087 }
00088
00090 void OverrideManagerBase::ResetOverride()
00091 {
00092 for (uint16 i = 0; i < max_offset; i++) {
00093 entity_overrides[i] = invalid_ID;
00094 grfid_overrides[i] = 0;
00095 }
00096 }
00097
00104 uint16 OverrideManagerBase::GetID(uint8 grf_local_id, uint32 grfid) const
00105 {
00106 const EntityIDMapping *map;
00107
00108 for (uint16 id = 0; id < max_new_entities; id++) {
00109 map = &mapping_ID[id];
00110 if (map->entity_id == grf_local_id && map->grfid == grfid) {
00111 return id;
00112 }
00113 }
00114
00115 return invalid_ID;
00116 }
00117
00125 uint16 OverrideManagerBase::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
00126 {
00127 uint16 id = this->GetID(grf_local_id, grfid);
00128 EntityIDMapping *map;
00129
00130
00131
00132
00133
00134 if (id != invalid_ID) {
00135 return id;
00136 }
00137
00138
00139 for (id = max_offset; id < max_new_entities; id++) {
00140 map = &mapping_ID[id];
00141
00142 if (CheckValidNewID(id) && map->entity_id == 0 && map->grfid == 0) {
00143 map->entity_id = grf_local_id;
00144 map->grfid = grfid;
00145 map->substitute_id = substitute_id;
00146 return id;
00147 }
00148 }
00149
00150 return invalid_ID;
00151 }
00152
00158 uint32 OverrideManagerBase::GetGRFID(uint16 entity_id) const
00159 {
00160 return mapping_ID[entity_id].grfid;
00161 }
00162
00168 uint16 OverrideManagerBase::GetSubstituteID(uint16 entity_id) const
00169 {
00170 return mapping_ID[entity_id].substitute_id;
00171 }
00172
00178 void HouseOverrideManager::SetEntitySpec(const HouseSpec *hs)
00179 {
00180 HouseID house_id = this->AddEntityID(hs->grf_prop.local_id, hs->grf_prop.grffile->grfid, hs->grf_prop.subst_id);
00181
00182 if (house_id == invalid_ID) {
00183 grfmsg(1, "House.SetEntitySpec: Too many houses allocated. Ignoring.");
00184 return;
00185 }
00186
00187 MemCpyT(HouseSpec::Get(house_id), hs);
00188
00189
00190 for (int i = 0; i != max_offset; i++) {
00191 HouseSpec *overridden_hs = HouseSpec::Get(i);
00192
00193 if (entity_overrides[i] != hs->grf_prop.local_id || grfid_overrides[i] != hs->grf_prop.grffile->grfid) continue;
00194
00195 overridden_hs->grf_prop.override = house_id;
00196 entity_overrides[i] = invalid_ID;
00197 grfid_overrides[i] = 0;
00198 }
00199 }
00200
00207 uint16 IndustryOverrideManager::GetID(uint8 grf_local_id, uint32 grfid) const
00208 {
00209 uint16 id = OverrideManagerBase::GetID(grf_local_id, grfid);
00210 if (id != invalid_ID) return id;
00211
00212
00213 for (id = 0; id < max_offset; id++) {
00214 if (entity_overrides[id] == grf_local_id && grfid_overrides[id] == grfid) return id;
00215 }
00216
00217 return invalid_ID;
00218 }
00219
00227 uint16 IndustryOverrideManager::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
00228 {
00229
00230 for (uint16 id = 0; id < max_new_entities; id++) {
00231
00232 if (id < max_offset && entity_overrides[id] != invalid_ID) continue;
00233
00234
00235 const IndustrySpec *inds = GetIndustrySpec(id);
00236
00237
00238
00239
00240 if (!inds->enabled && inds->grf_prop.grffile == NULL) {
00241 EntityIDMapping *map = &mapping_ID[id];
00242
00243 if (map->entity_id == 0 && map->grfid == 0) {
00244
00245 map->entity_id = grf_local_id;
00246 map->grfid = grfid;
00247 map->substitute_id = substitute_id;
00248 return id;
00249 }
00250 }
00251 }
00252
00253 return invalid_ID;
00254 }
00255
00262 void IndustryOverrideManager::SetEntitySpec(IndustrySpec *inds)
00263 {
00264
00265 IndustryType ind_id = this->GetID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid);
00266
00267 if (ind_id == invalid_ID) {
00268
00269
00270
00271
00272 ind_id = this->AddEntityID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid, inds->grf_prop.subst_id);
00273 inds->grf_prop.override = invalid_ID;
00274 }
00275
00276 if (ind_id == invalid_ID) {
00277 grfmsg(1, "Industry.SetEntitySpec: Too many industries allocated. Ignoring.");
00278 return;
00279 }
00280
00281
00282 memcpy(&_industry_specs[ind_id], inds, sizeof(*inds));
00283
00284 _industry_specs[ind_id].enabled = true;
00285 }
00286
00287 void IndustryTileOverrideManager::SetEntitySpec(const IndustryTileSpec *its)
00288 {
00289 IndustryGfx indt_id = this->AddEntityID(its->grf_prop.local_id, its->grf_prop.grffile->grfid, its->grf_prop.subst_id);
00290
00291 if (indt_id == invalid_ID) {
00292 grfmsg(1, "IndustryTile.SetEntitySpec: Too many industry tiles allocated. Ignoring.");
00293 return;
00294 }
00295
00296 memcpy(&_industry_tile_specs[indt_id], its, sizeof(*its));
00297
00298
00299 for (int i = 0; i < max_offset; i++) {
00300 IndustryTileSpec *overridden_its = &_industry_tile_specs[i];
00301
00302 if (entity_overrides[i] != its->grf_prop.local_id || grfid_overrides[i] != its->grf_prop.grffile->grfid) continue;
00303
00304 overridden_its->grf_prop.override = indt_id;
00305 overridden_its->enabled = false;
00306 entity_overrides[i] = invalid_ID;
00307 grfid_overrides[i] = 0;
00308 }
00309 }
00310
00317 void ObjectOverrideManager::SetEntitySpec(ObjectSpec *spec)
00318 {
00319
00320 ObjectType type = this->GetID(spec->grf_prop.local_id, spec->grf_prop.grffile->grfid);
00321
00322 if (type == invalid_ID) {
00323
00324
00325
00326
00327 type = this->AddEntityID(spec->grf_prop.local_id, spec->grf_prop.grffile->grfid, OBJECT_TRANSMITTER);
00328 }
00329
00330 if (type == invalid_ID) {
00331 grfmsg(1, "Object.SetEntitySpec: Too many objects allocated. Ignoring.");
00332 return;
00333 }
00334
00335 extern ObjectSpec _object_specs[NUM_OBJECTS];
00336
00337
00338 memcpy(&_object_specs[type], spec, sizeof(*spec));
00339 ObjectClass::Assign(&_object_specs[type]);
00340 }
00341
00350 uint32 GetTerrainType(TileIndex tile, TileContext context)
00351 {
00352 switch (_settings_game.game_creation.landscape) {
00353 case LT_TROPIC: return GetTropicZone(tile);
00354 case LT_ARCTIC: {
00355 bool has_snow;
00356 switch (GetTileType(tile)) {
00357 case MP_CLEAR:
00358
00359 if (_generating_world) goto genworld;
00360 has_snow = IsSnowTile(tile) && GetClearDensity(tile) >= 2;
00361 break;
00362
00363 case MP_RAILWAY: {
00364
00365 if (_generating_world) goto genworld;
00366 RailGroundType ground = GetRailGroundType(tile);
00367 has_snow = (ground == RAIL_GROUND_ICE_DESERT || (context == TCX_UPPER_HALFTILE && ground == RAIL_GROUND_HALF_SNOW));
00368 break;
00369 }
00370
00371 case MP_ROAD:
00372
00373 if (_generating_world) goto genworld;
00374 has_snow = IsOnSnow(tile);
00375 break;
00376
00377 case MP_TREES: {
00378
00379 if (_generating_world) goto genworld;
00380 TreeGround ground = GetTreeGround(tile);
00381 has_snow = (ground == TREE_GROUND_SNOW_DESERT || ground == TREE_GROUND_ROUGH_SNOW) && GetTreeDensity(tile) >= 2;
00382 break;
00383 }
00384
00385 case MP_TUNNELBRIDGE:
00386 if (context == TCX_ON_BRIDGE) {
00387 has_snow = (GetBridgeHeight(tile) > GetSnowLine());
00388 } else {
00389
00390 if (_generating_world) goto genworld;
00391 has_snow = HasTunnelBridgeSnowOrDesert(tile);
00392 }
00393 break;
00394
00395 case MP_STATION:
00396 case MP_HOUSE:
00397 case MP_INDUSTRY:
00398 case MP_OBJECT:
00399
00400 has_snow = (GetTileMaxZ(tile) > GetSnowLine());
00401 break;
00402
00403 case MP_VOID:
00404 case MP_WATER:
00405 genworld:
00406 has_snow = (GetTileZ(tile) > GetSnowLine());
00407 break;
00408
00409 default: NOT_REACHED();
00410 }
00411 return has_snow ? 4 : 0;
00412 }
00413 default: return 0;
00414 }
00415 }
00416
00425 TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets, Axis axis)
00426 {
00427 int8 x = GB(parameter, 0, 4);
00428 int8 y = GB(parameter, 4, 4);
00429
00430 if (signed_offsets && x >= 8) x -= 16;
00431 if (signed_offsets && y >= 8) y -= 16;
00432
00433
00434 if (axis == INVALID_AXIS && HasStationTileRail(tile)) axis = GetRailStationAxis(tile);
00435 if (axis == AXIS_Y) Swap(x, y);
00436
00437
00438 return TILE_MASK(tile + TileDiffXY(x, y));
00439 }
00440
00448 uint32 GetNearbyTileInformation(TileIndex tile, bool grf_version8)
00449 {
00450 TileType tile_type = GetTileType(tile);
00451
00452
00453 if (IsTileType(tile, MP_TREES) && GetTreeGround(tile) == TREE_GROUND_SHORE) tile_type = MP_WATER;
00454
00455 int z;
00456 Slope tileh = GetTilePixelSlope(tile, &z);
00457
00458 byte terrain_type = (HasTileWaterClass(tile) ? (GetWaterClass(tile) + 1) & 3 : 0) << 5 | GetTerrainType(tile) << 2 | (tile_type == MP_WATER ? 1 : 0) << 1;
00459 if (grf_version8) z /= TILE_HEIGHT;
00460 return tile_type << 24 | Clamp(z, 0, 0xFF) << 16 | terrain_type << 8 | tileh;
00461 }
00462
00469 uint32 GetCompanyInfo(CompanyID owner, const Livery *l)
00470 {
00471 if (l == NULL && Company::IsValidID(owner)) l = &Company::Get(owner)->livery[LS_DEFAULT];
00472 return owner | (Company::IsValidAiID(owner) ? 0x10000 : 0) | (l != NULL ? (l->colour1 << 24) | (l->colour2 << 28) : 0);
00473 }
00474
00482 CommandCost GetErrorMessageFromLocationCallbackResult(uint16 cb_res, uint32 grfid, StringID default_error)
00483 {
00484 CommandCost res;
00485
00486 if (cb_res < 0x400) {
00487 res = CommandCost(GetGRFStringID(grfid, 0xD000 + cb_res));
00488 } else {
00489 switch (cb_res) {
00490 case 0x400: return res;
00491
00492 default:
00493 case 0x401: res = CommandCost(default_error); break;
00494
00495 case 0x402: res = CommandCost(STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST); break;
00496 case 0x403: res = CommandCost(STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT); break;
00497 case 0x404: res = CommandCost(STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE); break;
00498 case 0x405: res = CommandCost(STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE); break;
00499 case 0x406: res = CommandCost(STR_ERROR_CAN_T_BUILD_ON_SEA); break;
00500 case 0x407: res = CommandCost(STR_ERROR_CAN_T_BUILD_ON_CANAL); break;
00501 case 0x408: res = CommandCost(STR_ERROR_CAN_T_BUILD_ON_RIVER); break;
00502 }
00503 }
00504
00505
00506 res.UseTextRefStack(4);
00507
00508 return res;
00509 }
00510
00518 void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res)
00519 {
00520 GRFConfig *grfconfig = GetGRFConfig(grfid);
00521
00522 if (!HasBit(grfconfig->grf_bugs, GBUG_UNKNOWN_CB_RESULT)) {
00523 SetBit(grfconfig->grf_bugs, GBUG_UNKNOWN_CB_RESULT);
00524 SetDParamStr(0, grfconfig->GetName());
00525 SetDParam(1, cbid);
00526 SetDParam(2, cb_res);
00527 ShowErrorMessage(STR_NEWGRF_BUGGY, STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT, WL_CRITICAL);
00528 }
00529
00530
00531 char buffer[512];
00532
00533 SetDParamStr(0, grfconfig->GetName());
00534 GetString(buffer, STR_NEWGRF_BUGGY, lastof(buffer));
00535 DEBUG(grf, 0, "%s", buffer + 3);
00536
00537 SetDParam(1, cbid);
00538 SetDParam(2, cb_res);
00539 GetString(buffer, STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT, lastof(buffer));
00540 DEBUG(grf, 0, "%s", buffer + 3);
00541 }
00542
00552 bool ConvertBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_res)
00553 {
00554 assert(cb_res != CALLBACK_FAILED);
00555
00556 if (grffile->grf_version < 8) return cb_res != 0;
00557
00558 if (cb_res > 1) ErrorUnknownCallbackResult(grffile->grfid, cbid, cb_res);
00559 return cb_res != 0;
00560 }
00561
00571 bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_res)
00572 {
00573 assert(cb_res != CALLBACK_FAILED);
00574
00575 if (grffile->grf_version < 8) return GB(cb_res, 0, 8) != 0;
00576
00577 if (cb_res > 1) ErrorUnknownCallbackResult(grffile->grfid, cbid, cb_res);
00578 return cb_res != 0;
00579 }
00580
00581
00582 SmallVector<DrawTileSeqStruct, 8> NewGRFSpriteLayout::result_seq;
00583
00588 void NewGRFSpriteLayout::Clone(const DrawTileSeqStruct *source)
00589 {
00590 assert(this->seq == NULL);
00591 assert(source != NULL);
00592
00593 size_t count = 1;
00594 const DrawTileSeqStruct *element;
00595 foreach_draw_tile_seq(element, source) count++;
00596
00597 DrawTileSeqStruct *sprites = MallocT<DrawTileSeqStruct>(count);
00598 MemCpyT(sprites, source, count);
00599 this->seq = sprites;
00600 }
00601
00606 void NewGRFSpriteLayout::Clone(const NewGRFSpriteLayout *source)
00607 {
00608 this->Clone((const DrawTileSprites*)source);
00609
00610 if (source->registers != NULL) {
00611 size_t count = 1;
00612 const DrawTileSeqStruct *element;
00613 foreach_draw_tile_seq(element, source->seq) count++;
00614
00615 TileLayoutRegisters *regs = MallocT<TileLayoutRegisters>(count);
00616 MemCpyT(regs, source->registers, count);
00617 this->registers = regs;
00618 }
00619 }
00620
00621
00626 void NewGRFSpriteLayout::Allocate(uint num_sprites)
00627 {
00628 assert(this->seq == NULL);
00629
00630 DrawTileSeqStruct *sprites = CallocT<DrawTileSeqStruct>(num_sprites + 1);
00631 sprites[num_sprites].MakeTerminator();
00632 this->seq = sprites;
00633 }
00634
00638 void NewGRFSpriteLayout::AllocateRegisters()
00639 {
00640 assert(this->seq != NULL);
00641 assert(this->registers == NULL);
00642
00643 size_t count = 1;
00644 const DrawTileSeqStruct *element;
00645 foreach_draw_tile_seq(element, this->seq) count++;
00646
00647 this->registers = CallocT<TileLayoutRegisters>(count);
00648 }
00649
00662 uint32 NewGRFSpriteLayout::PrepareLayout(uint32 orig_offset, uint32 newgrf_ground_offset, uint32 newgrf_offset, uint constr_stage, bool separate_ground) const
00663 {
00664 result_seq.Clear();
00665 uint32 var10_values = 0;
00666
00667
00668
00669 DrawTileSeqStruct *result = result_seq.Append();
00670 result->image = ground;
00671 result->delta_x = 0;
00672 result->delta_y = 0;
00673 result->delta_z = (int8)0x80;
00674
00675 const DrawTileSeqStruct *dtss;
00676 foreach_draw_tile_seq(dtss, this->seq) {
00677 *result_seq.Append() = *dtss;
00678 }
00679 result_seq.Append()->MakeTerminator();
00680
00681
00682
00683 const TileLayoutRegisters *regs = this->registers;
00684 bool ground = true;
00685 foreach_draw_tile_seq(result, result_seq.Begin()) {
00686 TileLayoutFlags flags = TLF_NOTHING;
00687 if (regs != NULL) flags = regs->flags;
00688
00689
00690 if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_SPRITE_REG_FLAGS)) {
00691 uint8 var10 = (flags & TLF_SPRITE_VAR10) ? regs->sprite_var10 : (ground && separate_ground ? 1 : 0);
00692 SetBit(var10_values, var10);
00693 }
00694
00695
00696 if (!(flags & TLF_SPRITE)) {
00697 if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
00698 result->image.sprite += ground ? newgrf_ground_offset : newgrf_offset;
00699 if (constr_stage > 0 && regs != NULL) result->image.sprite += GetConstructionStageOffset(constr_stage, regs->max_sprite_offset);
00700 } else {
00701 result->image.sprite += orig_offset;
00702 }
00703 }
00704
00705
00706 if (HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_PALETTE_REG_FLAGS)) {
00707 uint8 var10 = (flags & TLF_PALETTE_VAR10) ? regs->palette_var10 : (ground && separate_ground ? 1 : 0);
00708 SetBit(var10_values, var10);
00709 }
00710
00711
00712 if (!(flags & TLF_PALETTE)) {
00713 if (HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
00714 result->image.sprite += ground ? newgrf_ground_offset : newgrf_offset;
00715 if (constr_stage > 0 && regs != NULL) result->image.sprite += GetConstructionStageOffset(constr_stage, regs->max_palette_offset);
00716 }
00717 }
00718
00719 ground = false;
00720 if (regs != NULL) regs++;
00721 }
00722
00723 return var10_values;
00724 }
00725
00734 void NewGRFSpriteLayout::ProcessRegisters(uint8 resolved_var10, uint32 resolved_sprite, bool separate_ground) const
00735 {
00736 DrawTileSeqStruct *result;
00737 const TileLayoutRegisters *regs = this->registers;
00738 bool ground = true;
00739 foreach_draw_tile_seq(result, result_seq.Begin()) {
00740 TileLayoutFlags flags = TLF_NOTHING;
00741 if (regs != NULL) flags = regs->flags;
00742
00743
00744 if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_SPRITE_REG_FLAGS)) {
00745
00746 uint8 var10 = (flags & TLF_SPRITE_VAR10) ? regs->sprite_var10 : (ground && separate_ground ? 1 : 0);
00747 if (var10 == resolved_var10) {
00748
00749 if ((flags & TLF_DODRAW) && GetRegister(regs->dodraw) == 0) {
00750 result->image.sprite = 0;
00751 } else {
00752 if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE)) result->image.sprite += resolved_sprite;
00753 if (flags & TLF_SPRITE) {
00754 int16 offset = (int16)GetRegister(regs->sprite);
00755 if (!HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (offset >= 0 && offset < regs->max_sprite_offset)) {
00756 result->image.sprite += offset;
00757 } else {
00758 result->image.sprite = SPR_IMG_QUERY;
00759 }
00760 }
00761
00762 if (result->IsParentSprite()) {
00763 if (flags & TLF_BB_XY_OFFSET) {
00764 result->delta_x += (int32)GetRegister(regs->delta.parent[0]);
00765 result->delta_y += (int32)GetRegister(regs->delta.parent[1]);
00766 }
00767 if (flags & TLF_BB_Z_OFFSET) result->delta_z += (int32)GetRegister(regs->delta.parent[2]);
00768 } else {
00769 if (flags & TLF_CHILD_X_OFFSET) result->delta_x += (int32)GetRegister(regs->delta.child[0]);
00770 if (flags & TLF_CHILD_Y_OFFSET) result->delta_y += (int32)GetRegister(regs->delta.child[1]);
00771 }
00772 }
00773 }
00774 }
00775
00776
00777 if (result->image.sprite != 0 && (HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_PALETTE_REG_FLAGS))) {
00778
00779 uint8 var10 = (flags & TLF_PALETTE_VAR10) ? regs->palette_var10 : (ground && separate_ground ? 1 : 0);
00780 if (var10 == resolved_var10) {
00781
00782 if (HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) result->image.pal += resolved_sprite;
00783 if (flags & TLF_PALETTE) {
00784 int16 offset = (int16)GetRegister(regs->palette);
00785 if (!HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE) || (offset >= 0 && offset < regs->max_palette_offset)) {
00786 result->image.pal += offset;
00787 } else {
00788 result->image.sprite = SPR_IMG_QUERY;
00789 result->image.pal = PAL_NONE;
00790 }
00791 }
00792 }
00793 }
00794
00795 ground = false;
00796 if (regs != NULL) regs++;
00797 }
00798 }