Merge pull request #295 from westonCoder/portal-funneling

Added Portal Funneling
This commit is contained in:
lambertjamesd 2023-10-16 07:58:53 -06:00 committed by GitHub
commit 945855ca24
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 96 additions and 4 deletions

View file

@ -57,12 +57,14 @@ void gameplayOptionsInit(struct GameplayOptions* gameplayOptions) {
gameplayOptions->movingPortals = menuBuildCheckbox(&gDejaVuSansFont, "Movable Portals", GAMEPLAY_X + 8, GAMEPLAY_Y + 8);
gameplayOptions->wideScreen = menuBuildCheckbox(&gDejaVuSansFont, "Wide Screen", GAMEPLAY_X + 8, GAMEPLAY_Y + 28);
gameplayOptions->portalFunnel = menuBuildCheckbox(&gDejaVuSansFont, "Portal Funneling", GAMEPLAY_X + 8, GAMEPLAY_Y + 48);
gameplayOptions->portalRenderDepthText = menuBuildText(&gDejaVuSansFont, "Portal Render Depth", GAMEPLAY_X + 8, GAMEPLAY_Y + 48);
gameplayOptions->portalRenderDepth = menuBuildSlider(GAMEPLAY_X + 126, GAMEPLAY_Y + 48, 126, SCROLL_TICKS);
gameplayOptions->portalRenderDepthText = menuBuildText(&gDejaVuSansFont, "Portal Render Depth", GAMEPLAY_X + 8, GAMEPLAY_Y + 68);
gameplayOptions->portalRenderDepth = menuBuildSlider(GAMEPLAY_X + 126, GAMEPLAY_Y + 68, 126, SCROLL_TICKS);
gameplayOptions->movingPortals.checked = (gSaveData.controls.flags & ControlSaveMoveablePortals) != 0;
gameplayOptions->wideScreen.checked = (gSaveData.controls.flags & ControlSaveWideScreen) != 0;
gameplayOptions->portalFunnel.checked = (gSaveData.controls.flags & ControlSavePortalFunneling) != 0;
gameplayOptions->portalRenderDepth.value = (float)(gSaveData.controls.portalRenderDepth / PORTAL_RENDER_DEPTH_MAX);
gameplayOptions->render_depth = (0xFFFF/PORTAL_RENDER_DEPTH_MAX)* gSaveData.controls.portalRenderDepth;
gameplayOptionsHandleSlider(&gameplayOptions->render_depth, &gameplayOptions->portalRenderDepth.value);
@ -103,7 +105,6 @@ enum MenuDirection gameplayOptionsUpdate(struct GameplayOptions* gameplayOptions
gSaveData.controls.flags &= ~ControlSaveMoveablePortals;
}
}
break;
case GameplayOptionWideScreen:
if (controllerGetButtonDown(0, A_BUTTON)) {
@ -116,11 +117,24 @@ enum MenuDirection gameplayOptionsUpdate(struct GameplayOptions* gameplayOptions
gSaveData.controls.flags &= ~ControlSaveWideScreen;
}
}
case GameplayOptionPortalRenderDepth:
break;
case GameplayOptionPortalFunneling:
if (controllerGetButtonDown(0, A_BUTTON)) {
gameplayOptions->portalFunnel.checked = !gameplayOptions->portalFunnel.checked;
soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL);
if (gameplayOptions->portalFunnel.checked) {
gSaveData.controls.flags |= ControlSavePortalFunneling;
} else {
gSaveData.controls.flags &= ~ControlSavePortalFunneling;
}
}
break;
case GameplayOptionPortalRenderDepth:
gameplayOptionsHandleSlider(&gameplayOptions->render_depth, &gameplayOptions->portalRenderDepth.value);
gSaveData.controls.portalRenderDepth = (int)((gameplayOptions->render_depth * (1.0f/0xFFFF) * PORTAL_RENDER_DEPTH_MAX));
break;
break;
}
@ -153,6 +167,9 @@ void gameplayOptionsRender(struct GameplayOptions* gameplayOptions, struct Rende
gSPDisplayList(renderState->dl++, gameplayOptions->wideScreen.outline);
renderState->dl = menuCheckboxRender(&gameplayOptions->wideScreen, renderState->dl);
gSPDisplayList(renderState->dl++, gameplayOptions->portalFunnel.outline);
renderState->dl = menuCheckboxRender(&gameplayOptions->portalFunnel, renderState->dl);
gSPDisplayList(renderState->dl++, gameplayOptions->portalRenderDepth.back);
renderState->dl = menuSliderRender(&gameplayOptions->portalRenderDepth, renderState->dl);
@ -167,6 +184,9 @@ void gameplayOptionsRender(struct GameplayOptions* gameplayOptions, struct Rende
menuSetRenderColor(renderState, gameplayOptions->selectedItem == GameplayOptionWideScreen, &gSelectionGray, &gColorWhite);
gSPDisplayList(renderState->dl++, gameplayOptions->wideScreen.text);
menuSetRenderColor(renderState, gameplayOptions->selectedItem == GameplayOptionPortalFunneling, &gSelectionGray, &gColorWhite);
gSPDisplayList(renderState->dl++, gameplayOptions->portalFunnel.text);
gDPPipeSync(renderState->dl++);
menuSetRenderColor(renderState, gameplayOptions->selectedItem == GameplayOptionPortalRenderDepth, &gSelectionGray, &gColorWhite);
gSPDisplayList(renderState->dl++, gameplayOptions->portalRenderDepthText);

View file

@ -7,6 +7,7 @@
enum GameplayOption {
GameplayOptionMovingPortals,
GameplayOptionWideScreen,
GameplayOptionPortalFunneling,
GameplayOptionPortalRenderDepth,
GameplayOptionCount,
@ -15,6 +16,7 @@ enum GameplayOption {
struct GameplayOptions {
struct MenuCheckbox movingPortals;
struct MenuCheckbox wideScreen;
struct MenuCheckbox portalFunnel;
struct MenuSlider portalRenderDepth;
Gfx* portalRenderDepthText;
short selectedItem;

View file

@ -32,6 +32,13 @@
#define PLAYER_COLLISION_LAYERS (COLLISION_LAYERS_TANGIBLE | COLLISION_LAYERS_FIZZLER | COLLISION_LAYERS_BLOCK_BALL)
#define FUNNEL_DAMPENING_CONSTANT 0.32f
#define FUNNEL_CENTERING_CONSTANT 0.05f
#define FUNNEL_ACCEPTABLE_CENTERED_DISTANCE 0.1f
#define FUNNEL_MAX_DIST 1.2f
#define FUNNEL_MIN_DOWN_VEL -2.25f
#define FUNNEL_MAX_HORZ_VEL 7.0f
struct Vector3 gGrabDistance = {0.0f, 0.0f, -1.5f};
struct Vector3 gCameraOffset = {0.0f, 0.0f, 0.0f};
@ -573,6 +580,61 @@ void playerUpdateFooting(struct Player* player, float maxStandDistance) {
}
}
void playerPortalFunnel(struct Player* player) {
if (gCollisionScene.portalTransforms[0] != NULL && gCollisionScene.portalTransforms[1] != NULL){
struct Transform portal0transform = *gCollisionScene.portalTransforms[0];
struct Transform portal1transform = *gCollisionScene.portalTransforms[1];
struct Transform targetPortalTransform;
//remove z from distance calc
portal0transform.position.y = player->body.transform.position.y;
portal1transform.position.y = player->body.transform.position.y;
float portal0dist = vector3DistSqrd(&player->body.transform.position, &portal0transform.position);
float portal1dist = vector3DistSqrd(&player->body.transform.position, &portal1transform.position);
float targetDist;
if (portal0dist < portal1dist){
targetPortalTransform = portal0transform;
targetDist = portal0dist;
} else{
targetPortalTransform = portal1transform;
targetDist = portal1dist;
}
struct Vector3 straightForward;
vector3Negate(&gForward, &straightForward);
quatMultVector(&targetPortalTransform.rotation, &straightForward, &straightForward);
if (fabsf(straightForward.y) > 0.999f) {
if (!(player->flags & PlayerFlagsGrounded) &&
targetDist < (FUNNEL_MAX_DIST*FUNNEL_MAX_DIST) &&
player->body.velocity.y < FUNNEL_MIN_DOWN_VEL &&
fabsf(player->body.velocity.x) < FUNNEL_MAX_HORZ_VEL &&
fabsf(player->body.velocity.z) < FUNNEL_MAX_HORZ_VEL){
if (player->body.transform.position.x < targetPortalTransform.position.x - FUNNEL_ACCEPTABLE_CENTERED_DISTANCE){
player->body.velocity.x += (FUNNEL_DAMPENING_CONSTANT * (targetPortalTransform.position.x - player->body.transform.position.x));
}
else if (player->body.transform.position.x > targetPortalTransform.position.x + FUNNEL_ACCEPTABLE_CENTERED_DISTANCE){
player->body.velocity.x -= (FUNNEL_DAMPENING_CONSTANT * (player->body.transform.position.x - targetPortalTransform.position.x));
}
else{
player->body.velocity.x *= FUNNEL_CENTERING_CONSTANT;
}
if (player->body.transform.position.z < targetPortalTransform.position.z - FUNNEL_ACCEPTABLE_CENTERED_DISTANCE){
player->body.velocity.z += (FUNNEL_DAMPENING_CONSTANT * (targetPortalTransform.position.z - player->body.transform.position.z));
}
else if (player->body.transform.position.z > targetPortalTransform.position.z + FUNNEL_ACCEPTABLE_CENTERED_DISTANCE){
player->body.velocity.z -= (FUNNEL_DAMPENING_CONSTANT * (player->body.transform.position.z - targetPortalTransform.position.z));
}
else{
player->body.velocity.z *= FUNNEL_CENTERING_CONSTANT;
}
}
}
}
}
void playerUpdate(struct Player* player) {
struct Vector3 forward;
struct Vector3 right;
@ -841,6 +903,12 @@ void playerUpdate(struct Player* player) {
}
}
if (gSaveData.controls.flags & ControlSavePortalFunneling){
playerPortalFunnel(player);
}
// player not moving on ground
if ((player->flags & PlayerFlagsGrounded) && (player->body.velocity.x == 0) && (player->body.velocity.z == 0)){
player->stepTimer = STEP_TIME;

View file

@ -91,6 +91,7 @@ void savefileNew() {
controllerSetDefaultSource();
gSaveData.controls.flags = 0;
gSaveData.controls.flags |= ControlSavePortalFunneling;
gSaveData.controls.sensitivity = 0x4000;
gSaveData.controls.acceleration = 0x4000;
gSaveData.controls.deadzone = 0x4000;

View file

@ -41,6 +41,7 @@ enum ControlSaveFlags {
ControlSaveSubtitlesEnabled = (1 << 5),
ControlSaveAllSubtitlesEnabled = (1 << 6),
ControlSavePortalFunneling = (1 << 7),
ControlSaveMoveablePortals = (1 << 8),
ControlSaveWideScreen = (1 << 9),
};