mirror of
https://github.com/zeldaret/oot.git
synced 2025-07-05 15:34:41 +00:00
Fix misc 19 (#1488)
* "bgs sword" -> "biggoron sword" * Animation_ChangeImpl: last arg is `ANIMTAPER_` enum * TransitionTileStatus -> state * Tiny gbi.h formatting fixups * some cleanup on floormaster * misc float ops cleanup * sunsSongState = SUNSSONG_INACTIVE * continueFlag == CS_CMD_STOP * fix few camera names inconsistency * textual 0 padding? not on my lawn * libultra: construct address from end of dmem rather than oob from imem * more free1 -> 2 fixup
This commit is contained in:
parent
b4c97ce17e
commit
542012efa6
22 changed files with 146 additions and 152 deletions
|
@ -61,7 +61,7 @@ s32 func_800BB2B4(Vec3f* pos, f32* roll, f32* fov, CutsceneCameraPoint* point, s
|
|||
}
|
||||
*curFrame += advance;
|
||||
if (*curFrame >= 1) {
|
||||
if (point[++*keyFrame + 3].continueFlag == -1) {
|
||||
if (point[++*keyFrame + 3].continueFlag == CS_CMD_STOP) {
|
||||
*keyFrame = 0;
|
||||
ret = true;
|
||||
}
|
||||
|
|
|
@ -487,12 +487,12 @@ Vec3s* Camera_GetBgCamFuncDataUnderPlayer(Camera* camera, u16* bgCamCount) {
|
|||
CollisionPoly* floorPoly;
|
||||
s32 pad;
|
||||
s32 bgId;
|
||||
PosRot playerPosShape;
|
||||
PosRot playerPosRot;
|
||||
|
||||
Actor_GetWorldPosShapeRot(&playerPosShape, &camera->player->actor);
|
||||
playerPosShape.pos.y += Player_GetHeight(camera->player);
|
||||
Actor_GetWorldPosShapeRot(&playerPosRot, &camera->player->actor);
|
||||
playerPosRot.pos.y += Player_GetHeight(camera->player);
|
||||
|
||||
if (BgCheck_EntityRaycastDown3(&camera->play->colCtx, &floorPoly, &bgId, &playerPosShape.pos) == BGCHECK_Y_MIN) {
|
||||
if (BgCheck_EntityRaycastDown3(&camera->play->colCtx, &floorPoly, &bgId, &playerPosRot.pos) == BGCHECK_Y_MIN) {
|
||||
// no floor
|
||||
return NULL;
|
||||
}
|
||||
|
@ -508,14 +508,14 @@ Vec3s* Camera_GetBgCamFuncDataUnderPlayer(Camera* camera, u16* bgCamCount) {
|
|||
* Returns the camera data index otherwise.
|
||||
*/
|
||||
s32 Camera_GetWaterBoxBgCamIndex(Camera* camera, f32* waterY) {
|
||||
PosRot playerPosShape;
|
||||
PosRot playerPosRot;
|
||||
WaterBox* waterBox;
|
||||
s32 bgCamIndex;
|
||||
|
||||
Actor_GetWorldPosShapeRot(&playerPosShape, &camera->player->actor);
|
||||
*waterY = playerPosShape.pos.y;
|
||||
Actor_GetWorldPosShapeRot(&playerPosRot, &camera->player->actor);
|
||||
*waterY = playerPosRot.pos.y;
|
||||
|
||||
if (!WaterBox_GetSurface1(camera->play, &camera->play->colCtx, playerPosShape.pos.x, playerPosShape.pos.z, waterY,
|
||||
if (!WaterBox_GetSurface1(camera->play, &camera->play->colCtx, playerPosRot.pos.x, playerPosRot.pos.z, waterY,
|
||||
&waterBox)) {
|
||||
// player's position is not in a water box.
|
||||
*waterY = BGCHECK_Y_MIN;
|
||||
|
@ -7144,29 +7144,29 @@ void Camera_Stub80058140(Camera* camera) {
|
|||
}
|
||||
|
||||
void Camera_InitDataUsingPlayer(Camera* camera, Player* player) {
|
||||
PosRot playerPosShape;
|
||||
PosRot playerPosRot;
|
||||
VecGeo eyeNextAtOffset;
|
||||
s32 bgId;
|
||||
Vec3f floorPos;
|
||||
Vec3f floorNorm;
|
||||
s32 upXZ;
|
||||
f32 playerToAtOffsetY;
|
||||
Vec3f* eye = &camera->eye;
|
||||
Vec3f* at = &camera->at;
|
||||
Vec3f* eyeNext = &camera->eyeNext;
|
||||
|
||||
Actor_GetWorldPosShapeRot(&playerPosShape, &player->actor);
|
||||
Actor_GetWorldPosShapeRot(&playerPosRot, &player->actor);
|
||||
playerToAtOffsetY = Player_GetHeight(player);
|
||||
camera->player = player;
|
||||
camera->playerPosRot = playerPosShape;
|
||||
camera->playerPosRot = playerPosRot;
|
||||
camera->dist = eyeNextAtOffset.r = 180.0f;
|
||||
camera->inputDir.y = playerPosShape.rot.y;
|
||||
camera->inputDir.y = playerPosRot.rot.y;
|
||||
eyeNextAtOffset.yaw = camera->inputDir.y - 0x7FFF;
|
||||
camera->inputDir.x = eyeNextAtOffset.pitch = 0x71C;
|
||||
camera->inputDir.z = 0;
|
||||
camera->camDir = camera->inputDir;
|
||||
camera->xzSpeed = 0.0f;
|
||||
camera->playerPosDelta.y = 0.0f;
|
||||
camera->at = playerPosShape.pos;
|
||||
camera->at = playerPosRot.pos;
|
||||
camera->at.y += playerToAtOffsetY;
|
||||
|
||||
camera->playerToAtOffset.x = 0;
|
||||
|
@ -7182,7 +7182,7 @@ void Camera_InitDataUsingPlayer(Camera* camera, Player* player) {
|
|||
camera->up.y = 1.0f;
|
||||
camera->up.x = upXZ;
|
||||
|
||||
if (Camera_GetFloorYNorm(camera, &floorPos, at, &bgId) != BGCHECK_Y_MIN) {
|
||||
if (Camera_GetFloorYNorm(camera, &floorNorm, at, &bgId) != BGCHECK_Y_MIN) {
|
||||
camera->bgId = bgId;
|
||||
}
|
||||
|
||||
|
|
|
@ -874,7 +874,7 @@ CameraModeValue sDataOnlyNullFlags[] = {
|
|||
*=====================================================================
|
||||
*/
|
||||
|
||||
CameraModeValue sSetPrerendFixedModeZTargetFriendlyData[] = {
|
||||
CameraModeValue sSetPreRendFixedModeZTargetFriendlyData[] = {
|
||||
CAM_FUNCDATA_INTERFACE_FIELD(CAM_INTERFACE_FIELD(CAM_LETTERBOX_MEDIUM, CAM_HUD_VISIBILITY_ALL, 0)),
|
||||
};
|
||||
|
||||
|
@ -884,15 +884,15 @@ CameraModeValue sSetPrerendFixedModeZTargetFriendlyData[] = {
|
|||
*=====================================================================
|
||||
*/
|
||||
|
||||
CameraModeValue sSetPrerendPivotModeNormalData[] = {
|
||||
CameraModeValue sSetPreRendPivotModeNormalData[] = {
|
||||
CAM_FUNCDATA_UNIQ7(60, CAM_INTERFACE_FIELD(CAM_LETTERBOX_NONE, CAM_HUD_VISIBILITY_ALL, 0)),
|
||||
};
|
||||
|
||||
CameraModeValue sSetPrerendPivotModeZTargetFriendlyData[] = {
|
||||
CameraModeValue sSetPreRendPivotModeZTargetFriendlyData[] = {
|
||||
CAM_FUNCDATA_UNIQ7(60, CAM_INTERFACE_FIELD(CAM_LETTERBOX_MEDIUM, CAM_HUD_VISIBILITY_ALL, 0)),
|
||||
};
|
||||
|
||||
CameraModeValue sSetPrerendPivotModeTalkData[] = {
|
||||
CameraModeValue sSetPreRendPivotModeTalkData[] = {
|
||||
CAM_FUNCDATA_KEEP0(30, 0, 4, CAM_INTERFACE_FIELD(CAM_LETTERBOX_LARGE, CAM_HUD_VISIBILITY_A_HEARTS_MAGIC_FORCE, 0)),
|
||||
};
|
||||
|
||||
|
@ -957,11 +957,11 @@ CameraModeValue sSetFree0ModeNormalData[] = {
|
|||
|
||||
/**
|
||||
*=====================================================================
|
||||
* Custom Data: FREE1 Setting
|
||||
* Custom Data: FREE2 Setting
|
||||
*=====================================================================
|
||||
*/
|
||||
|
||||
CameraModeValue sSetFree1ModeNormalData[] = {
|
||||
CameraModeValue sSetFree2ModeNormalData[] = {
|
||||
CAM_FUNCDATA_INTERFACE_FIELD(CAM_INTERFACE_FIELD(CAM_LETTERBOX_IGNORE, CAM_HUD_VISIBILITY_IGNORE, UNIQUE6_FLAG_0)),
|
||||
};
|
||||
|
||||
|
@ -1459,7 +1459,7 @@ CameraModeValue sSetDirectedYawModeTalkData[] = {
|
|||
*=====================================================================
|
||||
*/
|
||||
|
||||
CameraModeValue sNormal4ModeTalkData[] = {
|
||||
CameraModeValue sSetNormal4ModeTalkData[] = {
|
||||
CAM_FUNCDATA_KEEP3(-30, 70, 200, 40, 10, 0, 5, 70, 45, 50, 10,
|
||||
CAM_INTERFACE_FIELD(CAM_LETTERBOX_LARGE, CAM_HUD_VISIBILITY_A_HEARTS_MAGIC_FORCE,
|
||||
KEEPON3_FLAG_7 | KEEPON3_FLAG_5)),
|
||||
|
@ -1965,15 +1965,15 @@ CameraMode sCamSetPivotInFrontModes[] = {
|
|||
CameraMode sCamSetPreRendFixedModes[] = {
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_FIXD3, sDataOnlyNullFlags), // CAM_MODE_NORMAL
|
||||
{ CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_Z_PARALLEL
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_FIXD3, sSetPrerendFixedModeZTargetFriendlyData), // CAM_MODE_Z_TARGET_FRIENDLY
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_FIXD3, sSetPrerendFixedModeZTargetFriendlyData), // CAM_MODE_TALK
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_FIXD3, sSetPreRendFixedModeZTargetFriendlyData), // CAM_MODE_Z_TARGET_FRIENDLY
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_FIXD3, sSetPreRendFixedModeZTargetFriendlyData), // CAM_MODE_TALK
|
||||
};
|
||||
|
||||
CameraMode sCamSetPreRendPivotModes[] = {
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_UNIQ7, sSetPrerendPivotModeNormalData), // CAM_MODE_NORMAL
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_UNIQ7, sSetPreRendPivotModeNormalData), // CAM_MODE_NORMAL
|
||||
{ CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_Z_PARALLEL
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_UNIQ7, sSetPrerendPivotModeZTargetFriendlyData), // CAM_MODE_Z_TARGET_FRIENDLY
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_KEEP0, sSetPrerendPivotModeTalkData), // CAM_MODE_TALK
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_UNIQ7, sSetPreRendPivotModeZTargetFriendlyData), // CAM_MODE_Z_TARGET_FRIENDLY
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_KEEP0, sSetPreRendPivotModeTalkData), // CAM_MODE_TALK
|
||||
};
|
||||
|
||||
CameraMode sCamSetPreRendSideScrollModes[] = {
|
||||
|
@ -2005,15 +2005,15 @@ CameraMode sCamSetFree0Modes[] = {
|
|||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_UNIQ6, sSetFree0ModeNormalData), // CAM_MODE_NORMAL
|
||||
};
|
||||
|
||||
CameraMode sCamSetFree1Modes[] = {
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_UNIQ6, sSetFree1ModeNormalData), // CAM_MODE_NORMAL
|
||||
CameraMode sCamSetFree2Modes[] = {
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_UNIQ6, sSetFree2ModeNormalData), // CAM_MODE_NORMAL
|
||||
};
|
||||
|
||||
CameraMode sCamSetPivotCornerModes[] = {
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_FIXD2, sSetPivotCornerModeNormalData), // CAM_MODE_NORMAL
|
||||
};
|
||||
|
||||
CameraMode sCamSetPivotDivingModes[] = {
|
||||
CameraMode sCamSetPivotWaterSurfaceModes[] = {
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_UNIQ2, sSetPivotWaterSurfaceModeNormalData), // CAM_MODE_NORMAL
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_UNIQ2, sSetPivotWaterSurfaceModeZParallelData), // CAM_MODE_Z_PARALLEL
|
||||
};
|
||||
|
@ -2319,7 +2319,7 @@ CameraMode sCamSetNormal4Modes[] = {
|
|||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_NORM1, sSetNormal2and4ModeNormalData), // CAM_MODE_NORMAL
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_PARA1, sSetNormal0ModeZParallelData), // CAM_MODE_Z_PARALLEL
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_KEEP1, sSetNormal0ModeZTargetFriendlyData), // CAM_MODE_Z_TARGET_FRIENDLY
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_KEEP3, sNormal4ModeTalkData), // CAM_MODE_TALK
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_KEEP3, sSetNormal4ModeTalkData), // CAM_MODE_TALK
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_BATT1, sSetNormal1ModeZTargetUnfriendlyData), // CAM_MODE_Z_TARGET_UNFRIENDLY
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_JUMP2, sSetNormal0ModeWallClimbData), // CAM_MODE_WALL_CLIMB
|
||||
CAM_SETTING_MODE_ENTRY(CAM_FUNC_SUBJ3, sSetNormal0ModeFirstPersonData), // CAM_MODE_FIRST_PERSON
|
||||
|
@ -2374,9 +2374,9 @@ CameraSetting sCameraSettings[] = {
|
|||
{ { 0xC5000001 }, sCamSetStart0Modes }, // CAM_SET_START0
|
||||
{ { 0xC5000001 }, sCamSetStart1Modes }, // CAM_SET_START1
|
||||
{ { 0x05000001 }, sCamSetFree0Modes }, // CAM_SET_FREE0
|
||||
{ { 0x05000001 }, sCamSetFree1Modes }, // CAM_SET_FREE2
|
||||
{ { 0x05000001 }, sCamSetFree2Modes }, // CAM_SET_FREE2
|
||||
{ { 0x85000001 }, sCamSetPivotCornerModes }, // CAM_SET_PIVOT_CORNER
|
||||
{ { 0x05000003 }, sCamSetPivotDivingModes }, // CAM_SET_PIVOT_WATER_SURFACE
|
||||
{ { 0x05000003 }, sCamSetPivotWaterSurfaceModes }, // CAM_SET_PIVOT_WATER_SURFACE
|
||||
{ { 0xCE000001 }, sCamSetCs0Modes }, // CAM_SET_CS_0
|
||||
{ { 0x4E000001 }, sCamSetCsTwistedHallwayModes }, // CAM_SET_CS_TWISTED_HALLWAY
|
||||
{ { 0x05000009 }, sCamSetForestBirdsEyeModes }, // CAM_SET_FOREST_BIRDS_EYE
|
||||
|
|
|
@ -1609,7 +1609,7 @@ void Message_OpenText(PlayState* play, u16 textId) {
|
|||
// Increments text id based on piece of heart count, assumes the piece of heart text is all
|
||||
// in order and that you don't have more than the intended amount of heart pieces.
|
||||
textId += (gSaveContext.inventory.questItems & 0xF0000000 & 0xF0000000) >> QUEST_HEART_PIECE_COUNT;
|
||||
} else if (msgCtx->textId == 0xC && CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BGS)) {
|
||||
} else if (msgCtx->textId == 0xC && CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON)) {
|
||||
textId = 0xB; // Traded Giant's Knife for Biggoron Sword
|
||||
} else if (msgCtx->textId == 0xB4 && GET_EVENTCHKINF(EVENTCHKINF_96)) {
|
||||
textId = 0xB5; // Destroyed Gold Skulltula
|
||||
|
|
|
@ -1282,7 +1282,7 @@ void Interface_InitHorsebackArchery(PlayState* play) {
|
|||
}
|
||||
|
||||
void func_800849EC(PlayState* play) {
|
||||
gSaveContext.inventory.equipment |= OWNED_EQUIP_FLAG(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BGS);
|
||||
gSaveContext.inventory.equipment |= OWNED_EQUIP_FLAG(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON);
|
||||
gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE);
|
||||
|
||||
if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE)) {
|
||||
|
@ -1419,7 +1419,7 @@ u8 Item_Give(PlayState* play, u8 item) {
|
|||
gSaveContext.swordHealth = 8;
|
||||
|
||||
if (ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD) ==
|
||||
((1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) | (1 << EQUIP_INV_SWORD_BGS) |
|
||||
((1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) | (1 << EQUIP_INV_SWORD_BIGGORON) |
|
||||
(1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE))) {
|
||||
gSaveContext.inventory.equipment ^=
|
||||
OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE);
|
||||
|
|
|
@ -26,7 +26,7 @@ u8 sActionModelGroups[PLAYER_IA_MAX] = {
|
|||
PLAYER_MODELGROUP_10, // PLAYER_IA_FISHING_POLE
|
||||
PLAYER_MODELGROUP_SWORD, // PLAYER_IA_SWORD_MASTER
|
||||
PLAYER_MODELGROUP_SWORD, // PLAYER_IA_SWORD_KOKIRI
|
||||
PLAYER_MODELGROUP_BGS, // PLAYER_IA_SWORD_BGS
|
||||
PLAYER_MODELGROUP_BGS, // PLAYER_IA_SWORD_BIGGORON
|
||||
PLAYER_MODELGROUP_10, // PLAYER_IA_DEKU_STICK
|
||||
PLAYER_MODELGROUP_HAMMER, // PLAYER_IA_HAMMER
|
||||
PLAYER_MODELGROUP_BOW_SLINGSHOT, // PLAYER_IA_BOW
|
||||
|
@ -723,7 +723,7 @@ s32 Player_GetMeleeWeaponHeld(Player* this) {
|
|||
}
|
||||
|
||||
s32 Player_HoldsTwoHandedWeapon(Player* this) {
|
||||
if ((this->heldItemAction >= PLAYER_IA_SWORD_BGS) && (this->heldItemAction <= PLAYER_IA_HAMMER)) {
|
||||
if ((this->heldItemAction >= PLAYER_IA_SWORD_BIGGORON) && (this->heldItemAction <= PLAYER_IA_HAMMER)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
|
@ -731,7 +731,7 @@ s32 Player_HoldsTwoHandedWeapon(Player* this) {
|
|||
}
|
||||
|
||||
s32 Player_HoldsBrokenKnife(Player* this) {
|
||||
return (this->heldItemAction == PLAYER_IA_SWORD_BGS) && (gSaveContext.swordHealth <= 0.0f);
|
||||
return (this->heldItemAction == PLAYER_IA_SWORD_BIGGORON) && (gSaveContext.swordHealth <= 0.0f);
|
||||
}
|
||||
|
||||
s32 Player_ActionToBottle(Player* this, s32 itemAction) {
|
||||
|
@ -1666,7 +1666,7 @@ u32 func_80091738(PlayState* play, u8* segment, SkelAnime* skelAnime) {
|
|||
u8 sPauseModelGroupBySword[] = {
|
||||
PLAYER_MODELGROUP_SWORD, // PLAYER_SWORD_KOKIRI
|
||||
PLAYER_MODELGROUP_SWORD, // PLAYER_SWORD_MASTER
|
||||
PLAYER_MODELGROUP_BGS, // PLAYER_SWORD_BGS
|
||||
PLAYER_MODELGROUP_BGS, // PLAYER_SWORD_BIGGORON
|
||||
};
|
||||
|
||||
s32 Player_OverrideLimbDrawPause(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* arg) {
|
||||
|
@ -1836,7 +1836,7 @@ void Player_DrawPause(PlayState* play, u8* segment, SkelAnime* skelAnime, Vec3f*
|
|||
srcTable = gLinkPauseChildJointTable;
|
||||
}
|
||||
} else {
|
||||
if (sword == PLAYER_SWORD_BGS) {
|
||||
if (sword == PLAYER_SWORD_BIGGORON) {
|
||||
srcTable = gLinkPauseAdultBgsJointTable;
|
||||
} else if (shield != PLAYER_SHIELD_NONE) {
|
||||
srcTable = gLinkPauseAdultShieldJointTable;
|
||||
|
|
|
@ -315,7 +315,7 @@ static Inventory sDebugSaveInventory = {
|
|||
// equipment
|
||||
((((1 << EQUIP_INV_SWORD_KOKIRI) << (EQUIP_TYPE_SWORD * 4)) |
|
||||
((1 << EQUIP_INV_SWORD_MASTER) << (EQUIP_TYPE_SWORD * 4)) |
|
||||
((1 << EQUIP_INV_SWORD_BGS) << (EQUIP_TYPE_SWORD * 4))) |
|
||||
((1 << EQUIP_INV_SWORD_BIGGORON) << (EQUIP_TYPE_SWORD * 4))) |
|
||||
(((1 << EQUIP_INV_SHIELD_DEKU) << (EQUIP_TYPE_SHIELD * 4)) |
|
||||
((1 << EQUIP_INV_SHIELD_HYLIAN) << (EQUIP_TYPE_SHIELD * 4)) |
|
||||
((1 << EQUIP_INV_SHIELD_MIRROR) << (EQUIP_TYPE_SHIELD * 4))) |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue