<spot>
<head>
	<debug/>
	<blockset href="http://blocks.flatland.com/flatsets/basic.bset"/>
	<blockset href="http://blocks.flatland.com/flatsets/basic2.bset"/>
	<blockset href="http://blocks.flatland.com/simon/wasp.bset"/>
	<map dimensions="(20,20,5)"/>
	<title name="Boids"/>
	<sky colour="(0,0,255)"/>
	<ground/>
	<ambient_light brightness="80%"/>
</head>
<body>


<create symbol="a" block="wasp">
	<param movable="yes"/>
	<define>        
	<v x="0.0" y="0.0" z="0.0" />
	<fixed>1</fixed>    
	</define>
</create>

<create symbol="b" block="wasp"> 
	<param movable="yes"/>    
	<define>          
	<v x="0.0" y="0.0" z="0.0" />     
	</define>
</create>

<create symbol="c" block="wasp"> 
	<param movable="yes"/>    
	<define>          
	<v x="0.0" y="0.0" z="0.0" />     
	</define>
</create>

<create symbol="d" block="wasp"> 
	<param movable="yes"/>    
	<define>          
	<v x="0.0" y="0.0" z="0.0" />     
	</define>
</create>

<create symbol="e" block="wasp"> 
	<param movable="yes"/>    
	<define>          
	<v x="0.0" y="0.0" z="0.0" />     
	</define>
</create>

