mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 08:11:10 +02:00
152 lines
4.3 KiB
C++
152 lines
4.3 KiB
C++
// Game_Sphere.cpp
|
|
//
|
|
// pushable exploding sphere
|
|
|
|
#include "precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "prey_local.h"
|
|
|
|
|
|
|
|
CLASS_DECLARATION(hhMoveable, hhSphere)
|
|
EVENT( EV_Touch, hhSphere::Event_Touch )
|
|
END_CLASS
|
|
|
|
|
|
hhSphere::hhSphere() {
|
|
additionalAxis.Identity();
|
|
}
|
|
|
|
void hhSphere::Spawn(void) {
|
|
|
|
radius = (GetPhysics()->GetBounds()[1][0] - GetPhysics()->GetBounds()[0][0]) * 0.5f;
|
|
lastOrigin = GetPhysics()->GetOrigin();
|
|
additionalAxis.Identity();
|
|
CreateLight();
|
|
|
|
fl.takedamage = false;
|
|
BecomeActive(TH_THINK);
|
|
}
|
|
|
|
void hhSphere::Save( idSaveGame *savefile ) const {
|
|
savefile->WriteFloat( radius );
|
|
savefile->WriteVec3( lastOrigin );
|
|
savefile->WriteMat3( additionalAxis );
|
|
light.Save(savefile);
|
|
}
|
|
|
|
void hhSphere::Restore( idRestoreGame *savefile ) {
|
|
savefile->ReadFloat( radius );
|
|
savefile->ReadVec3( lastOrigin );
|
|
savefile->ReadMat3( additionalAxis );
|
|
light.Restore(savefile);
|
|
}
|
|
|
|
void hhSphere::CreateLight() {
|
|
if ( spawnArgs.GetBool("haslight") ) {
|
|
idStr light_shader = spawnArgs.GetString("mtr_light");
|
|
idVec3 light_color = spawnArgs.GetVector("light_color");
|
|
idVec3 light_frustum = spawnArgs.GetVector("light_frustum");
|
|
idVec3 light_offset = spawnArgs.GetVector("offset_light");
|
|
idVec3 light_target = spawnArgs.GetVector("offset_lighttarget");
|
|
|
|
idDict args;
|
|
idVec3 lightOrigin = GetPhysics()->GetOrigin() + light_offset * GetPhysics()->GetAxis();
|
|
light_target.Normalize();
|
|
idMat3 lightAxis = (light_target * GetPhysics()->GetAxis()).hhToMat3();
|
|
|
|
if ( light_shader.Length() ) {
|
|
args.Set( "texture", light_shader );
|
|
}
|
|
args.SetVector( "origin", lightOrigin );
|
|
args.Set ("angles", lightAxis.ToAngles().ToString());
|
|
args.SetVector( "_color", light_color );
|
|
args.SetVector( "light_target", lightAxis[0] * light_frustum.x );
|
|
args.SetVector( "light_right", lightAxis[1] * light_frustum.y );
|
|
args.SetVector( "light_up", lightAxis[2] * light_frustum.z );
|
|
light = ( idLight * )gameLocal.SpawnEntityType( idLight::Type, &args );
|
|
light->Bind(this, true);
|
|
light->SetLightParm( 6, 1.0f );
|
|
light->SetLightParm( SHADERPARM_TIMEOFFSET, -MS2SEC(gameLocal.time) );
|
|
}
|
|
}
|
|
|
|
void hhSphere::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location ) {
|
|
// skip idMoveable::Damage which handles damage differently
|
|
idEntity::Damage(inflictor, attacker, dir, damageDefName, damageScale, location);
|
|
}
|
|
|
|
|
|
void hhSphere::RollThink( void ) {
|
|
float movedDistance, angle;
|
|
idVec3 curOrigin, gravityNormal, dir;
|
|
|
|
bool wasAtRest = IsAtRest();
|
|
|
|
RunPhysics();
|
|
|
|
// only need to give the visual model an additional rotation if the physics were run
|
|
if ( !wasAtRest ) {
|
|
|
|
// current physics state
|
|
curOrigin = GetPhysics()->GetOrigin();
|
|
|
|
dir = curOrigin - lastOrigin;
|
|
float movedDistanceSquared = dir.LengthSqr();
|
|
|
|
// if the sphere moved
|
|
if ( movedDistanceSquared > 0.0f && movedDistanceSquared < 20.0f) {
|
|
|
|
gravityNormal = GetPhysics()->GetGravityNormal();
|
|
|
|
// movement since last frame
|
|
movedDistance = idMath::Sqrt( movedDistanceSquared );
|
|
dir *= 1.0f / movedDistance;
|
|
|
|
// Get local coordinate axes
|
|
idVec3 right = -dir.Cross(gravityNormal);
|
|
|
|
// Rotate about it proportional to the distance moved using axis/angle
|
|
angle = 180.0f * movedDistance / (radius*idMath::PI);
|
|
additionalAxis *= (idRotation( vec3_origin, right, angle).ToMat3());
|
|
}
|
|
|
|
// save state for next think
|
|
lastOrigin = curOrigin;
|
|
}
|
|
|
|
Present();
|
|
}
|
|
|
|
void hhSphere::Think() {
|
|
RollThink();
|
|
}
|
|
|
|
void hhSphere::ClientPredictionThink( void ) {
|
|
RollThink();
|
|
}
|
|
|
|
bool hhSphere::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) {
|
|
origin = vec3_origin;
|
|
axis = additionalAxis * GetPhysics()->GetAxis().Inverse();
|
|
return true;
|
|
}
|
|
|
|
void hhSphere::Event_Touch( idEntity *other, trace_t *trace ) {
|
|
if (spawnArgs.GetBool("walkthrough")) {
|
|
idVec3 otherVel = other->GetPhysics()->GetLinearVelocity();
|
|
float otherSpeed = otherVel.NormalizeFast();
|
|
if (otherSpeed > 50.0f) { // && GetPhysics()->IsAtRest()) {
|
|
idVec3 toSide = hhUtils::RandomSign() * other->GetAxis()[1];
|
|
idVec3 toMoveable = GetOrigin() - other->GetOrigin();
|
|
toMoveable.NormalizeFast();
|
|
idVec3 newVel = ( 3*otherVel + toSide + hhUtils::RandomVector() ) * (1.0f/5.0f);
|
|
newVel.z = 0.0f;
|
|
newVel.NormalizeFast();
|
|
newVel *= otherSpeed*1.5f;
|
|
GetPhysics()->SetLinearVelocity(newVel);
|
|
}
|
|
}
|
|
}
|