xxxxxxxxxx
2
tokenData="0x01c22f96f74a4c3c0b395aad4fa2cdb6feee6fd9c964c69e171aad7edce61dd6";
let dim,hdim,buffer,R,nox,noy,bgColor,dkBgColor,ltBgColor,fgColor,dkFgColor,edgeColor,highlightColor,shadowColor,BIOME,COMP,CITY_TYPE,GRID_TYPE,LAND_TYPE,HISTORY_TYPE,HEAVY_SEASON_FREQ,COLOR_TYPE,HISTORY_CONTRAST,FIELD_SCALE,PLOT_TYPE,SQUARE_TYPE,PALETTE_ID,RENDER_TYPE,MEANDER_TYPE,LINE_TYPE,INVERTED,HAS_CONTOURS,HAS_POISSON,DRIFTER,TREASURE_MAP,HAS_BORDER,HAS_RAILROAD,borderWidth,treasurePos,MYSIZE=1200,SIMSIZE=600,SIMRATIO=MYSIZE/SIMSIZE,MYHALF=MYSIZE/2,cs=[],BIOMES=["FARMLAND","SWAMP","DESERT","ARCTIC","MOUNTAINS"],COMPS=["HORIZONTAL","VERTICAL","DIAGONAL","SINE WAVE","S-CURVE","DOUBLE"],CITY_TYPES=["REMOTE","HAMLET","SETTLEMENT","TOWN"],GRID_TYPES=["NO GRID","JUST DOTS","PLUSSES","DOTTED LINES"],LAND_TYPES=["DESERT","SWAMP","MIXED","SPARSE","ARCTIC","MOUNTAIN"],HISTORY_TYPES=["SEQUENTIAL","STACKS","SHORTSTACKS","RANDOMIZED"],COLOR_TYPES=["FADED","VIBRANT"],FIELD_SCALES=["CLOSE","MEDIUM","FAR"],PLOT_TYPES=["EMPTY","FULL","HALVED","HALF_QUARTERED","QUARTERED"],SQUARE_TYPES=["CLEAN","OVERGROWN","REMNANT","DIVIDED"],PALETTES=["Elevation","Warm Grays","Warm Autumn","Kirkjufell","Reynisfjara","Dry Spell","Lupine Fields","Purple Sand","Lava Fisk","Classic Map","Moss","Classic Fisk","Pale Fields","Landmannalaugar","Dried Slate","Color Shift","Ocean Desert","Pale Fisk","Dark Fisk","Near Buðir","Black/White"],RENDER_TYPES=["COLORFUL","MONOCHROME","BLACKWHITE"],MEANDER_TYPES=["REALISTIC","EXCESSIVE","CLOSE-UP"],LINE_TYPES=["NONE","HIGHLIGHTED","STROKED","SHORELINE"],tps=[];const EMPTY=0,FULL=1,HALVED=2,HALF_QUARTERED=3,QUARTERED=4,CLEAN=0,OVERGROWN=1,REMNANT=2,DIVIDED=3,FARMLAND=0,SWAMP=1,DESERT=2,ARCTIC=3,MOUNTAINS=4,REMOTE=0,RURAL=1,TOWN=2,TWIN_TOWNS=3,LAND_DESERT=0,LAND_SWAMP=1,LAND_MIXED=2,LAND_SPARSE=3,LAND_ARCTIC=4,LAND_MOUNTAIN=5,REALISTIC=0,EXCESSIVE=1,CLOSEUP=2,NONE=0,HIGHLIGHTED=1,STROKED=2,SEQUENTIAL=0,STACKS=1,SHORTSTACKS=2,RANDOMIZED=3;let riverBg,riverFg,river,riverDur,riverSpacing,riverSpeed,riverWidth,riverTanLerp,riverHistoryIter,riverCollSpacing,riverCollDistSqrd,riverHistoryCount,riverStartPos,riverEndPos,plotBg,plotsImg,plotGrowthSpeed,plotTypeThresh,plotStartFrame,rail,railStartFrame,landBg,poisson,poissonStartFrame,field,SUN_DIRECTION,mainSw,mainGapMin,mainGapMax,qTree,overlayFg,mainRand,plots=[],Q_MAX_GEN=7,qRects=[],qUpdated=!1,HALFPI=1.570796,TOTAL_DUR=2e3,myFrameCount=0,introAnim=0,introDur=60,riverStartFrame=350,riverFramePer=0,ITERATION=0,SHOW_DETAILS=!1,SAVE_IMAGE=!1,SAVE_PRINT_RES=!1,SAVE_ALT_PRINT_RES=!1;class Random{constructor(){this.useA=!1;let e=function(e){let r=parseInt(e.substr(0,8),16),t=parseInt(e.substr(8,8),16),o=parseInt(e.substr(16,8),16),n=parseInt(e.substr(24,8),16);return function(){let e=((r|=0)+(t|=0)|0)+(n|=0)|0;return n=n+1|0,r=t^t>>>9,t=(o|=0)+(o<<3)|0,o=(o=o<<21|o>>>11)+e|0,(e>>>0)/4294967296}};this.prngA=new e(tokenData.substr(2,32)),this.prngB=new e(tokenData.substr(34,32));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}random_num(e,r){return e+(r-e)*this.random_dec()}random_int(e,r){return Math.floor(this.random_num(e,r+1))}random_bool(e){return this.random_dec()<e}random_choice(e){return e[this.random_int(0,e.length-1)]}}function createColors(e){let r=[];append(r,[35,92,92,44,158,158,158,248,238,255,254,204,242,130,90]),append(r,[166,164,165,64,63,62,242,236,233,217,167,150,191,105,105]),append(r,[89,73,54,242,214,179,217,168,126,94,8,11,181,56,56]),append(r,[186,203,217,109,150,166,21,56,64,92,115,63,159,171,135]),append(r,[94,113,138,8,30,38,49,78,89,213,217,199,193,87,80]),append(r,[166,158,143,217,208,193,166,130,99,140,72,48,124,165,157]),append(r,[146,153,110,252,255,235,223,230,188,131,95,153,214,188,230]),append(r,[237,199,183,238,226,220,186,178,181,18,60,105,172,59,97]),append(r,[69,133,140,160,217,217,217,197,137,191,151,101,217,43,4]),append(r,[134,154,166,242,220,194,242,163,94,38,30,23,191,162,136]),append(r,[16,69,79,80,98,102,129,130,116,163,171,120,202,224,119]),append(r,[147,184,177,247,210,198,226,114,91,255,248,197,128,143,106]),append(r,[230,244,242,184,216,205,168,126,52,242,212,126,255,239,205]),append(r,[122,159,191,156,193,216,114,101,37,216,204,145,165,41,41]),append(r,[215,215,217,104,120,140,166,143,73,191,165,132,115,101,85]),append(r,[191,107,130,37,65,89,128,151,166,197,209,217,242,236,145]),append(r,[59,102,140,87,115,140,33,49,64,140,104,45,255,218,158]),append(r,[223,173,137,115,103,88,186,201,189,237,222,199,222,122,108]),append(r,[30,73,89,217,152,95,242,214,189,166,69,33,115,34,16]),append(r,[225,223,242,180,185,217,1,40,64,191,160,4,140,117,3]),append(r,[20,20,20,70,70,70,120,120,120,150,150,150,225,225,225]),cs=[];let t=r[e];for(let e=0;e<5;e++){let r=3*e,o=255*pow(t[r+0]/255,1),n=255*pow(t[r+1]/255,1),i=255*pow(t[r+2]/255,1),l=color(int(o),int(n),int(i));brightness(l);append(cs,l)}colorMode(HSB,255);let o=[];for(let e=0;e<cs.length;e++){let r=cs[e],t=brightness(r);append(o,t)}let n=0;for(;n<cs.length;){for(let e=0;e<cs.length-n-1;e++){cs[e],cs[e+1];o[e]>o[e+1]&&(swap(cs,e,e+1),swap(o,e,e+1))}n++}colorMode(RGB,255)}function getColor(e){let r;if(e<.2){let t=map(e,0,.2,0,1);r=lerpColor(cs[0],cs[1],t)}else if(e<.4){let t=map(e,.2,.4,0,1);r=lerpColor(cs[1],cs[2],t)}else if(e<.6){let t=map(e,.4,.6,0,1);r=lerpColor(cs[2],cs[3],t)}else if(e<.8){let t=map(e,.6,.8,0,1);r=lerpColor(cs[3],cs[4],t)}else{let t=map(e,.8,1,0,1);r=lerpColor(cs[4],cs[0],t)}return r}function readColor(e,r,t){let o=4*(int(e)+int(r)*SIMSIZE),n=t.pixels[o+0],i=t.pixels[o+1],l=t.pixels[o+2];return color(n,i,l,255)}function writeColor(e,r,t,o){let n=4*(int(e)+int(r)*SIMSIZE);o.pixels[n+0]=red(t),o.pixels[n+1]=green(t),o.pixels[n+2]=blue(t),o.pixels[n+3]=255}function wrapTheta(e){let r=e;return r<0?r+=TWO_PI:r>TWO_PI&&(r-=TWO_PI),r}function swap(e,r,t){let o=e[r];e[r]=e[t],e[t]=o}function getNoise(e,r){return noise(e.x*r+nox,e.y*r+noy)}function resampleLine(e,r,t){let o=[];return append(o,e),append(o,r),o=resample(o,t)}function resample(e,r){let t=e.length,o=[],n=0;for(let r=0;r<e.length-1;r++){let t=e[r],i=e[r+1],l=p5.Vector.dist(t,i);n+=l,append(o,l)}let i=r,l=ceil(n/float(i));i=n/float(l);let a=0,E=0,p=[];append(p,createVector(e[0].x,e[0].y));for(let r=1;r<l;r++){let r=float(E),t=0;for(;r<=i;)r+=o[a],a++,t++;let n=a-1,l=1-(r-i)/o[n];E=r-i;let s=e[n],S=e[n+1],T=p5.Vector.lerp(s,S,l);T.x=Math.floor(1e7*T.x)/1e7,T.y=Math.floor(1e7*T.y)/1e7,append(p,T)}return append(p,e[t-1]),p}function smoothSubdiv(e){let r=e.length,t=[];for(let o=0;o<r-1;o++){let r,n=e[o],i=e[o+1];if(o>0){let t=e[o-1],l=(4*n.x+t.x+i.x)/6,a=(4*n.y+t.y+i.y)/6;r=createVector(l,a)}else r=n.copy();let l=r.copy(),a=p5.Vector.add(n,i);a.x*=.5,a.y*=.5,append(t,l),append(t,a)}return append(t,e[r-1]),t}function calcCoordFrame(e){let r=e.length,t=[],o=createVector(0,0);for(let n=0;n<r;n++){if(0==n){let r=e[n],t=e[n+1];o=p5.Vector.sub(t,r).normalize()}else if(n==r-1){let r=e[n-1],t=e[n];o=p5.Vector.sub(t,r).normalize()}else{let r=e[n-1],t=e[n],i=e[n+1],l=p5.Vector.sub(t,r),a=p5.Vector.sub(i,t);o=p5.Vector.lerp(l,a,.5).normalize()}append(t,createVector(o.x,o.y)),append(t,createVector(o.y,-o.x))}return t}function calcFlowBitangent(e,r){let t,o=e.length,n=[];for(let i=0;i<o;i++){let l=(i+1)%o,a=e[i].normalize(),E=e[l].normalize();t=r[i].copy();let p=createVector(a.x,a.y,0),s=createVector(E.x,E.y,0);p5.Vector.cross(p,s).z<0&&(t=createVector(-t.x,-t.y));let S=p5.Vector.dot(p,s),T=sqrt(1-S)*riverSpeed;t=createVector(t.x*T,t.y*T),append(n,t)}return n}function distanceToRiver(e){let r=river.getPs(),t=1e3;for(let o=0;o<r.length;o+=3){let n=r[o],i=p5.Vector.dist(n,e);i<t&&(t=i)}return t}function drawRiver(e,r,t,o,n,i){riverStartPos=e[0].copy(),riverEndPos=e[e.length-1].copy();let l=riverHistoryCount%5;HISTORY_TYPE==STACKS?l=int(.2*riverHistoryCount)%5:HISTORY_TYPE==SHORTSTACKS?l=int(.4*riverHistoryCount)%5:HISTORY_TYPE==RANDOMIZED&&(l=R.random_int(0,4));let a=cs[l],E=o,p=createVector(0,0),s=createVector(.75*-SUN_DIRECTION.x,.75*-SUN_DIRECTION.y),S=createVector(.75*SUN_DIRECTION.x,.75*SUN_DIRECTION.y),T=!1;LINE_TYPE==STROKED&&(T=!0);let d=buildRiverGeo(e,r,t,o,n);if(myFrameCount%riverHistoryIter==0&&myFrameCount<=riverDur){let i=lerpColor(bgColor,a,riverFramePer*HISTORY_CONTRAST),l=lerpColor(i,color(0,0,0),.25);if(LINE_TYPE==HIGHLIGHTED&&drawRiverGeo(d,s,1,riverBg,l,T,E,shadowColor,n),R.random_dec()<HEAVY_SEASON_FREQ&&(i=fgColor),drawRiverGeo(d,S,1,riverBg,highlightColor,T,E,shadowColor,n),drawRiverGeo(d,p,1,riverBg,i,T,E,l,n),MEANDER_TYPE==CLOSEUP){let i=buildRiverGeo(e,r,t,.875*o,n),a=buildRiverGeo(e,r,t,1*o,n);drawDottedRiverLine(i,.4*E,riverBg,l),drawDottedRiverLine(a,.4*E,riverBg,l)}}if(myFrameCount<=riverDur&&(LINE_TYPE==HIGHLIGHTED&&drawRiverGeo(d,s,1,riverFg,shadowColor,!1,E,color(0),n),drawRiverGeo(d,p,1,riverFg,fgColor,T,3*mainSw,dkFgColor,n)),myFrameCount==riverDur&&3==LINE_TYPE)for(let i=0;i<20;i++){let l=map(i,0,19,0,1),a=buildRiverGeo(e,r,t,o*(13*pow(l,3)+1),n),p=255*(1-l),s=color(red(fgColor),green(fgColor),blue(fgColor),p);drawDottedRiverLine(a,.3*E,riverBg,s)}if(MEANDER_TYPE==CLOSEUP&&myFrameCount==riverDur){riverFg.strokeCap(SQUARE);let i=buildRiverGeo(e,r,t,.875*o,n);drawDottedRiverLine(i,.6*E,riverFg,shadowColor);let l=buildRiverGeo(e,r,t,1*o,n);drawDottedRiverLine(l,.3*E,riverFg,shadowColor)}}function drawRiverBanks(e){let r=[],t=int(map(mainRand,0,1,3,15)),o=resample(e,1);for(let e=0;e<o.length;e++){let n=o[e];.5*(getNoise(n,.04)+getNoise(n,.01))<.3&&R.random_bool(.5)&&(n.x+=R.random_num(-t,t),n.y+=R.random_num(-t,t),n.x=int(n.x/t)*t,n.y=int(n.y/t)*t,append(r,n))}for(let e=0;e<r.length;e++){let o=r[e],n=distanceToRiver(o),i=map(n,0,150,.25*t,.01*t,!0);riverBg.stroke(edgeColor),riverBg.strokeWeight(mainSw*i*2.5),riverBg.stroke(cs[R.random_int(0,4)]),riverBg.line(o.x-i,o.y-i,o.x+i,o.y+i),riverBg.line(o.x+i,o.y-i,o.x-i,o.y+i)}}function buildRiverGeo(e,r,t,o,n){let i,l=createVector(0,0),a=e.length,E=[],p=[];for(let s=0;s<a;s++){let S=e[s],T=r[s],d=t[s].mag(),R=riverWidth;if(n||(R+=.5*d),i=map(getNoise(S,.01),0,1,.15*R,.9*R)*o,n){let e=map(s,0,a-1,0,1);i*=.9*pow(Math.sin(e*PI),.5)+.1}append(E,i),l=createVector(S.x+T.x*i,S.y+T.y*i),append(p,l)}for(let t=a-1;t>=0;t--){map(t,0,a-1,0,1);let o=e[t],n=r[t];i=E[t],l=createVector(o.x-n.x*i,o.y-n.y*i),append(p,l)}return p=smoothSubdiv(p=smoothSubdiv(p))} function drawRiverGeo(e,t,r,i,s,o,n,a,l){i.beginShape(),o?(i.stroke(a),i.strokeWeight(.5*n)):i.noStroke(),i.fill(s);let h=e.length;for(let s=0;s<h;s++){let o=e[s].x,n=e[s].y;o=(o-MYHALF)*r+MYHALF,n=(n-MYHALF)*r+MYHALF,0==s&&i.curveVertex(o+t.x,n+t.y),i.curveVertex(o+t.x,n+t.y)}i.endShape(CLOSE),l||5!=COMP||(i.stroke(s),i.strokeWeight(riverWidth*introAnim*.9),i.noFill(),i.line(riverStartPos.x,riverStartPos.y,riverEndPos.x,riverEndPos.y))}function drawScreenOverlay(e,t,r,i){e.stroke(t),e.strokeWeight(i);for(let t=0;t<MYSIZE;t+=r)e.line(0,t,MYSIZE,t)}function drawDottedRiverLine(e,t,r,i){r.stroke(i),r.strokeWeight(t),r.noFill();let s=resample(e,1);for(let e=0;e<s.length-1;e++)if(e%4<=1){let t=s[e],i=s[e+1];r.line(t.x,t.y,i.x,i.y)}}function distanceToRiver(e){let t=river.getPs(),r=2e3;for(let i=0;i<t.length;i+=3){let s=t[i],o=p5.Vector.dist(s,e);o<r&&(r=o)}return r}function drawBuilding(e,t,r,i,s,o){let n=map(pow(R.random_dec(),2),0,1,2,6),a=map(pow(R.random_dec(),2),0,1,2,6),l=3;R.random_bool(.01)&&(n*=3,a*=3,l*=2);let h=.6*i,c=.6*-r;R.random_bool(.5)&&(h=.6*-i,c=.6*r);let d=createVector(e+h*l,t+c*l),p=createVector(d.x+h*a,d.y+c*a),x=createVector(p.x+r*n,p.y+i*n),y=createVector(d.x+r*n,d.y+i*n);o.beginShape(),o.fill(s),o.noStroke(),o.vertex(d.x,d.y),o.vertex(p.x,p.y),o.vertex(x.x,x.y),o.vertex(y.x,y.y),o.endShape()}function createPlotNetwork(e,t){let r=350;0==CITY_TYPE?r=0:1==CITY_TYPE?r=5:2==CITY_TYPE&&(r=50);let i=e.length,s=R.random_num(-.4,.4);for(let o=0;o<r;o++){let r=R.random_int(50,i-50);1==CITY_TYPE?r=R.random_int(int(i/2)-10,int(i/2)+10):2==CITY_TYPE?(r=R.random_int(int(i/2)-20,int(i/2)+20),5==COMP&&(r=R.random_int(int(i/4)-10,int(i/4)+10))):3==CITY_TYPE&&(r=R.random_bool(.5)?R.random_int(int(.3*i)-10,int(.3*i)+10):R.random_int(int(.7*i)-10,int(.7*i)+10));let o=e[r].x,n=e[r].y,a=t[r].x,l=t[r].y,h=atan2(l,a);if(R.random_bool(.5)&&(h+=PI),BIOME==DESERT){let e=R.random_int(0,3);h=0+HALFPI*float(e)+s}addPlot(o/2,n/2,h,color(0),0)}}function addPlot(e,t,r,i,s){let o=wrapTheta(r),n=new Plot(e,t,o,i,s);plots.push(n)}function makeGrid(e,t){let r=R.random_int(8,50);2==GRID_TYPE&&(r=R.random_int(12,16));let i=r,s=1.5;if(3==GRID_TYPE&&(s=65),t.noFill(),t.stroke(fgColor),t.strokeWeight(.25*mainSw),3!=GRID_TYPE)for(let e=0;e<r;e++){let o=map(e,0,r-1,0,MYSIZE),n=map(e+1,0,r-1,0,MYSIZE);for(let e=0;e<i;e++){let r=map(e,0,i-1,0,MYSIZE),a=map(e+1,0,i-1,0,MYSIZE);1==GRID_TYPE&&(t.circle(o,r,1),t.circle(o,r,.5)),2==GRID_TYPE&&(t.line(o,r+.4*s,o,r+2*s),t.line(o+.4*s,r,o+2*s,r),t.line(o,a-.4*s,o,a-2*s),t.line(n-.4*s,r,n-2*s,r))}}else{for(let e=0;e<r;e++){let i=map(e,0,r-1,0,MYSIZE),s=createVector(i,0),o=createVector(i,MYSIZE),n=[];append(n,s),append(n,o),n=resample(n,3);for(let e=0;e<n.length-1;e+=2){let r=n[e],i=n[e+1];t.line(r.x,r.y,i.x,i.y)}}for(let e=0;e<i;e++){let r=map(e,0,i-1,0,MYSIZE),s=createVector(0,r),o=createVector(MYSIZE,r),n=[];append(n,s),append(n,o),n=resample(n,3);for(let e=0;e<n.length-1;e+=2){let r=n[e],i=n[e+1];t.line(r.x,r.y,i.x,i.y)}}}}function makeTreasure(){let e=river.getPs(),t=e[R.random_int(max(e.length/2-20,1),min(e.length/2+20,e.length-2))],r=[];append(r,t.copy()),append(r,treasurePos.copy()),r=resample(r,50);for(let e=1;e<r.length-1;e++)r[e].x+=125*getNoise(r[e],.03),r[e].y+=125*getNoise(r[e],.03);return r=smoothSubdiv(r),r=resample(r,5)}function xMarksTheSpot(e){let t=treasurePos.x,r=treasurePos.y;e.stroke(edgeColor),e.strokeWeight(2.25),e.strokeCap(SQUARE),e.line(t-3,r-3,t+3,r+3),e.line(t+3,r-3,t-3,r+3)}function outOfBounds(e,t){let r=!1;return e<=2&&(r=!0),t<=2&&(r=!0),e>=SIMSIZE-3&&(r=!0),t>=SIMSIZE-3&&(r=!0),r}function getPlotType(){let e=R.random_dec(),t=0;return t=e<.1?0:e<.5?1:e<.7?2:e<.8?3:4}class RectPlot{constructor(e,t,r,i){this.p0=createVector(e,t),this.p1=createVector(r,i),this.x0=this.p0.x,this.y0=this.p0.y,this.x1=this.p1.x,this.y1=this.p1.y,this.center=p5.Vector.lerp(this.p0,this.p1,.5),this.w=r-e,this.h=i-t,this.density=0,this.innerDensity=0,this.radius=this.w/2-.01*this.w*2,this.rect=new Rectangle(this.center.x,this.center.y,this.w/2,this.h/2)}setDensity(e){this.density=e}split(e){let t=[];for(let r=0;r<e;r++){let i=map(r,0,e,this.x0,this.x1),s=map(r+1,0,e,this.x0,this.x1),o=new RectPlot(i,this.y0,s,this.y1);append(t,o)}return t}draw(e,t,r){let i=getColor(R.random_dec());e.noStroke(),e.fill(red(i),green(i),blue(i),R.random_int(20,100)),e.rect(this.x0,this.y0,this.w,this.h),this.drawDottedLine(e,i,createVector(this.x0,this.y0),createVector(this.x1,this.y0)),this.drawDottedLine(e,i,createVector(this.x1,this.y0),createVector(this.x1,this.y1)),this.drawDottedLine(e,i,createVector(this.x1,this.y1),createVector(this.x0,this.y1)),this.drawDottedLine(e,i,createVector(this.x0,this.y1),createVector(this.x0,this.y0)),R.random_bool(.75)&&this.drawDottedFill(e,i,this.rect)}drawDottedLine(e,t,r,i){let s=p5.Vector.sub(i,r);s.normalize();let o=createVector(-s.y,s.x);e.stroke(t),e.strokeWeight(.5*mainSw);let n=[];append(n,r),append(n,i);let a=resample(n,1),l=1.5;for(let t=0;t<a.length-1;t++)if(t%3==0){let r=a[t],i=a[t+1];e.line(r.x+o.x*l,r.y+o.y*l,i.x+o.x*l,i.y+o.y*l)}e.stroke(0,0,0,50),e.line(r.x,r.y,i.x,i.y)}drawDottedFill(e,t,r){let i=createVector(r.x-r.w,r.y-r.h),s=createVector(r.x-r.w,r.y+r.h),o=createVector(r.x+r.w,r.y-r.h),n=[];append(n,i),append(n,s),e.stroke(t),e.strokeWeight(.5*mainSw);let a=resample(n,1);for(let t=1;t<a.length-1;t+=2){let r=a[t],i=createVector(o.x,r.y),s=[];append(s,r),append(s,i);let n=resample(s,.5);for(let t=0;t<n.length-1;t++)if(t%3==0){let r=n[t],i=n[t+1];e.line(r.x,r.y,i.x,i.y)}}}}class Point{constructor(e,t){this.x=e,this.y=t,this.p=createVector(e,t)}}class Line{constructor(e,t,r,i){this.x0=e,this.y0=t,this.x1=r,this.y1=i,this.p0=createVector(e,t),this.p1=createVector(r,i),this.d=p5.Vector.dist(this.p0,this.p1)}}class Rectangle{constructor(e,t,r,i){this.x=e,this.y=t,this.w=r,this.h=i}contains(e){return e.x>=this.x-this.w&&e.x<this.x+this.w&&e.y>=this.y-this.h&&e.y<this.y+this.h}}class Contours{constructor(){this.field=[],this.res=7,this.cols=1+MYSIZE/this.res,this.rows=1+MYSIZE/this.res;for(let e=0;e<this.cols;e++){let e=[];for(let t=0;t<this.rows;t++)e.push(0);this.field.push(e)}}getXYDist(e,t,r){let i=createVector(e,t),s=111111;for(let e=0;e<r.length;e++){let t=r[e],o=p5.Vector.sub(t,i).mag();o<s&&(s=o)}return s}solve(e){let t=7,r=7,i=1.4;BIOME==FARMLAND||BIOME==DESERT?(t=5,r=5,i=1.4):BIOME==MOUNTAINS&&(t=15,r=15,i=.225);for(let s=0;s<this.cols;s++){let o=map(s,0,this.cols-1,0,t),n=map(s,0,this.cols-1,0,MYSIZE);for(let t=0;t<this.rows;t++){let a=map(t,0,this.rows-1,0,r),l=map(t,0,this.rows-1,0,MYSIZE),h=this.getXYDist(n,l,e);this.field[s][t]=float(h/1e3+noise(o+123.45,a+456.78)*i)}}}drawLine(e,t,r){let i=p5.Vector.sub(t,r),s=i.mag();i.normalize(),e.line(t.x,t.y,t.x-i.x*s*.5,t.y-i.y*s*.5)}draw(e){let t=this.res,r=.25;BIOME==MOUNTAINS?r=.05:BIOME!=FARMLAND&&BIOME!=DESERT||(r=.25);for(let i=-1;i<1.25;i+=r){e.stroke(edgeColor),e.strokeWeight(map(i,-1,1.25,.1,.25));for(let r=0;r<this.cols-1;r++)for(let s=0;s<this.rows-1;s++){let o=this.field[r][s]-i,n=this.field[r+1][s]-i,a=this.field[r+1][s+1]-i,l=this.field[r][s+1]-i,h=r*t,c=s*t,d=createVector(h+t*o/(o-n),c),p=createVector(h+t,c+t*n/(n-a)),x=createVector(h+t*(1-a/(a-l)),c+t),y=createVector(h,c+t*(1-l/(l-o)));switch(this.getState(o,n,a,l)){case 1:this.drawLine(e,x,y);break;case 2:this.drawLine(e,p,x);break;case 3:this.drawLine(e,p,y);break;case 4:this.drawLine(e,d,p);break;case 5:this.drawLine(e,d,y),this.drawLine(e,p,x);break;case 6:this.drawLine(e,d,x);break;case 7:case 8:this.drawLine(e,d,y);break;case 9:this.drawLine(e,d,x);break;case 10:this.drawLine(e,d,p),this.drawLine(e,x,y);break;case 11:this.drawLine(e,d,p);break;case 12:this.drawLine(e,p,y);break;case 13:this.drawLine(e,p,x);break;case 14:this.drawLine(e,x,y)}}}}getState(e,t,r,i){return(e>0?8:0)+(t>0?4:0)+(r>0?2:0)+(i>0?1:0)}} class FastPoisson{constructor(){this.points=[],this.index=0,this.radius=7,this.dead=!1}solve(){this.radius=7;let t=this.radius,s=MYSIZE,e=MYSIZE,i=s;t=Math.min(t,i/50*.9),t*=t;let h=R.random_dec(),a=R.random_dec(),o=createVector(h,a);for(let i=0;i<100;i++)for(let h=0;h<50;h++){let a=0;for(;;){o=createVector(R.random_dec(),R.random_dec());let r=createVector(o.x+h,o.y+i);r.x/=50,r.y/=100,r.x*=s,r.y*=e;let n=h+100*i,l=h-1+100*i,p=h+100*(i-1),d=h-1+100*(i-1),c=h+1+100*(i-1),m=this.points[l],g=this.points[p],I=this.points[d],f=this.points[c];if(0!=h&&0==i){if(p5.Vector.sub(m,r).magSq()>t){this.points[n]=r;break}}else if(0==h&&0!=i){if(p5.Vector.sub(g,r).magSq()>t){this.points[n]=r;break}}else{if(0==h&&0==i){this.points[n]=r;break}if(0!=h&&0!=i&&49!=h){let s=p5.Vector.sub(g,r),e=(p5.Vector.sub(m,r),p5.Vector.sub(I,r),p5.Vector.sub(f,r),s.magSq()),i=s.magSq(),h=s.magSq(),a=s.magSq();if(e>t&&i>t&&h>t&&a>t){this.points[n]=r;break}}else if(0!=h&&0!=i&&49==h){let s=p5.Vector.sub(g,r),e=(p5.Vector.sub(m,r),p5.Vector.sub(I,r),s.magSq()),i=s.magSq(),h=s.magSq();if(e>t&&i>t&&h>t){this.points[n]=r;break}}}if(++a>1e3)break}}}draw(t){t.stroke(edgeColor),t.strokeWeight(mainSw);for(let s=0;s<MYSIZE;s+=4)for(let e=0;e<MYSIZE;e+=3){let i=.5*(getNoise(createVector(e,s),75e-5)+map(getNoise(createVector(e,s),.005),.5,.9,.4,1));i=map(i,.1,.7,0,1);let h=R.random_num(1,3);i<.15&&R.random_dec()<map(i,0,.12,.3,0)&&t.line(2*e-h+e%2,s,2*e+h+e%2,s)}for(let s=0;s<this.points.length;s++)if(this.points[s]){let e=this.points[s].x,i=this.points[s].y,h=R.random_num(.3*this.radius,.5*this.radius),a=noise(.0015*e,.0035*i);if(a=.333*(a+noise(.02*e,.005*i)+noise(.005*e,25e-5*i)),LAND_TYPE==LAND_DESERT){if(a>.2&&a<.3){let s=map(a,.2,.3,0,1);this.drawDesertIcon(t,e,i,h,s)}}else if(LAND_TYPE==LAND_SWAMP||LAND_TYPE==LAND_ARCTIC){if(a>.2&&a<.3){let s=map(a,.2,.3,0,1);this.drawSwampIcon(t,e,i,h,s)}}else if(LAND_TYPE==LAND_MIXED){if(a>.2&&a<.3){let s=map(a,.2,.3,0,1);this.drawDesertIcon(t,e,i,h,s)}else if(a>.4&&a<.45){let s=map(a,.4,.45,0,1);this.drawSwampIcon(t,e,i,h,s)}}else if(LAND_TYPE==LAND_SPARSE){if((a=noise(.008*e,.012*i))>.2&&a<.3){let s=map(a,.2,.3,0,1);this.drawDesertIcon(t,e,i,h,s)}}else if(LAND_TYPE==LAND_MOUNTAIN)if((a=noise(.004*e,.008*i))>.15&&a<.25){let s=map(a,.2,.3,0,1);this.drawDesertIcon(t,e,i,h,s)}else if(a>.25&&a<.35){let s=map(a,.2,.3,0,1);this.drawMountainIcon(t,e,i,h,s)}}}drawMountainIcon(t,s,e,i,h){let a=floor(map(Math.sin(h*PI),0,1,0,3))%3;0==a?(t.line(s-.5*i,e+.35*i,s,e),t.line(s+.5*i,e+.35*i,s,e)):1==a?(t.line(s-.8*i,e+.5*i,s,e),t.line(s+.8*i,e+.5*i,s,e)):2==a&&(t.line(s-1.1*i,e+.75*i,s,e),t.line(s+1.1*i,e+.75*i,s,e))}drawSwampIcon(t,s,e,i,h){let a=floor(map(Math.sin(h*PI),0,1,0,3))%3;if(0==a)for(let h=0;h<5;h++){let a=s-(h-2)*i*.5;t.line(a,e,a+.3*i,e)}else 1==a?(t.line(s-i,e,s-.3*i,e),t.line(s+i,e,s+.3*i,e)):2==a&&(t.line(s-.3*i,e,s+.3*i,e),t.line(s-1.25*i,e+4,s+1.25*i,e+4))}drawDesertIcon(t,s,e,i,h){let a=floor(map(Math.sin(h*PI),0,1,0,3))%3;0==a?(t.line(s-.2*i,e,s-.5*i,e-.5*i),t.line(s+.2*i,e,s+.5*i,e-.5*i)):1==a?(t.line(s-.5*i,e,s-i,e-.5*i),t.line(s+.5*i,e,s+i,e-.5*i),t.line(s,e,s,e-.7*i)):2==a&&(t.line(s-.5*i,e,s-1.2*i,e-.5*i),t.line(s+.5*i,e,s+1.2*i,e-.5*i),t.line(s-.1*i,e,s-.4*i,e-.8*i),t.line(s+.1*i,e,s+.4*i,e-.8*i))}}class Rail{constructor(t,s){let e=p5.Vector.sub(s,t);e.normalize();let i=createVector(e.y,-e.x),h=createVector(MYHALF,MYHALF),a=h.x+i.x*MYHALF*1.414,o=h.y+i.y*MYHALF*1.414,r=h.x-i.x*MYHALF*1.414,n=h.y-i.y*MYHALF*1.414,l=R.random_num(-200,200),p=createVector(e.x*l,e.y*l),d=createVector(a,o),c=createVector(r,n),m=p5.Vector.lerp(d,c,.2),g=p5.Vector.lerp(d,c,.8),I=R.random_num(-50,50),f=R.random_num(-50,50);m.x+=e.x*I,m.y+=e.y*I,g.x+=e.x*f,g.y+=e.y*f,this.ps=[],this.prevPos=d.copy(),this.pos=d.copy(),append(this.ps,p5.Vector.add(d,p)),append(this.ps,p5.Vector.add(m,p)),append(this.ps,p5.Vector.add(g,p)),append(this.ps,p5.Vector.add(c,p)),this.ps=smoothSubdiv(this.ps),this.ps=resample(this.ps,5),this.age=0,this.life=this.ps.length-1,this.dead=!1}update(){0==this.dead&&(this.age++,this.prevPos=this.pos.copy(),this.pos=this.ps[this.age].copy(),this.age==this.life&&(this.dead=!0))}draw(){let t=this.prevPos.x,s=this.prevPos.y,e=this.pos.x,i=this.pos.y,h=p5.Vector.sub(this.pos,this.prevPos);h.normalize();let a=createVector(h.y,-h.x),o=2.5,r=R.random_num(1.75,2.1);CITY_TYPE<2&&(r=R.random_num(1.4,1.75));pow(1/float(this.gen+1),2);landBg.noFill(),landBg.stroke(edgeColor),landBg.strokeWeight(mainSw),landBg.line(t,s,e,i),landBg.strokeWeight(mainSw),landBg.line(this.pos.x+a.x*o,this.pos.y+a.y*o,this.pos.x-a.x*o,this.pos.y-a.y*o)}isDead(){return this.dead}}class Plot{constructor(t,s,e,i,h){this.x=t,this.y=s,this.theta=e,this.gen=h,this.vx=Math.cos(this.theta)*plotGrowthSpeed,this.vy=Math.sin(this.theta)*plotGrowthSpeed,this.px=this.x,this.py=this.y,this.frameIter=5,this.cd=color(R.random_int(0,255),R.random_int(0,255),R.random_int(0,255)),this.dead=!1,this.age=0,this.iterAge=2,this.life=R.random_int(350,500),this.randThresh=.1,this.maxGen=R.random_int(8,15),this.delay=20,0==h&&(this.delay=0);let a=R.random_dec();CITY_TYPE==REMOTE?(this.maxGen=R.random_int(2,4),this.life=R.random_int(150,250),a<.1&&(this.frameIter=2,this.iterAge=2,this.randThresh=1)):CITY_TYPE==RURAL?(this.maxGen=R.random_int(2,6),this.life=R.random_int(200,350),a<.2&&(this.frameIter=2,this.iterAge=2,this.randThresh=1)):a<.3&&(this.frameIter=2,this.iterAge=2,this.randThresh=1)}update(){if(this.vx=cos(this.theta)*plotGrowthSpeed,this.vy=sin(this.theta)*plotGrowthSpeed,this.px=this.x,this.py=this.y,this.x+=this.vx,this.y+=this.vy,this.x>2&&this.x<SIMSIZE-3&&this.y>2&&this.y<SIMSIZE-3){let t=readColor(this.x,this.y,plotsImg);brightness(t)>20&&t.toString()!=this.cd.toString()&&(this.dead=!0)}if(getNoise(createVector(this.x,this.y),.05)>plotTypeThresh){let t=.25,s=noise(this.x*t+nox,this.y*t+noy);this.theta+=map(s,0,.7,-.1,.1),this.theta=wrapTheta(this.theta)}if(BIOME==DESERT){let t=Math.abs(Math.sin(.4*this.x)),s=Math.abs(Math.sin(.4*this.y));if(t<.25&&s<.25&&this.age>this.iterAge){let t=HALFPI;R.random_bool(.5)&&(t=-HALFPI),addPlot(this.x,this.y,this.theta+t,this.cd,this.gen+1)}}else if(R.random_dec()<this.randThresh&&myFrameCount%this.frameIter==0&&this.age>this.iterAge){let t=HALFPI;R.random_bool(.5)&&(t=-HALFPI),addPlot(this.x,this.y,this.theta+t,this.cd,this.gen+1)}this.age++,this.age>=this.life&&(this.dead=!0),this.gen>=this.maxGen&&(this.dead=!0),outOfBounds(this.x,this.y)&&(this.dead=!0)}render(){writeColor(this.x,this.y,this.cd,plotsImg)}drawLine(){let t=1/float(this.gen+1)+.5;this.gen<this.maxGen&&this.age%3<=1&&this.age>2&&!this.dead&&(landBg.stroke(bgColor),landBg.strokeWeight(7*t),landBg.line(this.x*SIMRATIO,this.y*SIMRATIO,this.px*SIMRATIO,this.py*SIMRATIO),plotBg.stroke(edgeColor),plotBg.strokeWeight(t),plotBg.line(this.x*SIMRATIO,this.y*SIMRATIO,this.px*SIMRATIO,this.py*SIMRATIO));let s=1.5;plotBg.noStroke(),plotBg.strokeWeight(6*t),this.age>=this.life&&(plotBg.fill(cs[R.random_int(0,4)]),plotBg.rect(this.x*SIMRATIO-s,this.y*SIMRATIO-s,s,s));let e=map(this.age-this.delay,0,70,.4,0);R.random_dec()<e&&this.gen<6&&this.age%3==0&&drawBuilding(this.x*SIMRATIO,this.y*SIMRATIO,this.vx,this.vy,cs[R.random_int(0,4)],plotBg)}isDead(){return this.dead}}class Oxbow{constructor(t){this.ps=[];for(let s=0;s<t.length;s++)append(this.ps,t[s].copy());let s=resample(this.ps,riverSpacing);this.initNumPts=s.length,s=smoothSubdiv(s),this.ps=[];for(let t=0;t<s.length;t++)append(this.ps,createVector(s[t].x,s[t].y));this.numPts=s.length,this.ts=[],this.bs=[],this.bds=[];for(let t=0;t<this.numPts;t++)append(this.ts,createVector(1,0)),append(this.bs,createVector(0,-1)),append(this.bds,createVector(0,-1));this.age=0,this.life=50,this.agePer=1,this.dead=!1}update(){let t=resample(this.ps,riverSpacing);this.ps=[];for(let s=0;s<t.length;s++)append(this.ps,createVector(t[s].x,t[s].y));this.numPts=this.ps.length;let s=calcCoordFrame(this.ps);this.ts=[],this.bs=[];for(let t=0;t<s.length;t+=2)append(this.ts,s[t]),append(this.bs,s[t+1]);if(this.bds=calcFlowBitangent(this.ts,this.bs),myFrameCount%2==0){let t=[],s=[];for(let e=1;e<this.numPts-1;e++)append(t,this.ps[e]),append(s,this.bds[e]);this.ps=[],this.bitansDir=[];for(let e=0;e<t.length;e++)append(this.ps,t[e]),append(this.bds,s[e])}this.numPts=this.ps.length,this.age++,this.agePer=map(this.numPts,0,this.initNumPts,0,1),this.numPts<4&&(this.dead=!0)}draw(){drawRiver(this.ps,this.bs,this.bds,this.agePer,!0)}writeColors(t){let s=resample(this.ps,4);for(let e=0;e<s.length;e++){let i=s[e].x,h=s[e].y,a=int(i-SIMSIZE+SIMSIZE),o=int(h-SIMSIZE+SIMSIZE);writeColor(a,o,color(255,0,0),t)}}isDead(){return this.dead}isTooLong(){return this.tooLong}getPs(){return this.ps}} class River{constructor(t){this.ps=[],this.rs=[],this.ts=[],this.bs=[],this.bds=[],this.vel=createVector(0,0);let e=R.random_dec(),s=MYSIZE,r=MYHALF;if(0==t){let t=0,e=R.random_bool(.2),i=R.random_bool(.5);if(DRIFTER&&(e=!0),e){let e=R.random_num(MYSIZE/4,MYSIZE/2.8);t=i?-e:e}DRIFTER&&(this.vel.y=i?.625:-.625);for(let e=0;e<400;e++){let i=map(e,0,399,0,1),o=map(i,0,1,-200,s+200),n=r,h=createVector(o,n);n+=map(getNoise(h,.004),.1,.7,-100,100)+t,this.ps[e]=createVector(o,n)}let o=R.random_num(300,MYSIZE-300),n=R.random_num(350,400);R.random_bool(.5)&&(n=MYSIZE-n),treasurePos=createVector(o,n),treasurePos.y-=.5*t}else if(1==t){let t=0,e=R.random_bool(.2),i=R.random_bool(.5);if(DRIFTER&&(e=!0),e){let e=R.random_num(MYSIZE/4,MYSIZE/2.8);t=i?-e:e}DRIFTER&&(this.vel.x=i?.625:-.625);for(let e=0;e<400;e++){let i=map(e,0,399,0,1),o=r,n=map(i,0,1,-200,s+200),h=createVector(o,n);o+=map(getNoise(h,.004),.1,.7,-100,100)+t,this.ps[e]=createVector(o,n)}let o=R.random_num(250,300),n=R.random_num(300,MYSIZE-300);R.random_bool(.5)&&(o=MYSIZE-o),treasurePos=createVector(o,n),treasurePos.x-=.25*t}else if(2==t){let t=R.random_num(MYSIZE-500,MYSIZE-300),r=R.random_num(350,400);R.random_bool(.5)&&(t=R.random_num(300,500),r=R.random_num(MYSIZE-400,MYSIZE-350));let i=0,o=0;DRIFTER&&(R.random_bool(.5)?R.random_bool(.5)?(this.vel.y=-.625,o+=300):(this.vel.y=.625,o-=300):R.random_bool(.5)?(this.vel.x=-.625,i+=300):(this.vel.x=.625,i-=300));for(let n=0;n<400;n++){let h=map(n,0,399,0,1),a=map(h,0,1,-200,s+200),p=map(h,0,1,-200,s+200),l=map(getNoise(createVector(a,p),.004),.1,.7,-100,100);e<.5?(a=map(h,0,1,s+200,-200),t=R.random_num(300,500),r=R.random_num(300,500),a-=l,p-=l):(a-=l,p+=l),this.ps[n]=createVector(a+i,p+o)}treasurePos=createVector(t,r)}else if(3==t){let t,i;e<.5?(t=R.random_num(200,MYSIZE-200),i=R.random_num(MYSIZE-250,MYSIZE-200)):(i=R.random_num(200,MYSIZE-200),t=R.random_num(MYSIZE-250,MYSIZE-200));let o,n,h=R.random_num(0,TWO_PI),a=0,p=0;DRIFTER&&(e<.5?R.random_bool(.5)?(this.vel.y=-.625,p+=400):(this.vel.y=.625,p-=400):R.random_bool(.5)?(this.vel.x=-.625,a+=400):(this.vel.x=.625,a-=400));for(let t=0;t<400;t++){let i=map(t,0,399,0,1);if(e<.5){o=map(i,0,1,-200,s+200),n=r;let t=map(getNoise(createVector(o,n),.005),.1,.7,-100,100);n+=100*sin(i*TWO_PI*2.75+h)+t}else{n=map(i,0,1,-200,s+200),o=r;let t=map(getNoise(createVector(o,n),.005),.1,.7,-100,100);o+=100*sin(i*TWO_PI*2.75+h)+t}this.ps[t]=createVector(o+a,n+p)}treasurePos=createVector(t,i)}else if(4==t){let t=R.random_num(MYHALF+200,MYHALF+250),r=R.random_num(MYHALF-250,MYHALF-200),i=[];if(append(i,createVector(-200,.3*s)),append(i,createVector(.3*s,s)),append(i,createVector(.7*s,0)),append(i,createVector(s+200,.7*s)),e<.5){t=R.random_num(MYHALF-250,MYHALF-200);let e=[];for(let t=0;t<i.length;t++)append(e,createVector(i[t].x,MYSIZE-i[t].y));i=[],i=e}i=smoothSubdiv(i),i=smoothSubdiv(i),this.ps=resample(i,10),R.random_bool(.5)&&(t=MYSIZE-t,r=MYSIZE-r),treasurePos=createVector(t,r)}else if(5==t){let t=[],r=R.random_num(.25,.4),i=1-r;e<.5?(append(t,createVector(-200,s*r)),append(t,createVector(1*s,s*r)),append(t,createVector(1.2*s,s*r)),append(t,createVector(1.4*s,.5*s)),append(t,createVector(1.2*s,s*i)),append(t,createVector(1*s,s*i)),append(t,createVector(-200,s*i))):(append(t,createVector(s*r,-200)),append(t,createVector(s*r,1*s)),append(t,createVector(s*r,1.2*s)),append(t,createVector(.5*s,1.4*s)),append(t,createVector(s*i,1.2*s)),append(t,createVector(s*i,1*s)),append(t,createVector(s*i,-200))),t=smoothSubdiv(t),t=smoothSubdiv(t),this.ps=resample(t,10);for(let t=0;t<this.ps.length;t++)e<.5?this.ps[t].y+=map(getNoise(this.ps[t],.005),.1,.8,-20,20):this.ps[t].x+=map(getNoise(this.ps[t],.005),.1,.8,-20,20);treasurePos=createVector(MYHALF,R.random_num(200,MYSIZE-200))}for(let t=0;t<this.ps.length;t++)append(this.rs,this.ps[t]);this.speedMulti=1,this.numPts=this.ps.length,this.startPos=this.ps[0],this.endPos=this.ps[this.numPts-1],this.oxbows=[]}checkOxbows(){let t=[];for(let e=0;e<this.numPts;e++){for(let t=e+riverCollSpacing;t<min(e+this.numPts/2,this.numPts);t++){let s=this.ps[e],r=this.ps[t];if(p5.Vector.sub(s,r).magSq()<riverCollDistSqrd&&t-e<this.numPts/2){let s=[];for(let r=e+1;r<=t-1;r++)append(s,this.ps[r].copy());this.addOxbow(s),t=(e=min(t+1,this.numPts-1))+riverSpacing}}append(t,this.ps[e])}this.ps=[];for(let e=0;e<t.length;e++)append(this.ps,createVector(t[e].x,t[e].y));this.numPts=this.ps.length}addOxbow(t){let e=new Oxbow(t);this.oxbows.push(e)}updateOxbows(){for(let t=0;t<this.oxbows.length;t++){let e=this.oxbows[t];e.update(),e.isDead()&&this.oxbows.splice(t,1)}}update(){let t=resample(this.ps,riverSpacing);this.ps=[];for(let e=0;e<t.length;e++)append(this.ps,createVector(t[e].x,t[e].y));this.numPts=this.ps.length;let e=calcCoordFrame(this.ps);this.ts=[],this.bs=[];for(let t=0;t<e.length;t+=2)append(this.ts,e[t]),append(this.bs,e[t+1]);this.bds=calcFlowBitangent(this.ts,this.bs);for(let t=0;t<this.numPts;t++){map(t,0,this.numPts-1,0,1);let e=this.ps[t].copy(),s=this.ts[t].copy(),r=this.bds[t].copy(),i=p5.Vector.lerp(s,r,riverTanLerp);if(MEANDER_TYPE==REALISTIC){let t=1*pow(map(getNoise(e,.06),.2,.7,.1,1),.1);i.x*=t,i.y*=t}if(DRIFTER){let t=this.vel.x*introAnim,e=this.vel.y*introAnim;i=p5.Vector.add(i,createVector(t,e))}e=p5.Vector.add(e,i),this.ps[t]=e.copy()}}setEndPoints(){this.ps[0]=this.startPos.copy();let t=createVector(R.random_num(-50,50),R.random_num(-50,50));this.ps[0].add(t.copy()),this.ps[this.ps.length-1]=this.endPos.copy(),this.ps[this.ps.length-1].add(t.copy())}writeColors(t){let e=resample(this.ps,4);for(let s=0;s<e.length;s++){let r=e[s].x,i=e[s].y,o=int(r-SIMSIZE+SIMSIZE),n=int(i-SIMSIZE+SIMSIZE);writeColor(o,n,color(255,0,0),t)}}draw(){drawRiver(this.ps,this.bs,this.bds,1,!1)}drawOxbows(){for(let t=0;t<this.oxbows.length;t++)this.oxbows[t].draw()}getPs(){return this.ps}getBs(){return this.bs}getRs(){return this.rs}getStartPos(){return this.startPos}getEndPos(){return this.endPos}}class QuadTree{constructor(t,e,s){this.bounds=t,this.gen=e,this.capacity=s,this.points=[],this.divided=!1}subdivide(){let t=this.bounds.x,e=this.bounds.y,s=this.bounds.w/2,r=this.bounds.h/2,i=new Rectangle(t+s,e-r,s,r);this.northeast=new QuadTree(i,this.gen+1,this.capacity);let o=new Rectangle(t-s,e-r,s,r);this.northwest=new QuadTree(o,this.gen+1,this.capacity);let n=new Rectangle(t+s,e+r,s,r);this.southeast=new QuadTree(n,this.gen+1,this.capacity);let h=new Rectangle(t-s,e+r,s,r);this.southwest=new QuadTree(h,this.gen+1,this.capacity),this.divided=!0}insert(t){if(!this.bounds.contains(t))return!1;if(this.points.length<=this.capacity)return this.points.push(t),this.gen<Q_MAX_GEN&&(this.divided||this.subdivide()),!0;if(this.gen<Q_MAX_GEN){if(this.divided||this.subdivide(),this.northeast.insert(t))return!0;if(this.northwest.insert(t))return!0;if(this.southeast.insert(t))return!0;if(this.southwest.insert(t))return!0}}getRectangles(t){this.divided?(this.northeast.getRectangles(t),this.northwest.getRectangles(t),this.southeast.getRectangles(t),this.southwest.getRectangles(t)):append(t,this.bounds)}draw(t){t.stroke(0),t.fill(100),t.strokeWeight(1),t.rectMode(CENTER),t.rect(this.bounds.x,this.bounds.y,2*this.bounds.w,2*this.bounds.h);for(let e of this.points)t.strokeWeight(2),t.point(e.x,e.y);this.divided&&(this.northeast.draw(t),this.northwest.draw(t),this.southeast.draw(t),this.southwest.draw(t))}}class Field{constructor(t){let e=[];for(let s=0;s<t.length;s++){let r=t[s],i=createVector(r.x,r.y),o=distanceToRiver(i);append(e,o)}let s=0;for(;s<e.length;){for(let r=0;r<e.length-s-1;r++){let s=e[r],i=e[r+1];t[r],t[r+1];s>i&&(swap(e,r,r+1),swap(t,r,r+1))}s++}this.squares=[],this.circles=[],this.squareCount=0,this.circleCount=0;for(let e=0;e<t.length;e++){let s=t[e],r=createVector(s.x,s.y),i=s.w,o=!1;distanceToRiver(r)<120&&(o=!0);let n=new SquarePlot(r,i,o);append(this.squares,n);let h=R.random_num(.5,1);if(R.random_dec()<h&&1!=n.squareType){let t=new CirclePlot(r,i);append(this.circles,t)}}}draw(){for(let t=0;t<5;t++)this.squareCount<this.squares.length&&(this.squares[this.squareCount].draw(landBg),this.squareCount++);if(this.squareCount>=this.squares.length)for(let t=0;t<5;t++)this.circleCount<this.circles.length&&(this.circles[this.circleCount].draw(landBg),this.circleCount++)}}class SquarePlot{constructor(t,e,s){this.pos=t,this.scale=.01*e,this.width=2*e,this.direction=R.random_int(0,1),this.squareType=R.random_int(0,SQUARE_TYPES.length-1),s&&R.random_bool(.7)&&(this.squareType=OVERGROWN,this.direction=0);let r=createVector(this.pos.x-this.width/2,this.pos.y-this.width/2),i=createVector(this.pos.x+this.width/2,this.pos.y-this.width/2),o=createVector(this.pos.x-this.width/2,this.pos.y+this.width/2),n=createVector(this.pos.x+this.width/2,this.pos.y+this.width/2);if(this.corners=[],append(this.corners,r),append(this.corners,i),append(this.corners,o),append(this.corners,n),this.cornerOffset=[],append(this.cornerOffset,createVector(1,1)),append(this.cornerOffset,createVector(-1,1)),append(this.cornerOffset,createVector(1,-1)),append(this.cornerOffset,createVector(-1,-1)),this.plot=new RectPlot(r.x,r.y,n.x,n.y),this.plots=[],this.squareType!=DIVIDED){let t=R.random_num(.6,1.3);s&&(t=.2),this.plot.setDensity(t),append(this.plots,this.plot)}else{let t=R.random_int(2,5);this.plots=this.plot.split(t);for(let e=0;e<t;e++){let t=R.random_num(.5,1);this.plots[e].setDensity(t)}}this.hasRemnant=this.squareType==REMNANT,this.hasStorage=R.random_bool(.8),s&&(this.hasStorage=!1),this.squareType==OVERGROWN&&(this.hasStorage=!1)}draw(t){for(let e=0;e<this.plots.length;e++){this.plots[e].draw(t,this.direction,this.hasRemnant)}}drawStorage(t){let e=R.random_int(1,5),s=R.random_int(1,5),r=.05*this.width,i=R.random_int(0,3),o=this.corners[i],n=this.cornerOffset[i],h=R.random_num(.5,2),a=R.random_num(.5,2),p=[];t.fill(fgColor),t.noStroke();for(let i=0;i<e;i++)for(let e=0;e<s;e++)if(R.random_bool(.8)){let s=o.x+(r+i*h*1.2)*n.x,l=o.y+(r+e*a*1.2)*n.y;append(p,createVector(s,l)),t.rect(s+.5*SUN_DIRECTION.x,l+.5*SUN_DIRECTION.y,h,a)}t.fill(bgColor);for(let e=0;e<p.length;e++){let s=p[e];t.rect(s.x,s.y,h,a)}}} class CirclePlot{constructor(e,t){this.pos=e,this.scale=.01*t,this.width=2*t,this.radius=t;let o=map(this.radius,10,MYHALF,5,16);this.ringRadii=[];for(let e=0;e<2*o;e++){let t=map(e,0,2*o,0,1),i=map(t,0,1,0,this.radius);e%2==1&&append(this.ringRadii,i)}this.numRings=this.ringRadii.length,this.angle=R.random_num(0,TWO_PI),this.numStripes=int(this.radius/R.random_num(mainGapMin,mainGapMax)),R.random_bool(.2)&&(this.numStripes=int(1.5*this.numStripes)),this.plotType=getPlotType(),this.densities=[],this.rot=R.random_int(0,3),this.setDensities(this.plotType)}setDensities(e){if(e==EMPTY)this.densities=[0,0,0,0];else if(e==FULL){let e=R.random_num(.2,1);this.densities=[e,e,e,e]}else if(e==HALVED){let e=R.random_num(.2,1),t=R.random_num(.2,1);this.densities=[e,t,e,t],this.rot%2==1&&(this.densities=[e,e,t,t])}else if(e==HALF_QUARTERED){let e=R.random_num(.2,1),t=R.random_num(.2,1),o=R.random_num(.2,1);this.densities=[e,t,o,o],this.rot%2==1&&(this.densities=[e,t,o,t])}else if(e==QUARTERED){let e=R.random_num(.2,1),t=R.random_num(.2,1),o=R.random_num(.2,1),i=R.random_num(.2,1);this.densities=[e,t,o,i]}}draw(e){if(this.plotType>EMPTY){let t=getColor(R.random_dec());e.noStroke(),e.fill(red(t),green(t),blue(t),R.random_int(20,100)),e.circle(this.pos.x,this.pos.y,this.radius),this.drawConcentricCircles(e),this.drawAccessRoad(e),this.drawSwingArm(e)}}drawMainCircle(e){e.noStroke(),e.fill(bgColor),e.circle(this.pos.x,this.pos.y,this.radius-1),e.stroke(edgeColor),e.strokeWeight(mainSw),this.drawDottedCircle(e,this.pos,this.radius)}drawQuarterFieldLines(e){e.stroke(fgColor),e.strokeWeight(mainSw);let t=this.radius-2,o=[];for(let e=0;e<2*this.numStripes;e++){let i,r;if(this.rot%2==0){let o=map(e,0,2*this.numStripes,-t,t),s=sqrt(t*t-o*o);i=createVector(this.pos.x+o,this.pos.y+s),r=createVector(this.pos.x+o,this.pos.y-s)}else{let o=map(e,0,2*this.numStripes,-t,t),s=sqrt(t*t-o*o);i=createVector(this.pos.x-s,this.pos.y+o),r=createVector(this.pos.x+s,this.pos.y+o)}append(o,i),append(o,r)}let i=o.length;for(let t=0;t<i-1;t+=2){let i=resampleLine(o[t],o[t+1],mainGapMax);for(let t=0;t<i.length-1;t++){let o=i[t],r=i[t+1];p5.Vector.dist(this.pos,o);o.x<this.pos.x&&o.y<this.pos.y?this.drawFieldLine(e,o,r,this.densities[0],t):o.x>this.pos.x&&o.y<this.pos.y?this.drawFieldLine(e,o,r,this.densities[1],t):o.x<this.pos.x&&o.y>this.pos.y?this.drawFieldLine(e,o,r,this.densities[2],t):this.drawFieldLine(e,o,r,this.densities[3],t)}}}drawFieldLine(e,t,o,i,r){let s=i;s>.7?(e.point(t.x,t.y),e.point(.5*t.x+.5*o.x,.5*t.y+.5*o.y),e.point(t.x+1,t.y+1)):s>.4?e.line(t.x,t.y,o.x,o.y):e.point(t.x,t.y)}drawConcentricCircles(e){e.noFill(),e.stroke(fgColor),e.strokeWeight(.5*this.scale);for(let t=0;t<this.numRings;t++)this.drawDottedCircle(e,this.pos,this.ringRadii[t])}drawDottedCircle(e,t,o){let i=[];for(let e=0;e<180;e++){let r=map(e,0,180,0,TWO_PI),s=t.x+cos(r)*o,n=t.y+sin(r)*o;append(i,createVector(s,n))}let r=resample(i,1);for(let t=0;t<r.length-1;t++)if(t%3==0){let o=r[t],i=r[t+1];e.line(o.x,o.y,i.x,i.y)}}drawAccessRoad(e){let t,o,i=R.random_int(0,3);0==i?(t=.5*this.width,o=0):1==i?(t=.5*-this.width,o=0):2==i?(t=0,o=.5*this.width):(t=0,o=.5*-this.width);let r=map(this.radius,0,MYHALF,1,6);e.strokeWeight(r-mainSw),e.stroke(bgColor),e.line(this.pos.x,this.pos.y,this.pos.x+t,this.pos.y+o),e.fill(bgColor),e.noStroke(),e.circle(this.pos.x,this.pos.y,r-mainSw)}drawSwingArm(e){let t=.5*this.scale;e.stroke(fgColor),e.strokeWeight(t);for(let o=0;o<this.numRings;o++){let i=this.ringRadii[o],r=Math.cos(this.angle)*(i-.5*this.scale),s=Math.sin(this.angle)*(i-.5*this.scale),n=Math.cos(this.angle)*(i+.5*this.scale),l=Math.sin(this.angle)*(i+.5*this.scale);e.circle(this.pos.x+r,this.pos.y+s,.5*t),e.circle(this.pos.x+n,this.pos.y+l,.5*t)}let o=Math.cos(this.angle)*this.radius*.995,i=Math.sin(this.angle)*this.radius*.995;e.line(this.pos.x,this.pos.y,this.pos.x+o,this.pos.y+i),e.stroke(bgColor),e.line(this.pos.x-.2*SUN_DIRECTION.x,this.pos.y-.2*SUN_DIRECTION.y,this.pos.x+o-.2*SUN_DIRECTION.x,this.pos.y+i-.2*SUN_DIRECTION.y)}}function reset(e){print(tokenData),print(tokenData.tokenId),dim=Math.min(windowWidth,windowHeight),hdim=dim/2,buffer=createCanvas(dim,dim),pixelDensity(e),myFrameCount=0,R=new Random,setupFeatures(),setupColors(),noiseSeed(R.random_dec()),noiseDetail(3,.3),nox=R.random_num(500,5e3),noy=R.random_num(500,5e3),mainRand=R.random_dec(),mainSw=.5,mainGapMin=2,mainGapMax=2,landBg=createGraphics(MYSIZE,MYSIZE),landBg.ellipseMode(RADIUS),setupWeather(),setupOverlay(),setupRiver(),setupPlots(),setupPoisson(),setupContours(),setupGrid(),setupRail(),myFrameCount=0,introAnim=0,outroAnim=1}function setup(){reset(2)}function setupFeatures(){let e=R.random_dec();BIOME=e<.15?FARMLAND:e<.35?SWAMP:e<.5?DESERT:e<.7?ARCTIC:MOUNTAINS,RENDER_TYPE=R.random_bool(.9)?0:2;let t,o=[1,7,11,14,16,17,19,20],i=[0,12,13,15,20],r=[3,10,19,20],s=R.random_dec();PALETTE_ID=s<.15?0:s<.3?1:s<.4?2:s<.45?3:s<.5?4:s<.6?5:R.random_int(6,PALETTES.length-2),2==RENDER_TYPE&&(PALETTE_ID=20),BIOME==DESERT?(t=R.random_int(0,o.length-1),PALETTE_ID=o[t]):BIOME==ARCTIC?(t=R.random_int(0,i.length-1),PALETTE_ID=i[t]):BIOME==SWAMP&&(t=R.random_int(0,r.length-1),PALETTE_ID=r[t]);let n=R.random_dec();if(COMP=n<.3?0:n<.6?1:n<.8?2:n<.9?3:n<.98?4:5,GRID_TYPE=R.random_int(0,GRID_TYPES.length-1),BIOME==FARMLAND&&(GRID_TYPE=0),HISTORY_TYPE=R.random_int(0,HISTORY_TYPES.length-1),BIOME==FARMLAND)CITY_TYPE=REMOTE,LAND_TYPE=R.random_bool(.8)?LAND_MIXED:LAND_SPARSE;else if(BIOME==SWAMP){let e=R.random_dec();CITY_TYPE=e<.1?REMOTE:e<.3?RURAL:TOWN,e=R.random_dec(),LAND_TYPE=e<.4?LAND_SWAMP:e<.8?LAND_MIXED:LAND_SPARSE}else if(BIOME==DESERT){let e=R.random_dec();CITY_TYPE=e<.1?REMOTE:e<.3?RURAL:TOWN,e=R.random_dec(),LAND_TYPE=e<.4?LAND_DESERT:e<.8?LAND_MIXED:LAND_SPARSE}else if(BIOME==ARCTIC){let e=R.random_dec();CITY_TYPE=e<.1?REMOTE:e<.4?RURAL:TOWN,LAND_TYPE=LAND_ARCTIC}else if(BIOME==MOUNTAINS){let e=R.random_dec();CITY_TYPE=e<.1?REMOTE:e<.35?RURAL:e<.95?TOWN:TWIN_TOWNS,LAND_TYPE=R.random_bool(.2)?LAND_DESERT:LAND_MOUNTAIN}COLOR_TYPE=R.random_int(0,COLOR_TYPES.length-1),0==COLOR_TYPE?HISTORY_CONTRAST=.4:HISTORY_CONTRAST=.8;let l=R.random_dec();MEANDER_TYPE=l<.5?EXCESSIVE:l<.9?REALISTIC:CLOSEUP,LINE_TYPE=R.random_int(0,LINE_TYPES.length-1),0==LINE_TYPE&&R.random_bool(.5)&&(LINE_TYPE=1),MEANDER_TYPE==CLOSEUP&&(LINE_TYPE=1),DRIFTER=!!R.random_bool(.4),MEANDER_TYPE==CLOSEUP&&(DRIFTER=!1),TREASURE_MAP=!!R.random_bool(.01),HAS_BORDER=!!R.random_bool(.7),HAS_RAILROAD=!!R.random_bool(.05),CITY_TYPE==REMOTE&&(HAS_RAILROAD=!1),HAS_CONTOURS=!!R.random_bool(.2),HAS_POISSON=!!R.random_bool(.2),HEAVY_SEASON_FREQ=0,R.random_bool(.2)&&(HEAVY_SEASON_FREQ=R.random_num(0,.2))}function setupColors(){createColors(PALETTE_ID),INVERTED=!1;let e=R.random_int(2,4),t=0;R.random_dec()<.25&&(INVERTED=!0,e=R.random_int(0,2),t=4),fgColor=cs[t],bgColor=cs[e],2==RENDER_TYPE&&(fgColor=cs[0],bgColor=cs[4],INVERTED&&(fgColor=cs[4],bgColor=cs[0])),INVERTED?(edgeColor=lerpColor(bgColor,color(255),.4),dkFgColor=lerpColor(fgColor,color(0),.5),ltFgColor=lerpColor(fgColor,color(255),.5),dkBgColor=lerpColor(bgColor,color(0),.5),ltBgColor=lerpColor(bgColor,color(255),.5)):(edgeColor=lerpColor(bgColor,color(0),.4),dkFgColor=lerpColor(fgColor,color(0),.5),ltFgColor=lerpColor(fgColor,color(255),.5),dkBgColor=lerpColor(bgColor,color(0),.5),ltBgColor=lerpColor(bgColor,color(255),.5)),highlightColor=color(255,255,255,30),shadowColor=color(0,0,0,60)}function setupWeather(){SUN_DIRECTION=createVector(R.random_num(-1,1),R.random_num(.3,1)),SUN_DIRECTION.normalize(),2==RENDER_TYPE&&(SUN_DIRECTION=createVector(R.random_num(-1,1),R.random_num(.3,1)),SUN_DIRECTION.normalize())}function setupOverlay(){overlayFg=createGraphics(MYSIZE,MYSIZE)}function setupRiver(){riverDur=450,DRIFTER&&(riverDur=650),riverSpacing=R.random_int(10,25),5==COMP&&(riverSpacing=8),MEANDER_TYPE==CLOSEUP&&(riverSpacing=45),riverSpeed=float(riverSpacing)*R.random_num(.3,.4)*5,MEANDER_TYPE==CLOSEUP&&(riverSpeed*=.85),riverWidth=.8*riverSpacing+1,riverTanLerp=.15,riverHistoryIter=R.random_int(5,10),riverCollSpacing=int(riverSpacing/2)+3;let e=2*float(riverSpacing);MEANDER_TYPE==CLOSEUP&&(e*=1.75),riverCollDistSqrd=e*e,riverStartFrame=3,riverHistoryCount=0,riverBg=createGraphics(MYSIZE,MYSIZE),riverFg=createGraphics(MYSIZE,MYSIZE),river=new River(COMP),riverBg.background(0,0,0,0),riverFg.background(0,0,0,0)}function setupPlots(){plots=[],plotsImg=createImage(SIMSIZE,SIMSIZE),plotBg=createGraphics(MYSIZE,MYSIZE),plotBg.ellipseMode(RADIUS),plotGrowthSpeed=.65,plotTypeThresh=.4,BIOME==SWAMP?plotTypeThresh=R.random_num(.3,.5):BIOME==DESERT?plotTypeThresh=1:BIOME==MOUNTAINS&&(plotTypeThresh=R.random_num(.2,.3)),plotStartFrame=riverDur}function setupPoisson(){poissonStartFrame=2,poisson=new FastPoisson}function setupContours(){contoursStartFrame=3,contours=new Contours}function setupGrid(){0!=GRID_TYPE&&makeGrid(fgColor,landBg)}function setupRail(){railStartFrame=350}function setupQuadTree(){R.random_int(10,40);let e=new Rectangle(MYHALF,MYHALF,MYHALF,MYHALF);qTree=new QuadTree(e,0,0);let t,o=map(riverSpacing,8,25,0,3)%3;t=0==o?R.random_int(225,440):1==o?R.random_int(135,185):R.random_int(63,104);for(let e=0;e<t;e++){addPointToQuadTree(new Point(R.random_num(100,MYSIZE-100),R.random_num(100,MYSIZE-100)))}let i=river.getPs();for(let e=0;e<i.length;e+=3){let t=i[e],o=R.random_num(-50,50),r=R.random_num(-50,50);addPointToQuadTree(createVector(t.x+o,t.y+r))}qRects=[],qTree.getRectangles(qRects),qUpdated=!0}function setupField(){field=new Field(qRects)}function addPointToQuadTree(e){qTree.insert(e),qRects=[],qTree.getRectangles(qRects),qUpdated=!0}function keyTyped(){"d"==key||("r"==key?(SAVE_PRINT_RES=!1,SAVE_ALT_PRINT_RES=!1,reset(2)):"s"==key?SAVE_IMAGE=!0:"h"==key?(reset(8),SAVE_PRINT_RES=!0):"H"==key&&(reset(8),SAVE_ALT_PRINT_RES=!0))} function updateTreasure(){if(TREASURE_MAP){let e=riverDur;if(myFrameCount==e)tps=makeTreasure();else if(myFrameCount>e){let t=tps.length,r=myFrameCount-e,o=r+1;if(o<t&&o%2==0){let e=tps[r],t=tps[o];overlayFg.strokeWeight(.5),overlayFg.stroke(edgeColor),overlayFg.line(e.x,e.y,t.x,t.y)}else o==t&&xMarksTheSpot(overlayFg)}}}function updateContours(){1==myFrameCount&&contours.draw(landBg)}function updateRiver(){myFrameCount<riverDur?(river.checkOxbows(),river.updateOxbows(),river.update(),river.setEndPoints()):myFrameCount==riverDur&&(plotsImg.loadPixels(),river.writeColors(plotsImg),plotsImg.updatePixels())}function updatePlots(){if(myFrameCount==plotStartFrame&&createPlotNetwork(river.getPs(),river.getBs()),myFrameCount>=plotStartFrame){plotsImg.loadPixels();for(let e=0;e<plots.length;e++)plots[e].update();for(let e=0;e<plots.length;e++)plots[e].render();plotsImg.updatePixels();for(let e=0;e<plots.length;e++)plots[e].drawLine()}}function updateRail(){HAS_RAILROAD&&(myFrameCount==riverDur?rail=new Rail(river.getStartPos(),river.getEndPos()):myFrameCount>riverDur&&rail.update())}function updatePoisson(){myFrameCount==riverDur&&(poisson.solve(),poisson.draw(landBg))}function updateContours(){myFrameCount==riverDur&&(contours.solve(river.getPs()),contours.draw(landBg))}function cleanPlots(){for(let e=0;e<plots.length;e++){plots[e].isDead()&&plots.splice(e,1)}}function drawOverlay(){let e=R.random_int(0,1);BIOME==FARMLAND&&(e=1),2==RENDER_TYPE&&(e=0),0==e?borderWidth=.075*MYSIZE:1==e&&(borderWidth=.125*MYSIZE),overlayFg.noFill(),overlayFg.strokeWeight(borderWidth),overlayFg.stroke(bgColor),overlayFg.rect(0,0,MYSIZE,MYSIZE);let t=.5,r=2*t,o=R.random_int(2,5);for(let e=0;e<o;e++){let e=R.random_num(.25*mainSw,2*mainSw);overlayFg.strokeWeight(e),overlayFg.stroke(edgeColor),overlayFg.rect(borderWidth*t,borderWidth*t,MYSIZE-borderWidth*r,MYSIZE-borderWidth*r),r=2*(t=R.random_num(.3,.5))}}function update(){myFrameCount<riverDur&&riverFg.clear(),updateRiver(),BIOME!=DESERT&&BIOME!=MOUNTAINS&&BIOME!=ARCTIC&&BIOME!=SWAMP||updatePlots(),BIOME!=DESERT&&BIOME!=SWAMP&&BIOME!=ARCTIC||updatePoisson(),BIOME==MOUNTAINS&&updateContours(),BIOME!=FARMLAND&&updateRail(),updateTreasure()}function draw(){if(background(bgColor),myFrameCount<TOTAL_DUR&&(update(),myFrameCount>riverStartFrame&&(river.drawOxbows(),river.draw()),HAS_RAILROAD&&rail&&rail.draw(),1==myFrameCount&&HAS_BORDER&&drawOverlay()),myFrameCount==riverDur+1&&BIOME==FARMLAND&&(setupQuadTree(),setupField()),myFrameCount>riverDur+1&&qUpdated&&field.draw(),myFrameCount<=riverDur&&BIOME==FARMLAND&&(landBg.blendMode(REMOVE),drawScreenOverlay(landBg,fgColor,2,.5*mainSw),landBg.blendMode(BLEND)),image(landBg,0,0,dim,dim),image(plotBg,0,0,dim,dim),image(riverBg,0,0,dim,dim),image(riverFg,0,0,dim,dim),image(overlayFg,0,0,dim,dim),clean(),SAVE_IMAGE){let e=(new Date).getTime();save(buffer,str(e),"png"),SAVE_IMAGE=!1}if(SAVE_PRINT_RES||SAVE_ALT_PRINT_RES){if(myFrameCount==TOTAL_DUR){let e=(new Date).getTime();save(buffer,str(e),"png"),SAVE_PRINT_RES=!1,SAVE_ALT_PRINT_RES=!1}let e=map(myFrameCount,1,TOTAL_DUR,0,dim);fill(255,0,0),noStroke(),rect(0,dim-5,e,dim)}if(SHOW_DETAILS){let e=125,t=dim-370,r=20;fill(color(0)),INVERTED&&fill(color(255)),noStroke(),textSize(15),textFont("Serif"),text(myFrameCount,e,dim-120),text("Biome: ",e,t+0*r),text("Composition: ",e,t+1*r),text("Meander Type: ",e,t+2*r),text("Drifter: ",e,t+3*r),text("Line type: ",e,t+4*r),text("Color type:",e,t+5*r),text("Population: ",e,t+6*r),text("Grid: ",e,t+7*r),text("Palette: ",e,t+8*r),text("History: ",e,t+9*r),text("Railroad: ",e,t+10*r),text("Treasure Map: ",e,t+11*r),e+=200,text(frameRate(),e,dim-120),text(BIOMES[BIOME],e,t+0*r),text(COMPS[COMP],e,t+1*r),text(MEANDER_TYPES[MEANDER_TYPE],e,t+2*r),text(DRIFTER?"TRUE":"FALSE",e,t+3*r),text(LINE_TYPES[LINE_TYPE],e,t+4*r),text(COLOR_TYPES[COLOR_TYPE],e,t+5*r),text(CITY_TYPES[CITY_TYPE],e,t+6*r),text(GRID_TYPES[GRID_TYPE],e,t+7*r),text(PALETTES[PALETTE_ID],e,t+8*r),text(HISTORY_TYPES[HISTORY_TYPE],e,t+9*r),text(HAS_RAILROAD?"TRUE":"FALSE",e,t+10*r),text(TREASURE_MAP?"TRUE":"FALSE",e,t+11*r)}myFrameCount++,introAnim=pow(map(myFrameCount,0,introDur,0,1,!0),2),riverFramePer=map(myFrameCount,0,riverDur,0,1),myFrameCount%riverHistoryIter==1&&riverHistoryCount++}function clean(){cleanPlots()}