<create symbol="o" block="wasp"> 
	<define>
	<tempv x="0" y="0" z="0"/>  // temp vector
	<v1 x="0" y="0" z="0"/>  // placeholder vector
	<v2 x="0" y="0" z="0"/>  // placeholder vector
	<v3 x="0" y="0" z="0"/>  // placeholder vector
	<v4 x="0" y="0" z="0"/>  // placeholder vector
	<fcenter x="0" y="0" z="0"/>  // flock center
	<fvelocity x="0" y="0" z="0"/>  // flock center
	<pos1  x="0" y="0" z="0"/>  // holder for boid position
	<pos2  x="0" y="0" z="0"/>  // holder for boid position
	<function name="vClear" params="v">
	        v:x = 0;
	        v:y = 0;
	        v:z = 0;
	        return(v);
	</function>
	<function name="vSub" params="v,a,b">
	        v:x = a:x - b:x;
	        v:y = a:y - b:y;
	        v:z = a:z - b:z;
	        return(v);
	</function>
	<function name="vAdd" params="v,a,b">
	        v:x = a:x + b:x;
	        v:y = a:y + b:y;
	        v:z = a:z + b:z;
	        return(v);
	</function>
	<function name="getPosition" params="v,boid">
	        v:x = boid.location:x;
	        v:y = boid.location:y;
	        v:z = boid.location:z;
	        return(v);
	</function>
	<function name="setFlockCenter" params="b1,b2,b3,b4,b5">
		fcenter:x = 0.0;
		fcenter:y = 0.0;
		fcenter:z = 0.0;
		fcenter:x = (b1.location:x + b2.location:x + b3.location:x + b4.location:x + b5.location:x) / 5;
		fcenter:y = (b1.location:y + b2.location:y + b3.location:y + b4.location:y + b5.location:y) / 5;
		fcenter:z = (b1.location:z + b2.location:z + b3.location:z + b4.location:z + b5.location:z) / 5;
	</function>
	<function name="Rule1" params="boid"> // move towards center
		v1:x = (fcenter:x - boid.location:x) / 100;
		v1:y = (fcenter:y - boid.location:y) / 100;
		v1:z = (fcenter:z - boid.location:z) / 100;
	</function>
	<function name="Rule2" params="boid,b1,b2,b3,b4"> // move away from close birds
		v2:x = 0.0;
		v2:y = 0.0;
		v2:z = 0.0;
		pos1:x = boid.location:x;
		pos1:y = boid.location:y;
	        pos1:z = boid.location:z;
		pos2:x = b1.location:x;
		pos2:y = b1.location:y;
	        pos2:z = b1.location:z;
		tempv:x = pos1:x - pos2:x;
		tempv:y = pos1:y - pos2:y;
		tempv:z = pos1:z - pos2:z;
		if ((tempv:x lt 15) and (tempv:x gt -15)) {
			v2:x = v2:x - tempv:x;
		}
		if ((tempv:y lt 15) and (tempv:y gt -15)) {
			v2:y = v2:y - tempv:y;
		}
		if ((tempv:z lt 15) and (tempv:z gt -15)) {
			v2:z = v2:z - tempv:z;
		}
	spot.title = "v " # v2:x # " " # v2:y # " " # v2:z;
		pos2:x = b2.location:x;
		pos2:y = b2.location:y;
	        pos2:z = b2.location:z;
		tempv:x = pos1:x - pos2:x;
		tempv:y = pos1:y - pos2:y;
		tempv:z = pos1:z - pos2:z;
		if ((tempv:x lt 50) and (tempv:x gt -50)) {
			v2:x = v2:x - tempv:x;
		}
		if ((tempv:y lt 50) and (tempv:y gt -50)) {
			v2:y = v2:y - tempv:y;
		}
		if ((tempv:z lt 50) and (tempv:z gt -50)) {
			v2:z = v2:z - tempv:z;
		}
		pos2:x = b3.location:x;
		pos2:y = b3.location:y;
	        pos2:z = b3.location:z;
		tempv:x = pos1:x - pos2:x;
		tempv:y = pos1:y - pos2:y;
		tempv:z = pos1:z - pos2:z;
		if ((tempv:x lt 50) and (tempv:x gt -50)) {
			v2:x = v2:x - tempv:x;
		}
		if ((tempv:y lt 50) and (tempv:y gt -50)) {
			v2:y = v2:y - tempv:y;
		}
		if ((tempv:z lt 50) and (tempv:z gt -50)) {
			v2:z = v2:z - tempv:z;
		}
		pos2:x = b4.location:x;
		pos2:y = b4.location:y;
	        pos2:z = b4.location:z;
		tempv:x = pos1:x - pos2:x;
		tempv:y = pos1:y - pos2:y;
		tempv:z = pos1:z - pos2:z;
		if ((tempv:x lt 50) and (tempv:x gt -50)) {
			v2:x = v2:x - tempv:x;
		}
		if ((tempv:y lt 50) and (tempv:y gt -50)) {
			v2:y = v2:y - tempv:y;
		}
		if ((tempv:z lt 50) and (tempv:z gt -50)) {
			v2:z = v2:z - tempv:z;
		}
	</function>
	<function name="setFlockVelocity" params="b1,b2,b3,b4,b5">
		fvelocity:x = 0;
		fvelocity:y = 0;
		fvelocity:z = 0;
		fvelocity:x = (fvelocity:x + b1.v:x + b2.v:x + b3.v:x + b4.v:x + b5.v:x) / 5;
		fvelocity:y = (fvelocity:y + b1.v:y + b2.v:y + b3.v:y + b4.v:y + b5.v:y) / 5;
		fvelocity:z = (fvelocity:z + b1.v:z + b2.v:z + b3.v:z + b4.v:z + b5.v:z) / 5;
	</function>
	<function name="Rule3" params="boid"> // adjust velocity to match nearby
		v3:x = (fvelocity:x - boid.v:x) / 8;
		v3:y = (fvelocity:y - boid.v:y) / 8;
		v3:z = (fvelocity:z - boid.v:z) / 8;
	</function>	
	<function name="Rule4" params="boid"> // bound position
		v4:x = 0.0;
		v4:y = 0.0;
		v4:z = 0.0;
		if (boid.location:x lt 512.0) {v4:x = 10;}
		if (boid.location:x gt 2500.0) {v4:x = -10;}
		if (boid.location:y lt 800.0) {v4:y = 20;}
		if (boid.location:y gt 1000.0) {v4:y = -20;}
		if (boid.location:z lt 512.0) {v4:z = 10;}
		if (boid.location:z gt 2500.0) {v4:z = -10;}
	</function>
	<function name="MoveBoid" params="boid,b1,b2,b3,b4"> 
		Rule1(boid);
		Rule2(boid,b1,b2,b3,b4);
		Rule3(boid);
		Rule4(boid);
		boid.v:x = boid.v:x + v1:x + v2:x + v3:x + v4:x;
		boid.v:y = boid.v:y + v1:y + v2:y + v3:y + v4:y;
		boid.v:z = boid.v:z + v1:z + v2:z + v3:z + v4:z;
		boid.location:x = boid.location:x + boid.v:x;
		boid.location:y = boid.location:y + boid.v:y;
		boid.location:z = boid.location:z + boid.v:z;
	</function>
	</define>
	<script trigger="timer" delay="0.10">  
		p1 = map.get_block("a");    
		p2 = map.get_block("b");
		p3 = map.get_block("c"); 
		p4 = map.get_block("d");
		p5 = map.get_block("e");
		setFlockCenter(p1,p2,p3,p4,p5);
		setFlockVelocity(p1,p2,p3,p4,p5);
		MoveBoid(p1,p2,p3,p4,p5);
		MoveBoid(p2,p3,p4,p5,p1);
		MoveBoid(p3,p4,p5,p1,p2);
		MoveBoid(p4,p5,p1,p2,p3);
		MoveBoid(p5,p1,p2,p3,p4);
	</script>
</create>	
<create symbol="A" block="wasp">
</create>
<level number="1">
o...................
#...................
....................
....................
....................
....................
....................
....................
....................
........A...........
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
</level>
<level number="2">
....................
#...................
....................
....................
....................
....................
.............b......
.....a..............
....................
....................
....................
...............c....
....................
....................
....................
....................
....................
....................
............e.......
....................
....................
</level>
<level number="3">
....................
#...................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....d...............
....................
....................
....................
....................
....................
</level>
<level number="4">
....................
#...................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
</level>
<level number="5">
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
</level>

<entrance name="default" location="(1,2,5)" angle="180"/>


</body>
</spot>
