Skip to content

Commit

Permalink
fix some wonky experience calculations
Browse files Browse the repository at this point in the history
particularly protect against overflow
also fix BluRosie#328
  • Loading branch information
BluRosie authored and mozzydippers committed Oct 1, 2024
1 parent 5e16238 commit a7745e6
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 54 deletions.
77 changes: 39 additions & 38 deletions asm/thumb_help.s
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.text
.align 1
.text
.align 1

.force_thumb
.syntax unified
Expand All @@ -13,48 +13,49 @@ __aeabi_idiv:
.thumb_func
.type __aeabi_idivmod,function
__aeabi_idivmod:
push {lr}
blx 0x020F2998
pop {pc}
.size __aeabi_idiv, . - __aeabi_idiv
.size __aeabi_idivmod, . - __aeabi_idivmod


.force_thumb
.syntax unified
.global __aeabi_uidiv
.thumb_func
.type __aeabi_uidiv,function
__aeabi_uidiv:
push {lr}
blx 0x020f2998
pop {pc}
.size __aeabi_idiv, . - __aeabi_idiv
.size __aeabi_idivmod, . - __aeabi_idivmod
.size __aeabi_uidiv, . - __aeabi_uidiv

.force_thumb
.syntax unified
.global __gnu_thumb1_case_uqi
.thumb_func
.type __gnu_thumb1_case_uqi,function
__gnu_thumb1_case_uqi:
push {r1}
mov r1, lr
lsrs r1, r1, #1
lsls r1, r1, #1
ldrb r1, [r1, r0]
lsls r1, r1, #1
add lr, lr, r1
pop {r1}
bx lr
.size __gnu_thumb1_case_uqi, . - __gnu_thumb1_case_uqi

.force_thumb
.syntax unified
.global __aeabi_uidivmod
.thumb_func
.type __aeabi_uidivmod,function
__aeabi_uidivmod:
push {lr}
blx 0x020f2998
blx 0x020F2BA4
pop {pc}
.size __aeabi_uidivmod, . - __aeabi_uidivmod
.size __aeabi_uidiv, . - __aeabi_uidiv
.size __aeabi_uidivmod, . - __aeabi_uidivmod


.force_thumb
.syntax unified
.global __gnu_thumb1_case_uqi
.thumb_func
.type __gnu_thumb1_case_uqi,function
__gnu_thumb1_case_uqi:
push {r1}
mov r1, lr
lsrs r1, r1, #1
lsls r1, r1, #1
ldrb r1, [r1, r0]
lsls r1, r1, #1
add lr, lr, r1
pop {r1}
bx lr
.size __gnu_thumb1_case_uqi, . - __gnu_thumb1_case_uqi

.force_thumb
.syntax unified
.global __gnu_thumb1_case_sqi
Expand Down Expand Up @@ -124,16 +125,16 @@ memset:
.thumb_func
.type __gnu_thumb1_case_shi,function
__gnu_thumb1_case_shi:
push {r0, r1}
mov r1, lr
lsrs r1, r1, #1
lsls r0, r0, #1
lsls r1, r1, #1
ldrsh r1, [r1, r0]
lsls r1, r1, #1
add lr, lr, r1
pop {r0, r1}
bx lr
push {r0, r1}
mov r1, lr
lsrs r1, r1, #1
lsls r0, r0, #1
lsls r1, r1, #1
ldrsh r1, [r1, r0]
lsls r1, r1, #1
add lr, lr, r1
pop {r0, r1}
bx lr
.size __gnu_thumb1_case_shi, . - __gnu_thumb1_case_shi

.force_thumb
Expand Down
14 changes: 7 additions & 7 deletions data/text/197.txt
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ The opposing {STRVAR_1 1, 0, 0}’s\n{STRVAR_1 6, 1, 0} melted the ice!
{STRVAR_1 1, 0, 0} is paralyzed,\nso it may be unable to move!
The wild {STRVAR_1 1, 0, 0} is paralyzed,\nso it may be unable to move!
The opposing {STRVAR_1 1, 0, 0} is paralyzed,\nso it may be unable to move!
{STRVAR_1 1, 0, 0}’s {STRVAR_1 5, 1, 0}\nparalyzed {STRVAR_1 1, 2, 0}!,\fso it may be unable to move!
{STRVAR_1 1, 0, 0}’s {STRVAR_1 5, 1, 0}\nparalyzed the wild {STRVAR_1 1, 2, 0}!,\fso it may be unable to move!
{STRVAR_1 1, 0, 0}’s {STRVAR_1 5, 1, 0}\nparalyzed the opposing {STRVAR_1 1, 2, 0}!,\fso it may be unable to move!
The wild {STRVAR_1 1, 0, 0}’s {STRVAR_1 5, 1, 0}\nparalyzed {STRVAR_1 1, 2, 0}!,\fso it may be unable to move!
The wild {STRVAR_1 1, 0, 0}’s\n{STRVAR_1 5, 1, 0} paralyzed the wild\f{STRVAR_1 1, 2, 0}!,\fso it may be unable to move!
The opposing {STRVAR_1 1, 0, 0}’s\n{STRVAR_1 5, 1, 0} paralyzed\f{STRVAR_1 1, 2, 0}!,\fso it may be unable to move!
The opposing {STRVAR_1 1, 0, 0}’s\n{STRVAR_1 5, 1, 0} paralyzed the opposing\f{STRVAR_1 1, 2, 0}!,\fso it may be unable to move!
{STRVAR_1 1, 0, 0}’s {STRVAR_1 5, 1, 0}\nparalyzed {STRVAR_1 1, 2, 0},\fso it may be unable to move!
{STRVAR_1 1, 0, 0}’s {STRVAR_1 5, 1, 0}\nparalyzed the wild {STRVAR_1 1, 2, 0},\fso it may be unable to move!
{STRVAR_1 1, 0, 0}’s {STRVAR_1 5, 1, 0}\nparalyzed the opposing {STRVAR_1 1, 2, 0},\fso it may be unable to move!
The wild {STRVAR_1 1, 0, 0}’s {STRVAR_1 5, 1, 0}\nparalyzed {STRVAR_1 1, 2, 0},\fso it may be unable to move!
The wild {STRVAR_1 1, 0, 0}’s\n{STRVAR_1 5, 1, 0} paralyzed the wild\f{STRVAR_1 1, 2, 0},\fso it may be unable to move!
The opposing {STRVAR_1 1, 0, 0}’s\n{STRVAR_1 5, 1, 0} paralyzed\f{STRVAR_1 1, 2, 0},\fso it may be unable to move!
The opposing {STRVAR_1 1, 0, 0}’s\n{STRVAR_1 5, 1, 0} paralyzed the opposing\f{STRVAR_1 1, 2, 0},\fso it may be unable to move!
{STRVAR_1 1, 0, 0} couldn’t move\nbecause it’s paralyzed!
The wild {STRVAR_1 1, 0, 0} couldn’t move\nbecause it’s paralyzed!
The opposing {STRVAR_1 1, 0, 0} couldn’t move\nbecause it’s paralyzed!
Expand Down
35 changes: 26 additions & 9 deletions src/battle/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1319,15 +1319,15 @@ void Task_DistributeExp_Extend(void *arg0, void *work)
monCountFromItem = 0;
for (int i = 0; i < party->count; i++)
{
pp = BattleWorkPokemonParamGet(expcalc->bw, exp_client_no, i);
if ((GetMonData(pp, MON_DATA_SPECIES, NULL)) && (GetMonData(pp, MON_DATA_HP, NULL)))
struct PartyPokemon *pploop = BattleWorkPokemonParamGet(expcalc->bw, exp_client_no, i);
if ((GetMonData(pploop, MON_DATA_SPECIES, NULL)) && (GetMonData(pploop, MON_DATA_HP, NULL)))
{
if (expcalc->sp->obtained_exp_right_flag[client_no /*(expcalc->sp->fainting_client >> 1) & 1*/] & No2Bit(i))
{
monCount++;
}

item = GetMonData(pp, MON_DATA_HELD_ITEM, NULL);
item = GetMonData(pploop, MON_DATA_HELD_ITEM, NULL);
eqp = BattleItemDataGet(expcalc->sp, item, 1);

if (eqp == HOLD_EFFECT_EXP_SHARE)
Expand All @@ -1346,15 +1346,32 @@ void Task_DistributeExp_Extend(void *arg0, void *work)
u32 Lp = GetMonData(pp, MON_DATA_LEVEL, NULL); // this should contain the level of the person getting experience
u32 level = expcalc->sp->battlemon[expcalc->sp->fainting_client].level; // need to calculate exp individually for each mon it seems

totalexp = GetSpeciesBaseExp(expcalc->sp->battlemon[expcalc->sp->fainting_client].species, expcalc->sp->battlemon[expcalc->sp->fainting_client].form_no); // base experience
totalexp = (totalexp * level) / 5;
u32 base = GetSpeciesBaseExp(expcalc->sp->battlemon[expcalc->sp->fainting_client].species, expcalc->sp->battlemon[expcalc->sp->fainting_client].form_no); // base experience
totalexp = (base * level) / 5;

u32 top = (2*level + 10) * (2*level + 10); // tack on the square root later
u32 top = (2*level + 10) * (2*level + 10) * sqrt(2*level + 10);
u32 bottom = (level + Lp + 10) * (level + Lp + 10) * sqrt(level + Lp + 10);

totalexp *= top;
totalexp /= bottom;
totalexp = totalexp * sqrt(2*level + 10); // square root tacked on
u32 result = top * totalexp;
// top is at minimum 3 (beat a level 3 mon), don't need to worry about it being 0
if (/*top != 0 && */(result / top) != totalexp)
{
// the only way that this is possible is if an overflow happened--the top value is going to be really high, so we correct the top to prevent overflow
//debug_printf("[Task_DistributeExp_Extend] Overflow detected... result = %d\n", result);
// so basically the real bL*5 * top = (-1u) + (result + 1)
// max bL*5 * top = 7840980000 (level 1 manages to beat level 100 blissey)
// loops around to 3546012704
// so now we just need to add the results divided by bottom (and add another 1 to correct for what i'm looking at)
totalexp = result + 1;
totalexp = (totalexp / bottom) + (-1u / bottom) + 1;
}
else
{
totalexp *= top;
totalexp /= bottom;
}

//debug_printf("[Task_DistributeExp_Extend] L = %d, Lp = %d, b = %d, top = %d, bottom = %d, exp = %d\n", level, Lp, base, top, bottom, totalexp);

if (monCountFromItem)
{
Expand Down

0 comments on commit a7745e6

Please sign in to comment.