From 7ff547814243b2bd2d4c6cde59de4250ee30fefd Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Fri, 3 Apr 2015 12:21:28 +0200 Subject: [PATCH] make windbag burst more gradual and slightly depend on mass (#1297) --- .../Items.ocd/Tools.ocd/WindBag.ocd/Script.c | 328 ++++++++++-------- .../Tools.ocd/WindBag.ocd/StringTblDE.txt | 6 +- .../Tools.ocd/WindBag.ocd/StringTblUS.txt | 4 +- 3 files changed, 197 insertions(+), 141 deletions(-) diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/Script.c index 6a963af24..0e50bc049 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/Script.c @@ -1,172 +1,223 @@ -/*-- - Windbag (aka Jar of Winds) - Author: MimmoO +/** + Windbag + Automatically collects air when it is full which can be released into a blast. + + @author MimmoO, Maikel +*/ - Collect air until you're full, then release it with a blast. ---*/ +local fill_amount; -local Amount; -local MaxCap; -local sound; - -func Hit() -{ - Sound("GeneralHit?"); -} - -public func GetCarryMode(clonk) { return CARRY_Musket; } -public func GetCarryTransform() -{ - return Trans_Mul(Trans_Rotate(220,0,0,1),Trans_Rotate(-30,1,0,0),Trans_Rotate(26,0,1,0)); -} -public func GetCarryPhase() { return 600; } - -public func FxJarReloadTimer(object target, effect, int time) -{ - target->Load(); -} - -public func DoFullLoad() -{ - Amount = MaxCap; - return; -} protected func Initialize() { - MaxCap = 60; //Changes duration and power SetR(-45); - AddEffect("JarReload",this,100,2,this); - sound=false; + AddEffect("IntReload", this, 100, 1, this); + return; } -protected func ControlUse(object pClonk, iX, iY) +protected func Hit() { - if (pClonk->GetProcedure() == "ATTACH") + Sound("GeneralHit?"); + return; +} + +public func GetCarryMode(clonk) { return CARRY_Musket; } + +public func GetCarryTransform() +{ + return Trans_Mul(Trans_Rotate(220, 0, 0, 1), Trans_Rotate(-30, 1, 0, 0), Trans_Rotate(26, 0, 1, 0)); +} + +public func GetCarryPhase() { return 600; } + +public func IsInventorProduct() { return true; } + + +/*-- Usage --*/ + +protected func ControlUse(object clonk, x, y) +{ + if (clonk->GetProcedure() == "ATTACH") return true; - if(!GetEffect("JarReload",this)) + if (!GetEffect("IntReload", this) && !GetEffect("IntBurstWind", this)) { - if(!GBackLiquid()) - { - FireWeapon(pClonk, iX, iY); - Amount=0; - AddEffect("JarReload",this,100,1,this); - Sound("WindCharge",false,nil,nil,1); - sound=true; - } - + if (!GBackLiquid()) + BlastWind(clonk, x, y); return true; } - else - { - pClonk->Message("Reloading!"); - return true; - } -// ChargeSoundStop(); + clonk->Message("$MsgReloading$"); + return true; } -protected func Load() + +/*-- Loading --*/ + +public func DoFullLoad() { - - if(Amount <= MaxCap) - { - var R=RandomX(-25,25); - var D=RandomX(19,50); - var A=Random(360); - var SX=Sin(A + R,D); - var SY=Cos(A + R,D); + fill_amount = MaxIntake; + return; +} + +public func FxIntReloadStart(object target, proplist effect, int temp) +{ + if (temp) + return FX_OK; + effect.Interval = 1; + effect.sound = false; + return FX_OK; +} + +public func FxIntReloadTimer(object target, proplist effect, int time) +{ + if (fill_amount > MaxIntake) + return FX_Execute_Kill; - if(!GBackSolid(SX,SY) && !GBackLiquid(SX,SY) && !GBackSolid(0,0) && !GBackLiquid(0,0)) //when on a random spot in front is air... - { - if(!sound) - { - Sound("WindCharge",false,nil,nil,1); - sound=true; - } - Amount += 2; //Air is sucked in. - CreateParticle("Air", SX, SY, Sin(A + R,-D / 2), Cos(A + R,-D / 2), 18, {Prototype = Particles_Air(), Size = PV_KeyFrames(0, 0, 0, 250, 3, 1000, 0)}); - } - else if(GBackSolid(0,0) || GBackLiquid(0,0)) - { - if(sound) - ChargeSoundStop(); - } - - } - else + if (GBackSolid(0,0) || GBackLiquid(0,0)) { - RemoveEffect("JarReload",this); - ChargeSoundStop(); - + if (effect.sound) + { + Sound("WindCharge", false, nil, nil, -1); + Sound("WindChargeStop"); + effect.sound = false; + } + return FX_OK; } + + var radius = RandomX(12, 24); + var angle = Random(360); + var angle_var = RandomX(-25, 25); + var x = Sin(angle + angle_var, radius); + var y = Cos(angle + angle_var, radius); + // Check for a spot of air from which to take the air in. + if (!GBackSolid(x, y) && !GBackLiquid(x, y) && !GBackSolid(0, 0) && !GBackLiquid(0, 0)) + { + if (!effect.sound) + { + Sound("WindCharge", false, nil, nil, 1); + effect.sound = true; + } + + // Particles from the point where the air is sucked in. + var air = { + Prototype = Particles_Air(), + Size = PV_KeyFrames(0, 0, 0, 250, 3, 1000, 0) + }; + CreateParticle("Air", x, y, -x / 2, -y / 2, 18, air); + + // Increase the fill amount proportional to the number of frames. + fill_amount += effect.Interval; + } + return FX_OK; } -protected func ChargeSoundStop() +public func FxIntReloadStop(object target, proplist effect, int reason, bool temp) { - Sound("WindCharge",false,nil,nil,-1); - Sound("WindChargeStop"); - sound=false; + if (temp) + return FX_OK; + if (effect.sound) + { + Sound("WindCharge", false, nil, nil, -1); + Sound("WindChargeStop"); + } + return FX_OK; } -private func FireWeapon(object pClonk,iX,iY) + +/*-- Blasting --*/ + +private func BlastWind(object clonk, int x, int y) { - var iAngle=Angle(0,0,iX,iY); - - ChargeSoundStop(); + if (fill_amount <= 0) + { + fill_amount = 0; + AddEffect("IntReload", this, 100, 1, this); + return; + } + // The blast is handled by an effect. + AddEffect("IntBurstWind", this, 100, 1, this, nil, clonk, x, y); + return; +} + +public func FxIntBurstWindStart(object target, proplist effect, int temp, object clonk, int x, int y) +{ + if (temp) + return FX_OK; + effect.Interval = 1; + effect.clonk = clonk; + effect.x = clonk->GetX(); + effect.y = clonk->GetY(); + effect.angle = Angle(0, 0, x, y); + // Sound effect. Sound("WindGust"); - - //Find Victims to push - for(var i=10; i<32; i++) + // Particle effect. + for (var dr = 12; dr < 32; dr++) { - var R = RandomX(-20,20); - var SX = Sin(180 - iAngle + R,i); - var SY = Cos(180 - iAngle + R,i); - - if(!GBackSolid(SX,SY)) - { - CreateParticle("Air", SX, SY, Sin(180 - iAngle + (R),(Amount / 2) + 25), Cos(180 - iAngle + (R),(Amount / 2) + 25), 36, Particles_Air()); - } - } - - var sinspeed = Sin(180 - iAngle + (R / 2),(Amount) + 15); - var cosspeed = Cos(180 - iAngle + (R / 2),(Amount) + 15); - - if(pClonk->GetAction() != "Walk") - { //Makes the clonk firing it be pushed backwards a bit - var x = pClonk->GetXDir(); - var y = pClonk->GetYDir(); - pClonk->SetXDir((x) - (sinspeed / 3)); - pClonk->SetYDir((y) - (cosspeed / 3)); - } - - for( var obj in FindObjects( - Find_Or( - Find_Distance(10,Sin(180 - iAngle,20),Cos(180 - iAngle,20)), - Find_Distance(18,Sin(180 - iAngle,40),Cos(180 - iAngle,40)), - Find_Distance(25,Sin(180 - iAngle,70),Cos(180 - iAngle,70)) - ), - Find_Not(Find_Category(C4D_Structure)), - Find_Not(Find_Func("IsEnvironment")), - Find_Not(Find_Func("NoWindbagForce")), - Find_Layer(GetObjectLayer()), Find_NoContainer() - ) - ) - { - if(obj != pClonk && PathFree(pClonk->GetX(),pClonk->GetY(),obj->GetX(),obj->GetY())) - { - //enemys are pushed back - var x = obj->GetXDir(); - var y = obj->GetYDir(); - obj->SetXDir((x) + sinspeed); - obj->SetYDir((y) + cosspeed); - } + var r = RandomX(-20, 20); + var sx = Sin(effect.angle + r, dr / 2); + var sy = -Cos(effect.angle + r, dr / 2); + var vx = Sin(effect.angle + r, 2 * fill_amount / 3 + 12); + var vy = -Cos(effect.angle + r, 2 * fill_amount / 3 + 12); + if (!GBackSolid(sx, sy)) + CreateParticle("Air", sx, sy, vx, vy, 36, Particles_Air()); } + return FX_OK; } -func IsInventorProduct() { return true; } +public func FxIntBurstWindTimer(object target, proplist effect, int time) +{ + if (time > 12) + return FX_Execute_Kill; + + // Determine blast strength. + var vx = Sin(effect.angle, 20 * fill_amount + 150); + var vy = -Cos(effect.angle, 20 * fill_amount + 150); + + // Change the velocity of the shooter. + if (effect.clonk && effect.clonk->GetAction() != "Walk") + { + var cx = effect.clonk->GetXDir(100); + var cy = effect.clonk->GetYDir(100); + effect.clonk->SetXDir(cx - vx / (8 * time), 100); + effect.clonk->SetYDir(cy - vy / (8 * time), 100); + } + + // Move other objects in a cone around the burst direction. + var criteria = Find_And(Find_Not(Find_Category(C4D_Structure)), Find_Not(Find_Func("IsEnvironment")), Find_Not(Find_Func("NoWindbagForce")), + Find_Layer(GetObjectLayer()), Find_NoContainer(), Find_Exclude(effect.clonk), Find_PathFree(effect.clonk)); + var dist = 14 + 5 * time / 2; + var rad = 8 + 5 * time / 3; + var cone_x = Sin(effect.angle, dist); + var cone_y = -Cos(effect.angle, dist); + var vx_cone = vx / (2 * time); + var vy_cone = vy / (2 * time); + for (var obj in FindObjects(Find_Distance(rad, cone_x + AbsX(effect.x), cone_y + AbsY(effect.y)), criteria)) + { + var ox = obj->GetXDir(100); + var oy = obj->GetYDir(100); + var vx_cone_reduced = vx_cone / 2 + vx_cone / (2 * Max(1, obj->GetMass() / 4)); + var vy_cone_reduced = vy_cone / 2 + vy_cone / (2 * Max(1, obj->GetMass() / 4)); + obj->SetXDir(ox + vx_cone_reduced, 100); + obj->SetYDir(oy + vy_cone_reduced, 100); + } + return FX_OK; +} -func Definition(def) { - SetProperty("PictureTransformation",Trans_Mul(Trans_Scale(1500),Trans_Rotate(150,0,0,1),Trans_Rotate(-170,1,0,0),Trans_Rotate(10,0,1,0)),def); +public func FxIntBurstWindStop(object target, proplist effect, int reason, bool temp) +{ + if (temp) + return FX_OK; + // Reset the fill amount and start reloading. + fill_amount = 0; + AddEffect("IntReload", target, 100, 1, target); + return FX_OK; +} + + +/*-- Properties --*/ + +protected func Definition(def) +{ + SetProperty("PictureTransformation", Trans_Mul(Trans_Scale(1500), Trans_Rotate(150, 0, 0, 1), Trans_Rotate(-170, 1, 0, 0), Trans_Rotate(10, 0, 1, 0)), def); } local Name = "$Name$"; @@ -174,3 +225,4 @@ local Description = "$Description$"; local UsageHelp = "$UsageHelp$"; local Collectible = 1; local Rebuy = true; +local MaxIntake = 30; diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblDE.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblDE.txt index c3b9f5900..5c9a53cea 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblDE.txt @@ -1,3 +1,5 @@ Name=Windbeutel -Description=Enthält komprimierten Wind der in einem Stoß entfesselt werden kann. -UsageHelp=Ziele und drücke [Benutzen], um einen Windstoß in diese Richtung zu entfesseln. \ No newline at end of file +Description=Enthält komprimierten Wind der in einem Stoß entfesselt werden kann. +UsageHelp=Ziele und drücke [Benutzen], um einen Windstoß in diese Richtung zu entfesseln. + +MsgReloading=Lädt nach! \ No newline at end of file diff --git a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblUS.txt b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblUS.txt index 52d7d7563..f5bb8bd84 100644 --- a/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Items.ocd/Tools.ocd/WindBag.ocd/StringTblUS.txt @@ -1,3 +1,5 @@ Name=Wind bag Description=Contains compressed wind that can be released in one gust. -UsageHelp=Aim and press [Use] to release a gust of wind in the direction specified. \ No newline at end of file +UsageHelp=Aim and press [Use] to release a gust of wind in the direction specified. + +MsgReloading=Reloading! \ No newline at end of file