May 26, 2013 at 3:43 PM
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 27
Pronouns: he/him
Some useful Examples:
Debug Cat:
Code:
offset npc216 ;replaces Debug cat
push ebp ;This starts the code
mov ebp, esp ;You must always do this. Or die!
;And also note that ALL NUMBER ARE IN HEX (unless otherwise stated)
;[arg-1] = [EBP+8] for referance.
;============================
;=====<///FRAMERECTS\\\>=====
;============================
SUB ESP,10 ;10 represents the total amount of framerects. (must match the highest EBP-___)
MOV DWORD PTR SS:[EBP-10],100 ;framerects are ordered Left...
MOV DWORD PTR SS:[EBP-C],0C0 ;UP
MOV DWORD PTR SS:[EBP-8],110 ;RIGHT
MOV DWORD PTR SS:[EBP-4],0D8 ;DOWN (notice that you MUST count by four's [in hex] for your framerects).
;this gives us a sprite (4 borders)
;================================
;=====<///BEHAVIOUR CODE\\\>=====
;================================
;----RECTS----
MOV EAX,DWORD PTR SS:[EBP+8] ;"+8" puts object pointer in EDX. NEVER FORGET TO DO THIS!
ADD EAX,54 ;holds 54 in the EAX
MOV ECX,[EBP-10] ;takes EBP-10 (framerect 1) and stores the value of ECX into it.
MOV [EAX],ECX ;takes the 54 from the EAX and adds it to the argument and runs "+54" aka Frame_L to
;recognize that it is the left side on the NPC.
MOV EDX,[EBP-C] ;takes EBP-C (framerect 2) and stores the value of EDX into it.
MOV [EAX+4],EDX ;adds 4 to make "+58" aka Frame_U to recognize up side of NPC
MOV ECX,[EBP-8] ;takes EBP-8 (framerect 3) and stores the value of EDX into it.
MOV [EAX+8],ECX ;adds 4 to make "+5C" aka Frame_R to recognize right side of NPC
MOV EDX,[EBP-4] ;takes EBP-4 (framerect 4) and stores the value of EDX into it.
MOV [EAX+0C],EDX ;adds 4 to make "+60" aka Frame_D to recognize down side of NPC
;==============================
;======<///END OF CODE=========
;==============================
mov esp, ebp
pop ebp
retn
Shovel Bricade:
Code:
offset 451E90 ;replaces shovel bricade.
PUSH EBP ;As always, start of the code.
MOV EBP,ESP ;remember all number are in HEX
;==============================
;====<///FRAMARECTS\\\>========
;==============================
SUB ESP,44 ; The number of framarects,
;===sprite 0 (stand still face left do nothing)===
MOV DWORD PTR SS:[EBP-20],0 ;Left border, sprite 0
MOV DWORD PTR SS:[EBP-1C],40 ;Up border sprite 0
MOV DWORD PTR SS:[EBP-18],10 ;Rigth border sprite 0
MOV DWORD PTR SS:[EBP-14],50 ;Bottom border sprite 0
;===sprite 1 (stand still face left blink)===
MOV DWORD PTR SS:[EBP-10],10 ;Left border, sprite 1 (stand still blink)
MOV DWORD PTR SS:[EBP-0C],40 ;Up border, bla bla bla...
MOV DWORD PTR SS:[EBP-8],20 ;bla bla...
MOV DWORD PTR SS:[EBP-4],50
;===sprite 2 (stand still face left do nothing)===
MOV DWORD PTR SS:[EBP-40],0 ;Sprite 2
MOV DWORD PTR SS:[EBP-3C],50
MOV DWORD PTR SS:[EBP-38],10
MOV DWORD PTR SS:[EBP-34],60
;===sprite 3 (stand still face left blink)===
MOV DWORD PTR SS:[EBP-30],10 ;Sprite 3
MOV DWORD PTR SS:[EBP-2C],50
MOV DWORD PTR SS:[EBP-28],20
MOV DWORD PTR SS:[EBP-24],60
;================================
;=======<///BEHAVIOUR\\\>========
;================================
;-Starting up-
MOV EAX,DWORD PTR SS:[EBP+8] ;The oh-so important NPC pointer. nessisary before putting in any action (using EAX).
MOV ECX,DWORD PTR DS:[EAX+74] ;refering to you wonderful table of NPC's "74+" means event script state (using ECX)
MOV DWORD PTR SS:[EBP-44],ECX ;Let's store the value of [EBP-44] (a local variable) into the ECX for use later. (along with the script state)
;-Check for <ANP's and alternate direction flags-
CMP DWORD PTR SS:[EBP-44],0 ;Compares the state of [EBP-44] to see the current value
JE :jump_lower ;If it's zero, let's jump lower down...
CMP DWORD PTR SS:[EBP-44],1 ;Compares the state of [EBP-44] to see the current value
JE :even_lower ;If it's one, let's jump even lower down...
CMP DWORD PTR SS:[EBP-44],2 ;Compares the state of [EBP-44] to see the current value
JE :lowest ;If it's one, let's jump even lower down...
JMP :if_not_any ;What? It's not any of these numbers?!?
:jump_lower
MOV EDX,DWORD PTR SS:[EBP+8] ;NPC pointer stored (through EDX)
MOV DWORD PTR DS:[EDX+74],1 ;changes NPC script state to to "1" (next time it loops through we will jump straight to :even_lower becasue this is not nessisary to do this again)
MOV EAX,DWORD PTR SS:[EBP+8] ;NPC pointer stored (through EAX)
MOV DWORD PTR DS:[EAX+68],0 ;===NPC frame number changed to no. 0===
MOV ECX,DWORD PTR SS:[EBP+8] ;NPC pointer stored (through ECX)
MOV DWORD PTR DS:[ECX+64],0 ;a timer to Wait is stores through ECX
:even_lower
PUSH 78 ;Push 78
PUSH 0 ;Push 0 and then...
CALL 0040F350 ;call random number between 0 and 78, stores it into the EAX
ADD ESP,8 ;Something that has to be done after calling a random number.
CMP EAX,0A ;see's if the ramdon number is 0A (10 in decimal)
JNE :if_not_any ;If it isn't jump...
MOV EDX,DWORD PTR SS:[EBP+8] ;NPC pointer stored (through EDX)
MOV DWORD PTR DS:[EDX+74],2 ;changes NPC Scriptstate to 2
MOV EAX,DWORD PTR SS:[EBP+8] ;NPC pointer stored (through EAX)
MOV DWORD PTR DS:[EAX+78],0 ;NPC script timer stored through EAX using 0
MOV ECX,DWORD PTR SS:[EBP+8] ;NPC pointer stored (through ECX)
MOV DWORD PTR DS:[ECX+68],1 ;===NPC frame number changed to no. 1===
JMP :if_not_any
:lowest
MOV EDX,DWORD PTR SS:[EBP+8] ;NPC pointer stored (through EDX)
MOV EAX,DWORD PTR DS:[EDX+78] ;NPC script timer stored through EAX
ADD EAX,1 ;Add 1 to the EAX
MOV ECX,DWORD PTR SS:[EBP+8] ;NPC pointer stored to ECX
MOV DWORD PTR DS:[ECX+78],EAX ;store the Script timer to the EAX
MOV EDX,DWORD PTR SS:[EBP+8] ;NPC pointer stored to EDX
CMP DWORD PTR DS:[EDX+78],8 ;compare the EDX (including the script timer thingy stored to the EDX) to 8
JLE :if_not_any ;If it is equal or less then 8, jump...
MOV EAX,DWORD PTR SS:[EBP+8] ;NPC pointer stored to EAX
MOV DWORD PTR DS:[EAX+74],1 ;add 1 to Scriptstate
MOV ECX,DWORD PTR SS:[EBP+8] ;NPC pointer stored to ECX
MOV DWORD PTR DS:[ECX+68],0 ;changes frame number to 0
:if_not_any
MOV EDX,DWORD PTR SS:[EBP+8] ;NPC pointer stored (through EDX)
CMP DWORD PTR DS:[EDX+4C],0 ;Compares direction of NPC to 0 (left)
JNE :direction_not_zero
;-blink face left-
MOV EAX,DWORD PTR SS:[EBP+8] ;NPC pointer stored (through EAX)
MOV ECX,DWORD PTR DS:[EAX+68] ;Changes frame number to ECX's current number.
SHL ECX,4 ;SHL Shifts the value of the ECX 4 times.
LEA EDX,[ECX+EBP-20] ;put's ECX's number and [EPB-40] into EDX. (changes blink to previous sprite) done blink
MOV EAX,DWORD PTR SS:[EBP+8] ;we went over this with the debug cat, makes the game realise the border of the sprites....
ADD EAX,54 ;add 54 to EAX
MOV ECX,DWORD PTR DS:[EDX] ;EDX is 54 "Frame left"
MOV DWORD PTR DS:[EAX],ECX
MOV ECX,DWORD PTR DS:[EDX+4] ;EDX+4 is 58 "frame up"
MOV DWORD PTR DS:[EAX+4],ECX
MOV ECX,DWORD PTR DS:[EDX+8] ;EDX+8 is 5C "frame right"
MOV DWORD PTR DS:[EAX+8],ECX
MOV EDX,DWORD PTR DS:[EDX+0C] ;EDX+0C is 60 "frame bottom"
MOV DWORD PTR DS:[EAX+0C],EDX ;then we end the code.
JMP :end_of_code
;-blink face right-
:direction_not_zero
MOV EAX,DWORD PTR SS:[EBP+8] ;NPC pointer stored (through EAX)
MOV ECX,DWORD PTR DS:[EAX+68] ;Changes frame number to ECX's current number.
SHL ECX,4 ;SHL Shifts the value of the ECX 4 times.
LEA EDX,[ECX+EBP-40] ;put's ECX's number and [EPB-40] into EDX.(changes blink to previous sprite)
MOV EAX,DWORD PTR SS:[EBP+8] ;we went over this with the debug cat, makes the game realise the border of the sprites....
ADD EAX,54 ;add 54 to EAX
MOV ECX,DWORD PTR DS:[EDX] ;EDX is 54 "Frame left"
MOV DWORD PTR DS:[EAX],ECX
MOV ECX,DWORD PTR DS:[EDX+4] ;EDX+4 is 58 "frame up"
MOV DWORD PTR DS:[EAX+4],ECX
MOV ECX,DWORD PTR DS:[EDX+8] ;EDX+8 is 5C "frame right"
MOV DWORD PTR DS:[EAX+8],ECX
MOV EDX,DWORD PTR DS:[EDX+0C] ;EDX+0C is 60 "frame bottom"
MOV DWORD PTR DS:[EAX+0C],EDX
;=================================
;=======<///END OF CODE\\\>=======
;=================================
:end_of_code
MOV ESP,EBP ;That wasn't so bad.
POP EBP
RETN
Purple Critter:
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
old useless post:
I think this question is complicated enough to have it's own thread. How do I hack my own NPC into cave story? All I want (for now) is just a very simple npc that basically a carbon copy of Momorin. It stands around, blinks, and has one animation sprite (shocked).
here is what I've got
here are my questions:
What address do I start at?
How do I make my own framarects?
Is it really as a simple as
MOV DWORD PTR SS: [LOCAL.--],--
and do I need to define what .bmp image the game draws the sprite from?
Do I just copy/ paste momo's coding? (I prefer to write it out to know exactly what the coding is applying)
Will CE or BL realize the newly added entity?
And please don't just shove this off as "oh, you can learn this latter" or "you need more skill" I want to learn it now, and learn it well.
here is what I've got
PUSH EBP
MOV EBP, ESP
ze' framarects.
actual coding
MOV ESP, EBP
POP EBP
RETN
MOV EBP, ESP
ze' framarects.
actual coding
MOV ESP, EBP
POP EBP
RETN
here are my questions:
What address do I start at?
How do I make my own framarects?
Is it really as a simple as
MOV DWORD PTR SS: [LOCAL.--],--
and do I need to define what .bmp image the game draws the sprite from?
Do I just copy/ paste momo's coding? (I prefer to write it out to know exactly what the coding is applying)
Will CE or BL realize the newly added entity?
And please don't just shove this off as "oh, you can learn this latter" or "you need more skill" I want to learn it now, and learn it well.