[4.1] End of Text Action --> warps

dale_coop

Moderator
Staff member
For some who need that functionality... When a text is finished, it execute a warp.
It doesn't existing currently, but we can hijack the "Open Shop" end of text action, because it's not used in the current 4.1 (no code behind that action).


THE EASY WAY (NESMaker 4.1.3)
With a ZipScript patch:

1/ Download the ZipScript file from here: https://drive.google.com/open?id=1oOLYrjyY2KE4COhojJlHZG-h6HD_OzXR

2/ On your scrolling game project, select the "Project > Run Project Script" menu:

2019-01-13-15-58-19-NES-MAKER-4-1-1-Version-0x158-Mon-Jeu-Plateforme-MST.png


And select the "EndofTextAction_OpenShopWarps.zip" you just downloaded. Validate and after confirming the warnings message, you should have the patch installed:

2019-01-13-15-13-26-Script-Execute.png


3/ Set your Text to use the end of action :

2019-02-03-13-28-00-NES-MAKER-4-1-4-Version-0x158-Unsaved-Project.png


4 / Set your warp In / Out in your screen infos.

Now, it should work, after the text box is closed, it warps.
If you have error to if the patch doesn't work, you could try the normal manual way.



THE NORMAL MANUAL WAY
Doing manually the modifications in some scripts:

1/ Add a new user variable "openShopWarps" (initial value 0) in the "Project Settings > User Variables".

2/ Duplicate the "HandleTextBox.asm" script as "HandleTextBox_openShopWarps" (for example), assign it to your "Handle text Box" element in the "Project Settings > Script Settings":

2019-02-03-13-28-00-NES-MAKER-4-1-4-Version-0x158-Unsaved-Project.png



3/ modify the "HandleTextBox_openShopWarps", line 319, right after the "notEndItem:" line (but before the "CMP #_MORE" line), like this:

Code:
notEndItem:
;; begin check for warps -->> : 
	CMP #_ENDSHOP
	BNE notEndShop
	;; is an end "Open SHOP"
	LDA #$01
	STA openShopWarps 	;; we set a variable that be used to execute the warp when the text disappears
	JMP EndText
notEndShop:
;; <<-- end check for warps
;; The rest of the normal code from here:

	CMP #_MORE


4/ Still modifying the "HandleTextBox_openShopWarps", line 657, add this script (this execute the warp):

Code:
;;;; THIS WOULD WARP YOU TO A SCREEN AFTER TEXTBOX.
	LDA openShopWarps 
	BEQ +
	LDA #$00
	STA openShopWarps
	LDA #$00
	STA newGameState
	LDA warpMap
	STA currentMap
	CLC
	ADC #$01
	STA temp
	GoToScreen warpToScreen, temp, #$02
	LDA #$00
	STA playerToSpawn
	LDX player1_object
	DeactivateCurrentObject
	LDA #$01
	STA loadObjectFlag
	LDA mapPosX
	STA newX
	LDA mapPosY
	STA newY
	+


5/ Set your Text to use the end of action :

2019-02-03-13-28-00-NES-MAKER-4-1-4-Version-0x158-Unsaved-Project.png


6 / Set your warp In / Out in your screen infos.

Voilà... it should work, after the text box is closed, it warps.



Small Addition (optional)

To prevent the user to rapidly press "B" and skip all the text box (it will not warp), you can add those lines at the beginning of your b_crete_melee (or b_activate_textNPC) script:
Code:
	LDA textboxHandler  ;; check if the text is already displayed
	AND #%11000000 
	BEQ +
	RTS
	+
	;; from here, the normal script...:
 

CutterCross

Active member
I did this the stupid way in 4.0.11 for cutscenes with text. Since by default text stops all object updates, I just spawned the player above a warp tile and blocked off the rest of the screen with solid tiles. So when the text went away, gravity would make the player fall on the warp tile and warp to a new screen.

But this is clearly the better method XD
 

dale_coop

Moderator
Staff member
But you did it, with the limitations of the built in fonctionalities, the result was impressive. It’s the most important.
As Joe says, NES dev is just limitations, compromises and tricks ;)
 

dale_coop

Moderator
Staff member
I updated the script because I forgot to set back to 0 the variable on warp:
Code:
	LDA #$00
	STA openShopWarps
 

dale_coop

Moderator
Staff member
FOR NESMAKER 4.1.3 - 4.1.5


1/ In the "Project Settings > User Variables", add a new variable named "TextIDScreen" with initial value "0".


2/ Make a new script named "HandleTextBox_openShopWarps.asm", with that:
Code:
HandleTextBox:

;; textboxHandler
 ; 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0
  ;7 = Textbox is active.
   ;    6 = Black box is being created, will then create text.
    ;        5 = Attribute update to black.
     ;           4 = text is being created.
      ;             = loop to 5 if more text.
       ;             3 = Black box is being created, with then restore NT
        ;                 2 = Attributes to main NT
         ;                     1 = restore NT
          ;                          0 = check for "more" text.
			


	LDA textboxHandler
	AND #%10000000
	BNE textboxIsActive
	RTS ;; textbox is inactive.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
textboxIsActive:
	LDA updateNametable
	BEQ notAlreadyWritingToNT
	RTS
notAlreadyWritingToNT
	;HideSprites
;; DO TEXT BOX STUFF.
	;; Which text box stuff to do is determined by the textboxHandler byte.
	;; if it is active, but all other bits are inactive, that means we have just activated and we need to turn
	;; this system on.
	LDA textboxHandler
	AND #%01111111
	BNE textboxSettingsAlreadyOn
	;;; get textbox settings
 ;; skip resetting the offset.
	LDA #$00
	STA updateNT_offset
	STA updateHUD_offset

	STA updateNT_H_offset
	STA updateNT_V_offset
	
	;;; zero out the things offsets and start creating the blackout box.
	LDA #%11000000
	STA textboxHandler ;; flow right into the next.
textboxSettingsAlreadyOn:
	
	LdA textboxHandler
	AND #%01000000
	BEQ notCreatingBlackBox
	;;;; CREATE THE BLACK BOX.
	;;;; The frist phase is to create the black box.
	;;;; no matter what color the text box will be, or which palette it will use
	;;;; it will always first create a box of "blanks" so it can be changed to whatever
	;;;; background attribute you'd like without noticing the attribute change.
	JSR CreateBlackBox
	;;; now the black box has been created.
	
notCreatingBlackBox:
	LDA textboxHandler
	AND #%00100000
	BEQ notSettingTextboxAttributes
	JSR isWritingTextboxAttributes
	RTS
	
	;;; set textbox attributes.
notSettingTextboxAttributes:
	LDA textboxHandler
	AND #%00010000
	BEQ notUpdatingTextboxText
	;; updating textbox text.
	JSR isWritingTextToTextbox

	RTS
notUpdatingTextboxText:
	LDA textboxHandler
	AND #%00001000
	BEQ notErasingTextboxText
	JSR CreateBlackBox
	RTS
notErasingTextboxText:
	LDA textboxHandler
	AND #%00000010
	BEQ notRestoringNametables2
;	JSR CheckForEndOfTextString
;	LDA gameHandler
;	AND #%00100000
;	BEQ notRestoringNametables2 ;; because we have finished.
	JSR RestoreNametableData
notRestoringNametables2
	RTS
	

	
	
	
	
	
	
	
	
	
	
	
	
	
getUpdateTileOffsetPosition:
	LDA xScroll
	LSR
	LSR
	LSR
	LSR
	CLC
	ADC	#BOX_1_ORIGIN_X
	CLC
	ADC updateNT_H_offset
	STA tileX
	
	LDA #BOX_1_ORIGIN_Y
	CLC
	ADC updateNT_V_offset
	STA tileY
	JSR coordinatesToMetaNametableValue
	;;; spits out updateNT_pos as low and updateNT_pos+1 as hi of address to write.
	;;; right now, this is in terms of a single nametable, starting at $20 as the high top left corner high byte.
	
	

	
;;;; FOR HITE BYTE:
;;;; Take columnTracker and divide by 2 so you get a value 0-16
;;;; Add that number to BOX_1_ORIGIN_X.
;;;; If the sum is less than 16, this should stay in the same nametable.
;;;; Otherwise, it should cross nametables.
	Ldy columnTracker
	LDA columnTracker
	AND #%00001111
	CLC
	ADC #BOX_1_ORIGIN_X ;; plus offset of what tile you're drawing.
	CLC
	ADC updateNT_H_offset
	AND #%00010000
	BNE +
	;;; same nametable
	LDA columnTracker
	AND #%00010000
	BNE +++
	;; this started in even table,
	;; so it should stay in even table
	JMP updateIsEvenTable
+++	
	;;; this started in odd table
	;;; so it should stay in odd table.
	JMP updateIsOddTable
+
	;;; different nametable
	LDA columnTracker
	AND #%00010000
	BNE +++
	;; this started in even table
	;; so it should now be odd table.
	JMP updateIsOddTable
+++
	;;; this started in odd table
	;;; so it should now be even table.
	JMP updateIsEvenTable

	

updateIsEvenTable:
	LDA updateNT_pos+1
	AND #%00000011 ;; 0,1,2 or 3
	clc
	adc #$20
	STA updateNT_pos+1
	JMP gotHiUpdatePos
	
updateIsOddTable:
	LDA updateNT_pos+1
	AND #%00000011 ;; 0,1,2 or 3
	CLC
	ADC #$24
	STA updateNT_pos+1
	JMP gotHiUpdatePos
gotHiUpdatePos:

	RTS
	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
checkNTforNewTile:
	LDA temp3; updateNT_pos
	AND #%00100000
	CMP #%00100000
	BEQ newTileHasCrossedThreshold
	;; new tile has not crossed threshold.
	;; same nametable

	LDA columnTracker
	AND #%00010000
	BNE updateIsOddTable
	JMP updateIsEvenTable
newTileHasCrossedThreshold:
	
	LDA columnTracker
	AND #%00010000
	BNE updateIsEvenTable
	JMP updateIsOddTable
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;RTS ;; redundant, unnecessary
	
	
isWritingTextToTextbox:
	;;; already in bank 17.
	;; we need to get positioning.

	LDA xScroll
	LSR
	LSR
	LSR
	STA temp
	LDA #BOX_1_ORIGIN_X
	ASL
	CLC
	ADC updateNT_H_offset
	CLC
	ADC temp
	STA temp3
	AND #%00011111
	STA tileX
	
	LDA #BOX_1_ORIGIN_Y
	ASL
	CLC
	ADC updateNT_V_offset
	STA tileY
	
	JSR coordinatesToNametableValue
	JSR checkNTforNewTile
	;; temp has position value.
	;LDA temp
	;STA updateNT_pos
	
	
	
	LDY textVar ;; what string
	LDA screenText,y
	TAY
	LDA stringsTableLo,y
	STA temp16
	LDA stringsTableHi,y
	STA temp16+1
	LDY textboxOffsetHold
	LDA (temp16),y
	
	;; this is where we determine if this is a special character or a normal letter/number to update.
	CMP #_END
	BNE +
;;;; END:
EndText:
	;; this is and _END value.
	;; it turns off writing to the textbox.
	
	LDA textboxHandler
	AND #%01111111
	STA textboxHandler
	;;;;; textbox handler stays on the same state
	;;;;; but deactivates.
	;;;;; it will start again if bbutton is pressed again
	;;;;; on state 00001000, which will begin the 'turn off' process.
	
	JMP doneTextUpdate
+
	CMP #$FE ;; is it a new line?
	BNE notANewLine_text
;;;; NEW LINE:


	LDA #$00
	STA	updateNT_H_offset
	INC updateNT_V_offset
	INC textboxOffsetHold
	
	JMP doneTextUpdate
notANewLine_text:

	CMP #_ENDTRIGGER
	BNE notEndTrigger
	;; is an end trigger
	INC textboxOffsetHold ;; get the very next value.
	LDY textboxOffsetHold
	LDA (temp16),y
	STA temp
	;;;; this now has the trigger to change.
	TriggerScreen temp
	JMP EndText
