1 /**
2 IronBomb
3 Explodes after a short fuse. Explodes on contact if shot by the grenade launcher.
4
5 @author Ringwaul, Clonkonaut
6 */
7
8 // If true, explodes on contact.
9 local armed;
10
ControlUse(object clonk,int x,int y)11 public func ControlUse(object clonk, int x, int y)
12 {
13 // If already activated, nothing (so, throw).
14 if (GetEffect("FuseBurn", this))
15 {
16 clonk->ControlThrow(this, x, y);
17 return true;
18 }
19 Fuse();
20 return true;
21 }
22
Fuse(bool explode_on_hit)23 public func Fuse(bool explode_on_hit)
24 {
25 armed = explode_on_hit;
26 AddEffect("FuseBurn", this, 1, 1, this);
27 return;
28 }
29
FuseTime()30 public func FuseTime() { return 90; }
31
IsFusing()32 public func IsFusing() { return !!GetEffect("FuseBurn", this); }
33
OnCannonShot(object cannon)34 public func OnCannonShot(object cannon)
35 {
36 return Fuse(true);
37 }
38
FxFuseBurnStart(object target,effect fx,int temp)39 public func FxFuseBurnStart(object target, effect fx, int temp)
40 {
41 if (temp)
42 return FX_OK;
43 Sound("Fire::FuseLoop", {loop_count = +1});
44 return FX_OK;
45 }
46
47
FxFuseBurnTimer(object target,effect fx,int time)48 public func FxFuseBurnTimer(object target, effect fx, int time)
49 {
50 // Emit some smoke from the fuse hole.
51 var i = 3;
52 var x = +Sin(GetR(), i);
53 var y = -Cos(GetR(), i);
54 CreateParticle("Smoke", x, y, x, y, PV_Random(18, 36), Particles_Smoke(), 2);
55 // Explode if time is up.
56 if (time >= FuseTime())
57 {
58 DoExplode();
59 return FX_Execute_Kill;
60 }
61 return FX_OK;
62 }
63
FxFuseBurnStop(object target,effect fx,int reason,bool temp)64 public func FxFuseBurnStop(object target, effect fx, int reason, bool temp)
65 {
66 if (temp)
67 return FX_OK;
68 Sound("Fire::FuseLoop", {loop_count = -1});
69 return FX_OK;
70 }
71
DoExplode()72 public func DoExplode()
73 {
74 // Cast lots of shrapnel.
75 var shrapnel_count = 20;
76 for (var cnt = 0; cnt < shrapnel_count; cnt++)
77 {
78 var shrapnel = CreateObjectAbove(Shrapnel);
79 shrapnel->SetVelocity(Random(359), RandomX(100, 140));
80 shrapnel->SetRDir(-30 + Random(61));
81 shrapnel->Launch(GetController());
82 CreateObject(BulletTrail)->Set(shrapnel, 2, 30);
83 }
84 if (GBackLiquid())
85 Sound("Fire::BlastLiquid2");
86 else
87 Sound("Fire::BlastMetal");
88 CreateParticle("Smoke", PV_Random(-30, 30), PV_Random(-30, 30), 0, 0, PV_Random(40, 60), Particles_Smoke(), 60);
89 Explode(28);
90 return;
91 }
92
Hit(int x,int y)93 protected func Hit(int x, int y)
94 {
95 if (armed)
96 return DoExplode();
97 return StonyObjectHit(x,y);
98 }
99
Incineration(int caused_by)100 protected func Incineration(int caused_by)
101 {
102 Extinguish();
103 Fuse();
104 SetController(caused_by);
105 return;
106 }
107
108 // Drop fusing bomb on death to prevent explosion directly after respawn
IsDroppedOnDeath(object clonk)109 public func IsDroppedOnDeath(object clonk)
110 {
111 return !!GetEffect("FuseBurn", this);
112 }
113
HasExplosionOnImpact()114 public func HasExplosionOnImpact() { return armed; }
115
IsWeapon()116 public func IsWeapon() { return true; }
IsArmoryProduct()117 public func IsArmoryProduct() { return true; }
IsGrenadeLauncherAmmo()118 public func IsGrenadeLauncherAmmo() { return true; }
IsExplosive()119 public func IsExplosive() { return true; }
120
121 /*-- Properties --*/
122
123 local Name = "$Name$";
124 local Description = "$Description$";
125 local Collectible = true;
126 local BlastIncinerate = 1;
127 local ContactIncinerate = 1;
128 local Components = {Firestone = 1, Metal = 1};