Skip to content

Instantly share code, notes, and snippets.

@Nenkai
Last active March 1, 2026 13:18
Show Gist options
  • Select an option

  • Save Nenkai/4111b4fb44e3c00aadf4245e4f581c43 to your computer and use it in GitHub Desktop.

Select an option

Save Nenkai/4111b4fb44e3c00aadf4245e4f581c43 to your computer and use it in GitHub Desktop.
bool RewardLotData::ShouldGiveWeapon(RewardLotData *rewardLot, uint storyDifficultyType, int rewardRank)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]
storyDiff = rewardLot->StoryDiffType;
if ( storyDifficultyType == 3 )
{
if ( storyDiff != 3 )
return 0;
}
else if ( storyDiff != -1 && storyDiff != storyDifficultyType )
{
return 0;
}
v4 = rewardLot->RewardRank;
if ( v4 != -1 && v4 != rewardRank )
return 0;
WeaponId = rewardLot->WeaponId;
shouldGiveWeapon = 1;
if ( WeaponId != 0x887AE0B0LL )
{
v7 = g_WeaponManager;
v8 = g_CharaManager;
if ( WeaponManager::HasWeaponInInventory(a1: g_WeaponManager, weaponId: WeaponId) )
return 0;
v10 = WeaponId & v7->Weapon.field_30;
end = v7->Weapon.Field_8;
Field_18 = v7->Weapon.Field_18;
node = *&Field_18[16 * v10 + 8];
if ( node == end )
return shouldGiveWeapon; // Weapon row does not exist? Give it anyway? Bug?
if ( *(node + 16) == WeaponId ) // Search weapon in weapon row
{
nextWeaponRow:
if ( node != end )
{
WeaponData = *(node + 24);
if ( WeaponData )
{
CharaId = WeaponData->CharaId;
if ( CharaId == 0x2A26B1B2 || CharaId == 0xA4ACBA76 )// PL0000 / PL0100 (Gran / Djeeta)
{
CharaManager::GetCurrentCaptainCharacter(a1: v8, outCharaId: &captainCharaId);
CharaId = WeaponData->CharaId;
if ( CharaId == captainCharaId )
return 0;
}
if ( CharaId == 0x718E1A14 && g_VersionMajor < 4 )// PL2100 Sandalphon (why is this here? macro?)
return 0;
(v8->CharaList.vtable->GetEmptyKey)(&v8->CharaList, v22);// (always returns 887AE0B0 aka empty (XXHash32Custom.Hash(""))
if ( v22[0] == CharaId ) // Empty character?
return 0;
Field_8 = v8->CharaList.CharacterSaveList.Field_8;
v18 = v8->CharaList.CharacterSaveList.Field_18;
v19 = *&v18[16 * (CharaId & v8->CharaList.CharacterSaveList.field_30) + 8];// Iterate through characters & find character
if ( v19 == Field_8 )
return 0;
if ( *(v19 + 16) != CharaId )
{
while ( v19 != *&v18[16 * (CharaId & v8->CharaList.CharacterSaveList.field_30)] )
{
v19 = *(v19 + 8);
if ( *(v19 + 16) == CharaId ) // Found matching character?
goto LABEL_29;
}
return 0; // Character not found
}
LABEL_29:
if ( v19 == Field_8 )
return 0;
v20 = *(v19 + 0x18);
// Character save entity has no data, or character not unlocked? (characters are stored even if they're not unlocked.)
if ( !v20 || (*(v20 + 0x30D0) & 1) == 0 )
return 0;
}
}
}
else
{
v14 = *&Field_18[16 * v10];
while ( node != v14 )
{
node = *(node + 8);
if ( *(node + 16) == WeaponId )
goto nextWeaponRow;
}
}
}
return shouldGiveWeapon;
}
bool WeaponManager::HasWeaponInInventory(WeaponManager *this, uint weaponId)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]
v2 = this->Weapon.field_30;
Field_8 = this->Weapon.Field_8;
Field_18 = this->Weapon.Field_18;
v5 = *&Field_18[16 * (weaponId & v2) + 8];
if ( v5 != Field_8 )
{
if ( *(v5 + 16) == weaponId )
{
LABEL_5:
if ( v5 != Field_8 )
{
WeaponData = *(v5 + 24);
if ( WeaponData )
{
v7 = WeaponData->WeaponId;
if ( v7 != 0x887AE0B0 )
weaponId = v7;
}
}
}
else
{
while ( v5 != *&Field_18[16 * (weaponId & this->Weapon.field_30)] )
{
v5 = *(v5 + 8);
if ( *(v5 + 16) == weaponId )
goto LABEL_5;
}
}
}
v8 = &this->gap188[40]; // Weapon item list (save)
v9 = &this->gap188[41000];
while ( 1 )
{
v10 = v8[1];
v11 = *&Field_18[16 * (v10 & v2) + 8];
if ( v11 != Field_8 )
{
if ( *(v11 + 16) == v10 )
{
LABEL_14:
if ( v11 != Field_8 )
{
weaponRow = *(v11 + 24);
if ( weaponRow )
{
v13 = weaponRow->WeaponId;
if ( v13 != -2005213008 )
v10 = v13;
}
}
}
else
{
while ( v11 != *&Field_18[16 * (v10 & v2)] )
{
v11 = *(v11 + 8);
if ( *(v11 + 16) == v10 )
goto LABEL_14;
}
}
}
if ( v10 == weaponId )
return *v8;
v8 += 40; // Move next
if ( v8 == v9 )
{
LOBYTE(v14) = 0;
return v14;
}
}
}
// For completeness's sake, not necessary
void __fastcall RewardManager::GetReward(
RewardManager *a1,
void *a2,
unsigned int rewardLotId,
unsigned int storyDifficultyType,
int rewardRank,
char a6)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]
v58 = a2;
v7 = rewardLotId & a1->RewardLot_.field_30;
RewardLotData_1 = a1->RewardLot_.Field_8;
Field_18 = a1->RewardLot_.Field_18;
v10 = *&Field_18[16 * v7 + 8];
if ( v10 != RewardLotData_1 )
{
if ( *(v10 + 16) != rewardLotId )
{
v12 = *&Field_18[16 * v7];
do
{
if ( v10 == v12 )
return;
v10 = *(v10 + 8);
}
while ( *(v10 + 16) != rewardLotId );
}
if ( v10 != RewardLotData_1 )
{
randWeightChance = g_Rand[0];
v15 = g_Rand[0];
v14 = _InterlockedCompareExchange(g_Rand, 1664525 * g_Rand[0] + 1013904223, g_Rand[0]);
if ( v15 != v14 )
{
do
{
randWeightChance = v14;
v16 = v14;
v14 = _InterlockedCompareExchange(g_Rand, 1664525 * v14 + 1013904223, v14);
}
while ( v16 != v14 );
}
RewardLotData = *(v10 + 24);
end = *(v10 + 32);
if ( RewardLotData != end )
{
totalWeight = 0;
while ( 1 )
{
if ( !RewardLotData::ShouldGiveWeapon(a1: *&RewardLotData->Key, storyDifficultyType, rewardRank) )
goto LABEL_15;
v23 = *&RewardLotData->Key;
if ( a6 == -1 || v23[1] == 0x887AE0B0 && v23[3] == 0x887AE0B0 && v23[2] == 0x887AE0B0 && v23[5] == -1 )
{
weight = v23[11];
goto LABEL_14;
}
v24 = *(g_RupiManagerMaybe + 1168);
v21 = 0;
if ( v24 != *(g_RupiManagerMaybe + 1176) )
{
v25 = *v24;
if ( v25 )
{
if ( a6 == 1 )
{
v20 = (v25 + 52);
}
else
{
if ( a6 )
goto LABEL_13;
v20 = (v25 + 56);
}
v21 = *v20;
}
}
LABEL_13:
weight = v23[11] + v21;
LABEL_14:
totalWeight += weight;
LABEL_15:
RewardLotData = (RewardLotData + 8);
if ( RewardLotData == end )
{
if ( !totalWeight )
return;
v26 = *(v10 + 24);
if ( *(v10 + 32) == v26 )
return;
v27 = 0;
chance = randWeightChance % totalWeight;
v29 = 0;
while ( 2 )
{
v34 = *(v26 + 8 * v29);
if ( RewardLotData::ShouldGiveWeapon(a1: v34, storyDifficultyType, rewardRank) )
{
if ( a6 == -1
|| v34->ItemId == 0x887AE0B0
&& v34->GemId == -2005213008
&& v34->WeaponId == -2005213008
&& v34->PhaseItemIndex == -1 )
{
v37 = v34->Weight;
v33 = chance < v37;
chance -= v37;
if ( v33 )
{
LABEL_47:
if ( v29 != -1 )
{
v38 = *(*(v10 + 24) + (v27 >> 29));
if ( v38[5] == -1 )
{
__asm { vxorps xmm3, xmm3, xmm3 }
v41 = v58;
sub_7FF75C3E2610(&v58->Reward.field_0, v38[1], v38[6], *&_XMM3, -1);
}
else
{
sub_7FF75C2EC3F0(&v52, g_CurrentPhaseNumber);
sub_7FF75C2EC480(&v57, v52);
if ( v57 )
{
v39 = v38[5];
if ( v39 <= 9 )
{
__asm { vxorps xmm3, xmm3, xmm3 }
sub_7FF75C3E2610(&v58->Reward.field_0, *(v57 + 4 * v39), v38[6], *&_XMM3, -1);
}
}
v41 = v58;
}
v43 = v38[10];
v44 = v38[3];
v45 = v38[9];
LODWORD(v57) = v44;
v52 = -1;
v56 = 0;
v55 = v43;
if ( v45 > 0 && v44 != -2005213008 )
{
v46 = v41 + 48;
do
{
while ( 1 )
{
v54 = 0;
v53 = 1;
v47 = v41->Reward.field_38;
if ( v47 != *&v41->RewardLot_.field_0 )
break;
sub_7FF75C3E2700(v46, v47, &v57, &v53, &v55, &v56, &v54, &v52);
v41 = v58;
if ( !--v45 )
goto LABEL_60;
}
v47->Reward.field_0 = v44;
v47->Reward.field_4 = 1;
LODWORD(v47->Reward.Field_8) = v43;
*(&v47->Reward.Field_8 + 4) = 0;
HIDWORD(v47->Reward.field_10) = -1;
LOBYTE(v47->Reward.Field_18) = 0;
*(&v47->Reward.Field_18 + 4) = 0;
v41->Reward.field_38 += 36;
--v45;
}
while ( v45 );
}
LABEL_60:
v48 = v38[8];
v49 = v38[2];
v50 = v38[7];
LODWORD(v57) = v49;
v52 = -1;
v56 = v48;
v55 = v50;
if ( v49 != -2005213008 )
{
v54 = 0;
v53 = 1;
Field_20 = v41->Reward.Field_20;
if ( Field_20 == v41->Reward.field_28 )
{
sub_7FF75C3E2700(v41 + 24, Field_20, &v57, &v53, &v55, &v56, &v54, &v52);
}
else
{
LODWORD(Field_20->lpVtbl) = v49;
HIDWORD(Field_20->lpVtbl) = 1;
LODWORD(Field_20[1].lpVtbl) = v50;
HIDWORD(Field_20[1].lpVtbl) = v48;
Field_20[2].lpVtbl = 0xFFFFFFFF00000000LL;
LOBYTE(Field_20[3].lpVtbl) = 0;
*(&Field_20[3].lpVtbl + 4) = 0;
v41->Reward.Field_20 = (v41->Reward.Field_20 + 36);
}
}
}
return;
}
}
else
{
v35 = *(g_RupiManagerMaybe + 1168);
v31 = 0;
if ( v35 != *(g_RupiManagerMaybe + 1176) )
{
v36 = *v35;
if ( v36 )
{
if ( a6 == 1 )
{
v30 = (v36 + 52);
goto LABEL_32;
}
if ( !a6 )
{
v30 = (v36 + 56);
LABEL_32:
v31 = *v30;
}
}
}
v32 = v34->Weight + v31;
v33 = chance < v32;
chance -= v32;
if ( v33 )
goto LABEL_47;
}
}
++v29;
v26 = *(v10 + 24);
v27 += 0x100000000LL;
if ( (*(v10 + 32) - v26) >> 3 <= v29 )
return;
continue;
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment