openclonk/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c

213 lines
4.7 KiB
C
Raw Normal View History

2013-05-24 19:17:44 +00:00
/*--
Grenade Launcher
Author: Clonkonaut
A single shot grenade launcher which fires dangerous iron bombs.
--*/
//Uses the extra slot library
#include Library_HasExtraSlot
// Initial velocity of the bomb
local shooting_strength = 75;
2013-05-24 19:17:44 +00:00
func Hit()
{
Sound("Hits::GeneralHit?");
2013-05-24 19:17:44 +00:00
}
local fAiming;
public func GetCarryMode(clonk) { if(fAiming >= 0) return CARRY_Musket; }
public func GetCarrySpecial(clonk) { if(fAiming > 0) return "pos_hand2"; }
public func GetCarryBone() { return "main"; }
public func GetCarryTransform()
{
return Trans_Mul(Trans_Rotate(90,1,0,0), Trans_Rotate(-10,0,0,1));
2013-05-24 19:17:44 +00:00
}
local animation_set;
func Initialize()
{
//Tweaking options
MuzzleUp = 12;
MuzzleFront = 13;
MuzzleDown = 16;
MuzzleOffset = -8;
animation_set = {
AimMode = AIM_Position, // The aiming animation is done by adjusting the animation position to fit the angle
AnimationAim = "MusketAimArms",
AnimationLoad = "MusketLoadArms",
LoadTime = 80,
AnimationShoot = nil,
ShootTime = 20,
WalkSpeed = 84,
WalkBack = 56,
};
}
public func GetAnimationSet() { return animation_set; }
local loaded;
local reload;
local yOffset;
local iBarrel;
local holding;
local MuzzleUp; local MuzzleFront; local MuzzleDown; local MuzzleOffset;
protected func HoldingEnabled() { return true; }
public func RejectUse(object clonk)
2013-05-24 19:17:44 +00:00
{
return !clonk->HasHandAction(false, false, true);
}
2013-05-24 19:17:44 +00:00
func ControlUseStart(object clonk, int x, int y)
{
2013-05-24 19:17:44 +00:00
// nothing in extraslot?
if(!Contents(0))
{
// put something inside
var obj;
if(obj = FindObject(Find_Container(clonk), Find_Func("IsGrenadeLauncherAmmo")))
{
obj->Enter(this);
}
}
// something in extraslot
if(!Contents(0))
{
clonk->CancelUse();
return true;
}
fAiming = 1;
holding = true;
// reload weapon if not loaded yet
if(!loaded)
clonk->StartLoad(this);
else
clonk->StartAim(this);
ControlUseHolding(clonk, x, y);
return true;
}
// Callback from the clonk when loading is finished
public func FinishedLoading(object clonk)
{
// Change picture to indicate being loaded.
this.PictureTransformation = Trans_Mul(Trans_Translate(-3000, 3000, 4000),Trans_Rotate(-45,0,0,1),Trans_Rotate(130,0,1,0));
2013-05-24 19:17:44 +00:00
loaded = true;
if(holding) clonk->StartAim(this);
return holding; // false means stop here and reset the clonk
}
func ControlUseHolding(object clonk, ix, iy)
{
var angle = Angle(0,0,ix,iy-MuzzleOffset);
angle = Normalize(angle,-180);
clonk->SetAimPosition(angle);
// Show and update trajectory preview only when loaded.
if (loaded)
{
var shot_x = Sin(180 - angle, MuzzleFront);
var shot_y = Cos(180 - angle, MuzzleUp) + MuzzleOffset;
Trajectory->Create(clonk, GetX() + shot_x, GetY() + shot_y, Cos(angle - 90, shooting_strength), Sin(angle - 90, shooting_strength));
}
2013-05-24 19:17:44 +00:00
return true;
}
protected func ControlUseStop(object clonk, ix, iy)
{
holding = false;
clonk->StopAim();
return true;
2013-05-24 19:17:44 +00:00
}
// Callback from the clonk, when he actually has stopped aiming
public func FinishedAiming(object clonk, int angle)
{
if(!loaded) return;
// Fire
2014-05-03 19:03:19 +00:00
if(Contents(0) && Contents(0)->~IsGrenadeLauncherAmmo())
2013-05-24 19:17:44 +00:00
FireWeapon(clonk, angle);
Trajectory->Remove(clonk);
2013-05-24 19:17:44 +00:00
clonk->StartShoot(this);
return true;
}
protected func ControlUseCancel(object clonk, int x, int y)
{
clonk->CancelAiming(this);
Trajectory->Remove(clonk);
2013-05-24 19:17:44 +00:00
return true;
}
public func Reset(clonk)
{
fAiming = 0;
}
private func FireWeapon(object clonk, int angle)
{
var shot = Contents(0)->~TakeObject() ?? Contents(0);
var IX=Sin(180-angle,MuzzleFront);
var IY=Cos(180-angle,MuzzleUp)+MuzzleOffset;
shot->LaunchProjectile(angle, 0, shooting_strength, IX, IY);
2013-05-24 19:17:44 +00:00
shot->~Fuse(true);
shot->SetController(clonk->GetController());
2013-05-24 19:17:44 +00:00
loaded = false;
// Reset transformation to indicate empty grenade launcher.
this.PictureTransformation = this.Prototype.PictureTransformation;
2013-05-24 19:17:44 +00:00
Sound("Objects::Weapons::Musket::GunShoot?");
2013-05-24 19:17:44 +00:00
// Muzzle Flash & gun smoke
if(Abs(Normalize(angle,-180)) > 90)
IY=Cos(180-angle,MuzzleDown)+MuzzleOffset;
var x = Sin(angle, 20);
var y = -Cos(angle, 20);
CreateParticle("Smoke", IX, IY, PV_Random(x - 20, x + 20), PV_Random(y - 20, y + 20), PV_Random(40, 60), Particles_Smoke(), 20);
clonk->CreateMuzzleFlash(IX, IY, angle, 40);
CreateParticle("Flash", 0, 0, 0, 0, 8, Particles_Flash());
2013-05-24 19:17:44 +00:00
}
func RejectCollect(id shotid, object shot)
{
// Only collect grenade launcher ammo
if(!(shot->~IsGrenadeLauncherAmmo())) return true;
}
public func IsWeapon() { return true; }
public func IsArmoryProduct() { return true; }
func Definition(def)
{
def.PictureTransformation = Trans_Mul(Trans_Translate(-3000, 1000, 1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1));
2013-05-24 19:17:44 +00:00
}
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;
local ForceFreeHands = true;