373 lines
8.8 KiB
C#
373 lines
8.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using skyscraper5.Skyscraper.Plugins;
|
|
using Color = System.Drawing.Color;
|
|
|
|
namespace skyscraper8.UI.ImGui.MonoGame.Screenhacks
|
|
{
|
|
[PluginPriority(2)]
|
|
[DisplayName("Substrate")]
|
|
internal class _2_Substrate : Processing, IScreenhack
|
|
{
|
|
int dimx = 250;
|
|
int dimy = 250;
|
|
int num = 0;
|
|
int maxnum = 100;
|
|
|
|
// grid of cracks
|
|
int[] cgrid;
|
|
Crack[] cracks;
|
|
|
|
// color parameters
|
|
int maxpal = 512;
|
|
int numpal = 0;
|
|
private Color[] goodcolor;
|
|
|
|
// sand painters
|
|
SandPainter[] sands;
|
|
|
|
private void Begin()
|
|
{
|
|
// erase crack grid
|
|
for (int y = 0; y < dimy; y++)
|
|
{
|
|
for (int x = 0; x < dimx; x++)
|
|
{
|
|
cgrid[y * dimx + x] = 10001;
|
|
}
|
|
}
|
|
|
|
// make random crack seeds
|
|
for (int k = 0; k < 16; k++)
|
|
{
|
|
int i = (Random(dimx * dimy - 1));
|
|
cgrid[i] = (Random(360));
|
|
}
|
|
|
|
// make just three cracks
|
|
num = 0;
|
|
for (int k = 0; k < 3; k++)
|
|
{
|
|
MakeCrack();
|
|
}
|
|
//Background(Color.FromArgb(255, 255, 255, 255));
|
|
}
|
|
|
|
private void MakeCrack()
|
|
{
|
|
if (num < maxnum)
|
|
{
|
|
// make a new crack instance
|
|
cracks[num] = new Crack(this);
|
|
num++;
|
|
}
|
|
}
|
|
|
|
private void TakeColor()
|
|
{
|
|
uint[] srcArrays =
|
|
{
|
|
0x201F21, 0x262C2E, 0x352626, 0x372B27,
|
|
0x302C2E, 0x392B2D, 0x323229, 0x3F3229,
|
|
0x38322E, 0x2E333D, 0x333A3D, 0x473329,
|
|
0x40392C, 0x40392E, 0x47402C, 0x47402E,
|
|
0x4E402C, 0x4F402E, 0x4E4738, 0x584037,
|
|
0x65472D, 0x6D5D3D, 0x745530, 0x755532,
|
|
0x745D32, 0x746433, 0x7C6C36, 0x523152,
|
|
0x444842, 0x4C5647, 0x655D45, 0x6D5D44,
|
|
0x6C5D4E, 0x746C43, 0x7C6C42, 0x7C6C4B,
|
|
0x6B734B, 0x73734B, 0x7B7B4A, 0x6B6C55,
|
|
0x696D5E, 0x7B6C5D, 0x6B7353, 0x6A745D,
|
|
0x727B52, 0x7B7B52, 0x57746E, 0x687466,
|
|
0x9C542B, 0x9D5432, 0x9D5B35, 0x936B36,
|
|
0xAA7330, 0xC45A27, 0xD95223, 0xD85A20,
|
|
0xDB5A23, 0xE57037, 0x836C4B, 0x8C6B4B,
|
|
0x82735C, 0x937352, 0x817B63, 0x817B6D,
|
|
0x927B63, 0xD9893B, 0xE49832, 0xDFA133,
|
|
0xE5A037, 0xF0AB3B, 0x8A8A59, 0xB29A58,
|
|
0x89826B, 0x9A8262, 0x888B7C, 0x909A7A,
|
|
0xA28262, 0xA18A69, 0xA99968, 0x99A160,
|
|
0x99A168, 0xCA8148, 0xEB8D43, 0xC29160,
|
|
0xC29168, 0xD1A977, 0xC9B97F, 0xF0E27B,
|
|
0x9F928B, 0xC0B999, 0xE6B88F, 0xC8C187,
|
|
0xE0C886, 0xF2CC85, 0xF5DA83, 0xECDE9D,
|
|
0xF5D294, 0xF5DA94, 0xF4E784, 0xF4E18A,
|
|
0xF4E193, 0xE7D8A7, 0xF1D4A5, 0xF1DCA5,
|
|
0xF4DBAD, 0xF1DCAE, 0xF4DBB5, 0xF5DBBD,
|
|
0xF4E2AD, 0xF5E9AD, 0xF4E3BE, 0xF5EABE,
|
|
0xF7F0B6, 0xD9D1C1, 0xE0D0C0, 0xE7D8C0,
|
|
0xF1DDC6, 0xE8E1C0, 0xF3EDC7, 0xF6ECCE,
|
|
0xF8F2C7, 0xEFEFD0, 0
|
|
};
|
|
for (int i = 0; i < srcArrays.Length; i++)
|
|
{
|
|
srcArrays[i] |= 0xff000000;
|
|
goodcolor[i] = Color.FromArgb((int)srcArrays[i]);
|
|
}
|
|
|
|
numpal = srcArrays.Length;
|
|
}
|
|
|
|
class Crack
|
|
{
|
|
private readonly _2_Substrate _parent;
|
|
private float x, y, t;
|
|
private SandPainter sp;
|
|
|
|
public Crack(_2_Substrate parent)
|
|
{
|
|
_parent = parent;
|
|
FindStart();
|
|
sp = new SandPainter(_parent);
|
|
}
|
|
|
|
private void FindStart()
|
|
{
|
|
// pick random point
|
|
int px = 0;
|
|
int py = 0;
|
|
|
|
// shift until crack is found
|
|
bool found = false;
|
|
int timeout = 0;
|
|
while ((!found) || (timeout++ > 1000))
|
|
{
|
|
px = (_parent.Random(_parent.dimx));
|
|
py = (_parent.Random(_parent.dimy));
|
|
if (_parent.cgrid[py * _parent.dimx + px] < 10000)
|
|
{
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
if (found)
|
|
{
|
|
// start crack
|
|
int a = _parent.cgrid[py * _parent.dimx + px];
|
|
if (_parent.Random(100) < 50)
|
|
{
|
|
a -= 90 + (int)(_parent.Random(-2.0f, 2.1f));
|
|
}
|
|
else
|
|
{
|
|
a += 90 + (int)(_parent.Random(-2.0f, 2.1f));
|
|
}
|
|
|
|
StartCrack(px, py, a);
|
|
}
|
|
else
|
|
{
|
|
//println("timeout: "+timeout);
|
|
}
|
|
}
|
|
|
|
private void StartCrack(int X, int Y, int T)
|
|
{
|
|
x = X;
|
|
y = Y;
|
|
t = T; //%360;
|
|
x += 0.61f * (float)Math.Cos(t * Math.PI / 180.0);
|
|
y += 0.61f * (float)Math.Sin(t * Math.PI / 180.0);
|
|
}
|
|
|
|
public void Move()
|
|
{
|
|
// continue cracking
|
|
x += 0.42f * (float)Math.Cos(t * Math.PI / 180);
|
|
y += 0.42f * (float)Math.Sin(t * Math.PI / 180);
|
|
|
|
// bound check
|
|
float z = 0.33f;
|
|
int cx = (int)(x + _parent.Random(-z, z)); // add fuzz
|
|
int cy = (int)(y + _parent.Random(-z, z));
|
|
|
|
// draw sand painter
|
|
RegionColor();
|
|
|
|
// draw black crack
|
|
_parent.Stroke(0.0f, 85.0f);
|
|
_parent.Point(x + _parent.Random(-z, z), y + _parent.Random(-z, z));
|
|
|
|
|
|
if ((cx >= 0) && (cx < _parent.dimx) && (cy >= 0) && (cy < _parent.dimy))
|
|
{
|
|
// safe to check
|
|
if ((_parent.cgrid[cy * _parent.dimx + cx] > 10000) ||
|
|
(Math.Abs(_parent.cgrid[cy * _parent.dimx + cx] - t) < 5))
|
|
{
|
|
// continue cracking
|
|
_parent.cgrid[cy * _parent.dimx + cx] = (int)(t);
|
|
}
|
|
else if (Math.Abs(_parent.cgrid[cy * _parent.dimx + cx] - t) > 2)
|
|
{
|
|
// crack encountered (not self), stop cracking
|
|
FindStart();
|
|
_parent.MakeCrack();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// out of bounds, stop cracking
|
|
FindStart();
|
|
_parent.MakeCrack();
|
|
}
|
|
}
|
|
|
|
private void RegionColor()
|
|
{
|
|
// start checking one step away
|
|
float rx = x;
|
|
float ry = y;
|
|
bool openspace = true;
|
|
|
|
// find extents of open space
|
|
while (openspace)
|
|
{
|
|
// move perpendicular to crack
|
|
rx += 0.81f * (float)Math.Sin(t * Math.PI / 180.0);
|
|
ry -= 0.81f * (float)Math.Cos(t * Math.PI / 180.0);
|
|
int cx = (int)(rx);
|
|
int cy = (int)(ry);
|
|
if ((cx >= 0) && (cx < _parent.dimx) && (cy >= 0) && (cy < _parent.dimy))
|
|
{
|
|
// safe to check
|
|
if (_parent.cgrid[cy * _parent.dimx + cx] > 10000)
|
|
{
|
|
// space is open
|
|
}
|
|
else
|
|
{
|
|
openspace = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
openspace = false;
|
|
}
|
|
}
|
|
|
|
// draw sand painter
|
|
sp.Render(rx, ry, x, y);
|
|
}
|
|
}
|
|
|
|
class SandPainter
|
|
{
|
|
private readonly _2_Substrate _parent;
|
|
|
|
public SandPainter(_2_Substrate _parent)
|
|
{
|
|
this._parent = _parent;
|
|
c = _parent.SomeColor();
|
|
g = _parent.Random(0.01f, 0.1f);
|
|
}
|
|
|
|
private Color c;
|
|
private float g;
|
|
|
|
public void Render(float x, float y, float ox, float oy)
|
|
{
|
|
// modulate gain
|
|
g += _parent.Random(-0.050f, 0.050f);
|
|
float maxg = 1.0f;
|
|
if (g < 0) g = 0;
|
|
if (g > maxg) g = maxg;
|
|
|
|
// calculate grains by distance
|
|
//int grains = (int)(Math.Sqrt((ox-x)*(ox-x)+(oy-y)*(oy-y)));
|
|
int grains = 64;
|
|
|
|
// lay down grains of sand (transparent pixels)
|
|
float w = g / (grains - 1);
|
|
for (int i = 0; i < grains; i++)
|
|
{
|
|
float a = 0.1f - i / (grains * 10.0f);
|
|
_parent.Stroke(c.R, c.G, c.B, a * 256);
|
|
_parent.Point(ox + (x - ox) * (float)Math.Sin(Math.Sin(i * w)),
|
|
oy + (y - oy) * (float)Math.Sin(Math.Sin(i * w)));
|
|
}
|
|
}
|
|
}
|
|
|
|
private Color SomeColor()
|
|
{
|
|
if (rng == null)
|
|
rng = new Random();
|
|
return goodcolor[rng.Next(numpal)];
|
|
}
|
|
|
|
public void Draw(GameTime gameTime, SpriteBatch spriteBatch, Rectangle windowBounds)
|
|
{
|
|
for (int n = 0; n < num; n++)
|
|
{
|
|
cracks[n].Move();
|
|
}
|
|
|
|
texture.SetData(textureColors);
|
|
|
|
spriteBatch.Draw(texture, windowBounds, Microsoft.Xna.Framework.Color.White);
|
|
}
|
|
|
|
private Texture2D texture;
|
|
private Microsoft.Xna.Framework.Color[] textureColors;
|
|
private int screenWidth, screenHeight;
|
|
|
|
public void SetGraphicsDevice(GraphicsDevice graphicsDevice, Rectangle presentationParametersBounds)
|
|
{
|
|
screenWidth = presentationParametersBounds.Width;
|
|
screenHeight = presentationParametersBounds.Height;
|
|
|
|
texture = new Texture2D(graphicsDevice, presentationParametersBounds.Width,
|
|
presentationParametersBounds.Height);
|
|
textureColors =
|
|
new Microsoft.Xna.Framework.Color[presentationParametersBounds.Width *
|
|
presentationParametersBounds.Height];
|
|
texture.GetData(textureColors);
|
|
for (int i = 0; i < textureColors.Length; i++)
|
|
{
|
|
textureColors[i] = Microsoft.Xna.Framework.Color.White;
|
|
}
|
|
|
|
goodcolor = new Color[maxpal];
|
|
//Background(Color.FromArgb(255, 255, 255, 255));
|
|
TakeColor();
|
|
|
|
dimx = presentationParametersBounds.Width;
|
|
dimy = presentationParametersBounds.Height;
|
|
cgrid = new int[dimx * dimy];
|
|
cracks = new Crack[maxnum];
|
|
|
|
Begin();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
}
|
|
|
|
protected override void Point(float x, float y)
|
|
{
|
|
int ix = (int)x;
|
|
int iy = (int)y;
|
|
if (y < 0)
|
|
return;
|
|
if (y >= screenHeight)
|
|
return;
|
|
if (x < 0)
|
|
return;
|
|
if (x > screenWidth)
|
|
return;
|
|
|
|
textureColors[(iy * screenWidth) + ix].A = strokeColorObject.A;
|
|
textureColors[(iy * screenWidth) + ix].R = strokeColorObject.R;
|
|
textureColors[(iy * screenWidth) + ix].G = strokeColorObject.G;
|
|
textureColors[(iy * screenWidth) + ix].B = strokeColorObject.B;
|
|
}
|
|
}
|
|
}
|