mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-20 10:37:37 -04:00
Merge pull request #295 from westonCoder/portal-funneling
Added Portal Funneling
This commit is contained in:
commit
945855ca24
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -41,6 +41,7 @@ enum ControlSaveFlags {
|
|||
ControlSaveSubtitlesEnabled = (1 << 5),
|
||||
ControlSaveAllSubtitlesEnabled = (1 << 6),
|
||||
|
||||
ControlSavePortalFunneling = (1 << 7),
|
||||
ControlSaveMoveablePortals = (1 << 8),
|
||||
ControlSaveWideScreen = (1 << 9),
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue