src/ship_cmd.cpp
branchnoai
changeset 9722 ebf0ece7d8f6
parent 9718 f82a4facea8b
child 9723 eee46cb39750
equal deleted inserted replaced
9721:9a27928bcd5e 9722:ebf0ece7d8f6
   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 
   833 		int x;
   833 		int x;
   834 		int y;
   834 		int y;
   835 
   835 
   836 		const ShipVehicleInfo *svi = ShipVehInfo(p1);
   836 		const ShipVehicleInfo *svi = ShipVehInfo(p1);
   837 
   837 
       
   838 		v = new (v) Ship();
   838 		v->unitnumber = unit_num;
   839 		v->unitnumber = unit_num;
   839 
   840 
   840 		v->owner = _current_player;
   841 		v->owner = _current_player;
   841 		v->tile = tile;
   842 		v->tile = tile;
   842 		x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
   843 		x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
   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;