CP - Alien Breed Remake - 5

Miscellaneous Forums/Blitz Showcase/CP - Alien Breed Remake - 5

New aliens.bb

Const STANDARD_ALIEN 		= 0
Const FACE_HUGGER_ALIEN		= 1

;==========================================================================================
;TYPES
;==========================================================================================
Type alien
	Field x
	Field y
	Field frame
	Field health#
	Field fpause
	Field dir
	Field id
	Field sdelay
	Field targetdir
	Field mode$,image
	Field frameTotal
	Field visible ; are they currently visible to the player?
	Field speed#
	
	Field radius
	Field offset
	Field kind	
End Type

Global aliengfx = LoadAnimImage("gfx/alien2.png",64,64,0,128) : MaskImage aliengfx,255,0,255
Global facehugger_gfx = LoadAnimImage("gfx/hugger2.png",32,32,0,128) : MaskImage facehugger_gfx,255,0,255




Function SpawnAlien(X%,Y%,id,kind=STANDARD_ALIEN)
	al.alien = New alien
	
	al\x = X
	al\y = Y
	al\frame = 0
	al\health = 10
	al\fpause = 3
	al\dir = 0
	al\id = id
	al\sdelay = 0
	al\mode="newroam"
	al\speed = 1
	al\visible=gettile(al\x,al\y,LAYER_VISIBLE)
	
	al\kind = kind
	Select kind
		Case 0: ; standard alien
			al\radius=20
			al\offset=32
			al\frameTotal = 8
			al\image=aliengfx
		Case 1: ; face hugger
			al\radius=10
			al\offset=16
			al\frameTotal = 8
			al\image=facehugger_gfx
	End Select		
End Function

Function Alien_Die(al.alien)
	
	If al\kind = 0 Then createparticle(al\x,al\y,0,0,1000,0,7,alienblood,32,0)
	If al\kind = 1 Then createparticle(al\x,al\y,0,0,500,3,7,alienblood,32,0)
	playoneshot(snd_aliendeath,al\x,al\y)
	
	;create death splat
	n=Rand(20)+5
	For i=1 To n
		d=Rand(359)
		f=Rand(0,3)
		createparticle(al\x,al\y,Sin(d)*2,Cos(d)*2,Rand(10,100),f,f,particles,16)	
	Next
	
	Delete al.alien
			
End Function

Function alien_hit(al.alien,damage#=1.0)
	
	al\health = al\health - damage
	al\mode="underattack"
	
	If Rand(0,2)=0 Then playoneshot(snd_alienhit(Rand(0,3)),al\x,al\y)
	
	
	
	;random alien blood splats
	d=Rand(0,359)
	f=Rand(0,3)
	createparticle(al\x,al\y,Sin(d)*2,Cos(d)*2,Rand(10,100),f,f,particles,16)
		
	If al\health<=0 Then 
		alien_die(al)
		;Return true so we know the alien died
		Return True
		
	End If
	
	Return False
	
End Function


Function Alien_DrawAll()
	Local al.alien
	For al.alien = Each alien
		If al\visible Then 
			DrawImage al\image,al\x-al\offset-screenx,al\y-al\offset-screeny,(al\dir * al\frameTotal) +al\frame
		End If
	Next
End Function

Function DEBUG_drawAlienState()
	Local al.alien
	For al.alien = Each alien
		If al\visible Then 
			bText al\x-screenx,al\y-screeny,al\mode,True,True
		End If
	Next
End Function



Function update_aliens()

acount=0
	
For al.alien = Each alien

	oldmode$ = al\mode

	If al\visible

		acount=acount+1
	
	
		move=False
		direct$=""
		mr=False
		ml=False
		mu=False
		md=False
		
		; basic alien follow AI
		
		dis = 1000
		targetx=0
		targety=0
		For pl.player = Each player
			ndis = Sqr(((al\x-pl\x)*(al\x-pl\x))+((al\y-pl\y)*(al\y-pl\y)))
			If ndis<dis
				targetx=pl\x
				targety=pl\y
				dis=ndis
			EndIf
		Next
		
		
		If dis>500 And al\mode="underattack" Then al\mode="attack"
		
		; if a player is in range then attack
		If dis<1000
		
		
			If al\mode<>"underattack"
			
			
				; can alien see a player?
				
				For dd=-90 To 90 Step 30
				x=al\x
				y=al\y
				xd=Sin(al\dir*22.5+dd)*64
				yd=-Cos(al\dir*22.5+dd)*64
	
				
				ld=10
				cansee=False
				Repeat
					
					x=x+xd
					y=y+yd
					
					For pl.player = Each player
						If circlesoverlap(x,y,al\radius*4,pl\x,pl\y,playerradius) Then cansee=True:ld=1
					Next
					If x<0 Or x>7552 Or y<0 Or y>7552 Then x=0:y=0:id=1
					If gettile(x,y,0)=1 Then cansee=False:ld=1			
				
					ld=ld-1
				Until ld=0
				
				If cansee = True Then Exit
				
				Next
				
				If cansee And al\mode="roam" Then al\mode="attack"
				If cansee=False And al\mode="attack" Then al\mode="roam"
			EndIf
			
			
			;If al\mode="underattack" Then al\mode="attack"
					
			If al\mode="attack" Or al\mode="underattack"
				If al\x<targetx Then mr=True
				If al\x>targetx Then ml=True
				If al\y<targety Then md=True
				If al\y>targety Then mu=True
			EndIf
			
			If al\mode="roam"
				t=al\dir
				If t>12 Or t<4 Then mu=True
				If t>8 Then ml=True
				If t>4 And t<12 Then md=True
				If t<8 Then mr=True
			EndIf
					
			If al\mode="newroam"
				t=Rand(0,15)
				If t>12 Or t<4 Then mu=True
				If t>8 Then ml=True
				If t>4 And t<12 Then md=True
				If t<8 Then mr=True
				al\mode="roam"
			EndIf
			
	
		EndIf
		
		; check collisions with other aliens
		For al1.alien = Each alien
			If al\id<>al1\id
			
				If mr And circlesoverlap(al\x+2,al\y,al\radius,al1\x,al1\y,al1\radius) Then mr=False
				If ml And circlesoverlap(al\x-2,al\y,al\radius,al1\x,al1\y,al1\radius) Then ml=False
				If md And circlesoverlap(al\x,al\y+2,al\radius,al1\x,al1\y,al1\radius) Then md=False
				If mu And circlesoverlap(al\x,al\y-2,al\radius,al1\x,al1\y,al1\radius) Then mu=False
				
			EndIf
	
		Next
		
		; check collisions with players	
		For pl.player = Each player
		        If mr And circlesoverlap(al\x+2,al\y,al\radius,pl\x,pl\y,playerradius) Then mr=False
		        If ml And circlesoverlap(al\x-2,al\y,al\radius,pl\x,pl\y,playerradius) Then ml=False
			If md And circlesoverlap(al\x,al\y+2,al\radius,pl\x,pl\y,playerradius) Then md=False
			If mu And circlesoverlap(al\x,al\y-2,al\radius,pl\x,pl\y,playerradius) Then mu=False
					
			;Check for player damage
			If circlesoverlap(al\x,al\y,al\radius*1.2,pl\x,pl\y,playerradius) Then
				
				Player_affectHealth(pl,playerHealthDecrease)
				

					
			End If
		
		Next
		
		
		
	
		; Don't hit walls
		If mr Then
			If gettile(al\x+al\radius,al\y,0)=0 Then 
				If al\sDelay=0 Then al\x=al\x+1
				move=True
				direct=direct+"R"
			End If
				
			
		End If
		If ml Then 
			If gettile(al\x-al\radius,al\y,0)=0 Then 
				If al\sDelay=0 Then al\x=al\x-1
				move=True
				direct=direct+"L"
			End If
	
		End If
		If mu Then
			If gettile(al\x,al\y-al\radius,0)=0 Then 
				If al\sDelay=0 Then al\y=al\y-1
				move=True
				direct=direct+"U"
			End If
		End If
		If md Then 
			If gettile(al\x,al\y+al\radius,0)=0 Then 
				If al\sDelay=0 Then al\y=al\y+1
				move=True
				direct=direct+"D"
			End If	
		End If
		
		If move=False And al\mode="roam" Then al\mode="newroam"
		
		al\sdelay = (al\sdelay+1) Mod 2
		
		
		; animation frame control
		If move
			al\fpause = (al\fpause+1) Mod 5
			If al\fpause = 0 Then 
				al\frame = (al\frame+1) Mod al\frameTotal
			End If	
		EndIf
	
		If direct = "U" Then al\targetdir=0
		If direct = "RU" Then al\targetdir =2
		If direct = "R" Then al\targetdir =4 
		If direct = "RD" Then al\targetdir = 6
		If direct = "D" Then al\targetdir = 8
		If direct = "LD" Then al\targetdir = 10
		If direct = "L" Then al\targetdir = 12
		If direct = "LU" Then al\targetdir = 14
		
		If turndelay = 0
			al\dir = dirdif (al\dir,al\targetdir)
	
		EndIf

	EndIf
	
	If al\mode<>oldmode And (al\mode="attack" Or al\mode="underattack")
		playoneshot(snd_alienattack,al\x,al\y)
	EndIf

	If al\visible=0 Then
		If gettile(al\x,al\y,LAYER_VISIBLE)>0 Then al\visible=1
	End If
		
Next ; next alien

End Function