Start work on portal gun projectile
This commit is contained in:
parent
5582be9a3b
commit
66f19b3cd5
2
Makefile
2
Makefile
|
@ -269,7 +269,7 @@ build/src/scene/clock.o: build/assets/models/dynamic_model_list.h
|
|||
build/src/scene/door.o: build/assets/materials/static.h build/assets/models/props/door_01.h build/assets/models/props/door_02.h build/assets/models/dynamic_animated_model_list.h
|
||||
build/src/scene/fizzler.o: build/assets/models/dynamic_model_list.h
|
||||
build/src/scene/pedestal.o: build/assets/materials/static.h build/assets/models/pedestal.h build/assets/models/dynamic_animated_model_list.h build/assets/models/portal_gun/w_portalgun.h
|
||||
build/src/scene/portal_gun.o: $(MODEL_HEADERS)
|
||||
build/src/scene/portal_gun.o: build/assets/materials/static.h $(MODEL_HEADERS)
|
||||
build/src/scene/portal_render.o: $(MODEL_HEADERS)
|
||||
build/src/scene/portal.o: $(MODEL_HEADERS)
|
||||
build/src/scene/render_plan.o: $(MODEL_HEADERS)
|
||||
|
|
|
@ -148,7 +148,7 @@ void splashParticleEffectPlay(struct SplashParticleEffect* effect, struct Splash
|
|||
}
|
||||
|
||||
effect->startPosition = *origin;
|
||||
effect->dynamicId = dynamicSceneAdd(effect, splashParticleEffectRender, &effect->startPosition, 10.0f);
|
||||
effect->dynamicId = dynamicSceneAdd(effect, splashParticleEffectRender, &effect->startPosition, 3.0f);
|
||||
}
|
||||
|
||||
void splashParticleEffectUpdate(struct SplashParticleEffect* effect) {
|
||||
|
|
|
@ -425,6 +425,7 @@ int collisionSceneRaycastOnlyDynamic(struct CollisionScene* scene, struct Ray* r
|
|||
int collisionSceneRaycast(struct CollisionScene* scene, int roomIndex, struct Ray* ray, int collisionLayers, float maxDistance, int passThroughPortals, struct RaycastHit* hit) {
|
||||
hit->distance = maxDistance;
|
||||
hit->throughPortal = NULL;
|
||||
hit->roomIndex = roomIndex;
|
||||
|
||||
int roomsToCheck = 5;
|
||||
|
||||
|
@ -441,6 +442,9 @@ int collisionSceneRaycast(struct CollisionScene* scene, int roomIndex, struct Ra
|
|||
|
||||
roomIndex = nextRoom;
|
||||
|
||||
// even on a miss, the raycast should report which room it ended up in
|
||||
hit->roomIndex = roomIndex;
|
||||
|
||||
--roomsToCheck;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
#include "../physics/collision_scene.h"
|
||||
#include "../physics/collision_cylinder.h"
|
||||
|
||||
#include "../../build/assets/models/grav_flare.h"
|
||||
#include "../../build/assets/models/portal_gun/v_portalgun.h"
|
||||
#include "../../build/assets/materials/static.h"
|
||||
|
||||
#define PORTAL_GUN_RECOIL_TIME (0.18f)
|
||||
|
||||
|
@ -43,6 +45,10 @@ void portalGunInit(struct PortalGun* portalGun, struct Transform* at){
|
|||
portalGun->portalGunVisible = 0;
|
||||
portalGun->shootAnimationTimer = 0.0;
|
||||
|
||||
portalGun->projectiles[0].dynamicId = -1;
|
||||
portalGun->projectiles[0].roomIndex = -1;
|
||||
portalGun->projectiles[1].dynamicId = -1;
|
||||
portalGun->projectiles[1].roomIndex = -1;
|
||||
}
|
||||
|
||||
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState){
|
||||
|
@ -59,22 +65,110 @@ void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* render
|
|||
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
void portalGunUpdate(struct PortalGun* portalGun, struct Player* player){
|
||||
if (player->flags & (PlayerHasFirstPortalGun | PlayerHasSecondPortalGun)){
|
||||
#define PORTAL_PROJECTILE_RADIUS 0.2f
|
||||
#define NO_HIT_DISTANCE 20.0f
|
||||
#define PORTAL_PROJECTILE_SPEED 10.0f
|
||||
#define MAX_PROJECTILE_DISTANCE 100.0f
|
||||
|
||||
void portalGunUpdate(struct PortalGun* portalGun, struct Player* player) {
|
||||
if (player->flags & (PlayerHasFirstPortalGun | PlayerHasSecondPortalGun)) {
|
||||
portalGun->portalGunVisible = 1;
|
||||
}else{
|
||||
} else {
|
||||
portalGun->portalGunVisible = 0;
|
||||
}
|
||||
|
||||
if (player->flags & PlayerJustShotPortalGun && portalGun->shootAnimationTimer <= 0.0f){
|
||||
if (player->flags & PlayerJustShotPortalGun && portalGun->shootAnimationTimer <= 0.0f) {
|
||||
portalGun->shootAnimationTimer = PORTAL_GUN_RECOIL_TIME;
|
||||
}
|
||||
|
||||
if (portalGun->shootAnimationTimer >= 0.0f){
|
||||
if (portalGun->shootAnimationTimer >= 0.0f) {
|
||||
portalGun->shootAnimationTimer -= FIXED_DELTA_TIME;
|
||||
if (portalGun->shootAnimationTimer <= 0.0f){
|
||||
portalGun->shootAnimationTimer = 0.0f;
|
||||
player->flags &= ~PlayerJustShotPortalGun;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
struct PortalGunProjectile* projectile = &portalGun->projectiles[i];
|
||||
|
||||
if (projectile->dynamicId == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
struct RaycastHit hit;
|
||||
|
||||
if (collisionSceneRaycast(&gCollisionScene, projectile->roomIndex, &projectile->positionDirection, COLLISION_LAYERS_STATIC | COLLISION_LAYERS_BLOCK_PORTAL, PORTAL_PROJECTILE_SPEED * FIXED_DELTA_TIME + 0.1f, 0, &hit)) {
|
||||
// TODO open portal
|
||||
dynamicSceneRemove(projectile->dynamicId);
|
||||
projectile->dynamicId = -1;
|
||||
} else {
|
||||
projectile->roomIndex = hit.roomIndex;
|
||||
}
|
||||
|
||||
vector3AddScaled(
|
||||
&projectile->positionDirection.origin,
|
||||
&projectile->positionDirection.dir,
|
||||
PORTAL_PROJECTILE_SPEED * FIXED_DELTA_TIME,
|
||||
&projectile->positionDirection.origin
|
||||
);
|
||||
projectile->distance += PORTAL_PROJECTILE_SPEED * FIXED_DELTA_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
void portalBallRender(void* data, struct RenderScene* renderScene, struct Transform* fromView) {
|
||||
struct PortalGunProjectile* projectile = (struct PortalGunProjectile*)data;
|
||||
struct Transform transform;
|
||||
|
||||
if (projectile->distance < projectile->maxDistance) {
|
||||
vector3AddScaled(
|
||||
&projectile->positionDirection.origin,
|
||||
&projectile->effectOffset,
|
||||
1.0f - projectile->distance / projectile->maxDistance,
|
||||
&transform.position
|
||||
);
|
||||
} else {
|
||||
transform.position = projectile->positionDirection.origin;
|
||||
}
|
||||
|
||||
transform.rotation = fromView->rotation;
|
||||
vector3Scale(&gOneVec, &transform.scale, PORTAL_PROJECTILE_RADIUS);
|
||||
|
||||
Mtx* mtx = renderStateRequestMatrices(renderScene->renderState, 1);
|
||||
|
||||
transformToMatrixL(&transform, mtx, SCENE_SCALE);
|
||||
|
||||
renderSceneAdd(renderScene, grav_flare_model_gfx, mtx, GRAV_FLARE_INDEX, &transform.position, NULL);
|
||||
}
|
||||
|
||||
struct Vector3 gPortalGunExit = {0.0f, 0.0f, 0.154008};
|
||||
|
||||
void portalGunFire(struct PortalGun* portalGun, int portalIndex, struct Ray* ray, struct Vector3* playerUp, int roomIndex) {
|
||||
struct PortalGunProjectile* projectile = &portalGun->projectiles[portalIndex];
|
||||
|
||||
struct RaycastHit hit;
|
||||
|
||||
if (!collisionSceneRaycast(&gCollisionScene, roomIndex, ray, COLLISION_LAYERS_STATIC | COLLISION_LAYERS_BLOCK_PORTAL, 1000000.0f, 0, &hit)) {
|
||||
vector3AddScaled(&ray->origin, &ray->dir, NO_HIT_DISTANCE, &hit.at);
|
||||
hit.distance = NO_HIT_DISTANCE;
|
||||
hit.normal = gZeroVec;
|
||||
hit.object = NULL;
|
||||
hit.roomIndex = roomIndex;
|
||||
hit.throughPortal = NULL;
|
||||
}
|
||||
|
||||
projectile->positionDirection = *ray;
|
||||
projectile->roomIndex = roomIndex;
|
||||
projectile->playerUp = *playerUp;
|
||||
|
||||
projectile->distance = 0.0f;
|
||||
projectile->maxDistance = hit.distance;
|
||||
|
||||
struct Vector3 fireFrom;
|
||||
transformPoint(&portalGun->rigidBody.transform, &gPortalGunExit, &fireFrom);
|
||||
vector3Sub(&fireFrom, &ray->origin, &projectile->effectOffset);
|
||||
|
||||
if (projectile->dynamicId == -1) {
|
||||
projectile->dynamicId = dynamicSceneAddViewDependant(projectile, portalBallRender, &fireFrom, 0.5f);
|
||||
}
|
||||
}
|
|
@ -10,11 +10,27 @@
|
|||
#include "../player/player.h"
|
||||
#include "../util/time.h"
|
||||
|
||||
struct PortalGunProjectile {
|
||||
struct Ray positionDirection;
|
||||
// used to orient portals that land on the floor or ceiling
|
||||
struct Vector3 playerUp;
|
||||
|
||||
struct Vector3 effectOffset;
|
||||
|
||||
float distance;
|
||||
float maxDistance;
|
||||
|
||||
short roomIndex;
|
||||
short dynamicId;
|
||||
};
|
||||
|
||||
struct PortalGun {
|
||||
struct CollisionObject collisionObject;
|
||||
struct RigidBody rigidBody;
|
||||
int portalGunVisible;
|
||||
float shootAnimationTimer;
|
||||
|
||||
struct PortalGunProjectile projectiles[2];
|
||||
};
|
||||
|
||||
void portalGunInit(struct PortalGun* portalGun, struct Transform* at);
|
||||
|
@ -22,4 +38,6 @@ void portalGunInit(struct PortalGun* portalGun, struct Transform* at);
|
|||
void portalGunUpdate(struct PortalGun* portalGun, struct Player* player);
|
||||
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState);
|
||||
|
||||
void portalGunFire(struct PortalGun* portalGun, int portalIndex, struct Ray* ray, struct Vector3* playerUp, int roomIndex);
|
||||
|
||||
#endif
|
|
@ -353,6 +353,7 @@ void sceneCheckPortals(struct Scene* scene) {
|
|||
|
||||
if (fireOrange && hasOrange && !playerIsGrabbing(&scene->player)) {
|
||||
sceneFirePortal(scene, &raycastRay, &playerUp, 0, scene->player.body.currentRoom, 1, 0);
|
||||
portalGunFire(&scene->portalGun, 0, &raycastRay, &playerUp, scene->player.body.currentRoom);
|
||||
scene->player.flags |= PlayerJustShotPortalGun;
|
||||
scene->last_portal_indx_shot=0;
|
||||
soundPlayerPlay(soundsPortalgunShoot[0], 1.0f, 1.0f, NULL, NULL);
|
||||
|
@ -360,6 +361,7 @@ void sceneCheckPortals(struct Scene* scene) {
|
|||
|
||||
if ((fireBlue || (!hasOrange && fireOrange)) && hasBlue && !playerIsGrabbing(&scene->player)) {
|
||||
sceneFirePortal(scene, &raycastRay, &playerUp, 1, scene->player.body.currentRoom, 1, 0);
|
||||
portalGunFire(&scene->portalGun, 1, &raycastRay, &playerUp, scene->player.body.currentRoom);
|
||||
scene->player.flags |= PlayerJustShotPortalGun;
|
||||
scene->last_portal_indx_shot=1;
|
||||
soundPlayerPlay(soundsPortalgunShoot[1], 1.0f, 1.0f, NULL, NULL);
|
||||
|
|
Loading…
Reference in a new issue