778 lines
20 KiB
Plaintext
778 lines
20 KiB
Plaintext
|
|
object vehicle_magog_npc {
|
|
void preinit();
|
|
void init() {}
|
|
void destroy();
|
|
void syncFields();
|
|
|
|
// states
|
|
void Deliver();
|
|
void Drop();
|
|
void Return();
|
|
|
|
// callbacks
|
|
void OnSetDeploymentParms( float deploymentItemIndex, float playerIndex, vector target, float rotation );
|
|
void vSetDeploymentParms( float deploymentItemIndex, float playerIndex, vector target, float rotation ) {
|
|
OnSetDeploymentParms( deploymentItemIndex, playerIndex, target, rotation );
|
|
}
|
|
|
|
void ClearRequest();
|
|
void OnItemChanged();
|
|
void OnStateTimeChanged();
|
|
|
|
// utility
|
|
void SetupCrate();
|
|
void SetupCommandMap();
|
|
boolean PerformDrop();
|
|
void UpdateEffects( vector pos );
|
|
|
|
// virtuals
|
|
boolean vIgnoreMagogCollsion();
|
|
|
|
// threads
|
|
void UpdateRotors();
|
|
void KillAllInBoundingBox();
|
|
void RopeThread();
|
|
// void CheckDeployable();
|
|
|
|
vector GetItemAttachPoint();
|
|
|
|
// deployment stuff
|
|
float deployIndex;
|
|
float deployPlayerIndex;
|
|
entity item;
|
|
vector targetPos;
|
|
float itemRotation;
|
|
float startTime;
|
|
float dropTime;
|
|
float returnTime;
|
|
vector gdfCorner;
|
|
vector matchPosition;
|
|
|
|
// local data
|
|
float maxHealth;
|
|
float commandMapHandle;
|
|
|
|
// rotor blades
|
|
float rearUpperRotorJoint;
|
|
float rearLowerRotorJoint;
|
|
float leftUpperRotorJoint;
|
|
float leftLowerRotorJoint;
|
|
float rightUpperRotorJoint;
|
|
float rightLowerRotorJoint;
|
|
float bladeRotationSpeed;
|
|
|
|
// rope stuff
|
|
float attachJoint;
|
|
float ropeJoint;
|
|
float hatchJoint;
|
|
float itemAttachJoint;
|
|
|
|
// physics
|
|
float maxZAccel;
|
|
float maxZVel;
|
|
|
|
boolean cancelDrop;
|
|
boolean dropped;
|
|
|
|
vector renderMins;
|
|
vector renderMaxs;
|
|
|
|
// rotor ground fx
|
|
boolean groundEffects;
|
|
float groundEffectsThreshhold;
|
|
float lastGroundEffectsTime;
|
|
|
|
entity vGetItem() {
|
|
return item;
|
|
}
|
|
|
|
|
|
void CacheItemInfoThread();
|
|
vector cachedItemOrigin;
|
|
vector cachedItemAngles;
|
|
}
|
|
|
|
|
|
void vehicle_magog_npc::SetupCommandMap() {
|
|
commandMapHandle = sys.allocCMIcon( self, 1 );
|
|
|
|
float commandMapSize = getFloatKeyWithDefault( "icon_size_cm", 16.f );
|
|
|
|
sys.setCMIconDrawMode( commandMapHandle, DM_ROTATED_MATERIAL );
|
|
sys.setCMIconSize( commandMapHandle, commandMapSize );
|
|
sys.setCMIconColorMode( commandMapHandle, CM_ALLEGIANCE );
|
|
sys.setCMIconMaterial( commandMapHandle, GetMaterial( getKey( "mtr_commandmap" ) ) );
|
|
sys.setCMIconUnknownMaterial( commandMapHandle, GetMaterial( getKey( "mtr_commandmap_unknown" ) ) );
|
|
sys.setCMIconUnknownSize( commandMapHandle, getFloatKeyWithDefault( "icon_unknown_size_cm", commandMapSize / 2.0f ) );
|
|
|
|
sys.setCMIconFlag( commandMapHandle, CMF_FOLLOWROTATION );
|
|
}
|
|
|
|
void vehicle_magog_npc::syncFields() {
|
|
syncBroadcast( "item" );
|
|
syncBroadcast( "dropTime" );
|
|
syncBroadcast( "returnTime" );
|
|
syncBroadcast( "targetPos" );
|
|
syncBroadcast( "itemRotation" );
|
|
syncBroadcast( "gdfCorner" );
|
|
syncBroadcast( "startTime" );
|
|
syncBroadcast( "matchPosition" );
|
|
syncCallback( "item", "OnItemChanged" );
|
|
syncCallback( "startTime", "OnStateTimeChanged" );
|
|
syncCallback( "dropTime", "OnStateTimeChanged" );
|
|
syncCallback( "returnTime", "OnStateTimeChanged" );
|
|
}
|
|
|
|
void vehicle_magog_npc::OnItemChanged() {
|
|
SetupCrate();
|
|
|
|
if ( sys.isClient() ) {
|
|
thread CacheItemInfoThread();
|
|
}
|
|
}
|
|
|
|
void vehicle_magog_npc::OnStateTimeChanged() {
|
|
if ( returnTime != -1 ) {
|
|
setState( "Return" );
|
|
} else if ( dropTime != -1 ) {
|
|
setState( "Drop" );
|
|
} else if ( startTime != -1 ) {
|
|
setState( "Deliver" );
|
|
}
|
|
}
|
|
|
|
void vehicle_magog_npc::preinit() {
|
|
deployPlayerIndex = -1;
|
|
commandMapHandle = -1;
|
|
startTime = -1;
|
|
dropTime = -1;
|
|
returnTime = -1;
|
|
maxHealth = getFloatKey( "health" );
|
|
|
|
SetupCommandMap();
|
|
|
|
rearUpperRotorJoint = getJointHandle( "rear_upper_rotor" );
|
|
rearLowerRotorJoint = getJointHandle( "rear_lower_rotor" );
|
|
|
|
leftUpperRotorJoint = getJointHandle( "front_left_upper_rotor" );
|
|
leftLowerRotorJoint = getJointHandle( "front_left_lower_rotor" );
|
|
|
|
rightUpperRotorJoint = getJointHandle( "front_right_upper_rotor" );
|
|
rightLowerRotorJoint = getJointHandle( "front_right_lower_rotor" );
|
|
|
|
bladeRotationSpeed = getFloatKey( "blade_speed" );
|
|
if ( bladeRotationSpeed <= 0 ) {
|
|
bladeRotationSpeed = 1440.f;
|
|
}
|
|
|
|
// this is to account for rotor spooling etc
|
|
maxZAccel = getFloatKey( "max_thrust" );
|
|
maxZVel = getFloatKey( "max_z_vel" );
|
|
|
|
gdfCorner = g_vectorZero;
|
|
|
|
cancelDrop = false;
|
|
dropped = false;
|
|
|
|
// stop the comedy knock back from the deployable exploding when the magog is delivering it
|
|
disableKnockback();
|
|
|
|
startSound( "snd_rotor", SND_VEHICLE_START );
|
|
|
|
attachJoint = getJointHandle( getKey( "joint_attach" ) );
|
|
ropeJoint = getJointHandle( getKey( "joint_rope" ) );
|
|
hatchJoint = getJointHandle( getKey( "joint_hatch" ) );
|
|
itemAttachJoint = INVALID_JOINT;
|
|
|
|
groundEffects = false;
|
|
groundEffectsThreshhold = getFloatKey( "groundeffects_threshhold" );
|
|
lastGroundEffectsTime = 0.f;
|
|
|
|
setCoverage( 0.f );
|
|
|
|
thread UpdateRotors();
|
|
thread KillAllInBoundingBox();
|
|
thread RopeThread();
|
|
|
|
renderMins = getMins();
|
|
renderMaxs = getMaxs();
|
|
}
|
|
|
|
void vehicle_magog_npc::ClearRequest() {
|
|
if ( sys.isClient() ) {
|
|
return;
|
|
}
|
|
|
|
if ( deployPlayerIndex != -1 ) {
|
|
sys.clearDeployRequest( deployPlayerIndex );
|
|
deployPlayerIndex = -1;
|
|
}
|
|
}
|
|
|
|
void vehicle_magog_npc::destroy() {
|
|
if ( item != $null_entity && !sys.isClient() ) {
|
|
item.remove();
|
|
}
|
|
|
|
sys.freeCMIcon( self, commandMapHandle );
|
|
|
|
ClearRequest();
|
|
}
|
|
|
|
#define HOVER_HEIGHT_MIN 400
|
|
#define HOVER_HEIGHT_AIM 2300
|
|
|
|
void vehicle_magog_npc::Deliver() {
|
|
if ( sys.isClient() ) {
|
|
pathFind( getKey( "path_type" ), targetPos, startTime, 1.0f, gdfCorner_x, gdfCorner_y, 0, false );
|
|
pathLevel( 20, -1, -1 );
|
|
pathStraighten();
|
|
}
|
|
|
|
float numPoints = pathGetNumPoints();
|
|
if ( numPoints < 2 ) {
|
|
return;
|
|
}
|
|
|
|
// thread CheckDeployable();
|
|
|
|
float pathSpeed = getFloatKeyWithDefault( "path_speed", 1024 );
|
|
float pathLength = pathGetLength();
|
|
|
|
vector endPoint = pathGetPoint( numPoints - 1 );
|
|
endPoint_z += HOVER_HEIGHT_MIN;
|
|
vector endAngles = g_vectorZero;
|
|
endAngles_y = sys.angleNormalize180( itemRotation );
|
|
|
|
// find the actual end point
|
|
float fraction = 1.0f;
|
|
while ( fraction == 1.0f ) {
|
|
fraction = sys.traceOriented( endPoint, endPoint - '0 0 3000', renderMins, renderMaxs, endAngles, MASK_SOLID | MASK_OPAQUE, self );
|
|
endPoint = sys.getTraceEndPos();
|
|
}
|
|
endPoint_z += HOVER_HEIGHT_AIM;
|
|
matchPosition = endPoint;
|
|
|
|
startMagogDelivery( startTime, pathSpeed, 2.0f, endPoint, itemRotation );
|
|
|
|
float coverage = 0.f;
|
|
while ( true ) {
|
|
if ( sys.isServer() ) {
|
|
if ( item == $null_entity ) {
|
|
sys.warning( "DEPLOYABLE GONE" );
|
|
}
|
|
}
|
|
|
|
float frameTime = sys.getFrameTime();
|
|
|
|
setCoverage( coverage );
|
|
coverage = coverage + frameTime;
|
|
|
|
vector origin = getWorldOrigin();
|
|
if ( !sys.isClient() ) {
|
|
float distToEnd = sys.vecLength( origin - endPoint );
|
|
if ( sys.vecLength( origin - endPoint ) < 64.0f ) {
|
|
vector velocity = getLinearVelocity();
|
|
velocity_z = 0.0f;
|
|
if ( sys.vecLength( velocity ) < 50.0f ) {
|
|
setState( "Drop" );
|
|
}
|
|
}
|
|
|
|
if ( cancelDrop ) {
|
|
ClearRequest();
|
|
setState( "Return" );
|
|
}
|
|
}
|
|
|
|
sys.waitFrame();
|
|
}
|
|
}
|
|
|
|
void vehicle_magog_npc::CacheItemInfoThread() {
|
|
sys.threadName( "CacheItemInfoThread_" + getName() );
|
|
|
|
while ( true ) {
|
|
if ( item != $null_entity ) {
|
|
if ( item.isBound() ) {
|
|
cachedItemOrigin = item.getWorldOrigin();
|
|
cachedItemAngles = item.getAngles();
|
|
}
|
|
}
|
|
sys.waitFrame();
|
|
}
|
|
}
|
|
|
|
void vehicle_magog_npc::Drop() {
|
|
if( !sys.isClient() ) {
|
|
if ( !PerformDrop() ) {
|
|
// the player has switched sides or class since requesting the deployable
|
|
ClearRequest();
|
|
setState( "Return" );
|
|
}
|
|
}
|
|
|
|
if ( !sys.isClient() ) {
|
|
dropTime = sys.getTime();
|
|
} else {
|
|
while ( dropTime == -1 ) {
|
|
sys.waitFrame();
|
|
}
|
|
}
|
|
|
|
vector origin = getWorldOrigin();
|
|
vector endAngles = g_vectorZero;
|
|
endAngles_y = sys.angleNormalize180( itemRotation );
|
|
|
|
if ( item.isBound() ) {
|
|
cachedItemOrigin = item.getWorldOrigin();
|
|
cachedItemAngles = item.getAngles();
|
|
item.unbind();
|
|
}
|
|
sys.killThread( "CacheItemInfoThread_" + getName() );
|
|
|
|
// setting this back again ensures a seamless drop for all clients
|
|
item.setOrigin( cachedItemOrigin );
|
|
item.setAngles( cachedItemAngles );
|
|
|
|
item.vStartMagogDrop();
|
|
|
|
if ( item.getFloatKey( "no_drop" ) == 0.f ) {
|
|
|
|
float timeToDrop = 4.0f;
|
|
vector dropOrigin = item.getWorldOrigin();
|
|
vector dropDelta = targetPos - dropOrigin;
|
|
|
|
vector dropAngles = item.getAngles();
|
|
vector dropAngleDelta = endAngles - dropAngles;
|
|
dropAngleDelta_y = sys.angleNormalize180( dropAngleDelta_y );
|
|
|
|
|
|
float time;
|
|
float doneNess;
|
|
vector spot;
|
|
vector angles;
|
|
vector ropeModelSpot;
|
|
vector hookModelSpot;
|
|
|
|
// expand the bounds while dropping the item
|
|
vector mins = getRenderMins();
|
|
vector maxs = getRenderMaxs();
|
|
mins_z += dropDelta_z;
|
|
setRenderBounds( mins, maxs );
|
|
|
|
if ( !sys.isClient() ) {
|
|
item.vStartBoundsKillThread();
|
|
}
|
|
|
|
vector hookStartSpot = getJointPos( attachJoint );
|
|
vector ropeStartSpot = getJointPos( ropeJoint );
|
|
vector hookStartModelSpot = worldToModelSpace( hookStartSpot - origin );
|
|
vector ropeStartModelSpot = worldToModelSpace( ropeStartSpot - origin );
|
|
|
|
while ( true ) {
|
|
time = sys.getTime() - dropTime;
|
|
doneNess = time / timeToDrop;
|
|
if ( doneNess > 1.0f ) {
|
|
doneNess = 1.0f;
|
|
}
|
|
|
|
doneNess = 1 - ( sys.cos( doneNess * 180 ) + 1 ) * 0.5;
|
|
|
|
spot = dropOrigin + dropDelta * doneNess;
|
|
angles = dropAngles + dropAngleDelta * doneNess;
|
|
|
|
item.setWorldOrigin( spot );
|
|
item.setAngles( angles );
|
|
item.setLinearVelocity( vec3_origin );
|
|
item.setAngularVelocity( vec3_origin );
|
|
|
|
// use the joint position to position the hook
|
|
vector hookSpot = GetItemAttachPoint(); //item.getJointPos( itemAttachJoint );
|
|
vector ropeSpot = ( hookSpot + dropOrigin ) * 0.5f;
|
|
|
|
origin = getWorldOrigin();
|
|
hookModelSpot = worldToModelSpace( hookSpot - origin );
|
|
ropeModelSpot = worldToModelSpace( ropeSpot - origin );
|
|
|
|
setJointPos( attachJoint, JOINTMOD_WORLD_OVERRIDE, hookModelSpot );
|
|
setJointPos( ropeJoint, JOINTMOD_WORLD_OVERRIDE, ropeModelSpot );
|
|
|
|
vector resultHookSpot = getJointPos( attachJoint );
|
|
|
|
sys.waitFrame();
|
|
if ( doneNess == 1.0f ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !sys.isClient() ) {
|
|
ClearRequest();
|
|
|
|
if ( item != $null_entity ) {
|
|
item.vOnDeploy();
|
|
item = $null_entity;
|
|
}
|
|
}
|
|
|
|
// bring the hook back up
|
|
vector hookEndSpot = getJointPos( attachJoint );
|
|
vector ropeEndSpot = getJointPos( ropeJoint );
|
|
|
|
float raiseTime = sys.getTime() + 1;
|
|
while ( true ) {
|
|
time = sys.getTime() - raiseTime;
|
|
doneNess = time / ( timeToDrop * 0.75f );
|
|
|
|
CLAMP( doneNess, 0.0f, 1.0f );
|
|
doneNess = 1 - ( sys.cos( doneNess * 180 ) + 1 ) * 0.5;
|
|
|
|
origin = getWorldOrigin();
|
|
ropeStartSpot = sys.toWorldSpace( ropeStartModelSpot, self );
|
|
hookStartSpot = sys.toWorldSpace( hookStartModelSpot, self );
|
|
ropeModelSpot = worldToModelSpace( ( ropeStartSpot - ropeEndSpot ) * doneNess + ropeEndSpot - origin );
|
|
hookModelSpot = worldToModelSpace( ( hookStartSpot - hookEndSpot ) * doneNess + hookEndSpot - origin );
|
|
|
|
setJointPos( attachJoint, JOINTMOD_WORLD_OVERRIDE, hookModelSpot );
|
|
setJointPos( ropeJoint, JOINTMOD_WORLD_OVERRIDE, ropeModelSpot );
|
|
|
|
vector resultHookSpot2 = getJointPos( attachJoint );
|
|
vector hookPooSpot = ( hookStartSpot - hookEndSpot ) * doneNess + hookEndSpot - origin;
|
|
|
|
sys.waitFrame();
|
|
if ( doneNess == 1.0f ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// restore the original render bounds
|
|
mins_z -= dropDelta_z;
|
|
setRenderBounds( mins, maxs );
|
|
}
|
|
|
|
dropped = true;
|
|
|
|
if ( !sys.isClient() ) {
|
|
setState( "Return" );
|
|
}
|
|
}
|
|
|
|
void vehicle_magog_npc::Return() {
|
|
if ( !sys.isClient() ) {
|
|
returnTime = sys.getTime();
|
|
} else {
|
|
while ( returnTime == -1 ) {
|
|
sys.waitFrame();
|
|
}
|
|
}
|
|
|
|
pathFind( getKey( "path_type" ), targetPos, returnTime, -1.0f, gdfCorner_x, gdfCorner_y, 0, false );
|
|
float numPoints = pathGetNumPoints();
|
|
if ( numPoints < 2 ) {
|
|
return;
|
|
}
|
|
|
|
pathLevel( 20, -1, -1 );
|
|
pathStraighten();
|
|
|
|
float pathSpeed = getFloatKeyWithDefault( "path_speed", 1024 );
|
|
float pathLength = pathGetLength();
|
|
|
|
vector hoverOffset = g_vectorZero;
|
|
hoverOffset_z = HOVER_HEIGHT_MIN;
|
|
|
|
vector endPoint = pathGetPoint( numPoints - 1 ) + hoverOffset;
|
|
|
|
startMagogReturn( returnTime, pathSpeed, 2.0f, endPoint );
|
|
|
|
while ( true ) {
|
|
float time = sys.getTime() - returnTime;
|
|
|
|
float position = time * pathSpeed;
|
|
float coverage = ( pathLength - 1 - position ) / pathSpeed;
|
|
setCoverage( coverage );
|
|
|
|
if ( !sys.isClient() ) {
|
|
if ( position > pathLength ) {
|
|
remove();
|
|
}
|
|
}
|
|
|
|
sys.waitFrame();
|
|
}
|
|
}
|
|
|
|
void vehicle_magog_npc::UpdateRotors() {
|
|
vector ang;
|
|
ang_y = 0.f;
|
|
|
|
while ( true ) {
|
|
sys.waitFrame();
|
|
|
|
ang_y += bladeRotationSpeed * sys.getFrameTime();
|
|
|
|
setJointAngle( rearUpperRotorJoint, JOINTMOD_WORLD, ang );
|
|
setJointAngle( rearLowerRotorJoint, JOINTMOD_WORLD, ang );
|
|
|
|
setJointAngle( leftUpperRotorJoint, JOINTMOD_WORLD, ang * 0.99f );
|
|
setJointAngle( leftLowerRotorJoint, JOINTMOD_WORLD, ang * 0.99f );
|
|
|
|
setJointAngle( rightUpperRotorJoint, JOINTMOD_WORLD, ang * 1.01f );
|
|
setJointAngle( rightLowerRotorJoint, JOINTMOD_WORLD, ang * 1.01f );
|
|
|
|
vector absMins = getAbsMins();
|
|
vector traceOrg = ( absMins + getAbsMaxs() ) * 0.5f;
|
|
|
|
UpdateEffects( traceOrg );
|
|
}
|
|
}
|
|
|
|
void vehicle_magog_npc::OnSetDeploymentParms( float deploymentItemIndex, float playerIndex, vector target, float rotation ) {
|
|
deployPlayerIndex = playerIndex;
|
|
targetPos = target;
|
|
itemRotation = sys.angleNormalize180( rotation );
|
|
|
|
if( !PerformDrop() ) {
|
|
// player has switched sides since calling in the deployable
|
|
ClearRequest();
|
|
remove();
|
|
return;
|
|
}
|
|
|
|
player p = sys.getClient( playerIndex );
|
|
item = sys.spawnType( deploymentItemIndex );
|
|
item.vSetDeployableOwner( p );
|
|
|
|
deployable_base deployable = item;
|
|
if ( deployable != $null_entity ) {
|
|
p.SetTargetingItem( item );
|
|
}
|
|
|
|
string statName = item.getKey( "stat_name" );
|
|
if ( statName != "" ) {
|
|
sys.increaseStatInt( sys.allocStatInt( statName + "_deployed" ), deployPlayerIndex, 1 );
|
|
}
|
|
|
|
SetupCrate();
|
|
|
|
// setup the delivery path
|
|
startTime = sys.getTime();
|
|
gdfCorner = objManager.GetGDFBasePosition();
|
|
|
|
pathFind( getKey( "path_type" ), targetPos, startTime, 1.0f, gdfCorner_x, gdfCorner_y, 0, false );
|
|
pathLevel( 20, -1, -1 );
|
|
pathStraighten();
|
|
|
|
vector startPoint = pathGetPoint( 0 );
|
|
startPoint_z += HOVER_HEIGHT_MIN;
|
|
vector startDir = pathGetDirection( 0 );
|
|
startDir = sys.vecNormalize( startDir );
|
|
vector startAngles = sys.vecToAngles( startDir );
|
|
|
|
setWorldOrigin( startPoint );
|
|
setAngles( startAngles );
|
|
|
|
setState( "Deliver" );
|
|
}
|
|
|
|
void vehicle_magog_npc::SetupCrate() {
|
|
if ( item == $null_entity ) {
|
|
return;
|
|
}
|
|
|
|
vector org;
|
|
|
|
itemAttachJoint = item.getJointHandle( item.getKey( "joint_attach" ) );
|
|
org = GetItemAttachPoint();
|
|
org = item.worldToModelSpace( org - item.getWorldOrigin() );
|
|
|
|
if ( item != $null_entity ) {
|
|
item.setOrigin( getLocalJointPos( attachJoint ) - org );
|
|
item.bindToJoint( self, getKey( "joint_attach" ), 1 );
|
|
item.setGameTeam( getGameTeam() );
|
|
item.vSetManualDeploy();
|
|
}
|
|
}
|
|
|
|
vector vehicle_magog_npc::GetItemAttachPoint() {
|
|
if ( item == $null_entity ) {
|
|
return '0 0 0';
|
|
}
|
|
|
|
vector org;
|
|
|
|
if ( itemAttachJoint != -1 ) {
|
|
org = item.getJointPos( itemAttachJoint );
|
|
} else {
|
|
org = item.getWorldOrigin();
|
|
org_z += item.getFloatKey( "attach_height" );
|
|
}
|
|
|
|
return org;
|
|
}
|
|
|
|
void vehicle_magog_npc::KillAllInBoundingBox() {
|
|
sys.wait( 3 );
|
|
|
|
eachFrame {
|
|
|
|
vector mins = getAbsMins();
|
|
vector maxs = getAbsMaxs();
|
|
|
|
// sys.debugBounds( '1 1 1', mins, maxs, 0.f );
|
|
|
|
entitiesInBounds( mins, maxs, MASK_ALL, 1 );
|
|
float count = filterEntitiesByClass( "sdTransport", 1 );
|
|
|
|
float i;
|
|
for( i = 0; i < count; i++ ) {
|
|
entity ent = getBoundsCacheEntity( i );
|
|
if( ent == self || ent == item || ent == $null_entity ) {
|
|
continue;
|
|
}
|
|
|
|
if( !ent.vIgnoreMagogCollsion() ) {
|
|
if ( touchesBounds( ent ) ) {
|
|
ent.applyDamage( $null_entity, self, '0 1 0', GetDamage( "damage_magog_npc_collide" ), 60000.f, $null_entity );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
boolean vehicle_magog_npc::vIgnoreMagogCollsion() {
|
|
return true;
|
|
}
|
|
|
|
#define MAGOC_NPC_SWINGLENGTHSCALE 2
|
|
#define MAGOC_NPC_SWINGMASS 1000
|
|
#define MAGOC_NPC_SWINGMASSEMPTY 1000
|
|
#define MAGOC_NPC_SWINGSCALE 75
|
|
#define MAGOC_NPC_SWINGSCALEEMPTY 75
|
|
#define MAGOC_NPC_SWINGFRICTION 1
|
|
|
|
void vehicle_magog_npc::RopeThread() {
|
|
vector dist = getLocalJointPos( hatchJoint ) - getLocalJointPos( ropeJoint );
|
|
vector pos = dist;
|
|
float length = sys.vecLength( dist );
|
|
vector momentum = g_vectorZero;
|
|
|
|
// sys.print( "dist:" + dist + "\n" );
|
|
|
|
while ( true ) {
|
|
sys.waitFrame();
|
|
|
|
float mass = MAGOC_NPC_SWINGMASS;
|
|
float swingScale = MAGOC_NPC_SWINGSCALE;
|
|
if ( item == $null_entity ) {
|
|
mass = MAGOC_NPC_SWINGMASSEMPTY;
|
|
swingScale = MAGOC_NPC_SWINGSCALEEMPTY;
|
|
}
|
|
|
|
float inverseMass = 1 / mass;
|
|
float gravity = 1066 * mass;
|
|
|
|
float len = length * MAGOC_NPC_SWINGLENGTHSCALE;
|
|
len = len * len;
|
|
|
|
float frameTime = sys.getFrameTime();
|
|
|
|
vector selfV = getLinearVelocity();
|
|
selfV_z = 0;
|
|
|
|
vector force = selfV * swingScale;
|
|
force_z += gravity;
|
|
|
|
vector path = sys.vecNormalize( pos );
|
|
path = path * ( -force_z / path_z );
|
|
|
|
force += path;
|
|
|
|
momentum += ( ( force - ( momentum * MAGOC_NPC_SWINGFRICTION ) ) * frameTime );
|
|
vector v = momentum * inverseMass;
|
|
|
|
pos_x = pos_x + ( v_x * frameTime );
|
|
pos_y = pos_y + ( v_y * frameTime );
|
|
pos_z = sys.sqrt( len - ( ( pos_x * pos_x ) + ( pos_y * pos_y ) ) );
|
|
|
|
// sys.print( "pos_x: " + pos_x + "\n" );
|
|
// sys.print( "v: " + v + "\n" );
|
|
|
|
vector modelPos = worldToModelSpace( pos );
|
|
setJointPos( ropeJoint, JOINTMOD_WORLD_OVERRIDE, getLocalJointPos( hatchJoint ) - modelPos );
|
|
modelPos = sys.vecNormalize( modelPos );
|
|
|
|
vector forward = '1 0 0' - ( modelPos_x * modelPos );
|
|
forward = sys.vecNormalize( forward );
|
|
forward = sys.vecToAngles( forward );
|
|
|
|
// objectStable = sys.vecLength( v ) < 0.5f && sys.fabs( pos_z - ( length * MAGOC_NPC_SWINGLENGTHSCALE ) ) < 0.5f;
|
|
|
|
setJointAngle( attachJoint, JOINTMOD_WORLD, forward );
|
|
|
|
// sys.debugLine( g_colorRed, getJointPos( hatchJoint ), getJointPos( hatchJoint ) - pos, 0.f );
|
|
}
|
|
}
|
|
|
|
boolean vehicle_magog_npc::PerformDrop() {
|
|
// special cases
|
|
if ( deployPlayerIndex == -1 ) {
|
|
return true;
|
|
}
|
|
|
|
if ( item != $null_entity ) {
|
|
if ( item.getIntKey( "always_drop" ) == 1 ) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
player p = sys.getClient( deployPlayerIndex );
|
|
if ( getEntityAllegiance( p ) != TA_FRIEND ) {
|
|
return false;
|
|
}
|
|
|
|
if( sys.getTerritoryForPoint( targetPos, getGameTeam(), 1.f, 0.f ) == $null_entity ) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void vehicle_magog_npc::vCancelDeployForPlayer( float playerIndex ) {
|
|
if ( playerIndex != deployPlayerIndex ) {
|
|
return;
|
|
}
|
|
|
|
// deployables already gone
|
|
if ( dropped ) {
|
|
return;
|
|
}
|
|
|
|
player p = sys.getClient( deployPlayerIndex );
|
|
objManager.PlaySoundForPlayer( getKey( "snd_cancel_deploy" ), p );
|
|
|
|
ClearRequest();
|
|
if ( !sys.isClient() ) {
|
|
setState( "Return" );
|
|
}
|
|
}
|
|
|
|
void vehicle_magog_npc::UpdateEffects( vector pos ) {
|
|
groundEffects = true;//( absMins.z - traceObject.endpos.z ) < groundEffectsThreshhold;
|
|
|
|
vector end = pos;
|
|
end_z -= groundEffectsThreshhold;
|
|
|
|
sys.tracePoint( pos, end, MASK_SOLID | MASK_OPAQUE, self );
|
|
|
|
if ( sys.getTime() >= ( lastGroundEffectsTime + 0.1f )
|
|
&& groundEffects && sys.getTraceFraction() < 1.0f ) {
|
|
|
|
string surfaceTypeName = sys.getTraceSurfaceType();
|
|
|
|
playOriginEffect( "fx_groundeffect", surfaceTypeName, sys.getTraceEndPos(), sys.getTraceNormal(), 0 );
|
|
lastGroundEffectsTime = sys.getTime();
|
|
}
|
|
}
|