notEndTrigger:

	CMP #_ENDITEM 
	BNE notEndItem
	;;; gives player an item.
	INC textboxOffsetHold ;; get the very next value.
	LDY textboxOffsetHold
	LDA (temp16),y
	TAY
	;;; this now has the bit to flip in BOSSES DEFEATED constant.
	LDA ValToBitTable_inverse,y
	ORA weaponsUnlocked
	STA weaponsUnlocked
	TriggerScreen screenType ;; will flip the current screen type
	;PlaySound #SFX_DO_TRIGGER
	JMP EndText
	
notEndItem:
;; begin check for warps -->> : 
	CMP #_ENDSHOP
	BNE notEndShop
	;; keep the Text Index of the NPC
	LDY textVar
	LDA screenText,y
	STA TextIDScreen
	JMP EndText
notEndShop:
;; <<-- end check for warps
;; The rest of the normal code from here:
	CMP #_MORE
	BNE notMoreText
	LDA #%10000000
	STA textboxHandler
	;; flip a more text flag.
	LDA #$01
	STA moreText
	INC textboxOffsetHold
	JMP EndText
notMoreText:
;;;; NORMAL VALUE
		;;;;; The look up was a normal letter, number, or other hud value.
	CLC 
	ADC #$C0
	STA updateHUD_fire_Tile	
	
	LDA updateNT_pos
	STA updateHUD_fire_Address_Lo
	LDA updateNT_pos+1
	STA updateHUD_fire_Address_Hi
	INC updateNT_H_offset
	INC textboxOffsetHold
doneTextUpdate:	

	RTS
	
	
	
	
	
	
	
	
	
	
	
CreateBlackBox	
	LDX #$00
	
;;; DRAW METATILE 1
	;; this macro SETS it to change on the next vblank update.
	;; starting at address hi-lo, with the tile in the third argument.
	;; if it sees #BLANK_TILE, it will create a meta tile of four blank tiles.
	;; if it sees any other value, it will create a metatile starting with 
	;; that index as the top left corner.
	
	;;;;;;; IF THE GAME DOES NOT SCROLL:
	;;;;;;; You can simply read the box value, do a little math, to get the offset
	;;;;;;; of the address for the top left corner, and skip the whole business of
	;;;;;;; finding the offset based on the scroll.
	
	;;;;;;; IF THE GAME DOES SCROLL:
	;;;;;;; YOu will need to get the offset value so it is at the box value position
	;;;;;;; compared to the CAMERA rather than zero.
	
	;;;;;;; Fortunately, we already have tables set up for columnTableLo and columnTableHi
	;;;;;;; which we use to handle the column for scrolling.  
	;;;;;;; we can use the columnTracker value to help determine the proper offset.
	
	;;;;;;; There can only be 32 columns.
	
	;;;;;;; And we will use updateNT_offset to continue this over frames, 
	;;;;;;; and to handle tile to offset.
	;;;;;;; this will be set to zero wherever HandleTextBox is activated.
	;;;;;;; It needs to, in some way, be boolean (like a key press, or using a boolean var).
	; LDA #$00
	; STA updateNT_H_offset
	; STA updateNT_V_offset
	;; THESE ALSO MUST BE SET IN THE BOOL VAR PLACE
	;; Whatever code is calling this must also set these to zero.

	
	
	
	LDA #$00
	STA tilesToWrite
	LDA #$04
	STA dummyVar2
DoLoopThing:
	JSR getUpdateTileOffsetPosition
	SetMetaTileToChange updateNT_pos+1, updateNT_pos, #BLANK_TILE

 	INC updateNT_H_offset
	LDA updateNT_H_offset
	CMP #BOX_1_WIDTH
	BEQ ++
	DEC dummyVar2
	LDA dummyVar2
	BEQ +
	JMP DoLoopThing
++ ;; width has been reached.
	;; now to test the height, and to move h pos back to the left.

	
	BEQ dontEndCreatingBlackBox
	JMP EndCreatingBlackBox
dontEndCreatingBlackBox:
	
	LDA #$00
	STA updateNT_offset
	STA updateHUD_offset
	STA updateNT_H_offset
	INC updateNT_V_offset


+	

	LDA #$01
	STA updateNametable  ;; turn on write.
	
	LDA updateNT_V_offset
	CMP #BOX_1_HEIGHT
	BCS turnOffCreatingTextBox
	
	LDA updateNT_H_offset
	CMP #BOX_1_WIDTH
	BEQ turnOffCreatingTextBox
	JMP EndCreatingBlackBox
turnOffCreatingTextBox:
	
	;;;;;;;;;;;;;;;;;;;;;;;;;;
	;;; Setup text specifics
	LDA #$00
	STA stringGroupOffset
	STA updateNT_H_offset
	STA updateNT_V_offset
	
	LDA xScroll
	LSR
	LSR
	LSR
	STA temp
	LDA #BOX_1_ORIGIN_X
	ASL
	CLC
	ADC temp
	CLC
	ADC #H_PAD_TEXTBOX
	STA tileX
	LDA #BOX_1_ORIGIN_Y
	ASL
	CLC
	ADC #V_PAD_TEXTBOX
	STA tileY
	
;	LDA #$01
;	STA writingText ;; turn on writing text.
	LDA moreText
	BEQ +
	LDA #$00
	STA moreText
	JMP ++
+
	LDA #$00
	STA textboxOffsetHold
++
	STA updateNT_H_offset
	STA updateNT_V_offset

	LDA textboxHandler
	AND #%00001000
	BEQ continueToUpdatingAttributes
	;;; is turning textbox OFF, so no writing to text.
	;;; will have to allot for changing attributes back with the
	;;; bit 00000100
	LDA #%10101000 ;; turn on attribute update
	STA textboxHandler
	LDA #$00
	STA updateNT_H_offset
	STA updateNT_V_offset
	STA updateNT_offset
	STA updateNT_compensation

;	LDA xScroll_hi

;	AND #%00000001
;	BEQ oddToEven2
;	LDA #$27
;	JMP gotNtDeets2
;oddToEven2:
;	LDA #$23
;gotNtDeets2:
;	STA updateNT_tableLeft
;	STA updateNT_details

	;LDA columnTracker
	LDA #BOX_1_ORIGIN_X
	LSR
	TAY
	LDA attrColumnTableHi,y
	STA updateNT_tableLeft
	STA updateNT_details

	RTS
continueToUpdatingAttributes:
	LDA #%10001000
	STA textboxHandler
	LDA #$00
	STA updateNT_H_offset
	STA updateNT_V_offset
	STA updateNT_offset
	STA updateNT_compensation
	
	
;	LDA xScroll_hi

;	AND #%00000001
;	BEQ oddToEven
;	LDA #$27
;	JMP gotNtDeets:
;oddToEven:
;	LDA #$23
;gotNtDeets:
;	STA updateNT_tableLeft
;	STA updateNT_details
	
	;LDA columnTracker
	LDA updateNT_H_offset
	CLC
	ADC updateNT_offset
	ASL
	CLC
	ADC	columnTracker
	AND #%00011111
	LSR 
	TAY
	LDA attrColumnTableHi,y
	STA updateNT_details
	
	LDA #%10100000
	STA textboxHandler
	;;;;;;;;;;;;;;;;;;;;;;;;;;;
	RTS
EndCreatingBlackBox:	
	LDA #$01
	RTS
	
	
	
	
RestoreNametableData:

	

	;;; FIRST we need to find the metaNametale value from the ROM.
	;;;;;;;;;;LESSER PRIORITY;;;;;;;;;;;;;;
	;;; THEN we need to check it againt collision type to / screen state to see if it should be 
	;;; change (for instance, a tile that changes at night / saved / changes if no monsters, if there are no monsters, etc)
	;;; THEN, we should probably always just restore the hud at the end.
	;;; the problem is, the data we need to fetch is in bank 16, then screen bank, 
	;;; while we are currently in bank 17 with this routine.
	;;; so restoration of nametable, or at least analysis of whate tiles to write, will have to happen OUTSIDE of this routine
	;;; We handle it in HandleBoxes, which will populate updateTile00-03, and respect paths.
	;;; And we handle POSITION to update here.

	LDX #$00
	LDA #$00
	STA tilesToWrite
	
	JSR getUpdateTileOffsetPosition
	
	

	LDA updateNT_pos
	STA temp
	LDA updateNT_pos+1
	STA temp1
	

	SetTileToChange temp1, temp, updateTile_00
	LDA temp
	CLC
	ADC #$01
	STA temp2
	LDA temp1
	ADC #$00
	STA temp3
	
	
	SetTileToChange temp3, temp2, updateTile_01
	
	LDA temp
	CLC
	ADC #$20
	STA temp2
	LDA temp1
	ADC #$00
	STA temp3
	
	
	SetTileToChange temp3, temp2, updateTile_02
	
	LDA temp
	CLC
	ADC #$21
	STA temp2
	LDA temp1
	ADC #$00
	STA temp3
	
	SetTileToChange temp3, temp2, updateTile_03
	INC tilesToWrite
	LDA #$01
	STA updateNametable
	
	INC updateNT_H_offset
	LDA updateNT_H_offset
	CMP #BOX_1_WIDTH
	BNE dontReturnToGame
	LDA #$00
	STA updateNT_H_offset
	INC updateNT_V_offset
	LDA updateNT_V_offset
	CMP #BOX_1_HEIGHT
	BNE dontReturnToGame
	LDA #$00
	STA textboxHandler
	STA updateHUD_offset
	LDA gameHandler
	AND #%11011111
	STA gameHandler
	;ShowSprites

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; check to see if there is behavior after a text box.

;;;; THIS WOULD WARP YOU TO A SCREEN AFTER TEXTBOX.
	LDA TextIDScreen 
	CLC
	BEQ +
		STA warpToScreen
		LDA #$00
		STA TextIDScreen
		STA newGameState
		LDA warpMap
		STA currentMap
		CLC
		ADC #$01
		STA temp
		GoToScreen warpToScreen, temp, #$02
		LDA #$00
		STA playerToSpawn
		;LDX player1_object
		;DeactivateCurrentObject
		;LDA #$01
		;STA loadObjectFlag
		LDA mapPosX
		STA newX
		LDA mapPosY
		STA newY
	+
	
	; LDA #$01
	; STA activateWarpFlag
	; PlaySound #SND_ENTER
	; LDX player1_object
	; LDA Object_x_hi,x
	; STA mapPosX
	; LDA Object_y_hi,x
	; STA mapPosY
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
	
dontReturnToGame:

	RTS
	
	
	
isWritingTextboxAttributes:
	;; handle all four quadrants of the attribute.
	
	
	RTS


3/ Assign the "HandleTextBox_openShopWarps.asm" script to the "Handle Text Box" element in the "Projet Settings > Script Settings".


4) Make some NPC monster/objects and put them on the screen


5) Set your Texts, for the screen warps. If you want a warp to Screen 16 (X=0, Y=1) then set your "Text 16"... and a warp to Screen 25, set your "Text 25" (X=9,Y=1)... using the text index corresponding the screen index you want.
2018-12-26-10-53-22.png

And for each Text you set, chose the "Open Shop" action (currently not used so we will use it for the warp to the textindex screen).

6) Add all those warp Text to a Text Group:
2018-12-26-10-56-14.png

And assign the Text Group to your main screen:
2018-12-26-10-56-29-Screen-Details.png

(don't care about the checkbox on that screen, it's an old screen)

Now, the multi warps should work.
 

DanielT1985

Member
Is there a way to make an end animation warp to screen? I'm wanting to do this for a cut-scene I'm making in my game.
 

dale_coop

Moderator
Staff member
I think there is a  « Warp to screen » already to end of animation... or I misremember it?
 

DanielT1985

Member
dale_coop said:
I think there is a  « Warp to screen » already to end of animation... or I misremember it?

Yeah, I just found it a minute ago. Glad the NESmaker team already knew what we were gonna do with that, lol. For real though, I'm glad it already exists.
 
It's too late for me to keep troubleshooting this, but at the off chance that someone knows what's going on: this code has stopped working for me. Or maybe I didn't test it properly and it never worked. I'm not sure because it half works.

I have two NPC's with different warps, and one works while the other seems to change depending on where I place my player at the start of the game. I have no idea what could be causing the discrepancy. I have this same screen copy pasted elsewhere on the map, with different warp coordinates and the same situation happens. One NPC warps to the proper location, the other goes some where else, and it doesn't seem to matter if the screen that it goes to has a "warp in" location or not, it just loads a couple different screens and sticks me in the wall on the edge of the screen.

-

I just tried switching the physical locations of the NPCs on the screen. No other changes. And both warps stopped working. The warp that used to work did send me to the proper location, but it acted like the "warp in" coordinates were not set and it booted me out and stuck me in the wall of another screen as usual.

It's possible that my nesmaker has developed a bug of some kind because I have been getting multiple random errors that seem to change without reason.

--
Edit:: One of my copy pasted screens started working, randomly as far as I can tell. This one is literally a copy paste of the screen with the broken warp, so I don't know why it's different. The screen that doesn't work is located at X0Y1, while the one that works is at X13Y13. I made another copy at X8Y1 with different warp coordinates and that one works as well, so it seems to be the X0 column that's causing problems? Hopefully it stays consistent now.
 

MrElephant

Member
Dale, thanks for creating this thread. Two questions, is there a way to use other text indexes not relative to that particular screen. I'm trying to keep my scripts organized. Second, warping to the underworld. Would that be text #257 if I wanted to go to the first screen?
 

dale_coop

Moderator
Staff member
I am not sure to understand your first question... if not relative/set to a screen, how you would set which text to display? you need to set texts to a text group and that text group to a screen... to be able to display a text on that screen.
Second, warp to underworld would be easy... the question would be, do you want the texts always warp you to the Underworld?
 

MrElephant

Member
No, I apologize for not being specific. When you wanted to warp to screen number 16, you used "Entry 16". I want to keep my entries organized based off the story I am writing, and would rather not have to put warps in random parts. I understand you have to assign the entries in the text groups. What I am asking is, can I use a different entry-say "Entry 3" to warp to screen 157-or do I always have to use the entry relative to the screen I am warping to. (Entry 157 to warp to screen 157)

@second question-Yes, I would like the scripts always to warp to the underworld. As long as the normal warp feature can still get out of it.
 

dale_coop

Moderator
Staff member
1/ Ok... I understand ;)
Hummm you can't... because if fact, it's not the name nor the text of the entry that is used. It's it's index. (Starting from 0...)
the script just match the text index ("entry 3" is the 0,1,2... 3rd text of the list) to the screen index (screen 0,1,2... 3rd screen of the overworld map).
So, to organise them, I would suggest to give specific names.

2/ So... to warp to the underworld... modiy the "HandleTextBox_openShopWarps.asm" script, around line 667, you will see:
Code:
		CLC
		ADC #$01
		STA temp
Try replacing those 3 lines with :
Code:
		; CLC
		; ADC #$01
		LDA #$02	;;<<---- ALWAYS warp to the UNDERWORLD
		STA temp
 

MrElephant

Member
Dale,

Thank you for responding. One final question. I have followed all of the steps, but it isnt working for 4.0.11. I am using the Adventure Game module, and I have added the HandleTextBox_openShopWarps.asm

There is a default HandleTextBox_openShopWarps.asm inside the NESmaker_4_0_11_Platformula\GameEngineData\Routines\Basic\System folder, but I have replaced the data with what you mentioned in the earlier post. I have followed all the steps in the tutorial, but all I am receiving is garbage after the text. Is this even possible for 4.0.11- I would assume so since the file was originally included in this version-but I am not getting anywhere

6fm81y.png
 

dale_coop

Moderator
Staff member
Hmm... You are using the 4.0.11? This post is about the 4.1.x (4.1.0, 4.1.1, ... 4.1.5) only, sorry.
It will NOT work on older version... because NESMaker engine is very different. If you want to make that for the 4.0.11, you need to follow the old tutorial:
http://nesmakers.com/viewtopic.php?p=9717#p9717
 

rimoJO

Member
The game won't export because of script errors. Everything that it says is wrong all point to "TextIDScreen". Hmm...
 

Saulus_Lira

Member
dale_coop said:
FOR NESMAKER 4.1.3 - 4.1.5


1/ In the "Project Settings > User Variables", add a new variable named "TextIDScreen" with initial value "0".


2/ Make a new script named "HandleTextBox_openShopWarps.asm", with that:
Code:
HandleTextBox:

;; textboxHandler
 ; 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0
  ;7 = Textbox is active.
   ;    6 = Black box is being created, will then create text.
    ;        5 = Attribute update to black.
     ;           4 = text is being created.
      ;             = loop to 5 if more text.
       ;             3 = Black box is being created, with then restore NT
        ;                 2 = Attributes to main NT
         ;                     1 = restore NT
          ;                          0 = check for "more" text.
			


	LDA textboxHandler
	AND #%10000000
	BNE textboxIsActive
	RTS ;; textbox is inactive.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
textboxIsActive:
	LDA updateNametable
	BEQ notAlreadyWritingToNT
	RTS
notAlreadyWritingToNT
	;HideSprites
;; DO TEXT BOX STUFF.
	;; Which text box stuff to do is determined by the textboxHandler byte.
	;; if it is active, but all other bits are inactive, that means we have just activated and we need to turn
	;; this system on.
	LDA textboxHandler
	AND #%01111111
	BNE textboxSettingsAlreadyOn
	;;; get textbox settings
 ;; skip resetting the offset.
	LDA #$00
	STA updateNT_offset
	STA updateHUD_offset

	STA updateNT_H_offset
	STA updateNT_V_offset
	
	;;; zero out the things offsets and start creating the blackout box.
	LDA #%11000000
	STA textboxHandler ;; flow right into the next.
textboxSettingsAlreadyOn:
	
	LdA textboxHandler
	AND #%01000000
	BEQ notCreatingBlackBox
	;;;; CREATE THE BLACK BOX.
	;;;; The frist phase is to create the black box.
	;;;; no matter what color the text box will be, or which palette it will use
	;;;; it will always first create a box of "blanks" so it can be changed to whatever
	;;;; background attribute you'd like without noticing the attribute change.
	JSR CreateBlackBox
	;;; now the black box has been created.
	
notCreatingBlackBox:
	LDA textboxHandler
	AND #%00100000
	BEQ notSettingTextboxAttributes
	JSR isWritingTextboxAttributes
	RTS
	
	;;; set textbox attributes.
notSettingTextboxAttributes:
	LDA textboxHandler
	AND #%00010000
	BEQ notUpdatingTextboxText
	;; updating textbox text.
	JSR isWritingTextToTextbox

	RTS
notUpdatingTextboxText:
	LDA textboxHandler
	AND #%00001000
	BEQ notErasingTextboxText
	JSR CreateBlackBox
	RTS
notErasingTextboxText:
	LDA textboxHandler
	AND #%00000010
	BEQ notRestoringNametables2
;	JSR CheckForEndOfTextString
;	LDA gameHandler
;	AND #%00100000
;	BEQ notRestoringNametables2 ;; because we have finished.
	JSR RestoreNametableData
notRestoringNametables2
	RTS
	

	
	
	
	
	
	
	
	
	
	
	
	
	
getUpdateTileOffsetPosition:
	LDA xScroll
	LSR
	LSR
	LSR
	LSR
	CLC
	ADC	#BOX_1_ORIGIN_X
	CLC
	ADC updateNT_H_offset
	STA tileX
	
	LDA #BOX_1_ORIGIN_Y
	CLC
	ADC updateNT_V_offset
	STA tileY
	JSR coordinatesToMetaNametableValue
	;;; spits out updateNT_pos as low and updateNT_pos+1 as hi of address to write.
	;;; right now, this is in terms of a single nametable, starting at $20 as the high top left corner high byte.
	
	

	
;;;; FOR HITE BYTE:
;;;; Take columnTracker and divide by 2 so you get a value 0-16
;;;; Add that number to BOX_1_ORIGIN_X.
;;;; If the sum is less than 16, this should stay in the same nametable.
;;;; Otherwise, it should cross nametables.
	Ldy columnTracker
	LDA columnTracker
	AND #%00001111
	CLC
	ADC #BOX_1_ORIGIN_X ;; plus offset of what tile you're drawing.
	CLC
	ADC updateNT_H_offset
	AND #%00010000
	BNE +
	;;; same nametable
	LDA columnTracker
	AND #%00010000
	BNE +++
	;; this started in even table,
	;; so it should stay in even table
	JMP updateIsEvenTable
+++	
	;;; this started in odd table
	;;; so it should stay in odd table.
	JMP updateIsOddTable
+
	;;; different nametable
	LDA columnTracker
	AND #%00010000
	BNE +++
	;; this started in even table
	;; so it should now be odd table.
	JMP updateIsOddTable
+++
	;;; this started in odd table
	;;; so it should now be even table.
	JMP updateIsEvenTable

	

updateIsEvenTable:
	LDA updateNT_pos+1
	AND #%00000011 ;; 0,1,2 or 3
	clc
	adc #$20
	STA updateNT_pos+1
	JMP gotHiUpdatePos
	
updateIsOddTable:
	LDA updateNT_pos+1
	AND #%00000011 ;; 0,1,2 or 3
	CLC
	ADC #$24
	STA updateNT_pos+1
	JMP gotHiUpdatePos
gotHiUpdatePos:

	RTS
	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
checkNTforNewTile:
	LDA temp3; updateNT_pos
	AND #%00100000
	CMP #%00100000
	BEQ newTileHasCrossedThreshold
	;; new tile has not crossed threshold.
	;; same nametable

	LDA columnTracker
	AND #%00010000
	BNE updateIsOddTable
	JMP updateIsEvenTable
newTileHasCrossedThreshold:
	
	LDA columnTracker
	AND #%00010000
	BNE updateIsEvenTable
	JMP updateIsOddTable
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;RTS ;; redundant, unnecessary
	
	
isWritingTextToTextbox:
	;;; already in bank 17.
	;; we need to get positioning.

	LDA xScroll
	LSR
	LSR
	LSR
	STA temp
	LDA #BOX_1_ORIGIN_X
	ASL
	CLC
	ADC updateNT_H_offset
	CLC
	ADC temp
	STA temp3
	AND #%00011111
	STA tileX
	
	LDA #BOX_1_ORIGIN_Y
	ASL
	CLC
	ADC updateNT_V_offset
	STA tileY
	
	JSR coordinatesToNametableValue
	JSR checkNTforNewTile
	;; temp has position value.
	;LDA temp
	;STA updateNT_pos
	
	
	
	LDY textVar ;; what string
	LDA screenText,y
	TAY
	LDA stringsTableLo,y
	STA temp16
	LDA stringsTableHi,y
	STA temp16+1
	LDY textboxOffsetHold
	LDA (temp16),y
	
	;; this is where we determine if this is a special character or a normal letter/number to update.
	CMP #_END
	BNE +
;;;; END:
EndText:
	;; this is and _END value.
	;; it turns off writing to the textbox.
	
	LDA textboxHandler
	AND #%01111111
	STA textboxHandler
	;;;;; textbox handler stays on the same state
	;;;;; but deactivates.
	;;;;; it will start again if bbutton is pressed again
	;;;;; on state 00001000, which will begin the 'turn off' process.
	
	JMP doneTextUpdate
+
	CMP #$FE ;; is it a new line?
	BNE notANewLine_text
;;;; NEW LINE:


	LDA #$00
	STA	updateNT_H_offset
	INC updateNT_V_offset
	INC textboxOffsetHold
	
	JMP doneTextUpdate
notANewLine_text:

	CMP #_ENDTRIGGER
	BNE notEndTrigger
	;; is an end trigger
	INC textboxOffsetHold ;; get the very next value.
	LDY textboxOffsetHold
	LDA (temp16),y
	STA temp
	;;;; this now has the trigger to change.
	TriggerScreen temp
	JMP EndText
notEndTrigger:

	CMP #_ENDITEM 
	BNE notEndItem
	;;; gives player an item.
	INC textboxOffsetHold ;; get the very next value.
	LDY textboxOffsetHold
	LDA (temp16),y
	TAY
	;;; this now has the bit to flip in BOSSES DEFEATED constant.
	LDA ValToBitTable_inverse,y
	ORA weaponsUnlocked
	STA weaponsUnlocked
	TriggerScreen screenType ;; will flip the current screen type
	;PlaySound #SFX_DO_TRIGGER
	JMP EndText
	
notEndItem:
;; begin check for warps -->> : 
	CMP #_ENDSHOP
	BNE notEndShop
	;; keep the Text Index of the NPC
	LDY textVar
	LDA screenText,y
	STA TextIDScreen
	JMP EndText
notEndShop:
;; <<-- end check for warps
;; The rest of the normal code from here:
	CMP #_MORE
	BNE notMoreText
	LDA #%10000000
	STA textboxHandler
	;; flip a more text flag.
	LDA #$01
	STA moreText
	INC textboxOffsetHold
	JMP EndText
notMoreText:
;;;; NORMAL VALUE
		;;;;; The look up was a normal letter, number, or other hud value.
	CLC 
	ADC #$C0
	STA updateHUD_fire_Tile	
	
	LDA updateNT_pos
	STA updateHUD_fire_Address_Lo
	LDA updateNT_pos+1
	STA updateHUD_fire_Address_Hi
	INC updateNT_H_offset
	INC textboxOffsetHold
doneTextUpdate:	

	RTS
	
	
	
	
	
	
	
	
	
	
	
CreateBlackBox	
	LDX #$00
	
;;; DRAW METATILE 1
	;; this macro SETS it to change on the next vblank update.
	;; starting at address hi-lo, with the tile in the third argument.
	;; if it sees #BLANK_TILE, it will create a meta tile of four blank tiles.
	;; if it sees any other value, it will create a metatile starting with 
	;; that index as the top left corner.
	
	;;;;;;; IF THE GAME DOES NOT SCROLL:
	;;;;;;; You can simply read the box value, do a little math, to get the offset
	;;;;;;; of the address for the top left corner, and skip the whole business of
	;;;;;;; finding the offset based on the scroll.
	
	;;;;;;; IF THE GAME DOES SCROLL:
	;;;;;;; YOu will need to get the offset value so it is at the box value position
	;;;;;;; compared to the CAMERA rather than zero.
	
	;;;;;;; Fortunately, we already have tables set up for columnTableLo and columnTableHi
	;;;;;;; which we use to handle the column for scrolling.  
	;;;;;;; we can use the columnTracker value to help determine the proper offset.
	
	;;;;;;; There can only be 32 columns.
	
	;;;;;;; And we will use updateNT_offset to continue this over frames, 
	;;;;;;; and to handle tile to offset.
	;;;;;;; this will be set to zero wherever HandleTextBox is activated.
	;;;;;;; It needs to, in some way, be boolean (like a key press, or using a boolean var).
	; LDA #$00
	; STA updateNT_H_offset
	; STA updateNT_V_offset
	;; THESE ALSO MUST BE SET IN THE BOOL VAR PLACE
	;; Whatever code is calling this must also set these to zero.

	
	
	
	LDA #$00
	STA tilesToWrite
	LDA #$04
	STA dummyVar2
DoLoopThing:
	JSR getUpdateTileOffsetPosition
	SetMetaTileToChange updateNT_pos+1, updateNT_pos, #BLANK_TILE

 	INC updateNT_H_offset
	LDA updateNT_H_offset
	CMP #BOX_1_WIDTH
	BEQ ++
	DEC dummyVar2
	LDA dummyVar2
	BEQ +
	JMP DoLoopThing
++ ;; width has been reached.
	;; now to test the height, and to move h pos back to the left.

	
	BEQ dontEndCreatingBlackBox
	JMP EndCreatingBlackBox
dontEndCreatingBlackBox:
	
	LDA #$00
	STA updateNT_offset
	STA updateHUD_offset
	STA updateNT_H_offset
	INC updateNT_V_offset


+	

	LDA #$01
	STA updateNametable  ;; turn on write.
	
	LDA updateNT_V_offset
	CMP #BOX_1_HEIGHT
	BCS turnOffCreatingTextBox
	
	LDA updateNT_H_offset
	CMP #BOX_1_WIDTH
	BEQ turnOffCreatingTextBox
	JMP EndCreatingBlackBox
turnOffCreatingTextBox:
	
	;;;;;;;;;;;;;;;;;;;;;;;;;;
	;;; Setup text specifics
	LDA #$00
	STA stringGroupOffset
	STA updateNT_H_offset
	STA updateNT_V_offset
	
	LDA xScroll
	LSR
	LSR
	LSR
	STA temp
	LDA #BOX_1_ORIGIN_X
	ASL
	CLC
	ADC temp
	CLC
	ADC #H_PAD_TEXTBOX
	STA tileX
	LDA #BOX_1_ORIGIN_Y
	ASL
	CLC
	ADC #V_PAD_TEXTBOX
	STA tileY
	
;	LDA #$01
;	STA writingText ;; turn on writing text.
	LDA moreText
	BEQ +
	LDA #$00
	STA moreText
	JMP ++
+
	LDA #$00
	STA textboxOffsetHold
++
	STA updateNT_H_offset
	STA updateNT_V_offset

	LDA textboxHandler
	AND #%00001000
	BEQ continueToUpdatingAttributes
	;;; is turning textbox OFF, so no writing to text.
	;;; will have to allot for changing attributes back with the
	;;; bit 00000100
	LDA #%10101000 ;; turn on attribute update
	STA textboxHandler
	LDA #$00
	STA updateNT_H_offset
	STA updateNT_V_offset
	STA updateNT_offset
	STA updateNT_compensation

