670 gp.x = v->x_pos; |
670 gp.x = v->x_pos; |
671 gp.y = v->y_pos; |
671 gp.y = v->y_pos; |
672 } else { |
672 } else { |
673 /* Not inside depot */ |
673 /* Not inside depot */ |
674 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); |
674 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); |
675 if (HASBIT(r, VETS_CANNOT_ENTER)) goto reverse_direction; |
675 if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction; |
676 |
676 |
677 /* A leave station order only needs one tick to get processed, so we can |
677 /* A leave station order only needs one tick to get processed, so we can |
678 * always skip ahead. */ |
678 * always skip ahead. */ |
679 if (v->current_order.type == OT_LEAVESTATION) { |
679 if (v->current_order.type == OT_LEAVESTATION) { |
680 v->current_order.Free(); |
680 v->current_order.Free(); |
740 gp.x = (gp.x & ~0xF) | b[0]; |
740 gp.x = (gp.x & ~0xF) | b[0]; |
741 gp.y = (gp.y & ~0xF) | b[1]; |
741 gp.y = (gp.y & ~0xF) | b[1]; |
742 |
742 |
743 /* Call the landscape function and tell it that the vehicle entered the tile */ |
743 /* Call the landscape function and tell it that the vehicle entered the tile */ |
744 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); |
744 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); |
745 if (HASBIT(r, VETS_CANNOT_ENTER)) goto reverse_direction; |
745 if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction; |
746 |
746 |
747 if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) { |
747 if (!HasBit(r, VETS_ENTERED_WORMHOLE)) { |
748 v->tile = gp.new_tile; |
748 v->tile = gp.new_tile; |
749 v->u.ship.state = TrackToTrackBits(track); |
749 v->u.ship.state = TrackToTrackBits(track); |
750 } |
750 } |
751 |
751 |
752 v->direction = (Direction)b[2]; |
752 v->direction = (Direction)b[2]; |
821 * so we must check against cheaters no sooner than now. --pasky */ |
821 * so we must check against cheaters no sooner than now. --pasky */ |
822 if (!IsTileDepotType(tile, TRANSPORT_WATER)) return CMD_ERROR; |
822 if (!IsTileDepotType(tile, TRANSPORT_WATER)) return CMD_ERROR; |
823 if (!IsTileOwner(tile, _current_player)) return CMD_ERROR; |
823 if (!IsTileOwner(tile, _current_player)) return CMD_ERROR; |
824 |
824 |
825 v = new Ship(); |
825 v = new Ship(); |
826 unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_SHIP); |
826 unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_SHIP); |
827 AutoPtrT<Vehicle> v_auto_delete = v; |
827 AutoPtrT<Vehicle> v_auto_delete = v; |
828 |
828 |
829 if (v == NULL || unit_num > _patches.max_ships) |
829 if (v == NULL || unit_num > _patches.max_ships) |
830 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
830 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
831 |
831 |
869 |
870 |
870 v->service_interval = _patches.servint_ships; |
871 v->service_interval = _patches.servint_ships; |
871 v->date_of_last_service = _date; |
872 v->date_of_last_service = _date; |
872 v->build_year = _cur_year; |
873 v->build_year = _cur_year; |
873 v->cur_image = 0x0E5E; |
874 v->cur_image = 0x0E5E; |
874 v = new (v) Ship(); |
|
875 v->random_bits = VehicleRandomBits(); |
875 v->random_bits = VehicleRandomBits(); |
876 |
876 |
877 v->vehicle_flags = 0; |
877 v->vehicle_flags = 0; |
878 if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); |
878 if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); |
879 |
879 |
880 v->cargo_cap = GetVehicleProperty(v, 0x0D, svi->capacity); |
880 v->cargo_cap = GetVehicleProperty(v, 0x0D, svi->capacity); |
881 |
881 |
882 VehiclePositionChanged(v); |
882 VehiclePositionChanged(v); |
883 |
883 |
917 |
917 |
918 if (!v->IsStoppedInDepot()) { |
918 if (!v->IsStoppedInDepot()) { |
919 return_cmd_error(STR_980B_SHIP_MUST_BE_STOPPED_IN); |
919 return_cmd_error(STR_980B_SHIP_MUST_BE_STOPPED_IN); |
920 } |
920 } |
921 |
921 |
|
922 CommandCost ret(-v->value); |
|
923 |
922 if (flags & DC_EXEC) { |
924 if (flags & DC_EXEC) { |
923 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
925 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
924 RebuildVehicleLists(); |
926 RebuildVehicleLists(); |
925 InvalidateWindow(WC_COMPANY, v->owner); |
927 InvalidateWindow(WC_COMPANY, v->owner); |
926 DeleteWindowById(WC_VEHICLE_VIEW, v->index); |
928 DeleteWindowById(WC_VEHICLE_VIEW, v->index); |
927 DeleteDepotHighlightOfVehicle(v); |
929 DeleteDepotHighlightOfVehicle(v); |
928 delete v; |
930 delete v; |
929 } |
931 } |
930 |
932 |
931 return CommandCost(-v->value); |
933 return ret; |
932 } |
934 } |
933 |
935 |
934 /** Start/Stop a ship. |
936 /** Start/Stop a ship. |
935 * @param tile unused |
937 * @param tile unused |
936 * @param flags type of operation |
938 * @param flags type of operation |
960 if (v->IsStoppedInDepot()) { |
962 if (v->IsStoppedInDepot()) { |
961 DeleteVehicleNews(p1, STR_981C_SHIP_IS_WAITING_IN_DEPOT); |
963 DeleteVehicleNews(p1, STR_981C_SHIP_IS_WAITING_IN_DEPOT); |
962 } |
964 } |
963 |
965 |
964 v->vehstatus ^= VS_STOPPED; |
966 v->vehstatus ^= VS_STOPPED; |
|
967 v->cur_speed = 0; |
965 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
968 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
966 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
969 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
967 InvalidateWindowClasses(WC_SHIPS_LIST); |
970 InvalidateWindowClasses(WC_SHIPS_LIST); |
968 } |
971 } |
969 |
972 |
999 |
1002 |
1000 if (v->IsInDepot()) return CMD_ERROR; |
1003 if (v->IsInDepot()) return CMD_ERROR; |
1001 |
1004 |
1002 /* If the current orders are already goto-depot */ |
1005 /* If the current orders are already goto-depot */ |
1003 if (v->current_order.type == OT_GOTO_DEPOT) { |
1006 if (v->current_order.type == OT_GOTO_DEPOT) { |
1004 if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) { |
1007 if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OFB_HALT_IN_DEPOT)) { |
1005 /* We called with a different DEPOT_SERVICE setting. |
1008 /* We called with a different DEPOT_SERVICE setting. |
1006 * Now we change the setting to apply the new one and let the vehicle head for the same depot. |
1009 * Now we change the setting to apply the new one and let the vehicle head for the same depot. |
1007 * Note: the if is (true for requesting service == true for ordered to stop in depot) */ |
1010 * Note: the if is (true for requesting service == true for ordered to stop in depot) */ |
1008 if (flags & DC_EXEC) { |
1011 if (flags & DC_EXEC) { |
1009 CLRBIT(v->current_order.flags, OFB_PART_OF_ORDERS); |
1012 ClrBit(v->current_order.flags, OFB_PART_OF_ORDERS); |
1010 TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); |
1013 ToggleBit(v->current_order.flags, OFB_HALT_IN_DEPOT); |
1011 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
1014 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
1012 } |
1015 } |
1013 return CommandCost(); |
1016 return CommandCost(); |
1014 } |
1017 } |
1015 |
1018 |
1016 if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders |
1019 if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders |
1017 if (flags & DC_EXEC) { |
1020 if (flags & DC_EXEC) { |
1018 /* If the orders to 'goto depot' are in the orders list (forced servicing), |
1021 /* If the orders to 'goto depot' are in the orders list (forced servicing), |
1019 * then skip to the next order; effectively cancelling this forced service */ |
1022 * then skip to the next order; effectively cancelling this forced service */ |
1020 if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) |
1023 if (HasBit(v->current_order.flags, OFB_PART_OF_ORDERS)) |
1021 v->cur_order_index++; |
1024 v->cur_order_index++; |
1022 |
1025 |
1023 v->current_order.type = OT_DUMMY; |
1026 v->current_order.type = OT_DUMMY; |
1024 v->current_order.flags = 0; |
1027 v->current_order.flags = 0; |
1025 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
1028 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
1034 if (v->current_order.type == OT_LOADING) v->LeaveStation(); |
1037 if (v->current_order.type == OT_LOADING) v->LeaveStation(); |
1035 |
1038 |
1036 v->dest_tile = dep->xy; |
1039 v->dest_tile = dep->xy; |
1037 v->current_order.type = OT_GOTO_DEPOT; |
1040 v->current_order.type = OT_GOTO_DEPOT; |
1038 v->current_order.flags = OF_NON_STOP; |
1041 v->current_order.flags = OF_NON_STOP; |
1039 if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); |
1042 if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OFB_HALT_IN_DEPOT); |
1040 v->current_order.refit_cargo = CT_INVALID; |
1043 v->current_order.refit_cargo = CT_INVALID; |
1041 v->current_order.dest = dep->index; |
1044 v->current_order.dest = dep->index; |
1042 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
1045 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
1043 } |
1046 } |
1044 |
1047 |
1079 if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR; |
1082 if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR; |
1080 |
1083 |
1081 SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN); |
1084 SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN); |
1082 |
1085 |
1083 /* Check the refit capacity callback */ |
1086 /* Check the refit capacity callback */ |
1084 if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) { |
1087 if (HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) { |
1085 /* Back up the existing cargo type */ |
1088 /* Back up the existing cargo type */ |
1086 CargoID temp_cid = v->cargo_type; |
1089 CargoID temp_cid = v->cargo_type; |
1087 byte temp_subtype = v->cargo_subtype; |
1090 byte temp_subtype = v->cargo_subtype; |
1088 v->cargo_type = new_cid; |
1091 v->cargo_type = new_cid; |
1089 v->cargo_subtype = new_subtype; |
1092 v->cargo_subtype = new_subtype; |