From 1d91243ae2c07c0356c1ec58f8638688430018b2 Mon Sep 17 00:00:00 2001
From: arsserpentarium <32496644+arsserpentarium@users.noreply.github.com>
Date: Thu, 11 Jan 2018 23:02:56 +0300
Subject: [PATCH 1/2] [READY]Pulling claw 2 (#33817)
Pulling claw is integrated circuit,which allows drones to pull things.
---
code/game/atoms_movable.dm | 98 +++++++++++++++++++
code/game/machinery/magnet.dm | 10 +-
code/game/objects/objs.dm | 3 +
.../integrated_electronics/core/assemblies.dm | 11 ++-
.../subtypes/arithmetic.dm | 2 +-
.../subtypes/manipulation.dm | 39 ++++++++
code/modules/mob/living/living.dm | 16 ---
code/modules/mob/mob.dm | 20 ++--
code/modules/mob/mob_defines.dm | 2 -
code/modules/mob/mob_movement.dm | 18 ----
10 files changed, 162 insertions(+), 57 deletions(-)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 83012750e0..6c4720f3b5 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -27,6 +27,8 @@
var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm
var/floating = FALSE
var/movement_type = GROUND //Incase you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc.
+ var/atom/movable/pulling
+ var/grab_state = 0
/atom/movable/vv_edit_var(var_name, var_value)
var/static/list/banned_edits = list("step_x", "step_y", "step_size")
@@ -61,7 +63,91 @@
return FALSE
return ..()
+/atom/movable/proc/start_pulling(atom/movable/AM,gs)
+ if(QDELETED(AM))
+ return FALSE
+ if(!(AM.can_be_pulled(src)))
+ return FALSE
+
+ // If we're pulling something then drop what we're currently pulling and pull this instead.
+ if(pulling)
+ if(gs==0)
+ stop_pulling()
+ return FALSE
+ // Are we trying to pull something we are already pulling? Then just stop here, no need to continue.
+ if(AM == pulling)
+ grab_state = gs
+ return TRUE
+ stop_pulling()
+ if(AM.pulledby)
+ add_logs(AM, AM.pulledby, "pulled from", src)
+ AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
+ pulling = AM
+ AM.pulledby = src
+ grab_state = gs
+ if(ismob(AM))
+ var/mob/M = AM
+ add_logs(src, M, "grabbed", addition="passive grab")
+ visible_message("[src] has grabbed [M] passively!")
+ return TRUE
+
+/atom/movable/proc/stop_pulling()
+ if(pulling)
+ pulling.pulledby = null
+ var/mob/living/ex_pulled = pulling
+ pulling = null
+ grab_state = 0
+ if(isliving(ex_pulled))
+ var/mob/living/L = ex_pulled
+ L.update_canmove()// mob gets up if it was lyng down in a chokehold
+
+/atom/movable/proc/Move_Pulled(atom/A)
+ if(!pulling)
+ return
+ if(pulling.anchored || !pulling.Adjacent(src))
+ stop_pulling()
+ return
+ if(isliving(pulling))
+ var/mob/living/L = pulling
+ if(L.buckled && L.buckled.buckle_prevents_pull) //if they're buckled to something that disallows pulling, prevent it
+ stop_pulling()
+ return
+ if(A == loc && pulling.density)
+ return
+ if(!Process_Spacemove(get_dir(pulling.loc, A)))
+ return
+ step(pulling, get_dir(pulling.loc, A))
+
+/atom/movable/proc/check_pulling()
+ if(pulling)
+ var/atom/movable/pullee = pulling
+ if(pullee && get_dist(src, pullee) > 1)
+ stop_pulling()
+ return
+ if(!isturf(loc))
+ stop_pulling()
+ return
+ if(pullee && !isturf(pullee.loc) && pullee.loc != loc) //to be removed once all code that changes an object's loc uses forceMove().
+ log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
+ stop_pulling()
+ return
+ if(pulling.anchored)
+ stop_pulling()
+ return
+
+
+
+
/atom/movable/Move(atom/newloc, direct = 0)
+ var/atom/movable/pullee = pulling
+ var/turf/T = loc
+ if(pulling)
+ if(pullee && get_dist(src, pullee) > 1)
+ stop_pulling()
+
+ if(pullee && pullee.loc != loc && !isturf(pullee.loc) ) //to be removed once all code that changes an object's loc uses forceMove().
+ log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
+ stop_pulling()
if(!loc || !newloc)
return FALSE
var/atom/oldloc = loc
@@ -110,6 +196,18 @@
if(.)
Moved(oldloc, direct)
+ if(. && pulling && pulling == pullee) //we were pulling a thing and didn't lose it during our move.
+ if(pulling.anchored)
+ stop_pulling()
+ return
+ var/pull_dir = get_dir(src, pulling)
+ if(get_dist(src, pulling) > 1 || ((pull_dir - 1) & pull_dir)) //puller and pullee more than one tile away or in diagonal position
+ pulling.Move(T, get_dir(pulling, T)) //the pullee tries to reach our previous position
+ if(pulling && get_dist(src, pulling) > 1) //the pullee couldn't keep up
+ stop_pulling()
+ if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move.
+ pulledby.stop_pulling()
+
last_move = direct
setDir(direct)
diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm
index 8263795c60..7fcca578ef 100644
--- a/code/game/machinery/magnet.dm
+++ b/code/game/machinery/magnet.dm
@@ -21,7 +21,7 @@
var/code = 0 // frequency code, they should be different unless you have a group of magnets working together or something
var/turf/center // the center of magnetic attraction
var/on = FALSE
- var/pulling = 0
+ var/magneting = FALSE
// x, y modifiers to the center turf; (0, 0) is centered on the magnet, whereas (1, -1) is one tile right, one tile down
var/center_x = 0
@@ -165,12 +165,12 @@
updateicon()
-/obj/machinery/magnetic_module/proc/magnetic_process() // proc that actually does the pulling
- if(pulling)
+/obj/machinery/magnetic_module/proc/magnetic_process() // proc that actually does the magneting
+ if(magneting)
return
while(on)
- pulling = 1
+ magneting = TRUE
center = locate(x+center_x, y+center_y, z)
if(center)
for(var/obj/M in orange(magnetic_field, center))
@@ -185,7 +185,7 @@
use_power(electricity_level * 5)
sleep(13 - electricity_level)
- pulling = 0
+ magneting = FALSE
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index a5562e3ded..ce4b4d8d79 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -28,6 +28,8 @@
var/list/unique_reskin //List of options to reskin.
var/dangerous_possession = FALSE //Admin possession yes/no
+
+
/obj/vv_edit_var(vname, vval)
switch(vname)
if("dangerous_possession")
@@ -63,6 +65,7 @@
visible_message("[src] shatters into a million pieces!")
qdel(src)
+
/obj/assume_air(datum/gas_mixture/giver)
if(loc)
return loc.assume_air(giver)
diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm
index 637c3bfcee..f88c197120 100644
--- a/code/modules/integrated_electronics/core/assemblies.dm
+++ b/code/modules/integrated_electronics/core/assemblies.dm
@@ -38,6 +38,7 @@
/obj/item/device/electronic_assembly/process()
handle_idle_power()
+ check_pulling()
/obj/item/device/electronic_assembly/proc/handle_idle_power()
// First we generate power.
@@ -376,6 +377,13 @@
var/obj/item/integrated_circuit/IC = I
IC.ext_moved(oldLoc, dir)
+/obj/item/device/electronic_assembly/stop_pulling()
+ ..()
+ for(var/I in assembly_components)
+ var/obj/item/integrated_circuit/IC = I
+ IC.stop_pulling()
+
+
// Returns the object that is supposed to be used in attack messages, location checks, etc.
// Override in children for special behavior.
/obj/item/device/electronic_assembly/proc/get_object()
@@ -393,8 +401,7 @@
return acting_object.drop_location()
/obj/item/device/electronic_assembly/default //The /default electronic_assemblys are to allow the introduction of the new naming scheme without breaking old saves.
- name = "type-a electronic assembly"
-
+ name = "type-a electronic assembly"
/obj/item/device/electronic_assembly/calc
name = "type-b electronic assembly"
diff --git a/code/modules/integrated_electronics/subtypes/arithmetic.dm b/code/modules/integrated_electronics/subtypes/arithmetic.dm
index edb51ec01e..d6ec4b9eb6 100644
--- a/code/modules/integrated_electronics/subtypes/arithmetic.dm
+++ b/code/modules/integrated_electronics/subtypes/arithmetic.dm
@@ -306,4 +306,4 @@
set_pin_data(IC_OUTPUT, 1, result)
push_data()
- activate_pin(2)
+ activate_pin(2)
\ No newline at end of file
diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm
index 028c021a88..5ef422b77a 100644
--- a/code/modules/integrated_electronics/subtypes/manipulation.dm
+++ b/code/modules/integrated_electronics/subtypes/manipulation.dm
@@ -349,6 +349,45 @@
set_pin_data(IC_OUTPUT, 3, contents.len)
push_data()
+/obj/item/integrated_circuit/manipulation/claw
+ name = "pulling claw"
+ desc = "Circuit which can pull things.."
+ icon_state = "pull_claw"
+ extended_desc = "The circuit accepts a reference to thing to be pulled. Modes: 0 for release.1 for pull. 2 for gressive grab."
+ w_class = WEIGHT_CLASS_SMALL
+ size = 3
+
+ complexity = 10
+ inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_INDEX)
+ outputs = list("is pulling" = IC_PINTYPE_BOOLEAN)
+ activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT,"released" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_RESEARCH
+ power_draw_per_use = 50
+ var/max_grab = 2 //change it to 1 if you tired of drone kung-fu.Return it to 2 if you miss it.
+
+/obj/item/integrated_circuit/manipulation/claw/do_work()
+ var/obj/acting_object = get_object()
+ var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
+ var/mode = get_pin_data(IC_INPUT, 2)
+ if(mode>max_grab)
+ return
+ if(AM)
+ if(check_target(AM, exclude_contents = TRUE))
+ acting_object.start_pulling(AM,mode)
+ if(acting_object.pulling)
+ set_pin_data(IC_OUTPUT, 1, TRUE)
+ else
+ set_pin_data(IC_OUTPUT, 1, FALSE)
+ push_data()
+ activate_pin(2)
+
+/obj/item/integrated_circuit/manipulation/claw/stop_pulling()
+ ..()
+ set_pin_data(IC_OUTPUT, 1, FALSE)
+ activate_pin(2)
+ push_data()
+
+
/obj/item/integrated_circuit/manipulation/thrower
name = "thrower"
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 2afbabef85..322b16de1b 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -452,24 +452,8 @@
return 0
var/old_direction = dir
- var/atom/movable/pullee = pulling
- if(pullee && get_dist(src, pullee) > 1)
- stop_pulling()
- if(pullee && !isturf(pullee.loc) && pullee.loc != loc) //to be removed once all code that changes an object's loc uses forceMove().
- log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
- stop_pulling()
var/turf/T = loc
. = ..()
- if(. && pulling && pulling == pullee) //we were pulling a thing and didn't lose it during our move.
- if(pulling.anchored)
- stop_pulling()
- return
-
- var/pull_dir = get_dir(src, pulling)
- if(get_dist(src, pulling) > 1 || ((pull_dir - 1) & pull_dir)) //puller and pullee more than one tile away or in diagonal position
- pulling.Move(T, get_dir(pulling, T)) //the pullee tries to reach our previous position
- if(pulling && get_dist(src, pulling) > 1) //the pullee couldn't keep up
- stop_pulling()
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move.
pulledby.stop_pulling()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 79260008ed..e78adfe697 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -335,7 +335,7 @@
return 1
//this and stop_pulling really ought to be /mob/living procs
-/mob/proc/start_pulling(atom/movable/AM, supress_message = 0)
+/mob/start_pulling(atom/movable/AM, supress_message = 0)
if(!AM || !src)
return FALSE
if(!(AM.can_be_pulled(src)))
@@ -410,20 +410,14 @@
setDir(D)
spintime -= speed
-/mob/verb/stop_pulling()
+/mob/stop_pulling()
+ ..()
+ update_pull_hud_icon()
+
+/mob/verb/stop_pulling1()
set name = "Stop Pulling"
set category = "IC"
-
- if(pulling)
- pulling.pulledby = null
- var/mob/living/ex_pulled = pulling
- pulling = null
- grab_state = 0
- update_pull_hud_icon()
-
- if(isliving(ex_pulled))
- var/mob/living/L = ex_pulled
- L.update_canmove()// mob gets up if it was lyng down in a chokehold
+ stop_pulling()
/mob/proc/update_pull_hud_icon()
if(hud_used)
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 9afeadc60b..a6ee2712af 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -29,8 +29,6 @@
var/obj/machinery/machine = null
var/other_mobs = null
- var/atom/movable/pulling = null
- var/grab_state = 0
var/next_move = null
var/notransform = null //Carbon
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index cbc74317fe..4a7278289c 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -266,24 +266,6 @@
/mob/proc/mob_negates_gravity()
return FALSE
-//moves the mob/object we're pulling
-/mob/proc/Move_Pulled(atom/A)
- if(!pulling)
- return
- if(pulling.anchored || !pulling.Adjacent(src))
- stop_pulling()
- return
- if(isliving(pulling))
- var/mob/living/L = pulling
- if(L.buckled && L.buckled.buckle_prevents_pull) //if they're buckled to something that disallows pulling, prevent it
- stop_pulling()
- return
- if(A == loc && pulling.density)
- return
- if(!Process_Spacemove(get_dir(pulling.loc, A)))
- return
- step(pulling, get_dir(pulling.loc, A))
-
/mob/proc/slip(s_amount, w_amount, obj/O, lube)
return