Turret AI

004401F0 . PUSH EBP
004401F1 . MOV EBP,ESP
004401F3 . MOV ECX,[EBP+8]
004401F6 . CMP DWORD PTR [ECX+A8],0
004401FD . JNZ KingTurr.004403D4
00440203 . MOV EAX,[ECX+74]
00440206 . JMP [EAX*4+4403C8]
0044020D > MOV BYTE PTR [ECX+68],0
00440211 . CMP DWORD PTR [ECX+4C],0
00440215 . JNZ SHORT KingTurr.0044024E
00440217 . MOV EAX,[ECX+8]
0044021A . MOV EDX,EAX
0044021C . SUB EAX,0C000
00440221 . PUSH EAX
00440222 . MOV EAX,[ECX+C]
00440225 . SUB EAX,3000
0044022A . PUSH EAX
0044022B . PUSH EDX
0044022C . ADD EAX,6000
00440231 . PUSH EAX
00440232 . CALL KingTurr.0042ECC0
00440237 . ADD ESP,10
0044023A . MOV ECX,[EBP+8]
0044023D . TEST EAX,EAX
0044023F . JE SHORT KingTurr.0044024C
00440241 . MOV BYTE PTR [ECX+74],1
00440245 . MOV DWORD PTR [ECX+78],0
0044024C > JMP SHORT KingTurr.004402C0
0044024E > MOV EAX,[ECX+8]
00440251 . MOV EDX,EAX
00440253 . ADD EAX,0C000
00440258 . PUSH EAX
00440259 . MOV EAX,[ECX+C]
0044025C . SUB EAX,3000
00440261 . PUSH EAX
00440262 . PUSH EDX
00440263 . ADD EAX,6000
00440268 . PUSH EAX
00440269 . CALL KingTurr.0042ECC0
0044026E . ADD ESP,10
00440271 . MOV ECX,[EBP+8]
00440274 . TEST EAX,EAX
00440276 . JE SHORT KingTurr.004402AF
00440278 . MOV BYTE PTR [ECX+74],1
0044027C . MOV DWORD PTR [ECX+78],0
00440283 . JMP SHORT KingTurr.004402C0
00440285 > CMP DWORD PTR [ECX+4C],0
00440289 . JNZ SHORT KingTurr.004402C2
0044028B . MOV EAX,[ECX+8]
0044028E . MOV EDX,EAX
00440290 . SUB EAX,0C000
00440295 . PUSH EAX
00440296 . MOV EAX,[ECX+C]
00440299 . SUB EAX,3000
0044029E . PUSH EAX
0044029F . PUSH EDX
004402A0 . ADD EAX,6000
004402A5 . PUSH EAX
004402A6 . CALL KingTurr.0042ECC0
004402AB . ADD ESP,10
004402AE . MOV ECX,[EBP+8]
004402B1 . TEST EAX,EAX
004402B3 . JNZ SHORT KingTurr.004402F7
004402B5 . MOV BYTE PTR [ECX+74],0
004402B9 . MOV DWORD PTR [ECX+78],0
004402C0 > JMP SHORT KingTurr.00440321
004402C2 > MOV EAX,[ECX+8]
004402C5 . MOV EDX,EAX
004402C7 . ADD EAX,0C000
004402CC . PUSH EAX
004402CD . MOV EAX,[ECX+C]
004402D0 . SUB EAX,3000
004402D5 . PUSH EAX
004402D6 . PUSH EDX
004402D7 . ADD EAX,6000
004402DC . PUSH EAX
004402DD . CALL KingTurr.0042ECC0
004402E2 . ADD ESP,10
004402E5 . MOV ECX,[EBP+8]
004402E8 . TEST EAX,EAX
004402EA . JNZ SHORT KingTurr.004402F7
004402EC . MOV BYTE PTR [ECX+74],0
004402F0 . MOV DWORD PTR [ECX+78],0
004402F7 > MOV BYTE PTR [ECX+68],1
004402FB . INC DWORD PTR [ECX+78]
004402FE . CMP DWORD PTR [ECX+78],0A0
00440305 . JL SHORT KingTurr.00440321
00440307 . XOR EDX,EDX
00440309 . MOV [ECX+78],EDX
0044030C . MOV BYTE PTR [ECX+74],2
00440310 . JMP SHORT KingTurr.00440321
00440312 > CMP DWORD PTR [ECX+78],8
00440316 . JL SHORT KingTurr.00440323
00440318 . MOV BYTE PTR [ECX+74],0
0044031C . XOR EAX,EAX
0044031E . MOV [ECX+78],EAX
00440321 > JMP SHORT KingTurr.00440399
00440323 > INC DWORD PTR [ECX+64]
00440326 . CMP DWORD PTR [ECX+64],5
0044032A . JL SHORT KingTurr.00440399
0044032C . XOR EDX,EDX
0044032E . MOV [ECX+64],EDX
00440331 . PUSH 100
00440336 . PUSH -100
0044033B . CALL KingTurr.0040F350
00440340 . ADD ESP,8
00440343 . MOV ECX,[EBP+8]
00440346 . MOV [EBP-10],EAX
00440349 . INC DWORD PTR [ECX+78]
0044034C . PUSH 0
0044034E . PUSH ECX
0044034F . PUSH 0
00440351 . PUSH DWORD PTR [EBP-10]
00440354 . CMP DWORD PTR [ECX+4C],1
00440358 . JNZ SHORT KingTurr.00440361
0044035A . PUSH 5FF
0044035F . JMP SHORT KingTurr.00440366
00440361 > PUSH -5FF
00440366 > MOV EAX,[ECX+C]
00440369 . SUB EAX,400
0044036E . PUSH EAX
0044036F . PUSH DWORD PTR [ECX+8]
00440372 . PUSH DWORD PTR [ECX+28]
00440375 . CALL KingTurr.0046EFD0
0044037A . ADD ESP,20
0044037D . PUSH 1
0044037F . PUSH 31
00440381 . CALL KingTurr.00420640
00440386 . ADD ESP,8
00440389 . MOV ECX,[EBP+8]
0044038C . INC DWORD PTR [ECX+68]
0044038F . CMP DWORD PTR [ECX+68],3
00440393 . JLE SHORT KingTurr.00440399
00440395 . MOV BYTE PTR [ECX+68],2
00440399 > XOR EDX,EDX
0044039B . MOV DL,50
0044039D . MOV EAX,[ECX+68]
004403A0 . SHL EAX,4
004403A3 . ADD EDX,EAX
004403A5 . MOV [ECX+54],EDX
004403A8 . ADD EDX,10
004403AB . MOV [ECX+5C],EDX
004403AE . MOV EAX,0A0
004403B3 . MOV EDX,[ECX+4C]
004403B6 . SHL EDX,5
004403B9 . ADD EAX,EDX
004403BB . MOV [ECX+58],EAX
004403BE . ADD EAX,20
004403C1 . MOV [ECX+60],EAX
004403C4 . MOV ESP,EBP
004403C6 . POP EBP
004403C7 . RETN
004403C8 . DD KingTurr.0044020D
004403CC . DD KingTurr.00440285
004403D0 . DD KingTurr.00440312
004403D4 > MOV EAX,[EBP+8]
004403D7 . MOV ECX,[EAX+4]
004403DA . MOV EDX,ECX
004403DC . AND EDX,1
004403DF . JNZ SHORT KingTurr.004403F6
004403E1 . MOV EDX,ECX
004403E3 . AND EDX,2
004403E6 . JNZ SHORT KingTurr.004403F6
004403E8 . MOV EDX,ECX
004403EA . AND EDX,4
004403ED . JNZ SHORT KingTurr.004403F6
004403EF . MOV EDX,ECX
004403F1 . AND EDX,8
004403F4 . JE SHORT KingTurr.004403FC
004403F6 > MOV DWORD PTR [EAX],0
004403FC > MOV ECX,[EAX+A8]
00440402 . MOV EDX,[ECX+4C]
00440405 . MOV [EAX+4C],EDX
00440408 . MOV ECX,90
0044040D . MOV EDX,[EAX+4C]
00440410 . SHL EDX,4
00440413 . ADD ECX,EDX
00440415 . MOV [EAX+54],ECX
00440418 . ADD ECX,10
0044041B . MOV [EAX+5C],ECX
0044041E . MOV DWORD PTR [EAX+58],0A0
00440425 . MOV DWORD PTR [EAX+60],0B0
0044042C . MOV ECX,[EAX+10]
0044042F . ADD [EAX+8],ECX
00440432 . MOV ECX,[EAX+14]
00440435 . ADD [EAX+C],ECX
00440438 MOV ECX,[EAX+50]
0044043B AND ECX,1
0044043E AND ECX,8000
00440444 MOV [EAX+50],ECX
00440447 MOV DWORD PTR [EAX+A4],6
00440451 CMP DWORD PTR [EAX+78],1
00440455 JNZ SHORT KingTurr.00440465
00440457 MOV DWORD PTR [EAX+40],3
0044045E MOV DWORD PTR [EAX+78],1
00440465 MOV ESP,EBP
00440467 POP EBP
00440468 RETN

