Heavily commentated NPC code

Sep 26, 2013 at 8:25 PM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
Pronouns: he/him
scriptstate is just a variable
it's entirely internal to the NPC and nothing else ever uses it or modifies it
except <ANP which sets it
 
Oct 7, 2013 at 9:35 PM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 27
Pronouns: he/him
ok... new Question.

What is this?

00444AE4 JMP DWORD PTR DS:[EDX*4+445035]

I looked through the defines.txt and didn't see the address 445035 inside.

I'm assuming that this jumps to some sort of table and calls something?
 
Oct 8, 2013 at 1:08 AM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
Pronouns: he/him
yes, if you look 445035 should be a table of pointers appended to the end of the function to different points in the code. depending on the value of edx, the JMP goes to one of those locations
 
Oct 9, 2013 at 8:45 PM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 27
Pronouns: he/him
Noxid said:
yes, if you look 445035 should be a table of pointers appended to the end of the function to different points in the code. depending on the value of edx, the JMP goes to one of those locations
So unless the value of EDX is stupidly high, this should jump to various parts of the next NPC's code (the critters projectile)

(man, this third one is kind of hard.)



I can't quite grasp what "test" means.

00444BB3 |. 0FB682 9C0000 movzx eax,byte ptr [edx+9C]
00444BBA |. 85C0 test eax,eax
00444BBC |. 74 1E je short 00444BDC

If your testing the two same values wouldn't you always come out with the same answer if them being equal?

TEST 2,2
JE 00444BDC

two is always equal to two.

Unless test is not similar to CMP.
 
Oct 9, 2013 at 10:01 PM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2326
Age: 28
Pronouns: he/him
Bombchu Link said:
I can't quite grasp what "test" means.
Code:
00444BB3  |.  0FB682 9C0000 movzx eax,byte ptr [edx+9C]
00444BBA  |.  85C0          test eax,eax
00444BBC  |.  74 1E         je short 00444BDC
If your testing the two same values wouldn't you always come out with the same answer if them being equal?

TEST 2,2
JE 00444BDC

two is always equal to two.

Unless test is not similar to CMP.
Code:
TEST EAX,EAX
does the exact same thing as
Code:
CMP EAX,0
Except the former takes up less space. You should look at one of the earlier versions of Carrotlord's ASM tutorial. It has some useful information that I have no idea why he took out in version 2.00.
 
Oct 9, 2013 at 10:34 PM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 27
Pronouns: he/him
HaydenStudios said:
TEST EAX,EAX
does the exact same thing as
Code:
CMP EAX,0
Except the former takes up less space. You should look at one of the earlier versions of Carrotlord's ASM tutorial. It has some useful information that I have no idea why he took out in version 2.00.
oh wow, I'm finding all kinds of goodies that weren't in the other tutorial.

thank you hayden!

EDIT: no, I really mean it, this like, make infinitely more sense the more I read it.

EDIT 2:
for some reason I cannot make another post, so I pray that Noxid sees this soon.

Here's a nibble of the purple crit's code.

:if_hit_not_true
00444BDC MOV ECX,DWORD PTR SS:[EBP+8] ;set dat pointer! (ecx)
00444BDF CMP DWORD PTR DS:[ECX+78],8 ;compare script timer to 8
00444BE3 JL SHORT :another_generic_jump ;if less, jump... to another jump...
00444BE5 MOV EDX,DWORD PTR SS:[EBP+8] ;set dat pointer! (edx)
00444BE8 MOV EAX,DWORD PTR DS:[EDX+8] ;move value of EAX to critter X position
00444BEB SUB EAX,6000 ;subtract 6000 from EAX
00444BF0 CMP EAX,DWORD PTR DS:[49E654] ;compare X position to Quotes X position
00444BF6 JGE SHORT :another_generic_jump ;if greater or equal jump
00444BF8 MOV ECX,DWORD PTR SS:[EBP+8] ;set dat pointer! (ecx)
00444BFB MOV EDX,DWORD PTR DS:[ECX+8] ;Move the EDX to critter X position
00444BFE ADD EDX,6000 ;Add 6,000 to EDX
00444C04 CMP EDX,DWORD PTR DS:[49E654] ;Compare EDX to X position
00444C0A JLE SHORT :another_generic_jump ;if less or equal jump
00444C0C MOV EAX,DWORD PTR SS:[EBP+8] ;set dat pointer! (eax)
00444C0F MOV ECX,DWORD PTR DS:[EAX+0C] ;move value of ECX to critter Y position
00444C12 SUB ECX,0C000 ;subtract c,000 from ECX
00444C18 CMP ECX,DWORD PTR DS:[49E658] ;compare Y position to Quotes Y position
00444C1E JGE SHORT :another_generic_jump ;if higher or equal jump
00444C20 MOV EDX,DWORD PTR SS:[EBP+8] ;set dat pointer! (edx)
00444C23 MOV EAX,DWORD PTR DS:[EDX+0C] ;move value of EAX to critter Y position
00444C26 ADD EAX,4000 ;Add 4,000 to EAX
00444C2B CMP EAX,DWORD PTR DS:[49E658] ;compare to Quote's Y position
00444C31 JLE SHORT :another_generic_jump ;If less or Equal, jump
00444C33 MOV ECX,DWORD PTR SS:[EBP+8] ;If we got past all thoese hurdals....
00444C36 MOV DWORD PTR DS:[ECX+74],2 ;change script state to two
00444C3D MOV EDX,DWORD PTR SS:[EBP+8]
00444C40 MOV DWORD PTR DS:[EDX+68],0 ;frame number to 0
00444C47 MOV EAX,DWORD PTR SS:[EBP+8]
00444C4A MOV DWORD PTR DS:[EAX+78],0 ;and script timer to 0
00444C51 JMP :if_var_equal


