Add editor props and user actions for boiling lava and acid

Also optimize the timer
console-destruction
Sven Eberhardt 2016-09-06 00:06:37 -04:00
parent 6aeeff0545
commit 282a561462
11 changed files with 142 additions and 28 deletions

View File

@ -1,8 +1,7 @@
[DefCore]
id=BoilingAcid
Version=5,2,0,1
Category=C4D_StaticBack
Width=1
Height=1
Offset=0,0
Version=8,0
Category=C4D_StaticBack|C4D_Environment
Width=32
Height=32
Offset=-16,-16

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,5 +1,5 @@
/**
BoilingMagma
BoilingAcid
Causes Acid on the map to bubble
@author
@ -11,15 +11,16 @@ local Name = "$Name$";
local Description = "$Description$";
// Magic number by which the total map size (in pixels) is divided to get the amount of tries per frame.
local intensity_quotient = 50000;
local intensity_quotient = 2500;
private func Boiling()
{
for (var i = 0; i < intensity; i++)
{
// Checks if there is a deep enough pool of acid at a random location of the map, then creates spawner at a random depth into the pool
var x_rand = Random(LandscapeWidth());
var y_rand = Random(LandscapeHeight());
area->GetRandomPoint(last_boilpos);
var x_rand = last_boilpos.x - GetX();
var y_rand = last_boilpos.y - GetY();
var mat = MaterialName(GetMaterial(x_rand, y_rand));
var random_depth = RandomX(30, 100);
var depth_check_mat = MaterialName(GetMaterial(x_rand, y_rand + random_depth));
@ -36,3 +37,9 @@ private func Boiling()
}
}
}
public func Definition(def, ...)
{
_inherited(def, ...);
def.EditorProps.area.Options[1].Delegate.Color=0x30ff30;
}

View File

@ -1,2 +1,2 @@
Name=BoilingMagma
Description=Causes Lava on the map to boil
Name=Kochende Säure
Description=Lässt Säure auf der Karte kochen.

View File

@ -1,2 +1,2 @@
Name=BoilingMagma
Description=Causes Lava on the map to boil
Name=Boiling acid
Description=Causes acid on the map to boil.

View File

@ -1,4 +1,7 @@
[DefCore]
id=BoilingLava
Version=6,0
Version=8,0
Category=C4D_StaticBack|C4D_Environment
Width=32
Height=32
Offset=-16,-16

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -11,6 +11,9 @@ local Description = "$Description$";
local intensity;
// Magic number by which the total map size (in pixels) is divided to get the amount of tries per frame.
local intensity_quotient = 10000;
local area, last_boilpos;
public func IsBoilingLiquid() { return true; }
public func Place(int amount)
{
@ -24,15 +27,25 @@ public func Place(int amount)
public func Construction()
{
SetPosition(0, 0);
intensity = GetDefaultIntensity();
if (intensity <= 0) intensity = 1;
AddTimer("Boiling", 1);
area = Shape->Rectangle(0, 0, LandscapeWidth(), LandscapeHeight());
last_boilpos = {};
SetIntensity();
}
public func SetArea(to_area)
{
var has_default_intensity = (intensity == GetDefaultIntensity());
this.area = to_area;
if (has_default_intensity) SetIntensity();
return true;
}
private func GetDefaultIntensity()
{
return (LandscapeWidth() * LandscapeHeight()) / this.intensity_quotient;
var barea = area->GetBoundingRectangle();
var def_int = (barea.wdt * barea.hgt) / this.intensity_quotient;
if (!def_int) ++def_int;
return def_int;
}
private func Boiling()
@ -40,19 +53,29 @@ private func Boiling()
for(var i = 0; i < intensity; i++)
{
// Checks if there is a deep enough pool of lava at a random location of the map, then creates spawner on the surface
var x_rand = Random(LandscapeWidth());
var y_rand = Random(LandscapeHeight());
var mat = MaterialName(GetMaterial(x_rand, y_rand));
var above_mat = MaterialName(GetMaterial(x_rand, y_rand - 1));
var depth_check_math = MaterialName(GetMaterial(x_rand, y_rand + 30));
area->GetRandomPoint(last_boilpos);
var x_rand = last_boilpos.x - GetX();
var y_rand = last_boilpos.y - GetY();
var mat = MaterialName(GetMaterial(x_rand, y_rand)), above_mat;
if (mat == "DuroLava" || mat == "Lava")
if (above_mat == nil || above_mat == "Tunnel")
{
for (var dy = 0; dy < 20; ++dy)
{
--y_rand;
if ((above_mat = MaterialName(GetMaterial(x_rand, --y_rand))) != mat) break;
}
if (!above_mat || above_mat == "Tunnel")
{
var depth_check_math = MaterialName(GetMaterial(x_rand, y_rand + 30));
if (depth_check_math == "DuroLava" || depth_check_math == "Lava")
{
if (PathFree(x_rand, y_rand, x_rand, y_rand + 30))
{
CreateObject(BoilingLava_Spawner, x_rand, y_rand);
}
}
}
}
}
}
@ -62,6 +85,8 @@ private func Boiling()
public func SetIntensity(int intensity)
{
this.intensity = intensity ?? GetDefaultIntensity();
RemoveTimer("Boiling");
if (this.intensity) AddTimer("Boiling", 20);
return true;
}
@ -71,5 +96,59 @@ public func SaveScenarioObject(props, ...)
if (!_inherited(props, ...)) return false;
if (this.intensity != GetDefaultIntensity())
props->AddCall("Intensity", this, "SetIntensity", this.intensity);
if (!this.area->~IsFullMap())
props->AddCall("Area", this, "SetArea", this.area);
return true;
}
/* Editor */
private func GetDefaultArea(boiler, def_val)
{
// Default area is whole map
return Shape->Rectangle(LandscapeWidth()/3, LandscapeHeight()/3, LandscapeWidth()/3, LandscapeHeight()/3);
}
private func SetAreaRect(to_rect)
{
// Editor sets properties only; convert to rectangle.
if (to_rect)
to_rect = Shape->Rectangle(to_rect.x, to_rect.y, to_rect.wdt, to_rect.hgt);
else
to_rect = GetDefaultArea();
return SetArea(to_rect);
}
private func GetAreaRect()
{
// Editor sets properties only; convert to rectangle.
if (!area->IsFullMap()) return area;
}
public func Definition(def, ...)
{
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.intensity = { Name="$Intensity$", EditorHelp="$IntensityHelp$", Type="int", Min=0, Set="SetIntensity" };
def.EditorProps.area = { Name="$Area$", EditorHelp="$AreaHelp$", Type="enum", AsyncGet="GetAreaRect", Set="SetAreaRect", Save="Area", Options = [
{ Name="$FullMap$" },
{ Name="$Rect$", OptionKey="Type", DefaultValueFunction=def.GetDefaultArea, Value={ Type="rect" }, Delegate={ Type="rect", Relative=false, Storage="proplist", Color=0xffa020, Set="SetAreaRect" } }
// other shapes not supported for now
] };
if (def == BoilingLava)
{
UserAction->AddEvaluator("Action", "Ambience", "$SetBoilingIntensity$", "$SetBoilingIntensityHelp$", "set_boiling_intensity", [def, def.EvalAct_SetBoilingIntensity], { Intensity={ Function="int_constant", Value=0 } },
{ Type="proplist", Display="{{Boiler}}, {{Intensity}}", EditorProps = {
Boiler = UserAction->GetObjectEvaluator("IsBoilingLiquid", "$Boiler$", "$BoilerTargetHelp$"),
Intensity = new UserAction.Evaluator.Integer { Name="$Intensity$", EditorHelp="$IntensityHelp$" },
} } );
}
return _inherited(def, ...);
}
private func EvalAct_SetBoilingIntensity(props, context)
{
var boiler = UserAction->EvaluateValue("Boiler", props.Boiler, context);
var intensity = Max(UserAction->EvaluateValue("Integer", props.Intensity, context));
if (boiler) boiler->~SetIntensity(intensity);
}

View File

@ -1,2 +1,12 @@
Name=Kochende Lava
Description=Lässt die Lava auf der Karte brodeln
Intensity=Intensität
IntensityHelp=Wie viele Blasen pro Frame erzeugt werden. Bei 0 ist das Brodeln deaktiviert.
Area=Gebiet
AreaHelp=In welchem Gebiet Blasen erzeugt werden.
FullMap=Ganze Karte
Rect=Rechteck
SetBoilingIntensity=Brodel-Intensität setzen
SetBoilingIntensityHelp=Setzt die Intensität eines Kochende Lava/Säure-Objektes
Boiler=Kochende Fluessigkeit-Objekt
BoilerTargetHelp=Das geänderte 'Kochende Lava' / 'Kochende Säure' Objekt.

View File

@ -1,2 +1,12 @@
Name=Boiling Lava
Description=Causes Lava on the map to boil
Intensity=Intensity
IntensityHelp=How many bubbles are created per frame. 0 deactivates the boiling.
Area=Aea
AreaHelp=In which area bubbles are created.
FullMap=Full map
Rect=Rectangle
SetBoilingIntensity=Set boiling intensity
SetBoilingIntensityHelp=Sets the intensity of a boiling lava / acid object.
Boiler=Boiler object
BoilerTargetHelp=The modified 'Boiling Lava' / 'Boiling Acid' object.

View File

@ -49,6 +49,11 @@ private func BaseRectangle_ToString()
return Format("Shape->Rectangle(%d, %d, %d, %d)", this.x, this.y, this.wdt, this.hgt);
}
private func BaseRectangle_IsFullMap()
{
return !this.x && !this.y && this.wdt == LandscapeWidth() && this.hgt == LandscapeHeight();
}
/** Constructor of rectangle area. (x,y) is included; (x+w,y+h) is excluded.
@par x Global left side of rectangle
@par y Global top side of rectangle
@ -319,7 +324,8 @@ public func Definition(def)
GetRandomPoint = Shape.BaseRectangle_GetRandomPoint,
Find_In = Shape.BaseRectangle_Find_In,
Find_At = Shape.BaseRectangle_Find_At,
ToString = Shape.BaseRectangle_ToString
ToString = Shape.BaseRectangle_ToString,
IsFullMap = Shape.BaseRectangle_IsFullMap
};
BaseCircle = new BaseShape
{