;	LDA xScroll_hi

;	AND #%00000001
;	BEQ oddToEven2
;	LDA #$27
;	JMP gotNtDeets2
;oddToEven2:
;	LDA #$23
;gotNtDeets2:
;	STA updateNT_tableLeft
;	STA updateNT_details

	;LDA columnTracker
	LDA #BOX_1_ORIGIN_X
	LSR
	TAY
	LDA attrColumnTableHi,y
	STA updateNT_tableLeft
	STA updateNT_details

	RTS
continueToUpdatingAttributes:
	LDA #%10001000
	STA textboxHandler
	LDA #$00
	STA updateNT_H_offset
	STA updateNT_V_offset
	STA updateNT_offset
	STA updateNT_compensation
	
	
;	LDA xScroll_hi

;	AND #%00000001
;	BEQ oddToEven
;	LDA #$27
;	JMP gotNtDeets:
;oddToEven:
;	LDA #$23
;gotNtDeets:
;	STA updateNT_tableLeft
;	STA updateNT_details
	
	;LDA columnTracker
	LDA updateNT_H_offset
	CLC
	ADC updateNT_offset
	ASL
	CLC
	ADC	columnTracker
	AND #%00011111
	LSR 
	TAY
	LDA attrColumnTableHi,y
	STA updateNT_details
	
	LDA #%10100000
	STA textboxHandler
	;;;;;;;;;;;;;;;;;;;;;;;;;;;
	RTS
EndCreatingBlackBox:	
	LDA #$01
	RTS
	
	
	
	
RestoreNametableData:

	

	;;; FIRST we need to find the metaNametale value from the ROM.
	;;;;;;;;;;LESSER PRIORITY;;;;;;;;;;;;;;
	;;; THEN we need to check it againt collision type to / screen state to see if it should be 
	;;; change (for instance, a tile that changes at night / saved / changes if no monsters, if there are no monsters, etc)
	;;; THEN, we should probably always just restore the hud at the end.
	;;; the problem is, the data we need to fetch is in bank 16, then screen bank, 
	;;; while we are currently in bank 17 with this routine.
	;;; so restoration of nametable, or at least analysis of whate tiles to write, will have to happen OUTSIDE of this routine
	;;; We handle it in HandleBoxes, which will populate updateTile00-03, and respect paths.
	;;; And we handle POSITION to update here.

	LDX #$00
	LDA #$00
	STA tilesToWrite
	
	JSR getUpdateTileOffsetPosition
	
	

	LDA updateNT_pos
	STA temp
	LDA updateNT_pos+1
	STA temp1
	

	SetTileToChange temp1, temp, updateTile_00
	LDA temp
	CLC
	ADC #$01
	STA temp2
	LDA temp1
	ADC #$00
	STA temp3
	
	
	SetTileToChange temp3, temp2, updateTile_01
	
	LDA temp
	CLC
	ADC #$20
	STA temp2
	LDA temp1
	ADC #$00
	STA temp3
	
	
	SetTileToChange temp3, temp2, updateTile_02
	
	LDA temp
	CLC
	ADC #$21
	STA temp2
	LDA temp1
	ADC #$00
	STA temp3
	
	SetTileToChange temp3, temp2, updateTile_03
	INC tilesToWrite
	LDA #$01
	STA updateNametable
	
	INC updateNT_H_offset
	LDA updateNT_H_offset
	CMP #BOX_1_WIDTH
	BNE dontReturnToGame
	LDA #$00
	STA updateNT_H_offset
	INC updateNT_V_offset
	LDA updateNT_V_offset
	CMP #BOX_1_HEIGHT
	BNE dontReturnToGame
	LDA #$00
	STA textboxHandler
	STA updateHUD_offset
	LDA gameHandler
	AND #%11011111
	STA gameHandler
	;ShowSprites

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; check to see if there is behavior after a text box.

;;;; THIS WOULD WARP YOU TO A SCREEN AFTER TEXTBOX.
	LDA TextIDScreen 
	CLC
	BEQ +
		STA warpToScreen
		LDA #$00
		STA TextIDScreen
		STA newGameState
		LDA warpMap
		STA currentMap
		CLC
		ADC #$01
		STA temp
		GoToScreen warpToScreen, temp, #$02
		LDA #$00
		STA playerToSpawn
		;LDX player1_object
		;DeactivateCurrentObject
		;LDA #$01
		;STA loadObjectFlag
		LDA mapPosX
		STA newX
		LDA mapPosY
		STA newY
	+
	
	; LDA #$01
	; STA activateWarpFlag
	; PlaySound #SND_ENTER
	; LDX player1_object
	; LDA Object_x_hi,x
	; STA mapPosX
	; LDA Object_y_hi,x
	; STA mapPosY
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
	
dontReturnToGame:

	RTS
	
	
	
isWritingTextboxAttributes:
	;; handle all four quadrants of the attribute.
	
	
	RTS


3/ Assign the "HandleTextBox_openShopWarps.asm" script to the "Handle Text Box" element in the "Projet Settings > Script Settings".


4) Make some NPC monster/objects and put them on the screen


5) Set your Texts, for the screen warps. If you want a warp to Screen 16 (X=0, Y=1) then set your "Text 16"... and a warp to Screen 25, set your "Text 25" (X=9,Y=1)... using the text index corresponding the screen index you want.
2018-12-26-10-53-22.png

And for each Text you set, chose the "Open Shop" action (currently not used so we will use it for the warp to the textindex screen).

6) Add all those warp Text to a Text Group:
2018-12-26-10-56-14.png

And assign the Text Group to your main screen:
2018-12-26-10-56-29-Screen-Details.png

(don't care about the checkbox on that screen, it's an old screen)

Now, the multi warps should work.

I followed all steps, pass by pass and revised, and dont works for me. Using ver 4.1.5.
 
Top Bottom