END_CHEAT_FUNCTION();
}
-float Drag(entity e, float candrag);
+float Drag(entity e, float grab);
void Drag_Begin(entity dragger, entity draggee, vector touchpoint);
void Drag_Finish(entity dragger);
float Drag_IsDraggable(entity draggee);
{
BEGIN_CHEAT_FUNCTION();
+ // Dragging can be used as either a cheat, or a function for some objects. If sv_cheats is active,
+ // the cheat dragging is used (unlimited pickup range and any entity can be carried). If sv_cheats
+ // is disabled, normal dragging is used (limited pickup range and only dragable objects can be carried),
+ // grabbing itself no longer being accounted as cheating.
+
switch(0)
{
default:
- if(self.BUTTON_DRAG && !cvar("g_sandbox"))
- {
- // consider dragging a cheat only if sandbox mode is disabled
- IS_CHEAT(0, 0, CHRAME_DRAG);
- }
if(autocvar_sv_cheats)
{
- // only use cheat dragging if cheats are enabled
+ // use cheat dragging if cheats are enabled
+ IS_CHEAT(0, 0, CHRAME_DRAG);
crosshair_trace_plusvisibletriggers(self);
- if(Drag(trace_ent, TRUE) && !cvar("g_sandbox"))
+ if(Drag(trace_ent, TRUE))
DID_CHEAT();
}
+ else
+ {
+ // drag is TRUE if the object can be picked up. While an object is being carried, the Drag() function
+ // must execute for it either way, otherwise it would cause bugs if it went out of the player's trace.
+ // This also makes sure that an object can only pe picked up if in range, but does not get dropped if
+ // it goes out of range while slinging it around.
+
+ float drag;
+ makevectors(self.v_angle);
+ WarpZone_TraceLine(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * autocvar_g_grab_range, MOVE_NORMAL, self);
+ switch(trace_ent.grab)
+ {
+ case 0: // can't grab
+ break;
+ case 1: // owner can grab
+ if(trace_ent.owner == self || trace_ent.realowner == self)
+ drag = TRUE;
+ break;
+ case 2: // owner and team mates can grab
+ if(!IsDifferentTeam(trace_ent.owner, self) || !IsDifferentTeam(trace_ent.realowner, self) || trace_ent.team == self.team)
+ drag = TRUE;
+ break;
+ case 3: // anyone can grab
+ drag = TRUE;
+ break;
+ default:
+ break;
+ }
+ Drag(trace_ent, drag); // execute dragging
+ }
break;
}
// ENTITY DRAGGING
-float Drag(entity e, float candrag)
+float Drag(entity e, float pick)
{
+ // returns TRUE when an entity has been picked up
+ // If pick is TRUE, the object can also be picked up if it's not being held already
+ // If pick is FALSE, only keep dragging the object if it's already being held
+
if(Drag_IsDragging(self))
{
if(self.BUTTON_DRAG)
else
{
if(Drag_CanDrag(self))
- if(self.BUTTON_DRAG && candrag)
+ if(self.BUTTON_DRAG && pick)
{
if(e)
if(Drag_IsDraggable(e))
float Drag_IsDraggable(entity draggee)
{
// TODO add more checks for bad stuff here
+ if(draggee == world)
+ return FALSE;
if(draggee.classname == "func_bobbing")
return FALSE;
if(draggee.classname == "door") // FIXME find out why these must be excluded, or work around the problem (trying to drag these causes like 4 fps)
}
}
-
-
-
-
-
void DragBox_Think()
{
if(self.aiment && self.enemy)