You are not logged in.
I'd probably be better off waiting until the way to give NPC trainers names (e.g. Youngster Joey or Picnicker Diana) is discovered and outlined, but how do you insert rematch and/or cell phone codes into the Gen I games? (Personally, I think rematch code is more feasible at the moment.)
Well, since Gen 1 doesn't have an internal scripting language like Crystal does, the answer is "by inventing a cell phone system".
To my knowledge, nobody has done this yet in Gen 1. It certainly would be possible, but you would just have to invent it. Crystal of course has the Pokegear, but I don't know if you want to try and add that just for the phone, you could probably just add a phone key item to call your phone menu in order to let you make calls. Receiving a call would just be a matter of playing a sound effect, showing some text, and activating some flags for whatever you want to happen. For example, if you want the player to receive a call after beating Brock, you could go into the map script for Pewter City (AFTER the "call EnableAutoTextBoxDrawing" line which should already be in there.) and do something like....
and then somewhere in with the rest of the map's scripts, do something like:
PewterPhoneCall: ld hl, wPhoneCallFlags ; something you would add to mark special event phone calls having already happened bit 1, [hl] ; check to see if this call has already happened ret nz ; if it has already happened, don't run it again ld a, [wObtainedBadges] ; variables that stores which badges you have bit 0,a ; check to see if you have beaten Brock ret z ; if you haven't, don't do the phone call yet ; if you haven't done the event yet, and you have beaten brock, do the phone call ld a,SFX_SHOOTING_STAR ; sound effect from the intro, I grabbed it as a placeholder ringtone for this example call PlaySound ld hl, PewterCallText ; the text for what you want the call to say call PrintText ld a,SFX_TURN_OFF_PC ; sound effect placeholder for hanging up call PlaySound ; you could also do other things in here too, such as showing an event that was hidden, like to make Oak's Aid show up in the Pokecenter with a gift for you or something ld hl,wPhoneCallFlags ; address with your special call flags that we checked earlier set 1,[hl] ; mark you as having received that call ret ; we're done, so go back to the rest of the scripts in the header
I just made that routine up on the fly as an example, but I double checked constant names and stuff when typing it, so that theoretically should work to make you receive a storyline phone call like the ones in Gen 2. I haven't compiled it and tested it, but yeah. Of course, you would need to include wPhoneCallFlags in wram.asm and define enough space for how many flags you'd need to store. If you needed more than 8 special calls, you'd wanna look at some other scripts and expand that into a larger bit array, but for just 8 or fewer you could use the standard bit and set commands for that.
As for random phone calls, you'd need to make some random phone call routine, probably have it run on a step counter or something, and have it run in the background. That would be more complicated so I'm not going to make up and example of that on the fly right now. But that routine I made up there aught to help give you a nudge in the right direction.
As for rematches, that would come down to:
- go to the trainer you want the rematch with
- find the text heading for what they say after the battle in that map's script .asm file
- make that one use TX_ASM so you can do some checks
- check a flag (you would need to make and set this yourself) to see if they want a rematch
- if they don't want a rematch, show the normal after-battle text
- if they do want a rematch, have them ask if you want to rematch them
- if you say no, end the script and let them hang out and wait for you
- if you say yes, clear the flag for them wanting a rematch, and load a battle with their stronger rematch team, then start the battle
For starting the battle and loading the trainer, you could look at how Rival Battles do it. admittedly those are more complex since he has to walk up to you and it has to figure out what your starter was and which team he should use based on that, and whatnot, but it's a starting point to help you track down where to load the Class and Team entries and what to call to start the battle and how to handle what happens when it's over.
Oh and you'd probably also want that step-counter related routine to have a function that clears all the "trainer wants a rematch" flags, so if you ignore them for long enough they will just go back to chilling until they randomly decide to call you again.
Last edited by Mateo (2015-10-29 05:30:12)
I'll test it out and let you know how well it worked.
Alright. Also, I'm just trying to help you get started so you can make this work. I'm not going to script everything for you. Just trying to work out some examples for the basics, then you can expand on it and make it actually useful.
Also, like I said, the example above assumes you would have no more than 8 special event calls (bits 0 through 7 of that wram byte) if you planned on having more than that, you would want to use a bit array instead. There are existing functions for reading and setting bits in an array for things like this, you would just need to call them properly. For an example of reading and writing to a bit array, you can check out my berry tree routine in Red++ (also, that function assumes the tree number is stored in wWhichTrade before you call the script, starting with tree 1.)
The parts that would relate to the flag array setting/checking are the section near the top about checking if the berry has been taken already, and the part a little lower that marks the berry as taken.
Last edited by Mateo (2015-10-29 05:52:41)
It seems to have compiled fine. I'll play it some up to that point and let you know how it plays out.
It froze as soon as I left Pewter Gym upon having defeated Brock. Long story short, I got stuck in the door and couldn't move a single step down, nor could I press any buttons and expect them to do anything.
Try adding this right before the part where we load and play the sound effect of the phone ringing:
ld a, 1 ; not 0 ld [hSpriteIndexOrTextID], a callba DisplayTextIDInit
That's something that had to be done to get stuff to work properly in another unrelated script, it just initializes text display stuff so that it will load properly.
Also,we're going to have to add something to make the player walk down a step first, so it doesn't show the call with him standing on the door. To make the player walk down, so it doesn't run with you standing on the door, you could add this:
before the part that we added up there ^
Then somewhere else in the scripts .asm file, you could just add this:
MovePlayerDown: ld a,D_DOWN ld [wSimulatedJoypadStatesEnd],a xor a ld [wWastedByteCD39],a inc a ld [wSimulatedJoypadStatesIndex],a ret
That's based on the way other scripts move the player forward, it just simulates you pressing Down to make you walk down off the door. I'm not really to where I can test this out, I'm not on my hacking computer, but since it is based on how the game already does it, it aught to work.
Last edited by Mateo (2015-10-29 18:12:40)
I believe it was immediately under "call EnableAutoTextBoxDrawing". Figuring that was the cause, I moved it to PewterCityScriptPointers and will recompile and attempt another test later today before I do any further diagnostics.
Actually no, try it again immediately under call EnableAutoTextBoxDrawing, but just add the changes I came up with. I seem to remember if you call it without having those in place, it will look like it is frozen, but it is really just not displaying anything while still sort of loading the text, and if you hit A enough times, it will run through the invisible text and whatnot. So try it again where it was, but with the changes I suggested. It will get tricky adding it in with the PewterCityScriptPointers if you aren't careful, since those are only called at certain times based on what the script number is set to (for things like what Gen 2 and 3 use trigger events for) so you might put it in the wrong one, and then it won't actually get run, since it would be in a script that isn't even called at the point in time when you will have beaten brock. If that makes sense.
So yeah, try keeping the call where you had it, but making the changes I suggested to the script, and see what that does.
I've been playing around with this a bit to test it out. So far, I've gotten it to properly play sound effects, show the text, and all that stuff. I just need to work out making you walk out of the doorway first, since the way I listed currently isn't working. I'll post the working version once I finish it up.
Okay! After a lot of fiddling around and testing it, this code should work:
PewterCityPhoneCall: ; check if you have already received the call ld hl,wPhoneCallFlags bit 1,[hl] ret nz ; check if you have received the badge from brock ld a, [wObtainedBadges] ; variables that stores which badges you have bit 0,a ; check to see if you have beaten Brock ret z ; if you haven't, don't do the phone call yet ; let you walk out the door first call IsPlayerCharacterBeingControlledByGame ret nz ; let the game display the text properly ld a, 1 ; not 0 ld [hSpriteIndexOrTextID], a callba DisplayTextIDInit ; play sound effects and do the phone call's text ld a, SFX_TURN_OFF_PC ; sound for the phone ringing call PlaySound call WaitForSoundToFinish ld hl, PewterCityPhoneCallText call PrintText ld a, SFX_TURN_OFF_PC ; sound for you hanging up call PlaySound ; mark the phone call as having been received ld hl,wPhoneCallFlags set 1,[hl] ; we're done here jp CloseTextDisplay
Then you would just need to remember to include the text for the call to display. I've been testing it in Red's House downstairs, and it works fine. Just add the call immediately after the "call EnableAutoTextBoxDrawing"
For the Pewter phone call, I'm planning to have Professor Oak call about the Rocket assault on Cerulean City and tell the player that his assistant rescued a Pokémon that had been kidnapped from a nearby Starter breeding center.
Here's the script for if the player chose Bulbasaur:
text "Oh!" line "I've got a call!" para "OAK: ", $52, "!" line "How's it going?" cont "Huh? You got the" cont "BOULDERBADGE?" cont "Wonderful!" para "It must've been" line "pretty easy with" cont "my old #MON." para "Oh! Meet my" line "assistant just" cont "outside of" cont "CERULEAN CITY." para "There's been an" line "attack there," cont "and a #MON" cont "was stolen from" cont "a nearby breeding" cont "center." para "Thankfully, my" line "assistant was" cont "able to rescue" cont "it, and he's now" cont "looking for a" cont "home for it." para "I'm hoping you" line "would be" cont "interested." para "Good luck!" done
If the player chose Charmander:
text "Oh!" line "I've got a call!" para "OAK: ", $52, "!" line "How's it going?" cont "Huh? You got the" cont "BOULDERBADGE?" cont "Amazing! I don't" cont "know how you" cont "managed it!" para "That one must've" line "been a rocky" cont "start, but hang" cont "in there!" para "Oh! Meet my" line "assistant just" cont "outside of" cont "CERULEAN CITY." para "There's been an" line "attack there," cont "and a #MON" cont "was stolen from" cont "a nearby breeding" cont "center." para "Thankfully, my" line "assistant was" cont "able to rescue" cont "it, and he's now" cont "looking for a" cont "home for it." para "I'm hoping you" line "would be" cont "interested." para "Good luck!" done
If the player chose Squirtle:
text "Oh!" line "I've got a call!" para "OAK: ", $52, "!" line "How's it going?" cont "Huh? You got the" cont "BOULDERBADGE?" cont "Great job!" para "My old #MON" line "must've done the" cont "trick without" cont "much trouble!" para "Oh! Meet my" line "assistant just" cont "outside of" cont "CERULEAN CITY." para "There's been an" line "attack there," cont "and a #MON" cont "was stolen from" cont "a nearby breeding" cont "center." para "Thankfully, my" line "assistant was" cont "able to rescue" cont "it, and he's now" cont "looking for a" cont "home for it." para "I'm hoping you" line "would be" cont "interested." para "Good luck!" done
Of course, then I would need to add a script for when the player character enters Cerulean City for the first time in order to back that up.
You can check wPlayerStarter to see which one the player chose and branch accordingly.
So you could replace
ld hl,PewterCityPhoneCallText call PrintText
ld a, [wPlayerStarter] cp CHARMANDER jr z, .charmander cp SQUIRTLE jr z, .squirtle ; else Bulbasaur ld hl,PhoneCallTextBulbasaur jr .showText .charmander ld hl,PhoneCallTextCharmander jr .showText .squirtle ld hl,PhoneCallTextSquirtle .showText call PrintText
And that way it calls a different text entry based on your starter.
OK, I did a test of the phone call function in Pallet Town as soon as I left the player character's house for the first time, and it worked fine, except the music stopped, and after I hung up, different music played until I stepped into the tall grass, which is, naturally, Professor Oak's cue to intercept me before I go too far up north.
Where do I add PlayMapMusic, specifically, in my script?
Last edited by Fotomac (2015-10-30 05:21:41)
Thanks! It works perfectly now.
Anyway, could you show me how to add NPCs to maps in general?
ETA: (This is, of course, related to the Pewter phone call.)
Last edited by Fotomac (2015-10-30 05:34:29)
You'd just need to:
- load the map objects file for that map
- increase the number for the amount of people on the map
- add a new entry for it at the end of the list of people events, formatted like the other NPCs
then go into the scripts file and add his text pointer.
Now, a thing to keep in mind, if text pointers go out of order, the game has issues. So all of the people events' text numbers need to go in order, and sign posts go afterwards. So if the last person was text 4, you'd need to add his pointer to the list After text 4, then shift all the signposts' numbers.
That's probably confusing so I'm going to look for a commit where I did that.
By default, people just load text and are simple to add. Most of them just point to a normal text entry. You can make them do fancy stuff if you need to by starting the entry off with TX_ASM but you won't need to most of the time.
EDIT: Keep in mind, I started Red++ on an older version of Pokered and haven't pulled in all of the changes, so your people event entries will be more readable than mine, but that commit still shows what you need to do in general.
Last edited by Mateo (2015-10-30 05:45:27)
I'm thinking of starting with the Oak Aide talking, then the exclamation mark appearing above the player character, followed by the Oak Aide appearing from the right, and then the Oak Aide continuing to talk, followed by a divergence depending on whether or not the current box is full. If it is full, the Oak Aide will tell you to make some room and then stay there until you change to a box that isn't full, and then, if you talk to him again when the current box isn't full, give the player character a Starter of the species nobody chose. If the box isn't already full when the event happens, the Oak Aide will give the player character the Unchosen Starter at that point in the event. After being prompted whether or not to give the Unchosen Starter a nickname, the Unchosen Starter will be transferred to Someone's PC if the party is full. After that, the Oak Aide will bid the player character farewell before returning the way he came. The Oak Aide sprite will then be hidden similar to how the Blue sprite is always hidden after he goes offscreen following a battle.
How do I do all that?
ETA: There'd be similarities to PalletTownScript0 (IIRC the one where Professor Oak intercepts you before you can go too far north) and any script where the rival departs after you defeat him.
Last edited by Fotomac (2015-10-30 06:13:43)
The best way to handle giving a Pokemon is to make sure there is room in the party. That's how the game does it, because it's simple and makes more sense from the story point of view. If you'll look at existing givePokemon scripts, you'll see how to check if there is room or not.
I've already shown you how to check the starter the player has, and from that you can figure out what the unchosen one was.
As for showing/hiding events, I'll try to explain that tomorrow.
Also, just a reminder, I am not going to sit here and just make up every single script for you. I'm trying to help you get started, but I want to help you figure out how to find and figure things out on your own, too.
Some of this I remember off top of my head, but a lot of this you could really do yourself, since that phone call script I made up by a combination of:
- trial and error
- looking at parts of existing routines that did part of what I wanted it to do.
Need to play a sound effect? Let's look at another script and see how they do it.
Need to check something? See if there is already a function to check it.
Need to fix the music? Look for a script that changes music and gets it back.
Need to start a battle? Look for a script that starts a battle.
That's the way I taught myself. Look around and see how the existing scripts do things and use them as a reference to get started. And don't give up if you mess up at first.
(This isn't saying I'm going to stop helping you, it's just saying that I'm not going to do everything for you, and pointing out the way I go about figuring these things out when you ask for something new).
In any case, how do I jump in the game to the part where I want to test, so I don't have to do the test in Pallet Town or another early portion of the game?