Decomp & Disassembly Guides and resources to help you develop your decompilation or disassembly-based hack can be found here.

Ad Content
Reply
 
Thread Tools
  #1   Link to this post, but load the entire thread.  
Old December 30th, 2018 (2:48 PM). Edited 6 Days Ago by Avara.
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Decomp Simple Modifications Directory
-----------------------------------------------------------------------------------------------------------------------------------------------------
This thread can hopefully be used to host instructions for a variety of small changes to pokéemerald (or pokéruby) that are much too short/simple to justify having their own thread/their own page on their respective wiki. Contributions can then be listed in this post for the sake of simplicity. Please test to ensure your implementation works before submitting!
If you can think of a small edit you'd like to be added to this list, go ahead and leave a comment, with a bit of luck it will help to encourage more rom hackers to switch to the decomps <3
-----------------------------------------------------------------------------------------------------------------------------------------------------
__________________
Reply With Quote
  #2   Link to this post, but load the entire thread.  
Old December 31st, 2018 (1:16 AM).
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Editing Player PC Items

To change the items the player has in their PC at the start of the game, open “src\player_pc.c” in Notepad++ and find the following:



Ctrl+F "POTION" to locate it quickly. It's self-explanatory - on the left you have the item and on the right you have the amount. Just make sure you don't accidentally overwrite the “{ ITEM_NONE, 0 }” line. For example, if I wanted my player to have five Sitrus Berries and three Lum Berries in their PC at the beginning of the game, I'd have:



A list of items can be found in “include\constants\items.h

Reply With Quote
  #3   Link to this post, but load the entire thread.  
Old December 31st, 2018 (1:27 AM).
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Modifying Starter Pokémon

To change the three starters in less than 30 seconds, open “src\starter_choose.c” in Notepad++ and Ctrl+F "TREECKO" to find the following section quickly:



You've probably guessed what to do already - just change the species names. If you wanted the Johto starters, you could have:



Compile and you're all set.

Reply With Quote
  #4   Link to this post, but load the entire thread.  
Old January 14th, 2019 (9:34 AM). Edited January 14th, 2019 by Avara.
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Changing the Beginning Amount of Money

For Pokéemerald, open “src\new_game.c” and look for this line:
Code:
SetMoney(&gSaveBlock1Ptr->money, 3000);
All there is to do is change that amount (3000) to whatever you like. For Pokéruby, it's the same file but this line:
Code:
gSaveBlock1.money = 3000;
Reply With Quote
  #5   Link to this post, but load the entire thread.  
Old January 14th, 2019 (9:34 AM).
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Editing Default Options Settings

If you open “src\new_game.c” you'll come across this:



These are the attributes you can change from the "Options" window in the start menu - text speed, the menu frame, battle style (set/shift) etc. Having the text speed automatically set to fast is something I'd recommend to everyone, since going straight to the options menu and changing it is one of the first things a lot of people do in-game!
Reply With Quote
  #6   Link to this post, but load the entire thread.  
Old January 14th, 2019 (9:44 AM).
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Changing Birch's Intro Pokémon

Open “src\main_menu.c” and Ctrl+F for “SPECIES_LOTAD”. Modify the following lines to change the sprite and cry:





The Pokémon species list is in “include\constants\species.h”. For Pokéruby, substitute the instances of “SPECIES_LOTAD” for “SPECIES_AZURILL”. I've changed it to Trapinch, for example:

Reply With Quote
  #7   Link to this post, but load the entire thread.  
