Serious-Engine/Sources/EntitiesMP/GravityMarker.es

178 lines
5.4 KiB
Erlang
Raw Normal View History

2016-03-12 01:20:51 +01:00
/* Copyright (c) 2002-2012 Croteam Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as published by
the Free Software Foundation
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
2016-03-11 14:57:17 +01:00
212
%{
#include "StdH.h"
%}
uses "EntitiesMP/Marker";
uses "EntitiesMP/GravityRouter";
enum GravityType {
0 LT_PARALLEL "Parallel",
1 LT_CENTRAL "Central",
2 LT_CYLINDRICAL "Cylindirical",
3 LT_TORUS "Torus",
};
class CGravityMarker: CMarker {
name "Gravity Marker";
thumbnail "Thumbnails\\GravityMarker.tbn";
features "IsImportant";
properties:
1 enum GravityType m_gtType "Type" 'Y' =LT_PARALLEL,
2 FLOAT m_fStrength "Strength" 'S' = 1,
3 RANGE m_rFallOff "FallOff" 'F' = 50,
4 RANGE m_rHotSpot "HotSpot" 'H' = 50,
5 RANGE m_rTorusR "Torus Radius" 'R' = 100,
10 FLOAT m_fAcc = 0,
11 FLOAT m_fSign = 1,
12 FLOAT m_fStep = 0,
20 ANGLE3D m_aForceDir "Forcefield Direction" 'F' = ANGLE3D(0,0,0),
21 FLOAT m_fForceA "Forcefield Acceleration" = 0.0f,
22 FLOAT m_fForceV "Forcefield Velocity" = 0.0f,
23 FLOAT3D m_vForceDir = FLOAT3D(1,0,0),
components:
1 model MODEL_MARKER "Models\\Editor\\GravityMarker.mdl",
2 texture TEXTURE_MARKER "Models\\Editor\\GravityMarker.tex"
functions:
// find strength at given distance
inline FLOAT StrengthAtDistance(FLOAT fDistance)
{
FLOAT fStrength = (m_rFallOff-fDistance)*m_fStep;
return Clamp(fStrength, 0.0f, m_fAcc);
}
/* Get force type name, return empty string if not used. */
const CTString &GetForceName(INDEX i)
{
return m_strName;
}
/* Get force in given point. */
void GetForce(INDEX i, const FLOAT3D &vPoint,
CForceStrength &fsGravity, CForceStrength &fsField)
{
const FLOATmatrix3D &m = GetRotationMatrix();
switch (m_gtType) {
case LT_PARALLEL: {
fsGravity.fs_vDirection(1) = -m(1,2) * m_fSign;
fsGravity.fs_vDirection(2) = -m(2,2) * m_fSign;
fsGravity.fs_vDirection(3) = -m(3,2) * m_fSign;
FLOAT fDistance = (vPoint-GetPlacement().pl_PositionVector)%fsGravity.fs_vDirection;
fsGravity.fs_fAcceleration = StrengthAtDistance(fDistance);
fsGravity.fs_fVelocity = 70;
} break;
case LT_CENTRAL: {
fsGravity.fs_vDirection = (GetPlacement().pl_PositionVector-vPoint)*m_fSign;
FLOAT fDistance = fsGravity.fs_vDirection.Length();
if (fDistance>0.01f) {
fsGravity.fs_vDirection/=fDistance;
}
fsGravity.fs_fAcceleration = StrengthAtDistance(fDistance);
fsGravity.fs_fVelocity = 70;
} break;
case LT_CYLINDRICAL: {
FLOAT3D vDelta = GetPlacement().pl_PositionVector-vPoint;
FLOAT3D vAxis;
vAxis(1) = m(1,2);
vAxis(2) = m(2,2);
vAxis(3) = m(3,2);
GetNormalComponent(vDelta, vAxis, fsGravity.fs_vDirection);
fsGravity.fs_vDirection*=m_fSign;
FLOAT fDistance = fsGravity.fs_vDirection.Length();
if (fDistance>0.01f) {
fsGravity.fs_vDirection/=fDistance;
}
fsGravity.fs_fAcceleration = StrengthAtDistance(fDistance);
fsGravity.fs_fVelocity = 70;
} break;
case LT_TORUS: {
// get referent point
FLOAT3D vDelta = vPoint-GetPlacement().pl_PositionVector;
FLOAT3D vAxis;
vAxis(1) = m(1,2);
vAxis(2) = m(2,2);
vAxis(3) = m(3,2);
FLOAT3D vR;
GetNormalComponent(vDelta, vAxis, vR);
vR.Normalize();
fsGravity.fs_vDirection = (vDelta-vR*m_rTorusR)*m_fSign;
FLOAT fDistance = fsGravity.fs_vDirection.Length();
if (fDistance>0.01f) {
fsGravity.fs_vDirection/=fDistance;
}
fsGravity.fs_fAcceleration = StrengthAtDistance(fDistance);
fsGravity.fs_fVelocity = 70;
} break;
default:
fsGravity.fs_fAcceleration = m_fAcc;
fsGravity.fs_fVelocity = 70;
fsGravity.fs_vDirection = FLOAT3D(0,-1,0);
}
// calculate forcefield influence
fsField.fs_fAcceleration = m_fForceA;
fsField.fs_fVelocity = m_fForceV;
fsField.fs_vDirection = m_vForceDir;
}
/* Handle an event, return false if the event is not handled. */
BOOL HandleEvent(const CEntityEvent &ee)
{
if( ee.ee_slEvent==EVENTCODE_ETrigger)
{
EChangeGravity eChangeGravity;
eChangeGravity.penNewGravity = this;
m_penTarget->SendEvent( eChangeGravity);
return TRUE;
}
return FALSE;
}
procedures:
Main()
{
InitAsEditorModel();
SetPhysicsFlags(EPF_MODEL_IMMATERIAL);
SetCollisionFlags(ECF_IMMATERIAL);
// set appearance
SetModel(MODEL_MARKER);
SetModelMainTexture(TEXTURE_MARKER);
// set name
if (m_strName=="Marker") {
m_strName = "Gravity Marker";
}
// precalc fast gravity parameters
m_fAcc = Abs(30*m_fStrength),
m_fSign = SgnNZ(m_fStrength),
m_fStep = m_fAcc/(m_rFallOff-m_rHotSpot);
AnglesToDirectionVector(m_aForceDir, m_vForceDir);
return;
}
};