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