animate ball from pedestal
add camera shake and rumble when auto portals open
This commit is contained in:
parent
3d3c012fea
commit
7a5267195d
|
@ -210,12 +210,13 @@ That will generate the rom at `/build/portal64.z64`
|
|||
<br />
|
||||
|
||||
## Current New Feature TODO List
|
||||
- [ ] valve intro
|
||||
- [ ] figure out why portals somtimes are in front of window
|
||||
- [ ] optimize static culling
|
||||
- [ ] jump animation
|
||||
- [ ] crashed when dying in test chamber 05 when hit by pellet in mid air while touching a portal
|
||||
- [ ] rumble pak support
|
||||
- [ ] pausing while glados is speaking can end her speech early
|
||||
- [x] valve intro
|
||||
- [x] polish up subtitles
|
||||
- [x] more sound settings
|
||||
- [x] add desk chairs and monitors
|
||||
|
|
|
@ -1180,10 +1180,11 @@ materials:
|
|||
|
||||
gDPSetRenderMode:
|
||||
flags:
|
||||
- Z_CMP
|
||||
- IM_RD
|
||||
- CVG_DST_FULL
|
||||
- FORCE_BL
|
||||
- ZMODE_OPA
|
||||
- ZMODE_XLU
|
||||
blend:
|
||||
- G_BL_CLR_IN
|
||||
- G_BL_A_IN
|
||||
|
@ -1194,8 +1195,8 @@ materials:
|
|||
color: ["1", "PRIMITIVE", "TEXEL0", "PRIMITIVE"]
|
||||
alpha: ["TEXEL0", "PRIMITIVE", "SHADE", "0"]
|
||||
gSPGeometryMode:
|
||||
clear: [G_CULL_BACK, G_CULL_FRONT, G_ZBUFFER]
|
||||
set: [G_FOG]
|
||||
clear: [G_CULL_BACK, G_CULL_FRONT]
|
||||
set: [G_FOG, G_ZBUFFER]
|
||||
|
||||
lab_monitor_screen_text:
|
||||
gDPSetTile:
|
||||
|
|
|
@ -32,19 +32,19 @@ cutscenes:
|
|||
portal_loop:
|
||||
- open_portal portal_exit 0
|
||||
- label loop_start
|
||||
- open_portal portal_0 1
|
||||
- open_portal portal_0 1 pedestal
|
||||
- delay 3
|
||||
- point_pedestal portal_1
|
||||
- delay 4
|
||||
- open_portal portal_1 1
|
||||
- open_portal portal_1 1 pedestal
|
||||
- delay 3 2
|
||||
- point_pedestal portal_2
|
||||
- delay 4 2
|
||||
- open_portal portal_2 1
|
||||
- open_portal portal_2 1 pedestal
|
||||
- delay 3 3
|
||||
- point_pedestal portal_3
|
||||
- delay 4 3
|
||||
- open_portal portal_3 1
|
||||
- open_portal portal_3 1 pedestal
|
||||
- delay 3 4
|
||||
- point_pedestal portal_0
|
||||
- delay 4 4
|
||||
|
|
|
@ -38,15 +38,15 @@ cutscenes:
|
|||
- q_sound 07_PART2_SUCCESS_1 CH_GLADOS PORTAL_07_PART2_SUCCESS_1
|
||||
portal_loop:
|
||||
- label loop_start
|
||||
- open_portal portal_0 0
|
||||
- delay 3.001
|
||||
- open_portal portal_0 0 pedestal
|
||||
- delay 3
|
||||
- point_pedestal portal_1
|
||||
- delay 4.001
|
||||
- open_portal portal_1 0
|
||||
- delay 4
|
||||
- open_portal portal_1 0 pedestal
|
||||
- delay 3 2
|
||||
- point_pedestal portal_2
|
||||
- delay 4 2
|
||||
- open_portal portal_2 0
|
||||
- open_portal portal_2 0 pedestal
|
||||
- delay 3 3
|
||||
- point_pedestal portal_3
|
||||
- delay 4 3
|
||||
|
|
|
@ -7,9 +7,22 @@
|
|||
#include "../util/memory.h"
|
||||
#include "../savefile/checkpoint.h"
|
||||
#include "../locales/locales.h"
|
||||
#include "../controls/rumble_pak.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
unsigned char gPortalOpenRumbleData[] = {
|
||||
0xFF, 0xE9, 0x99,
|
||||
};
|
||||
|
||||
struct RumblePakWave gPortalOpenRumbleWave = {
|
||||
.samples = gPortalOpenRumbleData,
|
||||
.sampleCount = 12,
|
||||
.samplesPerTick = 1 << 5,
|
||||
};
|
||||
|
||||
#define RUMBLE_PLAYER_DISTANCE 8.0f
|
||||
|
||||
struct CutsceneRunner* gRunningCutscenes;
|
||||
struct CutsceneRunner* gUnusedRunners;
|
||||
u64 gTriggeredCutscenes;
|
||||
|
@ -154,6 +167,12 @@ void cutsceneRunnerStartStep(struct CutsceneRunner* runner) {
|
|||
case CutsceneStepTypeOpenPortal:
|
||||
{
|
||||
struct Location* location = &gCurrentLevel->locations[step->openPortal.locationIndex];
|
||||
|
||||
if (step->openPortal.fromPedestal && gCurrentLevel->pedestalCount) {
|
||||
struct Vector3 fireFrom = gScene.pedestals[0].transform.position;
|
||||
fireFrom.y += 0.75f;
|
||||
portalGunFireWorld(&gScene.portalGun, step->openPortal.portalIndex, &fireFrom, &location->transform.position, gScene.pedestals[0].roomIndex);
|
||||
} else {
|
||||
struct Ray firingRay;
|
||||
struct Vector3 transformUp;
|
||||
firingRay.origin = location->transform.position;
|
||||
|
@ -162,6 +181,12 @@ void cutsceneRunnerStartStep(struct CutsceneRunner* runner) {
|
|||
vector3Negate(&transformUp, &transformUp);
|
||||
vector3AddScaled(&location->transform.position, &firingRay.dir, -0.1f, &firingRay.origin);
|
||||
sceneFirePortal(&gScene, &firingRay, &transformUp, step->openPortal.portalIndex, location->roomIndex, 0, 0);
|
||||
|
||||
if (vector3DistSqrd(&location->transform.position, &gScene.player.lookTransform.position) < RUMBLE_PLAYER_DISTANCE * RUMBLE_PLAYER_DISTANCE) {
|
||||
gScene.player.shakeTimer = 0.5f;
|
||||
rumblePakClipPlay(&gPortalOpenRumbleWave);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CutsceneStepTypeClosePortal:
|
||||
|
|
|
@ -90,7 +90,8 @@ struct CutsceneStep {
|
|||
} waitForChannel;
|
||||
struct {
|
||||
u16 locationIndex;
|
||||
u16 portalIndex;
|
||||
u8 portalIndex;
|
||||
u8 fromPedestal;
|
||||
} openPortal;
|
||||
struct {
|
||||
u16 portalIndex;
|
||||
|
|
|
@ -262,18 +262,17 @@ void playerShakeUpdate(struct Player* player) {
|
|||
if (player->shakeTimer > 0.0f){
|
||||
player->shakeTimer -= FIXED_DELTA_TIME;
|
||||
|
||||
float max = SHAKE_DISTANCE;
|
||||
float min = -SHAKE_DISTANCE;
|
||||
float x;
|
||||
x = ((float)rand()/(float)(RAND_MAX));
|
||||
x = min + x * ( max - min );
|
||||
player->lookTransform.position.x += x;
|
||||
x = ((float)rand()/(float)(RAND_MAX));
|
||||
x = min + x * ( max - min );
|
||||
player->lookTransform.position.y += x;
|
||||
x = ((float)rand()/(float)(RAND_MAX));
|
||||
x = min + x * ( max - min );
|
||||
player->lookTransform.position.z += x;
|
||||
float magnitude = 1.0f;
|
||||
|
||||
if (player->shakeTimer < 1.0f) {
|
||||
magnitude = player->shakeTimer;
|
||||
}
|
||||
|
||||
float max = SHAKE_DISTANCE * magnitude;
|
||||
float min = -SHAKE_DISTANCE * magnitude;
|
||||
player->lookTransform.position.x += randomInRangef(min, max);
|
||||
player->lookTransform.position.y += randomInRangef(min, max);
|
||||
player->lookTransform.position.z += randomInRangef(min, max);
|
||||
|
||||
if (player->shakeTimer < 0.0f){
|
||||
player->shakeTimer = 0.0f;
|
||||
|
|
|
@ -114,7 +114,7 @@ void portalBallRender(struct PortalGunProjectile* projectile, struct RenderState
|
|||
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Camera* fromCamera) {
|
||||
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Camera* fromCamera, int portalGunVisible) {
|
||||
struct MaterialState materialState;
|
||||
materialStateInit(&materialState, DEFAULT_INDEX);
|
||||
|
||||
|
@ -130,6 +130,10 @@ void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* render
|
|||
portalBallRender(projectile, renderState, &materialState, &fromCamera->transform, i);
|
||||
}
|
||||
|
||||
if (!portalGunVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
portalGun->rigidBody.transform.scale = gOneVec;
|
||||
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
|
||||
|
||||
|
@ -267,6 +271,24 @@ void portalGunFire(struct PortalGun* portalGun, int portalIndex, struct Ray* ray
|
|||
|
||||
portalTrailPlay(&projectile->trail, &fireFrom, &hit.at);
|
||||
}
|
||||
|
||||
|
||||
void portalGunFireWorld(struct PortalGun* portalGun, int portalIndex, struct Vector3* from, struct Vector3* to, int roomIndex) {
|
||||
struct PortalGunProjectile* projectile = &portalGun->projectiles[portalIndex];
|
||||
vector3Sub(to, from, &projectile->positionDirection.dir);
|
||||
vector3Normalize(&projectile->positionDirection.dir, &projectile->positionDirection.dir);
|
||||
projectile->positionDirection.origin = *from;
|
||||
projectile->roomIndex = roomIndex;
|
||||
projectile->playerUp = gUp;
|
||||
|
||||
projectile->distance = 0.0f;
|
||||
projectile->maxDistance = sqrtf(vector3DistSqrd(from, to));
|
||||
|
||||
projectile->effectOffset = gZeroVec;
|
||||
|
||||
portalTrailPlay(&projectile->trail, from, to);
|
||||
}
|
||||
|
||||
int portalGunIsFiring(struct PortalGun* portalGun){
|
||||
if (portalGun->shootTotalAnimationTimer > 0.0f){
|
||||
return 1;
|
||||
|
|
|
@ -39,9 +39,10 @@ struct PortalGun {
|
|||
void portalGunInit(struct PortalGun* portalGun, struct Transform* at);
|
||||
// void portalGunDummyRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState);
|
||||
void portalGunUpdate(struct PortalGun* portalGun, struct Player* player);
|
||||
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Camera* fromCamera);
|
||||
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Camera* fromCamera, int portalGunVisible);
|
||||
|
||||
void portalGunFire(struct PortalGun* portalGun, int portalIndex, struct Ray* ray, struct Vector3* playerUp, int roomIndex);
|
||||
void portalGunFireWorld(struct PortalGun* portalGun, int portalIndex, struct Vector3* from, struct Vector3* to, int roomIndex);
|
||||
int portalGunIsFiring(struct PortalGun* portalGun);
|
||||
|
||||
#endif
|
|
@ -306,9 +306,7 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr
|
|||
|
||||
// contactSolverDebugDraw(&gContactSolver, renderState);
|
||||
|
||||
if (scene->portalGun.portalGunVisible){
|
||||
portalGunRenderReal(&scene->portalGun, renderState, &scene->camera);
|
||||
}
|
||||
portalGunRenderReal(&scene->portalGun, renderState, &scene->camera, scene->portalGun.portalGunVisible);
|
||||
|
||||
gDPPipeSync(renderState->dl++);
|
||||
gDPSetRenderMode(renderState->dl++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
|
||||
|
|
|
@ -120,6 +120,7 @@ local function generate_cutscene_step(cutscene_name, step, step_index, label_loc
|
|||
result.openPortal = {
|
||||
find_location_index(step.args[1]),
|
||||
step.args[2] == "1" and 1 or 0,
|
||||
step.args[3] == "pedestal" and 1 or 0
|
||||
}
|
||||
elseif step.command == "close_portal" and #step.args >= 1 then
|
||||
result.type = sk_definition_writer.raw('CutsceneStepTypeClosePortal')
|
||||
|
|
Loading…
Reference in a new issue