mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-25 13:21:28 +00:00
Added, Visual mode: "Raise/Lower Floor/Ceiling to adjacent Sector" actions now take surrounding 3d floors into account.
Added, Visual mode: highlight/selection based on texture alpha now works on 3d floors. Changed, Game configurations, TranslucentLine:208 action: renamed the second argument from "Translucency Amount" to "Opacity". Internal, documentation: updated udmf_zdoom.txt.
This commit is contained in:
parent
5d47e331d8
commit
f9a7c22e03
11 changed files with 181 additions and 34 deletions
|
@ -40,7 +40,7 @@ gzdoom_lights
|
|||
9801
|
||||
{
|
||||
title = "Pulse Light";
|
||||
fixedrotation = true;
|
||||
fixedrotation = true;
|
||||
arg0
|
||||
{
|
||||
title = "Red";
|
||||
|
@ -70,7 +70,7 @@ gzdoom_lights
|
|||
9802
|
||||
{
|
||||
title = "Flicker Light";
|
||||
fixedrotation = true;
|
||||
fixedrotation = true;
|
||||
arg0
|
||||
{
|
||||
title = "Red";
|
||||
|
@ -124,7 +124,7 @@ gzdoom_lights
|
|||
9804
|
||||
{
|
||||
title = "Random Light";
|
||||
fixedrotation = true;
|
||||
fixedrotation = true;
|
||||
arg0
|
||||
{
|
||||
title = "Red";
|
||||
|
@ -178,7 +178,7 @@ gzdoom_lights
|
|||
9811
|
||||
{
|
||||
title = "Additive Pulse Light";
|
||||
fixedrotation = true;
|
||||
fixedrotation = true;
|
||||
arg0
|
||||
{
|
||||
title = "Red";
|
||||
|
@ -208,7 +208,7 @@ gzdoom_lights
|
|||
9812
|
||||
{
|
||||
title = "Additive Flicker Light";
|
||||
fixedrotation = true;
|
||||
fixedrotation = true;
|
||||
arg0
|
||||
{
|
||||
title = "Red";
|
||||
|
@ -262,7 +262,7 @@ gzdoom_lights
|
|||
9814
|
||||
{
|
||||
title = "Additive Random Light";
|
||||
fixedrotation = true;
|
||||
fixedrotation = true;
|
||||
arg0
|
||||
{
|
||||
title = "Red";
|
||||
|
@ -316,7 +316,7 @@ gzdoom_lights
|
|||
9821
|
||||
{
|
||||
title = "Subtractive Pulse Light";
|
||||
fixedrotation = true;
|
||||
fixedrotation = true;
|
||||
arg0
|
||||
{
|
||||
title = "Red";
|
||||
|
@ -346,7 +346,7 @@ gzdoom_lights
|
|||
9822
|
||||
{
|
||||
title = "Subtractive Flicker Light";
|
||||
fixedrotation = true;
|
||||
fixedrotation = true;
|
||||
arg0
|
||||
{
|
||||
title = "Red";
|
||||
|
@ -400,7 +400,7 @@ gzdoom_lights
|
|||
9824
|
||||
{
|
||||
title = "Subtractive Random Light";
|
||||
fixedrotation = true;
|
||||
fixedrotation = true;
|
||||
arg0
|
||||
{
|
||||
title = "Red";
|
||||
|
@ -427,10 +427,10 @@ gzdoom_lights
|
|||
default = 64;
|
||||
}
|
||||
}
|
||||
9825 = "Vavoom Light";
|
||||
9825 = "Vavoom Light (obsolete)";
|
||||
1502
|
||||
{
|
||||
title = "Vavoom Light ";
|
||||
title = "Vavoom Light";
|
||||
arg0
|
||||
{
|
||||
title = "Radius";
|
||||
|
|
|
@ -3957,7 +3957,8 @@ zdoom
|
|||
|
||||
arg1
|
||||
{
|
||||
title = "Translucency Amount";
|
||||
title = "Opacity";
|
||||
default = 128;
|
||||
}
|
||||
arg2
|
||||
{
|
||||
|
|
|
@ -27,7 +27,8 @@ II. Implementation Semantics
|
|||
II.A : Storage and Retrieval of Data
|
||||
------------------------------------
|
||||
|
||||
No changes.
|
||||
Any TEXTMAP lump in the described namespaces must be encoded in ISO 8859-1 which
|
||||
as of this writing is the only character encoding supported by ZDoom.
|
||||
|
||||
-----------------------------------
|
||||
II.B : Storage Within Archive Files
|
||||
|
@ -202,7 +203,18 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
// sound sequence thing in the sector will override this property.
|
||||
hidden = <bool>; // if true this sector will not be drawn on the textured automap.
|
||||
waterzone = <bool>; // Sector is under water and swimmable
|
||||
moreids = <string>; // Additional sector IDs/tags, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
|
||||
moreids = <string>; // Additional sector IDs/tags, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
|
||||
damageamount = <int>; // Amount of damage inflicted by this sector, default = 0. If this is 0, all other damage properties will be ignored.
|
||||
// Setting damage through these properties will override any damage set through 'special'.
|
||||
// Setting damageamount to a negative value will create a healing sector.
|
||||
damagetype = <string>; // Damage type for sector damage, Default = "None". (generic damage)
|
||||
damageinterval = <int>; // Interval in tics between damage application, default = 32.
|
||||
leakiness = <int>; // Probability of leaking through radiation suit (0 = never, 256 = always), default = 0.
|
||||
damageterraineffect = <bool>; // Will spawn a terrain splash when damage is inflicted. Default = false.
|
||||
damagehazard = <bool>; // Changes damage model to Strife's delayed damage for the given sector. Default = false.
|
||||
floorterrain = <string>; // Sets the terrain for the sector's floor. Default = 'use the flat texture's terrain definition.'
|
||||
ceilingterrain = <string>; // Sets the terrain for the sector's ceiling. Default = 'use the flat texture's terrain definition.'
|
||||
|
||||
|
||||
* Note about dropactors
|
||||
|
||||
|
@ -376,6 +388,10 @@ Changed language describing the DIALOGUE lump to mention USDF as an option.
|
|||
1.25 19.04.2015
|
||||
Added 'moreids' for linedefs and sectors.
|
||||
|
||||
1.26 05.01.2016
|
||||
added clarification about character encoding
|
||||
added sector damage properties.
|
||||
|
||||
===============================================================================
|
||||
EOF
|
||||
===============================================================================
|
||||
|
|
|
@ -53,8 +53,9 @@ namespace CodeImp.DoomBuilder.Data
|
|||
protected string shortname; //mxd. Name in uppercase and clamped to DataManager.CLASIC_IMAGE_NAME_LENGTH
|
||||
protected string virtualname; //mxd. Path of this name is used in TextureBrowserForm
|
||||
protected string displayname; //mxd. Name to display in TextureBrowserForm
|
||||
protected bool isFlat; //mxd. if false, it's a texture
|
||||
protected bool istranslucent; //mxd
|
||||
protected bool isFlat; //mxd. If false, it's a texture
|
||||
protected bool istranslucent; //mxd. If true, has pixels with alpha > 0 && < 255
|
||||
protected bool ismasked; //mxd. If true, has pixels with zero alpha
|
||||
protected bool hasLongName; //mxd. Texture name is longer than DataManager.CLASIC_IMAGE_NAME_LENGTH
|
||||
protected bool hasPatchWithSameName; //mxd
|
||||
protected int level; //mxd. Folder depth of this item
|
||||
|
@ -97,6 +98,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
public string DisplayName { get { return displayname; } } //mxd
|
||||
public bool IsFlat { get { return isFlat; } } //mxd
|
||||
public bool IsTranslucent { get { return istranslucent; } } //mxd
|
||||
public bool IsMasked { get { return ismasked; } } //mxd
|
||||
public bool HasPatchWithSameName { get { return hasPatchWithSameName; } } //mxd
|
||||
internal bool HasLongName { get { return hasLongName; } } //mxd
|
||||
public bool UseColorCorrection { get { return usecolorcorrection; } set { usecolorcorrection = value; } }
|
||||
|
@ -364,6 +366,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
// Also check alpha
|
||||
if(cp->a > 0 && cp->a < 255) istranslucent = true;
|
||||
else if(cp->a == 0) ismasked = true;
|
||||
}
|
||||
|
||||
// Update glow data
|
||||
|
@ -396,7 +399,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
}
|
||||
//mxd. Check if the texture is translucent
|
||||
else
|
||||
else if(!loadfailed)
|
||||
{
|
||||
BitmapData bmpdata = null;
|
||||
try { bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); }
|
||||
|
@ -410,11 +413,8 @@ namespace CodeImp.DoomBuilder.Data
|
|||
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
|
||||
{
|
||||
// Check alpha
|
||||
if(cp->a > 0 && cp->a < 255)
|
||||
{
|
||||
istranslucent = true;
|
||||
break;
|
||||
}
|
||||
if(cp->a > 0 && cp->a < 255) istranslucent = true;
|
||||
else if(cp->a == 0) ismasked = true;
|
||||
}
|
||||
|
||||
// Release the data
|
||||
|
|
|
@ -1042,7 +1042,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
if(General.Colors != null)
|
||||
e.Graphics.Clear(Color.FromArgb(General.Colors.Background.ToInt()));
|
||||
else
|
||||
e.Graphics.Clear(SystemColors.AppWorkspace);
|
||||
e.Graphics.Clear(SystemColors.ControlDarkDark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -627,7 +627,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
#region ================== Sectors
|
||||
|
||||
// This gets sectors which surround given sectors
|
||||
internal static IEnumerable<Sector> GetSectorsAround(IEnumerable<Sector> selected)
|
||||
internal static IEnumerable<Sector> GetSectorsAround(BaseVisualMode mode, IEnumerable<Sector> selected)
|
||||
{
|
||||
HashSet<int> processedsectors = new HashSet<int>();
|
||||
HashSet<Vertex> verts = new HashSet<Vertex>();
|
||||
|
@ -651,11 +651,39 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
result.Add(l.Front.Sector);
|
||||
processedsectors.Add(l.Front.Sector.Index);
|
||||
|
||||
// Add extrafloors as well
|
||||
SectorData sd = mode.GetSectorDataEx(l.Front.Sector);
|
||||
if(sd != null && sd.ExtraFloors.Count > 0)
|
||||
{
|
||||
foreach(Effect3DFloor effect in sd.ExtraFloors)
|
||||
{
|
||||
if(!processedsectors.Contains(effect.Linedef.Front.Sector.Index))
|
||||
{
|
||||
result.Add(effect.Linedef.Front.Sector);
|
||||
processedsectors.Add(effect.Linedef.Front.Sector.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(l.Back != null && l.Back.Sector != null && !processedsectors.Contains(l.Back.Sector.Index))
|
||||
{
|
||||
result.Add(l.Back.Sector);
|
||||
processedsectors.Add(l.Back.Sector.Index);
|
||||
|
||||
// Add extrafloors as well
|
||||
SectorData sd = mode.GetSectorDataEx(l.Back.Sector);
|
||||
if(sd != null && sd.ExtraFloors.Count > 0)
|
||||
{
|
||||
foreach(Effect3DFloor effect in sd.ExtraFloors)
|
||||
{
|
||||
if(!processedsectors.Contains(effect.Linedef.Front.Sector.Index))
|
||||
{
|
||||
result.Add(effect.Linedef.Front.Sector);
|
||||
processedsectors.Add(effect.Linedef.Front.Sector.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -701,7 +701,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
return sectordata[s];
|
||||
}
|
||||
|
||||
|
||||
//mxd. This requests a sector's extra data or null if given sector doesn't have it
|
||||
internal SectorData GetSectorDataEx(Sector s)
|
||||
{
|
||||
return (sectordata.ContainsKey(s) ? sectordata[s] : null);
|
||||
}
|
||||
|
||||
// This requests a things's extra data
|
||||
internal ThingData GetThingData(Thing t)
|
||||
{
|
||||
|
@ -2090,7 +2096,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
else
|
||||
{
|
||||
// Get next higher floor or ceiling from surrounding unselected sectors
|
||||
foreach(Sector s in BuilderModesTools.GetSectorsAround(ceilings.Keys))
|
||||
foreach(Sector s in BuilderModesTools.GetSectorsAround(this, ceilings.Keys))
|
||||
{
|
||||
if(s.FloorHeight < targetCeilingHeight && s.FloorHeight > maxSelectedHeight)
|
||||
targetCeilingHeight = s.FloorHeight;
|
||||
|
@ -2123,7 +2129,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
else
|
||||
{
|
||||
// Get next higher floor or ceiling from surrounding unselected sectors
|
||||
foreach(Sector s in BuilderModesTools.GetSectorsAround(floors.Keys))
|
||||
foreach(Sector s in BuilderModesTools.GetSectorsAround(this, floors.Keys))
|
||||
{
|
||||
if(s.FloorHeight > maxSelectedHeight && s.FloorHeight < targetFloorHeight && s.FloorHeight <= minSelectedCeilingHeight)
|
||||
targetFloorHeight = s.FloorHeight;
|
||||
|
@ -2290,7 +2296,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
else
|
||||
{
|
||||
// Get next lower ceiling or floor from surrounding unselected sectors
|
||||
foreach(Sector s in BuilderModesTools.GetSectorsAround(floors.Keys))
|
||||
foreach(Sector s in BuilderModesTools.GetSectorsAround(this, floors.Keys))
|
||||
{
|
||||
if(s.CeilHeight > targetFloorHeight && s.CeilHeight < minSelectedHeight)
|
||||
targetFloorHeight = s.CeilHeight;
|
||||
|
@ -2323,7 +2329,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
else
|
||||
{
|
||||
// Get next lower ceiling or floor from surrounding unselected sectors
|
||||
foreach(Sector s in BuilderModesTools.GetSectorsAround(ceilings.Keys))
|
||||
foreach(Sector s in BuilderModesTools.GetSectorsAround(this, ceilings.Keys))
|
||||
{
|
||||
if(s.CeilHeight > targetCeilingHeight && s.CeilHeight < minSelectedHeight && s.CeilHeight >= maxSelectedFloorHeight)
|
||||
targetCeilingHeight = s.CeilHeight;
|
||||
|
|
|
@ -480,7 +480,40 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// Check on which side of the nearest sidedef we are
|
||||
Sidedef sd = MapSet.NearestSidedef(Sector.Sector.Sidedefs, pickintersect);
|
||||
float side = sd.Line.SideOfLine(pickintersect);
|
||||
return (((side <= 0.0f) && sd.IsFront) || ((side > 0.0f) && !sd.IsFront));
|
||||
|
||||
//mxd. Alpha based picking. Used only on extrafloors with transparent or masked textures
|
||||
if((side <= 0.0f && sd.IsFront) || (side > 0.0f && !sd.IsFront))
|
||||
{
|
||||
if(!Texture.IsImageLoaded || extrafloor == null || RenderPass == RenderPass.Solid || (!Texture.IsTranslucent && !Texture.IsMasked))
|
||||
return true;
|
||||
|
||||
// Fetch ZDoom fields
|
||||
float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationceiling", 0.0f));
|
||||
Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningceiling", 0.0f), level.sector.Fields.GetValue("ypanningceiling", 0.0f));
|
||||
Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscaleceiling", 1.0f), level.sector.Fields.GetValue("yscaleceiling", 1.0f));
|
||||
Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight);
|
||||
|
||||
// Texture coordinates
|
||||
Vector2D o = pickintersect;
|
||||
o = o.GetRotated(rotate);
|
||||
o.y = -o.y;
|
||||
o = (o + offset) * scale * texscale;
|
||||
o.x = (o.x * Texture.Width) % Texture.Width;
|
||||
o.y = (o.y * Texture.Height) % Texture.Height;
|
||||
|
||||
// Make sure coordinates are inside of texture dimensions...
|
||||
if(o.x < 0) o.x += Texture.Width;
|
||||
if(o.y < 0) o.y += Texture.Height;
|
||||
|
||||
// Make final texture coordinates...
|
||||
int ox = General.Clamp((int)Math.Floor(o.x), 0, Texture.Width - 1);
|
||||
int oy = General.Clamp((int)Math.Floor(o.y), 0, Texture.Height - 1);
|
||||
|
||||
// Check pixel alpha
|
||||
return (Texture.GetBitmap().GetPixel(ox, oy).A > 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return texture name
|
||||
|
|
|
@ -432,7 +432,40 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// Check on which side of the nearest sidedef we are
|
||||
Sidedef sd = MapSet.NearestSidedef(Sector.Sector.Sidedefs, pickintersect);
|
||||
float side = sd.Line.SideOfLine(pickintersect);
|
||||
return (((side <= 0.0f) && sd.IsFront) || ((side > 0.0f) && !sd.IsFront));
|
||||
|
||||
//mxd. Alpha based picking. Used only on extrafloors with transparent or masked textures
|
||||
if((side <= 0.0f && sd.IsFront) || (side > 0.0f && !sd.IsFront))
|
||||
{
|
||||
if(!Texture.IsImageLoaded || extrafloor == null || RenderPass == RenderPass.Solid || (!Texture.IsTranslucent && !Texture.IsMasked))
|
||||
return true;
|
||||
|
||||
// Fetch ZDoom fields
|
||||
float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationfloor", 0.0f));
|
||||
Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningfloor", 0.0f), level.sector.Fields.GetValue("ypanningfloor", 0.0f));
|
||||
Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscalefloor", 1.0f), level.sector.Fields.GetValue("yscalefloor", 1.0f));
|
||||
Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight);
|
||||
|
||||
// Texture coordinates
|
||||
Vector2D o = pickintersect;
|
||||
o = o.GetRotated(rotate);
|
||||
o.y = -o.y;
|
||||
o = (o + offset) * scale * texscale;
|
||||
o.x = (o.x * Texture.Width) % Texture.Width;
|
||||
o.y = (o.y * Texture.Height) % Texture.Height;
|
||||
|
||||
// Make sure coordinates are inside of texture dimensions...
|
||||
if(o.x < 0) o.x += Texture.Width;
|
||||
if(o.y < 0) o.y += Texture.Height;
|
||||
|
||||
// Make final texture coordinates...
|
||||
int ox = General.Clamp((int)Math.Floor(o.x), 0, Texture.Width - 1);
|
||||
int oy = General.Clamp((int)Math.Floor(o.y), 0, Texture.Height - 1);
|
||||
|
||||
// Check pixel alpha
|
||||
return (Texture.GetBitmap().GetPixel(ox, oy).A > 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return texture name
|
||||
|
|
|
@ -319,6 +319,36 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
return base.PickFastReject(from, to, dir);
|
||||
}
|
||||
|
||||
//mxd. Alpha based picking
|
||||
public override bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray)
|
||||
{
|
||||
if(!Texture.IsImageLoaded || (!Texture.IsTranslucent && !Texture.IsMasked)) return base.PickAccurate(from, to, dir, ref u_ray);
|
||||
|
||||
float u;
|
||||
Sidedef sourceside = extrafloor.Linedef.Front;
|
||||
new Line2D(from, to).GetIntersection(Sidedef.Line.Line, out u);
|
||||
if(Sidedef != Sidedef.Line.Front) u = 1.0f - u;
|
||||
|
||||
// Get correct offset to texture space...
|
||||
float texoffsetx = Sidedef.OffsetX + sourceside.OffsetX + UniFields.GetFloat(Sidedef.Fields, "offsetx_mid") + UniFields.GetFloat(sourceside.Fields, "offsetx_mid");
|
||||
int ox = (int)Math.Floor((u * Sidedef.Line.Length * UniFields.GetFloat(sourceside.Fields, "scalex_mid", 1.0f) / Texture.Scale.x + texoffsetx) % Texture.Width);
|
||||
|
||||
float texoffsety = Sidedef.OffsetY + sourceside.OffsetY + UniFields.GetFloat(Sidedef.Fields, "offsety_mid") + UniFields.GetFloat(sourceside.Fields, "offsety_mid");
|
||||
int oy = (int)Math.Ceiling(((pickintersect.z - sourceside.Sector.CeilHeight) * UniFields.GetFloat(sourceside.Fields, "scaley_mid", 1.0f) / Texture.Scale.y - texoffsety) % Texture.Height);
|
||||
|
||||
// Make sure offsets are inside of texture dimensions...
|
||||
if(ox < 0) ox += Texture.Width;
|
||||
if(oy < 0) oy += Texture.Height;
|
||||
|
||||
// Check pixel alpha
|
||||
if(Texture.GetBitmap().GetPixel(General.Clamp(ox, 0, Texture.Width - 1), General.Clamp(Texture.Height - oy, 0, Texture.Height - 1)).A > 0)
|
||||
{
|
||||
return base.PickAccurate(from, to, dir, ref u_ray);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return texture name
|
||||
public override string GetTextureName()
|
||||
{
|
||||
|
|
|
@ -273,7 +273,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
//mxd. Alpha based picking
|
||||
public override bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray)
|
||||
{
|
||||
if(!Texture.IsImageLoaded) return base.PickAccurate(from, to, dir, ref u_ray);
|
||||
if(!Texture.IsImageLoaded || (!Texture.IsTranslucent && !Texture.IsMasked)) return base.PickAccurate(from, to, dir, ref u_ray);
|
||||
|
||||
float u;
|
||||
new Line2D(from, to).GetIntersection(Sidedef.Line.Line, out u);
|
||||
|
@ -300,8 +300,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
|
||||
// Make sure offsets are inside of texture dimensions...
|
||||
while(ox < 0) ox += Texture.Width;
|
||||
while(oy < 0) oy += Texture.Height;
|
||||
if(ox < 0) ox += Texture.Width;
|
||||
if(oy < 0) oy += Texture.Height;
|
||||
|
||||
// Check pixel alpha
|
||||
if(Texture.GetBitmap().GetPixel(General.Clamp(ox, 0, Texture.Width - 1), General.Clamp(Texture.Height - oy, 0, Texture.Height - 1)).A > 0)
|
||||
|
|
Loading…
Reference in a new issue