[READY]pathfinding circuitry upgrade (#36398)

* all in one

* fixfixfix

* uhhhh

* demuxdemuxdemuxdemux

* wire eriw

* icon noci

* tihsxifixshit

* rewopower

* fixif

* screeneercs

* returnruter
This commit is contained in:
arsserpentarium
2018-03-26 19:01:34 +03:00
committed by yogstation13-bot
parent 341843ddc8
commit c575ebbe7a
15 changed files with 482 additions and 68 deletions

View File

@@ -75,16 +75,26 @@ Actual Adjacent procs :
//wrapper that returns an empty list if A* failed to find a path //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) /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) while(!l)
stoplag(3) 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) var/list/path = AStar(caller, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent,id, exclude, simulated_only)
SSpathfinder.found(l) SSpathfinder.mobs.found(l)
if(!path) if(!path)
path = list() 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 return path
/proc/AStar(caller, _end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id=null, turf/exclude=null, simulated_only = 1) /proc/AStar(caller, _end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id=null, turf/exclude=null, simulated_only = 1)

View File

@@ -2,39 +2,47 @@ SUBSYSTEM_DEF(pathfinder)
name = "pathfinder" name = "pathfinder"
init_order = INIT_ORDER_PATH init_order = INIT_ORDER_PATH
flags = SS_NO_FIRE flags = SS_NO_FIRE
var/lcount = 10 var/datum/flowcache/mobs
var/run var/datum/flowcache/circuits
var/free
var/list/flow
var/static/space_type_cache var/static/space_type_cache
/datum/controller/subsystem/pathfinder/Initialize() /datum/controller/subsystem/pathfinder/Initialize()
space_type_cache = typecacheof(/turf/open/space) space_type_cache = typecacheof(/turf/open/space)
run = 0 mobs = new(10)
free = 1 circuits = new(3)
flow = new()
flow.len=lcount
return ..() 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) if(run < lcount)
run += 1 run += 1
while(flow[free]) while(flow[free])
CHECK_TICK CHECK_TICK
free = (free % lcount) + 1 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[free] = t
flow[t] = M flow[t] = M
return free return free
else else
return 0 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]]]") log_game("Pathfinder route took longer than 150 ticks, src bot [flow[flow[l]]]")
found(l) found(l)
/datum/controller/subsystem/pathfinder/proc/found(l) /datum/flowcache/proc/found(l)
deltimer(flow[l]) deltimer(flow[l])
flow[l] = null flow[l] = null
run -= 1 run -= 1

View File

@@ -15,7 +15,7 @@ PROCESSING_SUBSYSTEM_DEF(circuit)
var/cost_multiplier = MINERAL_MATERIAL_AMOUNT / 10 // Each circuit cost unit is 200cm3 var/cost_multiplier = MINERAL_MATERIAL_AMOUNT / 10 // Each circuit cost unit is 200cm3
/datum/controller/subsystem/processing/circuit/Initialize(start_timeofday) /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() circuits_init()
return ..() return ..()

View File

@@ -194,6 +194,30 @@
return amt return amt
return FALSE 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) /datum/component/material_container/proc/can_use_amount(amt, id, list/mats)
if(amt && id) if(amt && id)
var/datum/material/M = materials[id] var/datum/material/M = materials[id]

View File

@@ -58,7 +58,9 @@
var/mob/living/M = caller var/mob/living/M = caller
if(!M.ventcrawler && M.mob_size != MOB_SIZE_TINY) if(!M.ventcrawler && M.mob_size != MOB_SIZE_TINY)
return 0 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 return 1 //diseases, stings, etc can pass
/obj/structure/plasticflaps/CanPass(atom/movable/A, turf/T) /obj/structure/plasticflaps/CanPass(atom/movable/A, turf/T)

View File

