train_cmd.c
changeset 1024 5e446b5b3ec5
parent 954 66c89362a778
child 1035 812f837ee03f
equal deleted inserted replaced
1023:1ae7b7a78602 1024:5e446b5b3ec5
   393 
   393 
   394 	value = EstimateTrainCost(rvi);
   394 	value = EstimateTrainCost(rvi);
   395 
   395 
   396 	if (!(flags & DC_QUERY_COST)) {
   396 	if (!(flags & DC_QUERY_COST)) {
   397 		v = AllocateVehicle();
   397 		v = AllocateVehicle();
   398 		if (v == NULL || _ptr_to_next_order >= endof(_order_array))
   398 		if (v == NULL || IsOrderPoolFull())
   399 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   399 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   400 
   400 
   401 		unit_num = GetFreeUnitNumber(VEH_Train);
   401 		unit_num = GetFreeUnitNumber(VEH_Train);
   402 		if (unit_num > _patches.max_trains)
   402 		if (unit_num > _patches.max_trains)
   403 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   403 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   415 			v->z_pos = GetSlopeZ(x,y);
   415 			v->z_pos = GetSlopeZ(x,y);
   416 			v->z_height = 6;
   416 			v->z_height = 6;
   417 			v->u.rail.track = 0x80;
   417 			v->u.rail.track = 0x80;
   418 			v->u.rail.first_engine = 0xffff;
   418 			v->u.rail.first_engine = 0xffff;
   419 			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
   419 			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
   420 //			v->subtype = 0;
       
   421 			v->spritenum = rvi->image_index;
   420 			v->spritenum = rvi->image_index;
   422 			v->cargo_type = rvi->cargo_type;
   421 			v->cargo_type = rvi->cargo_type;
   423 			v->cargo_cap = rvi->capacity;
   422 			v->cargo_cap = rvi->capacity;
   424 			v->max_speed = rvi->max_speed;
   423 			v->max_speed = rvi->max_speed;
   425 //			v->cargo_count = 0;
       
   426 			v->value = value;
   424 			v->value = value;
   427 //			v->day_counter = 0;
       
   428 //			v->current_order = 0;
       
   429 //			v->next_station = 0;
       
   430 //			v->load_unload_time_rem = 0;
       
   431 //			v->progress = 0;
       
   432 //			v->targetairport = 0;
       
   433 //			v->crash_anim_pos = 0;
       
   434 			v->last_station_visited = 0xFFFF;
   425 			v->last_station_visited = 0xFFFF;
   435 			v->dest_tile = 0;
   426 			v->dest_tile = 0;
   436 //			v->profit_last_year = 0;
       
   437 //			v->profit_this_year = 0;
       
   438 
   427 
   439 			v->engine_type = (byte)p1;
   428 			v->engine_type = (byte)p1;
   440 			e = &_engines[p1];
   429 			e = &_engines[p1];
   441 
   430 
   442 			v->reliability = e->reliability;
   431 			v->reliability = e->reliability;
   443 			v->reliability_spd_dec = e->reliability_spd_dec;
   432 			v->reliability_spd_dec = e->reliability_spd_dec;
   444 			v->max_age = e->lifelength * 366;
   433 			v->max_age = e->lifelength * 366;
   445 
   434 
   446 			v->string_id = STR_SV_TRAIN_NAME;
   435 			v->string_id = STR_SV_TRAIN_NAME;
   447 //			v->cur_speed = 0;
       
   448 //			v->subspeed = 0;
       
   449 			v->u.rail.railtype = e->railtype;
   436 			v->u.rail.railtype = e->railtype;
   450 			_new_train_id = v->index;
   437 			_new_train_id = v->index;
   451 //			v->cur_order_index = 0;
       
   452 //			v->num_orders = 0;
       
   453 
       
   454 			_ptr_to_next_order->type = OT_NOTHING;
       
   455 			_ptr_to_next_order->flags = 0;
       
   456 			v->schedule_ptr = _ptr_to_next_order++;
       
   457 //			v->next_in_chain = 0xffff;
       
   458 //			v->next = NULL;
       
   459 
   438 
   460 			v->service_interval = _patches.servint_trains;
   439 			v->service_interval = _patches.servint_trains;
   461 //			v->breakdown_ctr = 0;
       
   462 //			v->breakdowns_since_last_service = 0;
       
   463 //			v->unk4D = 0;
       
   464 			v->date_of_last_service = _date;
   440 			v->date_of_last_service = _date;
   465 			v->build_year = _cur_year;
   441 			v->build_year = _cur_year;
   466 			v->type = VEH_Train;
   442 			v->type = VEH_Train;
   467 			v->cur_image = 0xAC2;
   443 			v->cur_image = 0xAC2;
   468 
   444 
   678 
   654 
   679 		if (dst == NULL) {
   655 		if (dst == NULL) {
   680 			// move the train to an empty line. for locomotives, we set the type to 0. for wagons, 4.
   656 			// move the train to an empty line. for locomotives, we set the type to 0. for wagons, 4.
   681 			if (is_loco) {
   657 			if (is_loco) {
   682 				if (src->subtype != 0) {
   658 				if (src->subtype != 0) {
   683 					// setting the type to 0 also involves setting up the schedule_ptr field.
   659 					// setting the type to 0 also involves setting up the orders field.
   684 					src->subtype = 0;
   660 					src->subtype = 0;
   685 					assert(src->schedule_ptr == NULL);
   661 					assert(src->orders == NULL);
   686 					_ptr_to_next_order->type = OT_NOTHING;
       
   687 					_ptr_to_next_order->flags = 0;
       
   688 					src->schedule_ptr = _ptr_to_next_order++;
       
   689 					src->num_orders = 0;
   662 					src->num_orders = 0;
   690 				}
   663 				}
   691 				dst_head = src;
   664 				dst_head = src;
   692 			} else {
   665 			} else {
   693 				src->subtype = 4;
   666 				src->subtype = 4;
   694 			}
   667 			}
   695 			src->u.rail.first_engine = 0xffff;
   668 			src->u.rail.first_engine = 0xffff;
   696 		} else {
   669 		} else {
   697 			if (src->subtype == 0) {
   670 			if (src->subtype == 0) {
   698 				// the vehicle was previously a loco. need to free the schedule list and delete vehicle windows etc.
   671 				// the vehicle was previously a loco. need to free the order list and delete vehicle windows etc.
   699 				DeleteWindowById(WC_VEHICLE_VIEW, src->index);
   672 				DeleteWindowById(WC_VEHICLE_VIEW, src->index);
   700 				DeleteVehicleSchedule(src);
   673 				DeleteVehicleOrders(src);
   701 			}
   674 			}
   702 
   675 
   703 			src->subtype = 2;
   676 			src->subtype = 2;
   704 			src->unitnumber = 0; // doesn't occupy a unitnumber anymore.
   677 			src->unitnumber = 0; // doesn't occupy a unitnumber anymore.
   705 
   678 
  1642 	return reverse_best != 0;
  1615 	return reverse_best != 0;
  1643 }
  1616 }
  1644 
  1617 
  1645 static bool ProcessTrainOrder(Vehicle *v)
  1618 static bool ProcessTrainOrder(Vehicle *v)
  1646 {
  1619 {
  1647 	Order order;
  1620 	const Order *order;
  1648 	bool result;
  1621 	bool result;
  1649 
  1622 
  1650 	// These are un-interruptible
  1623 	// These are un-interruptible
  1651 	if (v->current_order.type >= OT_GOTO_DEPOT &&
  1624 	if (v->current_order.type >= OT_GOTO_DEPOT &&
  1652 			v->current_order.type <= OT_LEAVESTATION) {
  1625 			v->current_order.type <= OT_LEAVESTATION) {
  1653 		// Let a depot order in the schedule interrupt.
  1626 		// Let a depot order in the orderlist interrupt.
  1654 		if (v->current_order.type != OT_GOTO_DEPOT ||
  1627 		if (v->current_order.type != OT_GOTO_DEPOT ||
  1655 				!(v->current_order.flags & OF_UNLOAD))
  1628 				!(v->current_order.flags & OF_UNLOAD))
  1656 			return false;
  1629 			return false;
  1657 	}
  1630 	}
  1658 
  1631 
  1674 	}
  1647 	}
  1675 
  1648 
  1676 	// Get the current order
  1649 	// Get the current order
  1677 	if (v->cur_order_index >= v->num_orders)
  1650 	if (v->cur_order_index >= v->num_orders)
  1678 		v->cur_order_index = 0;
  1651 		v->cur_order_index = 0;
  1679 	order = v->schedule_ptr[v->cur_order_index];
  1652 
       
  1653 	order = GetVehicleOrder(v, v->cur_order_index);
  1680 
  1654 
  1681 	// If no order, do nothing.
  1655 	// If no order, do nothing.
  1682 	if (order.type == OT_NOTHING) {
  1656 	if (order == NULL) {
  1683 		v->current_order.type = OT_NOTHING;
  1657 		v->current_order.type = OT_NOTHING;
  1684 		v->current_order.flags = 0;
  1658 		v->current_order.flags = 0;
  1685 		v->dest_tile = 0;
  1659 		v->dest_tile = 0;
  1686 		return false;
  1660 		return false;
  1687 	}
  1661 	}
  1688 
  1662 
  1689 	// If it is unchanged, keep it.
  1663 	// If it is unchanged, keep it.
  1690 	if (order.type == v->current_order.type &&
  1664 	if (order->type    == v->current_order.type &&
  1691 			order.flags == v->current_order.flags &&
  1665 			order->flags   == v->current_order.flags &&
  1692 			order.station == v->current_order.station)
  1666 			order->station == v->current_order.station)
  1693 		return false;
  1667 		return false;
  1694 
  1668 
  1695 	// Otherwise set it, and determine the destination tile.
  1669 	// Otherwise set it, and determine the destination tile.
  1696 	v->current_order = order;
  1670 	v->current_order = *order;
  1697 
  1671 
  1698 	v->dest_tile = 0;
  1672 	v->dest_tile = 0;
  1699 
  1673 
  1700 	result = false;
  1674 	result = false;
  1701 	if (order.type == OT_GOTO_STATION) {
  1675 	switch (order->type) {
  1702 		if (order.station == v->last_station_visited)
  1676 		case OT_GOTO_STATION:
  1703 			v->last_station_visited = 0xFFFF;
  1677 			if (order->station == v->last_station_visited)
  1704 		v->dest_tile = GetStation(order.station)->xy;
  1678 				v->last_station_visited = 0xFFFF;
  1705 		result = CheckReverseTrain(v);
  1679 			v->dest_tile = GetStation(order->station)->xy;
  1706 	} else if (order.type == OT_GOTO_DEPOT) {
  1680 			result = CheckReverseTrain(v);
  1707 		v->dest_tile = _depots[order.station].xy;
  1681 			break;
  1708 		result = CheckReverseTrain(v);
  1682 
  1709 	} else if (order.type == OT_GOTO_WAYPOINT) {
  1683 		case OT_GOTO_DEPOT:
  1710 		v->dest_tile = _waypoints[order.station].xy;
  1684 			v->dest_tile = _depots[order->station].xy;
  1711 		result = CheckReverseTrain(v);
  1685 			result = CheckReverseTrain(v);
  1712 	}
  1686 			break;
  1713 
  1687 
  1714 	InvalidateVehicleOrderWidget(v);
  1688 		case OT_GOTO_WAYPOINT:
       
  1689 			v->dest_tile = _waypoints[order->station].xy;
       
  1690 			result = CheckReverseTrain(v);
       
  1691 			break;
       
  1692 	}
       
  1693 
       
  1694 	InvalidateVehicleOrder(v);
  1715 
  1695 
  1716 	return result;
  1696 	return result;
  1717 }
  1697 }
  1718 
  1698 
  1719 static void MarkTrainDirty(Vehicle *v)
  1699 static void MarkTrainDirty(Vehicle *v)
  1769 		}
  1749 		}
  1770 	}
  1750 	}
  1771 
  1751 
  1772 	v->u.rail.days_since_order_progr = 0;
  1752 	v->u.rail.days_since_order_progr = 0;
  1773 	v->cur_order_index++;
  1753 	v->cur_order_index++;
  1774 	InvalidateVehicleOrderWidget(v);
  1754 	InvalidateVehicleOrder(v);
  1775 }
  1755 }
  1776 
  1756 
  1777 static int UpdateTrainSpeed(Vehicle *v)
  1757 static int UpdateTrainSpeed(Vehicle *v)
  1778 {
  1758 {
  1779 	uint spd;
  1759 	uint spd;
  2667 
  2647 
  2668 		t = v->current_order;
  2648 		t = v->current_order;
  2669 		v->current_order.type = OT_DUMMY;
  2649 		v->current_order.type = OT_DUMMY;
  2670 		v->current_order.flags = 0;
  2650 		v->current_order.flags = 0;
  2671 
  2651 
  2672 		if (t.flags & OF_UNLOAD) { // Part of the schedule?
  2652 		if (t.flags & OF_UNLOAD) { // Part of the orderlist?
  2673 			v->u.rail.days_since_order_progr = 0;
  2653 			v->u.rail.days_since_order_progr = 0;
  2674 			v->cur_order_index++;
  2654 			v->cur_order_index++;
  2675 		} else if (t.flags & OF_FULL_LOAD) { // User initiated?
  2655 		} else if (t.flags & OF_FULL_LOAD) { // User initiated?
  2676 			v->vehstatus |= VS_STOPPED;
  2656 			v->vehstatus |= VS_STOPPED;
  2677 			if (v->owner == _local_player) {
  2657 			if (v->owner == _local_player) {
  2699 		return;
  2679 		return;
  2700 
  2680 
  2701 	if (v->vehstatus & VS_STOPPED)
  2681 	if (v->vehstatus & VS_STOPPED)
  2702 		return;
  2682 		return;
  2703 
  2683 
  2704 	if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
  2684 	if (_patches.gotodepot && VehicleHasDepotOrders(v))
  2705 		return;
  2685 		return;
  2706 
  2686 
  2707 	// Don't interfere with a depot visit scheduled by the user, or a
  2687 	// Don't interfere with a depot visit scheduled by the user, or a
  2708 	// depot visit by the order list.
  2688 	// depot visit by the order list.
  2709 	if (v->current_order.type == OT_GOTO_DEPOT &&
  2689 	if (v->current_order.type == OT_GOTO_DEPOT &&
  2832 
  2812 
  2833 void InitializeTrains()
  2813 void InitializeTrains()
  2834 {
  2814 {
  2835 	_age_cargo_skip_counter = 1;
  2815 	_age_cargo_skip_counter = 1;
  2836 }
  2816 }
  2837 
       
  2838 int ScheduleHasDepotOrders(const Order *schedule)
       
  2839 {
       
  2840 	for (; schedule->type != OT_NOTHING; schedule++)
       
  2841 		if (schedule->type == OT_GOTO_DEPOT)
       
  2842 			return true;
       
  2843 	return false;
       
  2844 }