- added high level interface to the new properties, i.e. UDMF and ZScript.

This commit is contained in:
Christoph Oelckers 2019-12-20 18:02:42 +01:00
parent 3209d4ed23
commit 3a249cb06f
11 changed files with 447 additions and 10 deletions

View file

@ -200,13 +200,32 @@ Note: All <bool> fields default to false unless mentioned otherwise.
useowncolors_bottom = <bool>; // Set to 1 to use the colors set in the sidedef. Default is using the colors from the owning sector.
uppercolor_bottom = <int>; // Material color of the top of the lower tier.
lowercolor_bottom = <int>; // Material color of the bottom of the lower tier. (Hardware rendering only.)
colorscalefactor_top = <float> // scales the material color by the given factor. Default is 1.
colorscalefactor_mid = <float> // scales the material color by the given factor. Default is 1.
colorscalefactor_bottom = <float> // scales the material color by the given factor. Default is 1.
useowncoloradd_top = <bool>; // Whether or not to use the given additive color for the top section of the sidedef.
useowncoloradd_top = <bool>; // Controls where the advanced colorization properties are taken from.
useowncoloradd_mid = <bool>; // 0: From the containing sector, 1: from the given part of the linedef itself
useowncoloradd_bottom = <bool>; // Default for all 3 is 0.
// Note: All following properties are subject to the 'useowncoloradd' flag for the given wall tier.
coloradd_top = <int>; // Additive material color to apply to top section of sidedef. Default is black (0x000000)
useowncoloradd_mid = <bool>; // Whether or not to use the given additive color for the middle section of the sidedef.
coloradd_mid = <int>; // Additive material color to apply to middle section of sidedef. Default is black (0x000000)
useowncoloradd_bottom = <bool>; // Whether or not to use the given additive color for the bottom section of the sidedef.
coloradd_bottom = <int>; // Additive material color to apply to bottom section of sidedef. Default is black (0x000000)
colorblend_top = <int> // Blended material color to apply to top section of sidedef. Default is black (0x000000) Only active if a blend mode is set to non-0.
colorblend_mid = <int> // Blended material color to apply to middle section of sidedef. Default is black (0x000000) Only active if a blend mode is set to non-0.
colorblend_bottom = <int> // Blended material color to apply to bottom section of sidedef. Default is black (0x000000) Only active if a blend mode is set to non-0.
blendmode_top = <int> // Controls how the blend is applied. 0: off; 1: Blend by alpha of the blend color.
blendmode_mid = <int> // 2, 3 and 4 are modes taken from Build engine games, called "Screen", "Overlay" and "Hardlight"
blendmode_bottom = <int> // Default is 0 (off)
desaturationfactor_top = <float> // Desaturates the texture by the given amount. Default is 0, 1 is fully desaturated.
desaturationfactor_mid = <float> // Out-of-range values are explicitly supported. (e.g. negative factors will oversaturate the texture color.)
desaturationfactor_bottom = <float>
inverttexture_top = <bool> // Inverts the texture color. Default is off. This operation occurs after desaturation but before other color manipulations.
inverttexture_mid = <bool>
inverttexture_bottom = <bool>
}
sector
@ -285,6 +304,19 @@ Note: All <bool> fields default to false unless mentioned otherwise.
coloradd_sprites = <int>; // Additive material color applied to sprites within the sector. Default is black (0x000000)
coloradd_walls = <int>; // Additive material color applied to walls within the sector. Default is black (0x000000)
colorblend_floor = <int> // Blended material color to apply to the floor. Default is black (0x000000) Only active if a blend mode is set to non-0.
colorblend_ceiling = <int> // Blended material color to apply to the ceiling. Default is black (0x000000) Only active if a blend mode is set to non-0.
colorblend_walls = <int> // Blended material color to apply to walls. Default is black (0x000000) Only active if a blend mode is set to non-0.
blendmode_floor = <int> // Controls how the blend is applied. 0: off; 1: Blend by alpha of the blend color.
blendmode_ceiling = <int> // 2, 3 and 4 are modes taken from Build engine games, called "Screen", "Overlay" and "Hardlight"
blendmode_walls = <int> // Default is 0 (off)
desaturationfactor_floor = <float> // Desaturates the texture by the given amount. Default is 0, 1 is fully desaturated.
desaturationfactor_ceiling = <float> // Out-of-range values are explicitly supported. (e.g. negative factors will oversaturate the texture color.)
desaturationfactor_walls = <float>
inverttexture_floor = <bool> // Inverts the texture color. Default is off. This operation occurs after desaturation but before other color manipulations.
inverttexture_ceiling = <bool>
inverttexture_walls = <bool>
portal_ceil_blocksound = <bool>; // ceiling portal blocks sound.
portal_ceil_disabled = <bool>; // ceiling portal disabled.
portal_ceil_nopass = <bool>; // ceiling portal blocks movement if true.
@ -492,6 +524,9 @@ arg0str in dynamic lights.
Added automapstyle and revealed linedef properties.
Replaced tabs with spaces.
1.31 20.12.2019
Added more color manipulation options for sectors and linedefs
===============================================================================
EOF
===============================================================================

View file

@ -663,6 +663,12 @@ struct sector_t
PalEntry SpecialColors[5]; // Doom64 style colors
PalEntry AdditiveColors[5];
PalEntry BlendColors[3];
float ColorScaleFactor[3];
float MaterialDesaturationFactor[3]; // Unlike desaturated light this only affects the texture, nothing else.
uint8_t BlendModes[3];
uint8_t InvertModes;
FColormap Colormap; // Sector's own color/fog info.
short special; // map-defined sector special type
@ -1044,6 +1050,37 @@ public:
AdditiveColors[slot] = rgb;
}
void SetBlendColor(int slot, PalEntry rgb)
{
BlendColors[slot] = rgb;
}
void SetColorScaleFactor(int slot, double fac)
{
ColorScaleFactor[slot] = (float)fac;
}
void SetDesaturationFactor(int slot, double fac)
{
MaterialDesaturationFactor[slot] = (float)fac;
}
void SetBlendMode(int slot, int mode)
{
BlendModes[slot] = mode;
}
void SetInvertMode(int num, bool on)
{
if (on) InvertModes |= (1 << num);
else InvertModes &= ~(1 << num);
}
bool InvertMode(int num) const
{
return !!(InvertModes & (1 << num));
}
inline bool PortalBlocksView(int plane);
inline bool PortalBlocksSight(int plane);
inline bool PortalBlocksMovement(int plane);
@ -1153,6 +1190,8 @@ struct side_t
ClampGradient = 4,
UseOwnSpecialColors = 8,
UseOwnAdditiveColor = 16,
InvertedTexture = 32,
BlendBits = 64 + 128 + 256, // 4 blend modes plus off value means 5 possible values, so 3 bits are needed.
};
double xOffset;
double yOffset;
@ -1163,6 +1202,10 @@ struct side_t
int flags;
PalEntry SpecialColors[2];
PalEntry AdditiveColor;
PalEntry BlendColor;
float ColorScaleFactor;
float MaterialDesaturationFactor; // Unlike desaturated light this only affects the texture, nothing else.
void InitFrom(const part &other)
{
@ -1172,6 +1215,7 @@ struct side_t
if (1.0 == xScale && 0.0 != other.xScale) xScale = other.xScale;
if (1.0 == yScale && 0.0 != other.yScale) yScale = other.yScale;
}
};
sector_t* sector; // Sector the SideDef is facing.
@ -1333,6 +1377,32 @@ struct side_t
textures[which].AdditiveColor = rgb;
}
void SetBlendColor(int which, PalEntry rgb)
{
textures[which].BlendColor = rgb;
}
void SetDesaturationFactor(int which, double factor)
{
textures[which].MaterialDesaturationFactor = (float)factor;
}
void SetColorScaleFactor(int which, double factor)
{
textures[which].ColorScaleFactor = (float)factor;
}
void SetBlendMode(int which, int mode)
{
textures[which].flags &= ~part::BlendBits;
textures[which].flags |= (mode << 6) & part::BlendBits;
}
void SetInvertMode(int which, bool on)
{
if (on) textures[which].flags |= part::InvertedTexture;
else textures[which].flags &= ~part::InvertedTexture;
}
PalEntry GetAdditiveColor(int which, sector_t *frontsector) const
{
if (textures[which].flags & part::UseOwnAdditiveColor) {
@ -1344,6 +1414,63 @@ struct side_t
}
}
PalEntry GetBlendColor(int which, sector_t* frontsector) const
{
if (textures[which].flags & part::UseOwnAdditiveColor) {
return textures[which].BlendColor;
}
else
{
return frontsector->BlendColors[sector_t::walltop];
}
}
float GetDesaturationFactor(int which, sector_t* frontsector) const
{
if (textures[which].flags & part::UseOwnAdditiveColor) {
return textures[which].MaterialDesaturationFactor;
}
else
{
return frontsector->MaterialDesaturationFactor[sector_t::walltop];
}
}
float GetColorScaleFactor(int which, sector_t* frontsector) const
{
if (textures[which].flags & part::UseOwnAdditiveColor) {
return textures[which].ColorScaleFactor;
}
else
{
return frontsector->ColorScaleFactor[sector_t::walltop];
}
}
int GetBlendMode(int which, sector_t *frontsector) const
{
if (textures[which].flags & part::UseOwnAdditiveColor)
{
return (textures[which].flags & part::BlendBits) >> 6;
}
else
{
return frontsector->BlendModes[sector_t::walltop];
}
}
bool GetInvertMode(int which, sector_t* frontsector) const
{
if (textures[which].flags & part::UseOwnAdditiveColor)
{
return !!(textures[which].flags & part::InvertedTexture);
}
else
{
return !!(frontsector->InvertModes & (1<<sector_t::walltop));
}
}
DInterpolation *SetInterpolation(int position);
void StopInterpolation(int position);

View file

@ -1379,14 +1379,77 @@ public:
sd->SetAdditiveColor(side_t::bottom, CheckInt(key));
break;
case NAME_colorblend_top:
sd->SetBlendColor(side_t::top, CheckInt(key));
break;
case NAME_colorblend_mid:
sd->SetBlendColor(side_t::mid, CheckInt(key));
break;
case NAME_colorblend_bottom:
sd->SetBlendColor(side_t::bottom, CheckInt(key));
break;
case NAME_desaturationfactor_top:
sd->SetDesaturationFactor(side_t::top, CheckFloat(key));
break;
case NAME_desaturationfactor_mid:
sd->SetDesaturationFactor(side_t::mid, CheckFloat(key));
break;
case NAME_desaturationfactor_bottom:
sd->SetDesaturationFactor(side_t::bottom, CheckFloat(key));
break;
case NAME_colorscalefactor_top:
sd->SetColorScaleFactor(side_t::top, CheckFloat(key));
break;
case NAME_colorscalefactor_mid:
sd->SetColorScaleFactor(side_t::mid, CheckFloat(key));
break;
case NAME_colorscalefactor_bottom:
sd->SetColorScaleFactor(side_t::bottom, CheckFloat(key));
break;
case NAME_blendmode_top:
sd->SetColorScaleFactor(side_t::top, CheckInt(key));
break;
case NAME_blendmode_mid:
sd->SetColorScaleFactor(side_t::mid, CheckInt(key));
break;
case NAME_blendmode_bottom:
sd->SetColorScaleFactor(side_t::bottom, CheckInt(key));
break;
case NAME_inverttexture_top:
sd->SetInvertMode(side_t::top, CheckBool(key));
break;
case NAME_inverttexture_mid:
sd->SetInvertMode(side_t::mid, CheckBool(key));
break;
case NAME_inverttexture_bottom:
sd->SetInvertMode(side_t::bottom, CheckBool(key));
break;
case NAME_useowncoloradd_top:
sd->textures[side_t::top].flags |= side_t::part::UseOwnAdditiveColor * CheckBool(key);
break;
case NAME_useowncoloradd_mid:
sd->textures[side_t::mid].flags |= side_t::part::UseOwnAdditiveColor * CheckBool(key);
break;
case NAME_useowncoloradd_bottom:
sd->textures[side_t::bottom].flags |= side_t::part::UseOwnAdditiveColor * CheckBool(key);
break;
default:
break;
@ -1642,6 +1705,67 @@ public:
sec->AdditiveColors[sector_t::sprites] = CheckInt(key) | 0xff000000;
break;
case NAME_colorblend_floor:
sec->SetBlendColor(sector_t::floor, CheckInt(key));
break;
case NAME_colorblend_ceiling:
sec->SetBlendColor(sector_t::ceiling, CheckInt(key));
break;
case NAME_colorblend_walls:
sec->SetBlendColor(sector_t::walltop, CheckInt(key));
break;
case NAME_desaturationfactor_floor:
sec->SetDesaturationFactor(sector_t::floor, CheckFloat(key));
break;
case NAME_desaturationfactor_ceiling:
sec->SetDesaturationFactor(sector_t::ceiling, CheckFloat(key));
break;
case NAME_desaturationfactor_walls:
sec->SetDesaturationFactor(sector_t::walltop, CheckFloat(key));
break;
case NAME_colorscalefactor_floor:
sec->SetColorScaleFactor(sector_t::floor, CheckFloat(key));
break;
case NAME_colorscalefactor_ceiling:
sec->SetColorScaleFactor(sector_t::ceiling, CheckFloat(key));
break;
case NAME_colorscalefactor_walls:
sec->SetColorScaleFactor(sector_t::walltop, CheckFloat(key));
break;
case NAME_blendmode_floor:
sec->SetColorScaleFactor(sector_t::floor, CheckInt(key));
break;
case NAME_blendmode_ceiling:
sec->SetColorScaleFactor(sector_t::ceiling, CheckInt(key));
break;
case NAME_blendmode_walls:
sec->SetColorScaleFactor(sector_t::walltop, CheckInt(key));
break;
case NAME_inverttexture_floor:
sec->SetInvertMode(sector_t::floor, CheckBool(key));
break;
case NAME_inverttexture_ceiling:
sec->SetInvertMode(sector_t::ceiling, CheckBool(key));
break;
case NAME_inverttexture_walls:
sec->SetInvertMode(sector_t::walltop, CheckBool(key));
break;
case NAME_Desaturation:
desaturation = int(255*CheckFloat(key) + FLT_EPSILON); // FLT_EPSILON to avoid rounding errors with numbers slightly below a full integer.
continue;

View file

@ -114,6 +114,9 @@ FSerializer &Serialize(FSerializer &arc, const char *key, side_t::part &part, si
("color1", part.SpecialColors[0], def->SpecialColors[0])
("color2", part.SpecialColors[1], def->SpecialColors[1])
("addcolor", part.AdditiveColor, def->AdditiveColor)
("blendcolor", part.BlendColor, def->BlendColor)
("colorscalefactor", part.ColorScaleFactor, def->ColorScaleFactor)
("desaturationfactor", part.MaterialDesaturationFactor, def->MaterialDesaturationFactor)
.EndObject();
}
return arc;
@ -296,6 +299,11 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sector_t &p, sector_t
("colormap", p.Colormap, def->Colormap)
.Array("specialcolors", p.SpecialColors, def->SpecialColors, 5, true)
.Array("additivecolors", p.AdditiveColors, def->AdditiveColors, 5, true)
.Array("blendcolors", p.BlendColors, def->BlendColors, 3, true)
.Array("colorscalefactors", p.ColorScaleFactor, def->ColorScaleFactor, 3, true)
.Array("desaturationfactors", p.MaterialDesaturationFactor, def->MaterialDesaturationFactor, 3, true)
.Array("blendmodes", p.BlendModes, def->BlendModes, 3, true)
("invertmodes", p.InvertModes, def->InvertModes)
("gravity", p.gravity, def->gravity)
.Terrain("floorterrain", p.terrainnum[0], &def->terrainnum[0])
.Terrain("ceilingterrain", p.terrainnum[1], &def->terrainnum[1])

View file

@ -359,6 +359,11 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
state.SetObjectColor(0xffffffff);
}
state.SetAddColor(0);
state.SetBlendColor(0);
state.SetObjectDesaturateFactor(0);
state.SetObjectBlendMode(0);
state.SetObjectInvert(false);
state.SetColorizeFactor(1);
}
//==========================================================================

View file

@ -297,6 +297,11 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
state.SetObjectColor(0xffffffff);
state.SetAddColor(0);
state.SetBlendColor(0);
state.SetObjectDesaturateFactor(0);
state.SetObjectBlendMode(0);
state.SetObjectInvert(false);
state.SetColorizeFactor(1);
state.EnableTexture(true);
state.SetDynLight(0, 0, 0);
}

View file

@ -247,6 +247,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
state.SetObjectDesaturateFactor(0);
state.SetObjectInvert(false);
state.SetObjectBlendMode(0);
state.SetColorizeFactor(1);
}
//==========================================================================

View file

@ -103,6 +103,11 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state)
state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
state.SetObjectColor(0xffffffff);
state.SetAddColor(0);
state.SetBlendColor(0);
state.SetObjectDesaturateFactor(0);
state.SetObjectBlendMode(0);
state.SetObjectInvert(false);
state.SetColorizeFactor(1);
state.SetDynLight(0, 0, 0);
state.EnableBrightmap(false);
}

View file

@ -618,11 +618,12 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetFade, SetFade)
return 0;
}
static void SetSpecialColor(sector_t *self, int num, int color)
static void SetSpecialColor(sector_t *self, int num, int color, double factor)
{
if (num >= 0 && num < 5)
{
self->SetSpecialColor(num, color);
self->SetColorScaleFactor(num, factor);
}
}
@ -631,7 +632,8 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetSpecialColor, SetSpecialColor)
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
PARAM_INT(num);
PARAM_COLOR(color);
SetSpecialColor(self, num, color);
PARAM_FLOAT(factor)
SetSpecialColor(self, num, color, factor);
return 0;
}
@ -652,6 +654,45 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetAdditiveColor, SetAdditiveColor)
return 0;
}
static void SetBlendColor(sector_t* self, int pos, int color, int mode)
{
if (pos >= 0 && pos < 3)
{
self->SetBlendColor(pos, color);
self->SetBlendMode(pos, mode);
}
}
DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetBlendColor, SetBlendColor)
{
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
PARAM_INT(pos);
PARAM_COLOR(color);
PARAM_INT(mode);
SetBlendColor(self, pos, color, mode);
return 0;
}
static void SetTextureDesaturation(sector_t* self, int pos, double factor, int invert)
{
if (pos >= 0 && pos < 3)
{
self->SetDesaturationFactor(pos, factor);
self->SetInvertMode(pos, !!invert);
}
}
DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetTextureDesaturation, SetTextureDesaturation)
{
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
PARAM_INT(pos);
PARAM_FLOAT(factor);
PARAM_BOOL(invert);
SetTextureDesaturation(self, pos, factor, invert);
return 0;
}
static void SetFogDensity(sector_t *self, int dens)
{
self->Colormap.FogDensity = dens;
@ -1680,11 +1721,12 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetXOffset, SetXOffset)
ACTION_RETURN_POINTER(self->V2());
}
static void SetSideSpecialColor(side_t *self, int tier, int position, int color)
static void SetSideSpecialColor(side_t *self, int tier, int position, int color, double factor)
{
if (tier >= 0 && tier < 3 && position >= 0 && position < 2)
{
self->SetSpecialColor(tier, position, color);
if (position == 0) self->SetColorScaleFactor(tier, factor);
}
}
@ -1694,7 +1736,8 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetXOffset, SetXOffset)
PARAM_INT(tier);
PARAM_INT(position);
PARAM_COLOR(color);
SetSideSpecialColor(self, tier, position, color);
PARAM_FLOAT(factor)
SetSideSpecialColor(self, tier, position, color, factor);
return 0;
}
@ -1732,6 +1775,45 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetXOffset, SetXOffset)
return 0;
}
static void SetSideBlendColor(side_t* self, int tier, int color, int mode)
{
if (tier >= 0 && tier < 3)
{
self->SetBlendColor(tier, color);
self->SetBlendMode(tier, mode);
}
}
DEFINE_ACTION_FUNCTION_NATIVE(_Side, SetBlendColor, SetSideBlendColor)
{
PARAM_SELF_STRUCT_PROLOGUE(side_t);
PARAM_INT(tier);
PARAM_COLOR(color);
PARAM_INT(mode);
SetSideBlendColor(self, tier, color, mode);
return 0;
}
static void SetSideTextureDesaturation(side_t* self, int tier, double factor, int invert)
{
if (tier >= 0 && tier < 3)
{
self->SetDesaturationFactor(tier, factor);
self->SetInvertMode(tier, !!invert);
}
}
DEFINE_ACTION_FUNCTION_NATIVE(_Side, SetTextureDesaturation, SetSideTextureDesaturation)
{
PARAM_SELF_STRUCT_PROLOGUE(side_t);
PARAM_INT(tier);
PARAM_FLOAT(factor);
PARAM_BOOL(invert);
SetSideTextureDesaturation(self, tier, factor, invert);
return 0;
}
static void EnableSideAdditiveColor(side_t *self, int tier, bool enable)
{
if (tier >= 0 && tier < 3)

View file

@ -671,6 +671,39 @@ xx(useowncoloradd_mid)
xx(coloradd_mid)
xx(useowncoloradd_bottom)
xx(coloradd_bottom)
xx(colorblend_top)
xx(colorblend_mid)
xx(colorblend_bottom)
xx(desaturationfactor_top)
xx(desaturationfactor_mid)
xx(desaturationfactor_bottom)
xx(colorscalefactor_top)
xx(colorscalefactor_mid)
xx(colorscalefactor_bottom)
xx(blendmode_top)
xx(blendmode_mid)
xx(blendmode_bottom)
xx(inverttexture_top)
xx(inverttexture_mid)
xx(inverttexture_bottom)
xx(colorblend_floor)
xx(colorblend_ceiling)
xx(colorblend_walls)
xx(desaturationfactor_floor)
xx(desaturationfactor_ceiling)
xx(desaturationfactor_walls)
xx(colorscalefactor_floor)
xx(colorscalefactor_ceiling)
xx(colorscalefactor_walls)
xx(blendmode_floor)
xx(blendmode_ceiling)
xx(blendmode_walls)
xx(inverttexture_floor)
xx(inverttexture_ceiling)
xx(inverttexture_walls)
xx(Renderstyle)

View file

@ -1,4 +1,12 @@
enum BlendModes
{
BLEND_Off = 0,
BLEND_Alpha,
BLEND_Screen,
BLEND_Overlay,
BLEND_Hardlight
}
struct SectorPortal native play
{
enum EType
@ -83,10 +91,12 @@ struct Side native play
native void SetTextureYScale(int which, double scale);
native double GetTextureYScale(int which);
native void MultiplyTextureYScale(int which, double delta);
native void SetSpecialColor(int tier, int position, Color scolor);
native void SetSpecialColor(int tier, int position, Color scolor, double factor = 1.0);
native Color GetAdditiveColor(int tier);
native void SetAdditiveColor(int tier, Color color);
native void EnableAdditiveColor(int tier, bool enable);
native void SetBlendColor(int tier, Color color, int mode);
native void SetTextureDesaturation(int tier, double factor, bool invert = false);
//native DInterpolation *SetInterpolation(int position);
//native void StopInterpolation(int position);
@ -467,8 +477,10 @@ struct Sector native play
native color GetGlowColor(int pos);
native void SetGlowHeight(int pos, double height);
native void SetGlowColor(int pos, color color);
native void SetSpecialColor(int pos, color color);
native void SetSpecialColor(int pos, color color, float factor = 1.0);
native void SetAdditiveColor(int pos, Color color);
native void SetBlendColor(int pos, Color color, int mode);
native void SetTextureDesaturation(int pos, double factor, bool invert = false);
native TextureID GetTexture(int pos);
native void SetTexture(int pos, TextureID tex, bool floorclip = true);