Why would we do this?

MOV EDX,DWORD PTR SS:[EBP+8] ;set dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+8] ;move value of critter X position to EAX
SUB EAX,6000 ;subtract 6000 from EAX
CMP EAX,DWORD PTR DS:[49E654] ;compare X position to Quotes X position
JGE SHORT :another_generic_jump ;if greater or equal jump

If of course the critters X position is going to be less then Quotes!
With the Sub EAX, 6000 the critter is at like -5FF2 on the map!

I can't comprehend a scenario where it could possibly be greater.. (unless you had a map at least 6,000 [hex] in size)


and also...


+0x24: Event.Unknown2 ; the targeting macro.
What is the "targeting Macro"?

What is the difference between

npc.CurlyMacro1=[ecx+20]

and

npc.CurlyMacro2=[ecx+24]?
 
Oct 16, 2013 at 5:38 PM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
Pronouns: he/him
have you even /looked/ at the value of eax at those points?
I think if you actually checked it would make a lot more sense
---
the difference between the two is one is an x coord, one is a y coord
 
Oct 16, 2013 at 7:13 PM
Lvl 1
Forum Moderator
"Life begins and ends with Nu."
Join Date: May 28, 2008
Location: PMMM MMO
Posts: 3713
Age: 32
Bombchu Link said:
If of course the critters X position is going to be less then Quotes!
With the Sub EAX, 6000 the critter is at like -5FF2 on the map!

