Research & Development Got a well-founded knack with ROM hacking? Love reverse-engineering the Pokémon games? Or perhaps you love your assembly language. This is the spot for polling and gathering your ideas, and then implementing them! Share your hypothesis, get ideas from others, and collaborate to create!

Reply
 
Thread Tools
  #1    
Old February 15th, 2010 (10:28 PM). Edited February 16th, 2010 by JPAN.
JPAN JPAN is offline
pokemon rom researcher
     
    Join Date: Dec 2008
    Posts: 104
    From a request that started on the hacked engine thread came a question: "Now that we have a RTC system in Fire Red\Leaf Green, can we port the berry growth system from Ruby?" My answer to that was "Why not build one from scratch?" In this thread I will introduce the solution I came up with, but I feel can be somewhat improved. Also, as of the posting of this message, the berry system seems to work ok on the two-week trial it went through, but I would appreciate any help debugging and replacing problematic areas of code.

    First of all, I must say this code is built on top of a normal US Fire Red ROM with only the Day Night System by Interdpth & ZodiacDaGreat, using the Real Time Clock that comes with it. I would like to give credit to them for this great hack, and without which this would not be possible. I also use the code base for the hacked engine on the key-inserting and the OW hacks, and this latest is required for the correct working of this tool.

    Starting from the top:

    What is a berry tree?
    Berry trees are Overworld sprites, similar to any other, except they change with time. That time may pass by in-game or outside of the game, as the RTC will keep the game updated in either cases. Besides this outside look, they also need to store somewhere information about them, such as time since planted or watered, or what kind of berry tree it is.
    So, we can define a berry tree as an OW that changes with time and user interaction, and gives the player an item after a number of conditions are met.
    Where do we store that information? Variables are good, since they keep memory after the game is shut down. But can all information needed to be kept stored in a variable? Unfortunately, no. We need at least two variables for each tree.

    How is a berry tree made?
    This is the creative part. The official R/S/E berry tree is stored differently from the other OW's, and has its own sets of rules. They keep a memory area reserved for them, that the OW loader accesses direclty, and use a script with specials to obtain which area they are using, the berry growing there and the berry growth stage.
    In this approach, we will consider an hybrid model between R/S/E and D/P/Pt. Basically, a berry tree has two variables(with bit 0 being the least significant):
    Code:
    First Variable - Plant info
    first byte - "Berry" information
    bits 8-12 - Watered times
    bit 13 -     grow at 2x speed
    bit 14 -     grow at 1/2 speed
    bit 15 -     watered at this stage
    Code:
    Second Variable - Plant timer
    2 bytes time passed
    This approach considers the possibility to use damp and growth mulch on the berry after it was planted.
    Another think to note is the timespan. The time passed cannot be big enough to make one note a difference (one hour-apart updates would make a berry that was just planted to grow at the same time one that was planted 50 minutes ago) but not small enough to take much space (if in seconds, one day was too long for one variable). For this implementation, the timespan is one minute, that allows for a maximum livespan of 45 days and a half (0xfff0). As it seems impratical for such a long time, and because it's hard to make compares with this value, the day limit was set at 32 (0xb400).

    The berry information, shown in the first variable, is one byte long, too small to be the berry item number. Also, up until now we talked numbers, but what about the graphics?

    How does the game displays the correct berry tree?
    Once again, the official solution would do us no good. it involves some maths with the frame to display on the sole tree OW data, and some more maths to find the correct palette, and all of this using the data from the special memory area that we don't have. The solution for this is the use of a Dynamic OW hack to display the tree we need. But how does it know the correct image and when to display it? The solution is the creation of a Berry table, where the berry information byte is the index. That table is composed as this:
    Code:
    The Berry Tree Table
    2 byte item number
    1 byte empty (for now)
    1 byte min item quantity
    2 byte time it has in seed stage
    2 byte OW for seed stage
    2 byte time in sprout stage
    2 byte OW for sprout
    2 byte time in half-grown stage
    2 byte OW for half-grown stage
    2 byte time in full grown
    2 byte OW for full-grown
    2 byte time to go back to seed
    2 bytes OW for ripe
    This table allows anyone to design their own berry system, but it's more flexible than that. You can even design special events that take some time after you activate them to change into the event that you wanted it to. But it's main use is the berry system we come here to do. Simply slide the OW number and the time you need in the respective slot, the items it must give in the item slot and how many to give in the min_item slot and you get a berry tree for the item you wanted. The OW format is (OW table number) (OW number), as it was meant to be used with the OW hack.
    So, as an example, let's assume you have an oran berry tree's sprites stored (in order) in the positions 0-4 of your sprite table 0x5, and the ones for a sitrus berry tree in 5-7 (last three stages only). We assume that one oran tree gives 2-8 berries and sitrus gives 1-4 berries. We want the same times as the original version and we want oran as the first one and sitrus as the second. the table would look like this (| indicates end of berry):
    Code:
    8b 00 00 02 b4 00 05 00 68 01 05 01 1c 02 05 02
    d0 02 05 03 84 03 05 04|8e 00 00 01 68 01 05 00 
    d0 02 05 01 38 04 05 05 a0 05 05 06 08 07 05 07|
    The item minimum has double meaning, as the number of berries is currently calculated as min*watered_times.

    So, after all this long explanation on the ways this new berry system will work, it's time to put it into practice.
    All this code is useless if it is never used. So first of all, we need a function that, in game, runs at least once every minute, even if the player stays still. For that role, I chose the key reader.
    The key reader function is a special function that runs since the game begins to the moment you turn the power off. The keyboard may be pressed at any time, and as such, this function needs to read it frequently. More than once a minute. So, we take advantage of it, and place a small hack when it is called so that if a minute has passed since it last ran, a code is executed, and if not, simply carry on, with as little delay as possible. For that, I used a small memory room, not managed, at the position 0x0203f3f0. This code is the same as the one used for the key-pressing changes, so I'll only highlight the important piece of code in it, but will post it completely for testing purposes.
    Code:
    /*place the pointer to this function at 0x08000624, and change 0x080005ec to 00 47 */
    Key_wrecker_start: push {r4-r7}
       bl add_var_routine 
       ldr r0, key_addr
       ldrh r0, [r0]
       ldr r4, switches
       ldrb r1, [r4]
       cmp r1, #0x0
       beq nothing_to_do
       bl check_for_script
       bl check_for_forced
       bl check_for_cancel
    nothing_to_do:  pop {r4-r7}
       add r1, r0, #0x0
       ldr r0, return_place
       bx r0
    .hword 0x0000
    key_addr: .word 0x04000130
    switches: .word 0x0203f4ec
    return_place: .word 0x080005ef
    check_for_script: push {r0-r1,lr}
       mov r2, #0x4 /*check for flag*/
       and r2, r1
       cmp r2, #0x0
       beq end_all
       ldr r5, script_on /*check if a script is executing*/
       ldrb r3, [r5]
       cmp r3, #0x1
       beq end_all
       ldrh r2, [r4, #0x2] /*check if the keys are pressed*/
       and r2, r0
       cmp r2, #0x0
       bne end_all
     
       ldr r3, first_function /*checks if we are in the OW*/
       ldr r2, [r3]
       ldr r3, OW_function
       cmp r2, r3
       bne end_all
     
       mov r2, #0x1 /*if all is ok, run script*/
       strb r2, [r5]
       ldr  r0, [r4, #0x8]
       bl script_executer
    end_all:  pop {r0-r1,pc}
    script_on: .word 0x03000f9c
    first_function: .word 0x03005090
    OW_function: .word 0x08079e0d
    check_for_forced: push {lr}
       mov r2, #0x1 /*check for flag*/
       and r2, r1
       cmp r2, #0x0
       beq end_all_2
       ldrb r2, [r4, #0x1] /*check if it should apply it*/
       cmp r2, #0x0
       beq end_all_2
     
       sub r2, #0x1
       strb r2, [r4, #0x1] /*updates counter*/
       sub r4, #0xE
       ldrh r2, [r4] /*gets keymap to force*/
       add r4, #0xe
       mvn r2, r2
       and r0, r2 /*keys changed*/
    end_all_2:  pop {pc}
     
    check_for_cancel: push {lr}
       mov r2, #0x2 /*check for flag*/
       and r2, r1
       cmp r2, #0x0
       beq end_all_3
     
       ldr r2, [r4, #0x10] /*loads key to ignore*/
       orr r0, r2 /*ignored*/
    end_all_3:  pop {pc}
    script_executer: ldr r1, exe_addr
       bx r1
    exe_addr: .word 0x08069AE5
     
    add_var_routine:  ldr r1, last_time
                                 ldrb r0, [r1]
                                 cmp r0, #0x0 /*if timer is 0, nothing to do yet*/
                                 beq end_this
                                 sub r0, #0x1
                                 ldr r2, timer_min
                                 ldrb r2, [r2]
                                 cmp r2, r0
                                 beq end_this
     
    timer_update:       add r2, #0x1
                                 strb r2, [r1]
                                 push {r4-r7, lr}
                                 ldr r7, var_plant
                                 ldr r6, var_plant_time
                                 mov r5, #0xff
                                 ldr r4, berry_table 
     
    timer_up_loop:     add r0, r7, #0x0
                                 bl call_var_decrypt
                                 ldrh r1, [r0]
                                 cmp r1, #0x0
                                 beq next_plant
                                 bl time_and_water
     
    next_plant:            sub r5, #0x1
                                 add r7, #0x1
                                 add r6, #0x1
                                 cmp r5, #0x0
                                 bge timer_up_loop
                                 pop {r4-r7,pc}
     
    end_this: mov pc, lr
     
    .hword 0x0000 
    var_plant: .word 0x00007d00     /*intput your plant variables here*/
    var_plant_time: .word 0x00007e00
    last_time: .word 0x0203f3f0
    timer_min: .word 0x03005543
    berry_table: .word 0x00000000 /*replace by your table*/
     
    /*this function will up the timer and allow you to water again after the plant has supposedly grown. this function is completely dependant on the above one*/
    time_and_water:  push {r6,r7,lr}
                                 add r7, r0, #0x0
                                 add r0, r6, #0x0
                                 push {r1}
                                 bl call_var_decrypt
                                 pop {r1}
                                 add r6, r0, #0x0
                                 ldrh r2, [r0]
                                 add r2, #0x1
                                 strh r2, [r0] /*stores the value first, to avoid problems*/
                                 lsl r3, r1, #0x18 
                                 lsr r3, r3, #0x18
                                 mov r0, #0x18
                                 mul r3, r0
                                 add r3, r4, r3
                                 bl time_ops
                                 ldrh r0, [r3, #0x4]
                                 cmp r0, r2
                                 beq water_able
                                 ldrh r0, [r3, #0x8]
                                 cmp r0, r2
                                 beq water_able
                                 ldrh r0, [r3, #0xc]
                                 cmp r0, r2
                                 beq water_able
                                 ldrh r0, [r3, #0x10]
                                 cmp r0, r2
                                 beq water_able
                                 ldrh r0, [r3, #0x14]
                                 cmp r2, r0
                                 bge dispose_of
                                 pop {r6,r7,pc}
     
    water_able:           lsl r1, r1, #0x11
                                 lsr r1, r1, #0x11 /*eliminates watered byte*/
                                 strh r1, [r7]
                                 pop {r6,r7,pc}
     
    dispose_of:            lsl r1, r1, #0x18
                                 lsr r1, r1, #0x18
                                 strh r1, [r7]  /*eliminates the old care bits*/
                                 sub r2, r2, r0  
                                 str r2, [r6] /*places 0 on the old spot.*/   
                                 pop {r6,r7,pc} 
     
     
    call_var_decrypt: ldr r1, var_decrypt
                                 bx r1
    var_decrypt: .word 0x0806E455
     
    /*calculates the time appling the mulch effect*/
     
    time_ops:       lsl r0, r1, #0x11
                         lsr r0, r0, #0x1e 
                         cmp r0, #0x1
                         beq half_time /*grows 2 times faster*/
                         cmp r0, #0x2
                         beq double_time /*takes double time to grow*/
                         mov pc, lr
    half_time:       lsr r2, r2, #0x1
                         mov pc, lr
    double_time: lsl r2, r2, #0x1
                         mov pc, lr
    This last code takes care or the in-game update problem by making sure the game updates all variables in the given interval. But the key finder is used even before the game is loaded (title screen). To prevent the game from trying to update non-existing berries, the first condition was created. Checking if the time counter is 0 makes it possible to check if the game has started yet, as long as we use a non-0 number to initialize it when we want it to run. That problem comes into contact with the out-game time passage.
    The RTC doesn't run the game code to make sure berries are updated, so we need to create a system that allows the player to leave his game unattended for a large period of time without losing its berries. For that the next routine was created. A first problem encountered is that, to my knowledge, the clock time from the last save is not stored anwywhere. For that, I used two variables (0x4090 and 0x4091) to store the time. Also, as room was lacking, I saved only month, day, hour and minute of the last save. That means that if you played a hack using this system a year after you put it down, everything would be the same as when you left. Another problem was where to put it. It is expensive, so ideally we should run it only once, but what routines run only once just as soon the game loads? First attempt was made with the routine at 0xcc94, responsible for the fadescreen after the game is loaded in the starting screen, both for "continue" and "new game". But another problem ensued. When that routine is called, it loads the game, but uses the variable's space to determine the "last on" scene when it continues. at the end of that, another routine loads the variables again, and that routine is called through the WRAM Stack area, making it almost untraceable. So, as an alternative, I went with the collision detector. The function is located at 0x0806d698, and handles all movement. It doesn't, however, run until you move. So this is a somewhat poor replacement function, but since we believe that every person that plays the game will eventually walk around it, it's not that bad. All this code is relevant to the subject at hand
    Code:
    /*To make sure this is run, place bx r0 (00 47) at 0806d6a8, and place the pointer to this 
    at 0x0806D6E0
    */
     
    /*r7 keeps the plant variable and r6 the timer variable associated
    r5 is the variables remaining counter and r4 is the time that passed.
    this code is divided in two separate versions, one for when over 32 days passed and one
    for when less than 32 days passed. The first is called the Overflowed version, and the
    second regular version. The overflowed version is labled.
    */
     
    Berry_time: ldr r1, last_time
                    ldrb r1, [r1]
                    cmp r1, #0x0   /*the check for if this code already ran once*/
                    bne real_exit
     
                    push {r0-r7}
                    ldr r7, var_plant
                    ldr r6, var_plant_time
                    bl get_time
                    add r4, r0, #0x0
                    mov r5, #0xff
                    cmp r1, #0x1
                    beq overflowed
     
    timer_up_loop:  add r0, r7, #0x0         /*the extensive check verison*/
                          bl call_var_decrypt
                          ldrh r1, [r0]
                          cmp r1, #0x0      /*checks if there is a berry in there*/
                          beq next_plant
                          add r2, r6, #0x0  
                          bl add_and_store_berry
    next_plant:       sub r5, #0x1
                          add r7, #0x1
                          add r6, #0x1
                          cmp r5, #0x0
                          bge timer_up_loop
                          b almost_exit
     
    var_plant: .word 0x00007d00        /*replace for your own variables here*/
    var_plant_time: .word 0x00007e00
    .hword 0x0000
     
    overflowed:    add r0, r7, #0x0
                        bl call_var_decrypt
                        ldrh r1, [r0]
                        cmp r1, #0x0
                        beq next_plant_2
                        lsl r1, r1, #0x18   /*erase watering and mulch bytes*/
                        lsr r1, r1, #0x18  /*as they are no longer valid*/
                        strh r1, [r0]
     
                        add r2, r6, #0x0  
                        bl add_n_store_berry /*different function, as it doesn't search for water*/
                                                     /*bits*/
    next_plant_2: sub r5, #0x1
                       add r7, #0x1
                       add r6, #0x1
                       cmp r5, #0x0
                       bge overflowed
     
    almost_exit:   ldr r0, timer_var
                       bl call_var_decrypt 
                       add r1, r0, #0x0
                       ldr r0, rtc_time
                       ldr r3, last_time 
                       ldrb r2, [r0, #0x4]
                       add r2, #0x1
                       strb r2, [r3] /*places the minute+1 in the slot*/
                                        /*making this happen no more*/
                       bl replace_old_time 
                       pop {r0-r7}
     
    real_exit:       ldr r0, addr_adfa
                       ldrb r0, [r0, #0x7]
                       ldr r1, ret_addr
                       bx r1
     
    last_time: .word 0x0203f3f0
    timer_var: .word 0x00004090 /*variables that keep the last known time*/
    rtc_time: .word 0x0300553f
    addr_adfa: .word 0x0203adfa
    ret_addr: .word 0x0806d6ab
     
    /*this function calculates the time very thorughly (except february 29th is not included)
    receives nothing and returns in r0 the time difference, in minutes, from the latest 
    recorded time and the one currently on the RTC.
    modified so it fits the max berry time interval, and r1 as a flag determining if the time
    value has been exceeded.*/
     
    .hword 0x0000
    get_time:     push {r4-r7,lr}
                      ldr r4, var_time
                      add r0, r4, #0x0
                      bl call_var_decrypt
                      ldr r5, [r0] /*in the format month, day, hour, minute*/
                      add r6, r0, #0x0 /*for later storage*/
                      mov r7, #0x0    /*cleans r7, as it will be the timer counter*/
                      ldr r4, cur_time
                      ldrb r0, [r4, #0x4]
                      lsl r1, r5, #0x18
                      lsr r1, r1, #0x18
                      cmp r0, r1
                      beq check_hour
                      cmp r0, r1
                      bgt total_minute
                      add r0, #0x3c /*adds one hour*/
                      mov r2, #0x1
                      lsl r2, r2, #0x8 /*"one hour"*/
                      sub r5, r5, r2 /*hour removed for further calculus*/
     
    total_minute: sub r7, r0, r1 /*places the passed minutes at the counter*/
     
    check_hour: lsl r1, r5, #0x10
                     lsr r1, r1, #0x18
                     ldrb r0, [r4, #0x3]
                     cmp r0, r1
                     beq check_day
                     cmp r0, r1
                     bgt total_hour
                     add r0, #0x18 /*adds one day*/
                     mov r2, #0x1
                     lsl r2, r2, #0x10 /*"one day"*/
                     sub r5, r5, r2 /*one day less*/
     
    total_hour:  mov r2, #0x3c
                    sub r0, r0, r1
                    mul r0, r2 /*turns hours into minutes*/
                    add r7, r7, r0
     
    check_day: lsl r1, r5, #0x8
                    lsr r1, r1, #0x18
                    ldrb r0, [r4, #0x1]
                    cmp r0, r1
                    beq check_month
                    cmp r0, r1
                    bgt total_days
                    lsr r2, r5, #0x18   /*gets current month*/
                    sub r2, #0x1        /*gets the month before it*/
                    cmp r2, #0x0       /*if month before is december*/
                    bne get_month_day
                    mov r2, #0xc
     
    get_month_day: bl month_to_day
                           add r0, r2, r0
                           mov r2, #0x1
                           lsl r2, r2, #0x18
                           sub r5, r5, r2 /*takes a month away*/
     
    total_days:        sub r0, r0, r1
                           mov r2, #0x5a 
                           lsl r2, r2, #0x4 /* minutes_per_day*/
                           mul r0, r2
                           add r7, r0, r7
     
    /*the last one is trickier, as we need to add the days of each month one by one */
     
    check_month:    lsr r1, r5, #0x18
                           cmp r1, #0x0      /*may happen if to january we subtract 1 (december)*/
                           bne month_load
                           mov r1, #0xc
     
    month_load:      ldrb r0, [r4] /*after this point, r4-r6 contents are useless*/
                          cmp r0, r1
                          beq check_size
                          mov r5, #0x5a 
                          lsl r5, r5, #0x4
                          cmp r0, r1
                          bgt bigger_month
     
    over_december: cmp r1, #0xd
                          beq for_normal
                          add r2, r1, #0x0
                          bl month_to_day
                          mul r2, r5
                          add r7, r2, r7
                          add r1, #0x1
                          b over_december
     
    for_normal:       cmp r0, #0x1
                          beq check_size
                          mov r1, #0x1 
    bigger_month:   add r2, r1, #0x0
                          bl month_to_day
                          mul r2, r5
                          add r7, r2, r7
                          add r1, #0x1
                          cmp r0, r1
                          bgt bigger_month
     
    /*size check so it won't go over 0xb400, the 32-day limit imposed on berries. this limit
    can be upped to 45 and a half days (0xfff0), tops. the 32 day limit seemed appropriate and
    low-cost and speedy on the machine*/ 
     
    check_size: mov r2, #0xb4
                     lsl r2, r2, #0x8
                     cmp r7, r2
                     bgt special_flag
                     add r0, r7, #0x0
                     mov r1, #0x0
                     pop {r4-r7, pc}
     
    special_flag: mov r1, #0x1
     
    norm_loop: sub r7, r7, r2
                    cmp r7, r2
                    bgt norm_loop
                    add r0, r7, #0x0
                    pop {r4-r7, pc}
    var_time: .word 0x00004090 /*choose your own, as long as it's even*/
    cur_time: .word 0x0300553f
     
    /*Converts the month given in a ammount of days
    receives r2 as the month needed, as to not destroy r0 and r1
    */
    month_to_day: ldr r3, month_time
                         sub r2, #0x1
                         add r3, r3, r2
                         ldrb r2, [r3]
                         mov pc, lr
    .hword 0x0000
    month_time: .word 0x00000000
    days_of_month:   .byte 0x1f
                            .byte 0x1c
                            .byte 0x1f
                            .byte 0x1e
                            .byte 0x1f
                            .byte 0x1e
                            .byte 0x1f
                            .byte 0x1f
                            .byte 0x1e
                            .byte 0x1f
                            .byte 0x1e
                            .byte 0x1f
     
    /*A special function that adds the timer on for a berry, checking for water.
    This is the function called by the regular verison, and is very expensive 
    receives r0 as the berry variable address, r1 as the content of r0,  r2 as the berry timer
    var, r4 as the timer value
    returns nothing
    */
     
    add_and_store_berry: push {r5-r7, lr}
                                  add r6, r0, #0x0
                                  ldr r5, berry_table
                                  lsl r1, r1, #0x18
                                  lsr r1, r1, #0x18
                                  mov r3, #0x18
                                  mul r1, r3
                                  add r5, r1, r5  /*berry location in the table*/
                                  add r0, r2, #0x0
                                  bl call_var_decrypt
                                  add r7, r0, #0x0
                                  ldrh r2, [r7]
                                  add r2, r4, r2
                                  ldrh r3, [r5, #0x14]
                                  bl time_calc /*corrects the time with the used mulch*/
                                  cmp r2, r3
                                  bge subtract_time
                                  ldrh r0, [r7]
                                  add r1, r5, #0x0 /*gets the stage the berry was on*/
                                  bl get_stage
                                  add r3, r0, #0x0 
                                  add r0, r2, #0x0
                                  bl get_stage  /*gets the stage the berry is now in*/
                                  cmp r0, r3
                                  beq store_and_end
                                  ldrh r1, [r6]         /*different, erase watered bit*/
                                  lsl r1, r1, #0x11
                                  lsr r1, r1, #0x11
                                  strh r1, [r6]
                                  b store_and_end
     
    subtract_time:          ldrh r1, [r6]
                                  lsl r1, r1, #0x18
                                  lsr r1, r1, #0x18
                                  strh r1, [r6]
     
    subtract_loop:  sub r2, r2, r3
                         cmp r2, r3
                         bge subtract_loop
     
    store_and_end:  strh r2, [r7]
                           add r0, r6, #0x0
                           pop {r5-r7, pc}
     
    /*second add function, without checks for the water byte
    The one used in the overflown version.
    receives r0 as the timer variable*/
     
    add_n_store_berry:  push {r5-r6, lr}
                                ldr r5, berry_table
                                mov r3, #0x18
                                mul r1, r3
                                add r5, r1, r5
                                bl call_var_decrypt
                                ldrh r2, [r0]
                                add r2, r4, r2
                                ldrh r3, [r5, #0x14]/*doesn't check for mulch*/
                                cmp r2, r3             /*as we know it's gone*/                     
                                blt end_add_n_store 
     
    sub_berry_loop:       sub r2, r2, r3
                                cmp r2, r3
                                blt sub_berry_time_loop
     
    end_add_n_store:    strh r2, [r0]
                                pop {r5-r6, pc}
    .hword 0x0000
    berry_table: .word 0x090004e8
     
    call_var_decrypt: ldr r1, var_decrypt
                            bx r1
    var_decrypt: .word 0x0806E455
     
    /*function to get the stage a tree with a certain number is at on a certain time.
    r0 is the time value, r1 is the table position for the berry
    returns in r0 the value for the stage, 0xff if over the max*/
     
    get_stage:  push {r3,r5, lr}
                     add r5, r1, #0x0
                     ldrh r3, [r5, #0x4]
                     bl time_calc
                     cmp r0, r3
                     blt first_stage
     
                     ldrh r3, [r5, #0x8]
                     bl time_calc
                     cmp r0, r3
                     blt second_stage
     
                     ldrh r3, [r5, #0xc]
                     bl time_calc
                     cmp r0, r3
                     blt third_stage
     
                     ldrh r3, [r5, #0x10]
                     bl time_calc
                     cmp r0, r3
                     blt fourth_stage
     
                     ldrh r3, [r5, #0x14]
                     bl time_calc
                     cmp r0, r3
                     blt last_stage
     
                     mov r0, #0xff /*over the last stage, error*/
                     pop {r3,r5, pc}
     
    first_stage:  mov r0, #0x1
                     pop {r3,r5, pc}
     
    second_stage: mov r0, #0x2
                         pop {r3,r5, pc}
     
    third_stage: mov r0, #0x3
                     pop {r3,r5, pc}
    fourth_stage: mov r0, #0x4
                       pop {r3,r5, pc}
    last_stage:    mov r0, #0x5
                       pop {r3,r5, pc}
     
    /*the small function that calculates what mulch was used.
    made specifically for this batch of fucntions, doesn't work
    if used outside of them*/
    time_calc: ldrh r1, [r6]
                   lsl r1, r1, #0x11
                   lsr r1, r1, #0x1e 
                   cmp r1, #0x1
                   beq half_time /*grows 2 times faster*/
                   cmp r1, #0x2
                   beq double_time /*takes double time to grow*/
                   mov pc, lr
     
    half_time:  lsr r3, r3, #0x1
                   mov pc, lr
    double_time: lsl r3, r3, #0x1
                      mov pc, lr
     
     
    /*a small function that loads the current time and stores it at the time variables.
    receives r0 as the RTC loaction and r1 as the variable location. returns nothing.*/
    replace_old_time: push {r4, r5, lr}
                            add r4, r0, #0x0
                            add r5, r1, #0x0
                            ldrb r1, [r4]
                            lsl r1, r1, #0x8
                            ldrb r0, [r4, #0x1]
                            orr r1, r0
                            lsl r1, r1, #0x8
                            ldrb r0, [r4, #0x3]
                            orr r1, r0
                            lsl r1, r1, #0x8
                            ldrb r0, [r4, #0x4]
                            orr r1, r0
                            str r1, [r5]
                            pop {r4, r5, pc}
    Finally, we need to be able to change the image of the OW. Some theories came to mind on how to do this one, but in the end I ended up with the following:
    There is a limit of 256 different berry slots, each identified in the person id by the table number 0xfe. The game, when loading the OW, checks its table number, and in the same way Dynamic OWs were created, he also checks to see what it should print. It goes to the Plant variable, checks for the table index of that entry, calculates the current time on that variable to get its stage, and finally prints the corresponding OW. The code is as follows: (what matters in BOLD)
    Code:
    get_ow_addr: push {r2-r4}
      lsl r1, r0, #0x10
      lsr r1, r1, #0x18
      lsl r0, r0, #0x18
      lsr r0, r0, #0x18
      ldr r4, new_ow_table
      cmp r1, #0xff
      beq special_decrypter
      cmp r1, #0xfe
      beq berry_decrypter
    more_check: cmp r1, #0xff
      bgt go_old /*to allow for a multi-sized Table table*/
      cmp r1, #0x0
      bne end_check
      cmp r0, #0xef
      bgt go_old
      bl multi_check
    end_check: lsl r1, r1, #0x2
      add r3, r4, r1
      ldr r2, [r3]
      cmp r2, #0x0
      bne location_real
      ldr r2, [r4]
    location_real: lsl r0, r0, #0x2
      add r3, r2, r0
      ldr r0, [r3]
      cmp r0, #0x0
      bne end_ow_change
      ldr r3, [r4]
      add r3, #0x40
      ldr r0, [r3] 
    end_ow_change: pop {r2-r4}
      pop {r1}
      bx r1
    special_decrypter: cmp r0, #0xf /*change here for more variables usable*/
       bgt more_check
       ldr r1, var_4080
       add r0, r1, r0
       bl call_var_decrypt
       ldrb r1, [r0, #0x1]
       ldrb r0, [r0]
       b end_check
    berry_decrypter: bl plant_ow_get /*see berry implementations*/
                                b end_check
    .hword 0x0000   
    new_ow_table: .word 0x0871bae0  /*0xffffffff*/
    var_4080: .word 0x00004d00 /*0xffffffff*/
    go_old:  pop {r2-r4}
      ldr r1, loader_call
      bx r1   
    /*this is the check that allows for trainer OW switch
    How it works: Vars 4054-59 must have a value. 0x0 for the
    default sprite, 0xyyyy for the new sprite*/
    multi_check:  push {lr}
      push {r0, r1}
      cmp r0, #0xD
      bgt no_change
      cmp r0, #0x7
      blt hero_change
      sub r0, #0x7 
    hero_change: ldr r1, var_Hero
      add r0, r0, r1
      bl call_var_decrypt
      b end_multi_check
    no_change: pop {r0,r1}
      pop {pc}
    end_multi_check: ldrh r1, [r0]
      cmp r1, #0x0
      beq no_change
      lsl r0, r1, #0x18
      lsr r0, r0, #0x18
      lsr r1, r1, #0x8
      pop {r2,r3}
      pop {pc}
    .hword 0x0000
    var_Hero: .word 0x00004054
    loader_call:  .word 0x0805f2d5   
     
    plant_ow_get:  push {r4-r7, lr}
                            ldr r6, var_plant_time /*get plant spent time data*/
                            add r6, r0, r6
                            ldr r7, var_plant /*get plant data variable*/
                            add r0, r0, r7
                            bl call_var_decrypt
                            add r7, r0, #0x0
                            add r0, r6, #0x0
                            bl call_var_decrypt
                            add r6, r0, #0x0
                            ldrh r0, [r7]
                            lsl r0, r0, #0x18
                            lsr r0, r0, #0x18
                            cmp r0, #0x0
                            bne cont_tree
                            mov r0, #0x0
                            mov r1, #0x0
                            pop {r4-r7, pc}  
     
    cont_tree:         ldr r5, berry_table
                            mov r1, #0x18
                            mul r0, r1
                            add r5, r5, r0
                            mov r2, #0x0
                            ldrh r3, [r6]
                            ldrh r1, [r7]
                            lsl r1, r1, #0x11
                            lsr r1, r1, #0x1e /*gets the mulch used*/
     
    tree_find_loop: add r5, #0x4
                             ldrh r0, [r5]
                             bl time_calc  
                             cmp r3, r0
                             ble ow_found
                             add r2, #0x1
                             cmp r2, #0x5
                             blt tree_find_loop
     
                             sub r3, r3, r0
                             strh r3, [r6]
                             ldrh r1, [r7]
                             lsl r1, r1, #0x18
                             lsr r1, r1, #0x18
                             strh r1, [r7]
                             mov r1, #0x0
                             sub r5, #0x14
                             mov r2, #0x0
                             b tree_find_loop
                             pop {r4-r7,pc}
     
    ow_found:  ldrb r1, [r5, #0x2]
                     ldrb r0, [r5, #0x3]
                     pop {r4-r7,pc}
     
    var_plant: .word 0x00007d00 /*your variables here*/
    var_plant_time: .word 0x00007e00
    berry_table: .word 0x090004e8 /*your berry table here*/
     
    time_calc:      cmp r1, #0x1
                         beq half_time /*grows 2 times faster*/
                         cmp r1, #0x2
                         beq double_time /*takes double time to grow*/
                         mov pc, lr
    half_time:       lsr r0, r0, #0x1
                         mov pc, lr
    double_time: lsl r0, r0, #0x1
                         mov pc, lr
     
    call_var_decrypt: ldr r2, var_decrypt
                            bx r2
    .hword 0x0000
    var_decrypt: .word 0x0806E455
    This code is meant to replace the one at the OW hack. As such, if you want to use it, I would appreciate you compile this code and simply replace the one at the hacked engine tool version, the file "ow_main.out". I will not post the rest of the required code for the OW hack, as it is not the main topic here, and it's too big to post.

    Another problem present is how to keep the time the game was last updated. The out-game updating routine takes care of updating the time it was executed, but there was no need to save every minute. All we need is for the variable to be up-to-date as we save the game. So, I created this save hack that saves the variable when the save screen is shown:
    Code:
    /*if the game saved in the variables the new time all the time, the function would be
    so time-consuming it could never run once every minute without noticeable delay. as such
    the variables containing the time will only be saved when the Save game popup appears.
    because it doesn't really matter that the variables are changed in game, only that they
    have saved the last real time they were played on, the variables will write themselves each
    time the save popup is called.
    the easiset way to insert this function is to place it on the site of the save string, and
    force it to go to the string display function afterwards. So
    6f7c8 == bx r0 (00 47)
    6f7d4 == pointer to this function
    */
    replace_old_time: ldr r0, timer_var
                            bl call_var_decrypt
                            add r3, r0, #0x0
                            ldr r2, RTC
                            ldrb r1, [r2]
                            lsl r1, r1, #0x8
                            ldrb r0, [r2, #0x1]
                            orr r1, r0
                            lsl r1, r1, #0x8
                            ldrb r0, [r2, #0x3]
                            orr r1, r0
                            lsl r1, r1, #0x8
                            ldrb r0, [r2, #0x4]
                            orr r1, r0
                            str r1, [r3]
                            ldr r0, save_question
                            ldr r1, next_save_q
                            ldr r2, return_addr
                            mov lr, r2
                            ldr r2, copy_save_string
                            bx r2
     
    timer_var: .word 0x00004090
    RTC:  .word 0x0300553f
    save_question:  .word 0x081c55c9
    next_save_q: .word 0x0806f7dd
    return_addr: .word 0x0806f7cf
    copy_save_string: .word 0x0806f69d
    
    call_var_decrypt: ldr r1, var_decrypt
                            bx r1
    var_decrypt: .word 0x0806E455
    This code is quite similar to the one that does the same thing at the long-term update function, but this one has all the things the game needs to continue with the save function, where the other one doesn't.
    I finished a routine that gets the planted item, as well as the quantity produced. The formula to the number of items was previously mentioned, but there is a special case that when it's 0, it will give 2 if always watered and 1 otherwise. It uses variables 0x8004 and 0x8005, and returns to 0x8004 and to r0 the item and to 0x8005 returns the number of items. This code is supposed to be used with a callasm or included in an empty special.
    Code:
    /*this code does not remove the berry tree, or update any value. It simply checks.
    */
    Get_berry:     push {r4-r5, lr}
                       ldr r5, var_8004
                       ldrh r0, [r5]
                       mov r1, #0x40
                       lsl r1, r1, #0x8
                       cmp r0, r1       /*checks if r0 is a valid variable*/
                       blt end_now
                       bl call_var_decrypt
                       ldrh r4, [r0]
                       ldr r1, berry_table
                       lsl r0, r4, #0x18
                       lsr r0, r0, #0x18
                       mov r2, #0x18
                       mul r0, r2
                       add r1, r0, r1
                       ldrh r0, [r1] /*gets the item*/
                       strh r0, [r5] /*stores it at 0x8004*/
                       ldrb r0, [r1, #0x3] /*gets the min item value*/
                       lsl r2, r2, #0x13
                       lsr r2, r2, #0x18
                       cmp r0, #0x0
                       beq special_case
                       lsl r0, r2
    store_num:    strh r0, [r5, #0x2] /*number of berries stored at 0x8005*/
                       lsl r0, r4, #0x18
                       lsr r0, r0, #0x18 /*so it returns the berry number*/ 
    end_now:      pop {r4-r5, pc}
     
    special_case: mov r0, #0x1  /*the special "0" case*/
                       cmp r2, #0x4
                       bne store_num  
                       lsl r0, r0, #0x1
                       b store_num
     
    var_8004: .word 0x020370c0
    berry_table: .word 0x00000000 /*place table address here*/
     
    call_var_decrypt: ldr r1, var_decrypt
        bx r1
    var_decrypt: .word 0x0806E455
    That's what I've got so far. To be a fully functional berry tree hack, it still needs the gets and sets of this type, that is:
    planting routine;
    add mulch routine;
    watering routine;
    Check tree state routine;
    Check watered time routine;
    Berry script.

    So, before I leave, I have some questions I need to raise.

    First, how do you thing the planting should be done? It's two simple setvars, one for the plant and one for the timer, but how will we find the item the player wants to plant, and its position on the table?

    Second, do you think it would be more appropriate to change the OW hack to instead of reading of a variable, reading a set of variables concerning where it is? For instance, its not var sprite 0x0, table 0xfe = var 0x7d00 plant, but rather sprite 0x0, table 0xfe = a fixed variable that contains the plant variable. Having regional variables can increase the number of berries possible, but is it really necessary to have more than 256 berry plants? And if so, what would be a good number of variables to set apart for a map script to change?

    Third, do you think the item number should be determined by the given formula, or would you prefer something more like the 0 case (the byte only represents a mode)?
    __________________
    Here are the links for my work


    Currently working on:
    Battle Script Documentation
    Another large project
    Reply With Quote

    Relevant Advertising!

      #2    
    Old February 16th, 2010 (4:28 PM).
    NarutoActor's Avatar
    NarutoActor NarutoActor is offline
    The rocks cry out to me
    • Silver Tier
     
    Join Date: Jan 2009
    Location: Brooklyn/Marlboro
    Age: 23
    Gender: Female
    Nature: Bashful
    Posts: 1,979
    Wow, great job I had to read it twice to fully understand. But on your questions do you think it is possible to make a routine that when they click on the dirt path, you then they can click on a berry you want to plant, and the berry chosen gets placed into a var. Then the other routine checks the var.

    Or make a routine kinda similar to the special the makes the player chose 3 pokemon, but insted of choosing 3 pokemon you chose one berry.
    __________________
    ~There are those people who understand hex, F the rest
    Reply With Quote
      #3    
    Old February 17th, 2010 (10:21 AM).
    helloNL helloNL is offline
       
      Join Date: Oct 2009
      Gender: Male
      Posts: 37
      how to install this?
      i dont see how
      Reply With Quote
        #4    
      Old February 17th, 2010 (10:51 AM).
      Tropical Sunlight's Avatar
      Tropical Sunlight Tropical Sunlight is offline
      The Faltine
         
        Join Date: Mar 2008
        Location: Slovenia
        Age: 21
        Gender: Male
        Posts: 3,572
        Quote:
        Originally Posted by helloNL View Post
        how to install this?
        i dont see how
        You "install" this with an ASM... thing.
        __________________
        Reply With Quote
          #5    
        Old February 17th, 2010 (12:50 PM).
        NarutoActor's Avatar
        NarutoActor NarutoActor is offline
        The rocks cry out to me
        • Silver Tier
         
        Join Date: Jan 2009
        Location: Brooklyn/Marlboro
        Age: 23
        Gender: Female
        Nature: Bashful
        Posts: 1,979
        Some routines should be complied with gas, or goldroad while others should be complied with devkitpro. He specified what code was in devkitpro. Once it is complied you have the hex code.
        __________________
        ~There are those people who understand hex, F the rest
        Reply With Quote
          #6    
        Old February 18th, 2010 (9:55 AM).
        helloNL helloNL is offline
           
          Join Date: Oct 2009
          Gender: Male
          Posts: 37
          maybe someone make a ips?
          or aps?
          Reply With Quote
            #7    
          Old February 18th, 2010 (1:04 PM).
          NarutoActor's Avatar
          NarutoActor NarutoActor is offline
          The rocks cry out to me
          • Silver Tier
           
          Join Date: Jan 2009
          Location: Brooklyn/Marlboro
          Age: 23
          Gender: Female
          Nature: Bashful
          Posts: 1,979
          I would much more prefer to see this implemented into jpans program, if not keep it like this. Anybody can apply an ips patch, this way makes it so that only the decent hackers can reap the benefits.
          __________________
          ~There are those people who understand hex, F the rest
          Reply With Quote
            #8    
          Old February 18th, 2010 (7:35 PM).
          colcolstyles's Avatar
          colcolstyles colcolstyles is offline
          Yours truly
          • Crystal Tier
           
          Join Date: May 2008
          Location: The Bay Area
          Gender: Male
          Nature: Lonely
          Posts: 1,584
          Quote:
          Originally Posted by NarutoActor View Post
          I would much more prefer to see this implemented into jpans program, if not keep it like this. Anybody can apply an ips patch, this way makes it so that only the decent hackers can reap the benefits.
          That's a pretty elitist outlook on knowledge. For me, one of the core aspects of ROM Hacking is the sharing of discoveries with other members of the community. Why should we exclude hackers from "reaping the benefits" of this very useful code?

          And before you even think about, please don't pull the "it'll get overused and make it less special" argument. I saw that a lot with the release of Mastermind_X's Day/Night System and I'm getting pretty sick of it.
          __________________

          Brother of Vrai
          Reply With Quote
            #9    
          Old February 18th, 2010 (8:53 PM).
          ZodiacDaGreat's Avatar
          ZodiacDaGreat ZodiacDaGreat is offline
          Working on a Mobile System
             
            Join Date: Feb 2007
            Location: South Pacific
            Age: 24
            Gender: Male
            Nature: Relaxed
            Posts: 429
            Quote:
            Originally Posted by colcolstyles
            That's a pretty elitist outlook on knowledge. For me, one of the core aspects of ROM Hacking is the sharing of discoveries with other members of the community. Why should we exclude hackers from "reaping the benefits" of this very useful code?

            And before you even think about, please don't pull the "it'll get overused and make it less special" argument. I saw that a lot with the release of Mastermind_X's Day/Night System and I'm getting pretty sick of it.
            Yes, I agree knowledge should be shared and people who use the code must give credit - even if they temper with it and make a completely new code from it.

            If something's overused or less special, then work hard and pull of something even better than the existing version of a cool hack. Otherwise don't complain
            __________________
            Reply With Quote
              #10    
            Old February 19th, 2010 (5:20 AM).
            helloNL helloNL is offline
               
              Join Date: Oct 2009
              Gender: Male
              Posts: 37
              its just that i never understand what JPAN is explaining
              and i hack already a long time
              Reply With Quote
                #11    
              Old February 19th, 2010 (9:43 AM). Edited February 19th, 2010 by Nodddy.
              Nodddy Nodddy is offline
              Banned
                 
                Join Date: Feb 2010
                Gender: Male
                Posts: 9
                Quote:
                Originally Posted by colcolstyles View Post
                That's a pretty elitist outlook on knowledge. For me, one of the core aspects of ROM Hacking is the sharing of discoveries with other members of the community. Why should we exclude hackers from "reaping the benefits" of this very useful code?

                And before you even think about, please don't pull the "it'll get overused and make it less special" argument. I saw that a lot with the release of Mastermind_X's Day/Night System and I'm getting pretty sick of it.
                Are you saying that he isn't sharing his work? Because if not I'd sure like to know what was in that huge first post he made.

                Anyone who understands the information he has given is able to implement this in their own hack, and those who don't should learn what it means instead of blindly patching their ROM.
                Reply With Quote
                  #12    
                Old February 19th, 2010 (10:14 AM).
                helloNL helloNL is offline
                   
                  Join Date: Oct 2009
                  Gender: Male
                  Posts: 37
                  no
                  he was reacting to someone elses post
                  he wants that ppl share their discoveries
                  Reply With Quote
                    #13    
                  Old February 19th, 2010 (12:59 PM).
                  NarutoActor's Avatar
                  NarutoActor NarutoActor is offline
                  The rocks cry out to me
                  • Silver Tier
                   
                  Join Date: Jan 2009
                  Location: Brooklyn/Marlboro
                  Age: 23
                  Gender: Female
                  Nature: Bashful
                  Posts: 1,979
                  There not discovering anything throw a patch or learning anything. They will just be using the system for them self. It wouldn't be knowledge it would just be a new feature for them.
                  __________________
                  ~There are those people who understand hex, F the rest
                  Reply With Quote
                    #14    
                  Old February 20th, 2010 (4:36 PM).
                  colcolstyles's Avatar
                  colcolstyles colcolstyles is offline
                  Yours truly
                  • Crystal Tier
                   
                  Join Date: May 2008
                  Location: The Bay Area
                  Gender: Male
                  Nature: Lonely
                  Posts: 1,584
                  Quote:
                  Originally Posted by NarutoActor View Post
                  There not discovering anything throw a patch or learning anything. They will just be using the system for them self. It wouldn't be knowledge it would just be a new feature for them.
                  Clearly you misinterpreted what I said. I said nothing about whether using a patch is a discovery or not. My point was that if someone makes a discovery, it should be shared with the entire community. No one should be excluded based on how long they've been hacking or how "good" they are at hacking.
                  __________________

                  Brother of Vrai
                  Reply With Quote
                    #15    
                  Old February 20th, 2010 (8:43 PM).
                  NarutoActor's Avatar
                  NarutoActor NarutoActor is offline
                  The rocks cry out to me
                  • Silver Tier
                   
                  Join Date: Jan 2009
                  Location: Brooklyn/Marlboro
                  Age: 23
                  Gender: Female
                  Nature: Bashful
                  Posts: 1,979
                  Well then you most of miss understood me. I am all for sharing discoveries, I don't care how long you hack, but I like it when discoveries are not just patches; because then you actually learn something.
                  __________________
                  ~There are those people who understand hex, F the rest
                  Reply With Quote
                    #16    
                  Old February 20th, 2010 (9:32 PM).
                  Full Metal's Avatar
                  Full Metal Full Metal is offline
                  C(++) Developer.
                  • Silver Tier
                   
                  Join Date: Jan 2008
                  Location: In my mind.
                  Age: 22
                  Gender: Male
                  Nature: Timid
                  Posts: 806
                  >__< in other words u two are saying the same thing
                  colcolstyles wants things to be open to everyone, and narutoactor wants it to be available to those who know how to use it, stop fighting about stupid stuff >__>
                  anyways, really liken this interdepth xD before long u are prob gonna have the entire ROM hacked xD
                  __________________

                  ★ full metal.

                  I like to push it,
                  and push it,
                  until my luck is over.
                  Reply With Quote
                    #17    
                  Old February 20th, 2010 (11:49 PM).
                  Darthatron's Avatar
                  Darthatron Darthatron is offline
                  巨大なトロール。
                  • Silver Tier
                   
                  Join Date: Jan 2006
                  Location: Melbourne, Australia
                  Age: 25
                  Gender: Male
                  Nature: Modest
                  Posts: 1,152
                  I don't think you should make a patch, people should know how something works before they attempt to put it in their hack. It will just create more problems later.

                  Quote:
                  Originally Posted by Full Metal View Post
                  >__< in other words u two are saying the same thing
                  colcolstyles wants things to be open to everyone, and narutoactor wants it to be available to those who know how to use it, stop fighting about stupid stuff >__>
                  anyways, really liken this interdepth xD before long u are prob gonna have the entire ROM hacked xD
                  This is JPAN, not interdpth. :\
                  __________________
                  あなた は しきしゃ です
                  わたし は ばか です
                  Reply With Quote
                    #18    
                  Old February 21st, 2010 (12:01 AM).
                  ZodiacDaGreat's Avatar
                  ZodiacDaGreat ZodiacDaGreat is offline
                  Working on a Mobile System
                     
                    Join Date: Feb 2007
                    Location: South Pacific
                    Age: 24
                    Gender: Male
                    Nature: Relaxed
                    Posts: 429
                    Quote:
                    Originally Posted by Darthatron
                    I don't think you should make a patch, people should know how something works before they attempt to put it in their hack. It will just create more problems later.
                    Yeah which in turn leads to more PMs and more "How do Is", etc
                    __________________
                    Reply With Quote
                      #19    
                    Old February 21st, 2010 (12:08 AM).
                    Darthatron's Avatar
                    Darthatron Darthatron is offline
                    巨大なトロール。
                    • Silver Tier
                     
                    Join Date: Jan 2006
                    Location: Melbourne, Australia
                    Age: 25
                    Gender: Male
                    Nature: Modest
                    Posts: 1,152
                    Quote:
                    Originally Posted by ZodiacDaGreat View Post
                    Yeah which in turn leads to more PMs and more "How do Is", etc
                    Yeah... I get enough of them already... Ones that have absolutely nothing to do with me what-so-ever - "How do you set IVs in YAPE", for example. Anyway... There will probably be a few posts saying "How do I insert this into my hack?" anyway... I don't know... JPAN can do whatever he likes.
                    __________________
                    あなた は しきしゃ です
                    わたし は ばか です
                    Reply With Quote
                      #20    
                    Old February 21st, 2010 (12:25 AM).
                    Full Metal's Avatar
                    Full Metal Full Metal is offline
                    C(++) Developer.
                    • Silver Tier
                     
                    Join Date: Jan 2008
                    Location: In my mind.
                    Age: 22
                    Gender: Male
                    Nature: Timid
                    Posts: 806
                    Quote:
                    Originally Posted by Darthatron View Post
                    I don't think you should make a patch, people should know how something works before they attempt to put it in their hack. It will just create more problems later.


                    This is JPAN, not interdpth. :\
                    lol, i forgot they weren't the same (i thought interdepth was JPAN on another forum )
                    __________________

                    ★ full metal.

                    I like to push it,
                    and push it,
                    until my luck is over.
                    Reply With Quote
                      #21    
                    Old August 28th, 2010 (6:19 PM).
                    Shiny Quagsire's Avatar
                    Shiny Quagsire Shiny Quagsire is offline
                    I'm Still Alive, Elsewhere
                       
                      Join Date: May 2009
                      Location: Hoenn Safari Zone
                      Age: 19
                      Gender: Male
                      Nature: Jolly
                      Posts: 700
                      I'm pretty sure the revival limit doesn't apply here...

                      OK, so I've followed through on this tutorial, inserted all of the routines and such, I've even written a water checker, waterer, and mulch adders. But, how exactly does the game know which overworld is a tree? Is it the person ID that's set to the variable? Or is it something different?
                      __________________



                      Reply With Quote
                        #22    
                      Old August 29th, 2010 (1:48 PM).
                      jakerman999's Avatar
                      jakerman999 jakerman999 is offline
                      looking for spriters
                         
                        Join Date: Oct 2007
                        Location: Ingersoll
                        Age: 24
                        Gender: Male
                        Nature: Adamant
                        Posts: 52
                        Yo, JPAN, don't know if you got all the info you wanted from this thread(esp. with all the offtopic) and have carried on development, but thought I would throw in my two cents.

                        Planting berries could be done two ways that I can see. The first would be writing a routine from the use option in the item menu(checking if you're standing in front of a dirt patch, if not goto the regular berry use) which seems difficult as to my knowledge items are not completely understood yet. The second would be using a special command to select a berry(either by going to the item menu or your dynamic listboxes).

                        Your second question is worded somewhat ambiguously, so I'll answer both options. 256 is more than enough for types of berry plants. You might want to go up 1000(1024?) for number of berry plants that can be placed around the world map.

                        By your third question, I assume you mean number of berries received? I would just use a random number generator between 2 and 6. Saves space and time.

                        One more thought I had when reading your work was how you saved and recalled time. Your solution works, but it looks like a lot of effort only to fail if there is a one year gap, or February 29th pops up. My suggestion to this point is to store time in minutes and calculate the rtc value in minutes. It would save space both in asm code and in variables(one year in minutes can be expressed in twenty bits), won't break on February 29th and fixes the one year exploit/loophole/glitch/whatever.

                        And to everyone arguing about releasing this in a patch,see this spoilered rant.
                        Spoiler:
                        Releasing this in a patch is a horrible idea. It relies on to other hacks for it to work, so it would have to be packaged with those hacks, bringing out a higher probability of something going wrong. The day night hack with the RTC isn't even JPAN's work so that's less of a reason make a patch for it. All of his work is sitting in the first post for anyone who wants to use it. Releasing a tool for it, or bundling it with the hacked engine is a MAYBE if the process could be automated, and IF JPAN wants to spend the time on it. Both unlikely.

                        Also, JPAN didn't discover anything to share, this was all created from scratch. Anyone could implement the final project with just a little bit of research and hardwork. If someone isn't willing to do that then they don't really need this in their project. This has remarkable documentation and I understood most of it first time through. Difficult to create from scratch? Very. Difficult to copy and implement? Not so much.
                        __________________
                        you must build -inal pylons.

                        jakerman999's PokePet

                        sharpshell the level 45 Kabutops!


                        I have a life, I bought it on e-bay.

                        support shiny gold!
                        Reply With Quote
                          #23    
                        Old August 29th, 2010 (2:43 PM).
                        Shiny Quagsire's Avatar
                        Shiny Quagsire Shiny Quagsire is offline
                        I'm Still Alive, Elsewhere
                           
                          Join Date: May 2009
                          Location: Hoenn Safari Zone
                          Age: 19
                          Gender: Male
                          Nature: Jolly
                          Posts: 700
                          Man, how come whenever I ask a question, I always answer it myself? (I was pretty sleepy last night doing this, maybe that's why...)
                          Anyways, I found my answer.
                          Quote:
                          Originally Posted by JPAN
                          There is a limit of 256 different berry slots, each identified in the person id by the table number 0xfe.
                          So I set the overworld sprite # to 0xFE, and the person ID to the variable!
                          __________________



                          Reply With Quote
                            #24    
                          Old November 16th, 2010 (10:03 PM).
                          dt200's Avatar
                          dt200 dt200 is offline
                          Was and will be forever alone.
                             
                            Join Date: Sep 2010
                            Location: Malaysia
                            Gender: Male
                            Nature: Lonely
                            Posts: 18
                            Do I have to hex edit and which portion of hex codes?
                            Reply With Quote
                              #25    
                            Old December 31st, 2010 (4:56 PM).
                            NintendoBoyDX NintendoBoyDX is offline
                               
                              Join Date: Jul 2010
                              Gender: Male
                              Posts: 94
                              Sorry to resurrect an old topic, but I needed to ask, is there a way to get the time of the RTC clock? If so it would be pretty easily to script the entire GSC berry system(no planting/watering or moving icons involved, just pick a tree OW sprite, and give it a script to check the time, and if so use the giveitem command to give the person a berry once per day.
                              Reply With Quote
                              Reply
                              Quick Reply

                              Sponsored Links
                              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 7:44 AM.