mirror of https://github.com/OpenTTD/OpenTTD.git
Feature: Hotkey to honk a vehicle's horn (#10110)
This commit is contained in:
parent
27e1d057c5
commit
fd4f148c62
|
@ -181,11 +181,12 @@ SoundID GetNewGRFSoundID(const GRFFile *file, SoundID sound_id)
|
||||||
* Checks whether a NewGRF wants to play a different vehicle sound effect.
|
* Checks whether a NewGRF wants to play a different vehicle sound effect.
|
||||||
* @param v Vehicle to play sound effect for.
|
* @param v Vehicle to play sound effect for.
|
||||||
* @param event Trigger for the sound effect.
|
* @param event Trigger for the sound effect.
|
||||||
|
* @param force Should we play the sound effect even if vehicle sound effects are muted?
|
||||||
* @return false if the default sound effect shall be played instead.
|
* @return false if the default sound effect shall be played instead.
|
||||||
*/
|
*/
|
||||||
bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event)
|
bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event, bool force)
|
||||||
{
|
{
|
||||||
if (!_settings_client.sound.vehicle) return true;
|
if (!_settings_client.sound.vehicle && !force) return true;
|
||||||
|
|
||||||
const GRFFile *file = v->GetGRF();
|
const GRFFile *file = v->GetGRF();
|
||||||
uint16 callback;
|
uint16 callback;
|
||||||
|
|
|
@ -34,7 +34,7 @@ bool LoadNewGRFSound(SoundEntry *sound);
|
||||||
SoundID GetNewGRFSoundID(const struct GRFFile *file, SoundID sound_id);
|
SoundID GetNewGRFSoundID(const struct GRFFile *file, SoundID sound_id);
|
||||||
SoundEntry *GetSound(SoundID sound_id);
|
SoundEntry *GetSound(SoundID sound_id);
|
||||||
uint GetNumSounds();
|
uint GetNumSounds();
|
||||||
bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event);
|
bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event, bool force = false);
|
||||||
void PlayTileSound(const struct GRFFile *file, SoundID sound_id, TileIndex tile);
|
void PlayTileSound(const struct GRFFile *file, SoundID sound_id, TileIndex tile);
|
||||||
|
|
||||||
#endif /* NEWGRF_SOUND_H */
|
#endif /* NEWGRF_SOUND_H */
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> {
|
||||||
void MarkDirty();
|
void MarkDirty();
|
||||||
void UpdateDeltaXY();
|
void UpdateDeltaXY();
|
||||||
ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_SHIP_REVENUE : EXPENSES_SHIP_RUN; }
|
ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_SHIP_REVENUE : EXPENSES_SHIP_RUN; }
|
||||||
void PlayLeaveStationSound() const;
|
void PlayLeaveStationSound(bool force = false) const;
|
||||||
bool IsPrimaryVehicle() const { return true; }
|
bool IsPrimaryVehicle() const { return true; }
|
||||||
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const;
|
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const;
|
||||||
int GetDisplaySpeed() const { return this->cur_speed / 2; }
|
int GetDisplaySpeed() const { return this->cur_speed / 2; }
|
||||||
|
|
|
@ -272,16 +272,10 @@ void Ship::MarkDirty()
|
||||||
this->UpdateCache();
|
this->UpdateCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PlayShipSound(const Vehicle *v)
|
void Ship::PlayLeaveStationSound(bool force) const
|
||||||
{
|
{
|
||||||
if (!PlayVehicleSound(v, VSE_START)) {
|
if (PlayVehicleSound(this, VSE_START, force)) return;
|
||||||
SndPlayVehicleFx(ShipVehInfo(v->engine_type)->sfx, v);
|
SndPlayVehicleFx(ShipVehInfo(this->engine_type)->sfx, this);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Ship::PlayLeaveStationSound() const
|
|
||||||
{
|
|
||||||
PlayShipSound(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TileIndex Ship::GetOrderStationLocation(StationID station)
|
TileIndex Ship::GetOrderStationLocation(StationID station)
|
||||||
|
@ -398,7 +392,7 @@ static bool CheckShipLeaveDepot(Ship *v)
|
||||||
v->UpdateViewport(true, true);
|
v->UpdateViewport(true, true);
|
||||||
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
|
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
|
||||||
|
|
||||||
PlayShipSound(v);
|
v->PlayLeaveStationSound();
|
||||||
VehicleServiceInDepot(v);
|
VehicleServiceInDepot(v);
|
||||||
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
|
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
|
||||||
SetWindowClassesDirty(WC_SHIPS_LIST);
|
SetWindowClassesDirty(WC_SHIPS_LIST);
|
||||||
|
|
|
@ -235,6 +235,7 @@ void SndCopyToPool()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decide 'where' (between left and right speaker) to play the sound effect.
|
* Decide 'where' (between left and right speaker) to play the sound effect.
|
||||||
|
* Note: Callers must determine if sound effects are enabled. This plays a sound regardless of the setting.
|
||||||
* @param sound Sound effect to play
|
* @param sound Sound effect to play
|
||||||
* @param left Left edge of virtual coordinates where the sound is produced
|
* @param left Left edge of virtual coordinates where the sound is produced
|
||||||
* @param right Right edge of virtual coordinates where the sound is produced
|
* @param right Right edge of virtual coordinates where the sound is produced
|
||||||
|
@ -243,8 +244,6 @@ void SndCopyToPool()
|
||||||
*/
|
*/
|
||||||
static void SndPlayScreenCoordFx(SoundID sound, int left, int right, int top, int bottom)
|
static void SndPlayScreenCoordFx(SoundID sound, int left, int right, int top, int bottom)
|
||||||
{
|
{
|
||||||
if (_settings_client.music.effect_vol == 0) return;
|
|
||||||
|
|
||||||
/* Iterate from back, so that main viewport is checked first */
|
/* Iterate from back, so that main viewport is checked first */
|
||||||
for (const Window *w : Window::IterateFromBack()) {
|
for (const Window *w : Window::IterateFromBack()) {
|
||||||
const Viewport *vp = w->viewport;
|
const Viewport *vp = w->viewport;
|
||||||
|
|
|
@ -110,7 +110,7 @@ struct Train FINAL : public GroundVehicle<Train, VEH_TRAIN> {
|
||||||
void MarkDirty() override;
|
void MarkDirty() override;
|
||||||
void UpdateDeltaXY() override;
|
void UpdateDeltaXY() override;
|
||||||
ExpensesType GetExpenseType(bool income) const override { return income ? EXPENSES_TRAIN_REVENUE : EXPENSES_TRAIN_RUN; }
|
ExpensesType GetExpenseType(bool income) const override { return income ? EXPENSES_TRAIN_REVENUE : EXPENSES_TRAIN_RUN; }
|
||||||
void PlayLeaveStationSound() const override;
|
void PlayLeaveStationSound(bool force = false) const override;
|
||||||
bool IsPrimaryVehicle() const override { return this->IsFrontEngine(); }
|
bool IsPrimaryVehicle() const override { return this->IsFrontEngine(); }
|
||||||
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override;
|
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override;
|
||||||
int GetDisplaySpeed() const override { return this->gcache.last_speed; }
|
int GetDisplaySpeed() const override { return this->gcache.last_speed; }
|
||||||
|
|
|
@ -2100,7 +2100,7 @@ bool Train::FindClosestDepot(TileIndex *location, DestinationID *destination, bo
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Play a sound for a train leaving the station. */
|
/** Play a sound for a train leaving the station. */
|
||||||
void Train::PlayLeaveStationSound() const
|
void Train::PlayLeaveStationSound(bool force) const
|
||||||
{
|
{
|
||||||
static const SoundFx sfx[] = {
|
static const SoundFx sfx[] = {
|
||||||
SND_04_DEPARTURE_STEAM,
|
SND_04_DEPARTURE_STEAM,
|
||||||
|
@ -2110,10 +2110,9 @@ void Train::PlayLeaveStationSound() const
|
||||||
SND_41_DEPARTURE_MAGLEV
|
SND_41_DEPARTURE_MAGLEV
|
||||||
};
|
};
|
||||||
|
|
||||||
if (PlayVehicleSound(this, VSE_START)) return;
|
if (PlayVehicleSound(this, VSE_START, force)) return;
|
||||||
|
|
||||||
EngineID engtype = this->engine_type;
|
SndPlayVehicleFx(sfx[RailVehInfo(this->engine_type)->engclass], this);
|
||||||
SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -450,8 +450,9 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Play the sound associated with leaving the station
|
* Play the sound associated with leaving the station
|
||||||
|
* @param force Should we play the sound even if sound effects are muted? (horn hotkey)
|
||||||
*/
|
*/
|
||||||
virtual void PlayLeaveStationSound() const {}
|
virtual void PlayLeaveStationSound(bool force = false) const {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this is the primary vehicle in the chain.
|
* Whether this is the primary vehicle in the chain.
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "order_cmd.h"
|
#include "order_cmd.h"
|
||||||
#include "roadveh_cmd.h"
|
#include "roadveh_cmd.h"
|
||||||
#include "train_cmd.h"
|
#include "train_cmd.h"
|
||||||
|
#include "hotkeys.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
@ -2686,26 +2687,6 @@ static const NWidgetPart _nested_vehicle_view_widgets[] = {
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Vehicle view window descriptor for all vehicles but trains. */
|
|
||||||
static WindowDesc _vehicle_view_desc(
|
|
||||||
WDP_AUTO, "view_vehicle", 250, 116,
|
|
||||||
WC_VEHICLE_VIEW, WC_NONE,
|
|
||||||
0,
|
|
||||||
_nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets)
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vehicle view window descriptor for trains. Only minimum_height and
|
|
||||||
* default_height are different for train view.
|
|
||||||
*/
|
|
||||||
static WindowDesc _train_view_desc(
|
|
||||||
WDP_AUTO, "view_vehicle_train", 250, 134,
|
|
||||||
WC_VEHICLE_VIEW, WC_NONE,
|
|
||||||
0,
|
|
||||||
_nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/* Just to make sure, nobody has changed the vehicle type constants, as we are
|
/* Just to make sure, nobody has changed the vehicle type constants, as we are
|
||||||
using them for array indexing in a number of places here. */
|
using them for array indexing in a number of places here. */
|
||||||
static_assert(VEH_TRAIN == 0);
|
static_assert(VEH_TRAIN == 0);
|
||||||
|
@ -3151,6 +3132,20 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EventState OnHotkey(int hotkey) override
|
||||||
|
{
|
||||||
|
/* If the hotkey is not for any widget in the UI (i.e. for honking) */
|
||||||
|
if (hotkey == WID_VV_HONK_HORN) {
|
||||||
|
const Window* mainwindow = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||||
|
const Vehicle* v = Vehicle::Get(window_number);
|
||||||
|
/*Only play the sound if we're following this vehicle */
|
||||||
|
if (mainwindow->viewport->follow_vehicle == v->index) {
|
||||||
|
v->PlayLeaveStationSound(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Window::OnHotkey(hotkey);
|
||||||
|
}
|
||||||
|
|
||||||
void OnQueryTextFinished(char *str) override
|
void OnQueryTextFinished(char *str) override
|
||||||
{
|
{
|
||||||
if (str == nullptr) return;
|
if (str == nullptr) return;
|
||||||
|
@ -3225,8 +3220,36 @@ public:
|
||||||
{
|
{
|
||||||
::ShowNewGRFInspectWindow(GetGrfSpecFeature(Vehicle::Get(this->window_number)->type), this->window_number);
|
::ShowNewGRFInspectWindow(GetGrfSpecFeature(Vehicle::Get(this->window_number)->type), this->window_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HotkeyList hotkeys;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Hotkey vehicleview_hotkeys[] = {
|
||||||
|
Hotkey('H', "honk", WID_VV_HONK_HORN),
|
||||||
|
HOTKEY_LIST_END
|
||||||
|
};
|
||||||
|
HotkeyList VehicleViewWindow::hotkeys("vehicleview", vehicleview_hotkeys);
|
||||||
|
|
||||||
|
/** Vehicle view window descriptor for all vehicles but trains. */
|
||||||
|
static WindowDesc _vehicle_view_desc(
|
||||||
|
WDP_AUTO, "view_vehicle", 250, 116,
|
||||||
|
WC_VEHICLE_VIEW, WC_NONE,
|
||||||
|
0,
|
||||||
|
_nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets),
|
||||||
|
&VehicleViewWindow::hotkeys
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vehicle view window descriptor for trains. Only minimum_height and
|
||||||
|
* default_height are different for train view.
|
||||||
|
*/
|
||||||
|
static WindowDesc _train_view_desc(
|
||||||
|
WDP_AUTO, "view_vehicle_train", 250, 134,
|
||||||
|
WC_VEHICLE_VIEW, WC_NONE,
|
||||||
|
0,
|
||||||
|
_nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets),
|
||||||
|
&VehicleViewWindow::hotkeys
|
||||||
|
);
|
||||||
|
|
||||||
/** Shows the vehicle view window of the given vehicle. */
|
/** Shows the vehicle view window of the given vehicle. */
|
||||||
void ShowVehicleViewWindow(const Vehicle *v)
|
void ShowVehicleViewWindow(const Vehicle *v)
|
||||||
|
|
|
@ -27,6 +27,7 @@ enum VehicleViewWidgets {
|
||||||
WID_VV_SELECT_REFIT_TURN, ///< Selection widget between 'refit' and 'turn around' buttons.
|
WID_VV_SELECT_REFIT_TURN, ///< Selection widget between 'refit' and 'turn around' buttons.
|
||||||
WID_VV_TURN_AROUND, ///< Turn this vehicle around.
|
WID_VV_TURN_AROUND, ///< Turn this vehicle around.
|
||||||
WID_VV_FORCE_PROCEED, ///< Force this vehicle to pass a signal at danger.
|
WID_VV_FORCE_PROCEED, ///< Force this vehicle to pass a signal at danger.
|
||||||
|
WID_VV_HONK_HORN, ///< Honk the vehicles horn (not drawn on UI, only used for hotkey).
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Widgets of the #RefitWindow class. */
|
/** Widgets of the #RefitWindow class. */
|
||||||
|
|
Loading…
Reference in New Issue