I can't comprehend a scenario where it could possibly be greater.. (unless you had a map at least 6,000 [hex] in size)
Are you, uh, aware of the ingame scale at all? 0x200 (that's a hexadecimal value, note how it starts with 0x ) is one pixel iirc, so 0x6000 is like 48 pixels.
 
Oct 16, 2013 at 11:00 PM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 27
Pronouns: he/him
GIRakaCHEEZER said:
Are you, uh, aware of the ingame scale at all? 0x200 (that's a hexadecimal value, note how it starts with 0x ) is one pixel iirc, so 0x6000 is like 48 pixels.
No, I wasn't...

oh, so it checks to see if Quote is farther away then 48 pixels.

*does in game test*

Less then 48 pixels makes it jump up and fire a projectile.

That helps a lot actually, thanks.

I request to drink more from your fountains of ASM wisdom.

What is at address 004258E0? The assembly compendium/defines.txt isn't helping sadly.
 
Oct 17, 2013 at 1:22 AM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 27
Pronouns: he/him
Noxid said:


OhwowhowdidInothavethatohwell.


thank you.


I'll have some PROGRESS to post soon.


PROGRESS


Code:
offset 444930         

PUSH EBP                   ;Alright, the third and final test.
MOV EBP,ESP                ;Let's go.
 
SUB ESP,0D8                        ;Framarect/local variable counter 

              ;-Sprite 1 Idle face left-
MOV DWORD PTR SS:[EBP-68],0        ;Left border
MOV DWORD PTR SS:[EBP-64],60       ;Up border
MOV DWORD PTR SS:[EBP-60],10       ;Right border
MOV DWORD PTR SS:[EBP-5C],70       ;Down border

              ;-Sprite 2 alert face left-
MOV DWORD PTR SS:[EBP-58],10
MOV DWORD PTR SS:[EBP-54],60
MOV DWORD PTR SS:[EBP-50],20
MOV DWORD PTR SS:[EBP-4C],70

              ;-Sprite 3 jumping face left-
MOV DWORD PTR SS:[EBP-48],20
MOV DWORD PTR SS:[EBP-44],60
MOV DWORD PTR SS:[EBP-40],30
MOV DWORD PTR SS:[EBP-3C],70

              ;-Sprite 4 flying 1 face left-
MOV DWORD PTR SS:[EBP-38],30
MOV DWORD PTR SS:[EBP-34],60
MOV DWORD PTR SS:[EBP-30],40
MOV DWORD PTR SS:[EBP-2C],70

              ;-Sprite 5 flying 2 face left-
MOV DWORD PTR SS:[EBP-28],40
MOV DWORD PTR SS:[EBP-24],60
MOV DWORD PTR SS:[EBP-20],50
MOV DWORD PTR SS:[EBP-1C],70

              ;-Sprite 6 flying 3 face left-
MOV DWORD PTR SS:[EBP-18],50
MOV DWORD PTR SS:[EBP-14],60
MOV DWORD PTR SS:[EBP-10],60
MOV DWORD PTR SS:[EBP-0C],70

              ;-Sprite 7 Idle face right-
MOV DWORD PTR SS:[EBP-0D0],0
MOV DWORD PTR SS:[EBP-0CC],70
MOV DWORD PTR SS:[EBP-0C8],10
MOV DWORD PTR SS:[EBP-0C4],80

              ;-Sprite 8 alert face right-
MOV DWORD PTR SS:[EBP-0C0],10
MOV DWORD PTR SS:[EBP-0BC],70
MOV DWORD PTR SS:[EBP-0B8],20
MOV DWORD PTR SS:[EBP-0B4],80

              ;-Sprite 9 jumping face right-
MOV DWORD PTR SS:[EBP-0B0],20
MOV DWORD PTR SS:[EBP-0AC],70
MOV DWORD PTR SS:[EBP-0A8],30
MOV DWORD PTR SS:[EBP-0A4],80

              ;-Sprite 10 flying 1 face right-
MOV DWORD PTR SS:[EBP-0A0],30
MOV DWORD PTR SS:[EBP-9C],70
MOV DWORD PTR SS:[EBP-98],40
MOV DWORD PTR SS:[EBP-94],80

              ;-Sprite 11 flying 2 face right-
MOV DWORD PTR SS:[EBP-90],40
MOV DWORD PTR SS:[EBP-8C],70
MOV DWORD PTR SS:[EBP-88],50
MOV DWORD PTR SS:[EBP-84],80

              ;-Sprite 12 flying 3 face right-
MOV DWORD PTR SS:[EBP-80],50
MOV DWORD PTR SS:[EBP-7C],70
MOV DWORD PTR SS:[EBP-78],60
MOV DWORD PTR SS:[EBP-74],80

MOV EAX,DWORD PTR SS:[EBP+8]          ;NPC pointer
MOV ECX,DWORD PTR DS:[EAX+74]         ;Script State
MOV DWORD PTR SS:[EBP-0D8],ECX        ;add the scriptstate to the local variable. 
CMP DWORD PTR SS:[EBP-0D8],5          ;compare to 5.
JA :if_var_equal                      ;Jump on down.

MOV EDX,DWORD PTR SS:[EBP-0D8]        ;Move the variable to the EDX
JMP DWORD PTR DS:[EDX*4+445035]       ;jump to the critter state table, pending on the scriptstate stored in EDX, it will jump to the corosponding address. 


MOV EAX,DWORD PTR SS:[EBP+8]          ;set up dat pointer! (eax)
MOV ECX,DWORD PTR DS:[EAX+0C]         ;Load Y position of NPC to ECX
ADD ECX,600                           ;this changes the Y position by 3 pixels
MOV EDX,DWORD PTR SS:[EBP+8]          ;set up dat pointer! (edx)
MOV DWORD PTR DS:[EDX+0C],ECX         ;add ECX to Y position.
MOV EAX,DWORD PTR SS:[EBP+8]          ;set up dat pointer! (eax)
MOV DWORD PTR DS:[EAX+74],1           ;Make the script state 1
MOV ECX,DWORD PTR SS:[EBP+8]          ;set up dat pointer! (ecx)
CMP DWORD PTR DS:[ECX+78],8           ;Is our script timer 8?
JL SHORT :if_less_then_8              ;If less, JUMP
MOV EDX,DWORD PTR SS:[EBP+8]          ;set up dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+8]          ;check the X position of the critter
SUB EAX,0C000                         ;this
CMP EAX,DWORD PTR DS:[49E654]         ;compare the critters X position (stored in EAX) to Quotes Position (address 49E654) .       
JGE SHORT :if_less_then_8             ;If higer (Quote is to far away) JUMP
MOV ECX,DWORD PTR SS:[EBP+8]          ;otherwise, set pointer
MOV EDX,DWORD PTR DS:[ECX+8]          ;and load X position
ADD EDX,0C000                         ;this sees if critter is less then C000 [200 = 1 pixel] or 60 pixels to the right of Quote
CMP EDX,DWORD PTR DS:[49E654]         ;compare the critters X position (stored in EDX) to Quotes Position (address 49E654) . 
JLE SHORT :if_less_then_8             ;If less JUMP
MOV EAX,DWORD PTR SS:[EBP+8]          ;set up dat pointer! (eax)
MOV ECX,DWORD PTR DS:[EAX+0C]         ;move the Y position of critter to ECX
SUB ECX,0C000                         ;this sees if critter is less then C000 [200 = 1 pixel] or 60 pixels to the left of Quote
CMP ECX,DWORD PTR DS:[49E658]         ;CMP ECX to Player Y position (in Pixels)
JGE SHORT :if_less_then_8             ;If greater Jump
MOV EDX,DWORD PTR SS:[EBP+8]          ;set up dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+0C]         ;load the Y position of the critter to EAX 
ADD EAX,4000                          ;add 4000 to EAX
CMP EAX,DWORD PTR DS:[49E658]         ;again compare ECX to Player Y position (in Pixels)
JLE SHORT :if_less_then_8             ;if less or equal jump

         ;checks if it's to the left or right of Quote.
