Пример #1
0
/*
==============
idGrabber::~idGrabber
==============
*/
idGrabber::~idGrabber( void ) {
	StopDrag( true );
	if ( beam ) {
		delete beam;
	}
	if ( beamTarget ) {
		delete beamTarget;
	}
}
Пример #2
0
	void InputHandler::processEvents(sf::Window& window) {
		reset();

		sf::Event event;
		while (window.pollEvent(event)) {
			switch (event.type) {
				case sf::Event::KeyPressed:
					if (key_press_callback_func != nullptr)
						key_press_callback_func(event.key);
					break;
				case sf::Event::KeyReleased:
					if (key_release_callback_func != nullptr)
						key_release_callback_func(event.key);
					break;
				case sf::Event::MouseMoved:
					m_NewMousePosition.x = event.mouseMove.x;
					m_NewMousePosition.y = event.mouseMove.y;

					if (mouse_moved_callback_func != nullptr)
						mouse_moved_callback_func(event.mouseMove);

					m_LastMousePosition.x = event.mouseMove.x;
					m_LastMousePosition.y = event.mouseMove.y;
					break;
				case sf::Event::MouseWheelScrolled:
					if (mouse_wheel_scroll_callback_func != nullptr)
						mouse_wheel_scroll_callback_func(event.mouseWheelScroll);
					break;
				case sf::Event::MouseButtonPressed:
					if (mouse_button_pressed_callback_func != nullptr)
						mouse_button_pressed_callback_func(event.mouseButton);
					StartDrag(event.mouseButton);
					break;
				case sf::Event::MouseButtonReleased:
					StopDrag(event.mouseButton);
					if (mouse_button_released_callback_func != nullptr)
						mouse_button_released_callback_func(event.mouseButton);
					break;
				case sf::Event::Closed:
					window.close();
					break;
			}
		}
	}
