HUBOL ‐ Daily Log‐In Rewards - haven1433/HexManiacAdvance GitHub Wiki

Click here for HUBOL's main page. HUBOL is short for "Haven's Unofficial Build of Leon's dynamic Pokémon expansion."

Also known as "Perrennial Per-Frame scripts."

Credits: Defa

Tutorial

This routine adds the possibility to execute a script on each frame, exactly how a Per-Frame map script works, except it is toggled by a flag instead of a variable; the check for this flag is done continuously everywhere. To be accurate, the check is added in the function that waits for the player's input, so the script will not be executed automatically if there is another script currently running. The flag that toggles the script should be a daily flag; this way, the script will be executed only once — when the player boots up the game for the first time each day. If there is also a Per-Frame map script that should be executed at the same time, the daily script has precedence, then the Per-Frame map script will be executed right afterwards.

Add this routine in free space; at the bottom, change "E00" with a daily flag you did not use yet in your ROM hack, then change "112233" to the offset of the script you want to execute.

    lsr   r0, r0, #24
    push  {r4}
    mov   r4, r0 @backup TryRunOnFrameMapSCript return value
    ldr   r0, dailyflag
    ldr   r3, =0x0806E6D1 @FlagGet
    bl    linker
    cmp   r0, #1
    beq   back
    ldr   r0, dailyflag
    ldr   r3, =0x0806E681 @FlagSet
    bl    linker
    ldr   r0, script
    ldr   r3, =0x08069AE5 @ScriptContext_SetupScript
    bl    linker
    b     end
back:
    cmp   r4, #1
    beq   end @there is a Per-Frame map script
    pop   {r4}
    ldrb  r1, [r5, #0]
    ldr   r0, =0x0806CB31 @after hook
    bx    r0
end:
    pop   {r4}
    ldr   r3, =0x0806CB6D
linker:
    bx    r3
dailyflag: .word 0xE00
script: .word 0x08112233

Go to 06CB28, and change 00 0E 01 28 1E D0 29 78 to 00 49 08 47 <offset+1>.

You do not need to add setflag in your script: the routine sets the daily flag automatically in the routine for you.

You can use this script to implement a daily login reward, similar to some MMORPGs or games like Monster Hunter World, or respawn renewable items, Berry Trees, Pokémon Dens for Raid battles, etc.

Example Clip by Defa:

tDlir.mp4

In Addition

Check Consecutive Days for a Daily Log-in Reward Script

A little add-on routine you can use together with the above daily log-in reward script. This routine stores the current date in free saveblock space everytime it is used, so it has to be used only once each day. First, it gets the saved date, then adds 1 to the day number and compares it to the current date (today). If the dates match, then varResult is set to 1; otherwise, it is set to 0. This means that if the stored date is yesterday, the player logged in two days in a row, so if varResult is equal to 1, you can add 1 to an unused variable that keeps track of how many consecutive days the player logged in and give special login rewards after a set amount of days. If varResult is equal to 0, you reset the unused variable to 0 because the last day the player logged in was not yesterday. There will be no issues when executing this routine for the first time, when there is no stored date yet, because the routine will see that the stored date is day 0, month 0 and year 0, so comparing it with the current date will set varResult to 0 and then store the current date.

    push  {r4-r7, lr}
    ldr   r0, =0x03005008 @gSaveBlock1Ptr
    ldr   r0, [r0]
    ldr   r4, filler
    add   r4, r4, r0
    ldrb  r5, [r4] @day
    ldrb  r6, [r4, #1] @month
    ldrh  r7, [r4, #2] @year
    cmp   r5, #28
    beq   checkLeapYear
    cmp   r5, #29
    beq   checkFeb
    cmp   r5, #30
    beq   check30DaysMonths
    cmp   r5, #31
    bne   add1Day
setNewMonth:
    mov   r5, #1 @first day of new month
    cmp   r6, #12 @Dec
    beq   setNewYear
    add   r6, r6, #1
    b     loadCurrentDate
setNewYear:
    mov   r6, #1 @Jan
    add   r7, r7, #1 @new year
    b     loadCurrentDate
checkLeapYear:
    mov   r0, r7
    ldr   r3, =0x09463B31 @IsLeapYear
    bl    linker
    cmp   r0, #0
    beq   setNewMonth
    b     add1Day
checkFeb:
    cmp   r6, #2 @Feb
    beq   setNewMonth
    b     add1Day
check30DaysMonths:
    mov   r0, r6
    cmp   r6, #8
    blo   checkIs30DaysMonth
    sub   r0, r0, #5 @days in Mar~Jul match days in Aug~Dec
checkIs30DaysMonth:  @        (31-30-31-30-31)
    cmp   r0, #4 @Apr/Sep
    beq   setNewMonth
    cmp   r0, #6 @Jun/Nov
    beq   setNewMonth
add1Day:
    add   r5, r5, #1
loadCurrentDate:
    ldr   r0, =0x03005EA0 @gClock
    ldrb  r1, [r0, #4] @day
    ldrb  r2, [r0, #3] @month
    ldrh  r3, [r0] @year
    cmp   r1, r5
    bne   false
    cmp   r2, r6
    bne   false
    cmp   r3, r7
    bne   false
    mov   r0, #1
    b     setVarResult
false:
    mov   r0, #0
setVarResult:
    ldr   r5, =0x020370D0 @varResult
    strh  r0, [r5]
    strb  r1, [r4] @store current date
    strb  r2, [r4, #1]
    strh  r3, [r4, #2]
    pop   {r4-r7, pc}
linker: bx r3
filler: .word 0x00003A08

Example Script

  callasm <offset+1>
  if.yes.goto secAddOne
  setvar 0x4041 0 #reset counter variable if last login was not yesterday
  ### you can put regular daily rewards code here ###
  end

secAddOne:
  addvar 0x4041 1
  if.compare.goto 0x4041 == 5 sec5DaysReward
  if.compare.goto 0x4041 == 10 sec10DaysReward
  end

sec5DaysReward: #temp0 = item index, temp1 = quantity
  setvar temp0 2 #Ultra Ball
  setvar temp1 5
  goto secGiveReward

sec10DaysReward:
  setvar temp0 25 #Max Revive
  setvar temp1 3
#  goto secGiveReward #not needed if secGiveReward is right after this

secGiveReward:
  buffernumber buffer1 0x4041
  msgbox.default auto
{
You logged in for [buffer1]
consecutive days!

Take this special reward!
}
  npc.item 0x4000 0x4001
  if.compare.goto 0x4041 < 10 secEnd
  setvar 0x4041 0 #reset counter after 10 days (last reward)

secEnd:
  releaseall
  end
⚠️ **GitHub.com Fallback** ⚠️