435 ClrBit(grf_sprite->sprite, 15); |
435 ClrBit(grf_sprite->sprite, 15); |
436 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOR); |
436 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOR); |
437 } |
437 } |
438 } |
438 } |
439 |
439 |
440 typedef bool (*VCI_Handler)(uint engine, int numinfo, int prop, byte **buf, int len); |
440 enum ChangeInfoResult { |
441 |
441 CIR_SUCCESS, ///< Variable was parsed and read |
442 static bool CommonVehicleChangeInfo(EngineInfo *ei, int prop, byte **buf) |
442 CIR_UNHANDLED, ///< Variable was parsed but unread |
|
443 CIR_UNKNOWN, ///< Variable is unknown |
|
444 CIR_INVALID_ID, ///< Attempt to modify an invalid ID |
|
445 }; |
|
446 |
|
447 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, byte **buf, int len); |
|
448 |
|
449 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, byte **buf) |
443 { |
450 { |
444 switch (prop) { |
451 switch (prop) { |
445 case 0x00: // Introduction date |
452 case 0x00: // Introduction date |
446 ei->base_intro = grf_load_word(buf) + DAYS_TILL_ORIGINAL_BASE_YEAR; |
453 ei->base_intro = grf_load_word(buf) + DAYS_TILL_ORIGINAL_BASE_YEAR; |
447 break; |
454 break; |
469 /* Amount of cargo loaded during a vehicle's "loading tick" */ |
476 /* Amount of cargo loaded during a vehicle's "loading tick" */ |
470 ei->load_amount = grf_load_byte(buf); |
477 ei->load_amount = grf_load_byte(buf); |
471 break; |
478 break; |
472 |
479 |
473 default: |
480 default: |
474 return false; |
481 return CIR_UNKNOWN; |
475 } |
482 } |
476 |
483 |
477 return true; |
484 return CIR_SUCCESS; |
478 } |
485 } |
479 |
486 |
480 static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len) |
487 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len) |
481 { |
488 { |
482 byte *buf = *bufp; |
489 byte *buf = *bufp; |
483 bool ret = false; |
490 ChangeInfoResult ret = CIR_SUCCESS; |
484 |
491 |
485 for (int i = 0; i < numinfo; i++) { |
492 for (int i = 0; i < numinfo; i++) { |
486 Engine *e = GetNewEngine(_cur_grffile, VEH_TRAIN, engine + i); |
493 Engine *e = GetNewEngine(_cur_grffile, VEH_TRAIN, engine + i); |
487 EngineInfo *ei = &e->info; |
494 EngineInfo *ei = &e->info; |
488 RailVehicleInfo *rvi = &e->u.rail; |
495 RailVehicleInfo *rvi = &e->u.rail; |
705 case 0x2A: // Long format introduction date (days since year 0) |
712 case 0x2A: // Long format introduction date (days since year 0) |
706 ei->base_intro = grf_load_dword(&buf); |
713 ei->base_intro = grf_load_dword(&buf); |
707 break; |
714 break; |
708 |
715 |
709 default: |
716 default: |
710 ret = !CommonVehicleChangeInfo(ei, prop, &buf); |
717 ret = CommonVehicleChangeInfo(ei, prop, &buf); |
711 break; |
718 break; |
712 } |
719 } |
713 } |
720 } |
714 |
721 |
715 *bufp = buf; |
722 *bufp = buf; |
716 return ret; |
723 return ret; |
717 } |
724 } |
718 |
725 |
719 static bool RoadVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len) |
726 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len) |
720 { |
727 { |
721 byte *buf = *bufp; |
728 byte *buf = *bufp; |
722 bool ret = false; |
729 ChangeInfoResult ret = CIR_SUCCESS; |
723 |
730 |
724 for (int i = 0; i < numinfo; i++) { |
731 for (int i = 0; i < numinfo; i++) { |
725 Engine *e = GetNewEngine(_cur_grffile, VEH_ROAD, engine + i); |
732 Engine *e = GetNewEngine(_cur_grffile, VEH_ROAD, engine + i); |
726 EngineInfo *ei = &e->info; |
733 EngineInfo *ei = &e->info; |
727 RoadVehicleInfo *rvi = &e->u.road; |
734 RoadVehicleInfo *rvi = &e->u.road; |
794 case 0x15: // Speed in mph*0.8 |
801 case 0x15: // Speed in mph*0.8 |
795 /** @todo Support for road vehicles realistic power |
802 /** @todo Support for road vehicles realistic power |
796 * computations (called rvpower in TTDPatch) is just |
803 * computations (called rvpower in TTDPatch) is just |
797 * missing in OTTD yet. --pasky */ |
804 * missing in OTTD yet. --pasky */ |
798 grf_load_byte(&buf); |
805 grf_load_byte(&buf); |
799 ret = true; |
806 ret = CIR_UNHANDLED; |
800 break; |
807 break; |
801 |
808 |
802 case 0x16: // Cargos available for refitting |
809 case 0x16: // Cargos available for refitting |
803 ei->refit_mask = grf_load_dword(&buf); |
810 ei->refit_mask = grf_load_dword(&buf); |
804 break; |
811 break; |
809 |
816 |
810 case 0x18: // Tractive effort |
817 case 0x18: // Tractive effort |
811 case 0x19: // Air drag |
818 case 0x19: // Air drag |
812 /** @todo Tractive effort and air drag for road vehicles. */ |
819 /** @todo Tractive effort and air drag for road vehicles. */ |
813 grf_load_byte(&buf); |
820 grf_load_byte(&buf); |
814 ret = true; |
821 ret = CIR_UNHANDLED; |
815 break; |
822 break; |
816 |
823 |
817 case 0x1A: // Refit cost |
824 case 0x1A: // Refit cost |
818 ei->refit_cost = grf_load_byte(&buf); |
825 ei->refit_cost = grf_load_byte(&buf); |
819 break; |
826 break; |
842 case 0x20: // Alter purchase list sort order |
849 case 0x20: // Alter purchase list sort order |
843 AlterVehicleListOrder(e->index, grf_load_extended(&buf)); |
850 AlterVehicleListOrder(e->index, grf_load_extended(&buf)); |
844 break; |
851 break; |
845 |
852 |
846 default: |
853 default: |
847 ret = !CommonVehicleChangeInfo(ei, prop, &buf); |
854 ret = CommonVehicleChangeInfo(ei, prop, &buf); |
848 break; |
855 break; |
849 } |
856 } |
850 } |
857 } |
851 |
858 |
852 *bufp = buf; |
859 *bufp = buf; |
853 return ret; |
860 return ret; |
854 } |
861 } |
855 |
862 |
856 static bool ShipVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len) |
863 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len) |
857 { |
864 { |
858 byte *buf = *bufp; |
865 byte *buf = *bufp; |
859 bool ret = false; |
866 ChangeInfoResult ret = CIR_SUCCESS; |
860 |
867 |
861 for (int i = 0; i < numinfo; i++) { |
868 for (int i = 0; i < numinfo; i++) { |
862 Engine *e = GetNewEngine(_cur_grffile, VEH_SHIP, engine + i); |
869 Engine *e = GetNewEngine(_cur_grffile, VEH_SHIP, engine + i); |
863 EngineInfo *ei = &e->info; |
870 EngineInfo *ei = &e->info; |
864 ShipVehicleInfo *svi = &e->u.ship; |
871 ShipVehicleInfo *svi = &e->u.ship; |
926 |
933 |
927 case 0x14: // Ocean speed fraction |
934 case 0x14: // Ocean speed fraction |
928 case 0x15: // Canal speed fraction |
935 case 0x15: // Canal speed fraction |
929 /** @todo Speed fractions for ships on oceans and canals */ |
936 /** @todo Speed fractions for ships on oceans and canals */ |
930 grf_load_byte(&buf); |
937 grf_load_byte(&buf); |
931 ret = true; |
938 ret = CIR_UNHANDLED; |
932 break; |
939 break; |
933 |
940 |
934 case 0x16: // Retire vehicle early |
941 case 0x16: // Retire vehicle early |
935 ei->retire_early = grf_load_byte(&buf); |
942 ei->retire_early = grf_load_byte(&buf); |
936 break; |
943 break; |
955 case 0x1B: // Alter purchase list sort order |
962 case 0x1B: // Alter purchase list sort order |
956 AlterVehicleListOrder(e->index, grf_load_extended(&buf)); |
963 AlterVehicleListOrder(e->index, grf_load_extended(&buf)); |
957 break; |
964 break; |
958 |
965 |
959 default: |
966 default: |
960 ret = !CommonVehicleChangeInfo(ei, prop, &buf); |
967 ret = CommonVehicleChangeInfo(ei, prop, &buf); |
961 break; |
968 break; |
962 } |
969 } |
963 } |
970 } |
964 |
971 |
965 *bufp = buf; |
972 *bufp = buf; |
966 return ret; |
973 return ret; |
967 } |
974 } |
968 |
975 |
969 static bool AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len) |
976 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len) |
970 { |
977 { |
971 byte *buf = *bufp; |
978 byte *buf = *bufp; |
972 bool ret = false; |
979 ChangeInfoResult ret = CIR_SUCCESS; |
973 |
980 |
974 for (int i = 0; i < numinfo; i++) { |
981 for (int i = 0; i < numinfo; i++) { |
975 Engine *e = GetNewEngine(_cur_grffile, VEH_AIRCRAFT, engine + i); |
982 Engine *e = GetNewEngine(_cur_grffile, VEH_AIRCRAFT, engine + i); |
976 EngineInfo *ei = &e->info; |
983 EngineInfo *ei = &e->info; |
977 AircraftVehicleInfo *avi = &e->u.air; |
984 AircraftVehicleInfo *avi = &e->u.air; |
1064 case 0x1B: // Alter purchase list sort order |
1071 case 0x1B: // Alter purchase list sort order |
1065 AlterVehicleListOrder(e->index, grf_load_extended(&buf)); |
1072 AlterVehicleListOrder(e->index, grf_load_extended(&buf)); |
1066 break; |
1073 break; |
1067 |
1074 |
1068 default: |
1075 default: |
1069 ret = !CommonVehicleChangeInfo(ei, prop, &buf); |
1076 ret = CommonVehicleChangeInfo(ei, prop, &buf); |
1070 break; |
1077 break; |
1071 } |
1078 } |
1072 } |
1079 } |
1073 |
1080 |
1074 *bufp = buf; |
1081 *bufp = buf; |
1075 return ret; |
1082 return ret; |
1076 } |
1083 } |
1077 |
1084 |
1078 static bool StationChangeInfo(uint stid, int numinfo, int prop, byte **bufp, int len) |
1085 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, byte **bufp, int len) |
1079 { |
1086 { |
1080 byte *buf = *bufp; |
1087 byte *buf = *bufp; |
1081 bool ret = false; |
1088 ChangeInfoResult ret = CIR_SUCCESS; |
1082 |
1089 |
1083 if (stid + numinfo > MAX_STATIONS) { |
1090 if (stid + numinfo > MAX_STATIONS) { |
1084 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, MAX_STATIONS); |
1091 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, MAX_STATIONS); |
1085 return false; |
1092 return CIR_INVALID_ID; |
1086 } |
1093 } |
1087 |
1094 |
1088 /* Allocate station specs if necessary */ |
1095 /* Allocate station specs if necessary */ |
1089 if (_cur_grffile->stations == NULL) _cur_grffile->stations = CallocT<StationSpec*>(MAX_STATIONS); |
1096 if (_cur_grffile->stations == NULL) _cur_grffile->stations = CallocT<StationSpec*>(MAX_STATIONS); |
1090 |
1097 |
1092 StationSpec *statspec = _cur_grffile->stations[stid + i]; |
1099 StationSpec *statspec = _cur_grffile->stations[stid + i]; |
1093 |
1100 |
1094 /* Check that the station we are modifying is defined. */ |
1101 /* Check that the station we are modifying is defined. */ |
1095 if (statspec == NULL && prop != 0x08) { |
1102 if (statspec == NULL && prop != 0x08) { |
1096 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i); |
1103 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i); |
1097 return false; |
1104 return CIR_INVALID_ID; |
1098 } |
1105 } |
1099 |
1106 |
1100 switch (prop) { |
1107 switch (prop) { |
1101 case 0x08: { // Class ID |
1108 case 0x08: { // Class ID |
1102 StationSpec **spec = &_cur_grffile->stations[stid + i]; |
1109 StationSpec **spec = &_cur_grffile->stations[stid + i]; |
1273 case 0x18: // Animation triggers |
1280 case 0x18: // Animation triggers |
1274 statspec->anim_triggers = grf_load_word(&buf); |
1281 statspec->anim_triggers = grf_load_word(&buf); |
1275 break; |
1282 break; |
1276 |
1283 |
1277 default: |
1284 default: |
1278 ret = true; |
1285 ret = CIR_UNKNOWN; |
1279 break; |
1286 break; |
1280 } |
1287 } |
1281 } |
1288 } |
1282 |
1289 |
1283 *bufp = buf; |
1290 *bufp = buf; |
1284 return ret; |
1291 return ret; |
1285 } |
1292 } |
1286 |
1293 |
1287 static bool CanalChangeInfo(uint id, int numinfo, int prop, byte **bufp, int len) |
1294 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, byte **bufp, int len) |
1288 { |
1295 { |
1289 byte *buf = *bufp; |
1296 byte *buf = *bufp; |
1290 bool ret = false; |
1297 ChangeInfoResult ret = CIR_SUCCESS; |
1291 |
1298 |
1292 if (id + numinfo > CF_END) { |
1299 if (id + numinfo > CF_END) { |
1293 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoreing", id + numinfo, CF_END); |
1300 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoreing", id + numinfo, CF_END); |
1294 return false; |
1301 return CIR_INVALID_ID; |
1295 } |
1302 } |
1296 |
1303 |
1297 for (int i = 0; i < numinfo; i++) { |
1304 for (int i = 0; i < numinfo; i++) { |
1298 WaterFeature *wf = &_water_feature[id + i]; |
1305 WaterFeature *wf = &_water_feature[id + i]; |
1299 |
1306 |
1305 case 0x09: |
1312 case 0x09: |
1306 wf->flags = grf_load_byte(&buf); |
1313 wf->flags = grf_load_byte(&buf); |
1307 break; |
1314 break; |
1308 |
1315 |
1309 default: |
1316 default: |
1310 ret = true; |
1317 ret = CIR_UNKNOWN; |
1311 break; |
1318 break; |
1312 } |
1319 } |
1313 } |
1320 } |
1314 |
1321 |
1315 *bufp = buf; |
1322 *bufp = buf; |
1316 return ret; |
1323 return ret; |
1317 } |
1324 } |
1318 |
1325 |
1319 static bool BridgeChangeInfo(uint brid, int numinfo, int prop, byte **bufp, int len) |
1326 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, byte **bufp, int len) |
1320 { |
1327 { |
1321 byte *buf = *bufp; |
1328 byte *buf = *bufp; |
1322 bool ret = false; |
1329 ChangeInfoResult ret = CIR_SUCCESS; |
1323 |
1330 |
1324 if (brid + numinfo > MAX_BRIDGES) { |
1331 if (brid + numinfo > MAX_BRIDGES) { |
1325 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES); |
1332 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES); |
1326 return false; |
1333 return CIR_INVALID_ID; |
1327 } |
1334 } |
1328 |
1335 |
1329 for (int i = 0; i < numinfo; i++) { |
1336 for (int i = 0; i < numinfo; i++) { |
1330 BridgeSpec *bridge = &_bridge[brid + i]; |
1337 BridgeSpec *bridge = &_bridge[brid + i]; |
1331 |
1338 |
1404 case 0x13: // 16 bits cost multiplier |
1411 case 0x13: // 16 bits cost multiplier |
1405 bridge->price = grf_load_word(&buf); |
1412 bridge->price = grf_load_word(&buf); |
1406 break; |
1413 break; |
1407 |
1414 |
1408 default: |
1415 default: |
1409 ret = true; |
1416 ret = CIR_UNKNOWN; |
1410 break; |
1417 break; |
1411 } |
1418 } |
1412 } |
1419 } |
1413 |
1420 |
1414 *bufp = buf; |
1421 *bufp = buf; |
1415 return ret; |
1422 return ret; |
1416 } |
1423 } |
1417 |
1424 |
1418 static bool TownHouseChangeInfo(uint hid, int numinfo, int prop, byte **bufp, int len) |
1425 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, byte **bufp, int len) |
1419 { |
1426 { |
1420 byte *buf = *bufp; |
1427 byte *buf = *bufp; |
1421 bool ret = false; |
1428 ChangeInfoResult ret = CIR_SUCCESS; |
1422 |
1429 |
1423 if (hid + numinfo > HOUSE_MAX) { |
1430 if (hid + numinfo > HOUSE_MAX) { |
1424 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, HOUSE_MAX); |
1431 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, HOUSE_MAX); |
1425 return false; |
1432 return CIR_INVALID_ID; |
1426 } |
1433 } |
1427 |
1434 |
1428 /* Allocate house specs if they haven't been allocated already. */ |
1435 /* Allocate house specs if they haven't been allocated already. */ |
1429 if (_cur_grffile->housespec == NULL) { |
1436 if (_cur_grffile->housespec == NULL) { |
1430 _cur_grffile->housespec = CallocT<HouseSpec*>(HOUSE_MAX); |
1437 _cur_grffile->housespec = CallocT<HouseSpec*>(HOUSE_MAX); |
1433 for (int i = 0; i < numinfo; i++) { |
1440 for (int i = 0; i < numinfo; i++) { |
1434 HouseSpec *housespec = _cur_grffile->housespec[hid + i]; |
1441 HouseSpec *housespec = _cur_grffile->housespec[hid + i]; |
1435 |
1442 |
1436 if (prop != 0x08 && housespec == NULL) { |
1443 if (prop != 0x08 && housespec == NULL) { |
1437 grfmsg(2, "TownHouseChangeInfo: Attempt to modify undefined house %u. Ignoring.", hid + i); |
1444 grfmsg(2, "TownHouseChangeInfo: Attempt to modify undefined house %u. Ignoring.", hid + i); |
1438 return false; |
1445 return CIR_INVALID_ID; |
1439 } |
1446 } |
1440 |
1447 |
1441 switch (prop) { |
1448 switch (prop) { |
1442 case 0x08: { // Substitute building type, and definition of a new house |
1449 case 0x08: { // Substitute building type, and definition of a new house |
1443 HouseSpec **house = &_cur_grffile->housespec[hid + i]; |
1450 HouseSpec **house = &_cur_grffile->housespec[hid + i]; |
1616 break; |
1623 break; |
1617 |
1624 |
1618 case 0x20: { // @todo Cargo acceptance watch list |
1625 case 0x20: { // @todo Cargo acceptance watch list |
1619 byte count = grf_load_byte(&buf); |
1626 byte count = grf_load_byte(&buf); |
1620 for (byte j = 0; j < count; j++) grf_load_byte(&buf); |
1627 for (byte j = 0; j < count; j++) grf_load_byte(&buf); |
1621 ret = true; |
1628 ret = CIR_UNHANDLED; |
1622 } break; |
1629 } break; |
1623 |
1630 |
1624 case 0x21: // long introduction year |
1631 case 0x21: // long introduction year |
1625 housespec->min_year = grf_load_word(&buf); |
1632 housespec->min_year = grf_load_word(&buf); |
1626 break; |
1633 break; |
1628 case 0x22: // long maximum year |
1635 case 0x22: // long maximum year |
1629 housespec->max_year = grf_load_word(&buf); |
1636 housespec->max_year = grf_load_word(&buf); |
1630 break; |
1637 break; |
1631 |
1638 |
1632 default: |
1639 default: |
1633 ret = true; |
1640 ret = CIR_UNKNOWN; |
1634 break; |
1641 break; |
1635 } |
1642 } |
1636 } |
1643 } |
1637 |
1644 |
1638 *bufp = buf; |
1645 *bufp = buf; |
1639 return ret; |
1646 return ret; |
1640 } |
1647 } |
1641 |
1648 |
1642 static bool GlobalVarChangeInfo(uint gvid, int numinfo, int prop, byte **bufp, int len) |
1649 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, byte **bufp, int len) |
1643 { |
1650 { |
1644 byte *buf = *bufp; |
1651 byte *buf = *bufp; |
1645 bool ret = false; |
1652 ChangeInfoResult ret = CIR_SUCCESS; |
1646 |
1653 |
1647 for (int i = 0; i < numinfo; i++) { |
1654 for (int i = 0; i < numinfo; i++) { |
1648 switch (prop) { |
1655 switch (prop) { |
1649 case 0x08: { // Cost base factor |
1656 case 0x08: { // Cost base factor |
1650 byte factor = grf_load_byte(&buf); |
1657 byte factor = grf_load_byte(&buf); |
1757 /* Each entry is 8 bytes. */ |
1764 /* Each entry is 8 bytes. */ |
1758 buf += 8; |
1765 buf += 8; |
1759 break; |
1766 break; |
1760 |
1767 |
1761 default: |
1768 default: |
1762 ret = true; |
1769 ret = CIR_UNKNOWN; |
1763 break; |
1770 break; |
1764 } |
1771 } |
1765 } |
1772 } |
1766 |
1773 |
1767 *bufp = buf; |
1774 *bufp = buf; |
1768 return ret; |
1775 return ret; |
1769 } |
1776 } |
1770 |
1777 |
1771 static bool CargoChangeInfo(uint cid, int numinfo, int prop, byte **bufp, int len) |
1778 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, byte **bufp, int len) |
1772 { |
1779 { |
1773 byte *buf = *bufp; |
1780 byte *buf = *bufp; |
1774 bool ret = false; |
1781 ChangeInfoResult ret = CIR_SUCCESS; |
1775 |
1782 |
1776 if (cid + numinfo > NUM_CARGO) { |
1783 if (cid + numinfo > NUM_CARGO) { |
1777 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1); |
1784 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1); |
1778 return false; |
1785 return CIR_INVALID_ID; |
1779 } |
1786 } |
1780 |
1787 |
1781 for (int i = 0; i < numinfo; i++) { |
1788 for (int i = 0; i < numinfo; i++) { |
1782 CargoSpec *cs = &_cargo[cid + i]; |
1789 CargoSpec *cs = &_cargo[cid + i]; |
1783 |
1790 |
1882 case 0x1A: /* Bitmask of callbacks to use */ |
1889 case 0x1A: /* Bitmask of callbacks to use */ |
1883 cs->callback_mask = grf_load_byte(&buf); |
1890 cs->callback_mask = grf_load_byte(&buf); |
1884 break; |
1891 break; |
1885 |
1892 |
1886 default: |
1893 default: |
1887 ret = true; |
1894 ret = CIR_UNKNOWN; |
1888 break; |
1895 break; |
1889 } |
1896 } |
1890 } |
1897 } |
1891 |
1898 |
1892 *bufp = buf; |
1899 *bufp = buf; |
1893 return ret; |
1900 return ret; |
1894 } |
1901 } |
1895 |
1902 |
1896 |
1903 |
1897 static bool SoundEffectChangeInfo(uint sid, int numinfo, int prop, byte **bufp, int len) |
1904 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, byte **bufp, int len) |
1898 { |
1905 { |
1899 byte *buf = *bufp; |
1906 byte *buf = *bufp; |
1900 bool ret = false; |
1907 ChangeInfoResult ret = CIR_SUCCESS; |
1901 |
1908 |
1902 if (_cur_grffile->sound_offset == 0) { |
1909 if (_cur_grffile->sound_offset == 0) { |
1903 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping"); |
1910 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping"); |
1904 return false; |
1911 return CIR_INVALID_ID; |
1905 } |
1912 } |
1906 |
1913 |
1907 for (int i = 0; i < numinfo; i++) { |
1914 for (int i = 0; i < numinfo; i++) { |
1908 uint sound = sid + i + _cur_grffile->sound_offset - GetNumOriginalSounds(); |
1915 uint sound = sid + i + _cur_grffile->sound_offset - GetNumOriginalSounds(); |
1909 |
1916 |
1910 if (sound >= GetNumSounds()) { |
1917 if (sound >= GetNumSounds()) { |
1911 grfmsg(1, "SoundEffectChangeInfo: Sound %d not defined (max %d)", sound, GetNumSounds()); |
1918 grfmsg(1, "SoundEffectChangeInfo: Sound %d not defined (max %d)", sound, GetNumSounds()); |
1912 return false; |
1919 return CIR_INVALID_ID; |
1913 } |
1920 } |
1914 |
1921 |
1915 switch (prop) { |
1922 switch (prop) { |
1916 case 0x08: // Relative volume |
1923 case 0x08: // Relative volume |
1917 GetSound(sound)->volume = grf_load_byte(&buf); |
1924 GetSound(sound)->volume = grf_load_byte(&buf); |
1934 *oldfe = *newfe; |
1941 *oldfe = *newfe; |
1935 } |
1942 } |
1936 } break; |
1943 } break; |
1937 |
1944 |
1938 default: |
1945 default: |
1939 ret = true; |
1946 ret = CIR_UNKNOWN; |
1940 break; |
1947 break; |
1941 } |
1948 } |
1942 } |
1949 } |
1943 |
1950 |
1944 *bufp = buf; |
1951 *bufp = buf; |
1945 return ret; |
1952 return ret; |
1946 } |
1953 } |
1947 |
1954 |
1948 static bool IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, byte **bufp, int len) |
1955 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, byte **bufp, int len) |
1949 { |
1956 { |
1950 byte *buf = *bufp; |
1957 byte *buf = *bufp; |
1951 bool ret = false; |
1958 ChangeInfoResult ret = CIR_SUCCESS; |
1952 |
1959 |
1953 if (indtid + numinfo > NUM_INDUSTRYTILES) { |
1960 if (indtid + numinfo > NUM_INDUSTRYTILES) { |
1954 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES); |
1961 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES); |
1955 return false; |
1962 return CIR_INVALID_ID; |
1956 } |
1963 } |
1957 |
1964 |
1958 /* Allocate industry tile specs if they haven't been allocated already. */ |
1965 /* Allocate industry tile specs if they haven't been allocated already. */ |
1959 if (_cur_grffile->indtspec == NULL) { |
1966 if (_cur_grffile->indtspec == NULL) { |
1960 _cur_grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES); |
1967 _cur_grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES); |
1963 for (int i = 0; i < numinfo; i++) { |
1970 for (int i = 0; i < numinfo; i++) { |
1964 IndustryTileSpec *tsp = _cur_grffile->indtspec[indtid + i]; |
1971 IndustryTileSpec *tsp = _cur_grffile->indtspec[indtid + i]; |
1965 |
1972 |
1966 if (prop != 0x08 && tsp == NULL) { |
1973 if (prop != 0x08 && tsp == NULL) { |
1967 grfmsg(2, "IndustryTilesChangeInfo: Attempt to modify undefined industry tile %u. Ignoring.", indtid + i); |
1974 grfmsg(2, "IndustryTilesChangeInfo: Attempt to modify undefined industry tile %u. Ignoring.", indtid + i); |
1968 return false; |
1975 return CIR_INVALID_ID; |
1969 } |
1976 } |
1970 |
1977 |
1971 switch (prop) { |
1978 switch (prop) { |
1972 case 0x08: { // Substitute industry tile type |
1979 case 0x08: { // Substitute industry tile type |
1973 IndustryTileSpec **tilespec = &_cur_grffile->indtspec[indtid + i]; |
1980 IndustryTileSpec **tilespec = &_cur_grffile->indtspec[indtid + i]; |
2044 case 0x12: // Special flags |
2051 case 0x12: // Special flags |
2045 tsp->animation_special_flags = grf_load_byte(&buf); |
2052 tsp->animation_special_flags = grf_load_byte(&buf); |
2046 break; |
2053 break; |
2047 |
2054 |
2048 default: |
2055 default: |
2049 ret = true; |
2056 ret = CIR_UNKNOWN; |
2050 break; |
2057 break; |
2051 } |
2058 } |
2052 } |
2059 } |
2053 |
2060 |
2054 *bufp = buf; |
2061 *bufp = buf; |
2055 return ret; |
2062 return ret; |
2056 } |
2063 } |
2057 |
2064 |
2058 static bool IndustriesChangeInfo(uint indid, int numinfo, int prop, byte **bufp, int len) |
2065 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, byte **bufp, int len) |
2059 { |
2066 { |
2060 byte *buf = *bufp; |
2067 byte *buf = *bufp; |
2061 bool ret = false; |
2068 ChangeInfoResult ret = CIR_SUCCESS; |
2062 |
2069 |
2063 if (indid + numinfo > NUM_INDUSTRYTYPES) { |
2070 if (indid + numinfo > NUM_INDUSTRYTYPES) { |
2064 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES); |
2071 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES); |
2065 return false; |
2072 return CIR_INVALID_ID; |
2066 } |
2073 } |
2067 |
2074 |
2068 grfmsg(1, "IndustriesChangeInfo: newid %u", indid); |
2075 grfmsg(1, "IndustriesChangeInfo: newid %u", indid); |
2069 |
2076 |
2070 /* Allocate industry specs if they haven't been allocated already. */ |
2077 /* Allocate industry specs if they haven't been allocated already. */ |
2075 for (int i = 0; i < numinfo; i++) { |
2082 for (int i = 0; i < numinfo; i++) { |
2076 IndustrySpec *indsp = _cur_grffile->industryspec[indid + i]; |
2083 IndustrySpec *indsp = _cur_grffile->industryspec[indid + i]; |
2077 |
2084 |
2078 if (prop != 0x08 && indsp == NULL) { |
2085 if (prop != 0x08 && indsp == NULL) { |
2079 grfmsg(2, "IndustriesChangeInfo: Attempt to modify undefined industry %u. Ignoring.", indid + i); |
2086 grfmsg(2, "IndustriesChangeInfo: Attempt to modify undefined industry %u. Ignoring.", indid + i); |
2080 return false; |
2087 return CIR_INVALID_ID; |
2081 } |
2088 } |
2082 |
2089 |
2083 switch (prop) { |
2090 switch (prop) { |
2084 case 0x08: { // Substitute industry type |
2091 case 0x08: { // Substitute industry type |
2085 IndustrySpec **indspec = &_cur_grffile->industryspec[indid + i]; |
2092 IndustrySpec **indspec = &_cur_grffile->industryspec[indid + i]; |
2366 } |
2373 } |
2367 |
2374 |
2368 while (numprops-- && buf < bufend) { |
2375 while (numprops-- && buf < bufend) { |
2369 uint8 prop = grf_load_byte(&buf); |
2376 uint8 prop = grf_load_byte(&buf); |
2370 |
2377 |
2371 if (handler[feature](engine, numinfo, prop, &buf, bufend - buf)) { |
2378 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, &buf, bufend - buf); |
2372 grfmsg(1, "FeatureChangeInfo: Ignoring property 0x%02X of feature 0x%02X (not implemented)", prop, feature); |
2379 switch (cir) { |
|
2380 case CIR_SUCCESS: |
|
2381 break; |
|
2382 |
|
2383 case CIR_UNHANDLED: |
|
2384 grfmsg(1, "FeatureChangeInfo: Ignoring property 0x%02X of feature 0x%02X (not implemented)", prop, feature); |
|
2385 break; |
|
2386 |
|
2387 case CIR_UNKNOWN: |
|
2388 grfmsg(0, "FeatureChangeInfo: Unknown property 0x%02X of feature 0x%02X, disabling", prop, feature); |
|
2389 /* Fall through */ |
|
2390 |
|
2391 case CIR_INVALID_ID: |
|
2392 /* No debug message for an invalid ID, as it has already been output */ |
|
2393 _skip_sprites = -1; |
|
2394 _cur_grfconfig->status = GCS_DISABLED; |
|
2395 _cur_grfconfig->error = CallocT<GRFError>(1); |
|
2396 _cur_grfconfig->error->severity = STR_NEWGRF_ERROR_MSG_FATAL; |
|
2397 _cur_grfconfig->error->message = (cir == CIR_INVALID_ID) ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY; |
|
2398 return; |
2373 } |
2399 } |
2374 } |
2400 } |
2375 } |
2401 } |
2376 |
2402 |
2377 /* Action 0x00 (GLS_SAFETYSCAN) */ |
2403 /* Action 0x00 (GLS_SAFETYSCAN) */ |