diff --git a/planet/Arena.ocf/RockBottom.ocs/Script.c b/planet/Arena.ocf/RockBottom.ocs/Script.c index bb579ae49..e389cbee5 100644 --- a/planet/Arena.ocf/RockBottom.ocs/Script.c +++ b/planet/Arena.ocf/RockBottom.ocs/Script.c @@ -35,9 +35,9 @@ protected func Initialize() var waterfall; waterfall = CreateWaterfall(130, 53, 2, "Water"); - waterfall->SetDirection(4, 0, 3, 6); + waterfall->SetDirection(6, 3, 2, 3); waterfall = CreateWaterfall(144, 50, 8, "Water"); - waterfall->SetDirection(6, 0, 5, 6); + waterfall->SetDirection(9, 3, 3, 3); CreateLiquidDrain(100, 315, 10); CreateLiquidDrain(130, 315, 10); CreateLiquidDrain(160, 315, 10); diff --git a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/DefCore.txt b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/DefCore.txt index e7cb7c985..f94bf6347 100644 --- a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/DefCore.txt +++ b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/DefCore.txt @@ -2,3 +2,6 @@ id=Waterfall Version=8,0 Category=C4D_StaticBack +Width=32 +Height=32 +Offset=-16,-16 \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Graphics.png b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Graphics.png new file mode 100644 index 000000000..75508d7aa Binary files /dev/null and b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Script.c b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Script.c index 398e046a9..74bd3a215 100644 --- a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Script.c +++ b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/Script.c @@ -1,82 +1,105 @@ -/*-- +/** Waterfall - Author: Maikel - Waterfall object, use to place waterfalls in the landscape. ---*/ + @author Maikel +*/ -protected func Initialize() -{ - - return; -} /*-- Waterfall --*/ global func CreateWaterfall(int x, int y, int strength, string mat) { - var fall = CreateObjectAbove(Waterfall, x, y, NO_OWNER); - if (!mat) mat = "Water"; - AddEffect("IntWaterfall", fall, 100, 1, fall, nil, x, y, strength, mat); - return fall; + var waterfall = CreateObjectAbove(Waterfall, x, y, NO_OWNER); + if (!mat) + mat = "Water"; + waterfall->CreateEffect(waterfall.FxWaterfallLiquidSource, 100, 1, x, y, strength, mat); + return waterfall; } -protected func FxIntWaterfallStart(object target, proplist effect, int temporary, int x, int y, int strength, string mat) +local FxWaterfallLiquidSource = new Effect { - if (temporary) - return 1; - effect.X = x; - effect.Y = y; - effect.Strength = strength; - effect.Material = mat; - // Start sound. - target->Sound("Environment::Waterfall", false, 5 * effect.Strength, nil, 1); - return 1; -} - -protected func FxIntWaterfallTimer(object target, proplist effect) -{ - // Insert liquid at location every frame. - for (var i = 0; i < effect.Strength / 2; i++) - InsertMaterial(Material(effect.Material), AbsX(effect.X), AbsY(effect.Y), effect.XDir + Random(effect.XVar), effect.YDir + Random(effect.YVar)); - return 1; -} - -protected func FxIntWaterfallStop(object target, proplist effect, bool temporary) -{ - if (temporary) - return 1; - // Stop sound. - target->Sound("Environment::Waterfall", false, 5 * effect.Strength, nil, -1); - return 1; -} + Construction = func(int x, int y, int strength, string mat) + { + this.source_position = [x, y]; + this.source_direction = [x, y]; + this.source_x = x; + this.source_y = y; + this.source_strength = strength; + this.source_mat = mat; + // Start sound. + Target->Sound("Environment::Waterfall", false, 5 * this.source_strength, nil, 1); + return FX_OK; + }, + Timer = func(int time) + { + // Insert liquid at location every frame. + for (var i = 0; i < this.source_strength / 2; i++) + Global->InsertMaterial(Material(this.source_mat), this.source_x, this.source_y, this.xdir + RandomX(-this.xvar, this.xvar), this.ydir + RandomX(-this.yvar, this.yvar)); + return FX_OK; + }, + Destruction = func() + { + // Stop sound. + Target->Sound("Environment::Waterfall", false, 5 * this.source_strength, nil, -1); + return FX_OK; + }, + EditorProps = + { + source_strength = { Name = "$EditorSourceStrength$", EditorHelp = "$EditorSourceStrengthHelp$", Type = "int", Min = 2, Max = 100 }, + source_mat = { Name = "$EditorSourceMaterial$", EditorHelp = "$EditorSourceMaterialHelp$", Type = "enum", Options = [ + { Name = "$EditorSourceMaterialWater$", Value = "Water" }, + { Name = "$EditorSourceMaterialAcid$", Value = "Acid" }, + { Name = "$EditorSourceMaterialLava$", Value = "Lava" }, + { Name = "$EditorSourceMaterialDuroLava$", Value = "DuroLava" }, + { Name = "$EditorSourceMaterialOil$", Value = "Oil" } + ] }, + // TODO: Replace these two properties with an arrow in editor once available. + source_position = { Name = "$EditorSourcePosition$", EditorHelp = "$EditorSourcePositionHelp$", Type = "point", Relative = false, Color = 0x008fff, Set = "SetSourcePosition" }, + source_direction = { Name = "$EditorSourceDirection$", EditorHelp = "$EditorSourceDirectionHelp$", Type = "point", Relative = false, Color = 0x006bbb, Set = "SetSourceDirection" } + }, + SetSourcePosition = func(array pos) + { + this.source_position = pos; + this.source_x = pos[0]; + this.source_y = pos[1]; + }, + SetSourceDirection = func(array dir) + { + this.source_direction = dir; + this.xdir = dir[0] - this.source_x; + this.ydir = dir[1] - this.source_y; + this.xvar = Abs(this.xdir / 2); + this.yvar = Abs(this.ydir / 2); + } +}; public func SetStrength(int strength) { - var effect = GetEffect("IntWaterfall", this); - if (effect) - effect.Strength = BoundBy(strength, 0, 100); + var fx_waterfall = GetEffect("FxWaterfallLiquidSource", this); + if (fx_waterfall) + fx_waterfall.source_strength = BoundBy(strength, 0, 100); return; } public func SetMaterial(int material) { - var effect = GetEffect("IntWaterfall", this); - if (effect) - effect.Material = material; + var fx_waterfall = GetEffect("FxWaterfallLiquidSource", this); + if (fx_waterfall) + fx_waterfall.source_mat = material; return; } public func SetDirection(int xdir, int ydir, int xvar, int yvar) { - var effect = GetEffect("IntWaterfall", this); - if (effect) + var fx_waterfall = GetEffect("FxWaterfallLiquidSource", this); + if (fx_waterfall) { - effect.XDir = xdir; - effect.YDir = ydir; - effect.XVar = xvar; - effect.YVar = yvar; + fx_waterfall.xdir = xdir; + fx_waterfall.ydir = ydir; + fx_waterfall.xvar = xvar; + fx_waterfall.yvar = yvar; + fx_waterfall.source_direction = [fx_waterfall.source_x + xdir, fx_waterfall.source_y + ydir]; } return; } @@ -85,58 +108,100 @@ public func SetSoundLocation(int x, int y) { SetPosition(x, y); // Update sound. - var effect = GetEffect("IntWaterfall", this); - if (effect) - Sound("Environment::Waterfall", false, 5 * effect.Strength, nil, 1); + var fx_waterfall = GetEffect("FxWaterfallLiquidSource", this); + if (fx_waterfall) + Sound("Environment::Waterfall", false, 5 * fx_waterfall.source_strength, nil, 1); return; } -// Scenario saving -func SaveScenarioObject(props) -{ - if (!inherited(props, ...)) return false; - var fx_waterfall = GetEffect("IntWaterfall", this), fx_drain = GetEffect("IntLiquidDrain", this); - if (!fx_waterfall && !fx_drain) return false; // effects lost? don't save dead object then - // Waterfall has its own creation procedure - props->RemoveCreation(); - if (fx_waterfall) - { - props->Add(SAVEOBJ_Creation, "CreateWaterfall(%d, %d, %d, %v)",fx_waterfall.X, fx_waterfall.Y, fx_waterfall.Strength, fx_waterfall.Material); - if (fx_waterfall.X != GetX() || fx_waterfall.Y != GetY()) props->AddCall("Position", this, "SetSoundLocation", GetX(), GetY()); - if (fx_waterfall.XDir || fx_waterfall.YDir || fx_waterfall.XVar || fx_waterfall.YVar) - props->AddCall("Direction", this, "SetDirection", fx_waterfall.XDir, fx_waterfall.YDir, fx_waterfall.XVar, fx_waterfall.YVar); - } - if (fx_drain) props->Add(SAVEOBJ_Creation, "CreateLiquidDrain(%d, %d, %d)",fx_drain.X, fx_drain.Y, fx_drain.Strength); - return true; -} - - /*-- Liquid Drain --*/ global func CreateLiquidDrain(int x, int y, int strength) { var drain = CreateObjectAbove(Waterfall, x, y, NO_OWNER); - AddEffect("IntLiquidDrain", drain, 100, 1, drain, nil, x, y, strength); + drain->CreateEffect(drain.FxWaterfallLiquidDrain, 100, 1, x, y, strength); return drain; } -protected func FxIntLiquidDrainStart(object target, proplist effect, int temporary, int x, int y, int strength) +local FxWaterfallLiquidDrain = new Effect { - if (temporary) - return 1; - effect.X = x; - effect.Y = y; - effect.Strength = strength; - return 1; -} + Construction = func(int x, int y, int strength) + { + this.drain_position = [x, y]; + this.drain_x = x; + this.drain_y = y; + this.drain_strength = strength; + return FX_OK; + }, + Timer = func(int time) + { + Global->ExtractLiquidAmount(this.drain_x, this.drain_y, this.drain_strength / 2); + return FX_OK; + }, + EditorProps = + { + drain_strength = { Name = "$EditorDrainStrength$", EditorHelp = "$EditorDrainStrengthHelp$", Type = "int", Min = 2, Max = 100}, + drain_position = { Name = "$EditorDrainPosition$", EditorHelp = "$EditorDrainPositionHelp$", Type = "point", Relative = false, Color = 0x00ff8f, Set = "SetDrainPosition" } + }, + SetDrainPosition = func(array pos) + { + this.drain_position = pos; + this.drain_x = pos[0]; + this.drain_y = pos[1]; + } +}; -protected func FxIntLiquidDrainTimer(object target, proplist effect) + +/*-- Editor --*/ + +public func EditorInitialize() { - ExtractLiquidAmount(AbsX(effect.X), AbsY(effect.Y),effect.Strength / 2); - return 1; + // Init waterfall with the source directly above the drain. + this->CreateEffect(this.FxWaterfallLiquidSource, 100, 1, GetX(), GetY() - 40, 10, "Water"); + this->CreateEffect(this.FxWaterfallLiquidDrain, 100, 1, GetX(), GetY() + 40, 10); + return; } +/*-- Scenario Saving --*/ + +public func SaveScenarioObject(proplist props) +{ + if (!inherited(props, ...)) + return false; + var fx_source = GetEffect("FxWaterfallLiquidSource", this); + var fx_drain = GetEffect("FxWaterfallLiquidDrain", this); + if (!fx_source && !fx_drain) + return false; + if (fx_source) + { + props->AddCall("SourceEffect", this, "AddSourceEffect", fx_source.source_x, fx_source.source_y, fx_source.source_strength, Format("%v", fx_source.source_mat)); + if (fx_source.source_x != GetX() || fx_source.source_y != GetY()) + props->AddCall("SoundLocation", this, "SetSoundLocation", GetX(), GetY()); + if (fx_source.xdir || fx_source.xdir || fx_source.xvar || fx_source.yvar) + props->AddCall("Direction", this, "SetDirection", fx_source.xdir, fx_source.ydir, fx_source.xvar, fx_source.yvar); + } + if (fx_drain) + props->AddCall("DrainEffect", this, "AddDrainEffect", fx_drain.drain_x, fx_drain.drain_y, fx_drain.drain_strength); + return true; +} + +public func AddSourceEffect(int x, int y, int strength, string mat) +{ + CreateEffect(this.FxWaterfallLiquidSource, 100, 1, x, y, strength, mat); + return; +} + +public func AddDrainEffect(int x, int y, int strength) +{ + CreateEffect(this.FxWaterfallLiquidDrain, 100, 1, x, y, strength); + return; +} + + +/*-- Properties --*/ local Name = "$Name$"; +local Description = "$Description$"; +local Visibility = VIS_Editor; diff --git a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblDE.txt b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblDE.txt index b889168f3..94b7ab14f 100644 --- a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblDE.txt @@ -1 +1,21 @@ Name=Wasserfall +Description=Spawns liquid pixels at a regular interval, place at a cliff to create a waterfall. The waterfall sound is played at the position of this object. + +EditorSourceStrength=Source strength +EditorSourceStrengthHelp=Amount of pixels the sources creates per 2 frames. +EditorSourceMaterial=Source material +EditorSourceMaterialHelp=The type of liquid to create. +EditorSourceMaterialWater=Water +EditorSourceMaterialAcid=Acid +EditorSourceMaterialLava=Lava +EditorSourceMaterialDuroLava=DuroLava +EditorSourceMaterialOil=Oil +EditorSourcePosition=Source position +EditorSourcePositionHelp=Set the position of the source. +EditorSourceDirection=Source direction +EditorSourceDirectionHelp=Set the direction of liquid insertion, relative to the source position. + +EditorDrainStrength=Drain strength +EditorDrainStrengthHelp=Amount of pixels the drain removes per 2 frames. +EditorDrainPosition=Drain position +EditorDrainPositionHelp=Set the position of the drain. \ No newline at end of file diff --git a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblUS.txt b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblUS.txt index 8a8423e80..ced439f21 100644 --- a/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Environment.ocd/Waterfall.ocd/StringTblUS.txt @@ -1 +1,21 @@ Name=Waterfall +Description=Spawns liquid pixels at a regular interval, place at a cliff to create a waterfall. The waterfall sound is played at the position of this object. + +EditorSourceStrength=Source strength +EditorSourceStrengthHelp=Amount of pixels the sources creates per 2 frames. +EditorSourceMaterial=Source material +EditorSourceMaterialHelp=The type of liquid to create. +EditorSourceMaterialWater=Water +EditorSourceMaterialAcid=Acid +EditorSourceMaterialLava=Lava +EditorSourceMaterialDuroLava=DuroLava +EditorSourceMaterialOil=Oil +EditorSourcePosition=Source position +EditorSourcePositionHelp=Set the position of the source. +EditorSourceDirection=Source direction +EditorSourceDirectionHelp=Set the direction of liquid insertion, relative to the source position. + +EditorDrainStrength=Drain strength +EditorDrainStrengthHelp=Amount of pixels the drain removes per 2 frames. +EditorDrainPosition=Drain position +EditorDrainPositionHelp=Set the position of the drain. \ No newline at end of file diff --git a/planet/Tutorials.ocf/Tutorial01.ocs/Script.c b/planet/Tutorials.ocf/Tutorial01.ocs/Script.c index ade7ffd58..8e52d4077 100644 --- a/planet/Tutorials.ocf/Tutorial01.ocs/Script.c +++ b/planet/Tutorials.ocf/Tutorial01.ocs/Script.c @@ -92,9 +92,9 @@ private func InitCaveEntrance() trunk.MeshTransformation = [-70, 0, 998, 0, 0, 1000, 0, 0, -998, 0, -70, 0]; var waterfall; waterfall = CreateWaterfall(325, 448, 2, "Water"); - waterfall->SetDirection(2, 0, 3, 6); + waterfall->SetDirection(3, 3, 1, 3); waterfall = CreateWaterfall(338, 450, 8, "Water"); - waterfall->SetDirection(1, 0, 4, 8); + waterfall->SetDirection(3, 4, 2, 4); CreateLiquidDrain(160, 648, 10); CreateLiquidDrain(184, 648, 10); CreateLiquidDrain(208, 648, 10); diff --git a/planet/Worlds.ocf/Chine.ocs/Script.c b/planet/Worlds.ocf/Chine.ocs/Script.c index 773c61510..42b66f91a 100644 --- a/planet/Worlds.ocf/Chine.ocs/Script.c +++ b/planet/Worlds.ocf/Chine.ocs/Script.c @@ -144,7 +144,7 @@ private func InitEnvironment(int map_size, int difficulty) for (var i = 0; i < 16 + 4 * difficulty; i++) { var fall = CreateWaterfall(waterfall_x + 2, 0, RandomX(3, 4), "Water"); - fall->SetDirection(RandomX(10, 12), 8, 8, 8); + fall->SetDirection(RandomX(14, 16), 12, 4, 4); fall->SetSoundLocation(LandscapeWidth() / 2, Random(LandscapeHeight())); } var trunk = CreateObjectAbove(Trunk, waterfall_x + 2, 20); diff --git a/planet/Worlds.ocf/RapidRefining.ocs/Script.c b/planet/Worlds.ocf/RapidRefining.ocs/Script.c index d1fa12ee2..30c3a5685 100644 --- a/planet/Worlds.ocf/RapidRefining.ocs/Script.c +++ b/planet/Worlds.ocf/RapidRefining.ocs/Script.c @@ -156,7 +156,7 @@ private func InitEnvironment(int difficulty) trunk->MakeInvincible(); var waterfall = CreateWaterfall(waterfall_x + 22, waterfall_y - 10, 10, "Water"); - waterfall->SetDirection(2, 0, 3, 6); + waterfall->SetDirection(3, 3, 2, 3); waterfall->SetSoundLocation(waterfall_x + 40, waterfall_y + 240); CreateLiquidDrain(8, 1040, 10);