~extremepopcorn/dhlib/dhlib_ep

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package fortress;

import mathx.MatrixUtil;
import mathx.MathUtil;
import mathx.Geometry;
import mathx.Point2;
import mathx.MatPoint;
import mathx.MatrixGeom;

import flash.display.Sprite;

class WalkerObject extends AttackingLiveObject
{
	private var target : Point2;	//what we are trying to get to
	private var walkTarget : Point2; //where we are walking to now
	private var walkTimeout : Float;
	private var walkTime : Float;
	private var pause : Float;
		
	var image : Sprite;
	
	public function new ( gd : GameDriver )
	{
		super( gd,  gd.global.walkerFireSpeed, Point2.at( 1, 1 ) );
		
		speed = gameDriver.global.walkerSpeed;
		maxHP = hp = gameDriver.global.walkerHP;
		pause = 0;
			
		image = new IClipWalker();
		image.width = GConst.gridSizeX * size.x;
		image.height = GConst.gridSizeY * size.y;
		image.x = -GConst.gridSizeX*size.x/2;
		image.y = -GConst.gridSizeY*size.y/2;
		addChild( image );
		
		draw();
	}
	
	override public function getScoreFactor() : Float
	{
		return 0.5;
	}
	
	override function stepMove( elapsed : Float )
	{
		//we will be paused if we did damage somewhere.
		if( pause < 0 )
		{
			pause += elapsed;
			if( pause >= 0 )
				orient = Geometry.xAxisAngleV( dir ) + Math.PI/2;
			else
				orient += elapsed * Math.PI * 2;
			return;
		}
		
		//how far are we from our walking target (to decide when we need to change directions
		//we use a timeout to change cases even if we overshoot the target
		walkTime += elapsed;
		if( walkTime >= walkTimeout )
		{
			walkTime = 0;
			//get next land nearest our target
			
			//check surrounding land and take one nearest our target
			//TODO: This is the same as in BoatObject, and similar to many other places, make generic!
			var land : MatPoint = null;
			var dist : Float = 0;
			for( mp in MatrixGeom.dirs4 )
			{
				var n = at.floorDemote().add( mp );
				var ct = gameDriver.data.map.landMap.def_get( n.x, n.y, MapData.ctUnknown );
				var mod = gameDriver.data.map.modMap.def_get( n.x, n.y, 0 );
				
				//it must be land (though it can be occupied, in which case we attack it)
				if( !(ct == MapData.ctLand || ct == MapData.ctWall ) )
					continue;
					
				var ndist = target.distanceTo( n.promoteCtrF() );
				if( land == null || ndist < dist )
				{
					land = n;
					dist = ndist;
				}
			}
			
			Assert.notNull( land );
			walkTarget = land.promoteCtrF();
			dir = at.unitVectorTo( walkTarget );
			orient = Geometry.xAxisAngleV( dir ) + Math.PI/2;
			walkTimeout = at.distanceTo( walkTarget ) / speed;
		}
		
		var prj = at.add( dir.mul( speed * elapsed ) );
		var prji = gameDriver.data.map.index( prj );
		var ct = gameDriver.data.map.landMap.get( prji.x, prji.y );
		var mod = gameDriver.data.map.modMap.get( prji.x, prji.y );
		
		if( ct == MapData.ctLand )
		{
			at = prj;
			return;
		}
		
	}
	
	override private function draw()
	{
/*		graphics.clear();
		
		graphics.beginFill( 0x80A040 );
		graphics.lineStyle( 1, 0x202020 );
		graphics.drawEllipse( -(GConst.gridSizeX*size.x)/2, -(GConst.gridSizeY*size.y)/2,
			GConst.gridSizeX*size.x, GConst.gridSizeY*size.y );
		graphics.endFill();
		
		graphics.beginFill( 0x202020 );
		graphics.drawEllipse( -(GConst.gridSizeX*size.x)/4, -(GConst.gridSizeY*size.y)/3,
			GConst.gridSizeX*size.x/2, GConst.gridSizeY*size.y/4 );
		graphics.endFill();*/
	}
	
	override function stepFire()
	{
		//only if near a wall or other on-land object
		
		var prji = gameDriver.data.map.index( at );
		var ct = gameDriver.data.map.landMap.get( prji.x, prji.y );
		
		//damage whatever static item is there.
		if( gameDriver.data.map.damageGrid( gameDriver.data.map.indexLive( this ), gameDriver.global.walkerDamage ) )
		{
			pause = -gameDriver.global.walkerDamagePause;
			return;
		}
		
		//otherwise we suicide bomb the tower...
		var q = gameDriver.data.map.hitObjects( this );
		for( lo in q )
		{
			if( Std.is( lo, TowerObject ) )
			{
				lo.hit( gameDriver.global.walkerDamage );
				hit( hp );	//hit ourselves to die
				return;
			}
		}
	}
	
	override private function added()
	{
		target = gameDriver.data.map.getClosestOwnedTower( at );
		Assert.notNull( target );
		
		walkTime = walkTimeout = 0;
		walkTarget = at;
		dir = at.unitVectorTo( walkTarget );
		orient = Geometry.xAxisAngleV( dir ) + Math.PI/2;
	}
}