@@ -22,13 +22,14 @@
var/charge_delay = 4 var/charge_delay = 4
var/use_cyborg_cell = TRUE var/use_cyborg_cell = TRUE
var/ext_next_use = 0 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/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/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/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. 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 hud_possible = list(DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD, DIAG_CIRCUIT_HUD) //diagnostic hud overlays
max_integrity = 50 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) armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0)
anchored = FALSE anchored = FALSE
var/can_anchor = TRUE var/can_anchor = TRUE
@@ -62,9 +63,9 @@
/obj/item/device/electronic_assembly/proc/check_interactivity(mob/user) /obj/item/device/electronic_assembly/proc/check_interactivity(mob/user)
return user.canUseTopic(src, BE_CLOSE) 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 collw = AM
..() .=..()
/obj/item/device/electronic_assembly/Initialize() /obj/item/device/electronic_assembly/Initialize()
.=..() .=..()
@@ -504,10 +505,10 @@
IC.ext_moved(oldLoc, dir) IC.ext_moved(oldLoc, dir)
/obj/item/device/electronic_assembly/stop_pulling() /obj/item/device/electronic_assembly/stop_pulling()
..()
for(var/I in assembly_components) for(var/I in assembly_components)
var/obj/item/integrated_circuit/IC = I var/obj/item/integrated_circuit/IC = I
IC.stop_pulling() IC.stop_pulling()
..()
// Returns the object that is supposed to be used in attack messages, location checks, etc. // Returns the object that is supposed to be used in attack messages, location checks, etc.

View File

@@ -94,7 +94,7 @@
complexity = 4 complexity = 4
inputs = list() inputs = list()
outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_REF) 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 spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
var/volume = 60 var/volume = 60
var/list/fuel = list("plasma" = 50000, "welding_fuel" = 15000, "carbon" = 10000, "ethanol" = 10000, "nutriment" = 8000) var/list/fuel = list("plasma" = 50000, "welding_fuel" = 15000, "carbon" = 10000, "ethanol" = 10000, "nutriment" = 8000)
@@ -125,7 +125,7 @@
if(lfwb) if(lfwb)
if(B && B.data["cloneable"]) if(B && B.data["cloneable"])
var/mob/M = B.data["donor"] var/mob/M = B.data["donor"]
if(M && M.stat != DEAD && M.client) if(M && (M.stat != DEAD) && (M.client))
bp = 500000 bp = 500000
if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > bp) if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > bp)
if(reagents.remove_reagent("blood", 1)) if(reagents.remove_reagent("blood", 1))
@@ -134,3 +134,7 @@
if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > fuel[I]) if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > fuel[I])
if(reagents.remove_reagent(I, 1)) if(reagents.remove_reagent(I, 1))
assembly.give_power(fuel[I]*multi) 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()

View File

