ID:195081
 
/*
Title: Grass Generator
Credit To: Lummox JR
Contributed By: Audeuro

Refer to http://developer.byond.com/forum/index.cgi?action=message_read&id=431346&forum=5&view=1

To use, simply call DrawGrass(). DrawGrass() returns an /icon of grass.
*/


icon
var/icon/nexti
var/icon/nextj

proc/DrawWrapPixel(overlapdir,color,x,y)
x=round(x,1)
y=round(y,1)
if(x<1 || x>32)
if(nexti)
if(x<1 && (overlapdir&WEST)) return nexti.DrawWrapPixel(overlapdir,color,x+32,y)
if(x>32 && (overlapdir&EAST)) return nexti.DrawWrapPixel(overlapdir,color,x-32,y)
x=(x-1)%32+1
if(y<1 || y>32)
if(nextj)
if(y<1 && (overlapdir&SOUTH)) return nextj.DrawWrapPixel(overlapdir,color,x,y+32)
if(y>32 && (overlapdir&NORTH)) return nextj.DrawWrapPixel(overlapdir,color,x,y-32)
y=(y-1)%32+1
DrawBox(color,x,y)

proc/DrawGrass(grassprob=80,startangle=20,anglevariance=15,avglength=5,lengthvariance=1,nooverlay)
if(startangle<0 || startangle>=360) startangle-=360*round(startangle/360)
var/overlapdir=0
if(startangle<90 || startangle>270) overlapdir=NORTH
else if(startangle>90 && startangle<270) overlapdir=SOUTH
if(startangle<180) overlapdir|=EAST
else if(startangle<180) overlapdir|=WEST
var/icon/I=new('blank.dmi')
if(overlapdir&12) I.nexti=new('blank.dmi')
if(overlapdir&3)
I.nextj=new('blank.dmi')
if(I.nexti)
I.nexti.nextj=new('blank.dmi')
I.nextj.nexti=I.nexti.nextj
var/xs=(overlapdir&EAST)?32:1
var/xinc=(overlapdir&EAST)?-1:1
var/ys=(overlapdir&NORTH)?32:1
var/yinc=(overlapdir&NORTH)?-1:1
var/i,j,x,y
for({j=32;y=ys},j>0,{--j;y+=yinc})
for({i=32;x=xs},i>0,{--i;x+=xinc})
if(!prob(grassprob)) continue
DrawBlade(I,startangle,anglevariance,avglength,lengthvariance,overlapdir,x,y)
if(nooverlay) return I
var/icon/J
if(I.nextj)
for(J=I,J,J=J.nexti) J.Blend(J.nextj, ICON_OVERLAY)
if(I.nexti) I.Blend(I.nexti, ICON_OVERLAY)
return I

proc/GaussRand()
var/x,y,rsq
do
x=2*rand()-1
y=2*rand()-1
rsq=x*x+y*y
while(rsq>1 || !rsq)
return y*sqrt(-2*log(rsq)/rsq)

proc/DrawBlade(icon/I,startangle,anglevariance,avglength,lengthvariance,overlapdir,x,y,grav=0.1)
var/angle=startangle+anglevariance*GaussRand()
var/l=avglength+lengthvariance*GaussRand()
var/ht=1/avglength
if(angle>89 && angle<91) angle=pick(89,90)
while(l-->0)
var/col=max(0,1-abs(angle-45)/90)*min(ht,1)
I.DrawWrapPixel(overlapdir,rgb(0,32+col*96,0),x,y)
var/sa=sin(angle)
var/ca=cos(angle)
x+=sa
y+=ca
ht+=ca/avglength
angle=arccos((ca-2*sa*grav)/sqrt(sa*sa+(ca-2*sa*grav)*(ca-2*sa*grav)))
if(sa<0) angle=-angle