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) |
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) { |