void TeleportWidget::Teleport() { QString start_location = regionLineEdit->text(); if (start_location.isEmpty()) start_location = regionComboBox->currentText(); if (start_location.isEmpty()) { return; } emit StartTeleport(start_location); AnimatedHide(); }
/*------------------------------------------------------------------- Procedure : Enable Teleport Input : uint8 * Data Output : nothing -------------------------------------------------------------------*/ void EVENT_TeleportEnable( uint8 * Data ) { StartTeleport( (uint16 *) Data ); }
/* ================ 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 ); }