856 res->trigger = 0; |
856 res->trigger = 0; |
857 res->reseed = 0; |
857 res->reseed = 0; |
858 } |
858 } |
859 |
859 |
860 |
860 |
|
861 /** Retrieve the SpriteGroup for the specified vehicle. |
|
862 * If the vehicle is not specified, the purchase list group for the engine is |
|
863 * chosen. For trains, an additional engine override lookup is performed. |
|
864 * @param engine Engine type of the vehicle. |
|
865 * @param v The vehicle itself. |
|
866 * @returns The selected SpriteGroup for the vehicle. |
|
867 */ |
|
868 static const SpriteGroup *GetVehicleSpriteGroup(EngineID engine, const Vehicle *v) |
|
869 { |
|
870 const SpriteGroup *group; |
|
871 CargoID cargo; |
|
872 |
|
873 if (v == NULL) { |
|
874 cargo = GC_PURCHASE; |
|
875 } else { |
|
876 cargo = _global_cargo_id[_opt.landscape][v->cargo_type]; |
|
877 assert(cargo != GC_INVALID); |
|
878 |
|
879 if (v->type == VEH_Train) { |
|
880 group = GetWagonOverrideSpriteSet(engine, cargo, v->u.rail.first_engine); |
|
881 |
|
882 if (group != NULL) return group; |
|
883 } |
|
884 } |
|
885 |
|
886 group = engine_custom_sprites[engine][cargo]; |
|
887 if (group != NULL) return group; |
|
888 |
|
889 /* Fall back to the default set if the selected cargo type is not defined */ |
|
890 return engine_custom_sprites[engine][GC_DEFAULT]; |
|
891 } |
|
892 |
|
893 |
861 SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction) |
894 SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction) |
862 { |
895 { |
863 const SpriteGroup *group; |
896 const SpriteGroup *group; |
864 ResolverObject object; |
897 ResolverObject object; |
865 CargoID cargo; |
|
866 |
898 |
867 NewVehicleResolver(&object, engine, v); |
899 NewVehicleResolver(&object, engine, v); |
868 |
900 |
869 cargo = (v == NULL) ? GC_PURCHASE : _global_cargo_id[_opt.landscape][v->cargo_type]; |
901 group = Resolve(GetVehicleSpriteGroup(engine, v), &object); |
870 assert(cargo != GC_INVALID); |
|
871 |
|
872 group = engine_custom_sprites[engine][cargo]; |
|
873 |
|
874 if (v != NULL && v->type == VEH_Train) { |
|
875 const SpriteGroup *overset = GetWagonOverrideSpriteSet(engine, cargo, v->u.rail.first_engine); |
|
876 |
|
877 if (overset != NULL) group = overset; |
|
878 } |
|
879 |
|
880 if (group == NULL) group = engine_custom_sprites[engine][GC_DEFAULT]; |
|
881 group = Resolve(group, &object); |
|
882 if (group == NULL || group->type != SGT_RESULT) return 0; |
902 if (group == NULL || group->type != SGT_RESULT) return 0; |
883 |
903 |
884 return group->g.result.sprite + (direction % group->g.result.num_sprites); |
904 return group->g.result.sprite + (direction % group->g.result.num_sprites); |
885 } |
905 } |
886 |
906 |
933 */ |
953 */ |
934 uint16 GetVehicleCallback(uint16 callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v) |
954 uint16 GetVehicleCallback(uint16 callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v) |
935 { |
955 { |
936 const SpriteGroup *group; |
956 const SpriteGroup *group; |
937 ResolverObject object; |
957 ResolverObject object; |
938 CargoID cargo; |
|
939 |
958 |
940 NewVehicleResolver(&object, engine, v); |
959 NewVehicleResolver(&object, engine, v); |
941 |
960 |
942 object.callback = callback; |
961 object.callback = callback; |
943 object.callback_param1 = param1; |
962 object.callback_param1 = param1; |
944 object.callback_param2 = param2; |
963 object.callback_param2 = param2; |
945 |
964 |
946 cargo = (v == NULL) ? GC_PURCHASE : _global_cargo_id[_opt.landscape][v->cargo_type]; |
965 group = Resolve(GetVehicleSpriteGroup(engine, v), &object); |
947 assert(cargo != GC_INVALID); |
|
948 |
|
949 group = engine_custom_sprites[engine][cargo]; |
|
950 |
|
951 if (v != NULL && v->type == VEH_Train) { |
|
952 const SpriteGroup *overset = GetWagonOverrideSpriteSet(engine, cargo, v->u.rail.first_engine); |
|
953 |
|
954 if (overset != NULL) group = overset; |
|
955 } |
|
956 |
|
957 if (group == NULL) group = engine_custom_sprites[engine][GC_DEFAULT]; |
|
958 group = Resolve(group, &object); |
|
959 if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED; |
966 if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED; |
960 |
967 |
961 return group->g.callback.result; |
968 return group->g.callback.result; |
962 } |
969 } |
963 |
970 |
973 */ |
980 */ |
974 uint16 GetVehicleCallbackParent(uint16 callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v, const Vehicle *parent) |
981 uint16 GetVehicleCallbackParent(uint16 callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v, const Vehicle *parent) |
975 { |
982 { |
976 const SpriteGroup *group; |
983 const SpriteGroup *group; |
977 ResolverObject object; |
984 ResolverObject object; |
978 CargoID cargo; |
|
979 |
985 |
980 NewVehicleResolver(&object, engine, v); |
986 NewVehicleResolver(&object, engine, v); |
981 |
987 |
982 object.callback = callback; |
988 object.callback = callback; |
983 object.callback_param1 = param1; |
989 object.callback_param1 = param1; |
984 object.callback_param2 = param2; |
990 object.callback_param2 = param2; |
985 |
991 |
986 object.u.vehicle.parent = parent; |
992 object.u.vehicle.parent = parent; |
987 |
993 |
988 cargo = (v == NULL) ? GC_PURCHASE : _global_cargo_id[_opt.landscape][v->cargo_type]; |
994 group = Resolve(GetVehicleSpriteGroup(engine, v), &object); |
989 assert(cargo != GC_INVALID); |
|
990 |
|
991 group = engine_custom_sprites[engine][cargo]; |
|
992 |
|
993 if (v != NULL && v->type == VEH_Train) { |
|
994 const SpriteGroup *overset = GetWagonOverrideSpriteSet(engine, cargo, v->u.rail.first_engine); |
|
995 |
|
996 if (overset != NULL) group = overset; |
|
997 } |
|
998 |
|
999 if (group == NULL) group = engine_custom_sprites[engine][GC_DEFAULT]; |
|
1000 group = Resolve(group, &object); |
|
1001 if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED; |
995 if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED; |
1002 |
996 |
1003 return group->g.callback.result; |
997 return group->g.callback.result; |
1004 } |
998 } |
1005 |
999 |
1006 static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_random_bits, bool first) |
1000 static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_random_bits, bool first) |
1007 { |
1001 { |
1008 const SpriteGroup *group; |
1002 const SpriteGroup *group; |
1009 ResolverObject object; |
1003 ResolverObject object; |
1010 CargoID cargo; |
|
1011 byte new_random_bits; |
1004 byte new_random_bits; |
1012 |
1005 |
1013 /* We can't trigger a non-existent vehicle... */ |
1006 /* We can't trigger a non-existent vehicle... */ |
1014 assert(v != NULL); |
1007 assert(v != NULL); |
1015 |
1008 |
1016 NewVehicleResolver(&object, v->engine_type, v); |
1009 NewVehicleResolver(&object, v->engine_type, v); |
1017 |
1010 |
1018 object.trigger = trigger; |
1011 object.trigger = trigger; |
1019 |
1012 |
1020 cargo = _global_cargo_id[_opt.landscape][v->cargo_type]; |
1013 group = Resolve(GetVehicleSpriteGroup(v->engine_type, v), &object); |
1021 assert(cargo != GC_INVALID); |
|
1022 |
|
1023 group = engine_custom_sprites[v->engine_type][cargo]; |
|
1024 |
|
1025 if (v->type == VEH_Train) { |
|
1026 const SpriteGroup *overset = GetWagonOverrideSpriteSet(v->engine_type, cargo, v->u.rail.first_engine); |
|
1027 if (overset != NULL) group = overset; |
|
1028 } |
|
1029 |
|
1030 if (group == NULL) group = engine_custom_sprites[v->engine_type][GC_DEFAULT]; |
|
1031 group = Resolve(group, &object); |
|
1032 |
1014 |
1033 new_random_bits = Random(); |
1015 new_random_bits = Random(); |
1034 v->random_bits &= ~object.reseed; |
1016 v->random_bits &= ~object.reseed; |
1035 v->random_bits |= (first ? new_random_bits : base_random_bits) & object.reseed; |
1017 v->random_bits |= (first ? new_random_bits : base_random_bits) & object.reseed; |
1036 |
1018 |