MOV ECX,DWORD PTR SS:[EBP+8]          ;set up dat pointer! (eCx)
MOV EDX,DWORD PTR DS:[ECX+8]          ;load the X position of the critter to EAX
CMP EDX,DWORD PTR DS:[49E654]         ;compare ECX to Player X position (in Pixels)
JLE SHORT :a_little_lower             ;If less or equal jump
MOV EAX,DWORD PTR SS:[EBP+8]          ;set up dat pointer! (eax)
MOV DWORD PTR DS:[EAX+4C],0           ;make direction 0 (becasue the above calculation tell us that Quote is to the left of the Critter)
JMP SHORT :direction_0                ;JUMP

:a_little_lower
MOV ECX,DWORD PTR SS:[EBP+8]          ;set up dat pointer! (ecx)
MOV DWORD PTR DS:[ECX+4C],2           ;make direction "2"

:direction_0
MOV EDX,DWORD PTR SS:[EBP+8]          ;set up dat pointer! (edx)
MOV DWORD PTR DS:[EDX+68],1           ;Change frame number to no.1 (idle, face left)
JMP SHORT :end_frame_change


           ;-----Alert-------

:if_less_then_8
MOV EAX,DWORD PTR SS:[EBP+8]       ;Pointer set.
CMP DWORD PTR DS:[EAX+78],8        ;See if script timer is 8
JGE SHORT :down_there              ;This time if higher JUMP
MOV ECX,DWORD PTR SS:[EBP+8]       ;Number must be 8 (set pointer)
MOV EDX,DWORD PTR DS:[ECX+78]      ;Set script timer
ADD EDX,1                          ;add 1 to the EDX (why not INC EDX?)
MOV EAX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (eax)
MOV DWORD PTR DS:[EAX+78],EDX      ;make whatever is in the EDX the script timer number (the <WAI period)

:down_there
MOV ECX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (ecx)
MOV DWORD PTR DS:[ECX+68],0        ;this changes the frame number to no. 0

:end_frame_change
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
MOVZX EAX,BYTE PTR DS:[EDX+9C]     ;See if entity is hit, [0 = not] [1= hit] (only a bite is required to see if 1 or 0)
TEST EAX,EAX                       ;same as CMP EAX,0
JE SHORT :if_hit_not_true          ;if 1 Jump
MOV ECX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (ecx)    
MOV DWORD PTR DS:[ECX+74],2        ;change script state to 2
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)  
MOV DWORD PTR DS:[EDX+68],0        ;change frame number to 0
MOV EAX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (eax) 
MOV DWORD PTR DS:[EAX+78],0        ;change script timer to 0

:if_hit_not_true
MOV ECX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (ecx)  
CMP DWORD PTR DS:[ECX+78],8        ;compare script timer to 8
JL SHORT :jump_and_fly             ;if less, jump... to another jump...
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+8]       ;move value of EAX to critter X position
SUB EAX,6000                       ;this sees if critter is less then 6000 [200 = 1 pixel] or 48 pixels away from Quote's left side.
CMP EAX,DWORD PTR DS:[49E654]      ;compare X position to Quotes X position
JGE SHORT :jump_and_fly            ;if greater or equal jump
MOV ECX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (ecx) 
MOV EDX,DWORD PTR DS:[ECX+8]       ;Move the EDX to critter X position
ADD EDX,6000                       ;this sees if critter is less then 6000 [200 = 1 pixel] or 48 pixels away from Quote's right side.
CMP EDX,DWORD PTR DS:[49E654]      ;Compare EDX to X position
JLE SHORT :jump_and_fly            ;if less or equal jump
MOV EAX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (eax)
MOV ECX,DWORD PTR DS:[EAX+0C]      ;move value of ECX to critter Y position
SUB ECX,0C000                      ;this sees if critter is less then C000 [200 = 1 pixel] or 60 pixels above Quote
CMP ECX,DWORD PTR DS:[49E658]      ;compare Y position to Quotes Y position
JGE SHORT :jump_and_fly            ;if higher or equal jump
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+0C]      ;move value of EAX to critter Y position
ADD EAX,4000                       ;this sees if critter is less then 4000 [200 = 1 pixel] or 20 pixels below Quote
CMP EAX,DWORD PTR DS:[49E658]      ;compare to Quote's Y position
JLE SHORT :jump_and_fly            ;If less or Equal, jump
MOV ECX,DWORD PTR SS:[EBP+8]       ;If we got past all thoese hurdals....
MOV DWORD PTR DS:[ECX+74],2        ;change script state to two
MOV EDX,DWORD PTR SS:[EBP+8]      
MOV DWORD PTR DS:[EDX+68],0        ;frame number to 0
MOV EAX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[EAX+78],0        ;and script timer to 0
JMP :if_var_equal


            ;----FLY FLY FLY!------

:jump_and_fly  
MOV ECX,DWORD PTR SS:[EBP+8]
MOV EDX,DWORD PTR DS:[ECX+78]      ;set script timer to EDX
ADD EDX,1                          ;INC EAX,1  pending on if it was facing left or right, increses frame number to the right sprite.
MOV EAX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (eax)
MOV DWORD PTR DS:[EAX+78],EDX      ;move EDX to sprite number.
MOV ECX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (ecx)
CMP DWORD PTR DS:[ECX+78],8        ;is sprite number 8?
JLE SHORT :Direction_zero          ;jump to another jump
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
MOV DWORD PTR DS:[EDX+74],3        ;change scriptstate to 3
MOV EAX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (eax)
MOV DWORD PTR DS:[EAX+68],2        ;change frame number to two
MOV ECX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (ecx)
MOV DWORD PTR DS:[ECX+14],-5FF     ;Change Y velocity to negative -5FF
PUSH 1                             ;Push 1
PUSH 1E                            ;Push 1E
CALL 00420640                      ;play sound 1E (mandatory to push 1 beforehand)
ADD ESP,8                          ;for every push we need to ADD 4 to the ESP
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+8]       ;move position X of crit to EAX
CMP EAX,DWORD PTR DS:[49E654]      ;Compare to Quotes X position
JLE SHORT :down_three_lines        ;if lessor equal, Jump
MOV ECX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (ecx)
MOV DWORD PTR DS:[ECX+4C],0        ;change direction to 0
JMP SHORT :Direction_zero

:down_three_lines
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
MOV DWORD PTR DS:[EDX+4C],2        ;change direction to 2

:Direction_zero
JMP 00444EF4
MOV EAX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (eax)
CMP DWORD PTR DS:[EAX+14],100      ;compare Y velocity to 100 [falling]
JLE SHORT :if_var_equal            ;If less or equal, jump
MOV ECX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (ecx)
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+0C]      ;move Y pos to EAX
MOV DWORD PTR DS:[ECX+24],EAX      ;Set Curly's targeting area for Y position [X pos in not required becasue the entity does not move left/right]
MOV ECX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (ecx)
MOV DWORD PTR DS:[ECX+74],4        ;Change script state to 4
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
MOV DWORD PTR DS:[EDX+68],3        ;change frame number to 3
MOV EAX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (eax)
MOV DWORD PTR DS:[EAX+78],0        ;change script timer to 0
MOV ECX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (ecx)
MOV DWORD PTR DS:[ECX+78],0        ;change script timer to 0 again?
JMP :if_var_equal

MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+8]       ;Move X position to EAX
CMP EAX,DWORD PTR DS:[49E654]      ;compare with Quotes X position
JGE SHORT :is_zero                 ;If greater or equal
MOV ECX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (ecx)
MOV DWORD PTR DS:[ECX+4C],2        ;Change direction of critter to two
JMP SHORT :is_two                  ;Jump

:is_zero
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
MOV DWORD PTR DS:[EDX+4C],0        ;Change direction of critter to zero

:is_two 
MOV EAX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (eax)
MOV ECX,DWORD PTR DS:[EAX+78]      ;move value of ECX to script timer
ADD ECX,1                          ;INC EAX
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
MOV DWORD PTR DS:[EDX+78],ECX      ;move script state to ECX
MOV EAX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (eax)
MOV ECX,DWORD PTR DS:[EAX+4]       ;see if it is colliding with cealing
AND ECX,00000007                   ;sets some asm flags that I can't comprehend
JNE SHORT :JNZ                     ;if flag zero is not set, jump
MOV EDX,DWORD PTR SS:[EBP+8]       ;set dat pointer! (edx)
CMP DWORD PTR DS:[EDX+78],3C       ;Is script timer less then 3C?
JLE SHORT :timer_less_then_3C      ;if yes, jump

:JNZ
MOV EAX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[EAX+0A4],3
MOV ECX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[ECX+74],5
MOV EDX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[EDX+68],2
JMP :if_var_equal

:timer_less_then_3C 
MOV EAX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (eax)
MOV ECX,DWORD PTR DS:[EAX+78]    ;Store script state to ECX
AND ECX,80000003                 ;Sets sign flag if EAX is high/low enough
JNS SHORT 00444D86               ;Jump if sign flag is clear
DEC ECX                          ;REmove 1 from ECX
OR ECX,FFFFFFFC                  ;set's a asm flag, maybe
INC ECX                          ;add 1 to ECX
CMP ECX,1                        ;see if the number is one (remember that FFFFFFFE + 2 = 1
JNE SHORT :sound_done               
PUSH 1                           ;Push 1
PUSH 6D                          ;Push 6D
CALL 00420640                    ;play sound 6D (critter jumping)
ADD ESP,8                        ;we pushed twice and 4 + 4 = 8 so ADD ESP, 8

:sound_done
MOV EDX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+4]     ;store collision data to EAX
AND EAX,00000008                 ;set some flags if the EAX is at the right number
JE SHORT :Vel_Set_done           ;if it is the undesired number, jump
MOV ECX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (ecx)
MOV DWORD PTR DS:[ECX+14],-200   ;set Y velocity to -200

:Vel_Set_done
MOV EDX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+78]    ;move value of EDX to script timer
CDQ                              ;makes EDX:EAX
MOV ECX,1E                       ;Move 1E into ECX
IDIV ECX                         ;divide ECX by EDX:EAX
CMP EDX,6                        ;EDX holds the remander, compare to 6
JNE :remiander_not_6             ;if it's not equal, jump
MOV EDX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+0C]    ;move Y position to EAX
SUB EAX,DWORD PTR DS:[49E658]    ;Subtract Quote's Y from EAX
PUSH EAX                         ;Push EAX onto stack
MOV ECX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (ecx)
MOV EDX,DWORD PTR DS:[ECX+8]     ;Move crit's X position to EDX
SUB EDX,DWORD PTR DS:[49E654]    ;Subtract Quote's X from Crit's X position
PUSH EDX                         ;Push EDX onto stack.
CALL 004258E0                    ;Detects player collision
ADD ESP,8                        ;we pushed twice and 4 + 4 = 8 so ADD ESP, 8
MOV BYTE PTR SS:[EBP-1],AL       ;move the value of AL to the local variable.
PUSH 6                           ;push 6
PUSH -6                          ;push -6 
CALL 0040F350                    ;Random number (stored in EAX) changes the angle that the critter proj will fire.
ADD ESP,8                        ;We pushed twice and 4 + 4 = 8 so ADD ESP, 8
MOVZX EAX,AL                     ;stores value of AL to EAX? (the start point and destination are the same?)
MOVZX ECX,BYTE PTR SS:[EBP-1]    ;move value of local variable to ECX
ADD ECX,EAX                      ;add EAX to ECX
MOV BYTE PTR SS:[EBP-1],CL       ;move the value of CL to the local variable 
MOV DL,BYTE PTR SS:[EBP-1]       ;and then move it to DL
PUSH EDX                         
CALL 004258B0                    ;call sin table (has to do with angle the crit projectile is fired at)
ADD ESP,4                        ;we already went over this part
IMUL EAX,EAX,3                   ;multiply EAX by 3, store answer into EAX
MOV DWORD PTR SS:[EBP-0D4],EAX   ;move the answer into this local variable
MOV AL,BYTE PTR SS:[EBP-1]       ;move the value of thie local variable to AL
PUSH EAX                         
CALL 004258C0                    ;call cos table( has to do with angle the crit projectile is fired at)
ADD ESP,4                        ;We already went over this.
IMUL EAX,EAX,3                   ;read above.
MOV DWORD PTR SS:[EBP-6C],EAX    ;store answer to this local variable
PUSH 100                                
PUSH 0                              
PUSH 0                             
MOV ECX,DWORD PTR SS:[EBP-0D4]   ;store the value of local variable to ECX
PUSH ECX                              
MOV EDX,DWORD PTR SS:[EBP-6C]    ;store the value of local var to EDX
PUSH EDX                              
MOV EAX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (eax)
MOV ECX,DWORD PTR DS:[EAX+0C]    ;store Y position of Crit to ECX
PUSH ECX                      
MOV EDX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+8]     ;store X position of Crit to EAX
PUSH EAX                             
PUSH 94                               
CALL 0046EFD0                    ;create NPC using above specs 
ADD ESP,20
PUSH 1                                 
PUSH 27                              
CALL 00420640                    ;play sound 27 [*bving*]
ADD ESP,8

:remiander_not_6
MOV ECX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (ecx)
MOV EDX,DWORD PTR DS:[ECX+64]    ;set frame timer into EDX
ADD EDX,1                        ;INC EDX
MOV EAX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (eax)
MOV DWORD PTR DS:[EAX+64],EDX    ;set frame timer to value of EDX
MOV ECX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (ecx)
CMP DWORD PTR DS:[ECX+64],0      ;is frame timer 0?
JLE SHORT :cat's_are_cool        ;if 0 or less, jump
MOV EDX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (edx)
MOV DWORD PTR DS:[EDX+64],0      ;change frame timer to 0
MOV EAX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (eax)
MOV ECX,DWORD PTR DS:[EAX+68]    ;move frame number to ECX
ADD ECX,1                        ;add 1
MOV EDX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (edx)
MOV DWORD PTR DS:[EDX+68],ECX    ;store it back frame number

:cat's_are_cool 
MOV EAX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (eax)
CMP DWORD PTR DS:[EAX+68],5      ;is frame number 5?
JLE SHORT :is_less_then_5        ;if less or equal to 5 jump
MOV ECX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (ecx)
MOV DWORD PTR DS:[ECX+68],3      ;change frame number to 3
JMP SHORT :if_var_equal

:is_less_then_5 
MOV EDX,DWORD PTR SS:[EBP+8]     ;set dat pointer! (edx)
MOV EAX,DWORD PTR DS:[EDX+4]     ;check for collision.
AND EAX,00000008                 ;set asm flags
JE SHORT :if_var_equal           ;jump if right number
MOV ECX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[ECX+0A4],2     ;collision with entity has happened, quote takes 2 damamge
MOV EDX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[EDX+10],0      ;change critter vel to 0
MOV EAX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[EAX+78],0      ;script timer to 0
MOV ECX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[ECX+68],0      ;frame number to 0
MOV EDX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[EDX+74],1      ;and script state to 1
PUSH 1                                   
PUSH 17                                  
CALL 00420640                    ;Play sound 17 [hex]
ADD ESP,8

:if_var_equal
MOV EAX,DWORD PTR SS:[EBP+8]               
CMP DWORD PTR DS:[EAX+74],4                ;compare the script state to 4
JE SHORT :if_four
MOV ECX,DWORD PTR SS:[EBP+8]               
MOV EDX,DWORD PTR DS:[ECX+14]              ;set EDX to NPC Y velocity
ADD EDX,20                                 ;add 20 to Y velocity
MOV EAX,DWORD PTR SS:[EBP+8]               
MOV DWORD PTR DS:[EAX+14],EDX              ;set Y velocity through EAX, Y vel is EDX
MOV ECX,DWORD PTR SS:[EBP+8]               
CMP DWORD PTR DS:[ECX+14],5FF              ;compare 5FF to the Y vel
JLE SHORT :less_then_5FF
MOV EDX,DWORD PTR SS:[EBP+8]               
MOV DWORD PTR DS:[EDX+14],5FF              ;make sure that it stays at 5FF
:less_then_5FF
JMP :near_bottom

:if_four
MOV EAX,DWORD PTR SS:[EBP+8]
MOV ECX,DWORD PTR SS:[EBP+8]
MOV EDX,DWORD PTR DS:[EAX+0C]    ;store Y pos ot EDX
CMP EDX,DWORD PTR DS:[ECX+24]    ;Compare to Curly targeting Y
JLE SHORT :Curly_target_off
MOV EAX,DWORD PTR SS:[EBP+8]
MOV ECX,DWORD PTR DS:[EAX+14]    ;move Y vel to ECX
SUB ECX,10                       ;subtract ten from it. [keeps it suspended in air]
MOV EDX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[EDX+14],ECX    ;store it back to the velocity
JMP SHORT :Velocity_set

:Curly_target_off
MOV EAX,DWORD PTR SS:[EBP+8]
MOV ECX,DWORD PTR DS:[EAX+14]    ;move Y vel to ECX
ADD ECX,10                       ;add 10
MOV EDX,DWORD PTR SS:[EBP+8]    
MOV DWORD PTR DS:[EDX+14],ECX    ;put it back in to Velocity

:Velocity_set
MOV EAX,DWORD PTR SS:[EBP+8]
CMP DWORD PTR DS:[EAX+14],200    ;compare the Y vel to 200
JLE SHORT :less_then_200         ;if less or equal jump
MOV ECX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[ECX+14],200    ;store 200 to Y velocity

:less_then_200
MOV EDX,DWORD PTR SS:[EBP+8]
CMP DWORD PTR DS:[EDX+14],-200   ;compare the vel to -200
JGE SHORT :more_then_200         ;if greater or equal jump
MOV EAX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[EAX+14],-200   ;store -200 to Y vel

:more_then_200
MOV ECX,DWORD PTR SS:[EBP+8]
CMP DWORD PTR DS:[ECX+10],200    ;see if X vel is 200
JLE SHORT :catZ
MOV EDX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[EDX+10],200    ;store 200 to X vel

:catZ
MOV EAX,DWORD PTR SS:[EBP+8]
CMP DWORD PTR DS:[EAX+10],-200   ;see if X vel is -200
JGE SHORT :near_bottom
MOV ECX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[ECX+10],-200   ;store -200 to X vel

:near_bottom
MOV EDX,DWORD PTR SS:[EBP+8]
MOV EAX,DWORD PTR DS:[EDX+8]     ;make EAX to X pos
MOV ECX,DWORD PTR SS:[EBP+8]
ADD EAX,DWORD PTR DS:[ECX+10]    ;add EAX to X vel
MOV EDX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[EDX+8],EAX     ;add EAX to X pos
MOV EAX,DWORD PTR SS:[EBP+8]
MOV ECX,DWORD PTR DS:[EAX+0C]    ;mov Y pos to eax
MOV EDX,DWORD PTR SS:[EBP+8]
ADD ECX,DWORD PTR DS:[EDX+14]    ;add Y vel tp EAX
MOV EAX,DWORD PTR SS:[EBP+8]
MOV DWORD PTR DS:[EAX+0C],ECX    ;move value of ECX to Y pos
MOV ECX,DWORD PTR SS:[EBP+8]
CMP DWORD PTR DS:[ECX+4C],0      ;is direction 0?
JNE SHORT :end_face_right

                     ;-Makes Game recognize sprite borders-