Пример #3
0
/*
==============
idGrabEntity::~idGrabEntity
==============
*/
idGrabEntity::~idGrabEntity( void )
{
    StopDrag( owner, true );
}
Пример #4
0
/*
==============
idGrabber::Update
==============
*/
int idGrabber::Update( idPlayer *player, bool hide ) {
	trace_t trace;
	idEntity *newEnt;

	// pause before allowing refire
	if ( lastFiredTime + FIRING_DELAY > gameLocal.time ) {
		return 3;
	}

	// Dead players release the trigger
	if ( hide || player->health <= 0 ) {
		StopDrag( true );
		if ( hide ) {
			lastFiredTime = gameLocal.time - FIRING_DELAY + 250;
		}
		return 3;
	}

	// Check if object being held has been removed (dead demon, projectile, etc.)
	if ( endTime > gameLocal.time ) {
		bool abort = !dragEnt.IsValid();

		if ( !abort && dragEnt.GetEntity()->IsType( idProjectile::Type ) ) {
			idProjectile *proj = (idProjectile *)dragEnt.GetEntity();

			if ( proj->GetProjectileState() >= 3 ) {
				abort = true;
			}
		}
		if ( !abort && dragEnt.GetEntity()->IsHidden() ) {
			abort = true;
		}
		// Not in multiplayer :: Pressing "reload" lets you carefully drop an item
		if ( !gameLocal.isMultiplayer && !abort && (( player->usercmd.flags & UCF_IMPULSE_SEQUENCE ) != ( oldUcmdFlags & UCF_IMPULSE_SEQUENCE )) && (player->usercmd.impulse == IMPULSE_13) ) {
			abort = true;
		}
        
		if ( abort ) {
			StopDrag( true );
			return 3;
		}
	}

	owner = player;

	// if no entity selected for dragging
    if ( !dragEnt.GetEntity() ) {
		idBounds bounds;
		idVec3 end = player->firstPersonViewOrigin + player->firstPersonViewAxis[0] * dragTraceDist;

		bounds.Zero();
		bounds.ExpandSelf( TRACE_BOUNDS_SIZE );

		gameLocal.clip.TraceBounds( trace, player->firstPersonViewOrigin, end, bounds, MASK_SHOT_RENDERMODEL|CONTENTS_PROJECTILE|CONTENTS_MOVEABLECLIP, player );
		// If the trace hit something
		if ( trace.fraction < 1.0f ) {
			newEnt = gameLocal.entities[ trace.c.entityNum ];

			// if entity is already being grabbed then bypass
			if ( gameLocal.isMultiplayer && newEnt->IsGrabbed() ) {
				return 0;
			}

			// Check if this is a valid entity to hold
			if ( newEnt && ( newEnt->IsType( idMoveable::Type ) ||
					newEnt->IsType( idMoveableItem::Type ) ||
					newEnt->IsType( idProjectile::Type ) ||
					newEnt->IsType( idAFEntity_Gibbable::Type ) ) &&
					newEnt->noGrab == false &&
					newEnt->GetPhysics()->GetBounds().GetRadius() < MAX_PICKUP_SIZE &&
					newEnt->GetPhysics()->GetLinearVelocity().LengthSqr() < MAX_PICKUP_VELOCITY ) {

				bool validAF = true;

				if ( newEnt->IsType( idAFEntity_Gibbable::Type ) ) {
					idAFEntity_Gibbable *afEnt = static_cast<idAFEntity_Gibbable*>(newEnt);

					if ( grabbableAI( newEnt->spawnArgs.GetString( "classname" ) ) ) {
						// Make sure it's also active
						if ( !afEnt->IsActive() ) {
							validAF = false;
						}
					} else if ( !afEnt->IsActiveAF() ) {
						validAF = false;
					}
				}

				if ( validAF && player->usercmd.buttons & BUTTON_ATTACK ) {
					// Grab this entity and start dragging it around
					StartDrag( newEnt, trace.c.id );
				} else if ( validAF ) {
					// A holdable object is ready to be grabbed
					return 1;
				}
			}
		}
	}

	// check backwards server time in multiplayer
	bool allow = true;

	if ( gameLocal.isMultiplayer ) {

		// if we've marched backwards
		if ( gameLocal.slow.time < startDragTime ) {
			allow = false;
		}
	}


	// if there is an entity selected for dragging
	if ( dragEnt.GetEntity() && allow ) {
		idPhysics *entPhys = dragEnt.GetEntity()->GetPhysics();
		idVec3 goalPos;

		// If the player lets go of attack, or time is up
		if ( !( player->usercmd.buttons & BUTTON_ATTACK ) ) {
			StopDrag( false );
			return 3;
		}
		if ( gameLocal.time > endTime ) {
			StopDrag( true );
			return 3;
		}

		// Check if the player is standing on the object
		if ( !holdingAF ) {
			idBounds	playerBounds;
			idBounds	objectBounds = entPhys->GetAbsBounds();
			idVec3		newPoint = player->GetPhysics()->GetOrigin();

			// create a bounds at the players feet
			playerBounds.Clear();
			playerBounds.AddPoint( newPoint );
			newPoint.z -= 1.f;
			playerBounds.AddPoint( newPoint );
			playerBounds.ExpandSelf( 8.f );

			// If it intersects the object bounds, then drop it
			if ( playerBounds.IntersectsBounds( objectBounds ) ) {
				StopDrag( true );
				return 3;
			}
		}

		// Shake the object at the end of the hold
		if ( g_grabberEnableShake.GetBool() && !gameLocal.isMultiplayer ) {
			ApplyShake();
		}

		// Set and evaluate drag force
		goalPos = player->firstPersonViewOrigin + localPlayerPoint * player->firstPersonViewAxis;

		drag.SetGoalPosition( goalPos );
		drag.Evaluate( gameLocal.time );

		// If an object is flying too fast toward the player, stop it hard
		if ( g_grabberHardStop.GetBool() ) {
			idPlane theWall;
			idVec3 toPlayerVelocity, objectCenter;
			float toPlayerSpeed;

			toPlayerVelocity = -player->firstPersonViewAxis[0];
			toPlayerSpeed = entPhys->GetLinearVelocity() * toPlayerVelocity;

			if ( toPlayerSpeed > 64.f ) {
				objectCenter = entPhys->GetAbsBounds().GetCenter();

				theWall.SetNormal( player->firstPersonViewAxis[0] );
				theWall.FitThroughPoint( goalPos );

				if ( theWall.Side( objectCenter, 0.1f ) == PLANESIDE_BACK ) {
					int i, num;

					num = entPhys->GetNumClipModels();
					for ( i=0; i<num; i++ ) {
						entPhys->SetLinearVelocity( vec3_origin, i );
					}
				}
			}

			// Make sure the object isn't spinning too fast
			const float MAX_ROTATION_SPEED = 12.f;

			idVec3	angVel = entPhys->GetAngularVelocity();
			float	rotationSpeed = angVel.LengthFast();

			if ( rotationSpeed > MAX_ROTATION_SPEED ) {
				angVel.NormalizeFast();
				angVel *= MAX_ROTATION_SPEED;
				entPhys->SetAngularVelocity( angVel );
			}
		}

		// Orient projectiles away from the player
		if ( dragEnt.GetEntity()->IsType( idProjectile::Type ) ) {
			idAngles ang = player->firstPersonViewAxis[0].ToAngles();
			ang.pitch += 90.f;
			entPhys->SetAxis( ang.ToMat3() );
		}

		// Some kind of effect from gun to object?
		UpdateBeams();

		// If the object is stuck away from its intended position for more than 500ms, let it go.
		if ( drag.GetDistanceToGoal() > DRAG_FAIL_LEN ) {
			if ( dragFailTime < (gameLocal.slow.time - 500) ) {
				StopDrag( true );
				return 3;
			}
		} else {
			dragFailTime = gameLocal.slow.time;
		}

		// Currently holding an object
		return 2;
	}

	// Not holding, nothing to hold
	return 0;
}
Пример #5
0
/*
==============
idGrabEntity::Update
==============
*/
void idGrabEntity::Update( idPlayer *player )
{
    owner = player;

    if ( lastThrownTime > gameLocal.time )
    {
        prevViewAngles = player->viewAngles;
        return;
    }

    bool valid = dragEnt.IsValid();

    // Check if object being held has been removed or player is dead
    if ( valid && dragEnt.GetEntity()->IsHidden() || player->health <= 0 )
    {
        StopDrag( player, true );
        prevViewAngles = player->viewAngles;
        return;
    }

    // attack throws object
    if ( valid && player->usercmd.buttons & BUTTON_ATTACK )
    {
        StopDrag( player, false );
        prevViewAngles = player->viewAngles;
        return;
    }

    // if there is an entity selected for dragging
    if ( dragEnt.GetEntity() )
    {
        idPhysics *entPhys = dragEnt.GetEntity()->GetPhysics();
        idVec3 goalPos;

        // Check if the player is standing on the object
        idBounds	playerBounds;
        idBounds	objectBounds = entPhys->GetAbsBounds();
        idVec3		newPoint = player->GetPhysics()->GetOrigin();

        // create a bounds at the players feet
        playerBounds.Clear();
        playerBounds.AddPoint( newPoint );
        newPoint.z -= 1.0f;
        playerBounds.AddPoint( newPoint );
        playerBounds.ExpandSelf( 8.0f );

        // If it intersects the object bounds, then drop it
        if ( playerBounds.IntersectsBounds( objectBounds ) )
        {
            StopDrag( player, true );
            prevViewAngles = player->viewAngles;
            return;
        }

        idAngles ang = entPhys->GetAxis().ToAngles();
        ang.yaw += player->viewAngles.yaw - prevViewAngles.yaw;
        if ( ang.yaw > 180.0f )
            ang.yaw -= 360.0f;
        else if ( ang.yaw < -180.0f )
            ang.yaw += 360.0f;
        entPhys->SetAxis( ang.ToMat3() );

        // Set and evaluate drag force
        goalPos = player->firstPersonViewOrigin + localPlayerPoint * player->firstPersonViewAxis;

        drag.SetGoalPosition( goalPos );
        drag.Evaluate( gameLocal.time, false );

        // If the object is stuck away from its intended position for more than 500ms, let it go.
        if ( drag.GetDistanceToGoal() > DRAG_FAIL_LEN )
        {
            if ( dragFailTime < gameLocal.time )
            {
                StopDrag( player, true );
                prevViewAngles = player->viewAngles;
                return;
            }
        }
        else
        {
            dragFailTime = gameLocal.time + 1000;
        }
    }
    prevViewAngles = player->viewAngles;
}
Пример #6
0
/*
==============
idDragEntity::DeleteSelected
==============
*/
void idDragEntity::DeleteSelected( void ) {
	delete selected.GetEntity();
	selected = NULL;
	StopDrag();
}
Пример #7
0
/*
==============
idDragEntity::SetSelected
==============
*/
void idDragEntity::SetSelected( idEntity *ent ) {
	selected = ent;
	StopDrag();
}
Пример #8
0
/*
==============
idDragEntity::Update
==============
*/
void idDragEntity::Update( idPlayer *player ) {
	idVec3 viewPoint, origin;
	idMat3 viewAxis, axis;
	trace_t trace;
	idEntity *newEnt;
	idAngles angles;
	jointHandle_t newJoint;
	idStr newBodyName;

	player->GetViewPos( viewPoint, viewAxis );

	// if no entity selected for dragging
	if ( !dragEnt.GetEntity() ) {

		if ( player->usercmd.buttons & BUTTON_ATTACK ) {

			gameLocal.clip.TracePoint( trace, viewPoint, viewPoint + viewAxis[0] * MAX_DRAG_TRACE_DISTANCE, (CONTENTS_SOLID|CONTENTS_RENDERMODEL|CONTENTS_BODY), player );
			if ( trace.fraction < 1.0f ) {

				newEnt = gameLocal.entities[ trace.c.entityNum ];
				if ( newEnt ) {

					if ( newEnt->GetBindMaster() ) {
						if ( newEnt->GetBindJoint() ) {
							trace.c.id = JOINT_HANDLE_TO_CLIPMODEL_ID( newEnt->GetBindJoint() );
						} else {
							trace.c.id = newEnt->GetBindBody();
						}
						newEnt = newEnt->GetBindMaster();
					}

					if ( newEnt->IsType( idAFEntity_Base::Type ) && static_cast<idAFEntity_Base *>(newEnt)->IsActiveAF() ) {
						idAFEntity_Base *af = static_cast<idAFEntity_Base *>(newEnt);

						// joint being dragged
						newJoint = CLIPMODEL_ID_TO_JOINT_HANDLE( trace.c.id );
						// get the body id from the trace model id which might be a joint handle
						trace.c.id = af->BodyForClipModelId( trace.c.id );
						// get the name of the body being dragged
						newBodyName = af->GetAFPhysics()->GetBody( trace.c.id )->GetName();

					} else if ( !newEnt->IsType( idWorldspawn::Type ) ) {

						if ( trace.c.id < 0 ) {
							newJoint = CLIPMODEL_ID_TO_JOINT_HANDLE( trace.c.id );
						} else {
							newJoint = INVALID_JOINT;
						}
						newBodyName = "";

					} else {

						newJoint = INVALID_JOINT;
						newEnt = NULL;
					}
				}
				if ( newEnt ) {
					dragEnt = newEnt;
					selected = newEnt;
					joint = newJoint;
					id = trace.c.id;
					bodyName = newBodyName;

					if ( !cursor ) {
						cursor = ( idCursor3D * )gameLocal.SpawnEntityType( idCursor3D::Type );
					}

					idPhysics *phys = dragEnt.GetEntity()->GetPhysics();
					localPlayerPoint = ( trace.c.point - viewPoint ) * viewAxis.Transpose();
					origin = phys->GetOrigin( id );
					axis = phys->GetAxis( id );
					localEntityPoint = ( trace.c.point - origin ) * axis.Transpose();

					cursor->drag.Init( g_dragDamping.GetFloat() );
					cursor->drag.SetPhysics( phys, id, localEntityPoint );
					cursor->Show();

					if ( phys->IsType( idPhysics_AF::Type ) ||
							phys->IsType( idPhysics_RigidBody::Type ) ||
								phys->IsType( idPhysics_Monster::Type ) ) {
						cursor->BecomeActive( TH_THINK );
					}
				}
			}
		}
	}

	// if there is an entity selected for dragging
	idEntity *drag = dragEnt.GetEntity();
	if ( drag ) {

		if ( !( player->usercmd.buttons & BUTTON_ATTACK ) ) {
			StopDrag();
			return;
		}

		cursor->SetOrigin( viewPoint + localPlayerPoint * viewAxis );
		cursor->SetAxis( viewAxis );

		cursor->drag.SetDragPosition( cursor->GetPhysics()->GetOrigin() );

		renderEntity_t *renderEntity = drag->GetRenderEntity();
		idAnimator *dragAnimator = drag->GetAnimator();

		if ( joint != INVALID_JOINT && renderEntity && dragAnimator ) {
			dragAnimator->GetJointTransform( joint, gameLocal.time, cursor->draggedPosition, axis );
			cursor->draggedPosition = renderEntity->origin + cursor->draggedPosition * renderEntity->axis;
			gameRenderWorld->DrawText( va( "%s\n%s\n%s, %s", drag->GetName(), drag->GetType()->classname, dragAnimator->GetJointName( joint ), bodyName.c_str() ), cursor->GetPhysics()->GetOrigin(), 0.1f, colorWhite, viewAxis, 1 );
		} else {
			cursor->draggedPosition = cursor->GetPhysics()->GetOrigin();
			gameRenderWorld->DrawText( va( "%s\n%s\n%s", drag->GetName(), drag->GetType()->classname, bodyName.c_str() ), cursor->GetPhysics()->GetOrigin(), 0.1f, colorWhite, viewAxis, 1 );
		}
	}

	// if there is a selected entity
	if ( selected.GetEntity() && g_dragShowSelection.GetBool() ) {
		// draw the bbox of the selected entity
		renderEntity_t *renderEntity = selected.GetEntity()->GetRenderEntity();
		if ( renderEntity ) {
			gameRenderWorld->DebugBox( colorYellow, idBox( renderEntity->bounds, renderEntity->origin, renderEntity->axis ) );
		}
	}
}
Пример #9
0
/*
==============
idDragEntity::~idDragEntity
==============
*/
idDragEntity::~idDragEntity( void ) {
	StopDrag();
	selected = NULL;
	delete cursor;
	cursor = NULL;
}