diff --git a/code/__HELPERS/AStar.dm b/code/__HELPERS/AStar.dm index 7de6ef522a..c038e2e2e2 100644 --- a/code/__HELPERS/AStar.dm +++ b/code/__HELPERS/AStar.dm @@ -75,16 +75,26 @@ Actual Adjacent procs : //wrapper that returns an empty list if A* failed to find a path /proc/get_path_to(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id=null, turf/exclude=null, simulated_only = 1) - var/l = SSpathfinder.getfree(caller) + var/l = SSpathfinder.mobs.getfree(caller) while(!l) stoplag(3) - l = SSpathfinder.getfree(caller) + l = SSpathfinder.mobs.getfree(caller) var/list/path = AStar(caller, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent,id, exclude, simulated_only) - SSpathfinder.found(l) + SSpathfinder.mobs.found(l) if(!path) path = list() + return path +/proc/cir_get_path_to(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id=null, turf/exclude=null, simulated_only = 1) + var/l = SSpathfinder.circuits.getfree(caller) + while(!l) + stoplag(3) + l = SSpathfinder.circuits.getfree(caller) + var/list/path = AStar(caller, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent,id, exclude, simulated_only) + SSpathfinder.circuits.found(l) + if(!path) + path = list() return path /proc/AStar(caller, _end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id=null, turf/exclude=null, simulated_only = 1) diff --git a/code/controllers/subsystem/pathfinder.dm b/code/controllers/subsystem/pathfinder.dm index 2cd52a4da1..fe503b0b7a 100644 --- a/code/controllers/subsystem/pathfinder.dm +++ b/code/controllers/subsystem/pathfinder.dm @@ -2,39 +2,47 @@ SUBSYSTEM_DEF(pathfinder) name = "pathfinder" init_order = INIT_ORDER_PATH flags = SS_NO_FIRE - var/lcount = 10 - var/run - var/free - var/list/flow + var/datum/flowcache/mobs + var/datum/flowcache/circuits var/static/space_type_cache /datum/controller/subsystem/pathfinder/Initialize() space_type_cache = typecacheof(/turf/open/space) - run = 0 - free = 1 - flow = new() - flow.len=lcount - + mobs = new(10) + circuits = new(3) return ..() -/datum/controller/subsystem/pathfinder/proc/getfree(atom/M) +/datum/flowcache + var/lcount + var/run + var/free + var/list/flow + +/datum/flowcache/New(var/n) + .=..() + lcount = n + run = 0 + free = 1 + flow = new/list(lcount) + +/datum/flowcache/proc/getfree(atom/M) if(run < lcount) run += 1 while(flow[free]) CHECK_TICK free = (free % lcount) + 1 - var/t = addtimer(CALLBACK(SSpathfinder, /datum/controller/subsystem/pathfinder.proc/toolong, free), 150, TIMER_STOPPABLE) + var/t = addtimer(CALLBACK(src, /datum/flowcache.proc/toolong, free), 150, TIMER_STOPPABLE) flow[free] = t flow[t] = M return free else return 0 -/datum/controller/subsystem/pathfinder/proc/toolong(l) +/datum/flowcache/proc/toolong(l) log_game("Pathfinder route took longer than 150 ticks, src bot [flow[flow[l]]]") found(l) -/datum/controller/subsystem/pathfinder/proc/found(l) +/datum/flowcache/proc/found(l) deltimer(flow[l]) flow[l] = null run -= 1 diff --git a/code/controllers/subsystem/processing/circuit.dm b/code/controllers/subsystem/processing/circuit.dm index 9fc3683266..e5b4791907 100644 --- a/code/controllers/subsystem/processing/circuit.dm +++ b/code/controllers/subsystem/processing/circuit.dm @@ -15,7 +15,7 @@ PROCESSING_SUBSYSTEM_DEF(circuit) var/cost_multiplier = MINERAL_MATERIAL_AMOUNT / 10 // Each circuit cost unit is 200cm3 /datum/controller/subsystem/processing/circuit/Initialize(start_timeofday) - SScircuit.cipherkey = random_string(2000+rand(0,10), GLOB.alphabet) + SScircuit.cipherkey = uppertext(random_string(2000+rand(0,10), GLOB.alphabet)) circuits_init() return ..() diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm index 7681b5491b..6f4e8d586d 100644 --- a/code/datums/components/material_container.dm +++ b/code/datums/components/material_container.dm @@ -194,6 +194,30 @@ return amt return FALSE +/datum/component/material_container/proc/transer_amt_to(var/datum/component/material_container/T, amt, id) + if((amt==0)||(!T)||(!id)) + return FALSE + if(amt<0) + return T.transer_amt_to(src, -amt, id) + var/datum/material/M = materials[id] + + if(M) + var/tr = min(amt, M.amount,T.can_insert_amount(amt, id)) + if(tr) + use_amount_type(tr, id) + T.insert_amount(tr, id) + return tr + return FALSE + +/datum/component/material_container/proc/can_insert_amount(amt, id) + if(amt && id) + var/datum/material/M = materials[id] + if(M) + if((total_amount + amt) <= max_amount) + return amt + else + return (max_amount-total_amount) + /datum/component/material_container/proc/can_use_amount(amt, id, list/mats) if(amt && id) var/datum/material/M = materials[id] diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index 6815d60e88..7143459fe2 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -58,7 +58,9 @@ var/mob/living/M = caller if(!M.ventcrawler && M.mob_size != MOB_SIZE_TINY) return 0 - + var/atom/movable/M = caller + if(M && M.pulling) + return CanAStarPass(ID, to_dir, M.pulling) return 1 //diseases, stings, etc can pass /obj/structure/plasticflaps/CanPass(atom/movable/A, turf/T) diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index e62e26d576..0a70774847 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -22,13 +22,14 @@ var/charge_delay = 4 var/use_cyborg_cell = TRUE var/ext_next_use = 0 - var/atom/movable/collw + var/atom/collw var/allowed_circuit_action_flags = IC_ACTION_COMBAT | IC_ACTION_LONG_RANGE //which circuit flags are allowed var/combat_circuits = 0 //number of combat cicuits in the assembly, used for diagnostic hud var/long_range_circuits = 0 //number of long range cicuits in the assembly, used for diagnostic hud var/prefered_hud_icon = "hudstat" // Used by the AR circuit to change the hud icon. hud_possible = list(DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD, DIAG_CIRCUIT_HUD) //diagnostic hud overlays max_integrity = 50 + pass_flags = 0 armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) anchored = FALSE var/can_anchor = TRUE @@ -62,9 +63,9 @@ /obj/item/device/electronic_assembly/proc/check_interactivity(mob/user) return user.canUseTopic(src, BE_CLOSE) -/obj/item/device/electronic_assembly/CollidedWith(atom/movable/AM) +/obj/item/device/electronic_assembly/Collide(atom/AM) collw = AM - ..() + .=..() /obj/item/device/electronic_assembly/Initialize() .=..() @@ -501,10 +502,10 @@ 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. diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index 186a2df257..859c8910f3 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -94,7 +94,7 @@ complexity = 4 inputs = list() outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_REF) - activators = list() + activators = list("push ref" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH var/volume = 60 var/list/fuel = list("plasma" = 50000, "welding_fuel" = 15000, "carbon" = 10000, "ethanol" = 10000, "nutriment" = 8000) @@ -125,7 +125,7 @@ if(lfwb) if(B && B.data["cloneable"]) var/mob/M = B.data["donor"] - if(M && M.stat != DEAD && M.client) + if(M && (M.stat != DEAD) && (M.client)) bp = 500000 if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > bp) if(reagents.remove_reagent("blood", 1)) @@ -134,3 +134,7 @@ if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > fuel[I]) if(reagents.remove_reagent(I, 1)) assembly.give_power(fuel[I]*multi) + +/obj/item/integrated_circuit/passive/power/chemical_cell/do_work() + set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) + push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 23895d7023..5f7dd24ad9 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -293,7 +293,7 @@ /obj/item/integrated_circuit/converter/abs_to_rel_coords name = "abs to rel coordinate converter" desc = "Easily convert absolute coordinates to relative coordinates with this." - complexity = 4 + complexity = 1 inputs = list( "X1" = IC_PINTYPE_NUMBER, "Y1" = IC_PINTYPE_NUMBER, diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm index a769a16768..481360f6cf 100644 --- a/code/modules/integrated_electronics/subtypes/data_transfer.dm +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -75,8 +75,10 @@ /obj/item/integrated_circuit/transfer/demultiplexer/do_work() var/output_index = get_pin_data(IC_INPUT, 1) - for(var/i = 1 to outputs.len) - set_pin_data(IC_OUTPUT, i, i == output_index ? get_pin_data(IC_INPUT, 2) : null) + if(!isnull(output_index) && (output_index >= 1 && output_index <= outputs.len)) + var/datum/integrated_io/O = outputs[output_index] + O.data = get_pin_data(IC_INPUT, 2) + O.push_data() activate_pin(2) @@ -141,4 +143,17 @@ name = "sixteen pulse demultiplexer" icon_state = "dmux16" w_class = WEIGHT_CLASS_SMALL - number_of_pins = 16 \ No newline at end of file + number_of_pins = 16 + +/obj/item/integrated_circuit/transfer/wire_node + name = "wire node" + desc = "Just wire node to make wiring more easy.Transfer pulse from in to out." + icon_state = "wire_node" + activators = list("pulse in" = IC_PINTYPE_PULSE_IN, "pulse out" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 0 + complexity = 0 + size = 0.1 + +/obj/item/integrated_circuit/transfer/wire_node/do_work() + activate_pin(2) \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index c666f05d88..6ad3fc9797 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -344,13 +344,92 @@ else activate_pin(3) +/obj/item/integrated_circuit/input/turfpoint + name = "Tile pointer" + desc = "This circuit will get tile ref with given relative coorinates." + extended_desc = "If the machine cannot see the target, it will not be able to calculate the correct direction.\ + This circuit is working only in assembly." + icon_state = "numberpad" + complexity = 5 + inputs = list("X" = IC_PINTYPE_NUMBER,"Y" = IC_PINTYPE_NUMBER) + outputs = list("tile" = IC_PINTYPE_REF) + activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 40 + +/obj/item/integrated_circuit/input/turfpoint/do_work() + if(!assembly) + activate_pin(3) + return + var/turf/T = get_turf(assembly) + var/target_x = CLAMP(get_pin_data(IC_INPUT, 1) - assembly.x, 0, world.maxx) + var/target_y = CLAMP(get_pin_data(IC_INPUT, 2) - assembly.y, 0, world.maxy) + var/turf/A = locate(target_x, target_y, T.z) + set_pin_data(IC_OUTPUT, 1, null) + if(!A||!(A in view(T))) + activate_pin(3) + return + else + set_pin_data(IC_OUTPUT, 1, WEAKREF(A)) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/input/turfscan + name = "tile analyzer" + desc = "This machine vision system can analyze contents of desired tile.And can read letters on floor." + icon_state = "video_camera" + complexity = 5 + inputs = list( + "target" = IC_PINTYPE_REF + ) + outputs = list( + "located ref" = IC_PINTYPE_LIST, + "Written letters" = IC_PINTYPE_STRING + ) + activators = list( + "scan" = IC_PINTYPE_PULSE_IN, + "on scanned" = IC_PINTYPE_PULSE_OUT, + "not scanned" = IC_PINTYPE_PULSE_OUT + ) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 40 + cooldown_per_use = 10 + +/obj/item/integrated_circuit/input/turfscan/do_work() + var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom) + var/turf/T = get_turf(src) + var/turf/E = get_turf(H) + if(!istype(H)) //Invalid input + return + + if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see. + var/list/cont = new() + if(E.contents.len) + for(var/i = 1 to E.contents.len) + var/atom/U = E.contents[i] + cont += WEAKREF(U) + set_pin_data(IC_OUTPUT, 1, cont) + var/list/St = new() + for(var/obj/effect/decal/cleanable/crayon/I in E.contents) + St.Add(I.icon_state) + if(St.len) + set_pin_data(IC_OUTPUT, 2, jointext(St, ",", 1, 0)) + push_data() + activate_pin(2) + else + activate_pin(3) + /obj/item/integrated_circuit/input/local_locator name = "local locator" desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \ that is holding the machine containing it." inputs = list() - outputs = list("located ref") - activators = list("locate" = IC_PINTYPE_PULSE_IN) + outputs = list("located ref" = IC_PINTYPE_REF, + "is ground" = IC_PINTYPE_BOOLEAN, + "is creature" = IC_PINTYPE_BOOLEAN) + activators = list("locate" = IC_PINTYPE_PULSE_IN, + "on scanned" = IC_PINTYPE_PULSE_OUT + ) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 20 @@ -358,10 +437,11 @@ var/datum/integrated_io/O = outputs[1] O.data = null if(assembly) - if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us. - O.data = WEAKREF(assembly.loc) - - O.push_data() + O.data = WEAKREF(assembly.loc) + set_pin_data(IC_OUTPUT, 2, isturf(assembly.loc)) + set_pin_data(IC_OUTPUT, 3, ismob(assembly.loc)) + push_data() + activate_pin(2) /obj/item/integrated_circuit/input/adjacent_locator name = "adjacent locator" @@ -800,7 +880,8 @@ "cell charge" = IC_PINTYPE_NUMBER, "max charge" = IC_PINTYPE_NUMBER, "percentage" = IC_PINTYPE_NUMBER, - "refference to assembly" = IC_PINTYPE_REF + "refference to assembly" = IC_PINTYPE_REF, + "refference to cell" = IC_PINTYPE_REF ) activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -810,13 +891,15 @@ set_pin_data(IC_OUTPUT, 1, null) set_pin_data(IC_OUTPUT, 2, null) set_pin_data(IC_OUTPUT, 3, null) - set_pin_data(IC_OUTPUT, 4, WEAKREF(assembly)) + set_pin_data(IC_OUTPUT, 4, null) + set_pin_data(IC_OUTPUT, 5, null) if(assembly) + set_pin_data(IC_OUTPUT, 4, WEAKREF(assembly)) if(assembly.battery) - set_pin_data(IC_OUTPUT, 1, assembly.battery.charge) set_pin_data(IC_OUTPUT, 2, assembly.battery.maxcharge) set_pin_data(IC_OUTPUT, 3, 100*assembly.battery.charge/assembly.battery.maxcharge) + set_pin_data(IC_OUTPUT, 5, WEAKREF(assembly.battery)) push_data() activate_pin(2) @@ -851,8 +934,8 @@ set_pin_data(IC_OUTPUT, 1, C.charge) set_pin_data(IC_OUTPUT, 2, C.maxcharge) set_pin_data(IC_OUTPUT, 3, C.percent()) - activate_pin(2) push_data() + activate_pin(2) return /obj/item/integrated_circuit/input/ntnetsc @@ -891,3 +974,54 @@ set_pin_data(IC_OUTPUT, 1, null) push_data() activate_pin(3) + +/obj/item/integrated_circuit/input/matscan + name = "material scaner" + desc = "It's special module, designed to get information about material containers of different machinery.\ + Like ORM, lathes, etc." + icon_state = "video_camera" + complexity = 6 + inputs = list( + "target" = IC_PINTYPE_REF + ) + outputs = list( + "Metal" = IC_PINTYPE_NUMBER, + "Glass" = IC_PINTYPE_NUMBER, + "Silver" = IC_PINTYPE_NUMBER, + "Gold" = IC_PINTYPE_NUMBER, + "Diamond" = IC_PINTYPE_NUMBER, + "Solid Plasma" = IC_PINTYPE_NUMBER, + "Uranium" = IC_PINTYPE_NUMBER, + "Bananium" = IC_PINTYPE_NUMBER, + "Titanium" = IC_PINTYPE_NUMBER, + "Bluespace Mesh" = IC_PINTYPE_NUMBER, + "Biomass" = IC_PINTYPE_NUMBER, + ) + activators = list( + "scan" = IC_PINTYPE_PULSE_IN, + "on scanned" = IC_PINTYPE_PULSE_OUT, + "not scanned" = IC_PINTYPE_PULSE_OUT + ) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 40 + var/list/mtypes = list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE, MAT_BIOMASS) + + +/obj/item/integrated_circuit/input/matscan/do_work() + var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) + var/turf/T = get_turf(src) + GET_COMPONENT_FROM(mt, /datum/component/material_container, H) + if(!mt) //Invalid input + return + if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see. + for(var/I in 1 to mtypes.len) + var/datum/material/M = mt.materials[mtypes[I]] + if(M) + set_pin_data(IC_OUTPUT, I, M.amount) + else + set_pin_data(IC_OUTPUT, I, null) + push_data() + activate_pin(2) + else + activate_pin(3) + diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm index f8e858ef94..702ab588c5 100644 --- a/code/modules/integrated_electronics/subtypes/logic.dm +++ b/code/modules/integrated_electronics/subtypes/logic.dm @@ -16,7 +16,6 @@ activators = list("compare" = IC_PINTYPE_PULSE_IN, "on true result" = IC_PINTYPE_PULSE_OUT, "on false result" = IC_PINTYPE_PULSE_OUT) /obj/item/integrated_circuit/logic/binary/do_work() - pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/O = outputs[1] @@ -36,7 +35,6 @@ activators = list("compare" = IC_PINTYPE_PULSE_IN, "on compare" = IC_PINTYPE_PULSE_OUT) /obj/item/integrated_circuit/logic/unary/do_work() - pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/O = outputs[1] O.data = do_check(A) ? TRUE : FALSE @@ -66,7 +64,6 @@ var/lstate=FALSE /obj/item/integrated_circuit/logic/binary/jklatch/do_work() - pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/O = outputs[1] @@ -98,7 +95,6 @@ var/lstate=FALSE /obj/item/integrated_circuit/logic/binary/rslatch/do_work() - pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/O = outputs[1] @@ -128,7 +124,6 @@ var/lstate=FALSE /obj/item/integrated_circuit/logic/binary/gdlatch/do_work() - pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/O = outputs[1] diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index b30500fad4..b6b83b8469 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -101,7 +101,6 @@ shootAt(locate(target_x, target_y, T.z)) /obj/item/integrated_circuit/manipulation/weapon_firing/proc/shootAt(turf/target) - var/turf/T = get_turf(src) var/turf/U = target if(!istype(T) || !istype(U)) @@ -123,8 +122,6 @@ else A = new lethal_projectile(T) playsound(loc, lethal_projectile_sound, 75, 1) - - installed_gun.cell.use(shot.e_cost) //Shooting Code: A.preparePixelProjectile(target, src) @@ -139,7 +136,7 @@ Pulsing the 'step towards dir' activator pin will cause the machine to move a meter in that direction, assuming it is not \ being held, or anchored in some way. It should be noted that the ability to move is dependant on the type of assembly that this circuit inhabits." w_class = WEIGHT_CLASS_SMALL - complexity = 20 + complexity = 10 cooldown_per_use = 8 ext_cooldown = 1 inputs = list("direction" = IC_PINTYPE_DIR) @@ -163,6 +160,7 @@ return else set_pin_data(IC_OUTPUT, 1, WEAKREF(assembly.collw)) + push_data() activate_pin(3) return FALSE return FALSE @@ -314,6 +312,7 @@ spawn_flags = IC_SPAWN_RESEARCH power_draw_per_use = 50 var/max_items = 10 + /obj/item/integrated_circuit/manipulation/grabber/do_work() var/max_w_class = assembly.w_class var/atom/movable/acting_object = get_object() @@ -370,34 +369,49 @@ size = 3 cooldown_per_use = 5 complexity = 10 - inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_INDEX) + inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_INDEX,"dir" = IC_PINTYPE_DIR) 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) + activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT,"released" = IC_PINTYPE_PULSE_OUT,"pull to dir" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH power_draw_per_use = 50 ext_cooldown = 1 var/max_grab = GRAB_PASSIVE -/obj/item/integrated_circuit/manipulation/claw/do_work() +/obj/item/integrated_circuit/manipulation/claw/do_work(ord) 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) - mode = CLAMP(mode, GRAB_PASSIVE, max_grab) - if(AM) - if(check_target(AM, exclude_contents = TRUE)) - acting_object.start_pulling(AM,mode) + switch(ord) + if(1) + mode = CLAMP(mode, GRAB_PASSIVE, max_grab) + 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() + + if(4) if(acting_object.pulling) - set_pin_data(IC_OUTPUT, 1, TRUE) - else - set_pin_data(IC_OUTPUT, 1, FALSE) - push_data() + var/dir = get_pin_data(IC_INPUT, 3) + var/turf/G =get_step(get_turf(acting_object),dir) + var/atom/movable/pullee = acting_object.pulling + var/turf/Pl = get_turf(pullee) + var/turf/F = get_step_towards(Pl,G) + if(acting_object.Adjacent(F)) + if(!step_towards(pullee, F)) + F = get_step_towards2(Pl,G) + if(acting_object.Adjacent(F)) + step_towards(pullee, F) activate_pin(2) /obj/item/integrated_circuit/manipulation/claw/stop_pulling() - ..() set_pin_data(IC_OUTPUT, 1, FALSE) - activate_pin(2) + activate_pin(3) push_data() + ..() @@ -407,7 +421,7 @@ extended_desc = "The first and second inputs need to be numbers which correspond to coordinates to throw objects at relative to the machine itself. \ The 'fire' activator will cause the mechanism to attempt to throw objects at the coordinates, if possible. Note that the \ projectile need to be inside the machine, or to be on an adjacent tile, and must be medium sized or smaller." - complexity = 15 + complexity = 25 w_class = WEIGHT_CLASS_SMALL size = 2 cooldown_per_use = 10 @@ -457,3 +471,123 @@ A.forceMove(drop_location()) A.throw_at(locate(x_abs, y_abs, T.z), range, 3) + +/obj/item/integrated_circuit/manipulation/matman + name = "material manager" + desc = "It's module, designed to automatic storage and distribution of materials" + extended_desc = "The first input is ref to object of interaction.Second input used for interaction with stacks of materials.\ + It accepts amount of sheets to insert.Inputs 3-13 used to direct mat transer between containers of machines.\ + It accepts amount of material to transfer.Positive values means, that circuit will drain another machine.\ + Negative ones means, that machine needs to be filled.Outputs shows current stored amounts of mats." + icon_state = "grabber" + complexity = 16 + inputs = list( + "target" = IC_PINTYPE_REF, + "sheets to insert" = IC_PINTYPE_NUMBER, + "Metal" = IC_PINTYPE_NUMBER, + "Glass" = IC_PINTYPE_NUMBER, + "Silver" = IC_PINTYPE_NUMBER, + "Gold" = IC_PINTYPE_NUMBER, + "Diamond" = IC_PINTYPE_NUMBER, + "Uranium" = IC_PINTYPE_NUMBER, + "Solid Plasma" = IC_PINTYPE_NUMBER, + "Bluespace Mesh" = IC_PINTYPE_NUMBER, + "Bananium" = IC_PINTYPE_NUMBER, + "Titanium" = IC_PINTYPE_NUMBER, + ) + outputs = list( + "self ref" = IC_PINTYPE_REF, + "Total amount" = IC_PINTYPE_NUMBER, + "Metal" = IC_PINTYPE_NUMBER, + "Glass" = IC_PINTYPE_NUMBER, + "Silver" = IC_PINTYPE_NUMBER, + "Gold" = IC_PINTYPE_NUMBER, + "Diamond" = IC_PINTYPE_NUMBER, + "Uranium" = IC_PINTYPE_NUMBER, + "Solid Plasma" = IC_PINTYPE_NUMBER, + "Bluespace Mesh" = IC_PINTYPE_NUMBER, + "Bananium" = IC_PINTYPE_NUMBER, + "Titanium" = IC_PINTYPE_NUMBER + ) + activators = list( + "insert sheet" = IC_PINTYPE_PULSE_IN, + "transfer mats" = IC_PINTYPE_PULSE_IN, + "on success" = IC_PINTYPE_PULSE_OUT, + "on failure" = IC_PINTYPE_PULSE_OUT, + "push ref" = IC_PINTYPE_PULSE_IN, + "on push ref" = IC_PINTYPE_PULSE_IN + ) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 40 + ext_cooldown = 1 + cooldown_per_use = 10 + var/list/mtypes = list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE) + +/obj/item/integrated_circuit/manipulation/matman/Initialize() + var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, + list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0, + FALSE, list(/obj/item/stack, /obj/item/stack/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) + materials.max_amount =100000 + materials.precise_insertion = TRUE + .=..() + +/obj/item/integrated_circuit/manipulation/matman/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted) + GET_COMPONENT(materials, /datum/component/material_container) + set_pin_data(IC_OUTPUT, 2, materials.total_amount) + for(var/I in 1 to mtypes.len) + var/datum/material/M = materials.materials[mtypes[I]] + if(M) + set_pin_data(IC_OUTPUT, I+2, M.amount) + push_data() + +/obj/item/integrated_circuit/manipulation/matman/proc/is_insertion_ready(mob/user) + return TRUE + +/obj/item/integrated_circuit/manipulation/matman/do_work(ord) + GET_COMPONENT(materials, /datum/component/material_container) + var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) + if(!check_target(H)) + activate_pin(4) + return + var/turf/T = get_turf(H) + switch(ord) + if(1) + var/obj/item/stack/sheet/S = H + if(!S) + activate_pin(4) + return + if(materials.insert_stack(S, CLAMP(get_pin_data(IC_INPUT, 2),0,100), multiplier = 1) ) + AfterMaterialInsert() + activate_pin(3) + else + activate_pin(4) + if(2) + GET_COMPONENT_FROM(mt, /datum/component/material_container, H) + var/suc + for(var/I in 1 to mtypes.len) + var/datum/material/M = materials.materials[mtypes[I]] + if(M) + var/U = CLAMP(get_pin_data(IC_INPUT, I+2),-100000,100000) + if(!U) + continue + if(!mt) //Invalid input + if(U>0) + if(materials.retrieve_amount(U, mtypes[I], T)) + suc = TRUE + else + if(mt.transer_amt_to(materials, U, mtypes[I])) + suc = TRUE + if(suc) + AfterMaterialInsert() + activate_pin(3) + else + activate_pin(4) + if(4) + AfterMaterialInsert() + set_pin_data(IC_OUTPUT, 1, WEAKREF(src)) + activate_pin(5) + +/obj/item/integrated_circuit/manipulation/matman/Destroy() + GET_COMPONENT(materials, /datum/component/material_container) + materials.retrieve_all() + .=..() \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index 4a845ec25d..c1b173d8c2 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -11,7 +11,6 @@ activators = list("load data" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 10 - cooldown_per_use = 10 var/eol = "<br>" var/stuff_to_display = null @@ -53,6 +52,7 @@ desc = "Takes any data type as an input and displays it to the user upon examining, and to all nearby beings when pulsed." icon_state = "screen_large" power_draw_per_use = 40 + cooldown_per_use = 10 /obj/item/integrated_circuit/output/screen/large/do_work() ..() @@ -222,7 +222,7 @@ desc = "Takes any string as an input and will make the device say the string when pulsed." extended_desc = "This unit is more advanced than the plain speaker circuit, able to transpose any valid text to speech." icon_state = "speaker" - ext_cooldown = 2 + cooldown_per_use = 10 complexity = 12 inputs = list("text" = IC_PINTYPE_STRING) outputs = list() diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index dc47290545..6a5a8547c7 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -7,26 +7,113 @@ extended_desc = "This circuit uses a miniturized integrated camera to determine where the target is. If the machine \ cannot see the target, it will not be able to calculate the correct direction." icon_state = "numberpad" - complexity = 25 - inputs = list("target" = IC_PINTYPE_REF) + complexity = 5 + inputs = list("target" = IC_PINTYPE_REF,"ignore obstacles" = IC_PINTYPE_BOOLEAN) outputs = list("dir" = IC_PINTYPE_DIR) - activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT) + activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH power_draw_per_use = 40 /obj/item/integrated_circuit/smart/basic_pathfinder/do_work() var/datum/integrated_io/I = inputs[1] set_pin_data(IC_OUTPUT, 1, null) - if(!isweakref(I.data)) return + activate_pin(3) var/atom/A = I.data.resolve() if(!A) + activate_pin(3) return if(!(A in view(get_turf(src)))) push_data() + activate_pin(3) return // Can't see the target. - set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A))) + if(get_pin_data(IC_INPUT, 2)) + set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A))) + else + set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A))) push_data() activate_pin(2) + +/obj/item/integrated_circuit/smart/coord_basic_pathfinder + name = "coordinte pathfinder" + desc = "This complex circuit is able to determine what direction a given target is." + extended_desc = "This circuit uses absolute coordintes to determine where the target is. If the machine \ + cannot see the target, it will not be able to calculate the correct direction.This circuit is working only in assembly." + icon_state = "numberpad" + complexity = 5 + inputs = list("X" = IC_PINTYPE_NUMBER,"Y" = IC_PINTYPE_NUMBER,"ignore obstacles" = IC_PINTYPE_BOOLEAN) + outputs = list( "dir" = IC_PINTYPE_DIR, + "distance" = IC_PINTYPE_NUMBER + ) + activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 40 + +/obj/item/integrated_circuit/smart/coord_basic_pathfinder/do_work() + if(!assembly) + activate_pin(3) + return + var/turf/T = get_turf(assembly) + var/target_x = CLAMP(get_pin_data(IC_INPUT, 1), 0, world.maxx) + var/target_y = CLAMP(get_pin_data(IC_INPUT, 2), 0, world.maxy) + var/turf/A = locate(target_x, target_y, T.z) + set_pin_data(IC_OUTPUT, 1, null) + if(!A||A==T) + activate_pin(3) + return + if(get_pin_data(IC_INPUT, 2)) + set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A))) + else + set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A))) + set_pin_data(IC_OUTPUT, 2, sqrt((A.x-T.x)*(A.x-T.x)+ (A.y-T.y)*(A.y-T.y))) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/smart/advanced_pathfinder + name = "advanced pathfinder" + desc = "This complex circuit using complex processor for path planning." + extended_desc = "This circuit uses global coordinates for target. It will count as obstacle turf with given ref.Passkey\ + is the same as used in door remotes." + icon_state = "numberpad" + complexity = 40 + cooldown_per_use = 50 + inputs = list("X target" = IC_PINTYPE_NUMBER,"Y target" = IC_PINTYPE_NUMBER,"obstacle" = IC_PINTYPE_REF,"access" = IC_PINTYPE_STRING) + outputs = list("X" = IC_PINTYPE_LIST,"Y" = IC_PINTYPE_LIST) + activators = list("calculate path" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 80 + var/obj/item/card/id/idc + +/obj/item/integrated_circuit/smart/advanced_pathfinder/Initialize() + .=..() + idc = new(src) + +/obj/item/integrated_circuit/smart/advanced_pathfinder/do_work() + if(!assembly) + activate_pin(3) + return + var/Ps = get_pin_data(IC_INPUT, 4) + if(!Ps) + return + var/list/Pl = json_decode(XorEncrypt(hextostr(Ps, TRUE), SScircuit.cipherkey)) + if(Pl&&islist(Pl)) + idc.access = Pl + var/list/P = cir_get_path_to(assembly, locate(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2),assembly.z), /turf/proc/Distance_cardinal, 0, 200, id=idc, exclude=get_turf(get_pin_data_as_type(IC_INPUT,3, /atom)), simulated_only = 0) + + if(!P) + activate_pin(3) + return + else + var/list/Xn = new/list(P.len) + var/list/Yn = new/list(P.len) + var/turf/T + for(var/i =1 to P.len) + T=P[i] + Xn[i] = T.x + Yn[i] = T.y + set_pin_data(IC_OUTPUT, 1, Xn) + set_pin_data(IC_OUTPUT, 2, Yn) + push_data() + activate_pin(2) \ No newline at end of file diff --git a/icons/obj/assemblies/electronic_components.dmi b/icons/obj/assemblies/electronic_components.dmi index a9dac06d6b..51e3a589d1 100644 Binary files a/icons/obj/assemblies/electronic_components.dmi and b/icons/obj/assemblies/electronic_components.dmi differ