diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm index f6cbab25230..293657dff5f 100644 --- a/code/game/machinery/bots/cleanbot.dm +++ b/code/game/machinery/bots/cleanbot.dm @@ -37,12 +37,28 @@ var/oldloc = null req_access = list(access_janitor) var/path[] = new() + var/patrol_path[] = null + var/beacon_freq = 1445 // navigation beacon frequency + var/closest_dist + var/closest_loc + var/failed_steps + var/should_patrol + var/next_dest + var/next_dest_loc /obj/machinery/bot/cleanbot/New() ..() src.get_targets() src.icon_state = "cleanbot[src.on]" + should_patrol = 0 + + src.botcard = new /obj/item/weapon/card/id(src) + src.botcard.access = get_access("Detective") + + if(radio_controller) + radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS) + /obj/machinery/bot/cleanbot/turn_on() . = ..() @@ -70,12 +86,12 @@ dat += text({" Automatic Station Cleaner v1.0

Status: []
-Behaviour controls are [src.locked ? "locked" : "unlocked"]""}, +Behaviour controls are [src.locked ? "locked" : "unlocked"]"}, text("[src.on ? "On" : "Off"]")) if(!src.locked) - dat += text({"
-Cleans Blood: []
"}, -text("[src.blood ? "Yes" : "No"]")) + dat += text({"
Cleans Blood: []
"}, text("[src.blood ? "Yes" : "No"]")) + dat += text({"
Patrol station: []
"}, text("[src.should_patrol ? "Yes" : "No"]")) + // dat += text({"
Beacon frequency: []
"}, text("[src.beacon_freq]")) if(src.panelopen && !src.locked) dat += text({" Odd looking screw twiddled: []
@@ -102,6 +118,15 @@ text("[src.oddbutton ? "Yes" : "No" src.blood =!src.blood src.get_targets() src.updateUsrDialog() + if("patrol") + src.should_patrol =!src.should_patrol + src.patrol_path = null + src.updateUsrDialog() + if("freq") + var/freq = text2num(input("Select frequency for navigation beacons", "Frequnecy", num2text(beacon_freq / 10))) * 10 + if (freq > 0) + src.beacon_freq = freq + src.updateUsrDialog() if("screw") src.screwloose = !src.screwloose usr << "You twiddle the screw." @@ -185,6 +210,35 @@ text("[src.oddbutton ? "Yes" : "No" if(!src.target || src.target == null) if(src.loc != src.oldloc) src.oldtarget = null + + if (!should_patrol) + return + + if (!patrol_path || patrol_path.len < 1) + var/datum/radio_frequency/frequency = radio_controller.return_frequency(beacon_freq) + + if(!frequency) return + + closest_dist = 9999 + closest_loc = null + next_dest_loc = null + + var/datum/signal/signal = new() + signal.source = src + signal.transmission_method = 1 + signal.data = list("findbeacon" = "patrol") + frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS) + spawn(5) + if (!next_dest_loc) + next_dest_loc = closest_loc + if (next_dest_loc) + src.patrol_path = AStar(src.loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=null) + src.patrol_path = reverselist(src.patrol_path) + else + patrol_move() + spawn(5) + patrol_move() + return if(src.target && (src.target != null) && src.path.len == 0) @@ -202,6 +256,7 @@ text("[src.oddbutton ? "Yes" : "No" step_to(src, target) if(src.target && (src.target != null)) + patrol_path = null if(src.loc == src.target.loc) clean(src.target) src.path = new() @@ -210,17 +265,54 @@ text("[src.oddbutton ? "Yes" : "No" src.oldloc = src.loc +/obj/machinery/bot/cleanbot/proc/patrol_move() + if (src.patrol_path.len <= 0) + return + + var/next = src.patrol_path[1] + src.patrol_path -= next + if (next == src.loc) + return + + var/moved = step_towards(src, next) + if (!moved) + failed_steps++ + if (failed_steps > 4) + patrol_path = null + next_dest = null + failed_steps = 0 + else + failed_steps = 0 + +/obj/machinery/bot/cleanbot/receive_signal(datum/signal/signal) + var/recv = signal.data["beacon"] + var/valid = signal.data["patrol"] + if(!recv || !valid) + return + + var/dist = get_dist(src, signal.source.loc) + if (dist < closest_dist && signal.source.loc != src.loc) + closest_dist = dist + closest_loc = signal.source.loc + next_dest = signal.data["next_patrol"] + + if (recv == next_dest) + next_dest_loc = signal.source.loc + next_dest = signal.data["next_patrol"] + /obj/machinery/bot/cleanbot/proc/get_targets() src.target_types = new/list() - if(src.blood) + target_types += /obj/effect/decal/cleanable/oil + target_types += /obj/effect/decal/cleanable/vomit + target_types += /obj/effect/decal/cleanable/robot_debris + target_types += /obj/effect/decal/cleanable/crayon + + if(src.blood) target_types += /obj/effect/decal/cleanable/xenoblood/ target_types += /obj/effect/decal/cleanable/xenoblood/xgibs target_types += /obj/effect/decal/cleanable/blood/ target_types += /obj/effect/decal/cleanable/blood/gibs/ - target_types += /obj/effect/decal/cleanable/oil - target_types += /obj/effect/decal/cleanable/robot_debris - target_types += /obj/effect/decal/cleanable/crayon /obj/machinery/bot/cleanbot/proc/clean(var/obj/effect/decal/cleanable/target) src.anchored = 1 @@ -274,10 +366,4 @@ text("[src.oddbutton ? "Yes" : "No" if (!in_range(src, usr) && src.loc != usr) return - src.created_name = t - - - - - - + src.created_name = t \ No newline at end of file diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index bc0d07d57e8..6774671f16c 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -40,7 +40,7 @@ display round(lastgen) and plasmatank amount //Baseline portable generator. Has all the default handling. Not intended to be used on it's own (since it generates unlimited power). /obj/machinery/power/port_gen - name = "protable generator" + name = "Portable Generator" desc = "A portable generator for emergency backup power" icon = 'power.dmi' icon_state = "portgen0" @@ -48,11 +48,13 @@ display round(lastgen) and plasmatank amount anchored = 0 directwired = 1 use_power = 0 + var active = 0 power_gen = 5000 open = 0 recent_fault = 0 + power_output = 1 proc HasFuel() //Placeholder for fuel check. @@ -61,15 +63,25 @@ display round(lastgen) and plasmatank amount UseFuel() //Placeholder for fuel use. return + handleInactive() + return + process() - if(active && HasFuel() && !crit_fail && powernet) - if(prob(reliability)) add_avail(power_gen) - else if(!recent_fault) recent_fault = 1 + if(active && HasFuel() && !crit_fail && anchored) + if(prob(reliability)) + add_avail(power_gen * power_output) + else if(!recent_fault) + recent_fault = 1 else crit_fail = 1 UseFuel() + for(var/mob/M in viewers(1, src)) + if (M.client && M.machine == src) + src.updateUsrDialog() + else active = 0 icon_state = initial(icon_state) + handleInactive() attack_hand(mob/user as mob) if(..()) @@ -88,9 +100,13 @@ display round(lastgen) and plasmatank amount name = "P.A.C.M.A.N.-type Portable Generator" var coins = 0 - max_coins = 120 + max_coins = 1000 coin_path = "/obj/item/weapon/coin/plasma" board_path = "/obj/item/weapon/circuitboard/pacman" + coin_left = 0 // How much is left of the coin + time_per_coin = 1 + emagged = 0 + heat = 0 New() ..() @@ -108,7 +124,7 @@ display round(lastgen) and plasmatank amount var/temp_reliability = 0 for(var/obj/item/weapon/stock_parts/SP in component_parts) if(istype(SP, /obj/item/weapon/stock_parts/matter_bin)) - max_coins = SP.rating * SP.rating * 120 + max_coins = SP.rating * SP.rating * 1000 else if(istype(SP, /obj/item/weapon/stock_parts/micro_laser) || istype(SP, /obj/item/weapon/stock_parts/capacitor)) temp_rating += SP.rating for(var/obj/item/weapon/CP in component_parts) @@ -122,15 +138,54 @@ display round(lastgen) and plasmatank amount if(crit_fail) usr << "\red The generator seems to have broken down." HasFuel() - if(coins) + if(coins >= 1 / (time_per_coin / power_output) - coin_left) return 1 return 0 UseFuel() - if(coins) + var/needed_coins = 1 / (time_per_coin / power_output) + var/temp = min(needed_coins, coin_left) + needed_coins -= temp + coin_left -= temp + coins -= round(needed_coins) + needed_coins -= round(needed_coins) + if (coin_left <= 0 && coins > 0) + coin_left = 1 - needed_coins coins-- + + var/lower_limit = 56 + power_output * 10 + var/upper_limit = 76 + power_output * 10 + var/bias = 0 + if (power_output > 4) + upper_limit = 400 + bias = power_output * 3 + if (heat < lower_limit) + heat += 3 + else + heat += rand(-7 + bias, 7 + bias) + if (heat < lower_limit) + heat = lower_limit + if (heat > upper_limit) + heat = upper_limit + + if (heat > 300) + overheat() + del(src) return + handleInactive() + heat -= 2 + if (heat < 0) + heat = 0 + else + for(var/mob/M in viewers(1, src)) + if (M.client && M.machine == src) + src.updateUsrDialog() + + proc + overheat() + explosion(src.loc, 2, 5, 2, -1) + attackby(var/obj/item/O as obj, var/mob/user as mob) if(istype(O, text2path(coin_path))) if(coins >= max_coins) @@ -140,17 +195,25 @@ display round(lastgen) and plasmatank amount user.drop_item() del(O) user << "\blue You add a coin to the generator." - + else if (istype(O, /obj/item/weapon/card/emag)) + emagged = 1 + emp_act(1) else if(!active) if(istype(O, /obj/item/weapon/wrench)) anchored = !anchored + playsound(src.loc, 'Deconstruct.ogg', 50, 1) if(anchored) - user << "\blue The generator is locked into place." + user << "\blue You secure the generator to the floor." else - user << "\blue The generator is unbolted from the floor." + user << "\blue You unsecure the generator from the floor." makepowernets() else if(istype(O, /obj/item/weapon/screwdriver)) open = !open + playsound(src.loc, 'Screwdriver.ogg', 50, 1) + if(open) + user << "\blue You open the access panel." + else + user << "\blue You close the access panel." else if(istype(O, /obj/item/weapon/crowbar) && !open) var/obj/machinery/constructable_frame/machine_frame/new_frame = new /obj/machinery/constructable_frame/machine_frame(src.loc) for(var/obj/item/I in component_parts) @@ -163,25 +226,105 @@ display round(lastgen) and plasmatank amount attack_hand(mob/user as mob) ..() - if(!active && HasFuel() && !crit_fail && powernet) - active = 1 - icon_state = "portgen1" - user << "\blue The generator is on." - else if(active) - active = 0 - icon_state = "portgen0" - user << "\blue The generator is off." + + if (istype(user.pulling,/obj/item/weapon/moneybag)) + var/new_coins = 0 + var/target_coins = text2num(input("How many coins do you wish to transfer?", "Generator", "0")) + for (var/obj/item/weapon/coin/C in user.pulling.contents) + if(istype(C, text2path(coin_path))) + if (coins >= max_coins) + user << "\blue The generator is full!" + break + if (new_coins >= target_coins) + break + coins++ + new_coins++ + del(C) + if (user.pulling.contents.len < 1) + del(user.pulling) + + user << "\blue You move [new_coins] coins from the money bag to the generator." + src.add_fingerprint(usr) + return + + if (!anchored) + return + + interact(user) + + attack_ai(mob/user as mob) + interact(user) + + attack_paw(mob/user as mob) + interact(user) + + proc + interact(mob/user) + if (get_dist(src, user) > 1 ) + if (!istype(user, /mob/living/silicon/ai)) + user.machine = null + user << browse(null, "window=port_gen") + return + + user.machine = src + + var/dat = text("[name]
") + if (active) + dat += text("Generator:
On
") + else + dat += text("Generator: Off
") + dat += text("Coins: [coins]
") + var/coin_percent = round(coin_left * 100, 1) + dat += text("Current coin: [coin_percent]%
") + dat += text("Power output: - [power_gen * power_output] +
") + dat += text("Heat: [heat]
") + dat += "
Close" + user << browse("[dat]", "window=port_gen") + + Topic(href, href_list) + if(..()) + return + + src.add_fingerprint(usr) + if(href_list["action"]) + if(href_list["action"] == "enable") + if(!active && HasFuel() && !crit_fail) + active = 1 + icon_state = "portgen1" + src.updateUsrDialog() + if(href_list["action"] == "disable") + if (active) + active = 0 + icon_state = "portgen0" + src.updateUsrDialog() + if(href_list["action"] == "lower_power") + if (power_output > 1) + power_output-- + src.updateUsrDialog() + if (href_list["action"] == "higher_power") + if (power_output < 4 || emagged) + power_output++ + src.updateUsrDialog() + if (href_list["action"] == "close") + usr << browse(null, "window=port_gen") + usr.machine = null /obj/machinery/power/port_gen/pacman/super name = "S.U.P.E.R.P.A.C.M.A.N.-type Portable Generator" icon_state = "portgen1" coin_path = "/obj/item/weapon/coin/uranium" - power_gen = 10000 + power_gen = 15000 + time_per_coin = 5 board_path = "/obj/item/weapon/circuitboard/pacman/super" + overheat() + explosion(src.loc, 3, 3, 3, -1) /obj/machinery/power/port_gen/pacman/mrs name = "M.R.S.P.A.C.M.A.N.-type Portable Generator" icon_state = "portgen2" coin_path = "/obj/item/weapon/coin/diamond" - power_gen = 20000 + power_gen = 40000 + time_per_coin = 60 board_path = "/obj/item/weapon/circuitboard/pacman/mrs" + overheat() + explosion(src.loc, 4, 4, 4, -1) \ No newline at end of file