Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save leoetlino/ff246cb5c16b12c5af14a899d1cd8ffd to your computer and use it in GitHub Desktop.
Save leoetlino/ff246cb5c16b12c5af14a899d1cd8ffd to your computer and use it in GitHub Desktop.
void action::ItemAmiiboCreateFromDropTable::doSpawn(const sead::SafeString& drop, BaseProcHandle* procHandle, const Vec3* additionalPosOffset)
{
if (!drop)
return;
const bool isImportant = ActorInfoData::sInstance->hasTagByName(drop.c_str(), Tag_Important);
if (isImportant && GameDataMgr::sInstance && GameDataMgr::sInstance->getFlagBool("IsGet_" + drop))
return;
if ( sead::SafeStringBase<char>::findIndex(drop, "GameRomHorse") != -1 )
setFlag_IsAmiiboDrop_GameRomHorseItem(true, 0);
ActorInstParams params;
Vec3 posOffset;
this->calculateCreatePositionOffset(&posOffset);
posOffset.x += additionalPosOffset->x;
posOffset.y += additionalPosOffset->y;
posOffset.z += additionalPosOffset->z;
const Bdrop* bdrop = this->actor->actorParam->dropTable;
bool spawnInTBox = ActorInfoData::sInstance->hasTagByName(drop.c_str(), Tag_AmiiboTreasure);
if ( bdrop )
{
// Daruk amiibo
if ( bdrop->resourceName == "Actor/DropTable/Item_Amiibo_DropTable_012" )
{
if (drop.startsWith("Item_Ore_") && drop != "Item_Ore_A") // Ore and not a Diamond
spawnInTBox = false;
}
// Revali amiibo
if ( bdrop->resourceName == "Actor/DropTable/Item_Amiibo_DropTable_013" )
{
if ( drop.startsWith("Obj_BombArrow") )
spawnInTBox = false;
}
// Urbosa amiibo
if ( bdrop->resourceName == "Actor/DropTable/Item_Amiibo_DropTable_015" )
{
if ( drop.startsWith("Obj_ElectricArrow") )
spawnInTBox = false;
}
}
auto getCreatePos = [&]() {
// Randomize create position, accounting for container objects
if ( !spawnInTBox )
{
const int breakBoxIronIdx = drop.findIndex("Obj_BreakBoxIron");
const int kibakoContainIdx = drop.findIndex("Kibako_Contain");
float createArea = *this->createArea;
if ( kibakoContainIdx != -1 || breakBoxIronIdx != -1 )
createArea *= 2;
int deltaIdx = this->randomPositionDeltaIdx++;
if ( deltaIdx >= 50 )
deltaIdx = 0;
posOffset.x += createArea * this->randomPositionDelta[deltaIdx].x;
posOffset.z += createArea * this->randomPositionDelta[deltaIdx].z;
posOffset.y += createArea * (2*getRandomFloat() - 1.0);
if ( breakBoxIronIdx != -1 )
posOffset.y *= 0.5;
if ( kibakoContainIdx != -1 )
posOffset.y *= 0.7;
if ( drop.findIndex("BarrelBomb") != -1 )
{
posOffset.x = fmaxf(posOffset.x, 1.5);
posOffset.z = fmaxf(posOffset.z, 1.5);
}
}
// More position calculation
const float norm = posOffset.norm();
if ( norm > 0.0 )
{
posOffset.x /= norm;
posOffset.y /= norm;
posOffset.z /= norm;
}
Vec3 createPos = this->actor->position.toVec3() + posOffset;
Vec3 createPos2 = this->actor->position.toVec3() + posOffset;
// stuff that calculates positions
sub_710072E280(&createPos, &createPos2, &posOffset, norm - 1.0);
if ( ActorInfoData::sInstance->hasTagByName(drop.c_str(), Tag_AmiiboFitGround) )
{
Vec3 offset{0.0, -1.0, 0.0};
sub_710072E280(&createPos, &createPos, &offset, 30.0);
createPos.y += 0.1;
}
else
{
createPos -= fminf(norm, 0.5) * posOffset;
}
return createPos;
};
const Vec3 createPos = getCreatePos();
params.add(createPos, "@P");
params.addBoolAITree(true, "IsAmiibo");
// if the Amiibo key exists in the "drops" dictionary
if ( ActorInfoData::sInstance->isAmiiboDrop(drop.c_str(), "Amiibo") )
{
if ( this->dropListType == AmiiboDropListType::Normal )
params.add("Amiibo", "DropTable");
else
params.add("Amiibo_After", "DropTable");
}
const char* finalActorName = nullptr;
Vec3 rotate;
if ( spawnInTBox )
{
this->field_A78 = 1;
params.add(drop, "DropActor");
if ( isWeaponActorProfile(drop) )
params.add(2, "SharpWeaponJudgeType");
v92 = sead::Random::getU32(sead::GlobalRandom::sInstance);
rotate.z = 0.05;
rotate.x = 0.0;
rotate.y = getRandomFloat() * 2 * PI;
params.add(rotate, "@R");
finalActorName = "TBox_Field_Iron";
}
else
{
if ( ActorInfoData::sInstance->hasTagByName(drop.c_str(), Tag_AmiiboFitGround)
|| ActorInfoData::sInstance->hasTagByName(drop.c_str(), Tag_Rupee) )
{
rotate.x = 0.0;
rotate.y = getRandomFloat() * 2 * PI;
rotate.z = 0.0;
}
else
{
rotate.x = getRandomFloat() * 2 * PI;
rotate.y = getRandomFloat() * 2 * PI;
rotate.z = getRandomFloat() * 2 * PI;
}
params.add(rotate, "@R");
finalActorName = drop.c_str();
}
ActorCreator::sInstance->requestActorCreate(finalActorName,
ActorHeapUtil::sInstance->forBaseProcDualHeap, procHandle, params, 0LL, 1);
}
void __fastcall AI_Action_ItemAmiiboCreateFromDropTable::doSpawn(AI_Action_ItemAmiiboCreateFromDropTable *this, sead::SafeStringBase *drop, BaseProcHandle *procHandle, Vec3 *a4)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
if ( *(unsigned __int8 *)drop->cstr != (unsigned __int8)sead::SafeStringBase<char>::cNullChar )
{
v8 = ActorInfoData::sInstance;
drop->vptr->assureTermination(drop);
if ( !ActorInfoData::hasTagByName(v8, drop->cstr, Tag_Important) )
goto LABEL_139;
flag.vptr = (sead::SafeStringBase::vtable *)v106.dataStart;
createPos2.str.vptr = &sead::SafeString::vt;
createPos2.str.cstr = "IsGet_";
flag.vptr = (sead::SafeStringBase::vtable *)&`vtable for'sead::BufferedSafeStringBase<char>;
*(_DWORD *)&v106.items = 0x80;
sead::BufferedSafeStringBase<char>::assureTerminationImpl_((sead::BufferedSafeString *)&flag);
v9 = flag.cstr;
flag.vptr = (sead::SafeStringBase::vtable *)&off_71023619F8;
createPos2.str.vptr->assureTermination((const sead::SafeString *)&createPos2);
v10 = createPos2.str.cstr;
if ( v9 != createPos2.str.cstr )
{
createPos2.str.vptr->assureTermination((const sead::SafeString *)&createPos2);
v11 = 0LL;
v12 = createPos2.str.cstr + 1;
while ( createPos2.str.cstr[v11] != sead::SafeStringBase<char>::cNullChar )
{
if ( v12[v11] == sead::SafeStringBase<char>::cNullChar )
{
LODWORD(v11) = v11 + 1;
break;
}
if ( v12[v11 + 1] == sead::SafeStringBase<char>::cNullChar )
{
LODWORD(v11) = v11 + 2;
break;
}
v13 = v11 + 2;
v11 += 3LL;
if ( v13 >= 0x80000 )
{
LODWORD(v11) = 0;
break;
}
}
if ( (signed int)v11 >= *(_DWORD *)&v106.items )
LODWORD(v11) = *(_DWORD *)&v106.items - 1;
v14 = (signed int)v11;
memcpy_0(v9, v10, (signed int)v11);
v9[v14] = sead::SafeStringBase<char>::cNullChar;
}
v15 = flag.cstr;
flag.vptr = &sead::FixedSafeString80::vt;
sead::BufferedSafeStringBase<char>::assureTerminationImpl_((sead::BufferedSafeString *)&flag);
v16 = 0LL;
v17 = flag.cstr + 1;
while...
v19 = v16 & ~((signed int)v16 >> 0x1F);
drop->vptr->assureTermination(drop);
v20 = 0LL;
v21 = drop->cstr + 1;
while...
if...
if...
LOBYTE(createPos2.str.vptr) = 0;
if ( !GameDataMgr::sInstance
|| (TriggerParam::getBoolByKey_0(
*GameDataMgr::sInstance->param.param,
(bool *)&createPos2,
&flag,
GameDataMgr::sInstance->param.x),
!LOBYTE(createPos2.str.vptr)) )
{
LABEL_139:
flag.vptr = &sead::SafeString::vt;
flag.cstr = "GameRomHorse";
if ( sead::SafeStringBase<char>::findIndex(drop, &flag) != 0xFFFFFFFF )
setFlag_IsAmiiboDrop_GameRomHorseItem(1LL, 0);
flag.vptr = (sead::SafeStringBase::vtable *)&ActorInstParams::vt;
flag.cstr = 0LL;
ActorInstParams::Buf::clear(&v106);
v25 = (float *)this->_._.actor.player;
v26 = v25[0xE9];
v27 = v25[0xED];
v28 = v25[0xF1];
posOffset.vec3.x = 0.0;
posOffset.str.vptr = 0LL;
AI_Action_ItemAmiiboCreateFromDropTable::calculateCreatePosition(this, (Vec3 *)&posOffset);
v29 = posOffset.vec3.x + a4->x;
posOffset.vec3.x = posOffset.vec3.x + a4->x;
posOffset.vec3.y = posOffset.vec3.y + a4->y;
v30 = a4->z;
actorInfoData = ActorInfoData::sInstance;
v32 = posOffset.vec3.z + v30;
posOffset.vec3.z = posOffset.vec3.z + v30;
drop->vptr->assureTermination(drop);
isAmiiboTreasure = ActorInfoData::hasTagByName(actorInfoData, drop->cstr, Tag_AmiiboTreasure);
bdrop = this->_._.actor.player->_._._.g.a.actorParam->_.dropTable;
isAmiiboTreasure_ = isAmiiboTreasure;
if ( bdrop )
{
resourceNameC = bdrop->resourceName.s._.cstr;
if ( sead::SafeStringBase<char>::cNullChar == 0x41 )
{
LABEL_44:
v37 = "tem_Ore_";
v38 = drop->cstr;
v39 = 'I';
v40 = drop->cstr;
while ( (unsigned __int8)*v40 == v39 )
{
v41 = (unsigned __int8)*v37++;
v39 = v41;
++v40;
if ( v41 == (unsigned __int8)sead::SafeStringBase<char>::cNullChar )
{
v42 = "tem_Ore_A";
v43 = 0x49;
while ( (unsigned __int8)*v38 == v43 )
{
v44 = (unsigned __int8)*v42++;
v43 = v44;
++v38;
if ( v44 == (unsigned __int8)sead::SafeStringBase<char>::cNullChar )
goto isOreA;
}
isAmiiboTreasure_ = 0;
break;
}
}
}
else
{
v45 = "ctor/DropTable/Item_Amiibo_DropTable_012";
v46 = 0x41;
v47 = resourceNameC;
while ( (unsigned __int8)*v47 == v46 )
{
v48 = (unsigned __int8)*v45++;
v46 = v48;
++v47;
if ( v48 == (unsigned __int8)sead::SafeStringBase<char>::cNullChar )
{
if ( sead::SafeStringBase<char>::cNullChar != 0x49 )
goto LABEL_44;
break;
}
}
}
isOreA:
if ( sead::SafeStringBase<char>::cNullChar == 0x41 )
{
LABEL_60:
v49 = drop->cstr;
v50 = "bj_BombArrow";
v51 = 0x4F;
while ( (unsigned __int8)*v49 == v51 )
{
v52 = (unsigned __int8)*v50++;
v51 = v52;
++v49;
if ( v52 == (unsigned __int8)sead::SafeStringBase<char>::cNullChar )
{
isAmiiboTreasure_ = 0;
if ( sead::SafeStringBase<char>::cNullChar == 0x41 )
goto LABEL_71;
goto LABEL_75;
}
}
}
else
{
v53 = "ctor/DropTable/Item_Amiibo_DropTable_013";
v54 = 'A';
v55 = resourceNameC;
while ( (unsigned __int8)*v55 == v54 )
{
v56 = (unsigned __int8)*v53++;
v54 = v56;
++v55;
if ( v56 == (unsigned __int8)sead::SafeStringBase<char>::cNullChar )
{
if ( sead::SafeStringBase<char>::cNullChar != 'O' )
goto LABEL_60;
isAmiiboTreasure_ = 0;
break;
}
}
}
if ( sead::SafeStringBase<char>::cNullChar == 0x41 )
{
LABEL_71:
v57 = drop->cstr;
v58 = "bj_ElectricArrow";
v59 = 0x4F;
while ( (unsigned __int8)*v57 == v59 )
{
v60 = (unsigned __int8)*v58++;
v59 = v60;
++v57;
if ( v60 == (unsigned __int8)sead::SafeStringBase<char>::cNullChar )
goto LABEL_81;
}
}
else
{
LABEL_75:
v61 = "ctor/DropTable/Item_Amiibo_DropTable_015";
v62 = 0x41;
while ( (unsigned __int8)*resourceNameC == v62 )
{
v63 = (unsigned __int8)*v61++;
v62 = v63;
++resourceNameC;
if ( v63 == (unsigned __int8)sead::SafeStringBase<char>::cNullChar )
{
if ( sead::SafeStringBase<char>::cNullChar != 0x4F )
goto LABEL_71;
goto LABEL_81;
}
}
}
if ( !isAmiiboTreasure_ )
goto LABEL_81;
}
else if ( !isAmiiboTreasure )
{
LABEL_81:
createPos2.str.vptr = &sead::SafeString::vt;
createPos2.str.cstr = "Obj_BreakBoxIron";
v64 = sead::SafeStringBase<char>::findIndex(drop, &createPos2.str);
createPos2.str.vptr = &sead::SafeString::vt;
createPos2.str.cstr = "Kibako_Contain";
v65 = sead::SafeStringBase<char>::findIndex(drop, &createPos2.str);
v66 = *this->createArea;
v67 = (unsigned __int8)this->amiiboRandomPosDeltaIdx[0];
v68 = v65;
this->amiiboRandomPosDeltaIdx[0] = v67 + 1;
if ( (v65 & v64) == 0xFFFFFFFF )
v69 = v66;
else
v69 = v66 + v66;
if ( (unsigned int)v67 >= 0x32 )
v67 = 0LL;
v70 = (AI_Action_ItemAmiiboCreateFromDropTable *)((char *)this + 8 * v67);
posOffset.vec3.x = posOffset.vec3.x + (float)(v69 * v70->randomFloats[0].field_0);
posOffset.vec3.z = posOffset.vec3.z + (float)(v69 * v70->randomFloats[0].field_4);
LODWORD(v71) = (sead::Random::getU32(sead::GlobalRandom::sInstance) >> 9) | 0x3F800000;
v72 = posOffset.vec3.y + (float)(v69 * (float)((float)((float)(v71 + -1.0) + (float)(v71 + -1.0)) + -1.0));
if ( v64 != 0xFFFFFFFF )
v72 = v72 * 0.5;
if ( v68 != 0xFFFFFFFF )
v72 = v72 * 0.7;
createPos2.str.vptr = &sead::SafeString::vt;
posOffset.vec3.y = v72;
createPos2.str.cstr = "BarrelBomb";
v73 = sead::SafeStringBase<char>::findIndex(drop, &createPos2.str);
v29 = posOffset.vec3.x;
if ( v73 == 0xFFFFFFFF )
{
v32 = posOffset.vec3.z;
v74 = 0;
}
else
{
v29 = fmaxf(posOffset.vec3.x, 1.5);
v32 = fmaxf(posOffset.vec3.z, 1.5);
v74 = 0;
posOffset.vec3.x = v29;
posOffset.vec3.z = v32;
}
LABEL_94:
v75 = posOffset.vec3.y;
v76 = sqrtf((float)(v32 * v32) + (float)((float)(v29 * v29) + (float)(v75 * v75)));
if ( v76 > 0.0 )
{
v29 = v29 * (float)(1.0 / v76);
v75 = posOffset.vec3.y * (float)(1.0 / v76);
v32 = v32 * (float)(1.0 / v76);
posOffset.vec3.x = v29;
posOffset.vec3.y = posOffset.vec3.y * (float)(1.0 / v76);
posOffset.vec3.z = v32;
}
createPos.x = v26 + (float)(v76 * v29);
createPos.y = v27 + (float)(v76 * v75);
createPos2.vec3.x = v26 + v29;
createPos2.vec3.y = v27 + v75;
createPos.z = v28 + (float)(v76 * v32);
createPos2.vec3.z = v28 + v32;
somePositionCalc(&createPos, (Vec3 *)&createPos2, (Vec3 *)&posOffset, v76 + -1.0);
v77 = ActorInfoData::sInstance;
drop->vptr->assureTermination(drop);
if ( ActorInfoData::hasTagByName(v77, drop->cstr, Tag_AmiiboFitGround) )
{
createPos2.vec3.x = -0.0;
createPos2.vec3.y = -1.0;
createPos2.vec3.z = -0.0;
somePositionCalc(&createPos, &createPos, (Vec3 *)&createPos2, 30.0);
createPos.y = createPos.y + 0.1;
}
else
{
v78 = fminf(v76, 0.5);
createPos.x = createPos.x - (float)(v78 * posOffset.vec3.x);
createPos.y = createPos.y - (float)(v78 * posOffset.vec3.y);
createPos.z = createPos.z - (float)(v78 * posOffset.vec3.z);
}
createPos2.str.vptr = &sead::SafeString::vt;
createPos2.str.cstr = "@P";
ActorInstParams::Buf::add(&v106, &createPos, &createPos2.str, 0xC, ActorInstParams::EntryType_Vec3);
createPos2.str.vptr = &sead::SafeString::vt;
createPos2.str.cstr = "IsAmiibo";
ActorInstParams::addBoolAITree((ActorInstParams *)&flag, 1, &createPos2.str);
v79 = ActorInfoData::sInstance;
drop->vptr->assureTermination(drop);
if ( !ActorInfoData::isAmiiboDrop(v79, drop->cstr, "Amiibo") )
goto LABEL_119;
v80 = this->dropListType;
if ( (unsigned int)(v80 - 1) >= 2 )
{
if ( v80 )
{
LABEL_119:
if ( v74 )
{
this->field_A78 = 1;
createPos2.str.vptr = &sead::SafeString::vt;
createPos2.str.cstr = "DropActor";
drop->vptr->assureTermination(drop);
v85 = drop->cstr;
drop->vptr->assureTermination(drop);
v86 = 0LL;
v87 = drop->cstr + 1;
while ( drop->cstr[v86] != sead::SafeStringBase<char>::cNullChar )
{
if ( v87[v86] == sead::SafeStringBase<char>::cNullChar )
{
LODWORD(v86) = v86 + 1;
break;
}
if ( v87[v86 + 1] == sead::SafeStringBase<char>::cNullChar )
{
LODWORD(v86) = v86 + 2;
break;
}
v88 = v86 + 2;
v86 += 3LL;
if ( v88 >= 0x80000 )
{
LODWORD(v86) = 0;
break;
}
}
ActorInstParams::Buf::add(&v106, v85, &createPos2.str, v86 + 1, ActorInstParams::EntryType_String);
if ( isWeaponActorProfile(drop) )
{
createPos2.str.vptr = &sead::SafeString::vt;
createPos2.str.cstr = "SharpWeaponJudgeType";
LODWORD(value.x) = 2;
ActorInstParams::Buf::add(&v106, &value, &createPos2.str, 4, 0);
}
v92 = sead::Random::getU32(sead::GlobalRandom::sInstance);
createPos2.str.vptr = &sead::SafeString::vt;
value.z = 0.05;
value.x = 0.0;
value.y = (float)(COERCE_FLOAT((v92 >> 9) | 0x3F800000) + -1.0) * 6.2832;
createPos2.str.cstr = "@R";
ActorInstParams::Buf::add(&v106, &value, &createPos2.str, 0xC, ActorInstParams::EntryType_Vec3);
v94 = ActorCreator::sInstance;
v95 = ActorHeapUtil::sInstance->forBaseProcDualHeap;
v96 = "TBox_Field_Iron";
}
else
{
v89 = ActorInfoData::sInstance;
drop->vptr->assureTermination(drop);
if ( ActorInfoData::hasTagByName(v89, drop->cstr, Tag_AmiiboFitGround)
|| (v90 = ActorInfoData::sInstance,
drop->vptr->assureTermination(drop),
ActorInfoData::hasTagByName(v90, drop->cstr, Tag_Rupee)) )
{
v91 = sead::Random::getU32(sead::GlobalRandom::sInstance);
value.x = 0.0;
createPos2.str.vptr = &sead::SafeString::vt;
value.y = (float)(COERCE_FLOAT((v91 >> 9) | 0x3F800000) + -1.0) * 6.2832;
value.z = 0.0;
}
else
{
v97 = (float)(COERCE_FLOAT((sead::Random::getU32(sead::GlobalRandom::sInstance) >> 9) | 0x3F800000)
+ -1.0)
* 6.2832;
v98 = (float)(COERCE_FLOAT((sead::Random::getU32(sead::GlobalRandom::sInstance) >> 9) | 0x3F800000)
+ -1.0)
* 6.2832;
v99 = sead::Random::getU32(sead::GlobalRandom::sInstance);
value.x = v97;
value.y = v98;
createPos2.str.vptr = &sead::SafeString::vt;
value.z = (float)(COERCE_FLOAT((v99 >> 9) | 0x3F800000) + -1.0) * 6.2832;
}
createPos2.str.cstr = "@R";
ActorInstParams::Buf::add(&v106, &value, &createPos2.str, 0xC, ActorInstParams::EntryType_Vec3);
v100 = ActorCreator::sInstance;
drop->vptr->assureTermination(drop);
v96 = drop->cstr;
v95 = ActorHeapUtil::sInstance->forBaseProcDualHeap;
v94 = v100;
}
ActorCreator::requestActorCreate(v94, v96, v95, procHandle, (ActorInstParams *)&flag, 0LL, 1);
return;
}
createPos2.str.vptr = &sead::SafeString::vt;
v82 = 0LL;
createPos2.str.cstr = "DropTable";
while ( aAmiibo[v82] != sead::SafeStringBase<char>::cNullChar )
{
if ( v82 >= 0x80000 )
{
LODWORD(v82) = 0;
break;
}
if ( aAmiibo[v82 + 1] == sead::SafeStringBase<char>::cNullChar )
{
LODWORD(v82) = v82 + 1;
break;
}
v82 += 2LL;
}
v83 = v82 + 1;
v84 = "Amiibo";
}
else
{
createPos2.str.vptr = &sead::SafeString::vt;
createPos2.str.cstr = "DropTable";
for ( i = 0LL; aAmiiboAfter[i] != sead::SafeStringBase<char>::cNullChar; i += 2LL )
{
if ( i >= 0x80000 )
{
LODWORD(i) = 0;
break;
}
if ( aAmiiboAfter[i + 1] == sead::SafeStringBase<char>::cNullChar )
{
LODWORD(i) = i + 1;
break;
}
}
v83 = i + 1;
v84 = "Amiibo_After";
}
ActorInstParams::Buf::add(&v106, v84, &createPos2.str, v83, ActorInstParams::EntryType_String);
goto LABEL_119;
}
v74 = 1;
goto LABEL_94;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment