mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-19 22:27:36 -04:00
Work on elevator logic
This commit is contained in:
parent
474d8f9d76
commit
f2b6ebd66f
|
@ -1 +1 @@
|
|||
-r 90,0,0 -m assets/materials/static.skm.yaml -m assets/materials/elevator.skm.yaml --default-material default
|
||||
-r 180,0,0 -m assets/materials/static.skm.yaml -m assets/materials/elevator.skm.yaml --default-material default
|
|
@ -1 +1 @@
|
|||
-r 0,0,0 --mesh-collider
|
||||
-r 90,0,0 --mesh-collider
|
|
@ -1 +1 @@
|
|||
-r 0,0,0 -m assets/materials/static.skm.yaml -m assets/materials/elevator.skm.yaml --default-material default
|
||||
-r 90,0,0 -m assets/materials/static.skm.yaml -m assets/materials/elevator.skm.yaml --default-material default
|
Binary file not shown.
|
@ -440,6 +440,52 @@ void generateFizzlerDefinitions(
|
|||
levelDef.AddPrimitive("fizzlerCount", fizzlerCount);
|
||||
}
|
||||
|
||||
void generateElevatorDefinitions(
|
||||
const aiScene* scene,
|
||||
CFileDefinition& fileDefinition,
|
||||
StructureDataChunk& levelDef,
|
||||
const RoomGeneratorOutput& roomOutput,
|
||||
const DisplayListSettings& settings,
|
||||
Signals& signals,
|
||||
NodeGroups& nodeGroups) {
|
||||
|
||||
int elevatorCount = 0;
|
||||
std::unique_ptr<StructureDataChunk> elevators(new StructureDataChunk());
|
||||
|
||||
aiMatrix4x4 baseTransform = settings.CreateCollisionTransform();
|
||||
|
||||
for (auto& nodeInfo : nodeGroups.NodesForType("@elevator")) {
|
||||
if (nodeInfo.arguments.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::unique_ptr<StructureDataChunk> elevatorData(new StructureDataChunk());
|
||||
aiVector3D pos;
|
||||
aiQuaternion rot;
|
||||
aiVector3D scale;
|
||||
(baseTransform * nodeInfo.node->mTransformation).Decompose(scale, rot, pos);
|
||||
elevatorData->Add(std::unique_ptr<StructureDataChunk>(new StructureDataChunk(pos)));
|
||||
elevatorData->Add(std::unique_ptr<StructureDataChunk>(new StructureDataChunk(rot)));
|
||||
elevatorData->AddPrimitive(roomOutput.RoomForNode(nodeInfo.node));
|
||||
elevatorData->AddPrimitive(signals.SignalIndexForName(nodeInfo.arguments[0]));
|
||||
elevatorData->AddPrimitive(nodeInfo.arguments.size() >= 2 && nodeInfo.arguments[1] == "isExit" ? 1 : 0);
|
||||
|
||||
elevators->Add(std::move(elevatorData));
|
||||
++elevatorCount;
|
||||
}
|
||||
|
||||
std::string elevatorsName = fileDefinition.AddDataDefinition(
|
||||
"elevators",
|
||||
"struct ElevatorDefinition",
|
||||
true,
|
||||
"_geo",
|
||||
std::move(elevators)
|
||||
);
|
||||
|
||||
levelDef.AddPrimitive("elevators", elevatorsName);
|
||||
levelDef.AddPrimitive("elevatorCount", elevatorCount);
|
||||
}
|
||||
|
||||
void generateLevel(
|
||||
const aiScene* scene,
|
||||
CFileDefinition& fileDefinition,
|
||||
|
@ -481,5 +527,7 @@ void generateLevel(
|
|||
|
||||
generateFizzlerDefinitions(scene, fileDefinition, *levelDef, roomOutput, settings, nodeGroups);
|
||||
|
||||
generateElevatorDefinitions(scene, fileDefinition, *levelDef, roomOutput, settings, signals, nodeGroups);
|
||||
|
||||
fileDefinition.AddDefinition(std::unique_ptr<FileDefinition>(new DataFileDefinition("struct LevelDefinition", fileDefinition.GetUniqueName("level"), false, "_geo", std::move(levelDef))));
|
||||
}
|
|
@ -79,6 +79,24 @@ std::unique_ptr<StructureDataChunk> generateCutsceneStep(CutsceneStep& step, con
|
|||
setSignal->AddPrimitive(step.command == "set_signal" ? 1 : 0);
|
||||
result->Add("setSignal", std::move(setSignal));
|
||||
return result;
|
||||
} else if (step.command == "wait_for_signal" && step.args.size() >= 1) {
|
||||
result->AddPrimitive<const char*>("CutsceneStepTypeWaitForSignal");
|
||||
std::unique_ptr<StructureDataChunk> waitforSignal(new StructureDataChunk());
|
||||
waitforSignal->AddPrimitive(signals.SignalIndexForName(step.args[0]));
|
||||
result->Add("waitForSignal", std::move(waitforSignal));
|
||||
return result;
|
||||
} else if (step.command == "teleport_player" && step.args.size() >= 2) {
|
||||
short fromLocation = roomOutput.FindLocationIndex(step.args[0]);
|
||||
short toLocation = roomOutput.FindLocationIndex(step.args[1]);
|
||||
|
||||
if (fromLocation != -1 && toLocation != -1) {
|
||||
result->AddPrimitive<const char*>("CutsceneStepTypeTeleportPlayer");
|
||||
std::unique_ptr<StructureDataChunk> teleportPlayer(new StructureDataChunk());
|
||||
teleportPlayer->AddPrimitive(fromLocation);
|
||||
teleportPlayer->AddPrimitive(toLocation);
|
||||
result->Add("teleportPlayer", std::move(teleportPlayer));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result->AddPrimitive<const char*>("CutsceneStepTypeNoop");
|
||||
|
|
|
@ -35,18 +35,14 @@ void cutsceneRunnerStartStep(struct CutsceneRunner* runner) {
|
|||
case CutsceneStepTypeSetSignal:
|
||||
signalsSetDefault(step->setSignal.signalIndex, step->setSignal.signalValue);
|
||||
break;
|
||||
case CutsceneOpenElevator:
|
||||
gScene.elevators[step->openElevator.elevatorIndex].flags = (gScene.elevators[step->openElevator.elevatorIndex].flags & ~ElevatorFlagsIsLocked) | ElevatorFlagsReleasePlayer;
|
||||
break;
|
||||
case CutsceneTeleportPlayer:
|
||||
{
|
||||
case CutsceneStepTypeTeleportPlayer:
|
||||
rigidBodyTeleport(
|
||||
&gScene.player.body,
|
||||
&gCurrentLevel->locations[step->teleportPlayer.fromLocation].transform,
|
||||
&gCurrentLevel->locations[step->teleportPlayer.toLocation].transform,
|
||||
gCurrentLevel->locations[step->teleportPlayer.toLocation].roomIndex
|
||||
);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
@ -59,8 +55,8 @@ int cutsceneRunnerUpdateCurrentStep(struct CutsceneRunner* runner) {
|
|||
case CutsceneStepTypeDelay:
|
||||
runner->state.delay -= FIXED_DELTA_TIME;
|
||||
return runner->state.delay <= 0.0f;
|
||||
case CutsceneWaitForElevator:
|
||||
return (gScene.elevators[step->waitForElevator.elevatorIndex].flags & ElevatorFlagsContainsPlayer) != 0;
|
||||
case CutsceneStepTypeWaitForSignal:
|
||||
return signalsRead(step->waitForSignal.signalIndex);
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -29,10 +29,9 @@ enum CutsceneStepType {
|
|||
CutsceneStepTypeDelay,
|
||||
CutsceneStepTypeOpenPortal,
|
||||
CutsceneStepTypeSetSignal,
|
||||
CutsceneWaitForElevator,
|
||||
CutsceneOpenElevator,
|
||||
CutsceneTeleportPlayer,
|
||||
CutsceneLoadLevel,
|
||||
CutsceneStepTypeWaitForSignal,
|
||||
CutsceneStepTypeTeleportPlayer,
|
||||
CutsceneStepTypeLoadLevel,
|
||||
};
|
||||
|
||||
struct CutsceneStep {
|
||||
|
@ -54,11 +53,8 @@ struct CutsceneStep {
|
|||
u16 signalValue;
|
||||
} setSignal;
|
||||
struct {
|
||||
u16 elevatorIndex;
|
||||
} waitForElevator;
|
||||
struct {
|
||||
u16 elevatorIndex;
|
||||
} openElevator;
|
||||
u16 signalIndex;
|
||||
} waitForSignal;
|
||||
struct {
|
||||
u16 fromLocation;
|
||||
u16 toLocation;
|
||||
|
@ -114,6 +110,14 @@ struct FizzlerDefinition {
|
|||
short roomIndex;
|
||||
};
|
||||
|
||||
struct ElevatorDefinition {
|
||||
struct Vector3 position;
|
||||
struct Quaternion rotation;
|
||||
short roomIndex;
|
||||
short signalIndex;
|
||||
short isExit;
|
||||
};
|
||||
|
||||
struct LevelDefinition {
|
||||
struct CollisionObject* collisionQuads;
|
||||
struct StaticContentElement *staticContent;
|
||||
|
@ -130,6 +134,7 @@ struct LevelDefinition {
|
|||
struct SignalOperator* signalOperators;
|
||||
struct DecorDefinition* decor;
|
||||
struct FizzlerDefinition* fizzlers;
|
||||
struct ElevatorDefinition* elevators;
|
||||
short collisionQuadCount;
|
||||
short staticContentCount;
|
||||
short portalSurfaceCount;
|
||||
|
@ -140,6 +145,7 @@ struct LevelDefinition {
|
|||
short signalOperatorCount;
|
||||
short decorCount;
|
||||
short fizzlerCount;
|
||||
short elevatorCount;
|
||||
short startLocation;
|
||||
};
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#include "../physics/collision_scene.h"
|
||||
#include "../scene/dynamic_scene.h"
|
||||
#include "../physics/mesh_collider.h"
|
||||
#include "./signals.h"
|
||||
#include "../math/mathf.h"
|
||||
#include "../util/time.h"
|
||||
|
||||
#include "../../build/assets/models/props/round_elevator_collision.h"
|
||||
#include "../../build/assets/models/props/round_elevator_interior.h"
|
||||
|
@ -10,8 +13,9 @@
|
|||
#include "../../build/assets/materials/static.h"
|
||||
|
||||
#define AUTO_OPEN_DISTANCE 4.0f
|
||||
|
||||
#define INSIDE_DISTANCE 1.0f
|
||||
#define SAME_LEVEL_HEIGHT 3.0f
|
||||
#define OPEN_SPEED 2.0f
|
||||
|
||||
struct ColliderTypeData gElevatorColliderType = {
|
||||
CollisionShapeTypeMesh,
|
||||
|
@ -42,12 +46,7 @@ void elevatorRender(void* data, struct RenderScene* renderScene) {
|
|||
Mtx* armature = renderStateRequestMatrices(renderScene->renderState, PROPS_ROUND_ELEVATOR_DEFAULT_BONES_COUNT);
|
||||
|
||||
for (int i = 0; i < PROPS_ROUND_ELEVATOR_DEFAULT_BONES_COUNT; ++i) {
|
||||
if (elevator->flags & ElevatorFlagsIsOpen) {
|
||||
props_round_elevator_default_bones[i].position = gOpenPosition[i];
|
||||
} else {
|
||||
props_round_elevator_default_bones[i].position = gClosedPosition[i];
|
||||
}
|
||||
|
||||
vector3Lerp(&gClosedPosition[i], &gOpenPosition[i], elevator->openAmount, &props_round_elevator_default_bones[i].position);
|
||||
transformToMatrixL(&props_round_elevator_default_bones[i], &armature[i], 1.0f);
|
||||
}
|
||||
|
||||
|
@ -60,7 +59,11 @@ void elevatorRender(void* data, struct RenderScene* renderScene) {
|
|||
armature
|
||||
);
|
||||
|
||||
if (elevator->flags & (ElevatorFlagsIsOpen | ElevatorFlagsContainsPlayer)) {
|
||||
int insideCheck = elevator->flags & (ElevatorFlagsIsLocked | ElevatorFlagsIsExit);
|
||||
|
||||
int isPlayerInside = insideCheck == ElevatorFlagsIsLocked || insideCheck == ElevatorFlagsIsExit;
|
||||
|
||||
if (elevator->openAmount > 0.0f || isPlayerInside) {
|
||||
renderSceneAdd(
|
||||
renderScene,
|
||||
props_round_elevator_interior_model_gfx,
|
||||
|
@ -72,46 +75,69 @@ void elevatorRender(void* data, struct RenderScene* renderScene) {
|
|||
}
|
||||
}
|
||||
|
||||
void elevatorInit(struct Elevator* elevator) {
|
||||
void elevatorInit(struct Elevator* elevator, struct ElevatorDefinition* elevatorDefinition) {
|
||||
collisionObjectInit(&elevator->collisionObject, &gElevatorColliderType, &elevator->rigidBody, 1.0f, gElevatorCollisionLayers);
|
||||
rigidBodyMarkKinematic(&elevator->rigidBody);
|
||||
collisionSceneAddDynamicObject(&elevator->collisionObject);
|
||||
|
||||
elevator->rigidBody.transform.position.x = -10.0f;
|
||||
elevator->rigidBody.transform.position.z = 2.5f;
|
||||
elevator->rigidBody.transform.position = elevatorDefinition->position;
|
||||
elevator->rigidBody.transform.rotation = elevatorDefinition->rotation;
|
||||
|
||||
collisionObjectUpdateBB(&elevator->collisionObject);
|
||||
|
||||
elevator->dynamicId = dynamicSceneAdd(elevator, elevatorRender, &elevator->rigidBody.transform, 3.9f);
|
||||
elevator->flags = 0;
|
||||
elevator->flags = elevatorDefinition->isExit ? ElevatorFlagsIsExit : 0;
|
||||
elevator->openAmount = 0.0f;
|
||||
elevator->roomIndex = elevatorDefinition->roomIndex;
|
||||
elevator->signalIndex = elevatorDefinition->signalIndex;
|
||||
}
|
||||
|
||||
void elevatorUpdate(struct Elevator* elevator, struct Player* player) {
|
||||
struct Vector3 offset;
|
||||
vector3Sub(&elevator->rigidBody.transform.position, &player->lookTransform.position, &offset);
|
||||
|
||||
float verticalDistance = fabsf(offset.y);
|
||||
offset.y = 0.0f;
|
||||
|
||||
float horizontalDistance = vector3MagSqrd(&offset);
|
||||
|
||||
int inRange = horizontalDistance < AUTO_OPEN_DISTANCE * AUTO_OPEN_DISTANCE;
|
||||
int inside = horizontalDistance < INSIDE_DISTANCE * INSIDE_DISTANCE;
|
||||
int inRange = horizontalDistance < AUTO_OPEN_DISTANCE * AUTO_OPEN_DISTANCE && verticalDistance < SAME_LEVEL_HEIGHT;
|
||||
int inside = horizontalDistance < INSIDE_DISTANCE * INSIDE_DISTANCE && verticalDistance < SAME_LEVEL_HEIGHT;
|
||||
|
||||
if (inside) {
|
||||
elevator->flags |= ElevatorFlagsContainsPlayer;
|
||||
player->body.currentRoom = RIGID_BODY_NO_ROOM;
|
||||
int shouldBeOpen;
|
||||
int shouldLock;
|
||||
|
||||
if (elevator->flags & ElevatorFlagsIsExit) {
|
||||
shouldBeOpen = signalsRead(elevator->signalIndex);
|
||||
shouldLock = !inRange && (elevator->flags & ElevatorFlagsHasHadPlayer) != 0;
|
||||
} else {
|
||||
shouldBeOpen = inRange && !inside;
|
||||
shouldLock = inside;
|
||||
|
||||
if (inside || (elevator->flags & ElevatorFlagsIsLocked) != 0) {
|
||||
signalsSend(elevator->signalIndex);
|
||||
}
|
||||
}
|
||||
|
||||
int shouldBeOpen = inRange && (elevator->flags & ElevatorFlagsContainsPlayer) == 0;
|
||||
if (inside) {
|
||||
elevator->flags |= ElevatorFlagsHasHadPlayer;
|
||||
}
|
||||
|
||||
if (shouldLock) {
|
||||
elevator->flags |= ElevatorFlagsIsLocked;
|
||||
}
|
||||
|
||||
if ((elevator->flags & ElevatorFlagsIsLocked) != 0) {
|
||||
shouldBeOpen = 0;
|
||||
}
|
||||
|
||||
if (shouldBeOpen) {
|
||||
props_round_elevator_collision_collider.children[PROPS_ROUND_ELEVATOR_COLLISION_DOOR_RIGHT_COLLISION_INDEX].collisionLayers = 0;
|
||||
props_round_elevator_collision_collider.children[PROPS_ROUND_ELEVATOR_COLLISION_DOOR_LEFT_COLLISION_INDEX].collisionLayers = 0;
|
||||
|
||||
elevator->flags |= ElevatorFlagsIsOpen;
|
||||
} else {
|
||||
props_round_elevator_collision_collider.children[PROPS_ROUND_ELEVATOR_COLLISION_DOOR_RIGHT_COLLISION_INDEX].collisionLayers = gElevatorCollisionLayers;
|
||||
props_round_elevator_collision_collider.children[PROPS_ROUND_ELEVATOR_COLLISION_DOOR_LEFT_COLLISION_INDEX].collisionLayers = gElevatorCollisionLayers;
|
||||
|
||||
elevator->flags &= ~ElevatorFlagsIsOpen;
|
||||
}
|
||||
|
||||
elevator->openAmount = mathfMoveTowards(elevator->openAmount, shouldBeOpen ? 1.0f : 0.0f, OPEN_SPEED * FIXED_DELTA_TIME);
|
||||
}
|
|
@ -4,12 +4,12 @@
|
|||
#include "../math/transform.h"
|
||||
#include "../physics/collision_object.h"
|
||||
#include "../player/player.h"
|
||||
#include "../levels/level_definition.h"
|
||||
|
||||
enum ElevatorFlags {
|
||||
ElevatorFlagsIsOpen = (1 << 0),
|
||||
ElevatorFlagsContainsPlayer = (1 << 1),
|
||||
ElevatorFlagsReleasePlayer = (1 << 2),
|
||||
ElevatorFlagsIsLocked = (1 << 3),
|
||||
ElevatorFlagsIsLocked = (1 << 0),
|
||||
ElevatorFlagsIsExit = (1 << 1),
|
||||
ElevatorFlagsHasHadPlayer = (1 << 2),
|
||||
};
|
||||
|
||||
struct Elevator {
|
||||
|
@ -17,9 +17,12 @@ struct Elevator {
|
|||
struct RigidBody rigidBody;
|
||||
short dynamicId;
|
||||
short flags;
|
||||
short signalIndex;
|
||||
short roomIndex;
|
||||
float openAmount;
|
||||
};
|
||||
|
||||
void elevatorInit(struct Elevator* elevator);
|
||||
void elevatorInit(struct Elevator* elevator, struct ElevatorDefinition* elevatorDefinition);
|
||||
|
||||
void elevatorUpdate(struct Elevator* elevator, struct Player* player);
|
||||
|
||||
|
|
|
@ -84,10 +84,10 @@ void sceneInit(struct Scene* scene) {
|
|||
fizzlerInit(&scene->fizzlers[i], &fizzlerTransform, fizzlerDef->width, fizzlerDef->height, fizzlerDef->roomIndex);
|
||||
}
|
||||
|
||||
scene->elevatorCount = 1;
|
||||
scene->elevatorCount = gCurrentLevel->elevatorCount;
|
||||
scene->elevators = malloc(sizeof(struct Elevator) * scene->elevatorCount);
|
||||
for (int i = 0; i < scene->elevatorCount; ++i) {
|
||||
elevatorInit(&scene->elevators[i]);
|
||||
elevatorInit(&scene->elevators[i], &gCurrentLevel->elevators[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue