Making the player weapon not disappear when it hits an enemy. (Ideal for melee attacks)

jorotroid

Member


This works best for melee attacks. If you have both melee and projectiles in your game, then I would suggest using this method for just the melee, and having projectiles get destroyed as they already do by default in NESmaker. If you want a projectile that can go through multiple enemies, then that will require some more thought than what I am going to be covering here.

Difficulty: Easy. You only have to make a couple of small changes in two files.

Pros and Cons:
Pros:
+You character won't look like they lost an arm or has an invisible weapon when you successfully attack an enemy.

Cons:
-Unforeseeable consequences

How to Do It:
1. Go to Project>Project Settings and click on the Script Settings tab. Select the Script for Handle Monster Hurt and click the edit button. Go all the way to the bottom of the code where it says DeactivateCurrentObject. This is the line that makes your weapon disappear, so either comment it out or delete it. In its place put the following code:
Code:
LDA Object_flags,x
AND #%11111011
STA Object_flags,x
Save these changes.

2. Next go back to the Script Settings tab. This time select the script for Handle Object Collision and again click edit. Search for the label continueObjectCollisions_objectIsNotHurtOrInvincible. It will probably be around line 60 or so. You should see the following code there:
Code:
continueObjectCollisions_objectIsNotHurtOrInvincible
	LDY Object_type,x
	LDA ObjectFlags,y
	AND #%00000110
	BNE continueObjectCollisions_onlyPlayerTypesCheck
	JMP doneWithThisObjectCollision

Delete the first line after the label, and change the second line from LDA ObjectFlags,y to LDA Object_flags,x. That section should now look like this:
Code:
continueObjectCollisions_objectIsNotHurtOrInvincible
	LDA Object_flags,x
	AND #%00000110
	BNE continueObjectCollisions_onlyPlayerTypesCheck
	JMP doneWithThisObjectCollision

Go down a couple more lines to where you see another ObjectFlags,y in the continueObjectCollisions_onlyPlayerTypesCheck section. Change that one also to an Object_flags,x. Save the changes.

And you're done! You should be able to run the game and your melee weapon should be able to hit an enemy without vanishing.

Extra Stuff:
If you also have projectiles in your game (that do disappear upon hitting an enemy), then you will need to do a check for what kind of player weapon it is. This is my suggestion for doing that, but I am writing this one off the top of my head, because I'm not in a position to test this easily right now. Use something like this code instead of the code in step 1 for the Handle Monster Hurt Script:
Code:
	LDA Object_type,x
	CMP #$01			;; this means it's checking if it is your second game object in the NESmaker Editor
	BEQ WeaponIsMelee
	DeactivateCurrentObject
	JMP DoneHurtingMonster
WeaponIsMelee:
	LDA Object_flags,x
	AND #%11111011
	STA Object_flags,x
DoneHurtingMonster

If you have more than one melee attack object as suggested in Adventure tutorials, you will have to modify this suggested code a bit.

A Brief explanation of what is going on:
ObjectFlags,y holds the the flag information that an object of type y should have when it is created. Upon creation that gets copied to Object_flags with an "id" of x. So when we change the Object_flags, we are saying that this object is no longer a weapon. So when the object collision checks occur, the weapon will be ignored for the rest of its lifetime. When we attack again, again ObjectFlags gets copied into Object_flags for our new instance and this attack object is ready to do some hurting.

Ok. That's everything. Once again feel free to ask any questions. I'll remember to subscribe to this topic so I will be notified if anyone comments.
 

dale_coop

Moderator
Staff member
Thank you jorotroid
Very clean tutorial. And so useful. I surely will add it to my game.
...then, we will have to see how all this can be adapted for the 4.1.0
 

jorotroid

Member
Ok, so I may have found a slightly better way of doing things, but this only matters if you want the weapon to hit multiple times. If your weapon is meant to hit an enemy once and then disappear before it has the chance to hit another, then you might as well use my original method. If you used my original method, you only have to get rid of the
Code:
LDA Object_flags,x
AND #%11111011
STA Object_flags,x

at the end of the hurt monster script that I had you put in. Also get rid of the LDX tempx that was right above that code. Scroll up a bit to find a DeactivateCurrentObject this one is run when the monster is killed. Put an INC tempx. This is the most hacky part of this new solution. I'm not 100% sure why it's neccessary, but if you don't do it, the game will freeze when you kill an enemy.

Now go to the Handle Object Collision script again and find this block of code:
Code:
keepCheckingWeaponObjectCollsion4:
	;;; there was a player collision
	;; go through the different types of collision possible.
	;; first, check monster OR monser projectile, as that should lead to hurt/death
	LDY Object_type,x
	LDA ObjectFlags,y
	AND #%00001000 ;; is it a monster type?
	;;; if you'd like the player weapon to ALSO destroy projectiles
	;;; use #%00011000 here
	BNE otherIsMonsterTypeCollision_weapon
	JMP otherIsNotAMonsterTypeCollision_weapon
otherIsMonsterTypeCollision_weapon:

And change it to look like this:

Code:
keepCheckingWeaponObjectCollsion4:
	;;; there was a player collision
	;; go through the different types of collision possible.
	;; first, check monster OR monser projectile, as that should lead to hurt/death
	LDY Object_type,x
	LDA Object_status,x
	AND #%00000011
	BEQ monsterNotHurtOrInvincible
	JMP doneWithThisObjectCollision
monsterNotHurtOrInvincible:
	LDA ObjectFlags,y
	AND #%00001000 ;; is it a monster type?
	;;; if you'd like the player weapon to ALSO destroy projectiles
	;;; use #%00011000 here
	BNE otherIsMonsterTypeCollision_weapon
	JMP otherIsNotAMonsterTypeCollision_weapon
otherIsMonsterTypeCollision_weapon:

Basically, originally, the code wasn't checking to see if the monster was invincible when a player weapon collides with it. This inserts that check.

This fix is not fully tested, and I haven't had the opportunity to go through the steps again as I normally do when making a tutorial to make sure that I didn't forget anything. I will update when I re-implement it when 4.1.0 comes out.
 

Artix

New member
This is amazing! Thank you.

How can we check to see if the projectile is out of bounds? When I fire a projectile off the edge of the screen it loops back around from the other side.
 

CutterCross

Active member
Artix said:
This is amazing! Thank you.

How can we check to see if the projectile is out of bounds? When I fire a projectile off the edge of the screen it loops back around from the other side.

In Object Details>Details, set Edge Object Reaction to "Destroy Me".
 

Artix

New member
Thank you CutterCross! That was a surprisingly easy fix :D (I also needed to add a bounding box to the projectile-- in case anyone else with the same issue sees this)
 

Jakten

New member
Sorry to bump this old thread but I have what I think is the same problem but for a newer version.

I'm using 4.5 and I've tried to find the scripts and coding posted here but most of it doesn't seem to exist in the same way anymore and I can't seem to find the similar code to change. So I was wondering if any one knows how to do the same thing but for 4.5.

Here is an example of how my sword disappears when it hits, I assume this is the same issue that this thread was trying to address.SwordDisappear.gif

Thanks ahead of time!
 

dale_coop

Moderator
Staff member
In the 4.5.X versions, the scripts are different.

You need to find the place where your weapon is destroyed (when you kill the monster).
It might be in the Handle Object Collision script...

Ok, search for a line the line:
Code:
JSR doHandleHurtMonster
This is the moment where your weapon is colliding the monster. Before that line, you will see a
Code:
DestroyObject
That line destroys your weapon object (when hurting a monster).

So, basically, you need to skip that line if the weapon is your sword obj.
In order to do that, you could try replacing with:
Less:
LDA Object_type,x
CMP #$02  ;; <-- HERE, write your weapon object ID
BEQ +skip
DestroyObject
+skip:
 

chains

New member
... and don't forget to destroy your sword at the end of the animation. It will feel way better other than destroying it at the collision.
 
Top Bottom