@@ -293,7 +293,7 @@
/obj/item/integrated_circuit/converter/abs_to_rel_coords /obj/item/integrated_circuit/converter/abs_to_rel_coords
name = "abs to rel coordinate converter" name = "abs to rel coordinate converter"
desc = "Easily convert absolute coordinates to relative coordinates with this." desc = "Easily convert absolute coordinates to relative coordinates with this."
complexity = 4 complexity = 1
inputs = list( inputs = list(
"X1" = IC_PINTYPE_NUMBER, "X1" = IC_PINTYPE_NUMBER,
"Y1" = IC_PINTYPE_NUMBER, "Y1" = IC_PINTYPE_NUMBER,

View File

@@ -75,8 +75,10 @@
/obj/item/integrated_circuit/transfer/demultiplexer/do_work() /obj/item/integrated_circuit/transfer/demultiplexer/do_work()
var/output_index = get_pin_data(IC_INPUT, 1) var/output_index = get_pin_data(IC_INPUT, 1)
for(var/i = 1 to outputs.len) if(!isnull(output_index) && (output_index >= 1 && output_index <= outputs.len))
set_pin_data(IC_OUTPUT, i, i == output_index ? get_pin_data(IC_INPUT, 2) : null) var/datum/integrated_io/O = outputs[output_index]
O.data = get_pin_data(IC_INPUT, 2)
O.push_data()
activate_pin(2) activate_pin(2)
@@ -141,4 +143,17 @@
name = "sixteen pulse demultiplexer" name = "sixteen pulse demultiplexer"
icon_state = "dmux16" icon_state = "dmux16"
w_class = WEIGHT_CLASS_SMALL w_class = WEIGHT_CLASS_SMALL
number_of_pins = 16 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)

View File

@@ -344,13 +344,92 @@
else else
activate_pin(3) 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 /obj/item/integrated_circuit/input/local_locator
name = "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 \ 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." that is holding the machine containing it."
inputs = list() inputs = list()
outputs = list("located ref") outputs = list("located ref" = IC_PINTYPE_REF,
activators = list("locate" = IC_PINTYPE_PULSE_IN) "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 spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 20 power_draw_per_use = 20
@@ -358,10 +437,11 @@
var/datum/integrated_io/O = outputs[1] var/datum/integrated_io/O = outputs[1]
O.data = null O.data = null
if(assembly) if(assembly)
if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us. O.data = WEAKREF(assembly.loc)
O.data = WEAKREF(assembly.loc) set_pin_data(IC_OUTPUT, 2, isturf(assembly.loc))
set_pin_data(IC_OUTPUT, 3, ismob(assembly.loc))
O.push_data() push_data()
activate_pin(2)
/obj/item/integrated_circuit/input/adjacent_locator /obj/item/integrated_circuit/input/adjacent_locator
name = "adjacent locator" name = "adjacent locator"
@@ -800,7 +880,8 @@
"cell charge" = IC_PINTYPE_NUMBER, "cell charge" = IC_PINTYPE_NUMBER,
"max charge" = IC_PINTYPE_NUMBER, "max charge" = IC_PINTYPE_NUMBER,
"percentage" = 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) activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
@@ -810,13 +891,15 @@
set_pin_data(IC_OUTPUT, 1, null) set_pin_data(IC_OUTPUT, 1, null)
set_pin_data(IC_OUTPUT, 2, null) set_pin_data(IC_OUTPUT, 2, null)
set_pin_data(IC_OUTPUT, 3, 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) if(assembly)
set_pin_data(IC_OUTPUT, 4, WEAKREF(assembly))
if(assembly.battery) if(assembly.battery)
set_pin_data(IC_OUTPUT, 1, assembly.battery.charge) set_pin_data(IC_OUTPUT, 1, assembly.battery.charge)
set_pin_data(IC_OUTPUT, 2, assembly.battery.maxcharge) 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, 3, 100*assembly.battery.charge/assembly.battery.maxcharge)
set_pin_data(IC_OUTPUT, 5, WEAKREF(assembly.battery))
push_data() push_data()
activate_pin(2) activate_pin(2)
@@ -851,8 +934,8 @@
set_pin_data(IC_OUTPUT, 1, C.charge) set_pin_data(IC_OUTPUT, 1, C.charge)
set_pin_data(IC_OUTPUT, 2, C.maxcharge) set_pin_data(IC_OUTPUT, 2, C.maxcharge)
set_pin_data(IC_OUTPUT, 3, C.percent()) set_pin_data(IC_OUTPUT, 3, C.percent())
activate_pin(2)
push_data() push_data()
activate_pin(2)
return return
/obj/item/integrated_circuit/input/ntnetsc /obj/item/integrated_circuit/input/ntnetsc
@@ -891,3 +974,54 @@
set_pin_data(IC_OUTPUT, 1, null) set_pin_data(IC_OUTPUT, 1, null)
push_data() push_data()
activate_pin(3) 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)

View File

