|
@@ -197,25 +197,25 @@ uint Vehicle::Crash(bool flooded)
|
|
|
{
|
|
|
assert((this->vehstatus & VS_CRASHED) == 0);
|
|
|
assert(this->Previous() == NULL); // IsPrimaryVehicle fails for free-wagon-chains
|
|
|
|
|
|
uint pass = 0;
|
|
|
/* Stop the vehicle. */
|
|
|
if (this->IsPrimaryVehicle()) this->vehstatus |= VS_STOPPED;
|
|
|
/* crash all wagons, and count passengers */
|
|
|
for (Vehicle *v = this; v != NULL; v = v->Next()) {
|
|
|
/* We do not transfer reserver cargo back, so TotalCount() instead of StoredCount() */
|
|
|
if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) pass += v->cargo.TotalCount();
|
|
|
v->vehstatus |= VS_CRASHED;
|
|
|
MarkSingleVehicleDirty(v);
|
|
|
v->MarkAllViewportsDirty();
|
|
|
}
|
|
|
|
|
|
/* Dirty some windows */
|
|
|
InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type), 0);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
|
|
|
SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
|
|
|
SetWindowDirty(WC_VEHICLE_DEPOT, this->tile);
|
|
|
|
|
|
delete this->cargo_payment;
|
|
|
this->cargo_payment = NULL;
|
|
|
|
|
|
return RandomRange(pass + 1); // Randomise deceased passengers.
|
|
@@ -800,25 +800,25 @@ void Vehicle::PreDestructor()
|
|
|
ReleaseDisastersTargetingVehicle(this->index);
|
|
|
}
|
|
|
|
|
|
Vehicle::~Vehicle()
|
|
|
{
|
|
|
if (CleaningPool()) {
|
|
|
this->cargo.OnCleanPool();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* sometimes, eg. for disaster vehicles, when company bankrupts, when removing crashed/flooded vehicles,
|
|
|
* it may happen that vehicle chain is deleted when visible */
|
|
|
if (!(this->vehstatus & VS_HIDDEN)) MarkSingleVehicleDirty(this);
|
|
|
if (!(this->vehstatus & VS_HIDDEN)) this->MarkAllViewportsDirty();
|
|
|
|
|
|
Vehicle *v = this->Next();
|
|
|
this->SetNext(NULL);
|
|
|
|
|
|
delete v;
|
|
|
|
|
|
UpdateVehicleTileHash(this, true);
|
|
|
UpdateVehicleViewportHash(this, INVALID_COORD, 0);
|
|
|
DeleteVehicleNews(this->index, INVALID_STRING_ID);
|
|
|
DeleteNewGRFInspectWindow(GetGrfSpecFeature(this->type), this->index);
|
|
|
}
|
|
|
|
|
@@ -1455,85 +1455,81 @@ void VehicleEnterDepot(Vehicle *v)
|
|
|
AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, v->index);
|
|
|
}
|
|
|
AI::NewEvent(v->owner, new ScriptEventVehicleWaitingInDepot(v->index));
|
|
|
}
|
|
|
v->current_order.MakeDummy();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* Update the position of the vehicle. This will update the hash that tells
|
|
|
* which vehicles are on a tile.
|
|
|
* @param v The vehicle to update.
|
|
|
*/
|
|
|
void VehicleUpdatePosition(Vehicle *v)
|
|
|
void Vehicle::UpdatePosition()
|
|
|
{
|
|
|
UpdateVehicleTileHash(v, false);
|
|
|
UpdateVehicleTileHash(this, false);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Update the vehicle on the viewport, updating the right hash and setting the
|
|
|
* new coordinates.
|
|
|
* @param v The vehicle to update.
|
|
|
* @param dirty Mark the (new and old) coordinates of the vehicle as dirty.
|
|
|
*/
|
|
|
void VehicleUpdateViewport(Vehicle *v, bool dirty)
|
|
|
void Vehicle::UpdateViewport(bool dirty)
|
|
|
{
|
|
|
int img = v->cur_image;
|
|
|
Point pt = RemapCoords(v->x_pos + v->x_offs, v->y_pos + v->y_offs, v->z_pos);
|
|
|
int img = this->cur_image;
|
|
|
Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
|
|
|
const Sprite *spr = GetSprite(img, ST_NORMAL);
|
|
|
|
|
|
pt.x += spr->x_offs;
|
|
|
pt.y += spr->y_offs;
|
|
|
|
|
|
UpdateVehicleViewportHash(v, pt.x, pt.y);
|
|
|
|
|
|
Rect old_coord = v->coord;
|
|
|
v->coord.left = pt.x;
|
|
|
v->coord.top = pt.y;
|
|
|
v->coord.right = pt.x + spr->width + 2 * ZOOM_LVL_BASE;
|
|
|
v->coord.bottom = pt.y + spr->height + 2 * ZOOM_LVL_BASE;
|
|
|
UpdateVehicleViewportHash(this, pt.x, pt.y);
|
|
|
|
|
|
Rect old_coord = this->coord;
|
|
|
this->coord.left = pt.x;
|
|
|
this->coord.top = pt.y;
|
|
|
this->coord.right = pt.x + spr->width + 2 * ZOOM_LVL_BASE;
|
|
|
this->coord.bottom = pt.y + spr->height + 2 * ZOOM_LVL_BASE;
|
|
|
|
|
|
if (dirty) {
|
|
|
if (old_coord.left == INVALID_COORD) {
|
|
|
MarkSingleVehicleDirty(v);
|
|
|
this->MarkAllViewportsDirty();
|
|
|
} else {
|
|
|
MarkAllViewportsDirty(
|
|
|
min(old_coord.left, v->coord.left),
|
|
|
min(old_coord.top, v->coord.top),
|
|
|
max(old_coord.right, v->coord.right) + 1 * ZOOM_LVL_BASE,
|
|
|
max(old_coord.bottom, v->coord.bottom) + 1 * ZOOM_LVL_BASE
|
|
|
::MarkAllViewportsDirty(
|
|
|
min(old_coord.left, this->coord.left),
|
|
|
min(old_coord.top, this->coord.top),
|
|
|
max(old_coord.right, this->coord.right) + 1 * ZOOM_LVL_BASE,
|
|
|
max(old_coord.bottom, this->coord.bottom) + 1 * ZOOM_LVL_BASE
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Update the position of the vehicle, and update the viewport.
|
|
|
* @param v The vehicle to update.
|
|
|
*/
|
|
|
void VehicleUpdatePositionAndViewport(Vehicle *v)
|
|
|
void Vehicle::UpdatePositionAndViewport()
|
|
|
{
|
|
|
VehicleUpdatePosition(v);
|
|
|
VehicleUpdateViewport(v, true);
|
|
|
this->UpdatePosition();
|
|
|
this->UpdateViewport(true);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Marks viewports dirty where the vehicle's image is.
|
|
|
* @param v vehicle to mark dirty
|
|
|
*/
|
|
|
void MarkSingleVehicleDirty(const Vehicle *v)
|
|
|
void Vehicle::MarkAllViewportsDirty() const
|
|
|
{
|
|
|
MarkAllViewportsDirty(v->coord.left, v->coord.top, v->coord.right + 1 * ZOOM_LVL_BASE, v->coord.bottom + 1 * ZOOM_LVL_BASE);
|
|
|
::MarkAllViewportsDirty(this->coord.left, this->coord.top, this->coord.right + 1 * ZOOM_LVL_BASE, this->coord.bottom + 1 * ZOOM_LVL_BASE);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get position information of a vehicle when moving one pixel in the direction it is facing
|
|
|
* @param v Vehicle to move
|
|
|
* @return Position information after the move
|
|
|
*/
|
|
|
GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v)
|
|
|
{
|
|
|
static const int8 _delta_coord[16] = {
|
|
|
-1,-1,-1, 0, 1, 1, 1, 0, /* x */
|
|
|
-1, 0, 1, 1, 1, 0,-1,-1, /* y */
|