]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cheats.qc
Merge branch 'master' into mirceakitsune/sandbox
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cheats.qc
index e5a78a05edd5fa59f6f03358c03bf6d497fcead0..d2a21edc1002e0f27202b788ff2eea689e373bd5 100644 (file)
@@ -664,7 +664,7 @@ float CheatCommand(float argc)
        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);
@@ -682,21 +682,52 @@ float CheatFrame()
 {
        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;
        }
 
@@ -709,8 +740,12 @@ float CheatFrame()
 
 // 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)
@@ -745,7 +780,7 @@ float Drag(entity e, float candrag)
        else
        {
                if(Drag_CanDrag(self))
-                       if(self.BUTTON_DRAG && candrag)
+                       if(self.BUTTON_DRAG && pick)
                        {
                                if(e)
                                        if(Drag_IsDraggable(e))
@@ -830,6 +865,8 @@ void Drag_Finish(entity dragger)
 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)
@@ -938,11 +975,6 @@ void Drag_MoveDrag(entity from, entity to)
        }
 }
 
-
-
-
-
-
 void DragBox_Think()
 {
        if(self.aiment && self.enemy)