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