@@ -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) 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() /obj/item/integrated_circuit/logic/binary/do_work()
pull_data()
var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/A = inputs[1]
var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/B = inputs[2]
var/datum/integrated_io/O = outputs[1] var/datum/integrated_io/O = outputs[1]
@@ -36,7 +35,6 @@
activators = list("compare" = IC_PINTYPE_PULSE_IN, "on compare" = IC_PINTYPE_PULSE_OUT) activators = list("compare" = IC_PINTYPE_PULSE_IN, "on compare" = IC_PINTYPE_PULSE_OUT)
/obj/item/integrated_circuit/logic/unary/do_work() /obj/item/integrated_circuit/logic/unary/do_work()
pull_data()
var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/A = inputs[1]
var/datum/integrated_io/O = outputs[1] var/datum/integrated_io/O = outputs[1]
O.data = do_check(A) ? TRUE : FALSE O.data = do_check(A) ? TRUE : FALSE
@@ -66,7 +64,6 @@
var/lstate=FALSE var/lstate=FALSE
/obj/item/integrated_circuit/logic/binary/jklatch/do_work() /obj/item/integrated_circuit/logic/binary/jklatch/do_work()
pull_data()
var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/A = inputs[1]
var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/B = inputs[2]
var/datum/integrated_io/O = outputs[1] var/datum/integrated_io/O = outputs[1]
@@ -98,7 +95,6 @@
var/lstate=FALSE var/lstate=FALSE
/obj/item/integrated_circuit/logic/binary/rslatch/do_work() /obj/item/integrated_circuit/logic/binary/rslatch/do_work()
pull_data()
var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/A = inputs[1]
var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/B = inputs[2]
var/datum/integrated_io/O = outputs[1] var/datum/integrated_io/O = outputs[1]
@@ -128,7 +124,6 @@
var/lstate=FALSE var/lstate=FALSE
/obj/item/integrated_circuit/logic/binary/gdlatch/do_work() /obj/item/integrated_circuit/logic/binary/gdlatch/do_work()
pull_data()
var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/A = inputs[1]
var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/B = inputs[2]
var/datum/integrated_io/O = outputs[1] var/datum/integrated_io/O = outputs[1]

View File

@@ -101,7 +101,6 @@
shootAt(locate(target_x, target_y, T.z)) shootAt(locate(target_x, target_y, T.z))
/obj/item/integrated_circuit/manipulation/weapon_firing/proc/shootAt(turf/target) /obj/item/integrated_circuit/manipulation/weapon_firing/proc/shootAt(turf/target)
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
var/turf/U = target var/turf/U = target
if(!istype(T) || !istype(U)) if(!istype(T) || !istype(U))
@@ -123,8 +122,6 @@
else else
A = new lethal_projectile(T) A = new lethal_projectile(T)
playsound(loc, lethal_projectile_sound, 75, 1) playsound(loc, lethal_projectile_sound, 75, 1)
installed_gun.cell.use(shot.e_cost) installed_gun.cell.use(shot.e_cost)
//Shooting Code: //Shooting Code:
A.preparePixelProjectile(target, src) 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 \ 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." 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 w_class = WEIGHT_CLASS_SMALL
complexity = 20 complexity = 10
cooldown_per_use = 8 cooldown_per_use = 8
ext_cooldown = 1 ext_cooldown = 1
inputs = list("direction" = IC_PINTYPE_DIR) inputs = list("direction" = IC_PINTYPE_DIR)
@@ -163,6 +160,7 @@
return return
else else
set_pin_data(IC_OUTPUT, 1, WEAKREF(assembly.collw)) set_pin_data(IC_OUTPUT, 1, WEAKREF(assembly.collw))
push_data()
activate_pin(3) activate_pin(3)
return FALSE return FALSE
return FALSE return FALSE
@@ -314,6 +312,7 @@
spawn_flags = IC_SPAWN_RESEARCH spawn_flags = IC_SPAWN_RESEARCH
power_draw_per_use = 50 power_draw_per_use = 50
var/max_items = 10 var/max_items = 10
/obj/item/integrated_circuit/manipulation/grabber/do_work() /obj/item/integrated_circuit/manipulation/grabber/do_work()
var/max_w_class = assembly.w_class var/max_w_class = assembly.w_class
var/atom/movable/acting_object = get_object() var/atom/movable/acting_object = get_object()
@@ -370,34 +369,49 @@
size = 3 size = 3
cooldown_per_use = 5 cooldown_per_use = 5
complexity = 10 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) 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 spawn_flags = IC_SPAWN_RESEARCH
power_draw_per_use = 50 power_draw_per_use = 50
ext_cooldown = 1 ext_cooldown = 1
var/max_grab = GRAB_PASSIVE 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/obj/acting_object = get_object()
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
var/mode = get_pin_data(IC_INPUT, 2) var/mode = get_pin_data(IC_INPUT, 2)
mode = CLAMP(mode, GRAB_PASSIVE, max_grab) switch(ord)
if(AM) if(1)
if(check_target(AM, exclude_contents = TRUE)) mode = CLAMP(mode, GRAB_PASSIVE, max_grab)
acting_object.start_pulling(AM,mode) 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) if(acting_object.pulling)
set_pin_data(IC_OUTPUT, 1, TRUE) var/dir = get_pin_data(IC_INPUT, 3)
else var/turf/G =get_step(get_turf(acting_object),dir)
set_pin_data(IC_OUTPUT, 1, FALSE) var/atom/movable/pullee = acting_object.pulling
push_data() 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) activate_pin(2)
/obj/item/integrated_circuit/manipulation/claw/stop_pulling() /obj/item/integrated_circuit/manipulation/claw/stop_pulling()
..()
set_pin_data(IC_OUTPUT, 1, FALSE) set_pin_data(IC_OUTPUT, 1, FALSE)
activate_pin(2) activate_pin(3)
push_data() 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. \ 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 \ 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." 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 w_class = WEIGHT_CLASS_SMALL
size = 2 size = 2
cooldown_per_use = 10 cooldown_per_use = 10
@@ -457,3 +471,123 @@
A.forceMove(drop_location()) A.forceMove(drop_location())
A.throw_at(locate(x_abs, y_abs, T.z), range, 3) 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()
.=..()

