void hhProjectileCocoon::Event_TrackTarget() { idVec3 newVelocity; if( !enemy.IsValid() ) { physicsObj.SetLinearVelocity( GetAxis()[ 0 ] * velocity[ 0 ] + GetAxis()[ 1 ] * velocity[ 1 ] + GetAxis()[ 2 ] * velocity[ 2 ] ); physicsObj.SetAngularVelocity( angularVelocity.ToAngularVelocity() * GetAxis() ); return; } idVec3 enemyDir = DetermineEnemyDir( enemy.GetEntity() ); idVec3 currentDir = GetAxis()[0]; idVec3 newDir = currentDir*(1-turnFactor) + enemyDir*turnFactor; newDir.Normalize(); if ( driver.IsValid() ) { driver->SetAxis(newDir.ToMat3()); } else { SetAxis(newDir.ToMat3()); } newVelocity = GetAxis()[ 0 ] * velocity[ 0 ] + GetAxis()[ 1 ] * velocity[ 1 ] + GetAxis()[ 2 ] * velocity[ 2 ]; newVelocity *= spawnArgs.GetFloat( "bounce", "1.0" ); physicsObj.SetLinearVelocity( newVelocity ); physicsObj.SetAngularVelocity( angularVelocity.ToAngularVelocity() * GetAxis() ); }
//-------------------------------- // hhProxDoor::Event_PostSpawn //-------------------------------- void hhProxDoor::Event_PostSpawn( void ) { int numSubObjs; int i; const char* objDef; //Parse and spawn our door sections numSubObjs = spawnArgs.GetInt( "num_doorobjs", "0" ); for( i = 0; i < numSubObjs; i++ ) { if( !spawnArgs.GetString( va("doorobject%i", i+1), "", &objDef ) ) { common->Warning( "failed to find doorobject%i", i+1 ); } else { //Set our default rotation/origin. idDict args; args.SetVector( "origin", this->GetOrigin() ); args.SetMatrix( "rotation", this->GetAxis() ); hhProxDoorSection* ent = static_cast<hhProxDoorSection*> ( gameLocal.SpawnObject(objDef, &args) ); if( !ent ) { common->Warning( "failed to spawn doorobject%i for entityDef '%s'", i+1, GetEntityDefName() ); } else { ent->proxyParent = this; doorPieces.Append( ent ); } } } //Spawn our trigger and link it up // if( doorLocked && !spawnArgs.GetBool("locktrigger") ) { //we would never be able to open the door, so don't spawn a trigger // } // else { doorTrigger = new idClipModel( idTraceModel(idBounds(vec3_origin).Expand(maxDistance)) ); doorTrigger->Link( gameLocal.clip, this, 255, GetOrigin(), GetAxis() ); doorTrigger->SetContents( CONTENTS_TRIGGER ); // } SpawnSoundTrigger(); SetAASAreaState( doorLocked ); //close the area state if we are locked... SetDoorState( PROXSTATE_Inactive ); }
/* ================ idPhysics_Base::DrawVelocity ================ */ void idPhysics_Base::DrawVelocity( int id, float linearScale, float angularScale ) const { idVec3 dir, org, vec, start, end; idMat3 axis; float length, a; dir = GetLinearVelocity( id ); dir *= linearScale; if ( dir.LengthSqr() > Square( 0.1f ) ) { dir.Truncate( 10.0f ); org = GetOrigin( id ); gameRenderWorld->DebugArrow( colorRed, org, org + dir, 1 ); } dir = GetAngularVelocity( id ); length = dir.Normalize(); length *= angularScale; if ( length > 0.1f ) { if ( length < 60.0f ) { length = 60.0f; } else if ( length > 360.0f ) { length = 360.0f; } axis = GetAxis( id ); vec = axis[2]; if ( idMath::Fabs( dir * vec ) > 0.99f ) { vec = axis[0]; } vec -= vec * dir * vec; vec.Normalize(); vec *= 4.0f; start = org + vec; for ( a = 20.0f; a < length; a += 20.0f ) { end = org + idRotation( vec3_origin, dir, -a ).ToMat3() * vec; gameRenderWorld->DebugLine( colorBlue, start, end, 1 ); start = end; } end = org + idRotation( vec3_origin, dir, -length ).ToMat3() * vec; gameRenderWorld->DebugArrow( colorBlue, start, end, 1 ); } }
/* ================ idSecurityCamera::DrawFov ================ */ void idSecurityCamera::DrawFov() { int i; float radius, a, s, c, halfRadius; idVec3 right, up; idVec4 color( 1, 0, 0, 1 ), color2( 0, 0, 1, 1 ); idVec3 lastPoint, point, lastHalfPoint, halfPoint, center; idVec3 dir = GetAxis(); dir.NormalVectors( right, up ); radius = tan( scanFov * idMath::PI / 360.0f ); halfRadius = radius * 0.5f; lastPoint = dir + up * radius; lastPoint.Normalize(); lastPoint = GetPhysics()->GetOrigin() + lastPoint * scanDist; lastHalfPoint = dir + up * halfRadius; lastHalfPoint.Normalize(); lastHalfPoint = GetPhysics()->GetOrigin() + lastHalfPoint * scanDist; center = GetPhysics()->GetOrigin() + dir * scanDist; for( i = 1; i < 12; i++ ) { a = idMath::TWO_PI * i / 12.0f; idMath::SinCos( a, s, c ); point = dir + right * s * radius + up * c * radius; point.Normalize(); point = GetPhysics()->GetOrigin() + point * scanDist; gameRenderWorld->DebugLine( color, lastPoint, point ); gameRenderWorld->DebugLine( color, GetPhysics()->GetOrigin(), point ); lastPoint = point; halfPoint = dir + right * s * halfRadius + up * c * halfRadius; halfPoint.Normalize(); halfPoint = GetPhysics()->GetOrigin() + halfPoint * scanDist; gameRenderWorld->DebugLine( color2, point, halfPoint ); gameRenderWorld->DebugLine( color2, lastHalfPoint, halfPoint ); lastHalfPoint = halfPoint; gameRenderWorld->DebugLine( color2, halfPoint, center ); } }
/* ================ idSecurityCamera::Event_AddLight ================ */ void idSecurityCamera::Event_AddLight( void ) { idDict args; idVec3 right, up, target, temp; idVec3 dir; float radius; idVec3 lightOffset; idLight *spotLight; dir = GetAxis(); dir.NormalVectors( right, up ); target = GetPhysics()->GetOrigin() + dir * scanDist; radius = idMath::Tan( scanFov * idMath::PI / 360.0f ); up = dir + up * radius; up.Normalize(); up = GetPhysics()->GetOrigin() + up * scanDist; up -= target; right = dir + right * radius; right.Normalize(); right = GetPhysics()->GetOrigin() + right * scanDist; right -= target; spawnArgs.GetVector( "lightOffset", "0 0 0", lightOffset ); args.Set( "origin", ( GetPhysics()->GetOrigin() + lightOffset ).ToString() ); args.Set( "light_target", target.ToString() ); args.Set( "light_right", right.ToString() ); args.Set( "light_up", up.ToString() ); args.SetFloat( "angle", GetPhysics()->GetAxis()[0].ToYaw() ); // RAVEN BEGIN // jnewquist: Use accessor for static class type spotLight = static_cast<idLight *>( gameLocal.SpawnEntityType( idLight::GetClassType(), &args ) ); // RAVEN END spotLight->Bind( this, true ); spotLight->UpdateVisuals(); }
// // Event_CreateAI() // void hhAISpawnCase::Event_CreateAI( void ) { // Spawn the monster const char *monsterName = spawnArgs.GetString("def_monster", NULL); int i; if ( aiSpawnCount < spawnArgs.GetInt("max_monsters", "1") && monsterName && monsterName[0]) { idDict args = entSpawnArgs; idVec3 offset = spawnArgs.GetVector("monster_offset", "0 0 0"); offset *= GetPhysics()->GetAxis(); args.SetVector( "origin", GetPhysics()->GetOrigin() + offset); args.SetBool("encased", TRUE); args.Set("encased_idle", spawnArgs.GetString("anim_encased_monster_idle", "encased_idle")); args.Set("encased_exit", spawnArgs.GetString("anim_encased_monster_exit", "encased_exit")); args.Set( "encased_exit_offset", spawnArgs.GetString( "encased_exit_offset", "0 0 0" ) ); args.SetMatrix("rotation", GetAxis()); encasedAI = static_cast<idAI*>(gameLocal.SpawnObject(monsterName, &args)); if(!encasedAI.GetEntity()) { //gameLocal.Warning("No monster specified for case"); return; } // Copy the targets that our case has to our newly spawned monster for( i = 0; i < targets.Num(); i++ ) { encasedAI->targets.AddUnique(targets[i]); } if ( spawnArgs.GetBool( "rotated" ) ) { encasedAI->SetAxis( GetAxis() ); encasedAI->GetPhysics()->SetAxis( GetAxis() ); encasedAI->GetRenderEntity()->axis = GetAxis(); encasedAI->viewAxis = GetAxis(); encasedAI->Bind(this, true); } else { encasedAI->viewAxis = GetAxis(); encasedAI->Bind(this, FALSE); } aiSpawnCount++; if(spawnArgs.GetBool("monster_hide", "0")) { encasedAI->ProcessEvent(&EV_Hide); } } }
/* ================ idSecurityCamera::CanSeePlayer ================ */ bool idSecurityCamera::CanSeePlayer( void ) { int i; float dist; idPlayer *ent; trace_t tr; idVec3 dir; pvsHandle_t handle; handle = gameLocal.pvs.SetupCurrentPVS( pvsArea ); for( i = 0; i < gameLocal.numClients; i++ ) { ent = static_cast<idPlayer *>( gameLocal.entities[ i ] ); if( !ent || ( ent->fl.notarget ) ) { continue; } // if there is no way we can see this player if( !gameLocal.pvs.InCurrentPVS( handle, ent->GetPVSAreas(), ent->GetNumPVSAreas() ) ) { continue; } dir = ent->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin(); dist = dir.Normalize(); if( dist > scanDist ) { continue; } if( dir * GetAxis() < scanFovCos ) { continue; } idVec3 eye; eye = ent->EyeOffset(); gameLocal.clip.TracePoint( tr, GetPhysics()->GetOrigin(), ent->GetPhysics()->GetOrigin() + eye, MASK_OPAQUE, this ); if( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == ent ) ) { gameLocal.pvs.FreeCurrentPVS( handle ); return true; } } gameLocal.pvs.FreeCurrentPVS( handle ); return false; }
void hhHarvesterSimple::Event_StartPreDeath(void) { int i; // No torso? Just kill myself ..... if(!spawnArgs.GetString("def_torso")) { ProcessEvent(&AI_Kill); return; } // Spawn death fx, if any const char *fx = spawnArgs.GetString("fx_death"); if (fx && fx[0]) { hhFxInfo fxInfo; fxInfo.RemoveWhenDone(true); BroadcastFxInfo(fx, GetOrigin(), GetAxis(), &fxInfo); } // do blood splats float size = spawnArgs.GetFloat("decal_torso_pop_size","96"); // copy my target keys to the keys that will spawn the torso idDict dict; const idDict *torsoDict = gameLocal.FindEntityDefDict(spawnArgs.GetString("def_torso")); if ( !torsoDict ) { gameLocal.Error("Unknown def_torso: %s\n", spawnArgs.GetString("def_torso")); } dict.Copy(*torsoDict); for(i=0;i<targets.Num();i++) { if(!targets[i].GetEntity()) { continue; } idStr key("target"); if(i > 0) { sprintf(key, "target%i", i); } dict.Set((const char*)key, (const char*)targets[i].GetEntity()->name); } // Passageway variables dict.SetInt("passage_health", AI_PASSAGEWAY_HEALTH); dict.SetInt("passage_count", passageCount); dict.SetVector("origin", GetOrigin()); dict.SetMatrix("rotation", GetAxis()); // remove my target keys (so they don't get fired) targets.Clear(); // Spawn the torso idEntity *e; hhMonsterAI *aiTorso; if(!gameLocal.SpawnEntityDef(dict, &e)) gameLocal.Error("Failed to spawn ai torso."); HH_ASSERT(e && e->IsType(hhMonsterAI::Type)); aiTorso = static_cast<hhMonsterAI*>(e); HH_ASSERT(aiTorso != NULL); // Throw gibs idStr debrisDef = spawnArgs.GetString("def_gibDebrisSpawnerPreDeath"); if(debrisDef.Length() > 0) { hhUtils::SpawnDebrisMass(debrisDef.c_str(), this, 1.0f); } health = 0; // remove myself Hide(); PostEventMS(&EV_Remove, 3000); }
void Quat::GetAxisAngle( Vector& OutAxis, float& OutTheta ) const { OutTheta = GetAngle(); OutAxis = GetAxis(); }
/* =========== hhForceField::Ticker =========== */ void hhForceField::Ticker( void ) { if( fieldState == StatePreTurningOn ) { idEntity* entityList[MAX_GENTITIES]; idEntity* entity = NULL; idPhysics* physics = NULL; int numEntities = 0; int numEntitiesImpulseAppliedTo = 0; idVec3 force = DetermineForce() * GetAxis(); numEntities = gameLocal.clip.EntitiesTouchingBounds( GetPhysics()->GetAbsBounds(), MASK_SOLID, entityList, MAX_GENTITIES ); for( int ix = 0; ix < numEntities; ++ix ) { entity = entityList[ix]; if( !entity ) { continue; } if( entity == this ) { continue; } //Removing mass from any calculations regarding impulse entity->ApplyImpulse( this, 0, entity->GetOrigin(), force * entity->GetPhysics()->GetMass() ); numEntitiesImpulseAppliedTo++; } --applyImpulseAttempts; if( !numEntitiesImpulseAppliedTo || !applyImpulseAttempts ) { fieldState = StateTurningOn; GetPhysics()->SetContents( cachedContents ); SetSkin( NULL ); StartSound( "snd_start", SND_CHANNEL_ANY ); Show(); EnterTurningOnState(); } } else if( fieldState == StateTurningOn ) { float deltaTime = MS2SEC( gameLocal.msec ); renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] += activationRate * deltaTime; if( renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] >= 1.0f ) { EnterOnState(); } UpdateVisuals(); } else if( fieldState == StateTurningOff ) { float deltaTime = MS2SEC( gameLocal.msec ); renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] -= deactivationRate * deltaTime; if( renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] <= 0.0f ) { EnterOffState(); } UpdateVisuals(); } if( damagedState ) { float deltaTime = MS2SEC( gameLocal.msec ); // Fade parm back to normal fade -= undamageFadeRate * deltaTime; if ( fade <= 0.0f ) { // Finished fading fade = 0; damagedState = false; } SetShaderParm( SHADERPARM_MODE, fade ); } if (!damagedState && (fieldState==StateOn || fieldState==StateOff)) { BecomeInactive( TH_TICKER ); } }
/* ================ sdTeleporter::OnTouch ================ */ void sdTeleporter::OnTouch( idEntity *other, const trace_t& trace ) { if ( gameLocal.isClient ) { return; } idPlayer* player = other->Cast< idPlayer >(); if ( player != NULL && !player->IsSpectator() && player->GetHealth() <= 0 ) { return; } // abort if it didn't touch the trigger model if ( trace.c.id != 1 ) { return; } // abort if there is no target if ( targets.Num() == 0 ) { return; } bool teamValid = true; // abort if the other is on a disabled team sdTeamInfo* otherTeam = other->GetGameTeam(); if ( otherTeam != NULL ) { if ( !teamInfo[ otherTeam->GetIndex() ].enabled ) { teamValid = false; idPlayer* otherPlayer = other->Cast< idPlayer >(); if ( otherPlayer != NULL ) { if ( otherPlayer->IsDisguised() ) { sdTeamInfo* disguiseTeam = otherPlayer->GetDisguiseTeam(); if ( disguiseTeam != NULL ) { if ( teamInfo[ disguiseTeam->GetIndex() ].enabled ) { teamValid = true; } } } } } } if ( !teamValid ) { return; } if ( !other->AllowTeleport() ) { return; } // check if this entity has already been touched if ( latches.FindIndex( other ) != -1 ) { return; } const idVec3& myPosition = GetPhysics()->GetOrigin(); const idMat3& myAxes = GetAxis(); // only allow the entity to teleport if its moving INTO the teleporter float moveDir = other->GetPhysics()->GetLinearVelocity() * myAxes[ 0 ]; if ( moveDir > 0.0f ) { return; } Latch( other ); idEntity *targetEntity = targets[ 0 ].GetEntity(); // get the positions of the target and the latch idVec3 targetPosition = targetEntity->GetPhysics()->GetOrigin(); idMat3 targetAxes = targetEntity->GetAxis(); // find the target teleporter // TODO: Make it an entity key on the target entity sdTeleporter* targetTeleporter = NULL; idClass* typeInstance = Type.instances.Next(); for ( ; typeInstance; typeInstance = typeInstance->GetInstanceNode()->Next() ) { sdTeleporter* testTeleporter = reinterpret_cast< sdTeleporter* >( typeInstance ); idBounds bounds = testTeleporter->GetPhysics()->GetAbsBounds(); if ( bounds.ContainsPoint( targetPosition ) ) { targetTeleporter = testTeleporter; } } if ( targetTeleporter != NULL ) { targetTeleporter->Latch( other ); } // modify the position & angles if its a vehicle that should land on the ramp sdTransport* transportOther = other->Cast< sdTransport >(); idPlayer* playerOther = other->Cast< idPlayer >(); sdJetPack* jetPackOther = other->Cast< sdJetPack >(); bool shouldTraceDown = false; bool shouldOrientToRamp = false; bool shouldOrientBackTrace = false; float traceDownOffset = 0.0f; if ( transportOther != NULL && transportOther->GetVehicleControl() != NULL ) { shouldTraceDown = transportOther->GetVehicleControl()->TeleportOntoRamp(); shouldOrientToRamp = transportOther->GetVehicleControl()->TeleportOntoRampOriented(); shouldOrientBackTrace = transportOther->GetVehicleControl()->TeleportBackTraceOriented(); traceDownOffset = transportOther->GetVehicleControl()->TeleportOntoRampHeightOffset(); } if ( playerOther != NULL || jetPackOther != NULL ) { shouldTraceDown = true; } if ( shouldOrientToRamp ) { // find the normal of the surface trace_t downTrace; gameLocal.clip.TracePoint( CLIP_DEBUG_PARMS downTrace, targetPosition + idVec3( 0.0f, 0.0f, 128.0f ), targetPosition - idVec3( 0.0f, 0.0f, 512.0f ), CONTENTS_MOVEABLECLIP, NULL ); // find the new target axes using that idMat3 newTargetAxes; newTargetAxes[ 2 ] = downTrace.c.normal; newTargetAxes[ 1 ] = newTargetAxes[ 2 ].Cross( targetAxes[ 0 ] ); newTargetAxes[ 1 ].Normalize(); newTargetAxes[ 0 ] = newTargetAxes[ 1 ].Cross( newTargetAxes[ 2 ] ); newTargetAxes[ 0 ].Normalize(); targetAxes = newTargetAxes; } if ( shouldTraceDown ) { // trace down to find where to land trace_t downTrace; const idBounds& bounds = other->GetPhysics()->GetBounds(); idMat3 traceAxis = targetAxes; if ( !shouldOrientToRamp ) { traceAxis = mat3_identity; } gameLocal.clip.TraceBounds( CLIP_DEBUG_PARMS downTrace, targetPosition + idVec3( 0.0f, 0.0f, 128.0f ), targetPosition - idVec3( 0.0f, 0.0f, 512.0f ), bounds, traceAxis, CONTENTS_MOVEABLECLIP, NULL ); targetPosition = downTrace.endpos + idVec3( 0.0f, 0.0f, traceDownOffset ); } // trace from front to back against the trigger to make sure the new position is outside the teleporting trigger if ( targetTeleporter != NULL ) { trace_t backTrace; const idBounds& bounds = other->GetPhysics()->GetBounds(); idMat3 traceAxis = targetAxes; if ( !shouldOrientBackTrace ) { traceAxis = mat3_identity; } idClipModel* triggerCM = targetTeleporter->GetPhysics()->GetClipModel( 1 ); const idClipModel* boundsClip = gameLocal.clip.GetTemporaryClipModel( bounds ); idVec3 endTraceBack = targetPosition; idVec3 startTraceBack = endTraceBack + 1024.0f*targetAxes[ 0 ]; // check all the collision models of the other against our trigger model gameLocal.clip.TranslationModel( CLIP_DEBUG_PARMS backTrace, startTraceBack, endTraceBack, boundsClip, traceAxis, -1, triggerCM, triggerCM->GetOrigin(), triggerCM->GetAxis() ); if ( backTrace.fraction < 1.0f ) { // push forwards a bit targetPosition = backTrace.endpos + 32.0f * targetAxes[ 0 ]; } } teleportParms_t parms; parms.location = targetPosition; parms.orientation = targetAxes; parms.linearVelocity = exitVelocity * targetAxes; parms.angularVelocity = vec3_zero; parms.spawnId = gameLocal.GetSpawnId( other ); // finally, we want to check if the entity went in backwards, in which case // they should come out backwards too const idMat3& otherAxes = other->GetAxis(); if ( otherAxes[ 0 ] * myAxes[ 0 ] > 0.7f ) { parms.orientation[ 0 ] *= -1.0f; parms.orientation[ 1 ] *= -1.0f; } if ( delay > 0 ) { StartTeleport( parms ); return; } FinishTeleport( parms ); }
/* ===================== sdClientScriptEntity::Event_GetWorldAxis ===================== */ void sdClientScriptEntity::Event_GetWorldAxis( int index ) { sdProgram::ReturnVector( GetAxis()[ index ] ); }
/* ===================== sdClientScriptEntity::Event_PlayMaterialEffect ===================== */ void sdClientScriptEntity::Event_PlayMaterialEffect( const char *effectName, const idVec3& color, const char* jointName, const char* materialType, bool loop ) { rvClientEntityPtr< rvClientEffect > eff; eff = gameLocal.PlayEffect( spawnArgs, color, effectName, materialType, GetOrigin(), GetAxis(), loop ); sdProgram::ReturnHandle( eff.GetSpawnId() ); }
void hhHarvesterSimple::Event_EnterPassageway(hhAIPassageway *pn) { CancelEvents( &MA_OnProjectileLaunch ); // Clear any anti-projectile attacks CancelEvents( &MA_AntiProjectileAttack ); // Clear any anti-projectile attacks if (nextPassageway.IsValid()) { if (nextPassageway.GetEntity() != pn) { gameLocal.Warning("hhAIPassageway entered was not the specified one!\n"); } nextPassageway.Clear(); } if(currPassageway != NULL) { gameLocal.Error("%s tried to ENTER a passageway but already had a passageway!", (const char*)name); } HH_ASSERT(currPassageway == NULL); Hide(); // Should already be hidden but just to make sure // Only consider passageCount if damaged (ignores scripted passage sequences) or if it's the torso if (health < spawnHealth || !idStr::Icmp(spawnArgs.GetString("classname"), "monster_harvester_torso") ) { passageCount++; if (passageCount > 1) { //TODO make this affected by the DDA system AI_PASSAGEWAY_HEALTH = AI_PASSAGEWAY_HEALTH * 0.75f; // Reduce passageway seeking health level to 3/4 of it's original value } } GetAnimator()->ClearAllAnims(gameLocal.GetTime(), 0); Event_AnimState(ANIMCHANNEL_LEGS, "Legs_Idle", (int)0); Event_AnimState(ANIMCHANNEL_TORSO, "Torso_Idle", (int)0); torsoAnim.UpdateState(); legsAnim.UpdateState(); StartSound("snd_inside_passage", SND_CHANNEL_VOICE, SSF_LOOPING, true, NULL); currPassageway = pn; if(GetPhysics()) GetPhysics()->SetContents(0); // Does this passage way give us health? int h = 0; pn->spawnArgs.GetInt("give_health", "0", h); health += h; health = idMath::ClampInt(0, spawnArgs.GetInt("health"), health); // Should we transform to another monster when entering? idStr transTo; if(spawnArgs.GetString("passage_transform_to", "", transTo)) { const idDict *def = gameLocal.FindEntityDefDict( transTo ); if(!def) { gameLocal.Error("Unknown def : %s", (const char*)transTo); } // copy my target keys to the keys of the transformed-to entity idDict dict; dict.Copy(*def); for(int i=0;i<targets.Num();i++) { if(!targets[i].GetEntity()) continue; idStr key("target"); if(i > 0) sprintf(key, "target%i", i); dict.Set((const char*)key, (const char*)targets[i].GetEntity()->name); } // Passageway variables dict.SetInt("passage_health", AI_PASSAGEWAY_HEALTH); dict.SetInt("passage_count", passageCount); idEntity *e = NULL; gameLocal.SpawnEntityDef(dict, &e); HH_ASSERT( e->IsType( hhHarvesterSimple::Type ) ); hhHarvesterSimple *ai = static_cast<hhHarvesterSimple*>(e); ai->SetOrigin(GetOrigin()); ai->SetAxis(GetAxis()); ai->Event_EnterPassageway(pn); targets.Clear(); PostEventSec(&EV_Remove, 0.1f); return; } PostEventMS(&MA_HandlePassageway, CheckPassageFreqInitial); }
/* ===================== sdClientAnimated::UpdateModel ===================== */ void sdClientAnimated::UpdateModel( void ) { renderEntity.origin = GetOrigin(); renderEntity.axis = GetAxis(); }
// Take the result of the popup menu selection, figure out // what the user wanted, and take the appropriate action int CXYChart::InterpretPopupMenuItem( int result ) { int whichAxis, returnVal; if( result >= kMinimumPopupValue ) return result; if( result <= 0 ) return kPopupError; if( result <= kMenuMinorVertGrids ) { switch( result ) { case kMenuMajorHorizGrids: m_UseMajorHorizontalGrids = !m_UseMajorHorizontalGrids; break; case kMenuMajorVertGrids: m_UseMajorVerticalGrids = !m_UseMajorVerticalGrids; break; case kMenuMinorHorizGrids: m_UseMinorHorizontalGrids = !m_UseMinorHorizontalGrids; break; case kMenuMinorVertGrids: m_UseMinorVerticalGrids = !m_UseMinorVerticalGrids; break; default: break; } return kPopupUpdate; } if( result >= kMenuTitleFont && result < kMenuTitleFont + nFontSizes ) { m_TitleFont.lfHeight = fontSizes[result-kMenuTitleFont]; return kPopupUpdate; } if( result == kMenuPlotSettings ) { if( PlotSettings() ) return kPopupUpdate; else return kPopupNoAction; } if( result >= kMenuAxisMinimum && result < kMenuAxisMinimum + (kMaxAxes*kMenuAxisRange) ) { // These must be axis sets whichAxis = (result-kMenuAxisMinimum) / kMenuAxisRange; if( whichAxis < 0 || whichAxis > GetAxisCount() ) return kPopupError; if( result % kMenuAxisRange == kMenuAxisRange-1 ) // have to do this one manually if( AxisSettings(whichAxis) ) return kPopupUpdate; else return kPopupNoAction; if( (returnVal = GetAxis(whichAxis)->InterpretAxisPopupMenuItem( (result-kMenuAxisMinimum) % kMenuAxisRange ) ) == kPopupError ) return result; else return returnVal; } if( result >= kMenuDataMinimum && result < kMenuDataMinimum + kMaxDataSets*kMenuDataRange ) { int whichDataSet; whichDataSet = (result-kMenuDataMinimum) / kMenuDataRange; if( whichDataSet < 0 || whichDataSet > GetDataSetCount() ) return kPopupError; if( (result-kMenuDataMinimum) % kMenuDataRange == kMenuDataRange-1 ) // have to do this one manually if( DataSettings(whichDataSet) ) return kPopupUpdate; else return kPopupNoAction; if( (returnVal = InterpretDataSetPopupMenuItem( whichDataSet, (result-kMenuDataMinimum) % kMenuDataRange ) ) == kPopupError ) return result; else return returnVal; } return kPopupError; }
void CXTPChartRadarAxisXView::CreateTickMarks(CXTPChartDeviceContext* pDC) { UNREFERENCED_PARAMETER(pDC); m_arrTicks.RemoveAll(); m_arrMinorTicks.RemoveAll(); double dAxisMinValue = m_dMinValue; double dAxisMaxValue = m_dMaxValue; double dGridSpacing = GetGridSpacing(); int nOffset = m_pAxis->GetThickness() + (m_pAxis->GetTickMarks()->IsVisible() ? m_pAxis->GetTickMarks()->GetLength() : 0); if (m_pAxis->GetCustomLabels()->GetCount() > 0) { CXTPChartAxisCustomLabels* pCustomLabels = m_pAxis->GetCustomLabels(); int nCount = pCustomLabels->GetCount(); for (int i = 0; i < nCount; i++) { CXTPChartAxisCustomLabel* pLabel = pCustomLabels->GetAt(i); CXTPChartRadarAxisXViewTick tick; tick.m_dValue = !pLabel->GetAxisValue().IsEmpty() ? m_pAxis->GetScaleTypeMap()->ValueToInternal(pLabel->GetAxisValue()) : pLabel->GetAxisValueInternal(); if (tick.m_dValue >= dAxisMinValue && tick.m_dValue <= dAxisMaxValue) { tick.m_strLabel = pLabel->GetText(); CXTPChartTextPainter painter(pDC, tick.m_strLabel, m_pAxis->GetLabel()); tick.m_szLabel = painter.GetSize(); tick.m_szBounds = painter.GetRoundedBounds().Size(); double lineAngle = ValueToAngle(tick.m_dValue); CXTPChartSizeF size = painter.GetSize(); CXTPChartPointF startPoint(m_ptCenter.X + m_nRadius * cos(lineAngle), m_ptCenter.Y - m_nRadius * sin(lineAngle)); CXTPChartPointF finishPoint(startPoint.X + (float)(cos(lineAngle) * nOffset), startPoint.Y - (float)(sin(lineAngle) * nOffset)); CXTPChartRectF innerBounds; CXTPChartSeriesLabelConnectorPainterBase::CalcBorderBoundsForTangentDrawing(finishPoint, lineAngle, size, 0, innerBounds); innerBounds.Round(); tick.m_ptLocation = innerBounds.GetLocation(); m_arrTicks.Add(tick); } } } else { double dMark = m_dMinValue; while (dMark < dAxisMaxValue - CXTPChartMathUtils::m_dEPS) { CXTPChartRadarAxisXViewTick tick; tick.m_dValue = AxisToValue(dMark); tick.m_strLabel = m_pAxis->GetScaleTypeMap()->InternalToValue(m_pAxis->GetLabel()->GetFormat(), tick.m_dValue); CXTPChartTextPainter painter(pDC, tick.m_strLabel, m_pAxis->GetLabel()); tick.m_szLabel = painter.GetSize(); tick.m_szBounds = painter.GetRoundedBounds().Size(); double lineAngle = ValueToAngle(tick.m_dValue); CXTPChartSizeF size = painter.GetSize(); CXTPChartPointF startPoint(m_ptCenter.X + m_nRadius * cos(lineAngle), m_ptCenter.Y - m_nRadius * sin(lineAngle)); CXTPChartPointF finishPoint(startPoint.X + (float)(cos(lineAngle) * nOffset), startPoint.Y - (float)(sin(lineAngle) * nOffset)); CXTPChartRectF innerBounds; CXTPChartSeriesLabelConnectorPainterBase::CalcBorderBoundsForTangentDrawing(finishPoint, lineAngle, size, 0, innerBounds); innerBounds.Round(); tick.m_ptLocation = innerBounds.GetLocation(); m_arrTicks.Add(tick); dMark += dGridSpacing; } int nMinorCount = m_pAxis->GetMinorCount(); if (m_arrTicks.GetSize() > 0 && nMinorCount > 0) { double cur, prev; for (int i = 0; i <= m_arrTicks.GetSize(); i++) { if (m_pAxis->IsLogarithmic()) { cur = i == m_arrTicks.GetSize() ? m_arrTicks[i - 1].m_dValue * m_pAxis->GetLogarithmicBase() : m_arrTicks[i].m_dValue; prev = i == 0 ? m_arrTicks[0].m_dValue / m_pAxis->GetLogarithmicBase() : m_arrTicks[i - 1].m_dValue; } else { cur = i == m_arrTicks.GetSize() ? m_arrTicks[i - 1].m_dValue + dGridSpacing : m_arrTicks[i].m_dValue; prev = i == 0 ? cur - dGridSpacing : m_arrTicks[i - 1].m_dValue; } for (int j = 0; j < nMinorCount; j++) { double dValue = prev + (cur - prev) * (j + 1) / (nMinorCount + 1); if (dValue >= dAxisMinValue && dValue <= dAxisMaxValue) { m_arrMinorTicks.Add(dValue); } } } } } if (GetAxis()->IsVisible() && GetAxis()->GetLabel()->IsVisible()) { CXTPChartRadarDiagramView* pDiagramView = GetDiagramView(); for (int i = 0; i < m_arrTicks.GetSize(); i++) { CXTPChartRectF rc(m_arrTicks[i].m_ptLocation, m_arrTicks[i].m_szLabel); pDiagramView->CheckLabelBounds(rc); } } }
void hhShuttleTransport::Lock() { bLocked = true; dockedShuttle->SetOrigin(GetOrigin() + offsetShuttlePoint * GetAxis()); dockingForce.SetRestoreFactor(spawnArgs.GetFloat("dockingforce_locked")); dockedShuttle->Bind(this, false); }
void JoyPollOne(joystick_t *joy) { joy->previousButtonsField = joy->currentButtonsField; joy->currentButtonsField = 0; GetAxis(joy); // Get hat state, convert to direction for (int i = 0; i < joy->numHats; i++) { Uint8 hat = SDL_JoystickGetHat(joy->j, i); switch (hat) { case SDL_HAT_UP: joy->currentButtonsField |= CMD_UP; break; case SDL_HAT_RIGHT: joy->currentButtonsField |= CMD_RIGHT; break; case SDL_HAT_DOWN: joy->currentButtonsField |= CMD_DOWN; break; case SDL_HAT_LEFT: joy->currentButtonsField |= CMD_LEFT; break; case SDL_HAT_RIGHTUP: joy->currentButtonsField |= CMD_RIGHT; joy->currentButtonsField |= CMD_UP; break; case SDL_HAT_RIGHTDOWN: joy->currentButtonsField |= CMD_RIGHT; joy->currentButtonsField |= CMD_DOWN; break; case SDL_HAT_LEFTUP: joy->currentButtonsField |= CMD_LEFT; joy->currentButtonsField |= CMD_UP; break; case SDL_HAT_LEFTDOWN: joy->currentButtonsField |= CMD_LEFT; joy->currentButtonsField |= CMD_DOWN; break; case SDL_HAT_CENTERED: default: break; } } // Get buttons #define GET_BUTTON(_button, _cmd)\ if (SDL_JoystickGetButton(joy->j, _button))\ {\ joy->currentButtonsField |= _cmd;\ } GET_BUTTON(joy->Button1, CMD_BUTTON1); GET_BUTTON(joy->Button2, CMD_BUTTON2); GET_BUTTON(joy->ButtonMap, CMD_MAP); GET_BUTTON(joy->ButtonEsc, CMD_ESC); for (int i = 0; i < joy->numAxes; i++) { int x = SDL_JoystickGetAxis(joy->j, i); if (x < -JOY_AXIS_THRESHOLD || x > JOY_AXIS_THRESHOLD) { debug(D_NORMAL, "axis %d value %d\n", i, x); } } // Special controls switch (joy->Type) { case JOY_XBOX_360: // Right trigger fire { const int z = SDL_JoystickGetAxis(joy->j, 2); if (z < -JOY_AXIS_THRESHOLD) { joy->currentButtonsField |= CMD_BUTTON1; } } break; default: // do nothing break; } }
/** * Perform velocity approximation * return true if non-visible state reset is suggested */ static short ProcessVelocityData( DeviceVelocityPtr s, int dx, int dy, int time) { float cvelocity; int diff = time - s->lrm_time; int cur_ax, last_ax; short reset = (diff >= s->reset_time); /* remember last round's result */ s->last_velocity = s->velocity; cur_ax = GetAxis(dx, dy); last_ax = GetAxis(s->last_dx, s->last_dy); if(cur_ax != last_ax && cur_ax != -1 && last_ax != -1 && !reset){ /* correct for the error induced when diagonal movements are reported as alternating axis mickeys */ dx += s->last_dx; dy += s->last_dy; diff += s->last_diff; s->last_diff = time - s->lrm_time; /* prevent repeating add-up */ DebugAccelF("(dix ptracc) axial correction\n"); }else{ s->last_diff = diff; } /* * cvelocity is not a real velocity yet, more a motion delta. constant * acceleration is multiplied here to make the velocity an on-screen * velocity (pix/t as opposed to [insert unit]/t). This is intended to * make multiple devices with widely varying ConstantDecelerations respond * similar to acceleration controls. */ cvelocity = (float)sqrt(dx*dx + dy*dy) * s->const_acceleration; s->lrm_time = time; if (s->reset_time < 0 || diff < 0) { /* reset disabled or timer overrun? */ /* simply set velocity from current movement, no reset. */ s->velocity = cvelocity; return FALSE; } if (diff == 0) diff = 1; /* prevent div-by-zero, though it shouldn't happen anyway*/ /* translate velocity to dots/ms (somewhat intractable in integers, so we multiply by some per-device adjustable factor) */ cvelocity = cvelocity * s->corr_mul / (float)diff; /* short-circuit: when nv-reset the rest can be skipped */ if(reset == TRUE){ /* * we don't really have a velocity here, since diff includes inactive * time. This is dealt with in ComputeAcceleration. */ StuffFilterChain(s, cvelocity); s->velocity = s->last_velocity = cvelocity; s->last_reset = TRUE; DebugAccelF("(dix ptracc) non-visible state reset\n"); return TRUE; } if(s->last_reset == TRUE){ /* * when here, we're probably processing the second mickey of a starting * stroke. This happens to be the first time we can reasonably pretend * that cvelocity is an actual velocity. Thus, to opt precision, we * stuff that into the filter chain. */ s->last_reset = FALSE; DebugAccelF("(dix ptracc) after-reset vel:%.3f\n", cvelocity); StuffFilterChain(s, cvelocity); s->velocity = cvelocity; return FALSE; } /* feed into filter chain */ FeedFilterChain(s, cvelocity, diff); /* perform coupling and decide final value */ s->velocity = QueryFilterChain(s, cvelocity); DebugAccelF("(dix ptracc) guess: vel=%.3f diff=%d %i|%i|%i|%i|%i|%i|%i|%i|%i\n", s->velocity, diff, s->statistics.filter_usecount[0], s->statistics.filter_usecount[1], s->statistics.filter_usecount[2], s->statistics.filter_usecount[3], s->statistics.filter_usecount[4], s->statistics.filter_usecount[5], s->statistics.filter_usecount[6], s->statistics.filter_usecount[7], s->statistics.filter_usecount[8]); return FALSE; }
void CXTPChartRadarAxisXView::CalcSize(CXTPChartDeviceContext* pDC, CRect rcDiagram) { m_ptCenter.X = rcDiagram.CenterPoint().x; m_ptCenter.Y = rcDiagram.CenterPoint().y; m_nRadius = rcDiagram.Width() / 2; CXTPChartAxis* pAxis = GetAxis(); double dScreenLength = 2.0 * m_nRadius * CXTPChartMathUtils::m_dPI; if (dScreenLength < 1) { m_nSize = 0; return; } if (pAxis->GetGridSpacingAuto()) { double dRangeDelta = GetAxisRangeMaxValue() - GetAxisRangeMinValue(); m_dGridSpacing = CalculateGridSpacing(dRangeDelta, dScreenLength, 50); if (pAxis->IsLogarithmic()) m_dGridSpacing = max(1, m_dGridSpacing); } else { m_dGridSpacing = pAxis->GetGridSpacing(); } m_dMinValue = int(GetRangeMinValue() / m_dGridSpacing) * m_dGridSpacing; if (m_dMinValue > GetRangeMinValue() + CXTPChartMathUtils::m_dEPS) m_dMinValue -= m_dGridSpacing; m_dMaxValue = int(GetRangeMaxValue() / m_dGridSpacing) * m_dGridSpacing; if (m_dMaxValue < GetRangeMaxValue() - CXTPChartMathUtils::m_dEPS) m_dMaxValue += m_dGridSpacing; m_dMaxValue += m_dGridSpacing; pAxis->m_dGridSpacing = m_dGridSpacing; CreateTickMarks(pDC); if (!pAxis->IsVisible()) { m_nSize = 0; return; } m_nSize = pAxis->GetThickness(); if (pAxis->GetTickMarks()->IsVisible()) { m_nSize += pAxis->GetTickMarks()->GetLength(); } if (pAxis->GetLabel()->IsVisible()) { int nLabelSize = 0; for (int i = 0; i < m_arrTicks.GetSize(); i++) { CSize szBounds = m_arrTicks[i].m_szBounds; nLabelSize = max(nLabelSize, szBounds.cx); } m_nSize += nLabelSize; } }
// Show the contextual menu (shortcut menu) for an XY Chart. If passedMenu // is not NULL, the menu is appended to passedMenu, otherwise a new // menu is created int CXYChart::ShowPopupMenu( CMenu *passedMenu, CWnd *window, UINT nFlags, CPoint point ) { CMenu menu, *menuPtr; CMenu axisMenus[kMaxAxes]; int result, i; UINT flag; if( window == NULL ) return FALSE; if( passedMenu == NULL || (!::IsMenu(passedMenu->m_hMenu)) ) { menuPtr = &menu; menuPtr->CreatePopupMenu(); } else menuPtr = passedMenu; // Grids sub-menu { CMenu gridSubMenu; gridSubMenu.CreatePopupMenu(); flag = GetPopupCheckedFlag(this->m_UseMajorHorizontalGrids); gridSubMenu.AppendMenu( MF_STRING | flag, kMenuMajorHorizGrids, _T("Major Horizontal Grids")); flag = GetPopupCheckedFlag(this->m_UseMajorVerticalGrids); gridSubMenu.AppendMenu( MF_STRING | flag, kMenuMajorVertGrids, _T("Major Vertical Grids")); flag = GetPopupCheckedFlag(this->m_UseMinorHorizontalGrids); gridSubMenu.AppendMenu( MF_STRING | flag, kMenuMinorHorizGrids, _T("Minor Horizontal Grids")); flag = GetPopupCheckedFlag(this->m_UseMinorVerticalGrids); gridSubMenu.AppendMenu( MF_STRING | flag, kMenuMinorVertGrids, _T("Minor Vertical Grids")); menuPtr->AppendMenu( MF_POPUP | MF_STRING, (UINT) gridSubMenu.GetSafeHmenu(), _T("Grids")); } // Separator menuPtr->AppendMenu( MF_SEPARATOR); // Check for a title, and put in title size if needed if( this->m_Title != "" ) { AddFontSizePopup( menuPtr, _T("Title size"), this->m_TitleFont.lfHeight, kMenuTitleFont ); // Separator menuPtr->AppendMenu( MF_SEPARATOR); } // Axes for( i = 0; i < GetAxisCount(); i++ ) { GetAxis(i)->AddAxisPopupMenus( menuPtr, (kMenuAxisRange*i)+kMenuAxisMinimum ); } // Separator if( GetAxisCount() > 0 ) menuPtr->AppendMenu( MF_SEPARATOR); // Data sets for( i = 0; i < GetDataSetCount(); i++ ) { AddDataPopupMenus( i, menuPtr, (kMenuDataRange*i) + kMenuDataMinimum ); } // Separator if( GetDataSetCount() > 0 ) menuPtr->AppendMenu( MF_SEPARATOR); // Settings... menuPtr->AppendMenu( MF_STRING, kMenuPlotSettings, _T("Settings...")); result = menuPtr->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, point.x, point.y, window ); return InterpretPopupMenuItem( result ); }