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
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
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
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