View File

@@ -11,7 +11,6 @@
activators = list("load data" = IC_PINTYPE_PULSE_IN) activators = list("load data" = IC_PINTYPE_PULSE_IN)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 10 power_draw_per_use = 10
cooldown_per_use = 10
var/eol = "&lt;br&gt;" var/eol = "&lt;br&gt;"
var/stuff_to_display = null 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." 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" icon_state = "screen_large"
power_draw_per_use = 40 power_draw_per_use = 40
cooldown_per_use = 10
/obj/item/integrated_circuit/output/screen/large/do_work() /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." 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." extended_desc = "This unit is more advanced than the plain speaker circuit, able to transpose any valid text to speech."
icon_state = "speaker" icon_state = "speaker"
ext_cooldown = 2 cooldown_per_use = 10
complexity = 12 complexity = 12
inputs = list("text" = IC_PINTYPE_STRING) inputs = list("text" = IC_PINTYPE_STRING)
outputs = list() outputs = list()

View File

@@ -7,26 +7,113 @@
extended_desc = "This circuit uses a miniturized integrated camera to determine where the target is. If the machine \ 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." cannot see the target, it will not be able to calculate the correct direction."
icon_state = "numberpad" icon_state = "numberpad"
complexity = 25 complexity = 5
inputs = list("target" = IC_PINTYPE_REF) inputs = list("target" = IC_PINTYPE_REF,"ignore obstacles" = IC_PINTYPE_BOOLEAN)
outputs = list("dir" = IC_PINTYPE_DIR) 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 spawn_flags = IC_SPAWN_RESEARCH
power_draw_per_use = 40 power_draw_per_use = 40
/obj/item/integrated_circuit/smart/basic_pathfinder/do_work() /obj/item/integrated_circuit/smart/basic_pathfinder/do_work()
var/datum/integrated_io/I = inputs[1] var/datum/integrated_io/I = inputs[1]
set_pin_data(IC_OUTPUT, 1, null) set_pin_data(IC_OUTPUT, 1, null)
if(!isweakref(I.data)) if(!isweakref(I.data))
return return
activate_pin(3)
var/atom/A = I.data.resolve() var/atom/A = I.data.resolve()
if(!A) if(!A)
activate_pin(3)
return return
if(!(A in view(get_turf(src)))) if(!(A in view(get_turf(src))))
push_data() push_data()
activate_pin(3)
return // Can't see the target. 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() push_data()
activate_pin(2) 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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB