33 if (zero_defaults) out_xy[0] = out_xy[1] = 0;
47 out_xy[0] = out_xy[1] = val.
getInt();
57 throw C4AulExecError(R
"(C4MapScriptAlgoLayer: Expected layer in "Layer" property.)");
66 return fg != 0 || bg != 0;
73 if (!seed) seed =
Random(65536);
75 if (!set_percentage) set_percentage = 50;
77 if (!checker_wdt) checker_wdt = 10;
79 if (!checker_hgt) checker_hgt = 10;
82 is_fixed_offset = is_fixed_offset_v.
getBool();
84 is_fixed_offset =
false;
89 static int32_t divD(int32_t
a, int32_t
b) {
return a/
b-(
a%
b<0); }
90 static int32_t modD(int32_t
a, int32_t
b) {
return (
a>=0)?
a%
b:
b-(-
a)%
b; }
96 return modD((((seed ^ (x*214013))*214013) ^ (y*214013)), scale);
102 if (!is_fixed_offset) { x+=seed%checker_wdt; y+=((seed*214013)%checker_hgt); }
103 x = divD(x, checker_wdt); y = divD(y, checker_hgt);
135 uint64_t dx =
Abs((cx-x)*hgt), dy =
Abs((cy-y)*wdt);
136 return dx*dx+dy*dy < uint64_t(wdt)*wdt*hgt*hgt;
145 if (!ptx || !pty || ptx->
GetSize() != pty->GetSize())
146 throw C4AulExecError(R
"(C4MapScriptAlgoPolygon: Expected two equally sized int arrays in properties "X" and "Y".)");
148 for (int32_t i=0; i<ptx->
GetSize(); ++i)
151 poly[i].y = pty->GetItem(i).getInt();
157 if (open && !empty)
throw C4AulExecError(
"C4MapScriptAlgoPolygon: Only empty polygons may be open.");
163 int32_t crossings = 0;
164 for (
size_t i=0; i<poly.size(); ++i)
167 Pt pt2 = poly[(i+1)%poly.size()];
169 int32_t pdx = pt2.x-pt1.x, pdy = pt2.y-pt1.y, dx = x-pt1.x, dy = y-pt1.y;
170 if (i!=poly.size()-1 || !open)
172 int64_t d = dx*pdy-dy*pdx;
173 int32_t lsq = (pdx*pdx+pdy*pdy);
174 if (d*d < wdt*wdt*lsq)
176 if (
Inside(dx*pdx+dy*pdy, 0, lsq))
181 if (dx*dx+dy*dy < wdt*wdt)
return true;
183 if (!empty && (pt1.y<=y) != (pt2.y<=y))
186 crossings += (dx>dy*pdx/pdy);
190 return (crossings % 2)==1;
198 if (!lx && !ly)
throw C4AulExecError(R
"(C4MapScriptAlgoLines: Invalid direction vector. Either "X" or "Y" must be nonzero!)");
205 if (!distance) distance = l+l;
207 ll = int64_t(lx)*lx+int64_t(ly)*ly;
208 dl = int64_t(distance) * l;
214 int64_t ax = int64_t(x)-ox;
215 int64_t ay = int64_t(y)-oy;
216 int64_t line_pos = (ax*lx + ay*ly) % dl;
217 if (line_pos < 0) line_pos += dl;
218 return line_pos < ll;
242 if (!ops || n<min_ops || (max_ops && n>max_ops))
243 throw C4AulExecError(
FormatString(R
"(C4MapScriptAlgo: Expected between %d and %d operands in property "Op".)", (int)min_ops, (
int)max_ops).getData());
249 for (int32_t i=0; i<n; ++i)
252 if (!new_algo)
throw C4AulExecError(
FormatString(R
"(C4MapScriptAlgo: Operand %d in property "Op" not valid.)", (int)i).getData());
266 for (
auto & operand :
operands)
delete operand;
276 if (!(val=(*operand)(x, y, fg, bg)))
287 if ((val=(*operand)(x, y, fg, bg)))
298 return !(*
operands[0])(x, y, fg, bg);
306 uint8_t fg1, bg1, fg2, bg2;
307 bool v1=(*
operands[0])(x,y,fg1,bg1);
308 bool v2=(*
operands[1])(x,y,fg2,bg2);
309 if ((v1 && v2) || (!v1 && !v2))
311 if (v1) { fg = fg1; bg = bg1;
return true; }
328 return (*
operands[0])(x-ox,y-oy, fg, bg);
347 return (*
operands[0])((((x-cx)*2+1)*50-sx/2)/sx+cx,(((y-cy)*2+1)*50-sy/2)/sy+cy, fg, bg);
366 return (*
operands[0])(x*cr/Precision-y*sr/Precision+ox,x*sr/Precision+y*cr/Precision+oy, fg, bg);
373 if (!seed) seed =
Random(65536);
376 if (!scale[0]) scale[0] = 10;
377 if (!scale[1]) scale[1] = 10;
378 if (!amp[0] && !amp[1]) { amp[0] = amp[1] = 10; }
380 if (!iterations) iterations = 2;
388 int32_t xy[] = {x, y};
389 for (int32_t iter=0; iter<iterations; ++iter)
392 for (
int dim=0; dim<2; ++dim)
394 s[dim] = divD(xy[dim], scale[dim]);
395 p[dim] = modD(xy[dim], scale[dim]);
398 for (
int dim=0; dim<2; ++dim)
400 int32_t aamp = amp[dim] / (iter+1);
402 for (
int dx=0; dx<2; ++dx)
for (
int dy=0; dy<2; ++dy)
a[dx][dy] =
QuerySeededRandomField(seed+dim,
s[0]+dx,
s[1]+dy, aamp) - aamp/2;
403 int32_t a_interp =
a[0][0]*(scale[0]-p[0])*(scale[1]-p[1])
404 +
a[1][0]*( p[0])*(scale[1]-p[1])
405 +
a[0][1]*(scale[0]-p[0])*( p[1])
406 +
a[1][1]*( p[0])*( p[1]);
407 xy[dim] += a_interp / (scale[0]*scale[1]);
410 return (*
operands[0])(xy[0],xy[1], fg, bg);
413 void C4MapScriptAlgoBorder::ResolveBorderProps(int32_t *p)
417 int32_t inner=0, outer=0;
418 for (int32_t i=0; i<2; ++i)
if (p[i]>0) inner=p[i];
else if (p[i]<0) outer=-p[i];
419 p[0] = inner; p[1] = outer;
425 int32_t wdt[2] = {0,0};
427 int32_t n_borders = 0;
429 for (int32_t i=0; i<2; ++i) left[i]=top[i]=right[i]=bottom[i]=wdt[i];
436 ResolveBorderProps(left);
437 ResolveBorderProps(top);
438 ResolveBorderProps(right);
439 ResolveBorderProps(bottom);
443 left[1] = top[1] = right[1] = bottom[1] = 1;
453 bool inside = l(x,y,fg,bg);
455 const int32_t *ymove[] = { top, bottom }, *xmove [] ={ left, right };
456 const int32_t d[] = { -1, +1 };
457 for (int32_t dir=0; dir<2; ++dir)
459 uint8_t fake_fg, fake_bg;
460 int32_t hgt = ymove[inside!=!dir][!inside];
461 for (int32_t dy=0; dy<hgt; ++dy)
462 if (inside==!l(x,y+d[dir]*(dy+1), fake_fg, fake_bg))
464 int32_t wdt = xmove[inside!=!dir][!inside];
465 for (int32_t dx=0; dx<wdt; ++dx)
466 if (inside==!l(x+d[dir]*(dx+1),y, fake_fg, fake_bg))
478 throw C4AulExecError(
"MapScriptAlgoFilter without Filter property.");
486 bool col = (*
operands[0])(x,y, fg, bg);
487 if (!col) fg = bg = 0;
488 return filter(fg, bg);
492 : inner(inner), fg(fg), bg(bg)
503 bool result = (*inner)(x, y, fg, bg);
544 if (!algo_par)
return nullptr;
551 uint8_t fg = 0, bg = 0;
553 throw C4AulExecError(
"Invalid Material in map script algorithm.");
bool DebugLog(const char *strMessage)
bool FnParTexCol(C4String *mattex, uint8_t &fg, uint8_t &bg)
C4MapScriptAlgo * FnParAlgo(C4PropList *algo_par)
int32_t QuerySeededRandomField(int32_t seed, int32_t x, int32_t y, int32_t scale)
C4Fixed itofix(int32_t x)
C4Real Cos(const C4Real &fAngle)
int fixtoi(const C4Fixed &x)
C4Real Sin(const C4Real &fAngle)
int32_t Distance(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2)
T Clamp(T bval, T lbound, T rbound)
bool Inside(T ival, U lbound, V rbound)
StdStrBuf FormatString(const char *szFmt,...)
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
C4MapScriptAlgoBorder(const C4PropList *props)
C4MapScriptAlgoEllipse(const C4PropList *props)
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
C4MapScriptAlgoFilter(const C4PropList *props)
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
bool GetXYProps(const C4PropList *props, C4PropertyName k, int32_t *out_xy, bool zero_defaults)
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
C4MapScriptAlgoLayer(const C4MapScriptLayer *layer)
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
C4MapScriptAlgoLines(const C4PropList *props)
C4MapScriptAlgoModifier(const C4PropList *props, int32_t min_ops=0, int32_t max_ops=0)
std::vector< C4MapScriptAlgo * > operands
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
C4MapScriptAlgoOffset(const C4PropList *props)
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
C4MapScriptAlgoPolygon(const C4PropList *props)
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
C4MapScriptAlgoRect(const C4PropList *props)
C4MapScriptAlgoRndChecker(const C4PropList *props)
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
C4MapScriptAlgoRotate(const C4PropList *props)
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
C4MapScriptAlgoScale(const C4PropList *props)
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
C4MapScriptAlgoSetMaterial(C4MapScriptAlgo *inner, int fg, int bg)
~C4MapScriptAlgoSetMaterial() override
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
C4MapScriptAlgoTurbulence(const C4PropList *props)
bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
uint8_t GetPix(int32_t x, int32_t y, uint8_t outside_col) const
uint8_t GetBackPix(int32_t x, int32_t y, uint8_t outside_col) const
void Init(const C4Value &spec)
int32_t GetPropertyInt(C4PropertyName k, int32_t default_val=0) const
bool HasProperty(C4String *k) const
C4PropList * GetPropertyPropList(C4PropertyName k) const
C4String * GetPropertyStr(C4PropertyName k) const
virtual class C4MapScriptLayer * GetMapScriptLayer()
bool GetProperty(C4PropertyName k, C4Value *pResult) const
bool Contains(int32_t iX, int32_t iY) const
const char * GetCStr() const
const C4Value & GetItem(int32_t iElem) const
void SetItem(int32_t iElemNr, const C4Value &Value)
C4ValueArray * getArray() const
C4PropList * getPropList() const
const char * getData() const