|
|
|
@ -2,17 +2,11 @@
|
|
|
|
|
Airplane
|
|
|
|
|
Acrobatic air-vehicle. Capable of firing lead shot.
|
|
|
|
|
|
|
|
|
|
@author: Ringwaul, Clonkonaut
|
|
|
|
|
@author: Ringwaul, Clonkonaut, Maikel
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
local throttle = 0;
|
|
|
|
|
local rdir = 0;
|
|
|
|
|
local thrust = 0;
|
|
|
|
|
local dir = DIR_Left;
|
|
|
|
|
|
|
|
|
|
local newrot;
|
|
|
|
|
|
|
|
|
|
local propanim;
|
|
|
|
|
local prop_speed, prop_speed_target, prop_speed_timer; // current and target propeller speed [0, 100]
|
|
|
|
|
|
|
|
|
|
local pilot;
|
|
|
|
@ -22,23 +16,23 @@ local clonkmesh;
|
|
|
|
|
local main_action = "Cannon"; // default: fire bullets
|
|
|
|
|
|
|
|
|
|
// All available click actions
|
|
|
|
|
local action_list = ["Cannon", "Rocket", "Bomb", "Spray", "Balloon", "Drop"];
|
|
|
|
|
local action_list = ["Cannon", "Rocket", "Bomb", "Spray", "Balloon", "Drop", "Afterburner"];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Engine Callbacks --*/
|
|
|
|
|
|
|
|
|
|
func Construction()
|
|
|
|
|
public func Construction()
|
|
|
|
|
{
|
|
|
|
|
SetR(-90);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Initialize()
|
|
|
|
|
public func Initialize()
|
|
|
|
|
{
|
|
|
|
|
propanim = PlayAnimation("Propellor", 15, Anim_Const(0));
|
|
|
|
|
AddEffect("IntPlane", this, 1, 1, this);
|
|
|
|
|
CreateEffect(FxControlPlaneFlight, 1, 1);
|
|
|
|
|
SetAction("Land");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func RejectCollect(id def, object obj)
|
|
|
|
|
public func RejectCollect(id def, object obj)
|
|
|
|
|
{
|
|
|
|
|
var contents_count = ObjectCount(Find_Container(this), Find_Not(Find_OCF(OCF_CrewMember)));
|
|
|
|
|
if (contents_count >= MaxContentsCount)
|
|
|
|
@ -46,17 +40,18 @@ func RejectCollect(id def, object obj)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Damage(int change, int cause, int by_player)
|
|
|
|
|
public func Damage(int change, int cause, int by_player)
|
|
|
|
|
{
|
|
|
|
|
if (GetDamage() >= this.HitPoints)
|
|
|
|
|
{
|
|
|
|
|
if (pilot) PlaneDismount(pilot);
|
|
|
|
|
if (pilot)
|
|
|
|
|
PlaneDismount(pilot);
|
|
|
|
|
SetController(by_player);
|
|
|
|
|
PlaneDeath();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ActivateEntrance(object clonk)
|
|
|
|
|
public func ActivateEntrance(object clonk)
|
|
|
|
|
{
|
|
|
|
|
if (clonk->Contained() == this)
|
|
|
|
|
return clonk->Exit();
|
|
|
|
@ -73,16 +68,17 @@ func ActivateEntrance(object clonk)
|
|
|
|
|
ShowMainActionTo(clonk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Ejection(object obj)
|
|
|
|
|
public func Ejection(object obj)
|
|
|
|
|
{
|
|
|
|
|
if (pilot && obj == pilot)
|
|
|
|
|
PlaneDismount(obj);
|
|
|
|
|
if(obj->Contained()) Exit();
|
|
|
|
|
if (obj->Contained())
|
|
|
|
|
Exit();
|
|
|
|
|
obj->SetSpeed(this->GetXDir(), this->GetYDir());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Inflict damage when hitting something with the plane and already damaged.
|
|
|
|
|
func Hit(int xdir, int ydir)
|
|
|
|
|
public func Hit(int xdir, int ydir)
|
|
|
|
|
{
|
|
|
|
|
var remaining_hp = this.HitPoints - GetDamage();
|
|
|
|
|
if (remaining_hp < 10)
|
|
|
|
@ -93,12 +89,14 @@ func Hit(int xdir, int ydir)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Callbacks --*/
|
|
|
|
|
|
|
|
|
|
public func IsContainer() { return true; }
|
|
|
|
|
|
|
|
|
|
public func IsProjectileTarget(target, shooter) { return true; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Interface --*/
|
|
|
|
|
|
|
|
|
|
//Quick command for scenario designers. The plane starts facing right instead of left.
|
|
|
|
@ -114,6 +112,7 @@ public func FaceLeft()
|
|
|
|
|
RollPlane(0, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Interaction --*/
|
|
|
|
|
|
|
|
|
|
// Provides an own interaction menu.
|
|
|
|
@ -124,7 +123,7 @@ public func GetInteractionMenus(object clonk)
|
|
|
|
|
{
|
|
|
|
|
var menus = _inherited(clonk, ...) ?? [];
|
|
|
|
|
|
|
|
|
|
// Do not show the menu if flying and if the clonk is not the pilot
|
|
|
|
|
// Do not show the menu if flying and if the clonk is not the pilot.
|
|
|
|
|
if (GetAction() == "Fly" && clonk != pilot)
|
|
|
|
|
return menus;
|
|
|
|
|
|
|
|
|
@ -201,6 +200,8 @@ public func OnSettingsHover(symbol, extra_data, desc_menu_target, menu_id)
|
|
|
|
|
text = Format("$BalloonInfo$", GetBalloonAmount());
|
|
|
|
|
if (main_action == "Drop")
|
|
|
|
|
text = Format("$DropInfo$");
|
|
|
|
|
if (main_action == "Afterburner")
|
|
|
|
|
text = Format("$AfterburnerInfo$");
|
|
|
|
|
if (text == "")
|
|
|
|
|
text = "$Description$";
|
|
|
|
|
}
|
|
|
|
@ -208,7 +209,7 @@ public func OnSettingsHover(symbol, extra_data, desc_menu_target, menu_id)
|
|
|
|
|
GuiUpdate({ Text = text }, menu_id, 1, desc_menu_target);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetActionTypeTooltip(string action)
|
|
|
|
|
private func GetActionTypeTooltip(string action)
|
|
|
|
|
{
|
|
|
|
|
// Show next firing mode
|
|
|
|
|
var position = GetIndexOf(action_list, action);
|
|
|
|
@ -222,7 +223,7 @@ func GetActionTypeTooltip(string action)
|
|
|
|
|
return Format("$SwitchTo$", GetActionTypeName(action_list[position]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetActionTypeName(string action)
|
|
|
|
|
private func GetActionTypeName(string action)
|
|
|
|
|
{
|
|
|
|
|
if (action == "Cannon")
|
|
|
|
|
return "$Bullet$";
|
|
|
|
@ -236,9 +237,11 @@ func GetActionTypeName(string action)
|
|
|
|
|
return "$Balloon$";
|
|
|
|
|
if (action == "Drop")
|
|
|
|
|
return "$Drop$";
|
|
|
|
|
if (action == "Afterburner")
|
|
|
|
|
return "$Afterburner$";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetActionTypeInfo(string action)
|
|
|
|
|
private func GetActionTypeInfo(string action)
|
|
|
|
|
{
|
|
|
|
|
if (action == "Cannon")
|
|
|
|
|
return LeadBullet;
|
|
|
|
@ -252,12 +255,15 @@ func GetActionTypeInfo(string action)
|
|
|
|
|
return Balloon;
|
|
|
|
|
if (action == "Drop")
|
|
|
|
|
return Icon_LetGo;
|
|
|
|
|
if (action == "Afterburner")
|
|
|
|
|
return Icon_Flame;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public func ToggleMainAction(object clonk)
|
|
|
|
|
{
|
|
|
|
|
var current_action = GetIndexOf(action_list, main_action);
|
|
|
|
|
if (current_action == -1) return; // ??
|
|
|
|
|
if (current_action == -1)
|
|
|
|
|
return; // ??
|
|
|
|
|
|
|
|
|
|
if (current_action == GetLength(action_list)-1)
|
|
|
|
|
current_action = 0;
|
|
|
|
@ -275,6 +281,7 @@ public func ToggleMainAction(object clonk)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Usage --*/
|
|
|
|
|
|
|
|
|
|
// Main action
|
|
|
|
@ -322,32 +329,33 @@ public func ContainedUseAltCancel(object clonk, int x, int y)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Starting the plane
|
|
|
|
|
// Starting the plane.
|
|
|
|
|
public func ContainedUp(object clonk)
|
|
|
|
|
{
|
|
|
|
|
if (pilot)
|
|
|
|
|
{
|
|
|
|
|
// For safety, check if the pilot is dead (which is never particularly good)
|
|
|
|
|
// During flight, pilot's health is constantly checked by the flying effect
|
|
|
|
|
// For safety, check if the pilot is dead (which is never particularly good).
|
|
|
|
|
// During flight, pilot's health is constantly checked by the flying effect.
|
|
|
|
|
if (!pilot->GetAlive())
|
|
|
|
|
PlaneDismount(pilot);
|
|
|
|
|
else if (clonk != pilot)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//engine start
|
|
|
|
|
if(clonk && GetAction() == "Land")
|
|
|
|
|
// Start engine.
|
|
|
|
|
if (clonk && GetAction() == "Land")
|
|
|
|
|
{
|
|
|
|
|
if (!pilot) PlaneMount(clonk);
|
|
|
|
|
if (!pilot)
|
|
|
|
|
PlaneMount(clonk);
|
|
|
|
|
StartFlight(15);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Stopping the plane
|
|
|
|
|
// Stopping the plane.
|
|
|
|
|
public func ContainedDown(object clonk)
|
|
|
|
|
{
|
|
|
|
|
//engine shutoff
|
|
|
|
|
// Shut down engine.
|
|
|
|
|
if (GetAction() == "Fly" && clonk == pilot)
|
|
|
|
|
{
|
|
|
|
|
CancelFlight();
|
|
|
|
@ -360,7 +368,7 @@ public func ContainedDown(object clonk)
|
|
|
|
|
else if (clonk != pilot)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//allow reverse
|
|
|
|
|
// Allow reverse pilot.
|
|
|
|
|
if (clonk && GetAction() == "Land")
|
|
|
|
|
{
|
|
|
|
|
if (!pilot)
|
|
|
|
@ -371,12 +379,14 @@ public func ContainedDown(object clonk)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Steering
|
|
|
|
|
// Steering.
|
|
|
|
|
public func ContainedLeft(object clonk)
|
|
|
|
|
{
|
|
|
|
|
if (clonk != pilot)
|
|
|
|
|
return false;
|
|
|
|
|
rdir = -1;
|
|
|
|
|
var ctrl_fx = GetPlaneControl();
|
|
|
|
|
if (ctrl_fx)
|
|
|
|
|
ctrl_fx->SetRotationDir(-1);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -384,7 +394,9 @@ public func ContainedRight(object clonk)
|
|
|
|
|
{
|
|
|
|
|
if (clonk != pilot)
|
|
|
|
|
return false;
|
|
|
|
|
rdir = 1;
|
|
|
|
|
var ctrl_fx = GetPlaneControl();
|
|
|
|
|
if (ctrl_fx)
|
|
|
|
|
ctrl_fx->SetRotationDir(1);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -392,31 +404,35 @@ public func ContainedStop(object clonk)
|
|
|
|
|
{
|
|
|
|
|
if (clonk != pilot)
|
|
|
|
|
return false;
|
|
|
|
|
rdir = 0;
|
|
|
|
|
var ctrl_fx = GetPlaneControl();
|
|
|
|
|
if (ctrl_fx)
|
|
|
|
|
ctrl_fx->SetRotationDir(0);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Control --*/
|
|
|
|
|
|
|
|
|
|
public func GetFacingDir()
|
|
|
|
|
{
|
|
|
|
|
return dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public func ControlLeft(object clonk)
|
|
|
|
|
{
|
|
|
|
|
if (Inside(GetR(), 80, 100) && dir == DIR_Right)
|
|
|
|
|
{
|
|
|
|
|
FaceLeft();
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public func ControlRight(object clonk)
|
|
|
|
|
{
|
|
|
|
|
if (Inside(GetR(), -100, -80) && dir == DIR_Left)
|
|
|
|
|
{
|
|
|
|
|
FaceRight();
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Bullet firing --*/
|
|
|
|
|
|
|
|
|
|
public func UseCannon(object clonk, int x, int y)
|
|
|
|
@ -459,7 +475,7 @@ public func GetBulletAmount()
|
|
|
|
|
return shots;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func FxFireBulletsStart(object target, proplist effect, int temp)
|
|
|
|
|
public func FxFireBulletsStart(object target, proplist effect, int temp)
|
|
|
|
|
{
|
|
|
|
|
if (temp)
|
|
|
|
|
return FX_OK;
|
|
|
|
@ -473,7 +489,7 @@ func FxFireBulletsStart(object target, proplist effect, int temp)
|
|
|
|
|
return FX_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func FxFireBulletsTimer(object target, proplist effect, int time)
|
|
|
|
|
public func FxFireBulletsTimer(object target, proplist effect, int time)
|
|
|
|
|
{
|
|
|
|
|
var ammo = FindObject(Find_Container(this), Find_Func("IsBullet"));
|
|
|
|
|
if (!ammo)
|
|
|
|
@ -482,7 +498,7 @@ func FxFireBulletsTimer(object target, proplist effect, int time)
|
|
|
|
|
return FX_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func FxFireBulletsStop(object target, proplist effect, int reason, bool temp)
|
|
|
|
|
public func FxFireBulletsStop(object target, proplist effect, int reason, bool temp)
|
|
|
|
|
{
|
|
|
|
|
if (temp)
|
|
|
|
|
return FX_OK;
|
|
|
|
@ -491,7 +507,7 @@ func FxFireBulletsStop(object target, proplist effect, int reason, bool temp)
|
|
|
|
|
return FX_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func FireBullet(object ammo)
|
|
|
|
|
public func FireBullet(object ammo)
|
|
|
|
|
{
|
|
|
|
|
var shot = ammo->TakeObject();
|
|
|
|
|
var angle = this->GetR();
|
|
|
|
@ -510,6 +526,7 @@ func FireBullet(object ammo)
|
|
|
|
|
CreateParticle("Flash", 0, 0, GetXDir(), GetYDir(), 8, Particles_Flash());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Rocket firing --*/
|
|
|
|
|
|
|
|
|
|
public func UseRocket(object clonk, int x, int y)
|
|
|
|
@ -544,7 +561,7 @@ public func GetRocketAmount()
|
|
|
|
|
return ContentsCount(Boompack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func FireRocket(object rocket, int x, int y)
|
|
|
|
|
public func FireRocket(object rocket, int x, int y)
|
|
|
|
|
{
|
|
|
|
|
var launch_x = Cos(GetR() - 180 * (1 - dir), 10);
|
|
|
|
|
var launch_y = Sin(GetR() - 180 * (1 - dir), 10);
|
|
|
|
@ -556,7 +573,7 @@ func FireRocket(object rocket, int x, int y)
|
|
|
|
|
rocket->SetDirectionDeviation(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func FxIntControlRocketTimer(object target, proplist effect, int time)
|
|
|
|
|
public func FxIntControlRocketTimer(object target, proplist effect, int time)
|
|
|
|
|
{
|
|
|
|
|
// Remove gravity on rocket.
|
|
|
|
|
target->SetYDir(target->GetYDir(100) - GetGravity(), 100);
|
|
|
|
@ -575,6 +592,7 @@ func FxIntControlRocketTimer(object target, proplist effect, int time)
|
|
|
|
|
return FX_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Bombing --*/
|
|
|
|
|
|
|
|
|
|
public func UseBomb(object clonk, int x, int y)
|
|
|
|
@ -622,7 +640,7 @@ public func GetBombAmount()
|
|
|
|
|
return bombs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func DropBomb(object bomb)
|
|
|
|
|
private func DropBomb(object bomb)
|
|
|
|
|
{
|
|
|
|
|
if (!bomb) return;
|
|
|
|
|
|
|
|
|
@ -633,6 +651,7 @@ func DropBomb(object bomb)
|
|
|
|
|
bomb->Fuse(true); // fuse and explode on hit
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Liquid spray --*/
|
|
|
|
|
|
|
|
|
|
public func UseSpray(object clonk, int x, int y)
|
|
|
|
@ -680,7 +699,7 @@ public func GetBarrelAmount()
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func SprayLiquid(object barrel, object clonk)
|
|
|
|
|
private func SprayLiquid(object barrel, object clonk)
|
|
|
|
|
{
|
|
|
|
|
if (!barrel) return;
|
|
|
|
|
|
|
|
|
@ -691,6 +710,7 @@ func SprayLiquid(object barrel, object clonk)
|
|
|
|
|
Sound("Liquids::Splash1");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Parachuting --*/
|
|
|
|
|
|
|
|
|
|
public func UseBalloon(object clonk, int x, int y)
|
|
|
|
@ -722,7 +742,7 @@ public func GetBalloonAmount()
|
|
|
|
|
return ContentsCount(Balloon);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Parachute(object balloon, int x, int y, object clonk)
|
|
|
|
|
private func Parachute(object balloon, int x, int y, object clonk)
|
|
|
|
|
{
|
|
|
|
|
if (!balloon || !clonk) return;
|
|
|
|
|
|
|
|
|
@ -736,6 +756,7 @@ func Parachute(object balloon, int x, int y, object clonk)
|
|
|
|
|
balloon->ControlUseStart(clonk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Object dropping --*/
|
|
|
|
|
|
|
|
|
|
public func UseDrop(object clonk, int x, int y)
|
|
|
|
@ -771,7 +792,7 @@ public func GetNonClonkContents()
|
|
|
|
|
return FindObjects(Find_Container(this), Find_Not(Find_OCF(OCF_CrewMember)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func DropObject(object to_drop, int x, int y, object clonk)
|
|
|
|
|
private func DropObject(object to_drop, int x, int y, object clonk)
|
|
|
|
|
{
|
|
|
|
|
if (!to_drop) return;
|
|
|
|
|
|
|
|
|
@ -783,69 +804,201 @@ func DropObject(object to_drop, int x, int y, object clonk)
|
|
|
|
|
to_drop->SetController(clonk->GetOwner());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Afterburner --*/
|
|
|
|
|
|
|
|
|
|
public func UseAfterburner(object clonk, int x, int y)
|
|
|
|
|
{
|
|
|
|
|
if (clonk != pilot)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!GetOilBarrel())
|
|
|
|
|
{
|
|
|
|
|
CustomMessage("$NoOil$", this, clonk->GetOwner());
|
|
|
|
|
Sound("Objects::Weapons::Blunderbuss::Click?");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
CreateEffect(FxAfterburner, 100, 2);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public func CancelAfterburner(object clonk, int x, int y)
|
|
|
|
|
{
|
|
|
|
|
if (clonk != pilot)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
var fx = GetEffect("FxAfterburner", this);
|
|
|
|
|
if (fx)
|
|
|
|
|
fx->Remove();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public func GetOilBarrel()
|
|
|
|
|
{
|
|
|
|
|
var barrels = FindObjects(Find_Container(this), Find_Or(Find_ID(Barrel), Find_ID(MetalBarrel)));
|
|
|
|
|
for (var barrel in barrels)
|
|
|
|
|
if (barrel->GetLiquidAmount("Oil") > 0)
|
|
|
|
|
return barrel;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public func IsUsingAfterburner()
|
|
|
|
|
{
|
|
|
|
|
return !!GetEffect("FxAfterburner", this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
local FxAfterburner = new Effect
|
|
|
|
|
{
|
|
|
|
|
Construction = func()
|
|
|
|
|
{
|
|
|
|
|
Target->Sound("Objects::Boompack::Fly", 0, 40, nil, 1);
|
|
|
|
|
},
|
|
|
|
|
Timer = func(int time)
|
|
|
|
|
{
|
|
|
|
|
var barrel = Target->GetOilBarrel();
|
|
|
|
|
if (!barrel)
|
|
|
|
|
return FX_Execute_Kill;
|
|
|
|
|
if (barrel->GetLiquidAmount("Oil") <= 0)
|
|
|
|
|
return FX_Execute_Kill;
|
|
|
|
|
barrel->RemoveLiquid("Oil", 1);
|
|
|
|
|
return FX_OK;
|
|
|
|
|
},
|
|
|
|
|
Destruction = func()
|
|
|
|
|
{
|
|
|
|
|
Target->Sound("Objects::Boompack::Fly", 0, 40, nil, -1);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Movement --*/
|
|
|
|
|
|
|
|
|
|
public func StartFlight(int new_throttle)
|
|
|
|
|
{
|
|
|
|
|
SetPropellerSpeedTarget(100);
|
|
|
|
|
SetAction("Fly");
|
|
|
|
|
throttle = new_throttle;
|
|
|
|
|
var ctrl_fx = GetPlaneControl();
|
|
|
|
|
if (ctrl_fx)
|
|
|
|
|
ctrl_fx.throttle = new_throttle;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public func StartInstantFlight(int angle, int new_throttle)
|
|
|
|
|
{
|
|
|
|
|
if (angle < 0) angle += 360;
|
|
|
|
|
if (angle < 180) angle -= 10; else angle += 10;
|
|
|
|
|
if (angle < 0)
|
|
|
|
|
angle += 360;
|
|
|
|
|
if (angle < 180)
|
|
|
|
|
angle -= 10;
|
|
|
|
|
else
|
|
|
|
|
angle += 10;
|
|
|
|
|
SetPropellerSpeed(100);
|
|
|
|
|
SetAction("Fly");
|
|
|
|
|
throttle = new_throttle;
|
|
|
|
|
thrust = new_throttle;
|
|
|
|
|
var ctrl_fx = GetPlaneControl();
|
|
|
|
|
if (ctrl_fx)
|
|
|
|
|
{
|
|
|
|
|
ctrl_fx.throttle = new_throttle;
|
|
|
|
|
ctrl_fx.thrust = new_throttle;
|
|
|
|
|
}
|
|
|
|
|
SetR(angle);
|
|
|
|
|
SetXDir(Sin(angle, thrust));
|
|
|
|
|
SetYDir(-Cos(angle, thrust));
|
|
|
|
|
SetXDir(Sin(angle, new_throttle));
|
|
|
|
|
SetYDir(-Cos(angle, new_throttle));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public func CancelFlight()
|
|
|
|
|
{
|
|
|
|
|
SetPropellerSpeedTarget(0);
|
|
|
|
|
SetAction("Land");
|
|
|
|
|
rdir = 0;
|
|
|
|
|
throttle = 0;
|
|
|
|
|
var ctrl_fx = GetPlaneControl();
|
|
|
|
|
if (ctrl_fx)
|
|
|
|
|
{
|
|
|
|
|
ctrl_fx.rdir = 0;
|
|
|
|
|
ctrl_fx.throttle = 0;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func FxIntPlaneTimer(object target, effect, int timer)
|
|
|
|
|
public func GetPlaneControl()
|
|
|
|
|
{
|
|
|
|
|
//Lift
|
|
|
|
|
var lift = Distance(0, 0, GetXDir(), GetYDir()) / 2;
|
|
|
|
|
if (lift > 20)
|
|
|
|
|
lift = 20;
|
|
|
|
|
if (throttle < 1)
|
|
|
|
|
lift = 0;
|
|
|
|
|
return GetEffect("FxControlPlaneFlight", this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GetAction() == "Fly")
|
|
|
|
|
public func RemovePlaneControl()
|
|
|
|
|
{
|
|
|
|
|
var ctrl_fx = GetPlaneControl();
|
|
|
|
|
if (ctrl_fx)
|
|
|
|
|
ctrl_fx->Remove();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Effect that controls the plane movement and related stuff.
|
|
|
|
|
local FxControlPlaneFlight = new Effect
|
|
|
|
|
{
|
|
|
|
|
Construction = func()
|
|
|
|
|
{
|
|
|
|
|
// clockwise
|
|
|
|
|
if (rdir == 1)
|
|
|
|
|
if(GetRDir() < 5) SetRDir(GetRDir() + 3);
|
|
|
|
|
// counter-clockwise
|
|
|
|
|
if (rdir == -1)
|
|
|
|
|
if(GetRDir() > -5) SetRDir(GetRDir() - 3);
|
|
|
|
|
if (rdir == 0) SetRDir();
|
|
|
|
|
|
|
|
|
|
// Roll plane to movement direction
|
|
|
|
|
if (throttle > 0)
|
|
|
|
|
this.thrust = 0;
|
|
|
|
|
this.throttle = 0;
|
|
|
|
|
this.lift = 0;
|
|
|
|
|
this.rdir = 0;
|
|
|
|
|
this.propanim = Target->PlayAnimation("Propellor", 15, Anim_Const(0));
|
|
|
|
|
},
|
|
|
|
|
Destruction = func()
|
|
|
|
|
{
|
|
|
|
|
Target->StopAnimation(this.propanim);
|
|
|
|
|
},
|
|
|
|
|
SetRotationDir = func(int new_dir)
|
|
|
|
|
{
|
|
|
|
|
this.rdir = new_dir;
|
|
|
|
|
},
|
|
|
|
|
Timer = func(int time)
|
|
|
|
|
{
|
|
|
|
|
// Perform flying actions.
|
|
|
|
|
if (Target->GetAction() == "Fly")
|
|
|
|
|
{
|
|
|
|
|
if(GetXDir() > 10 && dir != DIR_Right) RollPlane(1);
|
|
|
|
|
if(GetXDir() < -10 && dir != DIR_Left) RollPlane(0);
|
|
|
|
|
this->DoPlaneRotation();
|
|
|
|
|
this->DoEngineSmoke();
|
|
|
|
|
this->StirUpLiquids();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Vfx
|
|
|
|
|
|
|
|
|
|
// Engine smoke
|
|
|
|
|
var colour = 255 - (GetDamage() * 3);
|
|
|
|
|
// Perform landing actions.
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this->LandPlane();
|
|
|
|
|
}
|
|
|
|
|
// Perform plane movements.
|
|
|
|
|
this->ApplyThrust(time);
|
|
|
|
|
this->ApplyDrag();
|
|
|
|
|
this->PropellorAnim();
|
|
|
|
|
this->PerformSafetyChecks();
|
|
|
|
|
return FX_OK;
|
|
|
|
|
},
|
|
|
|
|
DoPlaneRotation = func()
|
|
|
|
|
{
|
|
|
|
|
// Perform plane rotation.
|
|
|
|
|
var max_rdir = 7;
|
|
|
|
|
if (Target->IsUsingAfterburner())
|
|
|
|
|
max_rdir = 9;
|
|
|
|
|
var current_rdir = Target->GetRDir();
|
|
|
|
|
var new_rdir = current_rdir + 3 * this.rdir;
|
|
|
|
|
if (this.rdir == 0)
|
|
|
|
|
new_rdir = 0;
|
|
|
|
|
new_rdir = BoundBy(new_rdir, -max_rdir, max_rdir);
|
|
|
|
|
Target->SetRDir(new_rdir);
|
|
|
|
|
// Roll plane to movement direction.
|
|
|
|
|
if (this.throttle > 0)
|
|
|
|
|
{
|
|
|
|
|
if (Target->GetXDir() > 10 && Target->GetFacingDir() != DIR_Right)
|
|
|
|
|
Target->RollPlane(1);
|
|
|
|
|
if (Target->GetXDir() < -10 && Target->GetFacingDir() != DIR_Left)
|
|
|
|
|
Target->RollPlane(0);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// Perform engine smoke.
|
|
|
|
|
DoEngineSmoke = func()
|
|
|
|
|
{
|
|
|
|
|
var colour = 255 - (Target->GetDamage() * 3);
|
|
|
|
|
var min = PV_Random(7, 20);
|
|
|
|
|
var max = PV_Random(40, 70);
|
|
|
|
|
if (GetDamage() >= this.HitPoints / 2)
|
|
|
|
|
var rot = Target->GetR();
|
|
|
|
|
if (Target->GetDamage() >= Target.HitPoints / 2)
|
|
|
|
|
{
|
|
|
|
|
min = PV_Random(20, 30);
|
|
|
|
|
max = PV_Random(70, 100);
|
|
|
|
@ -856,18 +1009,29 @@ func FxIntPlaneTimer(object target, effect, int timer)
|
|
|
|
|
R = colour, G = colour, B = colour,
|
|
|
|
|
Size = PV_Linear(min, max)
|
|
|
|
|
};
|
|
|
|
|
CreateParticle("Smoke", -Sin(GetR(), 10), Cos(GetR(), 10), 0, 0, PV_Random(36, 2 * 36), particles, 1);
|
|
|
|
|
// Stir up liquids
|
|
|
|
|
if (GBackLiquid(0, 40))
|
|
|
|
|
Target->CreateParticle("Smoke", -Sin(rot, 10), Cos(rot, 10), 0, 0, PV_Random(36, 2 * 36), particles, 1);
|
|
|
|
|
// Add fire if after burner is turned on.
|
|
|
|
|
if (Target->IsUsingAfterburner())
|
|
|
|
|
{
|
|
|
|
|
var particle_fire = Particles_Fire();
|
|
|
|
|
particle_fire.Size = PV_KeyFrames(0, 0, PV_Random(6, 8), 500, 4, 1000, 0);
|
|
|
|
|
Target->CreateParticle("Fire", -Sin(rot, 10), Cos(rot, 10), PV_Random(-1, 1), PV_Random(-1, 1), 20 + Random(10), particle_fire, 1);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// Stirs up liquids if flying above a liquid.
|
|
|
|
|
StirUpLiquids = func()
|
|
|
|
|
{
|
|
|
|
|
if (Target->GBackLiquid(0, 40))
|
|
|
|
|
{
|
|
|
|
|
var surface = 40;
|
|
|
|
|
while (surface && GBackSemiSolid(0, surface))
|
|
|
|
|
while (surface && Target->GBackSemiSolid(0, surface))
|
|
|
|
|
surface--;
|
|
|
|
|
if (surface > 0 && GBackLiquid(0, surface + 1))
|
|
|
|
|
if (surface > 0 && Target->GBackLiquid(0, surface + 1))
|
|
|
|
|
{
|
|
|
|
|
var phases = PV_Linear(0, 7);
|
|
|
|
|
if (dir == DIR_Left) phases = PV_Linear(8, 15);
|
|
|
|
|
var color = GetAverageTextureColor(GetTexture(0, surface + 1));
|
|
|
|
|
if (Target->GetFacingDir() == DIR_Left)
|
|
|
|
|
phases = PV_Linear(8, 15);
|
|
|
|
|
var color = GetAverageTextureColor(Target->GetTexture(0, surface + 1));
|
|
|
|
|
var particles =
|
|
|
|
|
{
|
|
|
|
|
Size = 16,
|
|
|
|
@ -879,84 +1043,105 @@ func FxIntPlaneTimer(object target, effect, int timer)
|
|
|
|
|
B = (color >> 0) & 0xff,
|
|
|
|
|
Attach = ATTACH_Front,
|
|
|
|
|
};
|
|
|
|
|
CreateParticle("Wave", 0, surface, (RandomX(-5, 5) - (-1 + 2 * dir) * 6) / 4, 0, 16, particles);
|
|
|
|
|
Target->CreateParticle("Wave", 0, surface, (RandomX(-5, 5) - (-1 + 2 * Target->GetFacingDir()) * 6) / 4, 0, 16, particles);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else // Action "Land"
|
|
|
|
|
},
|
|
|
|
|
// Lands the plane.
|
|
|
|
|
LandPlane = func()
|
|
|
|
|
{
|
|
|
|
|
// If under or on water, turn upright
|
|
|
|
|
if (GBackLiquid() || GBackLiquid(0, 21))
|
|
|
|
|
// If under or on water, turn upright.
|
|
|
|
|
if (Target->GBackLiquid() || Target->GBackLiquid(0, 21))
|
|
|
|
|
{
|
|
|
|
|
if (GetR() < 0)
|
|
|
|
|
if (Target->GetR() < 0)
|
|
|
|
|
{
|
|
|
|
|
if (!Inside(GetR(), -95, -85))
|
|
|
|
|
if (!Inside(Target->GetR(), -95, -85))
|
|
|
|
|
{
|
|
|
|
|
SetRDir((90 + GetR()) / Abs(90 + GetR()) * -3);
|
|
|
|
|
RollPlane(0);
|
|
|
|
|
Target->SetRDir((90 + Target->GetR()) / Abs(90 + Target->GetR()) * -3);
|
|
|
|
|
Target->RollPlane(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (!Inside(GetR(), 85, 95))
|
|
|
|
|
else if (!Inside(Target->GetR(), 85, 95))
|
|
|
|
|
{
|
|
|
|
|
SetRDir((90 - GetR()) / Abs(90 - GetR()) * 3);
|
|
|
|
|
RollPlane(1);
|
|
|
|
|
Target->SetRDir((90 - Target->GetR()) / Abs(90 - Target->GetR()) * 3);
|
|
|
|
|
Target->RollPlane(1);
|
|
|
|
|
}
|
|
|
|
|
// Also: slow down because the plane tends to slide across water
|
|
|
|
|
if (GetXDir() > 0)
|
|
|
|
|
SetXDir(GetXDir() - 1);
|
|
|
|
|
else if (GetXDir() < 0)
|
|
|
|
|
SetXDir(GetXDir() + 1);
|
|
|
|
|
// Also: slow down because the plane tends to slide across water.
|
|
|
|
|
if (Target->GetXDir() > 0)
|
|
|
|
|
Target->SetXDir(Target->GetXDir() - 1);
|
|
|
|
|
else if (Target->GetXDir() < 0)
|
|
|
|
|
Target->SetXDir(Target->GetXDir() + 1);
|
|
|
|
|
}
|
|
|
|
|
if (thrust > 0)
|
|
|
|
|
thrust--;
|
|
|
|
|
if (thrust < 0)
|
|
|
|
|
thrust++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Throttle-to-thrust lag
|
|
|
|
|
if (timer % 10 == 0)
|
|
|
|
|
// Decrease thrust rapidly.
|
|
|
|
|
if (this.thrust > 0)
|
|
|
|
|
this.thrust--;
|
|
|
|
|
if (this.thrust < 0)
|
|
|
|
|
this.thrust++;
|
|
|
|
|
},
|
|
|
|
|
ApplyThrust = func(int time)
|
|
|
|
|
{
|
|
|
|
|
if (throttle > thrust) ++thrust;
|
|
|
|
|
if (throttle < thrust) --thrust;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Propellor
|
|
|
|
|
var change = GetAnimationPosition(propanim) + thrust * 3;
|
|
|
|
|
if(change > GetAnimationLength("Propellor"))
|
|
|
|
|
change = (GetAnimationPosition(propanim) + thrust * 3) - GetAnimationLength("Propellor");
|
|
|
|
|
if(change < 0)
|
|
|
|
|
change = (GetAnimationLength("Propellor") - thrust * 3);
|
|
|
|
|
|
|
|
|
|
SetAnimationPosition(propanim, Anim_Const(change));
|
|
|
|
|
|
|
|
|
|
// Thrust
|
|
|
|
|
SetXDir(Sin(GetR(), thrust) + GetXDir(100), 100);
|
|
|
|
|
SetYDir(-Cos(GetR(), thrust) + GetYDir(100) - lift, 100);
|
|
|
|
|
|
|
|
|
|
// Drag
|
|
|
|
|
var maxspeed = 40;
|
|
|
|
|
var speed = Distance(0, 0, GetXDir(), GetYDir());
|
|
|
|
|
if (speed > maxspeed)
|
|
|
|
|
// Determine airplane lift.
|
|
|
|
|
this.lift = Distance(0, 0, Target->GetXDir(), Target->GetYDir()) / 2;
|
|
|
|
|
if (this.lift > 20)
|
|
|
|
|
this.lift = 20;
|
|
|
|
|
if (this.throttle < 1)
|
|
|
|
|
this.lift = 0;
|
|
|
|
|
// Modify throttle if afterburner is being used.
|
|
|
|
|
var mod_throttle = this.throttle;
|
|
|
|
|
if (Target->IsUsingAfterburner())
|
|
|
|
|
mod_throttle = 3 * mod_throttle / 2;
|
|
|
|
|
// Throttle-to-thrust lag
|
|
|
|
|
if (time % 10 == 0)
|
|
|
|
|
{
|
|
|
|
|
if (mod_throttle > this.thrust)
|
|
|
|
|
++this.thrust;
|
|
|
|
|
if (mod_throttle < this.thrust)
|
|
|
|
|
--this.thrust;
|
|
|
|
|
}
|
|
|
|
|
// Set airplane velocity.
|
|
|
|
|
Target->SetXDir(Sin(Target->GetR(), this.thrust) + Target->GetXDir(100), 100);
|
|
|
|
|
Target->SetYDir(-Cos(Target->GetR(), this.thrust) + Target->GetYDir(100) - this.lift, 100);
|
|
|
|
|
},
|
|
|
|
|
// Applies drag to the airplane to ensure a maximum speed.
|
|
|
|
|
ApplyDrag = func()
|
|
|
|
|
{
|
|
|
|
|
SetXDir(GetXDir(100)*maxspeed/speed, 100);
|
|
|
|
|
SetYDir(GetYDir(100)*maxspeed/speed, 100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!pilot && throttle != 0)
|
|
|
|
|
CancelFlight();
|
|
|
|
|
if (pilot && !pilot->GetAlive())
|
|
|
|
|
PlaneDismount(pilot);
|
|
|
|
|
|
|
|
|
|
// Planes cannot fly underwater!
|
|
|
|
|
if (GBackLiquid())
|
|
|
|
|
var maxspeed = 40;
|
|
|
|
|
if (Target->IsUsingAfterburner())
|
|
|
|
|
maxspeed += 18;
|
|
|
|
|
var speed = Distance(0, 0, Target->GetXDir(), Target->GetYDir());
|
|
|
|
|
if (speed > maxspeed)
|
|
|
|
|
{
|
|
|
|
|
Target->SetXDir(Target->GetXDir(100) * maxspeed / speed, 100);
|
|
|
|
|
Target->SetYDir(Target->GetYDir(100) * maxspeed / speed, 100);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
PropellorAnim = func()
|
|
|
|
|
{
|
|
|
|
|
if (pilot)
|
|
|
|
|
Ejection(pilot);
|
|
|
|
|
if (throttle != 0)
|
|
|
|
|
CancelFlight();
|
|
|
|
|
var change = Target->GetAnimationPosition(this.propanim) + this.thrust * 3;
|
|
|
|
|
if (change > Target->GetAnimationLength("Propellor"))
|
|
|
|
|
change = (Target->GetAnimationPosition(this.propanim) + this.thrust * 3) - Target->GetAnimationLength("Propellor");
|
|
|
|
|
if (change < 0)
|
|
|
|
|
change = (Target->GetAnimationLength("Propellor") - this.thrust * 3);
|
|
|
|
|
Target->SetAnimationPosition(this.propanim, Anim_Const(change));
|
|
|
|
|
},
|
|
|
|
|
PerformSafetyChecks = func()
|
|
|
|
|
{
|
|
|
|
|
// Check for pilot.
|
|
|
|
|
if (!Target->GetPilot() && this.throttle != 0)
|
|
|
|
|
Target->CancelFlight();
|
|
|
|
|
if (Target->GetPilot() && !Target->GetPilot()->GetAlive())
|
|
|
|
|
Target->PlaneDismount(Target->GetPilot());
|
|
|
|
|
|
|
|
|
|
// Planes cannot fly underwater!
|
|
|
|
|
if (Target->GBackLiquid())
|
|
|
|
|
{
|
|
|
|
|
if (Target->GetPilot())
|
|
|
|
|
Target->Ejection(Target->GetPilot());
|
|
|
|
|
if (this.throttle != 0)
|
|
|
|
|
Target->CancelFlight();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return FX_OK;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public func RollPlane(int rolldir, bool instant)
|
|
|
|
|
{
|
|
|
|
@ -965,11 +1150,12 @@ public func RollPlane(int rolldir, bool instant)
|
|
|
|
|
var i = 36;
|
|
|
|
|
if (instant)
|
|
|
|
|
i = 1;
|
|
|
|
|
newrot = PlayAnimation(Format("Roll%d",rolldir), 10, Anim_Linear(0, 0, GetAnimationLength(Format("Roll%d", rolldir)), i, ANIM_Hold));
|
|
|
|
|
PlayAnimation(Format("Roll%d",rolldir), 10, Anim_Linear(0, 0, GetAnimationLength(Format("Roll%d", rolldir)), i, ANIM_Hold));
|
|
|
|
|
dir = rolldir;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Piloting --*/
|
|
|
|
|
|
|
|
|
|
public func PlaneMount(object clonk)
|
|
|
|
@ -977,7 +1163,7 @@ public func PlaneMount(object clonk)
|
|
|
|
|
pilot = clonk;
|
|
|
|
|
SetOwner(clonk->GetController());
|
|
|
|
|
clonk->PlayAnimation("Stand", 15, nil, Anim_Const(1000));
|
|
|
|
|
clonkmesh = AttachMesh(clonk,"pilot","skeleton_body",Trans_Mul(Trans_Rotate(180, 1, 0, 0), Trans_Translate(-3000, 1000, 0)),AM_DrawBefore);
|
|
|
|
|
clonkmesh = AttachMesh(clonk, "pilot", "skeleton_body", Trans_Mul(Trans_Rotate(180, 1, 0, 0), Trans_Translate(-3000, 1000, 0)), AM_DrawBefore);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -991,11 +1177,16 @@ public func PlaneDismount(object clonk)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public func GetPilot()
|
|
|
|
|
{
|
|
|
|
|
return pilot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-- Effects --*/
|
|
|
|
|
|
|
|
|
|
func PlaneDeath()
|
|
|
|
|
private func PlaneDeath()
|
|
|
|
|
{
|
|
|
|
|
while(Contents(0))
|
|
|
|
|
while (Contents(0))
|
|
|
|
|
Contents(0)->Exit();
|
|
|
|
|
Explode(36);
|
|
|
|
|
}
|
|
|
|
@ -1015,12 +1206,13 @@ public func SetPropellerSpeed(int new_speed)
|
|
|
|
|
public func SetPropellerSpeedTarget(int new_speed_target)
|
|
|
|
|
{
|
|
|
|
|
prop_speed_target = new_speed_target;
|
|
|
|
|
if (!prop_speed_timer) prop_speed_timer = AddTimer(this.PropellerSpeedTimer, 10);
|
|
|
|
|
if (!prop_speed_timer)
|
|
|
|
|
prop_speed_timer = AddTimer(this.PropellerSpeedTimer, 10);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Execute fading to new propeller speed
|
|
|
|
|
func PropellerSpeedTimer()
|
|
|
|
|
public func PropellerSpeedTimer()
|
|
|
|
|
{
|
|
|
|
|
prop_speed = BoundBy(prop_speed_target, prop_speed - 10, prop_speed + 4);
|
|
|
|
|
if (prop_speed == prop_speed_target)
|
|
|
|
@ -1032,19 +1224,21 @@ func PropellerSpeedTimer()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set propeller speed sound. 0 = off, 100 = max speed.
|
|
|
|
|
func SetPropellerSound(int speed)
|
|
|
|
|
private func SetPropellerSound(int speed)
|
|
|
|
|
{
|
|
|
|
|
if (speed <= 0)
|
|
|
|
|
return Sound("Objects::Plane::PropellerLoop",0,100,nil,-1);
|
|
|
|
|
return Sound("Objects::Plane::PropellerLoop", 0, 100, nil, -1);
|
|
|
|
|
else
|
|
|
|
|
return Sound("Objects::Plane::PropellerLoop",0,100,nil,1,0,(speed-100)*2/3);
|
|
|
|
|
return Sound("Objects::Plane::PropellerLoop", 0, 100, nil, 1, 0, (speed - 100) * 2 / 3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Production --*/
|
|
|
|
|
|
|
|
|
|
public func IsVehicle() { return true; }
|
|
|
|
|
public func IsShipyardProduct() { return true; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Display --*/
|
|
|
|
|
|
|
|
|
|
public func ShowMainActionTo(object clonk)
|
|
|
|
@ -1059,6 +1253,7 @@ public func Definition(proplist def)
|
|
|
|
|
return _inherited(def, ...);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-- Properties --*/
|
|
|
|
|
|
|
|
|
|
local ActMap = {
|
|
|
|
|