Old 4 Weeks Ago (5:40 AM).
paccy's Avatar
paccy paccy is offline
Pokeholic
     
    Join Date: May 2009
    Location: 'Straya
    Gender: Male
    Nature: Quiet
    Posts: 4
    Reusable TMs

    To make TMs reusable open "src/party_menu.c" and search for the sub_81B6EB4 function.
    In it delete the lines
    Code:
    if (item < ITEM_HM01_CUT)
        RemoveBagItem(item, 1);
    If you also want to make TMs unholdable and remove the number from the bag saying how many of each TM you have open "src/data/items.h" and change the .importance number of each TM item from 0 to 1.

    Reply With Quote
      #8   Link to this post, but load the entire thread.  
    Old 3 Weeks Ago (8:31 AM). Edited 2 Weeks Ago by Avara.
    Avara's Avatar
    Avara Avara is offline
    Author Of Tales
     
    Join Date: Dec 2011
    Location: Izantine
    Gender: Female
    Nature: Calm
    Posts: 944
    Modifying the Start Location

    Open “src\new_game.c”and look for the following section:
    Code:
    static void WarpToTruck(void)
    {
        SetWarpDestination(MAP_GROUP(INSIDE_OF_TRUCK), MAP_NUM(INSIDE_OF_TRUCK), -1, -1, -1);
        WarpIntoMap();
    }
    The line in red is the one we want to make changes to as you could probably already tell. It's self explanatory so it shouldn't need very much breaking down. For instance, let's say we wanted the start map to be Oldale Town. We would have:
    Code:
    SetWarpDestination(MAP_GROUP(OLDALE_TOWN), MAP_NUM(OLDALE_TOWN), -1, 6, 18);
    The above will have the player start in Oldale Town, specifically outside the Pokémon Center. Something different, say you wanted the player to start off in the middle of May's room:
    Code:
    SetWarpDestination(MAP_GROUP(LITTLEROOT_TOWN_MAYS_HOUSE_2F), MAP_NUM(LITTLEROOT_TOWN_MAYS_HOUSE_2F), -1, -1, -1);
    Using “-1, -1, -1” as the default does will place the player in the center of the map. That's it!
    Oh and to remove the truck animation, again you only have to tweak a single line, this time in “src\overworld.c”:
    Code:
    // gFieldCallback = ExecuteTruckSequence;
    __________________
    Reply With Quote
      #9   Link to this post, but load the entire thread.  
    Old 3 Weeks Ago (8:23 AM). Edited 3 Weeks Ago by DizzyEgg.
    DizzyEgg's Avatar
    DizzyEgg DizzyEgg is offline
       
      Join Date: Feb 2014
      Location: Poland
      Age: 21
      Gender: Male
      Nature: Quiet
      Posts: 759
      BW Repel

      Whenever the Repel's effect wears off, a prompt will appear asking player if they wish to use another one. Similarly to my old pre-decomp implementation, this one also lets you choose which Repel(Regular, Super, Max) to use. Obviously, if you have only one kind, this part is skipped.

      Code:
      src/script_menu.c DrawMultichoiceMenu
      I modified the function, so it works with custom menu options, in ours case Repels ones. Change that part to:
      Spoiler:

      Code:
      static void DrawMultichoiceMenuCustom(u8 left, u8 top, u8 multichoiceId, u8 ignoreBPress, u8 cursorPos, const struct MenuAction *actions, int count)
      {
          int i;
          u8 windowId;
          int width = 0;
          u8 newWidth;
      
          for (i = 0; i < count; i++)
          {
              width = display_text_and_get_width(actions[i].text, width);
          }
      
          newWidth = convert_pixel_width_to_tile_width(width);
          left = sub_80E2D5C(left, newWidth);
          windowId = CreateWindowFromRect(left, top, newWidth, count * 2);
          SetStandardWindowBorderStyle(windowId, 0);
          PrintMenuTable(windowId, count, actions);
          InitMenuInUpperLeftCornerPlaySoundWhenAPressed(windowId, count, cursorPos);
          schedule_bg_copy_tilemap_to_vram(0);
          sub_80E1FBC(ignoreBPress, count, windowId, multichoiceId);
      }
      
      static void DrawMultichoiceMenu(u8 left, u8 top, u8 multichoiceId, u8 ignoreBPress, u8 cursorPos)
      {
          DrawMultichoiceMenuCustom(left, top, multichoiceId, ignoreBPress, cursorPos, gMultichoiceLists[multichoiceId].list, gMultichoiceLists[multichoiceId].count);
      }
      
      void TryDrawRepelMenu(void)
      {
          static const u16 repelItems[] = {ITEM_REPEL, ITEM_SUPER_REPEL, ITEM_MAX_REPEL};
          struct MenuAction menuItems[4] = {NULL};
          int i, count = 0;
      
          for (i = 0; i < ARRAY_COUNT(repelItems); i++)
          {
              if (CheckBagHasItem(repelItems[i], 1))
              {
                  VarSet(VAR_0x8004 + count, repelItems[i]);
                  menuItems[count].text = ItemId_GetName(repelItems[i]);
                  count++;
              }
          }
      
          if (count > 1)
              DrawMultichoiceMenuCustom(0, 0, 0, FALSE, 0, menuItems, count);
      
          gSpecialVar_Result = (count > 1);
      }
      
      void HandleRepelMenuChoice(void)
      {
          gSpecialVar_0x8004 = VarGet(VAR_0x8004 + gSpecialVar_Result); // Get item Id;
          VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(gSpecialVar_0x8004));
      }

      Now
      Code:
      data/event_script.s EventScript_RepelWoreOff
      Spoiler:

      Code:
      EventScript_RepelWoreOff:: @ 82A4B2A
      	msgbox Text_RepelWoreOff, MSGBOX_SIGN
      	checkitem ITEM_REPEL, 1
      	compare VAR_RESULT, TRUE
      	goto_if_eq EventScript_RepelWoreOff_AskAnother
      	checkitem ITEM_SUPER_REPEL, 1
      	compare VAR_RESULT, TRUE
      	goto_if_eq EventScript_RepelWoreOff_AskAnother
      	checkitem ITEM_MAX_REPEL, 1
      	compare VAR_RESULT, FALSE
      	goto_if_eq EventScript_RepelWoreOff_End
      EventScript_RepelWoreOff_AskAnother:
      	msgbox Text_RepelAskAnother, MSGBOX_YESNO
      	closemessage
      	compare VAR_RESULT, 0
      	goto_if_eq EventScript_RepelWoreOff_End
      	callnative TryDrawRepelMenu
      	compare VAR_RESULT, FALSE
      	goto_if_eq EventScript_RepelWoreOff_Chose
      	waitstate
      	compare VAR_RESULT, 127
      	goto_if_eq EventScript_RepelWoreOff_End
      EventScript_RepelWoreOff_Chose:
      	callnative HandleRepelMenuChoice
      	bufferitemname 1, VAR_0x8004
      	takeitem VAR_0x8004, 1
      	playse SE_TU_SAA
      	msgbox gText_PlayerUsedVar2, MSGBOX_SIGN
      EventScript_RepelWoreOff_End:
      	end
      
      Text_RepelWoreOff: @ 82A4B33
      	.string "REPEL's effect wore off…$"
      Text_RepelAskAnother:
      	.string "Would you like to use another one?$"

      Screenshots:
      Spoiler:



      I also have the code in my github branch called repel, so you can pull directly from it.
      __________________
      Support Pokeemerald!
      Reply With Quote
        #10   Link to this post, but load the entire thread.  
      Old 3 Weeks Ago (8:57 AM). Edited 1 Week Ago by DizzyEgg.
      DizzyEgg's Avatar
      DizzyEgg DizzyEgg is offline
         
        Join Date: Feb 2014
        Location: Poland
        Age: 21
        Gender: Male
        Nature: Quiet
        Posts: 759
        Money Limit
        Spoiler:

        In this example, I'll be moving the cap to 9 999 999.

        To change max possible money amount, go to
        Code:
        src/money.c
        At line 13,
        Code:
        #define MAX_MONEY 9999999
        At line 135
        Code:
        PrintMoneyAmount(windowId, 0x20, 1, amount, speed);
        At line 143
        Code:
        ConvertIntToDecimalStringN(gStringVar1, amount, STR_CONV_MODE_LEFT_ALIGN, 7);
        At line 145
        Code:
        strLength = 7 - StringLength(gStringVar1);
        In
        Code:
        src/shop.c
        At line 1148
        Code:
        PrintMoneyAmount(4, 32, 1, gShopDataPtr->totalCost, TEXT_SPEED_FF);
        And in
        Code:
        src/trainer_card.c
        At line 1014
        Code:
        ConvertIntToDecimalStringN(gStringVar1, sData->trainerCard.money, 0, 7);
        Things that were changed were respectively, max money amount, x position on the money box and max digits(previously 6, now 7).

        If you'd like to go above 7 digits, simply change the 7 to 8 and the x position argument from 0x20 to
        0x1A.

        Screenshots:
        Spoiler:




        I also have the code in my github branch called money, so you can pull directly from it.
        __________________
        Support Pokeemerald!
        Reply With Quote
          #11   Link to this post, but load the entire thread.  
        Old 2 Weeks Ago (3:20 AM). Edited 2 Weeks Ago by Lunos.
        Lunos's Avatar
        Lunos Lunos is online now
        Random Uruguayan User
           
          Join Date: Oct 2008
          Location: Montevideo (Uruguay)
          Gender: Male
          Nature: Lonely
          Posts: 1,808
          Quote:
          Originally Posted by paccy View Post
          -Snip-
          I'm not entirely sure if I'm going OffTopic here, but while this implementation works perfectly on itself, it introduces one issue.
          You can teach a TM to a pokémon, and the PPs for that move slot will refill as the pokémon learns a new move.
          This kinda removes the necessity of healing when/if you run out of PPs in some of all of your moves.

          ON: So, if we're talking about quick modifications, I have to give some love to my favourite ability.

          Modifying the table of items of the Pickup ability

          (outside of the Battle Pyramid)

          To do this, we're going to open the src\battle_script_commands.c file.
          Next, we'll take a look at the sPickupItems variable in the Line 824.
          What it contains is a list of the items the Player can obtain with a 4%, 10% or 30% chances every time they faint a pokémon, if a Pickup user is in their party.


          Right after it, we have the variable sRarePickupItems, which similarly, also contains a list of items.
          These are the items that the Player has a 1% chance of obtaining, every time they faint a pokémon, if a Pickup user is in their party.


          To modify any of these lists, you simply have to swap the defined item/s that you want to replace with a different one of your liking, save and compile.

          Here's a quick video, where I replaced all the common items (those in the 1st list) with Master Balls.


          I haven't looked into the separate table used for the Battle Pyramid, so I won't go into details with that one, but it looks fairly simple.
          Any curious people can find them (Lv50 and Open) starting from the Line 317 of the src\battle_pyramid.c file.
          __________________
          Reply With Quote
            #12   Link to this post, but load the entire thread.  
          Old 2 Weeks Ago (10:35 AM).
          DizzyEgg's Avatar
          DizzyEgg DizzyEgg is offline
             
            Join Date: Feb 2014
            Location: Poland
            Age: 21
            Gender: Male
            Nature: Quiet
            Posts: 759
            Scrolling Multichoices In Scripts

            I was asked to implement this, so here it goes. Just so you know, scrolling lists are already coded in, they're called list menus in pokeemerald. Check out list_menu.h and list_menu.c.

            Spoiler:

            I put the code in script_menu.c, but you can put it whenever you want.
            At the top of file make sure to include the header for the list menu. Add this.
            Code:
            #include "list_menu.h"
            At the end of the file paste all this code.
            Spoiler:

            Code:
            // Text displayed as options.
            static const u8 sText_Example1[] = _("Example 1");
            static const u8 sText_Example2[] = _("Example 2");
            static const u8 sText_Example3[] = _("Example 3");
            static const u8 sText_Example4[] = _("Example 4");
            static const u8 sText_Example5[] = _("Example 5");
            static const u8 sText_Example6[] = _("Example 6");
            static const u8 sText_Example7[] = _("Example 7");
            static const u8 sText_Example8[] = _("Example 8");
            static const u8 sText_Example9[] = _("Example 9");
            
            // Sets of multichoices.
            static const struct ListMenuItem sSet1[] =
            {
                {sText_Example1, 0},
                {sText_Example2, 1},
                {sText_Example3, 2},
                {sText_Example4, 3},
                {sText_Example5, 4},
                {sText_Example6, 5},
                {sText_Example7, 6},
                {sText_Example8, 7},
                {sText_Example9, 8},
            };
            
            static const struct ListMenuItem sSet2[] =
            {
                {sText_Example9, 0},
                {sText_Example8, 1},
                {sText_Example7, 2},
                {sText_Example6, 3},
                {sText_Example5, 4},
                {sText_Example4, 5},
                {sText_Example3, 6},
                {sText_Example2, 7},
                {sText_Example1, 8},
            };
            
            // Table of your multichoice sets.
            struct
            {
                const struct ListMenuItem *set;
                int count;
            } static const sScrollingSets[] =
            {
                {sSet1, ARRAY_COUNT(sSet1)},
                {sSet2, ARRAY_COUNT(sSet2)},
            };
            
            static void Task_ScrollingMultichoiceInput(u8 taskId);
            
            static const struct ListMenuTemplate sMultichoiceListTemplate =
            {
                .header_X = 0,
                .item_X = 8,
                .cursor_X = 0,
                .upText_Y = 1,
                .cursorPal = 2,
                .fillValue = 1,
                .cursorShadowPal = 3,
                .lettersSpacing = 1,
                .itemVerticalPadding = 0,
                .scrollMultiple = LIST_NO_MULTIPLE_SCROLL,
                .fontId = 1,
                .cursorKind = 0
            };
            
            // 0x8004 = set id
            // 0x8005 = window X
            // 0x8006 = window y
            // 0x8007 = showed at once
            // 0x8008 = Allow B press
            void ScriptMenu_ScrollingMultichoice(void)
            {
                int i, windowId, taskId, width = 0;
                int setId = gSpecialVar_0x8004;
                int left = gSpecialVar_0x8005;
                int top = gSpecialVar_0x8006;
                int maxShowed = gSpecialVar_0x8007;
            
                for (i = 0; i < sScrollingSets[setId].count; i++)
                    width = display_text_and_get_width(sScrollingSets[setId].set[i].name, width);
            
                width = convert_pixel_width_to_tile_width(width);
                left = sub_80E2D5C(left, width);
                windowId = CreateWindowFromRect(left, top, width, maxShowed * 2);
                SetStandardWindowBorderStyle(windowId, 0);
                CopyWindowToVram(windowId, 3);
            
                gMultiuseListMenuTemplate = sMultichoiceListTemplate;
                gMultiuseListMenuTemplate.windowId = windowId;
                gMultiuseListMenuTemplate.items = sScrollingSets[setId].set;
                gMultiuseListMenuTemplate.totalItems = sScrollingSets[setId].count;
                gMultiuseListMenuTemplate.maxShowed = maxShowed;
            
                taskId = CreateTask(Task_ScrollingMultichoiceInput, 0);
                gTasks[taskId].data[0] = ListMenuInit(&gMultiuseListMenuTemplate, 0, 0);
                gTasks[taskId].data[1] = gSpecialVar_0x8008;
                gTasks[taskId].data[2] = windowId;
            }
            
            static void Task_ScrollingMultichoiceInput(u8 taskId)
            {
                bool32 done = FALSE;
                s32 input = ListMenu_ProcessInput(gTasks[taskId].data[0]);
            
                switch (input)
                {
                case LIST_HEADER:
                case LIST_NOTHING_CHOSEN:
                    break;
                case LIST_B_PRESSED:
                    if (gTasks[taskId].data[1])
                    {
                        gSpecialVar_Result = 0x7F;
                        done = TRUE;
                    }
                    break;
                default:
                    gSpecialVar_Result = input;
                    done = TRUE;
                    break;
                }
            
                if (done)
                {
                    DestroyListMenuTask(gTasks[taskId].data[0], NULL, NULL);
                    ClearStdWindowAndFrame(gTasks[taskId].data[2], TRUE);
                    RemoveWindow(gTasks[taskId].data[2]);
                    EnableBothScriptContexts();
                    DestroyTask(taskId);
                }
            }

            Then, add this macro at the end of asm/macros/event.inc.
            Spoiler:
            Code:
            	.macro scrollingmultichoice id:req, x:req, y:req, show:req, b:req
            	setvar VAR_0x8004, \id,
            	setvar VAR_0x8005, \x,
            	setvar VAR_0x8006, \y,
            	setvar VAR_0x8007, \show,
            	setvar VAR_0x8008, \b,
            	callnative ScriptMenu_ScrollingMultichoice
            	waitstate
            	.endm

            How to use it? I provided two example sets of multichoices. Let me explain.
            Spoiler:

            Under the // Text displayed as options. comment I put all the strings that are displayed as options. Now, you may put the strings at any location, but keep in mind if the file location is different, you'll need to extern them.
            Spoiler:
            Code:
            static const u8 sText_Example1[] = _("Example 1");
            static const u8 sText_Example2[] = _("Example 2");
            static const u8 sText_Example3[] = _("Example 3");
            static const u8 sText_Example4[] = _("Example 4");
            static const u8 sText_Example5[] = _("Example 5");


            Then, under the // Sets of multichoices. comment I put all the sets of multichoices. What I mean by that is simply the options the player will be able to choose from. The syntax is simple, string name and id. The id is basically what you'll get in gSpecialVar_Result after the player chooses.
            Spoiler:
            Code:
            static const struct ListMenuItem sSet1[] =
            {
                {sText_Example1, 0},
                {sText_Example2, 1},
                {sText_Example3, 2},
                {sText_Example4, 3},
                {sText_Example5, 4},
                {sText_Example6, 5},
                {sText_Example7, 6},
                {sText_Example8, 7},
                {sText_Example9, 8},
            };


            And finally we have // Table of your multichoice sets. comment. As you may guess, this is the table with pointers to the multichoice sets along with the information how many options there are. Syntax is simple, set name and the number of options to choose from(I used a handy macro and advise you to do the same.)
            Spoiler:
            Code:
            struct
            {
                const struct ListMenuItem *set;
                int count;
            } static const sScrollingSets[] =
            {
                {sSet1, ARRAY_COUNT(sSet1)},
                {sSet2, ARRAY_COUNT(sSet2)},
            };

            Calling it from a script is simple, just use the macro you just put. The arguments are:
            - set id(sScrollingSets table)
            - window x
            - window y
            - amount of options showed at once on window
            - whether the player can press B(if TRUE, the return value is 0x7F just as from normal multichoice)
            Whichever option the player chooses is stored in gSpecialVar_Result.

            Example:
            scrollingmultichoice 1, 2, 3, 5, TRUE




            I also have the code in my github branch called script_multichoice, so you can pull directly from it.
            __________________
            Support Pokeemerald!
            Reply With Quote
              #13   Link to this post, but load the entire thread.  
            Old 2 Weeks Ago (8:10 PM). Edited 1 Week Ago by Petuuuhhh.
            Petuuuhhh's Avatar
            Petuuuhhh Petuuuhhh is offline
             
            Join Date: Apr 2017
            Location: Georgia
            Age: 25
            Gender: Male
            Posts: 615
            Disable Trade Restrictions (EM)

            This is untested, but I believe this works.

            Spoiler:
            Ctrl + F "IsNationalPokedexEnabled" in trade.c

            You'll find
            Code:
                if (!IsNationalPokedexEnabled())
                {
                    if (gUnknown_0203229C->unk_51[1][a3] || !IsSpeciesInHoennDex(species))
                    {
                        return 2;
                    }
                }
            Delete this.

            Then, find
            Code:
                if (!IsNationalPokedexEnabled())
                {
                    if (species2[monIdx] == SPECIES_EGG)
                    {
                        return 3;
                    }
            
                    if (!IsSpeciesInHoennDex(species2[monIdx]))
                    {
                        return 2;
                    }
                }
            Delete this as well.

            Now you should be able to trade with FRLG without having the National Dex!


            Disabled Disobedience (EM)

            This is also untested, but I believe this also works.

            Spoiler:
            Ctrl + F "static void atk00_attackcanceler(void)" in battle_script_commands.c until you get the function details. Then, find
            Code:
                if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
                {
                    i = IsMonDisobedient(); // why use the 'i' variable...?
                    switch (i)
                    {
                    case 0:
                        break;
                    case 2:
                        gHitMarker |= HITMARKER_OBEYS;
                        return;
                    default:
                        gMoveResultFlags |= MOVE_RESULT_MISSED;
                        return;
                    }
                }
            Delete this.

            Now your mon should obey you at any level!


            Update Moves to Gen 7 Standards (C), except for targeting, contact, priority, move interaction, and Mirror Move

            __________________
            Reply With Quote
              #14   Link to this post, but load the entire thread.  
            Old 1 Week Ago (2:10 PM). Edited 1 Week Ago by TheXaman.
            TheXaman TheXaman is offline
               
              Join Date: Nov 2018
              Posts: 3
              Running Indoors (EM)


              Simply remove the following from /src/bike.c and you should be able to use your running shoes inside any building.

              Inside the file search for:
              Code:
              bool32 IsRunningDisallowed(u8 metatile)
              and delete the following:
              Code:
              !(gMapHeader.flags & 4) ||
              Thats it, now you should be good to go (or run in this case).
              Reply With Quote
                #15   Link to this post, but load the entire thread.  
              Old 1 Week Ago (2:26 PM).
              TheXaman TheXaman is offline
                 
                Join Date: Nov 2018
                Posts: 3
                Surviving poison outside of battle with 1hp


                With just a few steps your pokemon should survive poison on the overworld now with 1hp, like in later gens.

                Open the file /src/field_poison.c
                Spoiler:

                Find the following function:
                Code:
                s32 DoPoisonFieldEffect(void)
                Simply add:
                Code:
                u32 numSurvived = 0;
                Then find this code inside:
                Code:
                if(hp == 0 || --hp == 0)
                and change the whole if-statement to:
                Code:
                if (hp == 1 || --hp == 1)
                {
                	u32 status = STATUS1_NONE;
                	SetMonData(pokemon, MON_DATA_STATUS, &status);
                	numSurvived++;
                	ScriptContext1_SetupScript(EventScript_PoisonSurvial);
                }
                Last in this file add the following after the for-loop:
                Code:
                if (numSurvived != 0)
                {
                	return FLDPSN_NONE;
                }


                Next open /data/event_scripts.s and add the following to the end of the file:
                Spoiler:

                Code:
                EventScript_PoisonSurvial::
                	msgbox Text_PoisonSurvial, MSGBOX_SIGN
                Text_PoisonSurvial:
                	.string "Poison survived with 1hp…$"


                Thats it, everything should be done.
                Reply With Quote
                  #16   Link to this post, but load the entire thread.  
                Old 2 Days Ago (1:52 PM).
                aueuaio aueuaio is offline
                   
                  Join Date: Jul 2018
                  Posts: 1
                  Skipping the poochyena battle after choosing the starter (pokéemerald)

                  You can skip the poochyena battle started by the script command "special ChooseStarter" by modifying a few lines in src/battle_setup.c.

                  In the CB2_GiveStarter function

                  Spoiler:
                  comment/delete the following line
                  Code:
                  PlayBattleBGM();
                  change the following line
                  Code:
                  BattleTransition_Start(B_TRANSITION_BLUR);
                  to
                  Code:
                  BeginNormalPaletteFade(0xFFFFFFFF, -1, 0, 0x10, 0);


                  In the CB2_StartFirstBattle function

                  Spoiler:
                  change the line
                  Code:
                  SetMainCallback2(CB2_InitBattle);
                  to
                  Code:
                  SetMainCallback2(CB2_EndFirstBattle);
                  and the line
                  Code:
                  if (IsBattleTransitionDone() == TRUE)
                  to
                  Code:
                  if (!gPaletteFade.active)


                  This modification also adds a graceful transition (a simple fade) to the overworld to avoid glitches. I didn't extensively test this, however since it only affects functions which are used once in the entire game, it should not have any unexpected side-effects.
                  Reply With Quote
                  Reply

                  Quick Reply

                  Join the conversation!

                  Create an account to post a reply in this thread, participate in other discussions, and more!

                  Create a PokéCommunity Account
                  Ad Content
                  Thread Tools

                  Posting Rules
                  You may not post new threads
                  You may not post replies
                  You may not post attachments
                  You may not edit your posts

                  BB code is On
                  Smilies are On
                  [IMG] code is On
                  HTML code is Off

                  Forum Jump


                  All times are GMT -8. The time now is 5:57 AM.