MOV EDX,DWORD PTR SS:[EBP+8]           ;We went over this with the debug cat.  
MOV EAX,DWORD PTR DS:[EDX+68]          ;And I'm to lazy to re-write this out.
SHL EAX,4                              ;Oh yeah, and this is if the NPc is facing left.
LEA ECX,[EAX+EBP-68]
MOV EDX,DWORD PTR SS:[EBP+8]
ADD EDX,54
MOV EAX,DWORD PTR DS:[ECX]
MOV DWORD PTR DS:[EDX],EAX
MOV EAX,DWORD PTR DS:[ECX+4]
MOV DWORD PTR DS:[EDX+4],EAX
MOV EAX,DWORD PTR DS:[ECX+8]
MOV DWORD PTR DS:[EDX+8],EAX
MOV ECX,DWORD PTR DS:[ECX+0C]
MOV DWORD PTR DS:[EDX+0C],ECX
JMP SHORT :end_of_code

:end_face_right
MOV EDX,DWORD PTR SS:[EBP+8]           ;We went over this with the debug cat.
MOV EAX,DWORD PTR DS:[EDX+68]          ;And I'm to lazy to re-write this out.
SHL EAX,4                              ;Oh yeah, and this is if the NPc is facing right.
LEA ECX,[EAX+EBP-0D0]
MOV EDX,DWORD PTR SS:[EBP+8]
ADD EDX,54
MOV EAX,DWORD PTR DS:[ECX]
MOV DWORD PTR DS:[EDX],EAX
MOV EAX,DWORD PTR DS:[ECX+4]
MOV DWORD PTR DS:[EDX+4],EAX
MOV EAX,DWORD PTR DS:[ECX+8]
MOV DWORD PTR DS:[EDX+8],EAX
MOV ECX,DWORD PTR DS:[ECX+0C]
MOV DWORD PTR DS:[EDX+0C],ECX

:end_of_code
MOV ESP,EBP                    ;End
POP EBP                        ;Of Code
RETN

I'll review the code and try to understand it later.



I'll put it in the first post with the debug cat and Shovel bricade.
 
Oct 17, 2013 at 2:20 AM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4481
Pronouns: she/her
Holy shit can you like
Put that in a spoiler tag or something
 
Oct 17, 2013 at 2:26 AM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 27
Pronouns: he/him
MagicDoors said:
Holy shit can you like
Put that in a spoiler tag or something
Yeah, I wasn't thinking.
I fried my brain from sitting there for 3 hours finishing that up today.
Not that it was hard, but If you've sat and modded intensely for 3 hours you would know what I mean.
 
Oct 17, 2013 at 2:30 AM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4481
Pronouns: she/her
No yeah I understand hacking is just so fun in large quantities. I wasn't taking a stab at you the thing was just really long.
 
Oct 18, 2013 at 2:17 AM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 27
Pronouns: he/him
ok...REALLY dumb question.

How do I move an NPC (with velocities,not instant teleportation.) to a given X, Y location?

it's not

PUSH ECX
PUSH EDX
PUSH 100
CALL 470060
push X, push Y push speed is it?
 
Oct 18, 2013 at 11:02 AM
Lvl 1
Forum Moderator
"Life begins and ends with Nu."
Join Date: May 28, 2008
Location: PMMM MMO
Posts: 3713
Age: 32
Bombchu Link said:
ok...REALLY dumb question.

How do I move an NPC (with velocities,not instant teleportation.) to a given X, Y location?

it's not
Code:
PUSH ECXPUSH EDXPUSH 100CALL 470060
push X, push Y push speed is it?
What? What are you trying to do?

Also I'm pretty sure the answer is that you don't, that or you have to do it internally via the NPC AI. There's no reason for non-instant movement to be coded as a general purpose NPC function in the game, rather, it's a bit illogical to make such functionality given how most NPCs handle their own movement.
 
Oct 18, 2013 at 5:18 PM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 27
Pronouns: he/him
GIRakaCHEEZER said:
What? What are you trying to do?

Also I'm pretty sure the answer is that you don't, that or you have to do it internally via the NPC AI. There's no reason for non-instant movement to be coded as a general purpose NPC function in the game, rather, it's a bit illogical to make such functionality given how most NPCs handle their own movement.
I'm trying to make an NPC that follows Quote. (think fairy from LoZ)

after loading Quotes X/Y position on map. and teleporting there.

---------

#1 Is Quote facing left or right?

#2 fly one space above and one behind behind quote?

#3 Has Quote moved?

load X and Y pos of Quote to ECX and EDX.

PUSH ECX
PUSH EDX
PUSH Velocity/speed
CALL function.

#4 end of code

-----

But it has to be...

#3 Has Quote moved horizontally?

#4 Give horizontal movement until X pos is equal to Quotes.

#5 Has Quote moved vertically?

#6 Give vertical movement until Y pos is equal to Quotes.

-----

I'm trying to think how this would work because if ,like you stated earlier, 200 = 1 pixel I wouldn't have to worry about jerky
movements with proper setup.

As you know this is the frist time I'm translating ideas to asm.

just trying to find out if this would work...
 
Back
Top