ship_cmd.c
changeset 555 02df8a1b7f33
parent 541 625227bb2a3d
child 578 1e66514eb621
equal deleted inserted replaced
554:a4ba0fbbf018 555:02df8a1b7f33
    93 		return;
    93 		return;
    94 
    94 
    95 	if (v->vehstatus & VS_STOPPED)
    95 	if (v->vehstatus & VS_STOPPED)
    96 		return;
    96 		return;
    97 
    97 
    98 	if ((v->next_order & (OT_MASK | OF_FULL_LOAD)) == (OT_GOTO_DEPOT | OF_FULL_LOAD))
    98 	if (v->current_order.type == OT_GOTO_DEPOT &&
       
    99 			v->current_order.flags & OF_FULL_LOAD)
    99 		return;
   100 		return;
   100 
   101 
   101 	if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
   102 	if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
   102 		return;
   103 		return;
   103 
   104 
   104 	i = FindClosestShipDepot(v);
   105 	i = FindClosestShipDepot(v);
   105 
   106 
   106 	if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) {
   107 	if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) {
   107 		if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
   108 		if (v->current_order.type == OT_GOTO_DEPOT) {
   108 			v->next_order = OT_DUMMY;
   109 			v->current_order.type = OT_DUMMY;
       
   110 			v->current_order.flags = 0;
   109 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   111 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   110 		}
   112 		}
   111 		return;
   113 		return;
   112 	}
   114 	}
   113 
   115 
   114 	v->next_order = OT_GOTO_DEPOT | OF_NON_STOP;
   116 	v->current_order.type = OT_GOTO_DEPOT;
   115 	v->next_order_param = (byte)i;
   117 	v->current_order.flags = OF_NON_STOP;
       
   118 	v->current_order.station = (byte)i;
   116 	v->dest_tile = (&_depots[i])->xy;
   119 	v->dest_tile = (&_depots[i])->xy;
   117 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   120 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   118 }
   121 }
   119 
   122 
   120 void OnNewDay_Ship(Vehicle *v)
   123 void OnNewDay_Ship(Vehicle *v)
   197 	TILE_XY(0,0),
   200 	TILE_XY(0,0),
   198 };
   201 };
   199 
   202 
   200 static void ProcessShipOrder(Vehicle *v)
   203 static void ProcessShipOrder(Vehicle *v)
   201 {
   204 {
   202 	uint order;
   205 	Order order;
   203 	Station *st;
   206 	Station *st;
   204 
   207 
   205 	if ((v->next_order & OT_MASK) >= OT_GOTO_DEPOT && (v->next_order & OT_MASK) <= OT_LEAVESTATION) {
   208 	if (v->current_order.type >= OT_GOTO_DEPOT &&
   206 		if ((v->next_order & (OT_MASK|OF_UNLOAD)) != (OT_GOTO_DEPOT|OF_UNLOAD))
   209 			v->current_order.type <= OT_LEAVESTATION) {
       
   210 		if (v->current_order.type != OT_GOTO_DEPOT ||
       
   211 				!(v->current_order.flags & OF_UNLOAD))
   207 			return;
   212 			return;
   208 	}
   213 	}
   209 
   214 
   210 	if ((v->next_order & (OT_MASK|OF_UNLOAD|OF_FULL_LOAD)) == (OT_GOTO_DEPOT|OF_UNLOAD|OF_FULL_LOAD) &&
   215 	if (v->current_order.type == OT_GOTO_DEPOT &&
       
   216 			(v->current_order.flags & (OF_UNLOAD | OF_FULL_LOAD)) == (OF_UNLOAD | OF_FULL_LOAD) &&
   211 			SERVICE_INTERVAL) {
   217 			SERVICE_INTERVAL) {
   212 		v->cur_order_index++;
   218 		v->cur_order_index++;
   213 	}
   219 	}
   214 
   220 
   215 
   221 
   216 	if (v->cur_order_index >= v->num_orders)
   222 	if (v->cur_order_index >= v->num_orders)
   217 		v->cur_order_index = 0;
   223 		v->cur_order_index = 0;
   218 
   224 
   219 	order = v->schedule_ptr[v->cur_order_index];
   225 	order = v->schedule_ptr[v->cur_order_index];
   220 
   226 
   221 	if (order == 0) {
   227 	if (order.type == OT_NOTHING) {
   222 		v->next_order = OT_NOTHING;
   228 		v->current_order.type = OT_NOTHING;
       
   229 		v->current_order.flags = 0;
   223 		v->dest_tile = 0;
   230 		v->dest_tile = 0;
   224 		return;
   231 		return;
   225 	}
   232 	}
   226 
   233 
   227 	if (order == (uint)((v->next_order | (v->next_order_param<<8))))
   234 	if (order.type == v->current_order.type &&
   228 		return;
   235 			order.flags == v->current_order.flags &&
   229 
   236 			order.station == v->current_order.station)
   230 	v->next_order = (byte)order;
   237 		return;
   231 	v->next_order_param = (byte)(order >> 8);
   238 
   232 
   239 	v->current_order = order;
   233 	if ((order & OT_MASK) == OT_GOTO_STATION) {
   240 
   234 		if ( (byte)(order >> 8) == v->last_station_visited)
   241 	if (order.type == OT_GOTO_STATION) {
       
   242 		if (order.station == v->last_station_visited)
   235 			v->last_station_visited = 0xFF;
   243 			v->last_station_visited = 0xFF;
   236 
   244 
   237 		st = DEREF_STATION(order >> 8);
   245 		st = DEREF_STATION(order.station);
   238 		if (st->dock_tile != 0) {
   246 		if (st->dock_tile != 0) {
   239 			v->dest_tile = TILE_ADD(st->dock_tile, _dock_offs[_map5[st->dock_tile]-0x4B]);
   247 			v->dest_tile = TILE_ADD(st->dock_tile, _dock_offs[_map5[st->dock_tile]-0x4B]);
   240 		}
   248 		}
   241 	} else if ((order & OT_MASK) == OT_GOTO_DEPOT) {
   249 	} else if (order.type == OT_GOTO_DEPOT) {
   242 		v->dest_tile = _depots[order >> 8].xy;
   250 		v->dest_tile = _depots[order.station].xy;
   243 	} else {
   251 	} else {
   244 		v->dest_tile = 0;
   252 		v->dest_tile = 0;
   245 	}
   253 	}
   246 	InvalidateVehicleOrderWidget(v);
   254 	InvalidateVehicleOrderWidget(v);
   247 }
   255 }
   248 
   256 
   249 static void HandleShipLoading(Vehicle *v)
   257 static void HandleShipLoading(Vehicle *v)
   250 {
   258 {
   251 	if (v->next_order == OT_NOTHING)
   259 	if (v->current_order.type == OT_NOTHING)
   252 		return;
   260 		return;
   253 
   261 
   254 	if (v->next_order != OT_DUMMY) {
   262 	if (v->current_order.type != OT_DUMMY) {
   255 		if ((v->next_order&OT_MASK) != OT_LOADING)
   263 		if (v->current_order.type != OT_LOADING)
   256 			return;
   264 			return;
   257 
   265 
   258 		if (--v->load_unload_time_rem)
   266 		if (--v->load_unload_time_rem)
   259 			return;
   267 			return;
   260 
   268 
   261 		if (v->next_order&OF_FULL_LOAD && CanFillVehicle(v)) {
   269 		if (v->current_order.flags & OF_FULL_LOAD && CanFillVehicle(v)) {
   262 			SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
   270 			SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
   263 			if (LoadUnloadVehicle(v)) {
   271 			if (LoadUnloadVehicle(v)) {
   264 				InvalidateWindow(WC_SHIPS_LIST, v->owner);
   272 				InvalidateWindow(WC_SHIPS_LIST, v->owner);
   265 				MarkShipDirty(v);
   273 				MarkShipDirty(v);
   266 			}
   274 			}
   267 			return;
   275 			return;
   268 		}
   276 		}
   269 		PlayShipSound(v);
   277 		PlayShipSound(v);
   270 
   278 
   271 		{
   279 		{
   272 			byte b = v->next_order;
   280 			Order b = v->current_order;
   273 			v->next_order = OT_LEAVESTATION;
   281 			v->current_order.type = OT_LEAVESTATION;
   274 			if (!(b & OF_NON_STOP))
   282 			v->current_order.flags = 0;
       
   283 			if (!(b.flags & OF_NON_STOP))
   275 				return;
   284 				return;
   276 		}
   285 		}
   277 	}
   286 	}
   278 
   287 
   279 	v->cur_order_index++;
   288 	v->cur_order_index++;
   378 
   387 
   379 static int32 EstimateShipCost(uint16 engine_type);
   388 static int32 EstimateShipCost(uint16 engine_type);
   380 
   389 
   381 static void ShipEnterDepot(Vehicle *v)
   390 static void ShipEnterDepot(Vehicle *v)
   382 {
   391 {
   383 	byte t;
       
   384 
       
   385 	v->u.ship.state = 0x80;
   392 	v->u.ship.state = 0x80;
   386 	v->vehstatus |= VS_HIDDEN;
   393 	v->vehstatus |= VS_HIDDEN;
   387 	v->cur_speed = 0;
   394 	v->cur_speed = 0;
   388 	RecalcShipStuff(v);
   395 	RecalcShipStuff(v);
   389 
   396 
   394 
   401 
   395 	MaybeRenewVehicle(v, EstimateShipCost(v->engine_type));
   402 	MaybeRenewVehicle(v, EstimateShipCost(v->engine_type));
   396 
   403 
   397 	TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
   404 	TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
   398 
   405 
   399 	if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
   406 	if (v->current_order.type == OT_GOTO_DEPOT) {
       
   407 		Order t;
       
   408 
   400 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
   409 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
   401 
   410 
   402 		t = v->next_order;
   411 		t = v->current_order;
   403 		v->next_order = OT_DUMMY;
   412 		v->current_order.type = OT_DUMMY;
   404 
   413 		v->current_order.flags = 0;
   405 		if (t&OF_UNLOAD) { v->cur_order_index++; }
   414 
   406 
   415 		if (t.flags & OF_UNLOAD) {
   407 		else if (t & 0x40) {
   416 			v->cur_order_index++;
       
   417 		} else if (t.flags & OF_FULL_LOAD) {
   408 			v->vehstatus |= VS_STOPPED;
   418 			v->vehstatus |= VS_STOPPED;
   409 			if (v->owner == _local_player) {
   419 			if (v->owner == _local_player) {
   410 				SetDParam(0, v->unitnumber);
   420 				SetDParam(0, v->unitnumber);
   411 				AddNewsItem(
   421 				AddNewsItem(
   412 					STR_981C_SHIP_IS_WAITING_IN_DEPOT,
   422 					STR_981C_SHIP_IS_WAITING_IN_DEPOT,
   634 		return;
   644 		return;
   635 
   645 
   636 	ProcessShipOrder(v);
   646 	ProcessShipOrder(v);
   637 	HandleShipLoading(v);
   647 	HandleShipLoading(v);
   638 
   648 
   639 	if ((v->next_order & OT_MASK) == OT_LOADING)
   649 	if (v->current_order.type == OT_LOADING)
   640 		return;
   650 		return;
   641 
   651 
   642 	CheckShipLeaveDepot(v);
   652 	CheckShipLeaveDepot(v);
   643 
   653 
   644 	if (!ShipAccelerate(v))
   654 	if (!ShipAccelerate(v))
   655 			/* isnot inside depot */
   665 			/* isnot inside depot */
   656 			r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
   666 			r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
   657 			if (r & 0x8) goto reverse_direction;
   667 			if (r & 0x8) goto reverse_direction;
   658 
   668 
   659 			if (v->dest_tile != 0 && v->dest_tile == gp.new_tile) {
   669 			if (v->dest_tile != 0 && v->dest_tile == gp.new_tile) {
   660 				if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
   670 				if (v->current_order.type == OT_GOTO_DEPOT) {
   661 					if ((gp.x&0xF)==8 && (gp.y&0xF)==8) {
   671 					if ((gp.x&0xF)==8 && (gp.y&0xF)==8) {
   662 						ShipEnterDepot(v);
   672 						ShipEnterDepot(v);
   663 						return;
   673 						return;
   664 					}
   674 					}
   665 				} else if ((v->next_order & OT_MASK) == OT_GOTO_STATION) {
   675 				} else if (v->current_order.type == OT_GOTO_STATION) {
   666 					Station *st;
   676 					Station *st;
   667 
   677 
   668 					v->last_station_visited = v->next_order_param;
   678 					v->last_station_visited = v->current_order.station;
   669 
   679 
   670 					/* Process station in the schedule. Don't do that for buoys (HVOT_BUOY) */
   680 					/* Process station in the schedule. Don't do that for buoys (HVOT_BUOY) */
   671 					st = DEREF_STATION(v->next_order_param);
   681 					st = DEREF_STATION(v->current_order.station);
   672 					if (!(st->had_vehicle_of_type & HVOT_BUOY) 
   682 					if (!(st->had_vehicle_of_type & HVOT_BUOY) 
   673 							&& (st->facilities & FACIL_DOCK)) { /* ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations */
   683 							&& (st->facilities & FACIL_DOCK)) { /* ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations */
   674 						v->next_order = (v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) | OF_NON_STOP | OT_LOADING;
   684 						v->current_order.type = OT_LOADING;
       
   685 						v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD;
       
   686 						v->current_order.flags |= OF_NON_STOP;
   675 						ShipArrivesAt(v, st);
   687 						ShipArrivesAt(v, st);
   676 
   688 
   677 						SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
   689 						SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
   678 						if (LoadUnloadVehicle(v)) {
   690 						if (LoadUnloadVehicle(v)) {
   679 							InvalidateWindow(WC_SHIPS_LIST, v->owner);
   691 							InvalidateWindow(WC_SHIPS_LIST, v->owner);
   680 							MarkShipDirty(v);
   692 							MarkShipDirty(v);
   681 						}
   693 						}
   682 						InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   694 						InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   683 					} else { /* leave buoys right aways */
   695 					} else { /* leave buoys right aways */
   684 						v->next_order = OT_LEAVESTATION;
   696 						v->current_order.type = OT_LEAVESTATION;
       
   697 						v->current_order.flags = 0;
   685 						v->cur_order_index++;
   698 						v->cur_order_index++;
   686 						InvalidateVehicleOrderWidget(v);
   699 						InvalidateVehicleOrderWidget(v);
   687 					}
   700 					}
   688 					goto else_end;
   701 					goto else_end;
   689 				}
   702 				}
   690 			}
   703 			}
   691 
   704 
   692 			if (v->next_order == OT_LEAVESTATION) {
   705 			if (v->current_order.type == OT_LEAVESTATION) {
   693 				v->next_order = OT_NOTHING;
   706 				v->current_order.type = OT_NOTHING;
       
   707 				v->current_order.flags = 0;
   694 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   708 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   695 			}
   709 			}
   696 		}
   710 		}
   697 	} else {
   711 	} else {
   698 		// new tile
   712 		// new tile
   841 		v->max_age = e->lifelength * 366;
   855 		v->max_age = e->lifelength * 366;
   842 		_new_ship_id = v->index;
   856 		_new_ship_id = v->index;
   843 
   857 
   844 		v->string_id = STR_SV_SHIP_NAME;
   858 		v->string_id = STR_SV_SHIP_NAME;
   845 		v->u.ship.state = 0x80;
   859 		v->u.ship.state = 0x80;
   846 		*(v->schedule_ptr = _ptr_to_next_order++) = 0;
   860 		_ptr_to_next_order->type = OT_NOTHING;
       
   861 		_ptr_to_next_order->flags = 0;
       
   862 		v->schedule_ptr = _ptr_to_next_order++;
   847 
   863 
   848 		v->service_interval = _patches.servint_ships;
   864 		v->service_interval = _patches.servint_ships;
   849 		v->date_of_last_service = _date;
   865 		v->date_of_last_service = _date;
   850 		v->build_year = _cur_year;
   866 		v->build_year = _cur_year;
   851 		v->cur_image = 0x0E5E;
   867 		v->cur_image = 0x0E5E;
   915 	v = &_vehicles[p1];
   931 	v = &_vehicles[p1];
   916 
   932 
   917 	if (!CheckOwnership(v->owner))
   933 	if (!CheckOwnership(v->owner))
   918 		return CMD_ERROR;
   934 		return CMD_ERROR;
   919 
   935 
   920 	if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
   936 	if (v->current_order.type == OT_GOTO_DEPOT) {
   921 		if (flags & DC_EXEC) {
   937 		if (flags & DC_EXEC) {
   922 			if (v->next_order&OF_UNLOAD) {v->cur_order_index++;}
   938 			if (v->current_order.flags & OF_UNLOAD) v->cur_order_index++;
   923 			v->next_order = OT_DUMMY;
   939 			v->current_order.type = OT_DUMMY;
       
   940 			v->current_order.flags = 0;
   924 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   941 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   925 		}
   942 		}
   926 	} else {
   943 	} else {
   927 		depot = FindClosestShipDepot(v);
   944 		depot = FindClosestShipDepot(v);
   928 		if (depot < 0)
   945 		if (depot < 0)
   929 			return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT);
   946 			return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT);
   930 
   947 
   931 		if (flags & DC_EXEC) {
   948 		if (flags & DC_EXEC) {
   932 			v->dest_tile = _depots[depot].xy;
   949 			v->dest_tile = _depots[depot].xy;
   933 			v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT;
   950 			v->current_order.type = OT_GOTO_DEPOT;
   934 			v->next_order_param = depot;
   951 			v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD;
       
   952 			v->current_order.station = depot;
   935 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   953 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
   936 		}
   954 		}
   937 	}
   955 	}
   938 
   956 
   939 	return 0;
   957 	return 0;