There’s the code for the turret – If you can make heads or tails of that, then I commend you. The first thing I do with larger entities is a scriptstate jump. Having different scriptstates for different behaviours keeps things organized for me and stops me from having code all run into itself. State 0 would be what it starts at, so we do a check on the direction and look to see if the player’s in field of view (that’s what 42Ecc0 does, checks if player is within range. I made it a function because I got tired of typing it out and trying to remember if it was JG here or JL there… much easier this way.) If the player’s in range, set state to 1
State 1, the thing starts counting down to fire. If the player runs out of range, then it’ll reset itself.
State 2 is firing. The gun generates a random y-velocity for each bullet and fires eight in total, along with playing a sound. After firing is finished, then it resets. After state 2 code finishes, then is my frame calculation thing and the switch table. After THAT is the code for the bullets; I sometimes make projectiles the same entity as the parent to save on entities. It won’t work all the time, mind you. All I do is make the second push [ebp+8] and then check if [eax+0A8] is nonzero at the very beginning of the code. The bullet code is very simple, just moves in a straight line and gives itself the proper flags, damage and HP.

The hardest part of it all is probably deciding when to change frames to make it animated, and the most tedious would be fixing every jump and call when you forget something and need to insert code partway through. I’m not entirely sure what to say about this so if you’ve got any more specific questions, feel free to ask.

§ One Response to Turret AI

  • bobbyis says:

    Can’t wait to see this incorparated into the game. Once I learn some scripting I might actually understand the first line XD

Leave a comment

  • Sign up to email notification and never miss an update!

    Join 33 other subscribers
  • Archives

  • Meta