= danger_levels[4] && danger_levels[4] > 0) || current_value <= danger_levels[1])
+ return 2
+ if((current_value >= danger_levels[3] && danger_levels[3] > 0) || current_value <= danger_levels[2])
+ return 1
+ return 0
update_icon()
- src.updateDialog()
- return
+ if(wiresexposed)
+ icon_state = "alarmx"
+ return
+ if((stat & (NOPOWER|BROKEN)) || shorted)
+ icon_state = "alarmp"
+ return
+ switch(max(danger_level, alarm_area.atmosalm))
+ if (0)
+ icon_state = "alarm0"
+ if (1)
+ icon_state = "alarm2" //yes, alarm2 is yellow alarm
+ if (2)
+ icon_state = "alarm1"
-/obj/machinery/alarm/proc/pulse(var/wireColor)
- //var/wireFlag = AAlarmWireColorToFlag[wireColor] //not used in this function
- var/wireIndex = AAlarmWireColorToIndex[wireColor]
- switch(wireIndex)
- if(AALARM_WIRE_IDSCAN) //unlocks for 30 seconds, if you have a better way to hack I'm all ears
- src.locked = 0
- spawn(300)
- src.locked = 1
- //world << "Idscan wire pulsed"
+ receive_signal(datum/signal/signal)
+ if(stat & (NOPOWER|BROKEN))
+ return
+ if (alarm_area.master_air_alarm != src)
+ if (master_is_operating())
+ return
+ elect_master()
+ if (alarm_area.master_air_alarm != src)
+ return
+ if(!signal || signal.encryption)
+ return
+ var/id_tag = signal.data["tag"]
+ if (!id_tag)
+ return
+ if (signal.data["area"] != area_uid)
+ return
+ if (signal.data["sigtype"] != "status")
+ return
- if (AALARM_WIRE_POWER)
- // world << "Power wire pulsed"
- if(shorted == 0)
+ var/dev_type = signal.data["device"]
+ if(!(id_tag in alarm_area.air_scrub_names) && !(id_tag in alarm_area.air_vent_names))
+ register_env_machine(id_tag, dev_type)
+ if(dev_type == "AScr")
+ alarm_area.air_scrub_info[id_tag] = signal.data
+ else if(dev_type == "AVP")
+ alarm_area.air_vent_info[id_tag] = signal.data
+
+ proc/register_env_machine(var/m_id, var/device_type)
+ var/new_name
+ if (device_type=="AVP")
+ new_name = "[alarm_area.name] Vent Pump #[alarm_area.air_vent_names.len+1]"
+ alarm_area.air_vent_names[m_id] = new_name
+ else if (device_type=="AScr")
+ new_name = "[alarm_area.name] Air Scrubber #[alarm_area.air_scrub_names.len+1]"
+ alarm_area.air_scrub_names[m_id] = new_name
+ else
+ return
+ spawn (10)
+ send_signal(m_id, list("init" = new_name) )
+
+ proc/refresh_all()
+ for(var/id_tag in alarm_area.air_vent_names)
+ var/list/I = alarm_area.air_vent_info[id_tag]
+ if (I && I["timestamp"]+AALARM_REPORT_TIMEOUT/2 > world.time)
+ continue
+ send_signal(id_tag, list("status") )
+ for(var/id_tag in alarm_area.air_scrub_names)
+ var/list/I = alarm_area.air_scrub_info[id_tag]
+ if (I && I["timestamp"]+AALARM_REPORT_TIMEOUT/2 > world.time)
+ continue
+ send_signal(id_tag, list("status") )
+
+ proc/set_frequency(new_frequency)
+ radio_controller.remove_object(src, frequency)
+ frequency = new_frequency
+ radio_connection = radio_controller.add_object(src, frequency, RADIO_TO_AIRALARM)
+
+ proc/send_signal(var/target, var/list/command)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise
+ if(!radio_connection)
+ return 0
+
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.source = src
+
+ signal.data = command
+ signal.data["tag"] = target
+ signal.data["sigtype"] = "command"
+
+ radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM)
+ // world << text("Signal [] Broadcasted to []", command, target)
+
+ return 1
+
+ proc/apply_mode()
+ var/current_pressures = TLV["pressure"]
+ var/target_pressure = (current_pressures[2] + current_pressures[3])/2
+ switch(mode)
+ if(AALARM_MODE_SCRUBBING)
+ for(var/device_id in alarm_area.air_scrub_names)
+ send_signal(device_id, list("power"= 1, "co2_scrub"= 1, "scrubbing"= 1, "panic_siphon"= 0) )
+ for(var/device_id in alarm_area.air_vent_names)
+ send_signal(device_id, list("power"= 1, "checks"= 1, "set_external_pressure"= target_pressure) )
+
+ if(AALARM_MODE_PANIC, AALARM_MODE_CYCLE)
+ for(var/device_id in alarm_area.air_scrub_names)
+ send_signal(device_id, list("power"= 1, "panic_siphon"= 1) )
+ for(var/device_id in alarm_area.air_vent_names)
+ send_signal(device_id, list("power"= 0) )
+
+ if(AALARM_MODE_REPLACEMENT)
+ for(var/device_id in alarm_area.air_scrub_names)
+ send_signal(device_id, list("power"= 1, "panic_siphon"= 1) )
+ for(var/device_id in alarm_area.air_vent_names)
+ send_signal(device_id, list("power"= 1, "checks"= 1, "set_external_pressure"= target_pressure) )
+
+ if(AALARM_MODE_FILL)
+ for(var/device_id in alarm_area.air_scrub_names)
+ send_signal(device_id, list("power"= 0) )
+ for(var/device_id in alarm_area.air_vent_names)
+ send_signal(device_id, list("power"= 1, "checks"= 1, "set_external_pressure"= target_pressure) )
+
+ if(AALARM_MODE_OFF)
+ for(var/device_id in alarm_area.air_scrub_names)
+ send_signal(device_id, list("power"= 0) )
+ for(var/device_id in alarm_area.air_vent_names)
+ send_signal(device_id, list("power"= 0) )
+
+ proc/apply_danger_level(var/new_danger_level)
+ alarm_area.atmosalm = new_danger_level
+
+ for (var/area/A in alarm_area.related)
+ for (var/obj/machinery/alarm/AA in A)
+ if ( !(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted && AA.danger_level != new_danger_level)
+ AA.update_icon()
+
+ if(danger_level > 1)
+ air_doors_close(0)
+ else
+ air_doors_open(0)
+
+ update_icon()
+
+ proc/refresh_danger_level()
+ var/level = 0
+ for (var/area/A in alarm_area.related)
+ for (var/obj/machinery/alarm/AA in A)
+ if ( !(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted)
+ if (AA.danger_level > level)
+ level = AA.danger_level
+ apply_danger_level(level)
+
+ proc/air_doors_close(manual)
+ var/area/A = get_area(src)
+ if(!A.master.air_doors_activated)
+ A.master.air_doors_activated = 1
+ for(var/obj/machinery/door/E in A.master.all_doors)
+ if(istype(E,/obj/machinery/door/firedoor))
+ if(!E:blocked)
+ if(E.operating)
+ E:nextstate = CLOSED
+ else if(!E.density)
+ spawn(0)
+ E.close()
+ continue
+
+/* if(istype(E, /obj/machinery/door/airlock))
+ if((!E:arePowerSystemsOn()) || (E.stat & NOPOWER) || E:air_locked) continue
+ if(!E.density)
+ spawn(0)
+ E.close()
+ spawn(10)
+ if(E.density)
+ E:air_locked = E.req_access
+ E:req_access = list(ACCESS_ENGINE, ACCESS_ATMOSPHERICS)
+ E.update_icon()
+ else if(E.operating)
+ spawn(10)
+ E.close()
+ if(E.density)
+ E:air_locked = E.req_access
+ E:req_access = list(ACCESS_ENGINE, ACCESS_ATMOSPHERICS)
+ E.update_icon()
+ else if(!E:locked) //Don't lock already bolted doors.
+ E:air_locked = E.req_access
+ E:req_access = list(ACCESS_ENGINE, ACCESS_ATMOSPHERICS)
+ E.update_icon()*/
+
+ proc/air_doors_open(manual)
+ var/area/A = get_area(loc)
+ if(A.master.air_doors_activated)
+ A.master.air_doors_activated = 0
+ for(var/obj/machinery/door/E in A.master.all_doors)
+ if(istype(E, /obj/machinery/door/firedoor))
+ if(!E:blocked)
+ if(E.operating)
+ E:nextstate = OPEN
+ else if(E.density)
+ spawn(0)
+ E.open()
+ continue
+
+/* if(istype(E, /obj/machinery/door/airlock))
+ if((!E:arePowerSystemsOn()) || (E.stat & NOPOWER)) continue
+ if(!isnull(E:air_locked)) //Don't mess with doors locked for other reasons.
+ E:req_access = E:air_locked
+ E:air_locked = null
+ E.update_icon()*/
+
+///////////
+//HACKING//
+///////////
+ proc/isWireColorCut(var/wireColor)
+ var/wireFlag = AAlarmWireColorToFlag[wireColor]
+ return ((AAlarmwires & wireFlag) == 0)
+
+ proc/isWireCut(var/wireIndex)
+ var/wireFlag = AAlarmIndexToFlag[wireIndex]
+ return ((AAlarmwires & wireFlag) == 0)
+
+ proc/cut(var/wireColor)
+ var/wireFlag = AAlarmWireColorToFlag[wireColor]
+ var/wireIndex = AAlarmWireColorToIndex[wireColor]
+ AAlarmwires &= ~wireFlag
+ switch(wireIndex)
+ if(AALARM_WIRE_IDSCAN)
+ locked = 1
+
+ if(AALARM_WIRE_POWER)
+ shock(usr, 50)
shorted = 1
update_icon()
- spawn(1200)
- if(shorted == 1)
- shorted = 0
+ if (AALARM_WIRE_AI_CONTROL)
+ if (aidisabled == 0)
+ aidisabled = 1
+
+ if(AALARM_WIRE_SYPHON)
+ mode = AALARM_MODE_PANIC
+ apply_mode()
+
+ if(AALARM_WIRE_AALARM)
+
+ if (alarm_area.atmosalert(2))
+ apply_danger_level(2)
+ spawn(1)
+ updateUsrDialog()
+ update_icon()
+
+ updateDialog()
+
+ return
+
+ proc/mend(var/wireColor)
+ var/wireFlag = AAlarmWireColorToFlag[wireColor]
+ var/wireIndex = AAlarmWireColorToIndex[wireColor] //not used in this function
+ AAlarmwires |= wireFlag
+ switch(wireIndex)
+ if(AALARM_WIRE_IDSCAN)
+
+ if(AALARM_WIRE_POWER)
+ shorted = 0
+ shock(usr, 50)
+ update_icon()
+
+ if(AALARM_WIRE_AI_CONTROL)
+ if (aidisabled == 1)
+ aidisabled = 0
+
+ updateDialog()
+ return
+
+ proc/pulse(var/wireColor)
+ //var/wireFlag = AAlarmWireColorToFlag[wireColor] //not used in this function
+ var/wireIndex = AAlarmWireColorToIndex[wireColor]
+ switch(wireIndex)
+ if(AALARM_WIRE_IDSCAN) //unlocks for 30 seconds, if you have a better way to hack I'm all ears
+ locked = 0
+ spawn(300)
+ locked = 1
+
+ if (AALARM_WIRE_POWER)
+ if(shorted == 0)
+ shorted = 1
update_icon()
+ spawn(1200)
+ if(shorted == 1)
+ shorted = 0
+ update_icon()
- if (AALARM_WIRE_AI_CONTROL)
- // world << "AI Control wire pulsed"
- if (src.aidisabled == 0)
- src.aidisabled = 1
- src.updateDialog()
- spawn(10)
- if (src.aidisabled == 1)
- src.aidisabled = 0
- src.updateDialog()
- if(AALARM_WIRE_SYPHON)
- // world << "Syphon wire pulsed"
- mode = AALARM_MODE_REPLACEMENT
- apply_mode()
+ if (AALARM_WIRE_AI_CONTROL)
+ if (aidisabled == 0)
+ aidisabled = 1
+ updateDialog()
+ spawn(10)
+ if (aidisabled == 1)
+ aidisabled = 0
+ updateDialog()
- if(AALARM_WIRE_AALARM)
- // world << "Aalarm wire pulsed"
- if (alarm_area.atmosalert(0))
- post_alert(0)
- spawn(1)
- src.updateUsrDialog()
- update_icon()
+ if(AALARM_WIRE_SYPHON)
+ mode = AALARM_MODE_REPLACEMENT
+ apply_mode()
- src.updateDialog()
- return
+ if(AALARM_WIRE_AALARM)
+ if (alarm_area.atmosalert(0))
+ apply_danger_level(0)
+ spawn(1)
+ updateUsrDialog()
+ update_icon()
-/obj/machinery/alarm/proc/shock(mob/user, prb)
- if((stat & (NOPOWER))) // unpowered, no shock
- return 0
- if(!prob(prb))
- return 0 //you lucked out, no shock for you
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, src)
- s.start() //sparks always.
- if (electrocute_mob(user, get_area(src), src))
- return 1
- else
- return 0
+ updateDialog()
+ return
-/obj/machinery/alarm/proc/refresh_all()
- for(var/id_tag in alarm_area.air_vent_names)
- var/list/I = alarm_area.air_vent_info[id_tag]
- if (I && I["timestamp"]+AALARM_REPORT_TIMEOUT/2 > world.time)
- continue
- send_signal(id_tag, list("status") )
- for(var/id_tag in alarm_area.air_scrub_names)
- var/list/I = alarm_area.air_scrub_info[id_tag]
- if (I && I["timestamp"]+AALARM_REPORT_TIMEOUT/2 > world.time)
- continue
- send_signal(id_tag, list("status") )
+ proc/shock(mob/user, prb)
+ if((stat & (NOPOWER))) // unpowered, no shock
+ return 0
+ if(!prob(prb))
+ return 0 //you lucked out, no shock for you
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(5, 1, src)
+ s.start() //sparks always.
+ if (electrocute_mob(user, get_area(src), src))
+ return 1
+ else
+ return 0
+///////////////
+//END HACKING//
+///////////////
-/obj/machinery/alarm/proc/set_frequency(new_frequency)
- radio_controller.remove_object(src, frequency)
- frequency = new_frequency
- radio_connection = radio_controller.add_object(src, frequency, RADIO_TO_AIRALARM)
+ attack_ai(mob/user)
+ return interact(user)
-/obj/machinery/alarm/proc/send_signal(var/target, var/list/command)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise
- if(!radio_connection)
- return 0
+ attack_hand(mob/user)
+ . = ..()
+ if (.)
+ return
+ return interact(user)
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.source = src
+ interact(mob/user)
+ user.set_machine(src)
- signal.data = command
- signal.data["tag"] = target
- signal.data["sigtype"] = "command"
+ if ( (get_dist(src, user) > 1 ))
+ if (!istype(user, /mob/living/silicon))
+ user.machine = null
+ user << browse(null, "window=air_alarm")
+ user << browse(null, "window=AAlarmwires")
+ return
- radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM)
-// world << text("Signal [] Broadcasted to []", command, target)
- return 1
+ else if (istype(user, /mob/living/silicon) && aidisabled)
+ user << "AI control for this Air Alarm interface has been disabled."
+ user << browse(null, "window=air_alarm")
+ return
-/obj/machinery/alarm/proc/return_text()
- if(!(istype(usr, /mob/living/silicon)) && locked)
- return "[src][return_status()]
(Swipe ID card to unlock interface)"
- else
- return "[src][return_status()]
[return_controls()]"
+ if(wiresexposed && (!istype(user, /mob/living/silicon)))
+ var/t1 = text("[alarm_area.name] Air Alarm WiresAccess Panel
\n")
+ var/list/AAlarmwires = list(
+ "Orange" = 1,
+ "Dark red" = 2,
+ "White" = 3,
+ "Yellow" = 4,
+ "Black" = 5,
+ )
+ for(var/wiredesc in AAlarmwires)
+ var/is_uncut = AAlarmwires & AAlarmWireColorToFlag[AAlarmwires[wiredesc]]
+ t1 += "[wiredesc] wire: "
+ if(!is_uncut)
+ t1 += "Mend"
-/obj/machinery/alarm/proc/return_status()
- var/turf/location = src.loc
- var/datum/gas_mixture/environment = location.return_air()
- var/total = environment.oxygen + environment.carbon_dioxide + environment.toxins + environment.nitrogen
- var/output = "Air Status:
"
+ else
+ t1 += "Cut "
+ t1 += "Pulse "
- if(total == 0)
- output +={"Warning: Cannot obtain air sample for analysis."}
- return output
+ t1 += "
"
+ t1 += text("
\n[(locked ? "The Air Alarm is locked." : "The Air Alarm is unlocked.")]
\n[((shorted || (stat & (NOPOWER|BROKEN))) ? "The Air Alarm is offline." : "The Air Alarm is working properly!")]
\n[(aidisabled ? "The 'AI control allowed' light is off." : "The 'AI control allowed' light is on.")]")
+ t1 += text("Close
")
+ user << browse(t1, "window=AAlarmwires")
+ onclose(user, "AAlarmwires")
- output += {"
+ if(!shorted)
+ user << browse(return_text(user),"window=air_alarm")
+ onclose(user, "air_alarm")
+
+ return
+
+ proc/return_text(mob/user)
+ if(!(istype(user, /mob/living/silicon)) && locked)
+ return "\The [src][return_status()]
[rcon_text()]
(Swipe ID card to unlock interface)"
+ else
+ return "\The [src][return_status()]
[rcon_text()]
[return_controls()]"
+
+ proc/return_status()
+ var/turf/location = get_turf(src)
+ var/datum/gas_mixture/environment = location.return_air()
+ var/total = environment.oxygen + environment.carbon_dioxide + environment.toxins + environment.nitrogen
+ var/output = "Air Status:
"
+
+ if(total == 0)
+ output += "Warning: Cannot obtain air sample for analysis."
+ return output
+
+ output += {"
"}
- var/datum/tlv/cur_tlv
- var/GET_PP = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
- cur_tlv = TLV["pressure"]
- var/environment_pressure = environment.return_pressure()
- var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure)
+ var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
- cur_tlv = TLV["oxygen"]
- var/oxygen_dangerlevel = cur_tlv.get_danger_level(environment.oxygen*GET_PP)
- var/oxygen_percent = round(environment.oxygen / total * 100, 2)
+ var/list/current_settings = TLV["pressure"]
+ var/environment_pressure = environment.return_pressure()
+ var/pressure_dangerlevel = get_danger_level(environment_pressure, current_settings)
- cur_tlv = TLV["carbon dioxide"]
- var/co2_dangerlevel = cur_tlv.get_danger_level(environment.carbon_dioxide*GET_PP)
- var/co2_percent = round(environment.carbon_dioxide / total * 100, 2)
+ current_settings = TLV["oxygen"]
+ var/oxygen_dangerlevel = get_danger_level(environment.oxygen*partial_pressure, current_settings)
+ var/oxygen_percent = round(environment.oxygen / total * 100, 2)
- cur_tlv = TLV["plasma"]
- var/plasma_dangerlevel = cur_tlv.get_danger_level(environment.toxins*GET_PP)
- var/plasma_percent = round(environment.toxins / total * 100, 2)
+ current_settings = TLV["carbon dioxide"]
+ var/co2_dangerlevel = get_danger_level(environment.carbon_dioxide*partial_pressure, current_settings)
+ var/co2_percent = round(environment.carbon_dioxide / total * 100, 2)
- cur_tlv = TLV["other"]
- var/other_moles = 0.0
- for(var/datum/gas/G in environment.trace_gases)
- other_moles+=G.moles
- var/other_dangerlevel = cur_tlv.get_danger_level(other_moles*GET_PP)
+ current_settings = TLV["plasma"]
+ var/plasma_dangerlevel = get_danger_level(environment.toxins*partial_pressure, current_settings)
+ var/plasma_percent = round(environment.toxins / total * 100, 2)
- cur_tlv = TLV["temperature"]
- var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature)
+ current_settings = TLV["other"]
+ var/other_moles = 0.0
+ for(var/datum/gas/G in environment.trace_gases)
+ other_moles+=G.moles
+ var/other_dangerlevel = get_danger_level(other_moles*partial_pressure, current_settings)
- output += {"
+ current_settings = TLV["temperature"]
+ var/temperature_dangerlevel = get_danger_level(environment.temperature, current_settings)
+
+ output += {"
Pressure: [environment_pressure]kPa
Oxygen: [oxygen_percent]%
Carbon dioxide: [co2_percent]%
Toxins: [plasma_percent]%
"}
- if (other_dangerlevel==2)
- output += {"Notice: High Concentration of Unknown Particles Detected
"}
- else if (other_dangerlevel==1)
- output += {"Notice: Low Concentration of Unknown Particles Detected
"}
+ if (other_dangerlevel==2)
+ output += "Notice: High Concentration of Unknown Particles Detected
"
+ else if (other_dangerlevel==1)
+ output += "Notice: Low Concentration of Unknown Particles Detected
"
- output += {"
-Temperature: [environment.temperature]K
-"}
+ output += "Temperature: [environment.temperature]K
"
- var/display_danger_level = max(
- pressure_dangerlevel,
- oxygen_dangerlevel,
- co2_dangerlevel,
- plasma_dangerlevel,
- other_dangerlevel,
- temperature_dangerlevel
- )
+ //Overall status
+ output += "Local Status: "
+ switch(max(pressure_dangerlevel,oxygen_dangerlevel,co2_dangerlevel,plasma_dangerlevel,other_dangerlevel,temperature_dangerlevel))
+ if(2)
+ output += "DANGER: Internals Required"
+ if(1)
+ output += "Caution"
+ if(0)
+ if(alarm_area.atmosalm)
+ output += {"Caution: Atmos alert in area"}
+ else
+ output += {"Optimal"}
- //Overall status
- output += {"Local Status: "}
- if(display_danger_level == 2)
- output += {"DANGER: Internals Required"}
- else if(display_danger_level == 1)
- output += {"Caution"}
- else if (alarm_area.atmosalm)
- output += {"Caution: Atmos alert in area"}
- else
- output += {"Optimal"}
+ return output
- return output
+ proc/rcon_text()
+ var/dat = "Remote Control:
"
+ if(rcon_setting == RCON_NO)
+ dat += "Off"
+ else
+ dat += "Off"
+ dat += " | "
+ if(rcon_setting == RCON_AUTO)
+ dat += "Auto"
+ else
+ dat += "Auto"
+ dat += " | "
+ if(rcon_setting == RCON_YES)
+ dat += "On"
+ else
+ dat += "On"
+ return dat
-/obj/machinery/alarm/proc/return_controls()
- var/output = ""//"[alarm_zone] Air [name]
"
+ proc/return_controls()
+ var/output = ""//"[alarm_zone] Air [name]
"
- switch(screen)
- if (AALARM_SCREEN_MAIN)
- if(alarm_area.atmosalm)
- output += {"Reset - Atmospheric Alarm
"}
- else
- output += {"Activate - Atmospheric Alarm
"}
+ switch(screen)
+ if (AALARM_SCREEN_MAIN)
+ if(alarm_area.atmosalm)
+ output += "Reset - Atmospheric Alarm
"
+ else
+ output += "Activate - Atmospheric Alarm
"
- output += {"
+ output += {"
Scrubbers Control
Vents Control
Set environmentals mode
Sensor Settings
"}
- if (mode==AALARM_MODE_PANIC)
- output += "PANIC SYPHON ACTIVE
Turn syphoning off"
- else
- output += "ACTIVATE PANIC SYPHON IN AREA"
- if (AALARM_SCREEN_VENT)
- var/sensor_data = ""
- if(alarm_area.air_vent_names.len)
- for(var/id_tag in alarm_area.air_vent_names)
- var/long_name = alarm_area.air_vent_names[id_tag]
- var/list/data = alarm_area.air_vent_info[id_tag]
- if(!data)
- continue;
- var/state = ""
-
- sensor_data += {"
-[long_name][state]
-Operating:
-[data["power"]?"on":"off"]
-
-Pressure checks:
-external
-internal
-
-External pressure bound:
--
--
--
--
-[data["external"]]
-+
-+
-+
-+
- (reset)
-
-"}
- if (data["direction"] == "siphon")
- sensor_data += {"
-Direction:
-siphoning
-
-"}
- sensor_data += {"
"}
- else
- sensor_data = "No vents connected.
"
- output = {"Main menu
[sensor_data]"}
- if (AALARM_SCREEN_SCRUB)
- var/sensor_data = ""
- if(alarm_area.air_scrub_names.len)
- for(var/id_tag in alarm_area.air_scrub_names)
- var/long_name = alarm_area.air_scrub_names[id_tag]
- var/list/data = alarm_area.air_scrub_info[id_tag]
- if(!data)
- continue;
- var/state = ""
-
- sensor_data += {"
-[long_name][state]
-Operating:
-[data["power"]?"on":"off"]
-Type:
-[data["scrubbing"]?"scrubbing":"syphoning"]
-"}
-
- if(data["scrubbing"])
- sensor_data += {"
-Filtering:
-Carbon Dioxide
-[data["filter_co2"]?"on":"off"];
-Toxins
-[data["filter_toxins"]?"on":"off"];
-Nitrous Oxide
-[data["filter_n2o"]?"on":"off"]
-
-"}
- sensor_data += {"
-Panic syphon: [data["panic"]?"PANIC SYPHON ACTIVATED":""]
-Dea":"red'>A")]ctivate
-
-"}
- else
- sensor_data = "No scrubbers connected.
"
- output = {"Main menu
[sensor_data]"}
-
- if (AALARM_SCREEN_MODE)
- output += {"
-Main menu
-Air machinery mode for the area:"}
- var/list/modes = list(
- AALARM_MODE_SCRUBBING = "Filtering",
- AALARM_MODE_VENTING = "Draught",
- AALARM_MODE_PANIC = "PANIC",
- AALARM_MODE_REPLACEMENT = "REPLACE AIR",
- AALARM_MODE_OFF = "Off",
- )
- for (var/m=1,m<=modes.len,m++)
- if (mode==m)
- output += {"- [modes[m]] (selected)
"}
+ if (mode==AALARM_MODE_PANIC)
+ output += "PANIC SYPHON ACTIVE
Turn syphoning off"
else
- output += {"- [modes[m]]
"}
- output += "
"
- if (AALARM_SCREEN_SENSORS)
- output += {"
+ output += "ACTIVATE PANIC SYPHON IN AREA"
+
+
+ if (AALARM_SCREEN_VENT)
+ var/sensor_data = ""
+ if(alarm_area.air_vent_names.len)
+ for(var/id_tag in alarm_area.air_vent_names)
+ var/long_name = alarm_area.air_vent_names[id_tag]
+ var/list/data = alarm_area.air_vent_info[id_tag]
+ if(!data)
+ continue;
+ var/state = ""
+
+ sensor_data += {"
+ [long_name][state]
+ Operating:
+ [data["power"]?"on":"off"]
+
+ Pressure checks:
+ external
+ internal
+
+ External pressure bound:
+ -
+ -
+ -
+ -
+ [data["external"]]
+ +
+ +
+ +
+ +
+ (reset)
+
+ "}
+ if (data["direction"] == "siphon")
+ sensor_data += {"
+ Direction:
+ siphoning
+
+ "}
+ sensor_data += {"
"}
+ else
+ sensor_data = "No vents connected.
"
+ output = {"Main menu
[sensor_data]"}
+ if (AALARM_SCREEN_SCRUB)
+ var/sensor_data = ""
+ if(alarm_area.air_scrub_names.len)
+ for(var/id_tag in alarm_area.air_scrub_names)
+ var/long_name = alarm_area.air_scrub_names[id_tag]
+ var/list/data = alarm_area.air_scrub_info[id_tag]
+ if(!data)
+ continue;
+ var/state = ""
+
+ sensor_data += {"
+ [long_name][state]
+ Operating:
+ [data["power"]?"on":"off"]
+ Type:
+ [data["scrubbing"]?"scrubbing":"syphoning"]
+ "}
+
+ if(data["scrubbing"])
+ sensor_data += {"
+ Filtering:
+ Carbon Dioxide
+ [data["filter_co2"]?"on":"off"];
+ Toxins
+ [data["filter_toxins"]?"on":"off"];
+ Nitrous Oxide
+ [data["filter_n2o"]?"on":"off"]
+
+ "}
+ sensor_data += {"
+ Panic syphon: [data["panic"]?"PANIC SYPHON ACTIVATED":""]
+ Dea":"red'>A")]ctivate
+
+ "}
+ else
+ sensor_data = "No scrubbers connected.
"
+ output = {"Main menu
[sensor_data]"}
+
+ if (AALARM_SCREEN_MODE)
+ output += "Main menu
Air machinery mode for the area:"
+ var/list/modes = list(AALARM_MODE_SCRUBBING = "Filtering",\
+ AALARM_MODE_REPLACEMENT = "REPLACE AIR",\
+ AALARM_MODE_PANIC = "PANIC",\
+ AALARM_MODE_CYCLE = "CYCLE",\
+ AALARM_MODE_FILL = "FILL",\
+ AALARM_MODE_OFF = "OFFF",)
+ for (var/m=1,m<=modes.len,m++)
+ if (mode==m)
+ output += "- [modes[m]] (selected)
"
+ else
+ output += "- [modes[m]]
"
+ output += "
"
+
+ if (AALARM_SCREEN_SENSORS)
+ output += {"
Main menu
Alarm thresholds:
Partial pressure for gases
@@ -631,404 +859,197 @@ table tr:first-child th:first-child { border: none;}
| min2 | min1 | max1 | max2 |
"}
- var/list/gases = list(
- "oxygen" = "O2",
- "carbon dioxide" = "CO2",
- "plasma" = "Toxin",
- "other" = "Other",
- )
- var/list/thresholds = list("min2", "min1", "max1", "max2")
- var/datum/tlv/tlv
- for (var/g in gases)
- output += {"
-| [gases[g]] |
-"}
- tlv = TLV[g]
- for (var/v in thresholds)
- output += {"
-
-[tlv.vars[v]>=0?tlv.vars[v]:"OFF"]
- |
-"}
- output += {"
-
-"}
- tlv = TLV["pressure"]
- output += {"
-| Pressure |
-"}
- for (var/v in thresholds)
- output += {"
-
-[tlv.vars[v]>=0?tlv.vars[v]:"OFF"]
- |
-"}
- output += {"
-
-"}
- tlv = TLV["temperature"]
- output += {"
-| Temperature |
-"}
- for (var/v in thresholds)
- output += {"
-
-[tlv.vars[v]>=0?tlv.vars[v]:"OFF"]
- |
-"}
- output += {"
-
-"}
- output += {"
"}
+ var/list/gases = list(
+ "oxygen" = "O2",
+ "carbon dioxide" = "CO2",
+ "plasma" = "Toxin",
+ "other" = "Other",)
- return output
+ var/list/selected
+ for (var/g in gases)
+ output += "| [gases[g]] | "
+ selected = TLV[g]
+ for(var/i = 1, i <= 4, i++)
+ output += "[selected[i] >= 0 ? selected[i] :"OFF"] | "
+ output += "
"
-/obj/machinery/alarm/Topic(href, href_list)
- if(..())
- return
- src.add_fingerprint(usr)
- usr.set_machine(src)
+ selected = TLV["pressure"]
+ output += " | Pressure | "
+ for(var/i = 1, i <= 4, i++)
+ output += "[selected[i] >= 0 ? selected[i] :"OFF"] | "
+ output += "
"
- if ( (get_dist(src, usr) > 1 ))
- if (!istype(usr, /mob/living/silicon))
- usr.unset_machine()
- usr << browse(null, "window=air_alarm")
- usr << browse(null, "window=AAlarmwires")
- return
+ selected = TLV["temperature"]
+ output += "| Temperature | "
+ for(var/i = 1, i <= 4, i++)
+ output += "[selected[i] >= 0 ? selected[i] :"OFF"] | "
+ output += "
"
- if (href_list["AAlarmwires"])
- var/t1 = text2num(href_list["AAlarmwires"])
- if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
- usr << "You need wirecutters!"
- return
- if (src.isWireColorCut(t1))
- src.mend(t1)
- else
- src.cut(t1)
- spawn(1)
- src.updateUsrDialog()
- else if (href_list["pulse"])
- var/t1 = text2num(href_list["pulse"])
- if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
- usr << "You need a multitool!"
- return
- if (src.isWireColorCut(t1))
- usr << "You can't pulse a cut wire."
- return
- else
- src.pulse(t1)
- spawn(1)
- src.updateUsrDialog()
+ return output
+ Topic(href, href_list)
+ if(href_list["rcon"])
+ rcon_setting = text2num(href_list["rcon"])
- if(href_list["command"])
- var/device_id = href_list["id_tag"]
- switch(href_list["command"])
- if(
- "power",
- "adjust_external_pressure",
- "set_external_pressure",
- "checks",
- "co2_scrub",
- "tox_scrub",
- "n2o_scrub",
- "panic_siphon",
- "scrubbing"
- )
- send_signal(device_id, list (href_list["command"] = text2num(href_list["val"])))
- spawn(3)
- src.updateUsrDialog()
+ if ( (get_dist(src, usr) > 1 ))
+ if (!istype(usr, /mob/living/silicon))
+ usr.machine = null
+ usr << browse(null, "window=air_alarm")
+ usr << browse(null, "window=AAlarmwires")
+ return
- //if("adjust_threshold") //was a good idea but required very wide window
- if("set_threshold")
- var/env = href_list["env"]
- var/varname = href_list["var"]
- var/datum/tlv/tlv = TLV[env]
- var/newval = input("Enter [varname] for env", "Alarm triggers", tlv.vars[varname]) as num|null
+ add_fingerprint(usr)
+ usr.machine = src
- if (isnull(newval) || ..() || (locked && !issilicon(usr)))
- return
- if (newval<0)
- tlv.vars[varname] = -1.0
- else if (env=="temperature" && newval>5000)
- tlv.vars[varname] = 5000
- else if (env=="pressure" && newval>50*ONE_ATMOSPHERE)
- tlv.vars[varname] = 50*ONE_ATMOSPHERE
- else if (env!="temperature" && env!="pressure" && newval>200)
- tlv.vars[varname] = 200
- else
- newval = round(newval,0.01)
- tlv.vars[varname] = newval
- spawn(1)
- src.updateUsrDialog()
+ if(href_list["command"])
+ var/device_id = href_list["id_tag"]
+ switch(href_list["command"])
+ if( "power",
+ "adjust_external_pressure",
+ "set_external_pressure",
+ "checks",
+ "co2_scrub",
+ "tox_scrub",
+ "n2o_scrub",
+ "panic_siphon",
+ "scrubbing")
- if(href_list["screen"])
- screen = text2num(href_list["screen"])
- spawn(1)
- src.updateUsrDialog()
+ send_signal(device_id, list(href_list["command"] = text2num(href_list["val"]) ) )
+ if("set_threshold")
+ var/env = href_list["env"]
+ var/threshold = text2num(href_list["var"])
+ var/list/selected = TLV[env]
+ var/list/thresholds = list("lower bound", "low warning", "high warning", "upper bound")
+ var/newval = input("Enter [thresholds[threshold]] for [env]", "Alarm triggers", selected[threshold]) as null|num
+ if (isnull(newval) || ..() || (locked && issilicon(usr)))
+ return
+ if (newval<0)
+ selected[threshold] = -1.0
+ else if (env=="temperature" && newval>5000)
+ selected[threshold] = 5000
+ else if (env=="pressure" && newval>50*ONE_ATMOSPHERE)
+ selected[threshold] = 50*ONE_ATMOSPHERE
+ else if (env!="temperature" && env!="pressure" && newval>200)
+ selected[threshold] = 200
+ else
+ newval = round(newval,0.01)
+ selected[threshold] = newval
+ if(threshold == 1)
+ if(selected[1] > selected[2])
+ selected[2] = selected[1]
+ if(selected[1] > selected[3])
+ selected[3] = selected[1]
+ if(selected[1] > selected[4])
+ selected[4] = selected[1]
+ if(threshold == 2)
+ if(selected[1] > selected[2])
+ selected[1] = selected[2]
+ if(selected[2] > selected[3])
+ selected[3] = selected[2]
+ if(selected[2] > selected[4])
+ selected[4] = selected[2]
+ if(threshold == 3)
+ if(selected[1] > selected[3])
+ selected[1] = selected[3]
+ if(selected[2] > selected[3])
+ selected[2] = selected[3]
+ if(selected[3] > selected[4])
+ selected[4] = selected[3]
+ if(threshold == 4)
+ if(selected[1] > selected[4])
+ selected[1] = selected[4]
+ if(selected[2] > selected[4])
+ selected[2] = selected[4]
+ if(selected[3] > selected[4])
+ selected[3] = selected[4]
- if(href_list["atmos_alarm"])
- if (alarm_area.atmosalert(2))
- post_alert(2)
- spawn(1)
- src.updateUsrDialog()
- update_icon()
- if(href_list["atmos_reset"])
- if (alarm_area.atmosalert(0))
- post_alert(0)
- spawn(1)
- src.updateUsrDialog()
- update_icon()
+ //Sets the temperature the built-in heater/cooler tries to maintain.
+ if(env == "temperature")
+ target_temperature = (selected[2] + selected[3])/2
- if(href_list["mode"])
- mode = text2num(href_list["mode"])
- apply_mode()
- spawn(5)
- src.updateUsrDialog()
+ apply_mode()
- return
+ if(href_list["screen"])
+ screen = text2num(href_list["screen"])
-/obj/machinery/alarm/proc/apply_mode()
- switch(mode)
- if(AALARM_MODE_SCRUBBING)
- for(var/device_id in alarm_area.air_scrub_names)
- send_signal(device_id, list(
- "power"= 1,
- "co2_scrub"= 1,
- "scrubbing"= 1,
- "panic_siphon"= 0,
- ))
- for(var/device_id in alarm_area.air_vent_names)
- send_signal(device_id, list(
- "power"= 1,
- "checks"= 1,
- "set_external_pressure"= ONE_ATMOSPHERE
- ))
+ if(href_list["atmos_unlock"])
+ switch(href_list["atmos_unlock"])
+ if("0")
+ air_doors_close(1)
+ if("1")
+ air_doors_open(1)
- if(AALARM_MODE_VENTING)
- for(var/device_id in alarm_area.air_scrub_names)
- send_signal(device_id, list(
- "power"= 1,
- "panic_siphon"= 0,
- "scrubbing"= 0
- ))
- for(var/device_id in alarm_area.air_vent_names)
- send_signal(device_id, list(
- "power"= 1,
- "checks"= 1,
- "set_external_pressure"= ONE_ATMOSPHERE
- ))
- if(
- AALARM_MODE_PANIC,
- AALARM_MODE_REPLACEMENT
- )
- for(var/device_id in alarm_area.air_scrub_names)
- send_signal(device_id, list(
- "power"= 1,
- "panic_siphon"= 1
- ))
- for(var/device_id in alarm_area.air_vent_names)
- send_signal(device_id, list(
- "power"= 0
- ))
- /*if(AALARM_MODE_OFF) Commented out cause the "turn off panic" uses scrubbing mode now instead.
- for(var/device_id in alarm_area.air_scrub_names)
- send_signal(device_id, list(
- "panic_siphon" = 0
- ))
- for(var/device_id in alarm_area.air_vent_names)
- send_signal(device_id, list(
- "power"= 1
- ))*/
+ if(href_list["atmos_alarm"])
+ if (alarm_area.atmosalert(2))
+ apply_danger_level(2)
+ update_icon()
-/obj/machinery/alarm/update_icon()
- if(wiresexposed)
- switch(buildstage)
- if(2)
- if(src.AAlarmwires == 0) // All wires cut
- icon_state = "alarm_b2"
- else
- icon_state = "alarmx"
- if(1)
- icon_state = "alarm_b2"
- if(0)
- icon_state = "alarm_b1"
- return
+ if(href_list["atmos_reset"])
+ if (alarm_area.atmosalert(0))
+ apply_danger_level(0)
+ update_icon()
- if((stat & (NOPOWER|BROKEN)) || shorted)
- icon_state = "alarmp"
- return
- switch(max(danger_level, alarm_area.atmosalm))
- if (0)
- src.icon_state = "alarm0"
- if (1)
- src.icon_state = "alarm2" //yes, alarm2 is yellow alarm
- if (2)
- src.icon_state = "alarm1"
+ if(href_list["mode"])
+ mode = text2num(href_list["mode"])
+ apply_mode()
-/obj/machinery/alarm/process()
- if((stat & (NOPOWER|BROKEN)) || shorted)
- return
+ if (href_list["AAlarmwires"])
+ var/t1 = text2num(href_list["AAlarmwires"])
+ if (!( istype(usr.equipped(), /obj/item/weapon/wirecutters) ))
+ usr << "You need wirecutters!"
+ return
+ if (isWireColorCut(t1))
+ mend(t1)
+ else
+ cut(t1)
- var/turf/simulated/location = src.loc
- if (!istype(location))
- return 0
+ else if (href_list["pulse"])
+ var/t1 = text2num(href_list["pulse"])
+ if (!istype(usr.equipped(), /obj/item/device/multitool))
+ usr << "You need a multitool!"
+ return
+ if (isWireColorCut(t1))
+ usr << "You can't pulse a cut wire."
+ return
+ else
+ pulse(t1)
- var/datum/gas_mixture/environment = location.return_air()
+ updateUsrDialog()
- var/datum/tlv/cur_tlv
- var/GET_PP = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
-
- cur_tlv = TLV["pressure"]
- var/environment_pressure = environment.return_pressure()
- var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure)
-
- cur_tlv = TLV["oxygen"]
- var/oxygen_dangerlevel = cur_tlv.get_danger_level(environment.oxygen*GET_PP)
-
- cur_tlv = TLV["carbon dioxide"]
- var/co2_dangerlevel = cur_tlv.get_danger_level(environment.carbon_dioxide*GET_PP)
-
- cur_tlv = TLV["plasma"]
- var/plasma_dangerlevel = cur_tlv.get_danger_level(environment.toxins*GET_PP)
-
- cur_tlv = TLV["other"]
- var/other_moles = 0.0
- for(var/datum/gas/G in environment.trace_gases)
- other_moles+=G.moles
- var/other_dangerlevel = cur_tlv.get_danger_level(other_moles*GET_PP)
-
- cur_tlv = TLV["temperature"]
- var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature)
-
- var/old_danger_level = danger_level
- danger_level = max(
- pressure_dangerlevel,
- oxygen_dangerlevel,
- co2_dangerlevel,
- plasma_dangerlevel,
- other_dangerlevel,
- temperature_dangerlevel
- )
- if (old_danger_level!=danger_level)
- apply_danger_level()
-
- if (mode==AALARM_MODE_REPLACEMENT && environment_pressureNo Party :(", src)
else
d1 = text("PARTY!!!", src)
- if (src.timing)
+ if (timing)
d2 = text("Stop Time Lock", src)
else
d2 = text("Initiate Time Lock", src)
- var/second = src.time % 60
- var/minute = (src.time - second) / 60
+ var/second = time % 60
+ var/minute = (time - second) / 60
var/dat = text("Party Button []\n
\nTimer System: []
\nTime Left: [][] - - + +\n", d1, d2, (minute ? text("[]:", minute) : null), second, src, src, src, src)
user << browse(dat, "window=partyalarm")
onclose(user, "partyalarm")
else
- A = A.loc
if (A.fire)
d1 = text("[]", src, stars("No Party :("))
else
d1 = text("[]", src, stars("PARTY!!!"))
- if (src.timing)
+ if (timing)
d2 = text("[]", src, stars("Stop Time Lock"))
else
d2 = text("[]", src, stars("Initiate Time Lock"))
- var/second = src.time % 60
- var/minute = (src.time - second) / 60
+ var/second = time % 60
+ var/minute = (time - second) / 60
var/dat = text("[] []\n
\nTimer System: []
\nTime Left: [][] - - + +\n", stars("Party Button"), d1, d2, (minute ? text("[]:", minute) : null), second, src, src, src, src)
user << browse(dat, "window=partyalarm")
onclose(user, "partyalarm")
return
/obj/machinery/partyalarm/proc/reset()
- if (!( src.working ))
- return
- var/area/A = src.loc
- A = A.loc
- if (!( istype(A, /area) ))
+ if (!( working ))
return
+ var/area/A = get_area(src)
+ ASSERT(isarea(A))
+ if(A.master)
+ A = A.master
A.partyreset()
return
/obj/machinery/partyalarm/proc/alarm()
- if (!( src.working ))
- return
- var/area/A = src.loc
- A = A.loc
- if (!( istype(A, /area) ))
+ if (!( working ))
return
+ var/area/A = get_area(src)
+ ASSERT(isarea(A))
+ if(A.master)
+ A = A.master
A.partyalert()
return
@@ -1521,25 +1543,25 @@ Code shamelessly copied from apc_frame
..()
if (usr.stat || stat & (BROKEN|NOPOWER))
return
- if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
- usr.set_machine(src)
+ if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
+ usr.machine = src
if (href_list["reset"])
- src.reset()
+ reset()
else
if (href_list["alarm"])
- src.alarm()
+ alarm()
else
if (href_list["time"])
- src.timing = text2num(href_list["time"])
+ timing = text2num(href_list["time"])
else
if (href_list["tp"])
var/tp = text2num(href_list["tp"])
- src.time += tp
- src.time = min(max(round(src.time), 0), 120)
- src.updateUsrDialog()
+ time += tp
+ time = min(max(round(time), 0), 120)
+ updateUsrDialog()
- src.add_fingerprint(usr)
+ add_fingerprint(usr)
else
usr << browse(null, "window=partyalarm")
return
- return
+ return
\ No newline at end of file
diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm
index edcfa9623fe..d43f7657f2c 100644
--- a/code/game/machinery/atmoalter/canister.dm
+++ b/code/game/machinery/atmoalter/canister.dm
@@ -136,6 +136,9 @@
else
can_label = 0
+ if(air_contents.temperature > PLASMA_FLASHPOINT)
+ air_contents.zburn()
+
src.updateDialog()
return
diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm
index 939e1c94f32..d29b1f065c0 100644
--- a/code/game/machinery/atmoalter/meter.dm
+++ b/code/game/machinery/atmoalter/meter.dm
@@ -129,5 +129,5 @@
if (!target)
src.target = loc
-/obj/machinery/meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
- return
\ No newline at end of file
+/obj/machinery/meter/turf/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
+ return
diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm
index f929cc0d5eb..dbfd5b62e6a 100644
--- a/code/game/machinery/atmoalter/portable_atmospherics.dm
+++ b/code/game/machinery/atmoalter/portable_atmospherics.dm
@@ -19,6 +19,14 @@
return 1
+ initialize()
+ . = ..()
+ spawn()
+ var/obj/machinery/atmospherics/portables_connector/port = locate() in loc
+ if(port)
+ connect(port)
+ update_icon()
+
process()
if(!connected_port) //only react when pipe_network will ont it do it for you
//Allow for reactions
@@ -135,4 +143,4 @@
user << "\blue Tank is empty!"
return
- return
\ No newline at end of file
+ return
diff --git a/code/game/machinery/bees.dm b/code/game/machinery/bees.dm
index 68b2838e70d..27a317a91a3 100644
--- a/code/game/machinery/bees.dm
+++ b/code/game/machinery/bees.dm
@@ -1,5 +1,5 @@
-/obj/effect/bee
+/mob/living/simple_animal/bee
name = "bees"
icon = 'icons/obj/apiary_bees_etc.dmi'
icon_state = "bees1"
@@ -11,162 +11,154 @@
var/mob/target_mob
var/obj/machinery/apiary/parent
pass_flags = PASSGRILLE|PASSTABLE
+ turns_per_move = 6
+ var/obj/machinery/hydroponics/my_hydrotray
-/obj/effect/bee/New(loc, var/obj/machinery/apiary/new_parent)
+/mob/living/simple_animal/bee/New(loc, var/obj/machinery/apiary/new_parent)
..()
- processing_objects.Add(src)
parent = new_parent
+ verbs -= /atom/movable/verb/pull
-/obj/effect/bee/Del()
- processing_objects.Remove(src)
+/mob/living/simple_animal/bee/Del()
if(parent)
parent.owned_bee_swarms.Remove(src)
..()
-/obj/effect/bee/process()
+/mob/living/simple_animal/bee/Life()
+ ..()
- //if we're strong enough, sting some people
- var/overrun = strength - 5 + feral / 2
- if(prob(max( overrun * 10 + feral * 10, 0)))
- var/mob/living/carbon/human/M = locate() in src.loc
- if(M)
- var/sting_prob = 100
- var/obj/item/clothing/worn_suit = M.wear_suit
- var/obj/item/clothing/worn_helmet = M.head
- if(worn_suit)
- sting_prob -= worn_suit.armor["bio"]
- if(worn_helmet)
- sting_prob -= worn_helmet.armor["bio"]
+ if(stat == CONSCIOUS)
+ //if we're strong enough, sting some people
+ var/overrun = strength - 5 + feral / 2
+ if(prob(max( overrun * 10 + feral * 10, 0)))
+ var/mob/living/carbon/human/M = pick(range(1,src))
+ if(M)
+ var/sting_prob = 100
+ var/obj/item/clothing/worn_suit = M.wear_suit
+ var/obj/item/clothing/worn_helmet = M.head
+ if(worn_suit)
+ sting_prob -= worn_suit.armor["bio"]
+ if(worn_helmet)
+ sting_prob -= worn_helmet.armor["bio"]
- if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) )
- M.apply_damage(overrun / 2 + mut / 2, BRUTE)
- M.apply_damage(overrun / 2 + toxic / 2, TOX)
- M << "\red You have been stung!"
- M.flash_pain()
+ if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) )
+ M.apply_damage(overrun / 2 + mut / 2, BRUTE)
+ M.apply_damage(overrun / 2 + toxic / 2, TOX)
+ M << "\red You have been stung!"
+ M.flash_pain()
- //if we're chasing someone, get a little bit angry
- if(target_mob && prob(10))
- feral++
+ //if we're chasing someone, get a little bit angry
+ if(target_mob && prob(10))
+ feral++
- //calm down a little bit
- var/move_prob = 40
- if(feral > 0)
- if(prob(feral * 10))
- feral -= 1
- else
- //if feral is less than 0, we're becalmed by smoke or steam
- if(feral < 0)
- feral += 1
-
- if(target_mob)
- target_mob = null
- target_turf = null
- if(strength > 5)
- //calm down and spread out a little
- var/obj/effect/bee/B = new(get_turf(pick(orange(src,1))))
- B.strength = rand(1,5)
- src.strength -= B.strength
- if(src.strength <= 5)
- src.icon_state = "bees[src.strength]"
- B.icon_state = "bees[B.strength]"
- if(src.parent)
- B.parent = src.parent
- src.parent.owned_bee_swarms.Add(B)
-
- //make some noise
- if(prob(0.5))
- src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
-
- //smoke, water and steam calms us down
- var/calming = 0
- var/list/calmers = list(/obj/effect/effect/chem_smoke, /obj/effect/effect/water, /obj/effect/effect/foam, /obj/effect/effect/steam, /obj/effect/mist)
-
- for(var/this_type in calmers)
- var/obj/effect/check_effect = locate() in src.loc
- if(check_effect.type == this_type)
- calming = 1
- break
-
- if(calming)
+ //calm down a little bit
if(feral > 0)
- src.visible_message("\blue The bees calm down!")
- feral = -10
- target_mob = null
- target_turf = null
-
- for(var/obj/effect/bee/B in src.loc)
- if(B == src)
- continue
-
- if(feral > 0)
- src.strength += B.strength
- del(B)
- src.icon_state = "bees[src.strength]"
- if(strength > 5)
- icon_state = "bees_swarm"
- else if(prob(10))
- //make the other swarm of bees stronger, then move away
- var/total_bees = B.strength + src.strength
- if(total_bees < 10)
- B.strength = min(5, total_bees)
- src.strength = total_bees - B.strength
-
- B.icon_state = "bees[B.strength]"
- if(src.strength <= 0)
- del(src)
- return
- src.icon_state = "bees[B.strength]"
- var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
- density = 1
- if(T.Enter(src, get_turf(src)))
- src.loc = T
- density = 0
- break
-
- if(target_mob)
- if(target_mob in view(src,7))
- target_turf = get_turf(target_mob)
+ if(prob(feral * 10))
+ feral -= 1
else
- for(var/mob/living/carbon/M in view(src,7))
- target_mob = M
+ //if feral is less than 0, we're becalmed by smoke or steam
+ if(feral < 0)
+ feral += 1
+
+ if(target_mob)
+ target_mob = null
+ target_turf = null
+ if(strength > 5)
+ //calm down and spread out a little
+ var/mob/living/simple_animal/bee/B = new(get_turf(pick(orange(src,1))))
+ B.strength = rand(1,5)
+ src.strength -= B.strength
+ if(src.strength <= 5)
+ src.icon_state = "bees[src.strength]"
+ B.icon_state = "bees[B.strength]"
+ if(src.parent)
+ B.parent = src.parent
+ src.parent.owned_bee_swarms.Add(B)
+
+ //make some noise
+ if(prob(0.5))
+ src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
+
+ //smoke, water and steam calms us down
+ var/calming = 0
+ var/list/calmers = list(/obj/effect/effect/chem_smoke, \
+ /obj/effect/effect/water, \
+ /obj/effect/effect/foam, \
+ /obj/effect/effect/steam, \
+ /obj/effect/mist)
+
+ for(var/this_type in calmers)
+ var/mob/living/simple_animal/check_effect = locate() in src.loc
+ if(check_effect.type == this_type)
+ calming = 1
break
- if(target_turf)
- var/turf/next_turf = get_step(src.loc, get_dir(src,target_turf))
+ if(calming)
+ if(feral > 0)
+ src.visible_message("\blue The bees calm down!")
+ feral = -10
+ target_mob = null
+ target_turf = null
+ wander = 1
+
+ for(var/mob/living/simple_animal/bee/B in src.loc)
+ if(B == src)
+ continue
+
+ if(feral > 0)
+ src.strength += B.strength
+ del(B)
+ src.icon_state = "bees[src.strength]"
+ if(strength > 5)
+ icon_state = "bees_swarm"
+ else if(prob(10))
+ //make the other swarm of bees stronger, then move away
+ var/total_bees = B.strength + src.strength
+ if(total_bees < 10)
+ B.strength = min(5, total_bees)
+ src.strength = total_bees - B.strength
+
+ B.icon_state = "bees[B.strength]"
+ if(src.strength <= 0)
+ del(src)
+ return
+ src.icon_state = "bees[B.strength]"
+ var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
+ density = 1
+ if(T.Enter(src, get_turf(src)))
+ src.loc = T
+ density = 0
+ break
+
+ if(target_mob)
+ if(target_mob in view(src,7))
+ target_turf = get_turf(target_mob)
+ wander = 0
+ else
+ for(var/mob/living/carbon/M in view(src,7))
+ target_mob = M
+ break
+
+ if(target_turf)
+ Move(get_step(src, get_dir(src,target_turf)))
- //hacky, but w/e
- var/old_density = -1
- if(target_mob && get_dist(src, target_mob) <= 1)
- old_density = target_mob.density
- target_mob.density = 0
- density = 1
- if(next_turf.Enter(src, get_turf(src)))
- src.loc = next_turf
- density = 0
if(src.loc == target_turf)
target_turf = null
- if(target_mob && old_density != -1)
- target_mob.density = old_density
+ wander = 1
else
//find some flowers, harvest
//angry bee swarms don't hang around
if(feral > 0)
- move_prob = 60
+ turns_per_move = rand(1,3)
else if(feral < 0)
- move_prob = 0
- else
- var/obj/machinery/hydroponics/H = locate() in src.loc
- if(H)
- if(H.planted && !H.dead && H.myseed)
- move_prob = 1
-
- //chance to wander around
- if(prob(move_prob))
- var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
- density = 1
- if(T.Enter(src, get_turf(src)))
- src.loc = T
- density = 0
+ turns_since_move = 0
+ else if(!my_hydrotray || my_hydrotray.loc != src.loc || !my_hydrotray.planted || my_hydrotray.dead || !my_hydrotray.myseed)
+ var/obj/machinery/hydroponics/my_hydrotray = locate() in src.loc
+ if(my_hydrotray)
+ if(my_hydrotray.planted && !my_hydrotray.dead && my_hydrotray.myseed)
+ turns_per_move = rand(20,50)
+ else
+ my_hydrotray = null
pixel_x = rand(-12,12)
pixel_y = rand(-12,12)
diff --git a/code/game/machinery/bees_apiary.dm b/code/game/machinery/bees_apiary.dm
index 9bd9a45bfb3..982feec1f2a 100644
--- a/code/game/machinery/bees_apiary.dm
+++ b/code/game/machinery/bees_apiary.dm
@@ -22,6 +22,7 @@
var/bees_in_hive = 0
var/list/owned_bee_swarms = list()
+ var/hydrotray_type = /obj/machinery/hydroponics
//overwrite this after it's created if the apiary needs a custom machinery sprite
/obj/machinery/apiary/New()
@@ -69,7 +70,7 @@
else
user << "\blue You begin to dislodge the dead apiary from the tray."
if(do_after(user, 50))
- new /obj/machinery/hydroponics(src.loc)
+ new hydrotray_type(src.loc)
new /obj/item/apiary(src.loc)
user << "\red You dislodge the apiary from the tray."
del(src)
@@ -112,11 +113,11 @@
if(swarming > 0)
swarming -= 1
if(swarming <= 0)
- for(var/obj/effect/bee/B in src.loc)
+ for(var/mob/living/simple_animal/bee/B in src.loc)
bees_in_hive += B.strength
del(B)
else if(bees_in_hive < 10)
- for(var/obj/effect/bee/B in src.loc)
+ for(var/mob/living/simple_animal/bee/B in src.loc)
bees_in_hive += B.strength
del(B)
@@ -144,7 +145,7 @@
health += max(nutrilevel - 1, round(-health / 2))
bees_in_hive += max(nutrilevel - 1, round(-bees_in_hive / 2))
if(owned_bee_swarms.len)
- var/obj/effect/bee/B = pick(owned_bee_swarms)
+ var/mob/living/simple_animal/bee/B = pick(owned_bee_swarms)
B.target_turf = get_turf(src)
//clear out some toxins
@@ -161,7 +162,7 @@
//make some new bees
if(bees_in_hive >= 10 && prob(bees_in_hive * 10))
- var/obj/effect/bee/B = new(get_turf(src), src)
+ var/mob/living/simple_animal/bee/B = new(get_turf(src), src)
owned_bee_swarms.Add(B)
B.mut = mut
B.toxic = toxic
@@ -193,7 +194,7 @@
/obj/machinery/apiary/proc/die()
if(owned_bee_swarms.len)
- var/obj/effect/bee/B = pick(owned_bee_swarms)
+ var/mob/living/simple_animal/bee/B = pick(owned_bee_swarms)
B.target_turf = get_turf(src)
B.strength -= 1
if(B.strength <= 0)
@@ -204,7 +205,7 @@
health = 0
/obj/machinery/apiary/proc/angry_swarm(var/mob/M)
- for(var/obj/effect/bee/B in owned_bee_swarms)
+ for(var/mob/living/simple_animal/bee/B in owned_bee_swarms)
B.feral = 50
B.target_mob = M
@@ -215,7 +216,7 @@
if(bees_in_hive >= 5)
spawn_strength = 6
- var/obj/effect/bee/B = new(get_turf(src), src)
+ var/mob/living/simple_animal/bee/B = new(get_turf(src), src)
B.target_mob = M
B.strength = spawn_strength
B.feral = 5
diff --git a/code/game/machinery/bees_items.dm b/code/game/machinery/bees_items.dm
index cbfc2b3bd7f..01ed5bfa407 100644
--- a/code/game/machinery/bees_items.dm
+++ b/code/game/machinery/bees_items.dm
@@ -17,7 +17,7 @@
/obj/item/weapon/bee_net/attack_self(mob/user as mob)
var/turf/T = get_step(get_turf(user), user.dir)
- for(var/obj/effect/bee/B in T)
+ for(var/mob/living/simple_animal/bee/B in T)
if(B.feral < 0)
caught_bees += B.strength
del(B)
@@ -38,7 +38,7 @@
while(caught_bees > 0)
//release a few super massive swarms
while(caught_bees > 5)
- var/obj/effect/bee/B = new(src.loc)
+ var/mob/living/simple_animal/bee/B = new(src.loc)
B.feral = 5
B.target_mob = M
B.strength = 6
@@ -46,7 +46,7 @@
caught_bees -= 6
//what's left over
- var/obj/effect/bee/B = new(src.loc)
+ var/mob/living/simple_animal/bee/B = new(src.loc)
B.strength = caught_bees
B.icon_state = "bees[B.strength]"
B.feral = 5
diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm
index 3e970a580c6..47b27ac54bd 100644
--- a/code/game/machinery/bots/cleanbot.dm
+++ b/code/game/machinery/bots/cleanbot.dm
@@ -225,7 +225,6 @@ text("[src.oddbutton ? "Yes" : "No"
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()
@@ -235,7 +234,6 @@ text("[src.oddbutton ? "Yes" : "No"
spawn(0)
if(!src || !target) return
src.path = AStar(src.loc, src.target.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance, 0, 30)
- src.path = reverselist(src.path)
if(src.path.len == 0)
src.oldtarget = src.target
src.target = null
diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm
index a833c8f10bd..30aa8a4e64d 100644
--- a/code/game/machinery/bots/ed209bot.dm
+++ b/code/game/machinery/bots/ed209bot.dm
@@ -615,7 +615,6 @@ Auto Patrol: []"},
// given an optional turf to avoid
/obj/machinery/bot/ed209/proc/calc_path(var/turf/avoid = null)
src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=avoid)
- src.path = reverselist(src.path)
// look for a criminal in view of the bot
diff --git a/code/game/machinery/bots/farmbot.dm b/code/game/machinery/bots/farmbot.dm
index ef582351570..5881f08ce28 100644
--- a/code/game/machinery/bots/farmbot.dm
+++ b/code/game/machinery/bots/farmbot.dm
@@ -357,7 +357,6 @@
var/turf/dest = get_step_towards(target,src) //Can't pathfind to a tray, as it is dense, so pathfind to the spot next to the tray
src.path = AStar(src.loc, dest, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30,id=botcard)
- src.path = reverselist(src.path)
if(src.path.len == 0)
for ( var/turf/spot in orange(1,target) ) //The closest one is unpathable, try the other spots
if ( spot == dest ) //We already tried this spot
diff --git a/code/game/machinery/bots/floorbot.dm b/code/game/machinery/bots/floorbot.dm
index 986728f5c66..bb984a1787b 100644
--- a/code/game/machinery/bots/floorbot.dm
+++ b/code/game/machinery/bots/floorbot.dm
@@ -244,7 +244,6 @@
src.path = AStar(src.loc, src.target.loc, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30)
else
src.path = AStar(src.loc, src.target, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30)
- src.path = reverselist(src.path)
if(src.path.len == 0)
src.oldtarget = src.target
src.target = null
diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm
index df7b8b0ff81..71cccfdc3ee 100644
--- a/code/game/machinery/bots/medbot.dm
+++ b/code/game/machinery/bots/medbot.dm
@@ -299,7 +299,6 @@
if(src.patient && src.path.len == 0 && (get_dist(src,src.patient) > 1))
spawn(0)
src.path = AStar(src.loc, get_turf(src.patient), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30,id=botcard)
- src.path = reverselist(src.path)
if(src.path.len == 0)
src.oldpatient = src.patient
src.patient = null
diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm
index c21e2554899..3496b6723a7 100644
--- a/code/game/machinery/bots/mulebot.dm
+++ b/code/game/machinery/bots/mulebot.dm
@@ -706,7 +706,8 @@
// given an optional turf to avoid
/obj/machinery/bot/mulebot/proc/calc_path(var/turf/avoid = null)
src.path = AStar(src.loc, src.target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 250, id=botcard, exclude=avoid)
- src.path = reverselist(src.path)
+ if(!src.path)
+ src.path = list()
// sets the current destination
diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm
index fb599c35ccb..19a43f41cc7 100644
--- a/code/game/machinery/bots/secbot.dm
+++ b/code/game/machinery/bots/secbot.dm
@@ -583,7 +583,6 @@ Auto Patrol: []"},
// given an optional turf to avoid
/obj/machinery/bot/secbot/proc/calc_path(var/turf/avoid = null)
src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=avoid)
- src.path = reverselist(src.path)
// look for a criminal in view of the bot
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 6640def45cd..124239dc82b 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -197,6 +197,7 @@
if(H.dna)
H.dna.mutantrace = mrace
H.update_mutantrace()
+ H.update_mutantrace_languages()
H.suiciding = 0
src.attempting = 0
return 1
diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm
index 939b87aa7fb..f24d0ce2b85 100644
--- a/code/game/machinery/computer/ai_core.dm
+++ b/code/game/machinery/computer/ai_core.dm
@@ -117,7 +117,7 @@
laws.add_inherent_law(M.newFreeFormLaw)
usr << "Added a freeform law."
- if(istype(P, /obj/item/device/mmi) || istype(P, /obj/item/device/posibrain))
+ if(istype(P, /obj/item/device/mmi) || istype(P, /obj/item/device/mmi/posibrain))
if(!P:brainmob)
user << "\red Sticking an empty [P] into the frame would sort of defeat the purpose."
return
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index fe89ceeb2fb..2081a640d8e 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -194,6 +194,10 @@
name = "Circuit board (Mining Shuttle)"
build_path = "/obj/machinery/computer/mining_shuttle"
origin_tech = "programming=2"
+/obj/item/weapon/circuitboard/research_shuttle
+ name = "Circuit board (Research Shuttle)"
+ build_path = "/obj/machinery/computer/research_shuttle"
+ origin_tech = "programming=2"
/obj/item/weapon/circuitboard/HolodeckControl // Not going to let people get this, but it's just here for future
name = "Circuit board (Holodeck Control)"
build_path = "/obj/machinery/computer/HolodeckControl"
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 880d2b565a6..acaabc984c0 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -122,15 +122,6 @@
if(emergency_shuttle.online)
post_status("shuttle")
src.state = STATE_DEFAULT
- if("crewtransfer")
- src.state= STATE_DEFAULT
- if(src.authenticated)
- src.state = STATE_CREWTRANSFER
- if("crewtransfer2")
- if(src.authenticated)
- init_shift_change(usr) //key difference here
- if(emergency_shuttle.online)
- post_status("shuttle")
if("cancelshuttle")
src.state = STATE_DEFAULT
if(src.authenticated)
@@ -323,7 +314,6 @@
dat += "
\[ Cancel Shuttle Call \]"
else
dat += "
\[ Call Emergency Shuttle \]"
- dat += "
\[ Initiate Crew Transfer \]"
dat += "
\[ Set Status Display \]"
else
@@ -331,8 +321,6 @@
dat += "
\[ Message List \]"
if(STATE_CALLSHUTTLE)
dat += "Are you sure you want to call the shuttle? \[ OK | Cancel \]"
- if(STATE_CREWTRANSFER) // this is the shiftchage screen.
- dat += "Are you sure you want to initiate a crew transfer? This will call the shuttle. \[ OK | Cancel \]"
if(STATE_CANCELSHUTTLE)
dat += "Are you sure you want to cancel the shuttle? \[ OK | Cancel \]"
if(STATE_MESSAGELIST)
diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm
index ab3c4565355..49d12a48478 100644
--- a/code/game/machinery/computer/crew.dm
+++ b/code/game/machinery/computer/crew.dm
@@ -29,7 +29,7 @@
/obj/machinery/computer/crew/update_icon()
if(stat & BROKEN)
- icon_state = "broken"
+ icon_state = "crewb"
else
if(stat & NOPOWER)
src.icon_state = "c_unpowered"
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 935cae8240f..e8d4078593e 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -1169,7 +1169,7 @@ About the new airlock wires panel:
return
src.add_fingerprint(user)
- if((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && src.density))
+ if((istype(C, /obj/item/weapon/weldingtool) && !( src.operating > 0 ) && src.density))
var/obj/item/weapon/weldingtool/W = C
if(W.remove_fuel(0,user))
if(!src.welded)
@@ -1198,7 +1198,7 @@ About the new airlock wires panel:
beingcrowbarred = 1 //derp, Agouri
else
beingcrowbarred = 0
- if( beingcrowbarred && (density && welded && !operating && src.p_open && (!src.arePowerSystemsOn() || stat & NOPOWER) && !src.locked) )
+ if( beingcrowbarred && (operating == -1 || density && welded && operating != 1 && src.p_open && (!src.arePowerSystemsOn() || stat & NOPOWER) && !src.locked) )
playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics from the airlock assembly.")
if(do_after(user,40))
@@ -1243,6 +1243,9 @@ About the new airlock wires panel:
ae = electronics
electronics = null
ae.loc = src.loc
+ if(operating == -1)
+ ae.icon_state = "door_electronics_smoked"
+ operating = 0
del(src)
return
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index f8c71f4decf..9ac8ad6c7f4 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -18,6 +18,7 @@
var/glass = 0
var/normalspeed = 1
var/heat_proof = 0 // For glass airlocks/opacity firedoors
+ var/air_properties_vary_with_direction = 0
/obj/machinery/door/New()
..()
@@ -78,6 +79,8 @@
/obj/machinery/door/proc/bumpopen(mob/user as mob)
if(operating) return
+ if(user.last_airflow > world.time - vsc.airflow_delay) //Fakkit
+ return
src.add_fingerprint(user)
if(!src.requiresID())
user = null
@@ -216,7 +219,7 @@
/obj/machinery/door/proc/close()
if(density) return 1
- if(operating) return
+ if(operating > 0) return
operating = 1
animate("closing")
@@ -229,6 +232,11 @@
SetOpacity(1) //caaaaarn!
operating = 0
update_nearby_tiles()
+
+ //I shall not add a check every x ticks if a door has closed over some fire.
+ var/obj/fire/fire = locate() in loc
+ if(fire)
+ del fire
return
/obj/machinery/door/proc/requiresID()
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index 4f8c7ba8c4b..9566cd6db40 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -17,6 +17,11 @@
New()
. = ..()
+ for(var/obj/machinery/door/firedoor/F in loc)
+ if(F != src)
+ spawn(1)
+ del src
+ return .
var/area/A = get_area(src)
ASSERT(istype(A))
@@ -134,7 +139,7 @@
else
users_name = "Unknown"
- if( !stat && ( istype(C, /obj/item/weapon/card/id) || istype(C, /obj/item/device/pda) ) )
+ if( ishuman(user) && !stat && ( istype(C, /obj/item/weapon/card/id) || istype(C, /obj/item/device/pda) ) )
var/obj/item/weapon/card/id/ID = C
if( istype(C, /obj/item/device/pda) )
@@ -223,10 +228,13 @@
/obj/machinery/door/firedoor/border_only
+//These are playing merry hell on ZAS. Sorry fellas :(
+/*
icon = 'icons/obj/doors/edge_Doorfire.dmi'
glass = 1 //There is a glass window so you can see through the door
//This is needed due to BYOND limitations in controlling visibility
heat_proof = 1
+ air_properties_vary_with_direction = 1
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(istype(mover) && mover.checkpass(PASSGLASS))
@@ -257,3 +265,4 @@
if(istype(source)) air_master.tiles_to_update += source
if(istype(destination)) air_master.tiles_to_update += destination
return 1
+*/
\ No newline at end of file
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 55aef446eaa..45ff776d401 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -11,6 +11,7 @@
opacity = 0
var/obj/item/weapon/airlock_electronics/electronics = null
explosion_resistance = 5
+ air_properties_vary_with_direction = 1
/obj/machinery/door/window/update_nearby_tiles(need_rebuild)
diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm
index fb5cc1575af..a0d9c847b2f 100644
--- a/code/game/machinery/embedded_controller/access_controller.dm
+++ b/code/game/machinery/embedded_controller/access_controller.dm
@@ -153,6 +153,7 @@ obj/machinery/embedded_controller/radio/access_controller
name = "Access Console"
density = 0
power_channel = ENVIRON
+ unacidable = 1
frequency = 1449
diff --git a/code/game/machinery/embedded_controller/airlock_controller.dm b/code/game/machinery/embedded_controller/airlock_controller.dm
index a997dcfdac0..9aa6a5a8e96 100644
--- a/code/game/machinery/embedded_controller/airlock_controller.dm
+++ b/code/game/machinery/embedded_controller/airlock_controller.dm
@@ -262,6 +262,7 @@ obj/machinery/embedded_controller/radio/airlock_controller
name = "Airlock Console"
density = 0
+ unacidable = 1
frequency = 1449
power_channel = ENVIRON
diff --git a/code/game/machinery/embedded_controller/simple_vent_controller.dm b/code/game/machinery/embedded_controller/simple_vent_controller.dm
index f43031884da..f226d33f9ef 100644
--- a/code/game/machinery/embedded_controller/simple_vent_controller.dm
+++ b/code/game/machinery/embedded_controller/simple_vent_controller.dm
@@ -44,6 +44,7 @@
name = "Vent Controller"
density = 0
+ unacidable = 1
frequency = 1229
power_channel = ENVIRON
diff --git a/code/game/machinery/embedded_controller/smart_airlock_controller.dm b/code/game/machinery/embedded_controller/smart_airlock_controller.dm
new file mode 100644
index 00000000000..032c1fa82c5
--- /dev/null
+++ b/code/game/machinery/embedded_controller/smart_airlock_controller.dm
@@ -0,0 +1,369 @@
+//States for airlock_control
+#define AIRLOCK_STATE_WAIT 0
+#define AIRLOCK_STATE_DEPRESSURIZE 1
+#define AIRLOCK_STATE_PRESSURIZE 2
+
+#define AIRLOCK_TARGET_INOPEN -1
+#define AIRLOCK_TARGET_NONE 0
+#define AIRLOCK_TARGET_OUTOPEN 1
+
+datum/computer/file/embedded_program/smart_airlock_controller
+ var/id_tag
+ var/tag_exterior_door
+ var/tag_interior_door
+ var/tag_airpump
+ var/tag_chamber_sensor
+ var/tag_exterior_sensor
+ var/tag_interior_sensor
+ //var/sanitize_external
+
+ state = AIRLOCK_STATE_WAIT
+ var/target_state = AIRLOCK_TARGET_NONE
+
+datum/computer/file/embedded_program/smart_airlock_controller/New()
+ ..()
+ memory["chamber_sensor_pressure"] = ONE_ATMOSPHERE
+ memory["external_sensor_pressure"] = ONE_ATMOSPHERE
+ memory["internal_sensor_pressure"] = ONE_ATMOSPHERE
+ memory["exterior_status"] = "unknown"
+ memory["interior_status"] = "unknown"
+ memory["pump_status"] = "unknown"
+ memory["target_pressure"] = ONE_ATMOSPHERE
+
+datum/computer/file/embedded_program/smart_airlock_controller/receive_signal(datum/signal/signal, receive_method, receive_param)
+ var/receive_tag = signal.data["tag"]
+ if(!receive_tag) return
+
+ if(receive_tag==tag_chamber_sensor)
+ if(signal.data["pressure"])
+ memory["chamber_sensor_pressure"] = text2num(signal.data["pressure"])
+
+ else if(receive_tag==tag_exterior_sensor)
+ if(signal.data["pressure"])
+ memory["external_sensor_pressure"] = text2num(signal.data["pressure"])
+
+ else if(receive_tag==tag_interior_sensor)
+ if(signal.data["pressure"])
+ memory["internal_sensor_pressure"] = text2num(signal.data["pressure"])
+
+ else if(receive_tag==tag_exterior_door)
+ memory["exterior_status"] = signal.data["door_status"]
+
+ else if(receive_tag==tag_interior_door)
+ memory["interior_status"] = signal.data["door_status"]
+
+ else if(receive_tag==tag_airpump)
+ if(signal.data["power"])
+ memory["pump_status"] = signal.data["direction"]
+ else
+ memory["pump_status"] = "off"
+
+ else if(receive_tag==id_tag)
+ switch(signal.data["command"])
+ if("cycle_exterior")
+ state = AIRLOCK_STATE_WAIT
+ target_state = AIRLOCK_TARGET_OUTOPEN
+ if("cycle_interior")
+ state = AIRLOCK_STATE_WAIT
+ target_state = AIRLOCK_TARGET_INOPEN
+
+ master.updateDialog()
+
+datum/computer/file/embedded_program/smart_airlock_controller/receive_user_command(command)
+ var/shutdown_pump = 0
+ switch(command)
+ if("cycle_closed")
+ state = AIRLOCK_STATE_WAIT
+ target_state = AIRLOCK_TARGET_NONE
+ if(memory["interior_status"] != "closed")
+ var/datum/signal/signal = new
+ signal.data["tag"] = tag_interior_door
+ signal.data["command"] = "secure_close"
+ post_signal(signal)
+ if(memory["exterior_status"] != "closed")
+ var/datum/signal/signal = new
+ signal.data["tag"] = tag_exterior_door
+ signal.data["command"] = "secure_close"
+ post_signal(signal)
+ shutdown_pump = 1
+ if("open_interior")
+ state = AIRLOCK_STATE_WAIT
+ target_state = AIRLOCK_TARGET_NONE
+ if(memory["interior_status"] != "open")
+ var/datum/signal/signal = new
+ signal.data["tag"] = tag_interior_door
+ signal.data["command"] = "secure_open"
+ post_signal(signal)
+ if("close_interior")
+ if(memory["interior_status"] != "closed")
+ var/datum/signal/signal = new
+ signal.data["tag"] = tag_interior_door
+ signal.data["command"] = "secure_close"
+ post_signal(signal)
+ shutdown_pump = 1
+ if("close_exterior")
+ if(memory["exterior_status"] != "closed")
+ var/datum/signal/signal = new
+ signal.data["tag"] = tag_exterior_door
+ signal.data["command"] = "secure_close"
+ post_signal(signal)
+ shutdown_pump = 1
+ if("open_exterior")
+ state = AIRLOCK_STATE_WAIT
+ target_state = AIRLOCK_TARGET_NONE
+ if(memory["exterior_status"] != "open")
+ var/datum/signal/signal = new
+ signal.data["tag"] = tag_exterior_door
+ signal.data["command"] = "secure_open"
+ post_signal(signal)
+ if("cycle_exterior")
+ state = AIRLOCK_STATE_WAIT
+ target_state = AIRLOCK_TARGET_OUTOPEN
+ if("cycle_interior")
+ state = AIRLOCK_STATE_WAIT
+ target_state = AIRLOCK_TARGET_INOPEN
+
+ if(shutdown_pump)
+ //send a signal to stop pressurizing
+ if(memory["pump_status"] != "off")
+ var/datum/signal/signal = new
+ signal.data = list(
+ "tag" = tag_airpump,
+ "power" = 0,
+ "sigtype"="command"
+ )
+ post_signal(signal)
+ master.updateDialog()
+
+datum/computer/file/embedded_program/smart_airlock_controller/process()
+ var/process_again = 1
+ while(process_again)
+ process_again = 0
+
+ if(!state && target_state)
+ //we're ready to do stuff, now what do we want to do?
+ switch(target_state)
+ if(AIRLOCK_TARGET_INOPEN)
+ memory["target_pressure"] = memory["internal_sensor_pressure"]
+ if(AIRLOCK_TARGET_OUTOPEN)
+ memory["target_pressure"] = memory["external_sensor_pressure"]
+
+ //work out whether we need to pressurize or depressurize the chamber (5% leeway with target pressure)
+ var/chamber_pressure = memory["chamber_sensor_pressure"]
+ var/target_pressure = memory["target_pressure"]
+ if(chamber_pressure <= target_pressure)
+ state = AIRLOCK_STATE_PRESSURIZE
+
+ //send a signal to start pressurizing
+ var/datum/signal/signal = new
+ signal.data = list(
+ "tag" = tag_airpump,
+ "sigtype"="command",
+ "power"=1,
+ "direction"=1,
+ "set_external_pressure"=target_pressure
+ )
+ post_signal(signal)
+
+ else if(chamber_pressure > target_pressure)
+ state = AIRLOCK_STATE_DEPRESSURIZE
+
+ //send a signal to start depressurizing
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.data = list(
+ "tag" = tag_airpump,
+ "sigtype"="command",
+ "power"=1,
+ "direction"=0,
+ "set_external_pressure"=target_pressure
+ )
+ post_signal(signal)
+
+ //actually do stuff
+ //override commands are handled elsewhere, otherwise everything proceeds automatically
+ switch(state)
+ if(AIRLOCK_STATE_PRESSURIZE)
+ if(memory["chamber_sensor_pressure"] >= memory["target_pressure"] * 0.95)
+ if(target_state < 0)
+ if(memory["interior_status"] != "open")
+ var/datum/signal/signal = new
+ signal.data["tag"] = tag_interior_door
+ signal.data["command"] = "secure_open"
+ post_signal(signal)
+ else if(target_state > 0)
+ if(memory["exterior_status"] != "open")
+ var/datum/signal/signal = new
+ signal.data["tag"] = tag_exterior_door
+ signal.data["command"] = "secure_open"
+ post_signal(signal)
+ state = AIRLOCK_STATE_WAIT
+ target_state = AIRLOCK_TARGET_NONE
+
+ //send a signal to stop pumping
+ if(memory["pump_status"] != "off")
+ var/datum/signal/signal = new
+ signal.data = list(
+ "tag" = tag_airpump,
+ "sigtype"="command",
+ "power" = 0
+ )
+ post_signal(signal)
+ master.updateDialog()
+
+ if(AIRLOCK_STATE_DEPRESSURIZE)
+ if(memory["chamber_sensor_pressure"] <= memory["target_pressure"] * 1.05)
+ if(target_state > 0)
+ if(memory["exterior_status"] != "open")
+ var/datum/signal/signal = new
+ signal.data["tag"] = tag_exterior_door
+ signal.data["command"] = "secure_open"
+ post_signal(signal)
+ else if(target_state < 0)
+ if(memory["interior_status"] != "open")
+ var/datum/signal/signal = new
+ signal.data["tag"] = tag_interior_door
+ signal.data["command"] = "secure_open"
+ post_signal(signal)
+ state = AIRLOCK_STATE_WAIT
+ target_state = AIRLOCK_TARGET_NONE
+
+ //send a signal to stop pumping
+ if(memory["pump_status"] != "off")
+ var/datum/signal/signal = new
+ signal.data = list(
+ "tag" = tag_airpump,
+ "sigtype"="command",
+ "power" = 0
+ )
+ post_signal(signal)
+ master.updateDialog()
+
+ //memory["sensor_pressure"] = sensor_pressure
+ memory["processing"] = state != target_state
+ //sensor_pressure = null //not sure if we can comment this out. Uncomment in case of problems -rastaf0
+
+ return 1
+
+
+obj/machinery/embedded_controller/radio/smart_airlock_controller
+ icon = 'icons/obj/airlock_machines.dmi'
+ icon_state = "airlock_control_standby"
+
+ name = "Cycling Airlock Console"
+ density = 0
+ unacidable = 1
+ frequency = 1449
+ power_channel = ENVIRON
+
+ // Setup parameters only
+ var/id_tag
+ var/tag_exterior_door
+ var/tag_interior_door
+ var/tag_airpump
+ var/tag_chamber_sensor
+ var/tag_exterior_sensor
+ var/tag_interior_sensor
+ //var/sanitize_external
+
+ initialize()
+ ..()
+
+ var/datum/computer/file/embedded_program/smart_airlock_controller/new_prog = new
+
+ new_prog.id_tag = id_tag
+ new_prog.tag_exterior_door = tag_exterior_door
+ new_prog.tag_interior_door = tag_interior_door
+ new_prog.tag_airpump = tag_airpump
+ new_prog.tag_chamber_sensor = tag_chamber_sensor
+ new_prog.tag_exterior_sensor = tag_exterior_sensor
+ new_prog.tag_interior_sensor = tag_interior_sensor
+ //new_prog.sanitize_external = sanitize_external
+
+ new_prog.master = src
+ program = new_prog
+
+ update_icon()
+ if(on && program)
+ if(program.memory["processing"])
+ icon_state = "airlock_control_process"
+ else
+ icon_state = "airlock_control_standby"
+ else
+ icon_state = "airlock_control_off"
+
+
+ return_text()
+ var/state_options = ""
+
+ var/state = 0
+ var/chamber_sensor_pressure = "----"
+ var/external_sensor_pressure = "----"
+ var/internal_sensor_pressure = "----"
+ var/exterior_status = "----"
+ var/interior_status = "----"
+ var/pump_status = "----"
+ var/target_pressure = "----"
+ if(program)
+ state = program.state
+ chamber_sensor_pressure = program.memory["chamber_sensor_pressure"]
+ external_sensor_pressure = program.memory["external_sensor_pressure"]
+ internal_sensor_pressure = program.memory["internal_sensor_pressure"]
+ exterior_status = program.memory["exterior_status"]
+ interior_status = program.memory["interior_status"]
+ pump_status = program.memory["pump_status"]
+ target_pressure = program.memory["target_pressure"]
+
+ var/exterior_closed = 0
+ if(exterior_status == "closed")
+ exterior_closed = 1
+ var/interior_closed = 0
+ if(interior_status == "closed")
+ interior_closed = 1
+
+ state_options += "Exterior status: [exterior_status] ([external_sensor_pressure] kPa)
"
+ if(exterior_closed)
+ state_options += "Open exterior airlock "
+ if(abs(chamber_sensor_pressure - external_sensor_pressure) > ONE_ATMOSPHERE * 0.05)
+ state_options += "WARNING"
+ state_options += "
"
+ if(!state && exterior_closed && interior_closed)
+ state_options += "Cycle to Exterior Airlock
"
+ else
+ state_options += "
"
+ else
+ state_options += "Close exterior airlock
"
+ state_options += "
"
+
+ state_options += "Interior status: [interior_status] ([internal_sensor_pressure] kPa)
"
+ if(interior_closed)
+ state_options += "Open interior airlock "
+ if(abs(chamber_sensor_pressure - internal_sensor_pressure) > ONE_ATMOSPHERE * 0.05)
+ state_options += "WARNING"
+ state_options += "
"
+ if(!state && exterior_closed && interior_closed)
+ state_options += "Cycle to Interior Airlock
"
+ else
+ state_options += "
"
+ else
+ state_options += "Close interior airlock
"
+ state_options += "
"
+
+ state_options += "
"
+ state_options += "Chamber Pressure: [chamber_sensor_pressure] kPa
"
+ state_options += "Target Chamber Pressure: [target_pressure] kPa
"
+ state_options += "Control Pump: [pump_status]
"
+ if(state)
+ state_options += "Abort Cycling
"
+ else
+ state_options += "
"
+
+ return state_options
+
+#undef AIRLOCK_STATE_PRESSURIZE
+#undef AIRLOCK_STATE_WAIT
+#undef AIRLOCK_STATE_DEPRESSURIZE
+
+#undef AIRLOCK_TARGET_INOPEN
+#undef AIRLOCK_TARGET_CLOSED
+#undef AIRLOCK_TARGET_OUTOPEN
diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm
index 1e5740ed8e0..57f1bc4be6e 100644
--- a/code/game/machinery/floodlight.dm
+++ b/code/game/machinery/floodlight.dm
@@ -6,66 +6,58 @@
icon_state = "flood00"
density = 1
var/on = 0
- var/obj/item/weapon/cell/cell = null
- var/use = 1
+ var/obj/item/weapon/cell/high/cell = null
+ var/use = 5
var/unlocked = 0
var/open = 0
+ var/brightness_on = 999 //can't remember what the maxed out value is
+
+/obj/machinery/floodlight/New()
+ src.cell = new(src)
+ ..()
/obj/machinery/floodlight/proc/updateicon()
icon_state = "flood[open ? "o" : ""][open && cell ? "b" : ""]0[on]"
/obj/machinery/floodlight/process()
- if (!on)
- if (luminosity)
+ if(on)
+ cell.charge -= use
+ if(cell.charge <= 0)
+ on = 0
updateicon()
- //sd_SetLuminosity(0)
- return
-
- if(!luminosity && cell && cell.charge > 0)
- //sd_SetLuminosity(10)
- updateicon()
-
- if(!cell && luminosity)
- on = 0
- updateicon()
- //sd_SetLuminosity(0)
- return
-
- cell.charge -= use
-
- if(cell.charge <= 0 && luminosity)
- on = 0
- updateicon()
- //sd_SetLuminosity(0)
- return
+ SetLuminosity(0)
+ src.visible_message("[src] shuts down due to lack of power!")
+ return
/obj/machinery/floodlight/attack_hand(mob/user as mob)
if(open && cell)
- cell.loc = usr
- cell.layer = 20
- if (user.hand )
- user.l_hand = cell
+ if(ishuman(user))
+ if(!user.get_active_hand())
+ user.put_in_hands(cell)
+ cell.loc = user.loc
else
- user.r_hand = cell
+ cell.loc = loc
cell.add_fingerprint(user)
- updateicon()
cell.updateicon()
src.cell = null
user << "You remove the power cell"
+ updateicon()
return
if(on)
on = 0
- user << "You turn off the light"
+ user << "\blue You turn off the light"
+ SetLuminosity(0)
else
if(!cell)
return
if(cell.charge <= 0)
return
on = 1
- user << "You turn on the light"
+ user << "\blue You turn on the light"
+ SetLuminosity(brightness_on)
updateicon()
@@ -101,10 +93,3 @@
cell = W
user << "You insert the power cell."
updateicon()
-
-/obj/machinery/floodlight/New()
- src.cell = new/obj/item/weapon/cell(src)
- cell.maxcharge = 1000
- cell.charge = 1000
- ..()
-
diff --git a/code/game/machinery/hydroponics.dm b/code/game/machinery/hydroponics.dm
index 265e3aec36e..5d187b337c7 100644
--- a/code/game/machinery/hydroponics.dm
+++ b/code/game/machinery/hydroponics.dm
@@ -779,6 +779,7 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
var/obj/machinery/apiary/A = new(src.loc)
A.icon = src.icon
A.icon_state = src.icon_state
+ A.hydrotray_type = src.type
del(src)
return
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 10002bc570b..d50cc775ca4 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -99,4 +99,32 @@ obj/machinery/recharger/update_icon() //we have an update_icon() in addition to
if(charging)
icon_state = "recharger1"
else
- icon_state = "recharger0"
\ No newline at end of file
+ icon_state = "recharger0"
+
+obj/machinery/recharger/wallcharger
+ name = "wall recharger"
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "wrecharger0"
+
+obj/machinery/recharger/wallcharger/process()
+ if(stat & (NOPOWER|BROKEN) || !anchored)
+ return
+
+ if(charging)
+ if(istype(charging, /obj/item/weapon/gun/energy))
+ var/obj/item/weapon/gun/energy/E = charging
+ if(E.power_supply.charge < E.power_supply.maxcharge)
+ E.power_supply.give(100)
+ icon_state = "wrecharger1"
+ use_power(250)
+ else
+ icon_state = "wrecharger2"
+ return
+ if(istype(charging, /obj/item/weapon/melee/baton))
+ var/obj/item/weapon/melee/baton/B = charging
+ if(B.charges < initial(B.charges))
+ B.charges++
+ icon_state = "wrecharger1"
+ use_power(150)
+ else
+ icon_state = "wrecharger2"
\ No newline at end of file
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index a27544b47c1..9a6849dcdf4 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -83,6 +83,10 @@
attack_hand(mob/user as mob)
src.add_fingerprint(user)
+ interact(user)
+
+ interact(mob/user as mob)
+
if(open)
var/dat
@@ -127,7 +131,7 @@
var/value = text2num(href_list["val"])
// limit to 20-90 degC
- set_temperature = dd_range(20, 90, set_temperature + value)
+ set_temperature = dd_range(0, 90, set_temperature + value)
if("cellremove")
if(open && cell && !usr.get_active_hand())
@@ -164,7 +168,7 @@
var/turf/simulated/L = loc
if(istype(L))
var/datum/gas_mixture/env = L.return_air()
- if(env.temperature < (set_temperature+T0C))
+ if(env.temperature != set_temperature + T0C)
var/transfer_moles = 0.25 * env.total_moles()
@@ -176,10 +180,12 @@
var/heat_capacity = removed.heat_capacity()
//world << "heating ([heat_capacity])"
- if(heat_capacity == 0 || heat_capacity == null) // Added check to avoid divide by zero (oshi-) runtime errors -- TLE
- heat_capacity = 1
- removed.temperature = min((removed.temperature*heat_capacity + heating_power)/heat_capacity, 1000) // Added min() check to try and avoid wacky superheating issues in low gas scenarios -- TLE
- cell.use(heating_power/20000)
+ if(heat_capacity) // Added check to avoid divide by zero (oshi-) runtime errors -- TLE
+ if(removed.temperature < set_temperature + T0C)
+ removed.temperature = min(removed.temperature + heating_power/heat_capacity, 1000) // Added min() check to try and avoid wacky superheating issues in low gas scenarios -- TLE
+ else
+ removed.temperature = max(removed.temperature - heating_power/heat_capacity, TCMB)
+ cell.use(heating_power/20000)
//world << "now at [removed.temperature]"
diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm
index 7dec73e335c..bbf765544fc 100644
--- a/code/game/machinery/syndicatebeacon.dm
+++ b/code/game/machinery/syndicatebeacon.dm
@@ -85,6 +85,8 @@
M << "You have joined the ranks of the Syndicate and become a traitor to the station!"
+ message_admins("[N]/([N.ckey]) has accepted a traitor objective from a syndicate beacon.")
+
var/obj_count = 1
for(var/datum/objective/OBJ in M.mind.objectives)
M << "Objective #[obj_count]: [OBJ.explanation_text]"
diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm
index 754d758248b..0845b0ba73b 100644
--- a/code/game/machinery/telecomms/broadcaster.dm
+++ b/code/game/machinery/telecomms/broadcaster.dm
@@ -148,6 +148,15 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"],, signal.data["compression"], list(0), connection.frequency)
+
+ if(connection.frequency == ERT_FREQ)
+ Broadcast_Message(signal.data["connection"], signal.data["mob"],
+ signal.data["vmask"], signal.data["vmessage"],
+ signal.data["radio"], signal.data["message"],
+ signal.data["name"], signal.data["job"],
+ signal.data["realname"], signal.data["vname"],, signal.data["compression"], list(0), connection.frequency)
+
+
else
if(intercept)
Broadcast_Message(signal.data["connection"], signal.data["mob"],
diff --git a/code/game/machinery/telecomms/presets.dm b/code/game/machinery/telecomms/presets.dm
index 0cd533cf274..2fe5b5e3a64 100644
--- a/code/game/machinery/telecomms/presets.dm
+++ b/code/game/machinery/telecomms/presets.dm
@@ -24,12 +24,18 @@
toggled = 0
autolinkers = list("r_relay")
+/obj/machinery/telecomms/relay/preset/centcom
+ id = "Centcom Relay"
+ hide = 1
+ toggled = 0
+ autolinkers = list("c_relay")
+
//HUB
/obj/machinery/telecomms/hub/preset
id = "Hub"
network = "tcommsat"
- autolinkers = list("hub", "relay", "s_relay", "m_relay", "r_relay", "science", "medical",
+ autolinkers = list("hub", "relay", "c_relay", "s_relay", "m_relay", "r_relay", "science", "medical",
"supply", "common", "command", "engineering", "security",
"receiverA", "receiverB", "broadcasterA", "broadcasterB")
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 3dbf72b36b5..d98d57de30b 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -2,6 +2,7 @@
var/product_name = "generic"
var/product_path = null
var/amount = 0
+ var/price = 0
var/display_color = "blue"
@@ -17,11 +18,13 @@
var/active = 1 //No sales pitches if off!
var/vend_ready = 1 //Are we ready to vend?? Is it time??
var/vend_delay = 10 //How long does it take to vend?
+ var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now.
// To be filled out at compile time
var/list/products = list() // For each, use the following pattern:
var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2)
var/list/premium = list() // No specified amount = only one in stock
+ var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price.
var/product_slogans = "" //String of slogans separated by semicolons, optional
var/product_ads = "" //String of small ad messages in the vending screen - random chance
@@ -49,6 +52,9 @@
var/const/WIRE_SHOCK = 3
var/const/WIRE_SHOOTINV = 4
+ var/obj/machinery/account_database/linked_db
+ var/datum/money_account/linked_account
+
/obj/machinery/vending/New()
..()
spawn(4)
@@ -64,10 +70,20 @@
src.build_inventory(contraband, 1)
src.build_inventory(premium, 0, 1)
power_change()
+
+ reconnect_database()
+ linked_account = vendor_account
+
return
return
+/obj/machinery/vending/proc/reconnect_database()
+ for(var/obj/machinery/account_database/DB in world)
+ if(DB.z == src.z)
+ linked_db = DB
+ break
+
/obj/machinery/vending/ex_act(severity)
switch(severity)
if(1.0)
@@ -98,6 +114,7 @@
/obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0)
for(var/typepath in productlist)
var/amount = productlist[typepath]
+ var/price = prices[typepath]
if(isnull(amount)) amount = 1
var/atom/temp = new typepath(null)
@@ -105,6 +122,7 @@
R.product_name = temp.name
R.product_path = typepath
R.amount = amount
+ R.price = price
R.display_color = pick("red","blue","green")
if(hidden)
@@ -139,9 +157,69 @@
coin = W
user << "\blue You insert the [W] into the [src]"
return
+ else if(istype(W, /obj/item/weapon/card) && currently_vending)
+ //attempt to connect to a new db, and if that doesn't work then fail
+ if(!linked_db)
+ reconnect_database()
+ if(linked_db)
+ if(linked_account)
+ var/obj/item/weapon/card/I = W
+ scan_card(I)
+ else
+ usr << "\icon[src]Unable to connect to linked account."
+ else
+ usr << "\icon[src]Unable to connect to accounts database."
else
..()
+/obj/machinery/vending/proc/scan_card(var/obj/item/weapon/card/I)
+ if(!currently_vending) return
+ if (istype(I, /obj/item/weapon/card/id))
+ var/obj/item/weapon/card/id/C = I
+ visible_message("[usr] swipes a card through [src].")
+ if(linked_account)
+ var/attempt_pin = input("Enter pin code", "Vendor transaction") as num
+ var/datum/money_account/D = linked_db.attempt_account_access(C.associated_account_number, attempt_pin, 2)
+ if(D)
+ var/transaction_amount = currently_vending.price
+ if(transaction_amount <= D.money)
+
+ //transfer the money
+ D.money -= transaction_amount
+ linked_account.money += transaction_amount
+
+ //create entries in the two account transaction logs
+ var/datum/transaction/T = new()
+ T.target_name = "[linked_account.owner_name] (via [src.name])"
+ T.purpose = "Purchase of [currently_vending.product_name]"
+ if(transaction_amount > 0)
+ T.amount = "([transaction_amount])"
+ else
+ T.amount = "[transaction_amount]"
+ T.source_terminal = src.name
+ T.date = current_date_string
+ T.time = worldtime2text()
+ D.transaction_log.Add(T)
+ //
+ T = new()
+ T.target_name = D.owner_name
+ T.purpose = "Purchase of [currently_vending.product_name]"
+ T.amount = "[transaction_amount]"
+ T.source_terminal = src.name
+ T.date = current_date_string
+ T.time = worldtime2text()
+ linked_account.transaction_log.Add(T)
+
+ // Vend the item
+ src.vend(src.currently_vending, usr)
+ currently_vending = null
+ else
+ usr << "\icon[src]You don't have that much money!"
+ else
+ usr << "\icon[src]Unable to access account. Check security settings and try again."
+ else
+ usr << "\icon[src]EFTPOS is not connected to an account."
+
/obj/machinery/vending/attack_paw(mob/user as mob)
return attack_hand(user)
@@ -158,6 +236,15 @@
return
var/vendorname = (src.name) //import the machine's name
+
+ if(src.currently_vending)
+ var/dat = "[vendorname]
" //display the name, and added a horizontal rule
+ dat += "You have selected [currently_vending.product_name].
Please swipe your ID to pay for the article.
"
+ dat += "Cancel"
+ user << browse(dat, "window=vending")
+ onclose(user, "")
+ return
+
var/dat = "[vendorname]
" //display the name, and added a horizontal rule
dat += "Select an item:
" //the rest is just general spacing and bolding
@@ -178,8 +265,10 @@
for (var/datum/data/vending_product/R in display_records)
dat += "[R.product_name]:"
dat += " [R.amount] "
+ if(R.price)
+ dat += " (Price: [R.price])"
if (R.amount > 0)
- dat += "(Vend)"
+ dat += " (Vend)"
else
dat += " SOLD OUT"
dat += "
"
@@ -247,48 +336,27 @@
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
usr.set_machine(src)
- if ((href_list["vend"]) && (src.vend_ready))
+ if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending))
if ((!src.allowed(usr)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH
usr << "\red Access denied." //Unless emagged of course
flick(src.icon_deny,src)
return
- src.vend_ready = 0 //One thing at a time!!
-
var/datum/data/vending_product/R = locate(href_list["vend"])
if (!R || !istype(R) || !R.product_path || R.amount <= 0)
- src.vend_ready = 1
return
- if (R in coin_records)
- if(!coin)
- usr << "\blue You need to insert a coin to get this item."
- return
- if(coin.string_attached)
- if(prob(50))
- usr << "\blue You successfully pull the coin out before the [src] could swallow it."
- else
- usr << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all."
- del(coin)
- else
- del(coin)
+ if(R.price == null)
+ src.vend(R, usr)
+ else
+ src.currently_vending = R
+ src.updateUsrDialog()
- R.amount--
-
- if(((src.last_reply + (src.vend_delay + 200)) <= world.time) && src.vend_reply)
- spawn(0)
- src.speak(src.vend_reply)
- src.last_reply = world.time
-
- use_power(5)
- if (src.icon_vend) //Show the vending animation if needed
- flick(src.icon_vend,src)
- spawn(src.vend_delay)
- new R.product_path(get_turf(src))
- src.vend_ready = 1
- return
+ return
+ else if (href_list["cancel_buying"])
+ src.currently_vending = null
src.updateUsrDialog()
return
@@ -323,6 +391,43 @@
return
return
+/obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user)
+ if ((!src.allowed(user)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH
+ user << "\red Access denied." //Unless emagged of course
+ flick(src.icon_deny,src)
+ return
+ src.vend_ready = 0 //One thing at a time!!
+
+ if (R in coin_records)
+ if(!coin)
+ user << "\blue You need to insert a coin to get this item."
+ return
+ if(coin.string_attached)
+ if(prob(50))
+ user << "\blue You successfully pull the coin out before the [src] could swallow it."
+ else
+ user << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all."
+ del(coin)
+ else
+ del(coin)
+
+ R.amount--
+
+ if(((src.last_reply + (src.vend_delay + 200)) <= world.time) && src.vend_reply)
+ spawn(0)
+ src.speak(src.vend_reply)
+ src.last_reply = world.time
+
+ use_power(5)
+ if (src.icon_vend) //Show the vending animation if needed
+ flick(src.icon_vend,src)
+ spawn(src.vend_delay)
+ new R.product_path(get_turf(src))
+ src.vend_ready = 1
+ return
+
+ src.updateUsrDialog()
+
/obj/machinery/vending/process()
if(stat & (BROKEN|NOPOWER))
return
@@ -532,6 +637,8 @@
vend_delay = 34
products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25,/obj/item/weapon/reagent_containers/food/drinks/tea = 25,/obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25)
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/ice = 10)
+ prices = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25, /obj/item/weapon/reagent_containers/food/drinks/tea = 25, /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25)
+
@@ -545,6 +652,9 @@
/obj/item/weapon/reagent_containers/food/snacks/sosjerky = 6,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 6,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 6,
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6)
contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6)
+ prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 20,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 30,/obj/item/weapon/reagent_containers/food/snacks/chips =25,
+ /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 30,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 20,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 30,
+ /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 25)
@@ -558,6 +668,9 @@
/obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/starkist = 10,
/obj/item/weapon/reagent_containers/food/drinks/space_up = 10)
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/thirteenloko = 5)
+ prices = list(/obj/item/weapon/reagent_containers/food/drinks/cola = 20,/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind = 20,
+ /obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 20,/obj/item/weapon/reagent_containers/food/drinks/starkist = 20,
+ /obj/item/weapon/reagent_containers/food/drinks/space_up = 20)
//This one's from bay12
/obj/machinery/vending/cart
@@ -581,6 +694,8 @@
products = list(/obj/item/weapon/storage/fancy/cigarettes = 10,/obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 4)
contraband = list(/obj/item/weapon/lighter/zippo = 4)
premium = list(/obj/item/clothing/mask/cigarette/cigar/havana = 2)
+ prices = list(/obj/item/weapon/storage/fancy/cigarettes = 60,/obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 60)
+
/obj/machinery/vending/medical
name = "NanoMed Plus"
@@ -659,7 +774,7 @@
/obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3,
/obj/item/seeds/poppyseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3,
/obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,
- /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3)
+ /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3)
contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2,
/obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2)
premium = list(/obj/item/toy/waterflower = 1)
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index 5a903c3f97d..25e3772baf4 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -40,6 +40,9 @@
for(var/atom/A in contents)
A.clean_blood()
+ for(var/obj/item/I in contents)
+ I.decontaminate()
+
//Tanning!
for(var/obj/item/stack/sheet/hairlesshide/HH in contents)
var/obj/item/stack/sheet/wetleather/WL = new(src)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 225318a9b86..d70512148c6 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -651,7 +651,7 @@
/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/posibrain))
+ if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/mmi/posibrain))
if(mmi_move_inside(W,user))
user << "[src]-MMI interface initialized successfuly"
else
@@ -1136,7 +1136,7 @@
src.occupant.client.perspective = MOB_PERSPECTIVE
*/
src.occupant << browse(null, "window=exosuit")
- if(istype(mob_container, /obj/item/device/mmi) || istype(mob_container, /obj/item/device/posibrain))
+ if(istype(mob_container, /obj/item/device/mmi) || istype(mob_container, /obj/item/device/mmi/posibrain))
var/obj/item/device/mmi/mmi = mob_container
if(mmi.brainmob)
occupant.loc = mmi
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index 2ad11bb0214..84bff5cffc4 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -110,4 +110,15 @@
return
-
+/obj/mecha/working/ripley/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/fluff/sven_fjeltson_1))//this shit broke ripleys
+ src.icon_state = "earth"
+ src.initial_icon = "earth"
+ src.name = "APLU \"Strike the Earth!\""
+ src.desc = "Looks like an over worked, under maintained Ripley with some horrific damage."
+ user << "You pick up your old \"Strike the Earth!\" APLU."
+ user.drop_item()
+ del(W)
+ return
+ else
+ ..()
diff --git a/code/game/objects/effects/decals/Cleanable/fuel.dm b/code/game/objects/effects/decals/Cleanable/fuel.dm
index e4c5ae42205..5cc3ebd3fe0 100644
--- a/code/game/objects/effects/decals/Cleanable/fuel.dm
+++ b/code/game/objects/effects/decals/Cleanable/fuel.dm
@@ -26,10 +26,11 @@ obj/effect/decal/cleanable/liquid_fuel
if(!istype(S)) return
for(var/d in cardinal)
if(rand(25))
- var/turf/simulated/O = get_step(src,d)
- if(O.CanPass(target = get_turf(src), air_group = 1))
- if(!locate(/obj/effect/decal/cleanable/liquid_fuel) in O)
- new/obj/effect/decal/cleanable/liquid_fuel(O,amount*0.25)
+ var/turf/simulated/target = get_step(src,d)
+ var/turf/simulated/origin = get_turf(src)
+ if(origin.CanPass(null, target, 0, 0) && target.CanPass(null, origin, 0, 0))
+ if(!locate(/obj/effect/decal/cleanable/liquid_fuel) in target)
+ new/obj/effect/decal/cleanable/liquid_fuel(target, amount*0.25)
amount *= 0.75
flamethrower_fuel
@@ -38,18 +39,19 @@ obj/effect/decal/cleanable/liquid_fuel
New(newLoc, amt = 1, d = 0)
dir = d //Setting this direction means you won't get torched by your own flamethrower.
. = ..()
+
Spread()
//The spread for flamethrower fuel is much more precise, to create a wide fire pattern.
if(amount < 0.1) return
var/turf/simulated/S = loc
if(!istype(S)) return
- for(var/d in list(turn(dir,90),turn(dir,-90)))
+ for(var/d in list(turn(dir,90),turn(dir,-90), dir))
var/turf/simulated/O = get_step(S,d)
if(locate(/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel) in O)
continue
- if(O.CanPass(target = get_turf(src), air_group = 1))
+ if(O.CanPass(null, S, 0, 0) && S.CanPass(null, O, 0, 0))
new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(O,amount*0.25,d)
O.hotspot_expose((T20C*2) + 380,500) //Light flamethrower fuel on fire immediately.
- amount *= 0.5
+ amount *= 0.25
diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm
index 29a652b7778..944efe32a77 100644
--- a/code/game/objects/effects/spawners/bombspawner.dm
+++ b/code/game/objects/effects/spawners/bombspawner.dm
@@ -110,15 +110,11 @@
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
var/btype = 0 // 0=radio, 1=prox, 2=time
- var/btemp1 = 1500
- var/btemp2 = 1000 // tank temperatures
timer
btype = 2
syndicate
- btemp1 = 150
- btemp2 = 20
proximity
btype = 1
@@ -130,75 +126,49 @@
/obj/effect/spawner/newbomb/New()
..()
+ var/obj/item/device/transfer_valve/V = new(src.loc)
+ var/obj/item/weapon/tank/plasma/PT = new(V)
+ var/obj/item/weapon/tank/oxygen/OT = new(V)
+
+ V.tank_one = PT
+ V.tank_two = OT
+
+ PT.master = V
+ OT.master = V
+
+ PT.air_contents.temperature = PLASMA_FLASHPOINT
+ PT.air_contents.toxins = 15
+ PT.air_contents.carbon_dioxide = 33
+ PT.air_contents.update_values()
+
+ OT.air_contents.temperature = PLASMA_FLASHPOINT
+ OT.air_contents.oxygen = 48
+ OT.air_contents.update_values()
+
+ var/obj/item/device/assembly/S
+
switch (src.btype)
// radio
if (0)
- var/obj/item/device/transfer_valve/V = new(src.loc)
- var/obj/item/weapon/tank/plasma/PT = new(V)
- var/obj/item/weapon/tank/oxygen/OT = new(V)
-
- var/obj/item/device/assembly/signaler/S = new(V)
-
- V.tank_one = PT
- V.tank_two = OT
- V.attached_device = S
-
- S.holder = V
- S.toggle_secure()
- PT.master = V
- OT.master = V
-
- PT.air_contents.temperature = btemp1 + T0C
- OT.air_contents.temperature = btemp2 + T0C
-
- V.update_icon()
+ S = new/obj/item/device/assembly/signaler(V)
// proximity
if (1)
- var/obj/item/device/transfer_valve/V = new(src.loc)
- var/obj/item/weapon/tank/plasma/PT = new(V)
- var/obj/item/weapon/tank/oxygen/OT = new(V)
-
- var/obj/item/device/assembly/prox_sensor/P = new(V)
-
- V.tank_one = PT
- V.tank_two = OT
- V.attached_device = P
-
- P.holder = V
- P.toggle_secure()
- PT.master = V
- OT.master = V
-
-
- PT.air_contents.temperature = btemp1 + T0C
- OT.air_contents.temperature = btemp2 + T0C
-
- V.update_icon()
-
+ S = new/obj/item/device/assembly/prox_sensor(V)
// timer
if (2)
- var/obj/item/device/transfer_valve/V = new(src.loc)
- var/obj/item/weapon/tank/plasma/PT = new(V)
- var/obj/item/weapon/tank/oxygen/OT = new(V)
- var/obj/item/device/assembly/timer/T = new(V)
+ S = new/obj/item/device/assembly/timer(V)
- V.tank_one = PT
- V.tank_two = OT
- V.attached_device = T
- T.holder = V
- T.toggle_secure()
- PT.master = V
- OT.master = V
- T.time = 30
+ V.attached_device = S
- PT.air_contents.temperature = btemp1 + T0C
- OT.air_contents.temperature = btemp2 + T0C
+ S.holder = V
+ S.toggle_secure()
+
+ V.update_icon()
- V.update_icon()
del(src)
\ No newline at end of file
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index 68f57112cbf..522ff35af10 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -114,7 +114,8 @@
/obj/effect/spider/spiderling/proc/die()
visible_message("[src] dies!")
- icon_state = "greenshatter"
+ new /obj/effect/decal/cleanable/spiderling_remains(src.loc)
+ del(src)
/obj/effect/spider/spiderling/healthcheck()
if(health <= 0)
@@ -189,6 +190,12 @@
new spawn_type(src.loc)
del(src)
+/obj/effect/decal/cleanable/spiderling_remains
+ name = "spiderling remains"
+ desc = "Green squishy mess."
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "greenshatter"
+
/obj/effect/spider/cocoon
name = "cocoon"
desc = "Something wrapped in silky spider web"
diff --git a/code/game/objects/empulse.dm b/code/game/objects/empulse.dm
index 4c02dd38fff..68cb8f2df3a 100644
--- a/code/game/objects/empulse.dm
+++ b/code/game/objects/empulse.dm
@@ -20,6 +20,9 @@ proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
if(heavy_range > light_range)
light_range = heavy_range
+ for(var/mob/M in range(heavy_range, epicenter))
+ M << 'sound/effects/EMPulse.ogg'
+
for(var/atom/T in range(light_range, epicenter))
var/distance = get_dist(epicenter, T)
if(distance < 0)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 964fe964353..8556b15abcf 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -645,7 +645,7 @@
user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
-
+ msg_admin_attack("ATTACK: [user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])") //BS12 EDIT ALG
log_attack(" [user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])")
src.add_fingerprint(user)
diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm
index 1c6fe70e8c0..ba63563d7c5 100644
--- a/code/game/objects/items/bodybag.dm
+++ b/code/game/objects/items/bodybag.dm
@@ -84,3 +84,45 @@
icon_state = icon_closed
else
icon_state = icon_opened
+
+
+/obj/item/bodybag/cryobag
+ name = "stasis bag"
+ desc = "A folded, non-reusable bag designed for the preservation of an occupant's brain by stasis."
+ icon = 'icons/obj/cryobag.dmi'
+ icon_state = "bodybag_folded"
+
+
+ attack_self(mob/user)
+ var/obj/structure/closet/body_bag/cryobag/R = new /obj/structure/closet/body_bag/cryobag(user.loc)
+ R.add_fingerprint(user)
+ del(src)
+
+
+
+/obj/structure/closet/body_bag/cryobag
+ name = "stasis bag"
+ desc = "A non-reusable plastic bag designed for the preservation of an occupant's brain by stasis."
+ icon = 'icons/obj/cryobag.dmi'
+ icon_state = "bodybag_closed"
+ icon_closed = "bodybag_closed"
+ icon_opened = "bodybag_open"
+ density = 0
+
+ var/used = 0
+
+ open()
+ . = ..()
+ if(used)
+ var/obj/item/O = new/obj/item(src.loc)
+ O.name = "used stasis bag"
+ O.icon = src.icon
+ O.icon_state = "bodybag_used"
+ O.desc = "Pretty useless now.."
+ del(src)
+
+ MouseDrop(over_object, src_location, over_location)
+ if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src))))
+ if(!ishuman(usr)) return
+ usr << "\red You can't fold that up anymore.."
+ ..()
\ No newline at end of file
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index e0cb6b3e0bd..be6c3390759 100755
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -117,7 +117,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/captain
default_cartridge = /obj/item/weapon/cartridge/captain
icon_state = "pda-c"
- toff = 1
+ detonate = 0
+ //toff = 1
/obj/item/device/pda/cargo
default_cartridge = /obj/item/weapon/cartridge/quartermaster
@@ -144,7 +145,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/lawyer
default_cartridge = /obj/item/weapon/cartridge/lawyer
icon_state = "pda-lawyer"
- ttone = "objection"
+ ttone = "..."
/obj/item/device/pda/botanist
//default_cartridge = /obj/item/weapon/cartridge/botanist
diff --git a/code/game/objects/items/devices/debugger.dm b/code/game/objects/items/devices/debugger.dm
new file mode 100644
index 00000000000..7a05fc696a9
--- /dev/null
+++ b/code/game/objects/items/devices/debugger.dm
@@ -0,0 +1,45 @@
+/**
+ * Multitool -- A multitool is used for hacking electronic devices.
+ * TO-DO -- Using it as a power measurement tool for cables etc. Nannek.
+ *
+ */
+
+/obj/item/device/debugger
+ icon = 'icons/obj/hacktool.dmi'
+ name = "debugger"
+ desc = "Used to debug electronic equipment."
+ icon_state = "hacktool-g"
+ flags = FPRINT | TABLEPASS| CONDUCT
+ force = 5.0
+ w_class = 2.0
+ throwforce = 5.0
+ throw_range = 15
+ throw_speed = 3
+ desc = "You can use this on airlocks or APCs to try to hack them without cutting wires."
+ m_amt = 50
+ g_amt = 20
+ origin_tech = "magnets=1;engineering=1"
+ var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
+
+/obj/item/device/debugger/is_used_on(obj/O, mob/user)
+ if(istype(O, /obj/machinery/power/apc))
+ var/obj/machinery/power/apc/A = O
+ if(A.emagged || A.malfhack)
+ user << "\red There is a software error with the device."
+ else
+ user << "\blue The device's software appears to be fine."
+ return 1
+ if(istype(O, /obj/machinery/door))
+ var/obj/machinery/door/D = O
+ if(D.operating == -1)
+ user << "\red There is a software error with the device."
+ else
+ user << "\blue The device's software appears to be fine."
+ return 1
+ else if(istype(O, /obj/machinery))
+ var/obj/machinery/A = O
+ if(A.emagged)
+ user << "\red There is a software error with the device."
+ else
+ user << "\blue The device's software appears to be fine."
+ return 1
\ No newline at end of file
diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm
index 5138014dce1..c230a3f5a9b 100644
--- a/code/game/objects/items/devices/radio/intercom.dm
+++ b/code/game/objects/items/devices/radio/intercom.dm
@@ -4,7 +4,7 @@
icon_state = "intercom"
anchored = 1
w_class = 4.0
- canhear_range = 7
+ canhear_range = 2
var/number = 0
var/anyai = 1
var/mob/living/silicon/ai/ai = list()
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 3b5da8c3a1d..cc6a5b52f52 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -210,10 +210,12 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
if (!connection)
return
- Broadcast_Message(connection, new /mob/living/silicon/ai(src,null,null,1),
+ var/mob/living/silicon/ai/A = new /mob/living/silicon/ai(src, null, null, 1)
+ Broadcast_Message(connection, A,
0, "*garbled automated announcement*", src,
message, from, "Automated Announcement", from, "synthesized voice",
- 4, 0, 1)
+ 4, 0, list(1), 1459)
+ del(A)
return
/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 6d8a77549f2..f86f38cc83a 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -126,9 +126,11 @@ MASS SPECTROMETER
if(M.status_flags & FAKEDEATH)
OX = fake_oxy > 50 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal"
user.show_message("[OX] | [TX] | [BU] | [BR]")
- if (istype(M, /mob/living/carbon/human))
- if(M:virus2 || M:reagents.total_volume > 0)
+ if (istype(M, /mob/living/carbon))
+ if(M:reagents.total_volume > 0)
user.show_message(text("\red Warning: Unknown substance detected in subject's blood."))
+ if(M:virus2)
+ user.show_message(text("\red Warning: Unknown pathogen detected in subject's blood."))
if (M.getCloneLoss())
user.show_message("\red Subject appears to have been imperfectly cloned.")
for(var/datum/disease/D in M.viruses)
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index 62dfb126bf5..b3911d7c9f5 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -1,281 +1,280 @@
-/obj/item/robot_parts
- name = "robot parts"
- icon = 'icons/obj/robot_parts.dmi'
- item_state = "buildpipe"
- icon_state = "blank"
- flags = FPRINT | TABLEPASS | CONDUCT
- slot_flags = SLOT_BELT
- var/construction_time = 100
- var/list/construction_cost = list("metal"=20000,"glass"=5000)
- var/list/part = null
-
-/obj/item/robot_parts/l_arm
- name = "robot left arm"
- desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
- icon_state = "l_arm"
- construction_time = 200
- construction_cost = list("metal"=18000)
- part = list("l_arm","l_hand")
-
-/obj/item/robot_parts/r_arm
- name = "robot right arm"
- desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
- icon_state = "r_arm"
- construction_time = 200
- construction_cost = list("metal"=18000)
- part = list("r_arm","r_hand")
-
-/obj/item/robot_parts/l_leg
- name = "robot left leg"
- desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
- icon_state = "l_leg"
- construction_time = 200
- construction_cost = list("metal"=15000)
- part = list("l_leg","l_foot")
-
-/obj/item/robot_parts/r_leg
- name = "robot right leg"
- desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
- icon_state = "r_leg"
- construction_time = 200
- construction_cost = list("metal"=15000)
- part = list("r_leg","r_foot")
-
-/obj/item/robot_parts/chest
- name = "robot torso"
- desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell."
- icon_state = "chest"
- construction_time = 350
- construction_cost = list("metal"=40000)
- var/wires = 0.0
- var/obj/item/weapon/cell/cell = null
-
-/obj/item/robot_parts/head
- name = "robot head"
- desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals."
- icon_state = "head"
- construction_time = 350
- construction_cost = list("metal"=25000)
- var/obj/item/device/flash/flash1 = null
- var/obj/item/device/flash/flash2 = null
-
-/obj/item/robot_parts/robot_suit
- name = "robot endoskeleton"
- desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors."
- icon_state = "robo_suit"
- construction_time = 500
- construction_cost = list("metal"=50000)
- var/obj/item/robot_parts/l_arm/l_arm = null
- var/obj/item/robot_parts/r_arm/r_arm = null
- var/obj/item/robot_parts/l_leg/l_leg = null
- var/obj/item/robot_parts/r_leg/r_leg = null
- var/obj/item/robot_parts/chest/chest = null
- var/obj/item/robot_parts/head/head = null
- var/created_name = ""
-
-/obj/item/robot_parts/robot_suit/New()
- ..()
- src.updateicon()
-
-/obj/item/robot_parts/robot_suit/proc/updateicon()
- src.overlays.Cut()
- if(src.l_arm)
- src.overlays += "l_arm+o"
- if(src.r_arm)
- src.overlays += "r_arm+o"
- if(src.chest)
- src.overlays += "chest+o"
- if(src.l_leg)
- src.overlays += "l_leg+o"
- if(src.r_leg)
- src.overlays += "r_leg+o"
- if(src.head)
- src.overlays += "head+o"
-
-/obj/item/robot_parts/robot_suit/proc/check_completion()
- if(src.l_arm && src.r_arm)
- if(src.l_leg && src.r_leg)
- if(src.chest && src.head)
- feedback_inc("cyborg_frames_built",1)
- return 1
- return 0
-
-/obj/item/robot_parts/robot_suit/attackby(obj/item/W as obj, mob/user as mob)
- ..()
- if(istype(W, /obj/item/stack/sheet/metal) && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
- var/obj/item/weapon/ed209_assembly/B = new /obj/item/weapon/ed209_assembly
- B.loc = get_turf(src)
- user << "You armed the robot frame"
- W:use(1)
- if (user.get_inactive_hand()==src)
- user.before_take_item(src)
- user.put_in_inactive_hand(B)
- del(src)
- if(istype(W, /obj/item/robot_parts/l_leg))
- if(src.l_leg) return
- user.drop_item()
- W.loc = src
- src.l_leg = W
- src.updateicon()
-
- if(istype(W, /obj/item/robot_parts/r_leg))
- if(src.r_leg) return
- user.drop_item()
- W.loc = src
- src.r_leg = W
- src.updateicon()
-
- if(istype(W, /obj/item/robot_parts/l_arm))
- if(src.l_arm) return
- user.drop_item()
- W.loc = src
- src.l_arm = W
- src.updateicon()
-
- if(istype(W, /obj/item/robot_parts/r_arm))
- if(src.r_arm) return
- user.drop_item()
- W.loc = src
- src.r_arm = W
- src.updateicon()
-
- if(istype(W, /obj/item/robot_parts/chest))
- if(src.chest) return
- if(W:wires && W:cell)
- user.drop_item()
- W.loc = src
- src.chest = W
- src.updateicon()
- else if(!W:wires)
- user << "\blue You need to attach wires to it first!"
- else
- user << "\blue You need to attach a cell to it first!"
-
- if(istype(W, /obj/item/robot_parts/head))
- if(src.head) return
- if(W:flash2 && W:flash1)
- user.drop_item()
- W.loc = src
- src.head = W
- src.updateicon()
- else
- user << "\blue You need to attach a flash to it first!"
-
- if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/posibrain))
- var/obj/item/device/mmi/M = W
- if(check_completion())
- if(!istype(loc,/turf))
- user << "\red You can't put the [W] in, the frame has to be standing on the ground to be perfectly precise."
- return
- if(!M.brainmob)
- user << "\red Sticking an empty [W] into the frame would sort of defeat the purpose."
- return
- if(!M.brainmob.key)
- var/ghost_can_reenter = 0
- if(M.brainmob.mind)
- for(var/mob/dead/observer/G in player_list)
- if(G.can_reenter_corpse && G.mind == M.brainmob.mind)
- ghost_can_reenter = 1
- break
- if(!ghost_can_reenter)
- user << "The [W] is completely unresponsive; there's no point."
- return
-
- if(M.brainmob.stat == DEAD)
- user << "\red Sticking a dead [W] into the frame would sort of defeat the purpose."
- return
-
- if(M.brainmob.mind in ticker.mode.head_revolutionaries)
- user << "\red The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [W]."
- return
-
- if(jobban_isbanned(M.brainmob, "Cyborg"))
- user << "\red This [W] does not seem to fit."
- return
-
- var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc))
- if(!O) return
-
- user.drop_item()
-
- O.mmi = W
- O.invisibility = 0
- O.custom_name = created_name
- O.updatename("Default")
-
- M.brainmob.mind.transfer_to(O)
-
- if(O.mind && O.mind.special_role)
- O.mind.store_memory("In case you look at this after being borged, the objectives are only here until I find a way to make them not show up for you, as I can't simply delete them without screwing up round-end reporting. --NeoFite")
-
- O.job = "Cyborg"
-
- O.cell = chest.cell
- O.cell.loc = O
- W.loc = O//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
-
- feedback_inc("cyborg_birth",1)
- O.Namepick()
-
- del(src)
- else
- user << "\blue The MMI must go in after everything else!"
-
- if (istype(W, /obj/item/weapon/pen))
- var/t = stripped_input(user, "Enter new robot name", src.name, src.created_name, MAX_NAME_LEN)
- if (!t)
- return
- if (!in_range(src, usr) && src.loc != usr)
- return
-
- src.created_name = t
-
- return
-
-/obj/item/robot_parts/chest/attackby(obj/item/W as obj, mob/user as mob)
- ..()
- if(istype(W, /obj/item/weapon/cell))
- if(src.cell)
- user << "\blue You have already inserted a cell!"
- return
- else
- user.drop_item()
- W.loc = src
- src.cell = W
- user << "\blue You insert the cell!"
- if(istype(W, /obj/item/weapon/cable_coil))
- if(src.wires)
- user << "\blue You have already inserted wire!"
- return
- else
- var/obj/item/weapon/cable_coil/coil = W
- coil.use(1)
- src.wires = 1.0
- user << "\blue You insert the wire!"
- return
-
-/obj/item/robot_parts/head/attackby(obj/item/W as obj, mob/user as mob)
- ..()
- if(istype(W, /obj/item/device/flash))
- if(src.flash1 && src.flash2)
- user << "\blue You have already inserted the eyes!"
- return
- else if(src.flash1)
- user.drop_item()
- W.loc = src
- src.flash2 = W
- user << "\blue You insert the flash into the eye socket!"
- else
- user.drop_item()
- W.loc = src
- src.flash1 = W
- user << "\blue You insert the flash into the eye socket!"
- else if(istype(W, /obj/item/weapon/stock_parts/manipulator))
- user << "\blue You install some manipulators and modify the head, creating a functional spider-bot!"
- new /mob/living/simple_animal/spiderbot(get_turf(loc))
- user.drop_item()
- del(W)
- del(src)
- return
- return
-
+/obj/item/robot_parts
+ name = "robot parts"
+ icon = 'icons/obj/robot_parts.dmi'
+ item_state = "buildpipe"
+ icon_state = "blank"
+ flags = FPRINT | TABLEPASS | CONDUCT
+ slot_flags = SLOT_BELT
+ var/construction_time = 100
+ var/list/construction_cost = list("metal"=20000,"glass"=5000)
+ var/list/part = null
+
+/obj/item/robot_parts/l_arm
+ name = "robot left arm"
+ desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
+ icon_state = "l_arm"
+ construction_time = 200
+ construction_cost = list("metal"=18000)
+ part = list("l_arm","l_hand")
+
+/obj/item/robot_parts/r_arm
+ name = "robot right arm"
+ desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
+ icon_state = "r_arm"
+ construction_time = 200
+ construction_cost = list("metal"=18000)
+ part = list("r_arm","r_hand")
+
+/obj/item/robot_parts/l_leg
+ name = "robot left leg"
+ desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
+ icon_state = "l_leg"
+ construction_time = 200
+ construction_cost = list("metal"=15000)
+ part = list("l_leg","l_foot")
+
+/obj/item/robot_parts/r_leg
+ name = "robot right leg"
+ desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
+ icon_state = "r_leg"
+ construction_time = 200
+ construction_cost = list("metal"=15000)
+ part = list("r_leg","r_foot")
+
+/obj/item/robot_parts/chest
+ name = "robot torso"
+ desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell."
+ icon_state = "chest"
+ construction_time = 350
+ construction_cost = list("metal"=40000)
+ var/wires = 0.0
+ var/obj/item/weapon/cell/cell = null
+
+/obj/item/robot_parts/head
+ name = "robot head"
+ desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals."
+ icon_state = "head"
+ construction_time = 350
+ construction_cost = list("metal"=25000)
+ var/obj/item/device/flash/flash1 = null
+ var/obj/item/device/flash/flash2 = null
+
+/obj/item/robot_parts/robot_suit
+ name = "robot endoskeleton"
+ desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors."
+ icon_state = "robo_suit"
+ construction_time = 500
+ construction_cost = list("metal"=50000)
+ var/obj/item/robot_parts/l_arm/l_arm = null
+ var/obj/item/robot_parts/r_arm/r_arm = null
+ var/obj/item/robot_parts/l_leg/l_leg = null
+ var/obj/item/robot_parts/r_leg/r_leg = null
+ var/obj/item/robot_parts/chest/chest = null
+ var/obj/item/robot_parts/head/head = null
+ var/created_name = ""
+
+/obj/item/robot_parts/robot_suit/New()
+ ..()
+ src.updateicon()
+
+/obj/item/robot_parts/robot_suit/proc/updateicon()
+ src.overlays.Cut()
+ if(src.l_arm)
+ src.overlays += "l_arm+o"
+ if(src.r_arm)
+ src.overlays += "r_arm+o"
+ if(src.chest)
+ src.overlays += "chest+o"
+ if(src.l_leg)
+ src.overlays += "l_leg+o"
+ if(src.r_leg)
+ src.overlays += "r_leg+o"
+ if(src.head)
+ src.overlays += "head+o"
+
+/obj/item/robot_parts/robot_suit/proc/check_completion()
+ if(src.l_arm && src.r_arm)
+ if(src.l_leg && src.r_leg)
+ if(src.chest && src.head)
+ feedback_inc("cyborg_frames_built",1)
+ return 1
+ return 0
+
+/obj/item/robot_parts/robot_suit/attackby(obj/item/W as obj, mob/user as mob)
+ ..()
+ if(istype(W, /obj/item/stack/sheet/metal) && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
+ var/obj/item/weapon/ed209_assembly/B = new /obj/item/weapon/ed209_assembly
+ B.loc = get_turf(src)
+ user << "You armed the robot frame"
+ W:use(1)
+ if (user.get_inactive_hand()==src)
+ user.before_take_item(src)
+ user.put_in_inactive_hand(B)
+ del(src)
+ if(istype(W, /obj/item/robot_parts/l_leg))
+ if(src.l_leg) return
+ user.drop_item()
+ W.loc = src
+ src.l_leg = W
+ src.updateicon()
+
+ if(istype(W, /obj/item/robot_parts/r_leg))
+ if(src.r_leg) return
+ user.drop_item()
+ W.loc = src
+ src.r_leg = W
+ src.updateicon()
+
+ if(istype(W, /obj/item/robot_parts/l_arm))
+ if(src.l_arm) return
+ user.drop_item()
+ W.loc = src
+ src.l_arm = W
+ src.updateicon()
+
+ if(istype(W, /obj/item/robot_parts/r_arm))
+ if(src.r_arm) return
+ user.drop_item()
+ W.loc = src
+ src.r_arm = W
+ src.updateicon()
+
+ if(istype(W, /obj/item/robot_parts/chest))
+ if(src.chest) return
+ if(W:wires && W:cell)
+ user.drop_item()
+ W.loc = src
+ src.chest = W
+ src.updateicon()
+ else if(!W:wires)
+ user << "\blue You need to attach wires to it first!"
+ else
+ user << "\blue You need to attach a cell to it first!"
+
+ if(istype(W, /obj/item/robot_parts/head))
+ if(src.head) return
+ if(W:flash2 && W:flash1)
+ user.drop_item()
+ W.loc = src
+ src.head = W
+ src.updateicon()
+ else
+ user << "\blue You need to attach a flash to it first!"
+
+ if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/mmi/posibrain))
+ var/obj/item/device/mmi/M = W
+ if(check_completion())
+ if(!istype(loc,/turf))
+ user << "\red You can't put the [W] in, the frame has to be standing on the ground to be perfectly precise."
+ return
+ if(!M.brainmob)
+ user << "\red Sticking an empty [W] into the frame would sort of defeat the purpose."
+ return
+ if(!M.brainmob.key)
+ var/ghost_can_reenter = 0
+ if(M.brainmob.mind)
+ for(var/mob/dead/observer/G in player_list)
+ if(G.can_reenter_corpse && G.mind == M.brainmob.mind)
+ ghost_can_reenter = 1
+ break
+ if(!ghost_can_reenter)
+ user << "The [W] is completely unresponsive; there's no point."
+ return
+
+ if(M.brainmob.stat == DEAD)
+ user << "\red Sticking a dead [W] into the frame would sort of defeat the purpose."
+ return
+
+ if(M.brainmob.mind in ticker.mode.head_revolutionaries)
+ user << "\red The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [W]."
+ return
+
+ if(jobban_isbanned(M.brainmob, "Cyborg"))
+ user << "\red This [W] does not seem to fit."
+ return
+
+ var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc))
+ if(!O) return
+
+ user.drop_item()
+
+ O.mmi = W
+ O.invisibility = 0
+ O.custom_name = created_name
+ O.updatename("Default")
+
+ M.brainmob.mind.transfer_to(O)
+
+ if(O.mind && O.mind.special_role)
+ O.mind.store_memory("In case you look at this after being borged, the objectives are only here until I find a way to make them not show up for you, as I can't simply delete them without screwing up round-end reporting. --NeoFite")
+
+ O.job = "Cyborg"
+
+ O.cell = chest.cell
+ O.cell.loc = O
+ W.loc = O//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
+
+ feedback_inc("cyborg_birth",1)
+ O.Namepick()
+
+ del(src)
+ else
+ user << "\blue The MMI must go in after everything else!"
+
+ if (istype(W, /obj/item/weapon/pen))
+ var/t = stripped_input(user, "Enter new robot name", src.name, src.created_name, MAX_NAME_LEN)
+ if (!t)
+ return
+ if (!in_range(src, usr) && src.loc != usr)
+ return
+
+ src.created_name = t
+
+ return
+
+/obj/item/robot_parts/chest/attackby(obj/item/W as obj, mob/user as mob)
+ ..()
+ if(istype(W, /obj/item/weapon/cell))
+ if(src.cell)
+ user << "\blue You have already inserted a cell!"
+ return
+ else
+ user.drop_item()
+ W.loc = src
+ src.cell = W
+ user << "\blue You insert the cell!"
+ if(istype(W, /obj/item/weapon/cable_coil))
+ if(src.wires)
+ user << "\blue You have already inserted wire!"
+ return
+ else
+ var/obj/item/weapon/cable_coil/coil = W
+ coil.use(1)
+ src.wires = 1.0
+ user << "\blue You insert the wire!"
+ return
+
+/obj/item/robot_parts/head/attackby(obj/item/W as obj, mob/user as mob)
+ ..()
+ if(istype(W, /obj/item/device/flash))
+ if(src.flash1 && src.flash2)
+ user << "\blue You have already inserted the eyes!"
+ return
+ else if(src.flash1)
+ user.drop_item()
+ W.loc = src
+ src.flash2 = W
+ user << "\blue You insert the flash into the eye socket!"
+ else
+ user.drop_item()
+ W.loc = src
+ src.flash1 = W
+ user << "\blue You insert the flash into the eye socket!"
+ else if(istype(W, /obj/item/weapon/stock_parts/manipulator))
+ user << "\blue You install some manipulators and modify the head, creating a functional spider-bot!"
+ new /mob/living/simple_animal/spiderbot(get_turf(loc))
+ user.drop_item()
+ del(W)
+ del(src)
+ return
+ return
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index 07a7a6308b5..4d8ef18f03d 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -1,168 +1,168 @@
-// robot_upgrades.dm
-// Contains various borg upgrades.
-
-/obj/item/borg/upgrade
- name = "A borg upgrade module."
- desc = "Protected by FRM."
- icon = 'icons/obj/module.dmi'
- icon_state = "cyborg_upgrade"
- var/construction_time = 120
- var/construction_cost = list("metal"=10000)
- var/locked = 0
- var/require_module = 0
- var/installed = 0
-
-/obj/item/borg/upgrade/proc/action(var/mob/living/silicon/robot/R)
- if(R.stat == DEAD)
- usr << "/red The [src] will not function on a deceased robot."
- return 1
- return 0
-
-
-/obj/item/borg/upgrade/reset
- name = "robotic module reset board"
- desc = "Used to reset a cyborg's module. Destroys any other upgrades applied to the robot."
- icon_state = "cyborg_upgrade1"
- require_module = 1
-
-/obj/item/borg/upgrade/reset/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
- R.uneq_all()
- R.hands.icon_state = "nomod"
- R.icon_state = "robot"
- del(R.module)
- R.module = null
- R.modtype = "robot"
- R.updatename("Default")
- R.status_flags |= CANPUSH
- R.updateicon()
-
- return 1
-
-/obj/item/borg/upgrade/rename
- name = "robot reclassification board"
- desc = "Used to rename a cyborg."
- icon_state = "cyborg_upgrade1"
- construction_cost = list("metal"=35000)
- var/heldname = "default name"
-
-/obj/item/borg/upgrade/rename/attack_self(mob/user as mob)
- heldname = stripped_input(user, "Enter new robot name", "Robot Reclassification", heldname, MAX_NAME_LEN)
-
-/obj/item/borg/upgrade/rename/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
- R.name = heldname
- R.real_name = heldname
-
- return 1
-
-/obj/item/borg/upgrade/restart
- name = "robot emergency restart module"
- desc = "Used to force a restart of a disabled-but-repaired robot, bringing it back online."
- construction_cost = list("metal"=60000 , "glass"=5000)
- icon_state = "cyborg_upgrade1"
-
-
-/obj/item/borg/upgrade/restart/action(var/mob/living/silicon/robot/R)
- if(R.health < 0)
- usr << "You have to repair the robot before using this module!"
- return 0
-
- if(!R.key)
- for(var/mob/dead/observer/ghost in player_list)
- if(ghost.mind && ghost.mind.current == R)
- R.key = ghost.key
-
- R.stat = CONSCIOUS
- return 1
-
-
-/obj/item/borg/upgrade/vtec
- name = "robotic VTEC Module"
- desc = "Used to kick in a robot's VTEC systems, increasing their speed."
- construction_cost = list("metal"=80000 , "glass"=6000 , "gold"= 5000)
- icon_state = "cyborg_upgrade2"
- require_module = 1
-
-/obj/item/borg/upgrade/vtec/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
-
- if(R.speed == -1)
- return 0
-
- R.speed--
- return 1
-
-
-/obj/item/borg/upgrade/tasercooler
- name = "robotic Rapid Taser Cooling Module"
- desc = "Used to cool a mounted taser, increasing the potential current in it and thus its recharge rate."
- construction_cost = list("metal"=80000 , "glass"=6000 , "gold"= 2000, "diamond" = 500)
- icon_state = "cyborg_upgrade3"
- require_module = 1
-
-
-/obj/item/borg/upgrade/tasercooler/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
-
- if(!istype(R.module, /obj/item/weapon/robot_module/security))
- R << "Upgrade mounting error! No suitable hardpoint detected!"
- usr << "There's no mounting point for the module!"
- return 0
-
- var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in R.module
- if(!T)
- T = locate() in R.module.contents
- if(!T)
- T = locate() in R.module.modules
- if(!T)
- usr << "This robot has had its taser removed!"
- return 0
-
- if(T.recharge_time <= 2)
- R << "Maximum cooling achieved for this hardpoint!"
- usr << "There's no room for another cooling unit!"
- return 0
-
- else
- T.recharge_time = max(2 , T.recharge_time - 4)
-
- return 1
-
-/obj/item/borg/upgrade/jetpack
- name = "mining robot jetpack"
- desc = "A carbon dioxide jetpack suitable for low-gravity mining operations."
- construction_cost = list("metal"=10000,"plasma"=15000,"uranium" = 20000)
- icon_state = "cyborg_upgrade3"
- require_module = 1
-
-/obj/item/borg/upgrade/jetpack/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
-
- if(!istype(R.module, /obj/item/weapon/robot_module/miner))
- R << "Upgrade mounting error! No suitable hardpoint detected!"
- usr << "There's no mounting point for the module!"
- return 0
- else
- R.module.modules += new/obj/item/weapon/tank/jetpack/carbondioxide
- for(var/obj/item/weapon/tank/jetpack/carbondioxide in R.module.modules)
- R.internals = src
- R.icon_state="Miner+j"
- return 1
-
-
-/obj/item/borg/upgrade/syndicate/
- name = "Illegal Equipment Module"
- desc = "Unlocks the hidden, deadlier functions of a robot"
- construction_cost = list("metal"=10000,"glass"=15000,"diamond" = 10000)
- icon_state = "cyborg_upgrade3"
- require_module = 1
-
-/obj/item/borg/upgrade/syndicate/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
-
- if(R.emagged == 1)
- return 0
-
- R.emagged = 1
+// robot_upgrades.dm
+// Contains various borg upgrades.
+
+/obj/item/borg/upgrade
+ name = "A borg upgrade module."
+ desc = "Protected by FRM."
+ icon = 'icons/obj/module.dmi'
+ icon_state = "cyborg_upgrade"
+ var/construction_time = 120
+ var/construction_cost = list("metal"=10000)
+ var/locked = 0
+ var/require_module = 0
+ var/installed = 0
+
+/obj/item/borg/upgrade/proc/action(var/mob/living/silicon/robot/R)
+ if(R.stat == DEAD)
+ usr << "/red The [src] will not function on a deceased robot."
+ return 1
+ return 0
+
+
+/obj/item/borg/upgrade/reset
+ name = "robotic module reset board"
+ desc = "Used to reset a cyborg's module. Destroys any other upgrades applied to the robot."
+ icon_state = "cyborg_upgrade1"
+ require_module = 1
+
+/obj/item/borg/upgrade/reset/action(var/mob/living/silicon/robot/R)
+ if(..()) return 0
+ R.uneq_all()
+ R.hands.icon_state = "nomod"
+ R.icon_state = "robot"
+ del(R.module)
+ R.module = null
+ R.modtype = "robot"
+ R.updatename("Default")
+ R.status_flags |= CANPUSH
+ R.updateicon()
+
+ return 1
+
+/obj/item/borg/upgrade/rename
+ name = "robot reclassification board"
+ desc = "Used to rename a cyborg."
+ icon_state = "cyborg_upgrade1"
+ construction_cost = list("metal"=35000)
+ var/heldname = "default name"
+
+/obj/item/borg/upgrade/rename/attack_self(mob/user as mob)
+ heldname = stripped_input(user, "Enter new robot name", "Robot Reclassification", heldname, MAX_NAME_LEN)
+
+/obj/item/borg/upgrade/rename/action(var/mob/living/silicon/robot/R)
+ if(..()) return 0
+ R.name = heldname
+ R.real_name = heldname
+
+ return 1
+
+/obj/item/borg/upgrade/restart
+ name = "robot emergency restart module"
+ desc = "Used to force a restart of a disabled-but-repaired robot, bringing it back online."
+ construction_cost = list("metal"=60000 , "glass"=5000)
+ icon_state = "cyborg_upgrade1"
+
+
+/obj/item/borg/upgrade/restart/action(var/mob/living/silicon/robot/R)
+ if(R.health < 0)
+ usr << "You have to repair the robot before using this module!"
+ return 0
+
+ if(!R.key)
+ for(var/mob/dead/observer/ghost in player_list)
+ if(ghost.mind && ghost.mind.current == R)
+ R.key = ghost.key
+
+ R.stat = CONSCIOUS
+ return 1
+
+
+/obj/item/borg/upgrade/vtec
+ name = "robotic VTEC Module"
+ desc = "Used to kick in a robot's VTEC systems, increasing their speed."
+ construction_cost = list("metal"=80000 , "glass"=6000 , "gold"= 5000)
+ icon_state = "cyborg_upgrade2"
+ require_module = 1
+
+/obj/item/borg/upgrade/vtec/action(var/mob/living/silicon/robot/R)
+ if(..()) return 0
+
+ if(R.speed == -1)
+ return 0
+
+ R.speed--
+ return 1
+
+
+/obj/item/borg/upgrade/tasercooler
+ name = "robotic Rapid Taser Cooling Module"
+ desc = "Used to cool a mounted taser, increasing the potential current in it and thus its recharge rate."
+ construction_cost = list("metal"=80000 , "glass"=6000 , "gold"= 2000, "diamond" = 500)
+ icon_state = "cyborg_upgrade3"
+ require_module = 1
+
+
+/obj/item/borg/upgrade/tasercooler/action(var/mob/living/silicon/robot/R)
+ if(..()) return 0
+
+ if(!istype(R.module, /obj/item/weapon/robot_module/security))
+ R << "Upgrade mounting error! No suitable hardpoint detected!"
+ usr << "There's no mounting point for the module!"
+ return 0
+
+ var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in R.module
+ if(!T)
+ T = locate() in R.module.contents
+ if(!T)
+ T = locate() in R.module.modules
+ if(!T)
+ usr << "This robot has had its taser removed!"
+ return 0
+
+ if(T.recharge_time <= 2)
+ R << "Maximum cooling achieved for this hardpoint!"
+ usr << "There's no room for another cooling unit!"
+ return 0
+
+ else
+ T.recharge_time = max(2 , T.recharge_time - 4)
+
+ return 1
+
+/obj/item/borg/upgrade/jetpack
+ name = "mining robot jetpack"
+ desc = "A carbon dioxide jetpack suitable for low-gravity mining operations."
+ construction_cost = list("metal"=10000,"plasma"=15000,"uranium" = 20000)
+ icon_state = "cyborg_upgrade3"
+ require_module = 1
+
+/obj/item/borg/upgrade/jetpack/action(var/mob/living/silicon/robot/R)
+ if(..()) return 0
+
+ if(!istype(R.module, /obj/item/weapon/robot_module/miner))
+ R << "Upgrade mounting error! No suitable hardpoint detected!"
+ usr << "There's no mounting point for the module!"
+ return 0
+ else
+ R.module.modules += new/obj/item/weapon/tank/jetpack/carbondioxide
+ for(var/obj/item/weapon/tank/jetpack/carbondioxide in R.module.modules)
+ R.internals = src
+ R.icon_state="Miner+j"
+ return 1
+
+
+/obj/item/borg/upgrade/syndicate/
+ name = "Illegal Equipment Module"
+ desc = "Unlocks the hidden, deadlier functions of a robot"
+ construction_cost = list("metal"=10000,"glass"=15000,"diamond" = 10000)
+ icon_state = "cyborg_upgrade3"
+ require_module = 1
+
+/obj/item/borg/upgrade/syndicate/action(var/mob/living/silicon/robot/R)
+ if(..()) return 0
+
+ if(R.emagged == 1)
+ return 0
+
+ R.emagged = 1
return 1
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index d79a76507a5..82abc09f7ea 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -76,9 +76,9 @@
M.updatehealth()
/obj/item/stack/medical/bruise_pack
- name = "bruise pack"
- singular_name = "bruise pack"
- desc = "A pack designed to treat blunt-force trauma."
+ name = "roll of gauze"
+ singular_name = "gauze length"
+ desc = "Some sterile gauze to wrap around bloody stumps."
icon_state = "brutepack"
heal_brute = 60
origin_tech = "biotech=1"
diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm
index c4697e63b6f..026ddb77f5f 100644
--- a/code/game/objects/items/stacks/nanopaste.dm
+++ b/code/game/objects/items/stacks/nanopaste.dm
@@ -1,7 +1,7 @@
/obj/item/stack/nanopaste
name = "nanopaste"
singular_name = "nanite swarm"
- desc = "A tube of paste containing swarms of repair nanties. Very effective in repairing robotic machinery."
+ desc = "A tube of paste containing swarms of repair nanites. Very effective in repairing robotic machinery."
icon = 'icons/obj/nanopaste.dmi'
icon_state = "tube"
origin_tech = "materials=4;engineering=3"
@@ -14,12 +14,12 @@
if (istype(M,/mob/living/silicon/robot)) //Repairing cyborgs
var/mob/living/silicon/robot/R = M
if (R.getBruteLoss() || R.getFireLoss() )
- R.adjustBruteLoss(-60)
- R.adjustFireLoss(-60)
+ R.adjustBruteLoss(-15)
+ R.adjustFireLoss(-15)
R.updatehealth()
use(1)
- user.visible_message("You apply some [src] at [R]'s damaged areas.",\
- "\The [user] applied some [src] at [R]'s damaged areas.")
+ user.visible_message("\The [user] applied some [src] at [R]'s damaged areas.",\
+ "You apply some [src] at [R]'s damaged areas.")
else
user << "All [R]'s systems are nominal."
@@ -28,10 +28,10 @@
var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting)
if (S && (S.status & ORGAN_ROBOT))
if(S.get_damage())
- S.heal_damage(30, 30, robo_repair = 1)
+ S.heal_damage(15, 15, robo_repair = 1)
H.updatehealth()
use(1)
- user.visible_message("You apply some nanite paste at [user == M ? "your" : "[M]'s"] [S.display_name]",\
- "\The [user] applies some nanite paste at[user != M ? " \the [M]'s" : " \the"][S.display_name] with \the [src]")
+ user.visible_message("\The [user] applies some nanite paste at[user != M ? " \the [M]'s" : " \the"][S.display_name] with \the [src].",\
+ "You apply some nanite paste at [user == M ? "your" : "[M]'s"] [S.display_name].")
else
user << "Nothing to fix here."
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
index 835666b7fe4..0169f5d894c 100644
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -287,7 +287,7 @@
var/datum/organ/external/affecting = H.get_organ(pick("l_foot", "r_foot"))
if(affecting.status & ORGAN_ROBOT)
return
-
+
H.Weaken(3)
if(affecting.take_damage(5, 0))
H.UpdateDamageIcon()
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 42fe0a3e4ca..c76ff2511f6 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -114,6 +114,33 @@ var/global/list/datum/stack_recipe/plasma_recipes = list ( \
pixel_y = rand(0,4)-4
..()
+/obj/item/stack/sheet/mineral/plastic
+ name = "Plastic"
+ icon_state = "sheet-plastic"
+ force = 5.0
+ throwforce = 5
+ w_class = 3.0
+ throw_speed = 3
+ throw_range = 3
+ origin_tech = "materials=3"
+ perunit = 2000
+ sheettype = "plastic"
+
+var/global/list/datum/stack_recipe/plastic_recipes = list ( \
+ new/datum/stack_recipe("plastic crate", /obj/structure/closet/pcrate, 10, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("plastic ashtray", /obj/item/ashtray/plastic, 2, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("plastic fork", /obj/item/weapon/kitchen/utensil/pfork, 1, on_floor = 1), \
+ new/datum/stack_recipe("plastic spoon", /obj/item/weapon/kitchen/utensil/pspoon, 1, on_floor = 1), \
+ new/datum/stack_recipe("plastic knife", /obj/item/weapon/kitchen/utensil/pknife, 1, on_floor = 1), \
+ new/datum/stack_recipe("plastic bag", /obj/item/weapon/storage/bag/plasticbag, 3, on_floor = 1), \
+ )
+
+/obj/item/stack/sheet/mineral/plastic/New(var/loc, var/amount=null)
+ recipes = plastic_recipes
+ pixel_x = rand(0,4)-4
+ pixel_y = rand(0,4)-4
+ ..()
+
/*
* Gold
*/
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 6c3814a8010..dd4d2662a7d 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -556,6 +556,7 @@
name = "toy phazon"
desc = "Mini-Mecha action figure! Collect them all! 11/11."
icon_state = "phazonprize"
+
/obj/item/toy/katana
name = "replica katana"
desc = "Woefully underpowered in D20."
@@ -575,4 +576,4 @@
desc = "This baby looks almost real. Wait, did it just burp?"
force = 5
w_class = 4.0
- slot_flags = SLOT_BACK
+ slot_flags = SLOT_BACK
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 649a4fe713c..aeb3e86227d 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -119,7 +119,7 @@
/obj/item/weapon/card/id/syndicate
name = "agent card"
- access = list(access_maint_tunnels, access_syndicate)
+ access = list(access_maint_tunnels, access_syndicate, access_external_airlocks)
origin_tech = "syndicate=3"
/obj/item/weapon/card/id/syndicate/afterattack(var/obj/item/weapon/O as obj, mob/user as mob)
@@ -156,7 +156,7 @@
desc = "An ID straight from the Syndicate."
registered_name = "Syndicate"
assignment = "Syndicate Overlord"
- access = list(access_syndicate)
+ access = list(access_syndicate, access_external_airlocks)
/obj/item/weapon/card/id/captains_spare
name = "captain's spare ID"
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
index 86fb3a87e24..8639477ce48 100644
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -209,15 +209,17 @@
/obj/item/weapon/flamethrower/proc/ignite_turf(turf/target)
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
//Transfer 5% of current tank air contents to turf
- var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.05)
- air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is retarded and I could probably make it work without fucking it up like this, but there you have it. -- TLE
+ var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.02*(throw_amount/100))
+ //air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is retarded and I could probably make it work without fucking it up like this, but there you have it. -- TLE
+ new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(target,air_transfer.toxins,get_dir(loc,target))
+ air_transfer.toxins = 0
target.assume_air(air_transfer)
//Burn it based on transfered gas
+ //target.hotspot_expose(part4.air_contents.temperature*2,300)
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) // -- More of my "how do I shot fire?" dickery. -- TLE
//location.hotspot_expose(1000,500,1)
return
-
/obj/item/weapon/flamethrower/full/New(var/loc)
..()
weldtool = new /obj/item/weapon/weldingtool(src)
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index 168ef431ede..0c075c5725a 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -114,7 +114,7 @@
activate(mob/user as mob)
if(active) return
-
+
if(detonator)
if(!isigniter(detonator.a_left))
detonator.a_left.activate()
@@ -216,9 +216,11 @@
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
- B1.reagents.add_reagent("aluminum", 25)
- B2.reagents.add_reagent("plasma", 25)
- B2.reagents.add_reagent("sacid", 25)
+ B1.reagents.add_reagent("aluminum", 15)
+ B1.reagents.add_reagent("fuel",20)
+ B2.reagents.add_reagent("plasma", 15)
+ B2.reagents.add_reagent("sacid", 15)
+ B1.reagents.add_reagent("fuel",20)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
diff --git a/code/game/objects/items/weapons/hydroponics.dm b/code/game/objects/items/weapons/hydroponics.dm
index 024dcd60084..daebf114d2f 100644
--- a/code/game/objects/items/weapons/hydroponics.dm
+++ b/code/game/objects/items/weapons/hydroponics.dm
@@ -209,7 +209,7 @@
*/
/obj/item/weapon/corncob/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
- if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/kitchen/utensil/knife))
+ if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/kitchen/utensil/knife) || istype(W, /obj/item/weapon/kitchenknife) || istype(W, /obj/item/weapon/kitchenknife/ritual))
user << "You use [W] to fashion a pipe out of the corn cob!"
new /obj/item/clothing/mask/cigarette/pipe/cobpipe (user.loc)
del(src)
diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm
index 02f270d767d..a68276a3100 100644
--- a/code/game/objects/items/weapons/kitchen.dm
+++ b/code/game/objects/items/weapons/kitchen.dm
@@ -34,12 +34,18 @@
/*
* Spoons
*/
- /obj/item/weapon/kitchen/utensil/spoon
+/obj/item/weapon/kitchen/utensil/spoon
name = "spoon"
desc = "SPOON!"
icon_state = "spoon"
attack_verb = list("attacked", "poked")
+/obj/item/weapon/kitchen/utensil/pspoon
+ name = "plastic spoon"
+ desc = "Super dull action!"
+ icon_state = "pspoon"
+ attack_verb = list("attacked", "poked")
+
/*
* Forks
*/
@@ -71,6 +77,34 @@
M = user
return eyestab(M,user)
+/obj/item/weapon/kitchen/utensil/pfork
+ name = "plastic fork"
+ desc = "Yay, no washing up to do."
+ icon_state = "pfork"
+
+/obj/item/weapon/kitchen/utensil/pfork/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ if(!istype(M))
+ return ..()
+
+ if(user.zone_sel.selecting != "eyes" && user.zone_sel.selecting != "head")
+ return ..()
+
+ if (src.icon_state == "forkloaded") //This is a poor way of handling it, but a proper rewrite of the fork to allow for a more varied foodening can happen when I'm in the mood. --NEO
+ if(M == user)
+ for(var/mob/O in viewers(M, null))
+ O.show_message(text("\blue [] eats a delicious forkful of omelette!", user), 1)
+ M.reagents.add_reagent("nutriment", 1)
+ else
+ for(var/mob/O in viewers(M, null))
+ O.show_message(text("\blue [] feeds [] a delicious forkful of omelette!", user, M), 1)
+ M.reagents.add_reagent("nutriment", 1)
+ src.icon_state = "fork"
+ return
+ else
+ if((CLUMSY in user.mutations) && prob(50))
+ M = user
+ return eyestab(M,user)
+
/*
* Knives
*/
@@ -95,6 +129,21 @@
playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
return ..()
+/obj/item/weapon/kitchen/utensil/pknife
+ name = "plastic knife"
+ desc = "The bluntest of blades."
+ icon_state = "pknife"
+ force = 10.0
+ throwforce = 10.0
+
+/obj/item/weapon/kitchen/utensil/knife/attack(target as mob, mob/living/user as mob)
+ if ((CLUMSY in user.mutations) && prob(50))
+ user << "\red You somehow managed to cut yourself with the [src]."
+ user.take_organ_damage(20)
+ return
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
+ return ..()
+
/*
* Kitchen knives
*/
diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm
index ebaebdcabe0..706102d6145 100644
--- a/code/game/objects/items/weapons/storage/bags.dm
+++ b/code/game/objects/items/weapons/storage/bags.dm
@@ -38,7 +38,6 @@
can_hold = list() // any
cant_hold = list("/obj/item/weapon/disk/nuclear")
-
/obj/item/weapon/storage/bag/trash/update_icon()
if(contents.len == 0)
icon_state = "trashbag0"
@@ -48,6 +47,24 @@
icon_state = "trashbag2"
else icon_state = "trashbag3"
+
+// -----------------------------
+// Plastic Bag
+// -----------------------------
+
+/obj/item/weapon/storage/bag/plasticbag
+ name = "plastic bag"
+ desc = "It's a very flimsy, very noisy alternative to a bag."
+ icon = 'icons/obj/trash.dmi'
+ icon_state = "plasticbag"
+ item_state = "plasticbag"
+
+ w_class = 4
+ max_w_class = 2
+ storage_slots = 21
+ can_hold = list() // any
+ cant_hold = list("/obj/item/weapon/disk/nuclear")
+
// -----------------------------
// Mining Satchel
// -----------------------------
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index fcb00122873..9cc03ebce3b 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -51,7 +51,8 @@
"/obj/item/device/flashlight",
"/obj/item/weapon/cable_coil",
"/obj/item/device/t_scanner",
- "/obj/item/device/analyzer")
+ "/obj/item/device/analyzer",
+ "/obj/item/taperoll/engineering")
/obj/item/weapon/storage/belt/utility/full/New()
diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm
index a5874f09855..8ea7ff3903d 100644
--- a/code/game/objects/items/weapons/storage/firstaid.dm
+++ b/code/game/objects/items/weapons/storage/firstaid.dm
@@ -103,9 +103,10 @@
icon = 'icons/obj/chemical.dmi'
item_state = "contsolid"
w_class = 2.0
- can_hold = list("/obj/item/weapon/reagent_containers/pill","/obj/item/weapon/dice")
+ can_hold = list("/obj/item/weapon/reagent_containers/pill","/obj/item/weapon/dice","/obj/item/weapon/paper")
allow_quick_gather = 1
use_to_pickup = 1
+ storage_slots = 14
/obj/item/weapon/storage/pill_bottle/MouseDrop(obj/over_object as obj) //Quick pillbottle fix. -Agouri
diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm
index 2d332ce177f..673bb96c9bb 100644
--- a/code/game/objects/items/weapons/surgery_tools.dm
+++ b/code/game/objects/items/weapons/surgery_tools.dm
@@ -1,819 +1,819 @@
-/* Surgery Tools
- * Contains:
- * Retractor
- * Hemostat
- * Cautery
- * Surgical Drill
- * Scalpel
- * Circular Saw
- */
-
-/*
- * Retractor
- */
-/obj/item/weapon/retractor
- name = "retractor"
- desc = "Retracts stuff."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "retractor"
- m_amt = 10000
- g_amt = 5000
- flags = FPRINT | TABLEPASS | CONDUCT
- w_class = 1.0
- origin_tech = "materials=1;biotech=1"
-
-/*HAHA, SUCK IT, 2000 LINES OF SPAGHETTI CODE!
-
-NOW YOUR JOB IOS DONE BY ONLY 500 LINES OF SPAGHETTI CODE!
-
-LOOK FOR SURGERY.DM*/
-
-/*
-/obj/item/weapon/retractor/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M))
- return
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- if(istype(M, /mob/living/carbon/alien) || istype(M, /mob/living/carbon/slime))//Aliens don't have eyes./N
- user << "\red You cannot locate any eyes on this creature!"
- return
-
- switch(M.eye_op_stage)
- if(1.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is having his eyes retracted by [user].", 1)
- M << "\red [user] begins to seperate your eyes with [src]!"
- user << "\red You seperate [M]'s eyes with [src]!"
- else
- user.visible_message( \
- "\red [user] begins to have his eyes retracted.", \
- "\red You begin to pry open your eyes with [src]!" \
- )
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- M.updatehealth()
- else
- M.take_organ_damage(15)
-
- M:eye_op_stage = 2.0
-
- else if(user.zone_sel.selecting == "chest")
- switch(M:alien_op_stage)
- if(3.0)
- var/mob/living/carbon/human/H = M
- if(!istype(H))
- return ..()
-
- if(H.wear_suit || H.w_uniform)
- user << "\red You're going to need to remove that suit/jumpsuit first."
- return
-
- var/obj/item/alien_embryo/A = locate() in M.contents
- if(!A)
- return ..()
- user.visible_message("\red [user] begins to pull something out of [M]'s chest.", "\red You begin to pull the alien organism out of [M]'s chest.")
-
- spawn(20 + rand(0,50))
- if(!A || A.loc != M)
- return
-
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("chest")
- if(affecting.take_damage(30))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(30)
-
- if(A.stage > 3)
- var/chance = 15 + max(0, A.stage - 3) * 10
- if(prob(chance))
- A.AttemptGrow(0)
- M:alien_op_stage = 4.0
-
- if(M)
- user.visible_message("\red [user] pulls an alien organism out of [M]'s chest.", "\red You pull the alien organism out of [M]'s chest.")
- A.loc = M.loc //alien embryo handles cleanup
-
- else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
- return ..()
-
- return
-*/
-
-/*
- * Hemostat
- */
-/obj/item/weapon/hemostat
- name = "hemostat"
- desc = "You think you have seen this before."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "hemostat"
- m_amt = 5000
- g_amt = 2500
- flags = FPRINT | TABLEPASS | CONDUCT
- w_class = 1.0
- origin_tech = "materials=1;biotech=1"
- attack_verb = list("attacked", "pinched")
-
-/*
-/obj/item/weapon/hemostat/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M))
- return
-
- if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
- return ..()
-
- if(user.zone_sel.selecting == "groin")
- if(istype(M, /mob/living/carbon/human))
- switch(M:appendix_op_stage)
- if(1.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [user] is beginning to clamp bleeders in [M]'s abdomen cut open with [src].", 1)
- M << "\red [user] begins to clamp bleeders in your abdomen with [src]!"
- user << "\red You clamp bleeders in [M]'s abdomen with [src]!"
- M:appendix_op_stage = 2.0
- if(4.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [user] is removing [M]'s appendix with [src].", 1)
- M << "\red [user] begins to remove your appendix with [src]!"
- user << "\red You remove [M]'s appendix with [src]!"
- for(var/datum/disease/D in M.viruses)
- if(istype(D, /datum/disease/appendicitis))
- new /obj/item/weapon/reagent_containers/food/snacks/appendix/inflamed(get_turf(M))
- M:appendix_op_stage = 5.0
- return
- new /obj/item/weapon/reagent_containers/food/snacks/appendix(get_turf(M))
- M:appendix_op_stage = 5.0
- return
-
- if (user.zone_sel.selecting == "eyes")
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- if(istype(M, /mob/living/carbon/alien))//Aliens don't have eyes./N
- user << "\red You cannot locate any eyes on this creature!"
- return
-
- switch(M.eye_op_stage)
- if(2.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is having his eyes mended by [user].", 1)
- M << "\red [user] begins to mend your eyes with [src]!"
- user << "\red You mend [M]'s eyes with [src]!"
- else
- user.visible_message( \
- "\red [user] begins to have his eyes mended.", \
- "\red You begin to mend your eyes with [src]!" \
- )
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- M.updatehealth()
- else
- M.take_organ_damage(15)
- M:eye_op_stage = 3.0
-
- else if(user.zone_sel.selecting == "chest")
- if(M:alien_op_stage == 2.0 || M:alien_op_stage == 3.0)
- var/mob/living/carbon/human/H = M
- if(!istype(H))
- return ..()
-
- if(H.wear_suit || H.w_uniform)
- user << "\red You're going to need to remove that suit/jumpsuit first."
- return
-
- user.visible_message("\red [user] begins to dig around in [M]'s chest.", "\red You begin to dig around in [M]'s chest.")
-
- spawn(20 + (M:alien_op_stage == 3 ? 0 : rand(0,50)))
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("chest")
- if(affecting.take_damage(30))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(30)
-
- var/obj/item/alien_embryo/A = locate() in M.contents
- if(A)
- var/dat = "\blue You found an unknown alien organism in [M]'s chest!"
- if(A.stage < 4)
- dat += " It's small and weak, barely the size of a foetus."
- if(A.stage > 3)
- dat += " It's grown quite large, and writhes slightly as you look at it."
- if(prob(10))
- A.AttemptGrow()
- user << dat
- M:alien_op_stage = 3.0
- else
- user << "\blue You find nothing of interest."
-
- else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
- return ..()
-
- return
-*/
-
-/*
- * Cautery
- */
-/obj/item/weapon/cautery
- name = "cautery"
- desc = "This stops bleeding."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "cautery"
- m_amt = 5000
- g_amt = 2500
- flags = FPRINT | TABLEPASS | CONDUCT
- w_class = 1.0
- origin_tech = "materials=1;biotech=1"
- attack_verb = list("burnt")
-
-/*
-/obj/item/weapon/cautery/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M))
- return
-
- if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
- return ..()
-
- if(user.zone_sel.selecting == "groin")
- if(istype(M, /mob/living/carbon/human))
- switch(M:appendix_op_stage)
- if(5.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [user] is beginning to cauterize the incision in [M]'s abdomen with [src].", 1)
- M << "\red [user] begins to cauterize the incision in your abdomen with [src]!"
- user << "\red You cauterize the incision in [M]'s abdomen with [src]!"
- M:appendix_op_stage = 6.0
- for(var/datum/disease/appendicitis in M.viruses)
- appendicitis.cure()
- return
-
- if (user.zone_sel.selecting == "eyes")
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- if(istype(M, /mob/living/carbon/alien))//Aliens don't have eyes./N
- user << "\red You cannot locate any eyes on this creature!"
- return
-
- switch(M.eye_op_stage)
- if(3.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is having his eyes cauterized by [user].", 1)
- M << "\red [user] begins to cauterize your eyes!"
- user << "\red You cauterize [M]'s eyes with [src]!"
- else
- user.visible_message( \
- "\red [user] begins to have his eyes cauterized.", \
- "\red You begin to cauterize your eyes!" \
- )
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- M.updatehealth()
- else
- M.take_organ_damage(15)
- M.sdisabilities &= ~BLIND
- M.eye_stat = 0
- M:eye_op_stage = 0.0
-
- else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
- return ..()
-
- return
-*/
-
-/*
- * Surgical Drill
- */
-/obj/item/weapon/surgicaldrill
- name = "surgical drill"
- desc = "You can drill using this item. You dig?"
- icon = 'icons/obj/surgery.dmi'
- icon_state = "drill"
- hitsound = 'sound/weapons/circsawhit.ogg'
- m_amt = 15000
- g_amt = 10000
- flags = FPRINT | TABLEPASS | CONDUCT
- force = 15.0
- w_class = 1.0
- origin_tech = "materials=1;biotech=1"
- attack_verb = list("drilled")
-
- suicide_act(mob/user)
- viewers(user) << pick("/red [user] is pressing the [src.name] to \his temple and activating it! It looks like \he's trying to commit suicide.", \
- "/red [user] is pressing [src.name] to \his chest and activating it! It looks like \he's trying to commit suicide.")
- return (BRUTELOSS)
-
-/*
- * Scalpel
- */
-/obj/item/weapon/scalpel
- name = "scalpel"
- desc = "Cut, cut, and once more cut."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "scalpel"
- flags = FPRINT | TABLEPASS | CONDUCT
- force = 10.0
- w_class = 1.0
- throwforce = 5.0
- throw_speed = 3
- throw_range = 5
- m_amt = 10000
- g_amt = 5000
- origin_tech = "materials=1;biotech=1"
- attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
-
- suicide_act(mob/user)
- viewers(user) << pick("\red [user] is slitting \his wrists with the [src.name]! It looks like \he's trying to commit suicide.", \
- "\red [user] is slitting \his throat with the [src.name]! It looks like \he's trying to commit suicide.", \
- "\red [user] is slitting \his stomach open with the [src.name]! It looks like \he's trying to commit seppuku.")
- return (BRUTELOSS)
-
-/*
-/obj/item/weapon/scalpel/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M))
- return ..()
-
- //if(M.mutations & HUSK) return ..()
-
- if((CLUMSY in user.mutations) && prob(50))
- M = user
- return eyestab(M,user)
-
- if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
- return ..()
-
- src.add_fingerprint(user)
-
- if(user.zone_sel.selecting == "groin")
- if(istype(M, /mob/living/carbon/human))
- switch(M:appendix_op_stage)
- if(0.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is beginning to have his abdomen cut open with [src] by [user].", 1)
- M << "\red [user] begins to cut open your abdomen with [src]!"
- user << "\red You cut [M]'s abdomen open with [src]!"
- M:appendix_op_stage = 1.0
- if(3.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is beginning to have his appendix seperated with [src] by [user].", 1)
- M << "\red [user] begins to seperate your appendix with [src]!"
- user << "\red You seperate [M]'s appendix with [src]!"
- M:appendix_op_stage = 4.0
- return
-
- if(user.zone_sel.selecting == "head" || istype(M, /mob/living/carbon/slime))
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- switch(M:brain_op_stage)
- if(0.0)
- if(istype(M, /mob/living/carbon/slime))
- if(M.stat == 2)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M.name] is beginning to have its flesh cut open with [src] by [user].", 1)
- M << "\red [user] begins to cut open your flesh with [src]!"
- user << "\red You cut [M]'s flesh open with [src]!"
- M:brain_op_stage = 1.0
-
- return
-
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is beginning to have his head cut open with [src] by [user].", 1)
- M << "\red [user] begins to cut open your head with [src]!"
- user << "\red You cut [M]'s head open with [src]!"
- else
- user.visible_message( \
- "\red [user] begins to cut open his skull with [src]!", \
- "\red You begin to cut open your head with [src]!" \
- )
-
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(15)
-
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- affecting.take_damage(7)
- else
- M.take_organ_damage(7)
-
- M.updatehealth()
- M:brain_op_stage = 1.0
-
- if(1)
- if(istype(M, /mob/living/carbon/slime))
- if(M.stat == 2)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M.name] is having its silky innards cut apart with [src] by [user].", 1)
- M << "\red [user] begins to cut apart your innards with [src]!"
- user << "\red You cut [M]'s silky innards apart with [src]!"
- M:brain_op_stage = 2.0
- return
- if(2.0)
- if(istype(M, /mob/living/carbon/slime))
- if(M.stat == 2)
- var/mob/living/carbon/slime/slime = M
- if(slime.cores > 0)
- if(istype(M, /mob/living/carbon/slime))
- user << "\red You attempt to remove [M]'s core, but [src] is ineffective!"
- return
-
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is having his connections to the brain delicately severed with [src] by [user].", 1)
- M << "\red [user] begins to cut open your head with [src]!"
- user << "\red You cut [M]'s head open with [src]!"
- else
- user.visible_message( \
- "\red [user] begin to delicately remove the connections to his brain with [src]!", \
- "\red You begin to cut open your head with [src]!" \
- )
- if(M == user && prob(25))
- user << "\red You nick an artery!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(75))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(75)
-
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- affecting.take_damage(7)
- else
- M.take_organ_damage(7)
-
- M.updatehealth()
- M:brain_op_stage = 3.0
- else
- ..()
- return
-
- else if(user.zone_sel.selecting == "eyes")
- user << "\blue So far so good."
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- if(istype(M, /mob/living/carbon/alien) || istype(M, /mob/living/carbon/slime))//Aliens don't have eyes./N
- user << "\red You cannot locate any eyes on this creature!"
- return
-
- switch(M:eye_op_stage)
- if(0.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is beginning to have his eyes incised with [src] by [user].", 1)
- M << "\red [user] begins to cut open your eyes with [src]!"
- user << "\red You make an incision around [M]'s eyes with [src]!"
- else
- user.visible_message( \
- "\red [user] begins to cut around his eyes with [src]!", \
- "\red You begin to cut open your eyes with [src]!" \
- )
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(15)
-
- user << "\blue So far so good before."
- M.updatehealth()
- M:eye_op_stage = 1.0
- user << "\blue So far so good after."
-
- else if(user.zone_sel.selecting == "chest")
- switch(M:alien_op_stage)
- if(0.0)
- var/mob/living/carbon/human/H = M
- if(!istype(H))
- return ..()
-
- if(H.wear_suit || H.w_uniform)
- user << "\red You're going to need to remove that suit/jumpsuit first."
- return
-
- user.visible_message("\red [user] begins to slice open [M]'s chest.", "\red You begin to slice open [M]'s chest.")
-
- spawn(rand(20,50))
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("chest")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(15)
-
- M:alien_op_stage = 1.0
- user << "\blue So far so good."
-
- else
- return ..()
-/* wat
- else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
- return ..()*/
- return
-*/
-
-/*
- * Circular Saw
- */
-/obj/item/weapon/circular_saw
- name = "circular saw"
- desc = "For heavy duty cutting."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "saw3"
- hitsound = 'sound/weapons/circsawhit.ogg'
- flags = FPRINT | TABLEPASS | CONDUCT
- force = 15.0
- w_class = 1.0
- throwforce = 9.0
- throw_speed = 3
- throw_range = 5
- m_amt = 20000
- g_amt = 10000
- origin_tech = "materials=1;biotech=1"
- attack_verb = list("attacked", "slashed", "sawed", "cut")
-
-/*
-/obj/item/weapon/circular_saw/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M))
- return ..()
-
- if((CLUMSY in user.mutations) && prob(50))
- M = user
- return eyestab(M,user)
-
- if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
- return ..()
-
- src.add_fingerprint(user)
-
- if(user.zone_sel.selecting == "head" || istype(M, /mob/living/carbon/slime))
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- switch(M:brain_op_stage)
- if(1.0)
- if(istype(M, /mob/living/carbon/slime))
- return
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] has his skull sawed open with [src] by [user].", 1)
- M << "\red [user] begins to saw open your head with [src]!"
- user << "\red You saw [M]'s head open with [src]!"
- else
- user.visible_message( \
- "\red [user] saws open his skull with [src]!", \
- "\red You begin to saw open your head with [src]!" \
- )
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(40))
- M:UpdateDamageIcon()
- M.updatehealth()
- else
- M.take_organ_damage(40)
-
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- affecting.take_damage(7)
- else
- M.take_organ_damage(7)
-
- M.updatehealth()
- M:brain_op_stage = 2.0
-
- if(2.0)
- if(istype(M, /mob/living/carbon/slime))
- if(M.stat == 2)
- var/mob/living/carbon/slime/slime = M
- if(slime.cores > 0)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M.name] is having one of its cores sawed out with [src] by [user].", 1)
-
- slime.cores--
- M << "\red [user] begins to remove one of your cores with [src]! ([slime.cores] cores remaining)"
- user << "\red You cut one of [M]'s cores out with [src]! ([slime.cores] cores remaining)"
-
- new slime.coretype(M.loc)
-
- if(slime.cores <= 0)
- M.icon_state = "[slime.colour] baby slime dead-nocore"
-
- return
-
- if(3.0)
- /*if(M.mind && M.mind.changeling)
- user << "\red The neural tissue regrows before your eyes as you cut it."
- return*/
-
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] has his spine's connection to the brain severed with [src] by [user].", 1)
- M << "\red [user] severs your brain's connection to the spine with [src]!"
- user << "\red You sever [M]'s brain's connection to the spine with [src]!"
- else
- user.visible_message( \
- "\red [user] severs his brain's connection to the spine with [src]!", \
- "\red You sever your brain's connection to the spine with [src]!" \
- )
-
- user.attack_log += "\[[time_stamp()]\] Debrained [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
- M.attack_log += "\[[time_stamp()]\] Debrained by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
-
- log_attack("[user.name] ([user.ckey]) debrained [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])")
-
-
- var/obj/item/brain/B = new(M.loc)
- B.transfer_identity(M)
-
- M:brain_op_stage = 4.0
- M.death()//You want them to die after the brain was transferred, so not to trigger client death() twice.
-
- else
- ..()
- return
-
- else if(user.zone_sel.selecting == "chest")
- switch(M:alien_op_stage)
- if(1.0)
- var/mob/living/carbon/human/H = M
- if(!istype(H))
- return ..()
-
- if(H.wear_suit || H.w_uniform)
- user << "\red You're going to need to remove that suit/jumpsuit first."
- return
-
- user.visible_message("\red [user] begins to slice through the bone of [M]'s chest.", "\red You begin to slice through the bone of [M]'s chest.")
-
- spawn(20 + rand(0,50))
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("chest")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(15)
-
- M:alien_op_stage = 2.0
- user << "\blue So far so good."
-
- else
- return ..()
-/*
- else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
- return ..()
-*/
- return
-*/
-
-//misc, formerly from code/defines/weapons.dm
-/obj/item/weapon/bonegel
- name = "bone gel"
- icon = 'surgery.dmi'
- icon_state = "bone-gel"
- force = 0
- throwforce = 1.0
-
-/obj/item/weapon/FixOVein
- name = "FixOVein"
- icon = 'surgery.dmi'
- icon_state = "fixovein"
- force = 0
- throwforce = 1.0
- origin_tech = "materials=1;biotech=3"
- var/usage_amount = 10
-
-/obj/item/weapon/bonesetter
- name = "bone setter"
- icon = 'surgery.dmi'
- icon_state = "bone setter"
- force = 8.0
- throwforce = 9.0
- throw_speed = 3
- throw_range = 5
- attack_verb = list("attacked", "hit", "bludgeoned")
+/* Surgery Tools
+ * Contains:
+ * Retractor
+ * Hemostat
+ * Cautery
+ * Surgical Drill
+ * Scalpel
+ * Circular Saw
+ */
+
+/*
+ * Retractor
+ */
+/obj/item/weapon/retractor
+ name = "retractor"
+ desc = "Retracts stuff."
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "retractor"
+ m_amt = 10000
+ g_amt = 5000
+ flags = FPRINT | TABLEPASS | CONDUCT
+ w_class = 1.0
+ origin_tech = "materials=1;biotech=1"
+
+/*HAHA, SUCK IT, 2000 LINES OF SPAGHETTI CODE!
+
+NOW YOUR JOB IOS DONE BY ONLY 500 LINES OF SPAGHETTI CODE!
+
+LOOK FOR SURGERY.DM*/
+
+/*
+/obj/item/weapon/retractor/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ if(!istype(M))
+ return
+
+ var/mob/living/carbon/human/H = M
+ if(istype(H) && ( \
+ (H.head && H.head.flags & HEADCOVERSEYES) || \
+ (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
+ (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ var/mob/living/carbon/monkey/Mo = M
+ if(istype(Mo) && ( \
+ (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ if(istype(M, /mob/living/carbon/alien) || istype(M, /mob/living/carbon/slime))//Aliens don't have eyes./N
+ user << "\red You cannot locate any eyes on this creature!"
+ return
+
+ switch(M.eye_op_stage)
+ if(1.0)
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M] is having his eyes retracted by [user].", 1)
+ M << "\red [user] begins to seperate your eyes with [src]!"
+ user << "\red You seperate [M]'s eyes with [src]!"
+ else
+ user.visible_message( \
+ "\red [user] begins to have his eyes retracted.", \
+ "\red You begin to pry open your eyes with [src]!" \
+ )
+ if(M == user && prob(25))
+ user << "\red You mess up!"
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("head")
+ if(affecting.take_damage(15))
+ M:UpdateDamageIcon()
+ M.updatehealth()
+ else
+ M.take_organ_damage(15)
+
+ M:eye_op_stage = 2.0
+
+ else if(user.zone_sel.selecting == "chest")
+ switch(M:alien_op_stage)
+ if(3.0)
+ var/mob/living/carbon/human/H = M
+ if(!istype(H))
+ return ..()
+
+ if(H.wear_suit || H.w_uniform)
+ user << "\red You're going to need to remove that suit/jumpsuit first."
+ return
+
+ var/obj/item/alien_embryo/A = locate() in M.contents
+ if(!A)
+ return ..()
+ user.visible_message("\red [user] begins to pull something out of [M]'s chest.", "\red You begin to pull the alien organism out of [M]'s chest.")
+
+ spawn(20 + rand(0,50))
+ if(!A || A.loc != M)
+ return
+
+ if(M == user && prob(25))
+ user << "\red You mess up!"
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("chest")
+ if(affecting.take_damage(30))
+ M:UpdateDamageIcon()
+ else
+ M.take_organ_damage(30)
+
+ if(A.stage > 3)
+ var/chance = 15 + max(0, A.stage - 3) * 10
+ if(prob(chance))
+ A.AttemptGrow(0)
+ M:alien_op_stage = 4.0
+
+ if(M)
+ user.visible_message("\red [user] pulls an alien organism out of [M]'s chest.", "\red You pull the alien organism out of [M]'s chest.")
+ A.loc = M.loc //alien embryo handles cleanup
+
+ else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
+ return ..()
+
+ return
+*/
+
+/*
+ * Hemostat
+ */
+/obj/item/weapon/hemostat
+ name = "hemostat"
+ desc = "You think you have seen this before."
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "hemostat"
+ m_amt = 5000
+ g_amt = 2500
+ flags = FPRINT | TABLEPASS | CONDUCT
+ w_class = 1.0
+ origin_tech = "materials=1;biotech=1"
+ attack_verb = list("attacked", "pinched")
+
+/*
+/obj/item/weapon/hemostat/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ if(!istype(M))
+ return
+
+ if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
+ return ..()
+
+ if(user.zone_sel.selecting == "groin")
+ if(istype(M, /mob/living/carbon/human))
+ switch(M:appendix_op_stage)
+ if(1.0)
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [user] is beginning to clamp bleeders in [M]'s abdomen cut open with [src].", 1)
+ M << "\red [user] begins to clamp bleeders in your abdomen with [src]!"
+ user << "\red You clamp bleeders in [M]'s abdomen with [src]!"
+ M:appendix_op_stage = 2.0
+ if(4.0)
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [user] is removing [M]'s appendix with [src].", 1)
+ M << "\red [user] begins to remove your appendix with [src]!"
+ user << "\red You remove [M]'s appendix with [src]!"
+ for(var/datum/disease/D in M.viruses)
+ if(istype(D, /datum/disease/appendicitis))
+ new /obj/item/weapon/reagent_containers/food/snacks/appendix/inflamed(get_turf(M))
+ M:appendix_op_stage = 5.0
+ return
+ new /obj/item/weapon/reagent_containers/food/snacks/appendix(get_turf(M))
+ M:appendix_op_stage = 5.0
+ return
+
+ if (user.zone_sel.selecting == "eyes")
+
+ var/mob/living/carbon/human/H = M
+ if(istype(H) && ( \
+ (H.head && H.head.flags & HEADCOVERSEYES) || \
+ (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
+ (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ var/mob/living/carbon/monkey/Mo = M
+ if(istype(Mo) && ( \
+ (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ if(istype(M, /mob/living/carbon/alien))//Aliens don't have eyes./N
+ user << "\red You cannot locate any eyes on this creature!"
+ return
+
+ switch(M.eye_op_stage)
+ if(2.0)
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M] is having his eyes mended by [user].", 1)
+ M << "\red [user] begins to mend your eyes with [src]!"
+ user << "\red You mend [M]'s eyes with [src]!"
+ else
+ user.visible_message( \
+ "\red [user] begins to have his eyes mended.", \
+ "\red You begin to mend your eyes with [src]!" \
+ )
+ if(M == user && prob(25))
+ user << "\red You mess up!"
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("head")
+ if(affecting.take_damage(15))
+ M:UpdateDamageIcon()
+ M.updatehealth()
+ else
+ M.take_organ_damage(15)
+ M:eye_op_stage = 3.0
+
+ else if(user.zone_sel.selecting == "chest")
+ if(M:alien_op_stage == 2.0 || M:alien_op_stage == 3.0)
+ var/mob/living/carbon/human/H = M
+ if(!istype(H))
+ return ..()
+
+ if(H.wear_suit || H.w_uniform)
+ user << "\red You're going to need to remove that suit/jumpsuit first."
+ return
+
+ user.visible_message("\red [user] begins to dig around in [M]'s chest.", "\red You begin to dig around in [M]'s chest.")
+
+ spawn(20 + (M:alien_op_stage == 3 ? 0 : rand(0,50)))
+ if(M == user && prob(25))
+ user << "\red You mess up!"
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("chest")
+ if(affecting.take_damage(30))
+ M:UpdateDamageIcon()
+ else
+ M.take_organ_damage(30)
+
+ var/obj/item/alien_embryo/A = locate() in M.contents
+ if(A)
+ var/dat = "\blue You found an unknown alien organism in [M]'s chest!"
+ if(A.stage < 4)
+ dat += " It's small and weak, barely the size of a foetus."
+ if(A.stage > 3)
+ dat += " It's grown quite large, and writhes slightly as you look at it."
+ if(prob(10))
+ A.AttemptGrow()
+ user << dat
+ M:alien_op_stage = 3.0
+ else
+ user << "\blue You find nothing of interest."
+
+ else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
+ return ..()
+
+ return
+*/
+
+/*
+ * Cautery
+ */
+/obj/item/weapon/cautery
+ name = "cautery"
+ desc = "This stops bleeding."
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "cautery"
+ m_amt = 5000
+ g_amt = 2500
+ flags = FPRINT | TABLEPASS | CONDUCT
+ w_class = 1.0
+ origin_tech = "materials=1;biotech=1"
+ attack_verb = list("burnt")
+
+/*
+/obj/item/weapon/cautery/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ if(!istype(M))
+ return
+
+ if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
+ return ..()
+
+ if(user.zone_sel.selecting == "groin")
+ if(istype(M, /mob/living/carbon/human))
+ switch(M:appendix_op_stage)
+ if(5.0)
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [user] is beginning to cauterize the incision in [M]'s abdomen with [src].", 1)
+ M << "\red [user] begins to cauterize the incision in your abdomen with [src]!"
+ user << "\red You cauterize the incision in [M]'s abdomen with [src]!"
+ M:appendix_op_stage = 6.0
+ for(var/datum/disease/appendicitis in M.viruses)
+ appendicitis.cure()
+ return
+
+ if (user.zone_sel.selecting == "eyes")
+
+ var/mob/living/carbon/human/H = M
+ if(istype(H) && ( \
+ (H.head && H.head.flags & HEADCOVERSEYES) || \
+ (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
+ (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ var/mob/living/carbon/monkey/Mo = M
+ if(istype(Mo) && ( \
+ (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ if(istype(M, /mob/living/carbon/alien))//Aliens don't have eyes./N
+ user << "\red You cannot locate any eyes on this creature!"
+ return
+
+ switch(M.eye_op_stage)
+ if(3.0)
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M] is having his eyes cauterized by [user].", 1)
+ M << "\red [user] begins to cauterize your eyes!"
+ user << "\red You cauterize [M]'s eyes with [src]!"
+ else
+ user.visible_message( \
+ "\red [user] begins to have his eyes cauterized.", \
+ "\red You begin to cauterize your eyes!" \
+ )
+ if(M == user && prob(25))
+ user << "\red You mess up!"
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("head")
+ if(affecting.take_damage(15))
+ M:UpdateDamageIcon()
+ M.updatehealth()
+ else
+ M.take_organ_damage(15)
+ M.sdisabilities &= ~BLIND
+ M.eye_stat = 0
+ M:eye_op_stage = 0.0
+
+ else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
+ return ..()
+
+ return
+*/
+
+/*
+ * Surgical Drill
+ */
+/obj/item/weapon/surgicaldrill
+ name = "surgical drill"
+ desc = "You can drill using this item. You dig?"
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "drill"
+ hitsound = 'sound/weapons/circsawhit.ogg'
+ m_amt = 15000
+ g_amt = 10000
+ flags = FPRINT | TABLEPASS | CONDUCT
+ force = 15.0
+ w_class = 1.0
+ origin_tech = "materials=1;biotech=1"
+ attack_verb = list("drilled")
+
+ suicide_act(mob/user)
+ viewers(user) << pick("/red [user] is pressing the [src.name] to \his temple and activating it! It looks like \he's trying to commit suicide.", \
+ "/red [user] is pressing [src.name] to \his chest and activating it! It looks like \he's trying to commit suicide.")
+ return (BRUTELOSS)
+
+/*
+ * Scalpel
+ */
+/obj/item/weapon/scalpel
+ name = "scalpel"
+ desc = "Cut, cut, and once more cut."
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "scalpel"
+ flags = FPRINT | TABLEPASS | CONDUCT
+ force = 10.0
+ w_class = 1.0
+ throwforce = 5.0
+ throw_speed = 3
+ throw_range = 5
+ m_amt = 10000
+ g_amt = 5000
+ origin_tech = "materials=1;biotech=1"
+ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+
+ suicide_act(mob/user)
+ viewers(user) << pick("\red [user] is slitting \his wrists with the [src.name]! It looks like \he's trying to commit suicide.", \
+ "\red [user] is slitting \his throat with the [src.name]! It looks like \he's trying to commit suicide.", \
+ "\red [user] is slitting \his stomach open with the [src.name]! It looks like \he's trying to commit seppuku.")
+ return (BRUTELOSS)
+
+/*
+/obj/item/weapon/scalpel/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ if(!istype(M))
+ return ..()
+
+ //if(M.mutations & HUSK) return ..()
+
+ if((CLUMSY in user.mutations) && prob(50))
+ M = user
+ return eyestab(M,user)
+
+ if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
+ return ..()
+
+ src.add_fingerprint(user)
+
+ if(user.zone_sel.selecting == "groin")
+ if(istype(M, /mob/living/carbon/human))
+ switch(M:appendix_op_stage)
+ if(0.0)
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M] is beginning to have his abdomen cut open with [src] by [user].", 1)
+ M << "\red [user] begins to cut open your abdomen with [src]!"
+ user << "\red You cut [M]'s abdomen open with [src]!"
+ M:appendix_op_stage = 1.0
+ if(3.0)
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M] is beginning to have his appendix seperated with [src] by [user].", 1)
+ M << "\red [user] begins to seperate your appendix with [src]!"
+ user << "\red You seperate [M]'s appendix with [src]!"
+ M:appendix_op_stage = 4.0
+ return
+
+ if(user.zone_sel.selecting == "head" || istype(M, /mob/living/carbon/slime))
+
+ var/mob/living/carbon/human/H = M
+ if(istype(H) && ( \
+ (H.head && H.head.flags & HEADCOVERSEYES) || \
+ (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
+ (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ var/mob/living/carbon/monkey/Mo = M
+ if(istype(Mo) && ( \
+ (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ switch(M:brain_op_stage)
+ if(0.0)
+ if(istype(M, /mob/living/carbon/slime))
+ if(M.stat == 2)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M.name] is beginning to have its flesh cut open with [src] by [user].", 1)
+ M << "\red [user] begins to cut open your flesh with [src]!"
+ user << "\red You cut [M]'s flesh open with [src]!"
+ M:brain_op_stage = 1.0
+
+ return
+
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M] is beginning to have his head cut open with [src] by [user].", 1)
+ M << "\red [user] begins to cut open your head with [src]!"
+ user << "\red You cut [M]'s head open with [src]!"
+ else
+ user.visible_message( \
+ "\red [user] begins to cut open his skull with [src]!", \
+ "\red You begin to cut open your head with [src]!" \
+ )
+
+ if(M == user && prob(25))
+ user << "\red You mess up!"
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("head")
+ if(affecting.take_damage(15))
+ M:UpdateDamageIcon()
+ else
+ M.take_organ_damage(15)
+
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("head")
+ affecting.take_damage(7)
+ else
+ M.take_organ_damage(7)
+
+ M.updatehealth()
+ M:brain_op_stage = 1.0
+
+ if(1)
+ if(istype(M, /mob/living/carbon/slime))
+ if(M.stat == 2)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M.name] is having its silky innards cut apart with [src] by [user].", 1)
+ M << "\red [user] begins to cut apart your innards with [src]!"
+ user << "\red You cut [M]'s silky innards apart with [src]!"
+ M:brain_op_stage = 2.0
+ return
+ if(2.0)
+ if(istype(M, /mob/living/carbon/slime))
+ if(M.stat == 2)
+ var/mob/living/carbon/slime/slime = M
+ if(slime.cores > 0)
+ if(istype(M, /mob/living/carbon/slime))
+ user << "\red You attempt to remove [M]'s core, but [src] is ineffective!"
+ return
+
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M] is having his connections to the brain delicately severed with [src] by [user].", 1)
+ M << "\red [user] begins to cut open your head with [src]!"
+ user << "\red You cut [M]'s head open with [src]!"
+ else
+ user.visible_message( \
+ "\red [user] begin to delicately remove the connections to his brain with [src]!", \
+ "\red You begin to cut open your head with [src]!" \
+ )
+ if(M == user && prob(25))
+ user << "\red You nick an artery!"
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("head")
+ if(affecting.take_damage(75))
+ M:UpdateDamageIcon()
+ else
+ M.take_organ_damage(75)
+
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("head")
+ affecting.take_damage(7)
+ else
+ M.take_organ_damage(7)
+
+ M.updatehealth()
+ M:brain_op_stage = 3.0
+ else
+ ..()
+ return
+
+ else if(user.zone_sel.selecting == "eyes")
+ user << "\blue So far so good."
+
+ var/mob/living/carbon/human/H = M
+ if(istype(H) && ( \
+ (H.head && H.head.flags & HEADCOVERSEYES) || \
+ (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
+ (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ var/mob/living/carbon/monkey/Mo = M
+ if(istype(Mo) && ( \
+ (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ if(istype(M, /mob/living/carbon/alien) || istype(M, /mob/living/carbon/slime))//Aliens don't have eyes./N
+ user << "\red You cannot locate any eyes on this creature!"
+ return
+
+ switch(M:eye_op_stage)
+ if(0.0)
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M] is beginning to have his eyes incised with [src] by [user].", 1)
+ M << "\red [user] begins to cut open your eyes with [src]!"
+ user << "\red You make an incision around [M]'s eyes with [src]!"
+ else
+ user.visible_message( \
+ "\red [user] begins to cut around his eyes with [src]!", \
+ "\red You begin to cut open your eyes with [src]!" \
+ )
+ if(M == user && prob(25))
+ user << "\red You mess up!"
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("head")
+ if(affecting.take_damage(15))
+ M:UpdateDamageIcon()
+ else
+ M.take_organ_damage(15)
+
+ user << "\blue So far so good before."
+ M.updatehealth()
+ M:eye_op_stage = 1.0
+ user << "\blue So far so good after."
+
+ else if(user.zone_sel.selecting == "chest")
+ switch(M:alien_op_stage)
+ if(0.0)
+ var/mob/living/carbon/human/H = M
+ if(!istype(H))
+ return ..()
+
+ if(H.wear_suit || H.w_uniform)
+ user << "\red You're going to need to remove that suit/jumpsuit first."
+ return
+
+ user.visible_message("\red [user] begins to slice open [M]'s chest.", "\red You begin to slice open [M]'s chest.")
+
+ spawn(rand(20,50))
+ if(M == user && prob(25))
+ user << "\red You mess up!"
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("chest")
+ if(affecting.take_damage(15))
+ M:UpdateDamageIcon()
+ else
+ M.take_organ_damage(15)
+
+ M:alien_op_stage = 1.0
+ user << "\blue So far so good."
+
+ else
+ return ..()
+/* wat
+ else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
+ return ..()*/
+ return
+*/
+
+/*
+ * Circular Saw
+ */
+/obj/item/weapon/circular_saw
+ name = "circular saw"
+ desc = "For heavy duty cutting."
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "saw3"
+ hitsound = 'sound/weapons/circsawhit.ogg'
+ flags = FPRINT | TABLEPASS | CONDUCT
+ force = 15.0
+ w_class = 1.0
+ throwforce = 9.0
+ throw_speed = 3
+ throw_range = 5
+ m_amt = 20000
+ g_amt = 10000
+ origin_tech = "materials=1;biotech=1"
+ attack_verb = list("attacked", "slashed", "sawed", "cut")
+
+/*
+/obj/item/weapon/circular_saw/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ if(!istype(M))
+ return ..()
+
+ if((CLUMSY in user.mutations) && prob(50))
+ M = user
+ return eyestab(M,user)
+
+ if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
+ return ..()
+
+ src.add_fingerprint(user)
+
+ if(user.zone_sel.selecting == "head" || istype(M, /mob/living/carbon/slime))
+
+ var/mob/living/carbon/human/H = M
+ if(istype(H) && ( \
+ (H.head && H.head.flags & HEADCOVERSEYES) || \
+ (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
+ (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ var/mob/living/carbon/monkey/Mo = M
+ if(istype(Mo) && ( \
+ (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
+ ))
+ user << "\red You're going to need to remove that mask/helmet/glasses first."
+ return
+
+ switch(M:brain_op_stage)
+ if(1.0)
+ if(istype(M, /mob/living/carbon/slime))
+ return
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M] has his skull sawed open with [src] by [user].", 1)
+ M << "\red [user] begins to saw open your head with [src]!"
+ user << "\red You saw [M]'s head open with [src]!"
+ else
+ user.visible_message( \
+ "\red [user] saws open his skull with [src]!", \
+ "\red You begin to saw open your head with [src]!" \
+ )
+ if(M == user && prob(25))
+ user << "\red You mess up!"
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("head")
+ if(affecting.take_damage(40))
+ M:UpdateDamageIcon()
+ M.updatehealth()
+ else
+ M.take_organ_damage(40)
+
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("head")
+ affecting.take_damage(7)
+ else
+ M.take_organ_damage(7)
+
+ M.updatehealth()
+ M:brain_op_stage = 2.0
+
+ if(2.0)
+ if(istype(M, /mob/living/carbon/slime))
+ if(M.stat == 2)
+ var/mob/living/carbon/slime/slime = M
+ if(slime.cores > 0)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M.name] is having one of its cores sawed out with [src] by [user].", 1)
+
+ slime.cores--
+ M << "\red [user] begins to remove one of your cores with [src]! ([slime.cores] cores remaining)"
+ user << "\red You cut one of [M]'s cores out with [src]! ([slime.cores] cores remaining)"
+
+ new slime.coretype(M.loc)
+
+ if(slime.cores <= 0)
+ M.icon_state = "[slime.colour] baby slime dead-nocore"
+
+ return
+
+ if(3.0)
+ /*if(M.mind && M.mind.changeling)
+ user << "\red The neural tissue regrows before your eyes as you cut it."
+ return*/
+
+ if(M != user)
+ for(var/mob/O in (viewers(M) - user - M))
+ O.show_message("\red [M] has his spine's connection to the brain severed with [src] by [user].", 1)
+ M << "\red [user] severs your brain's connection to the spine with [src]!"
+ user << "\red You sever [M]'s brain's connection to the spine with [src]!"
+ else
+ user.visible_message( \
+ "\red [user] severs his brain's connection to the spine with [src]!", \
+ "\red You sever your brain's connection to the spine with [src]!" \
+ )
+
+ user.attack_log += "\[[time_stamp()]\] Debrained [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
+ M.attack_log += "\[[time_stamp()]\] Debrained by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
+
+ log_attack("[user.name] ([user.ckey]) debrained [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])")
+
+
+ var/obj/item/brain/B = new(M.loc)
+ B.transfer_identity(M)
+
+ M:brain_op_stage = 4.0
+ M.death()//You want them to die after the brain was transferred, so not to trigger client death() twice.
+
+ else
+ ..()
+ return
+
+ else if(user.zone_sel.selecting == "chest")
+ switch(M:alien_op_stage)
+ if(1.0)
+ var/mob/living/carbon/human/H = M
+ if(!istype(H))
+ return ..()
+
+ if(H.wear_suit || H.w_uniform)
+ user << "\red You're going to need to remove that suit/jumpsuit first."
+ return
+
+ user.visible_message("\red [user] begins to slice through the bone of [M]'s chest.", "\red You begin to slice through the bone of [M]'s chest.")
+
+ spawn(20 + rand(0,50))
+ if(M == user && prob(25))
+ user << "\red You mess up!"
+ if(istype(M, /mob/living/carbon/human))
+ var/datum/organ/external/affecting = M:get_organ("chest")
+ if(affecting.take_damage(15))
+ M:UpdateDamageIcon()
+ else
+ M.take_organ_damage(15)
+
+ M:alien_op_stage = 2.0
+ user << "\blue So far so good."
+
+ else
+ return ..()
+/*
+ else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
+ return ..()
+*/
+ return
+*/
+
+//misc, formerly from code/defines/weapons.dm
+/obj/item/weapon/bonegel
+ name = "bone gel"
+ icon = 'surgery.dmi'
+ icon_state = "bone-gel"
+ force = 0
+ throwforce = 1.0
+
+/obj/item/weapon/FixOVein
+ name = "FixOVein"
+ icon = 'surgery.dmi'
+ icon_state = "fixovein"
+ force = 0
+ throwforce = 1.0
+ origin_tech = "materials=1;biotech=3"
+ var/usage_amount = 10
+
+/obj/item/weapon/bonesetter
+ name = "bone setter"
+ icon = 'surgery.dmi'
+ icon_state = "bone setter"
+ force = 8.0
+ throwforce = 9.0
+ throw_speed = 3
+ throw_range = 5
+ attack_verb = list("attacked", "hit", "bludgeoned")
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm
index bc79c6634f2..24d622bff1a 100644
--- a/code/game/objects/items/weapons/swords_axes_etc.dm
+++ b/code/game/objects/items/weapons/swords_axes_etc.dm
@@ -75,13 +75,13 @@
else
user.take_organ_damage(2*force)
return
+/*this is already called in ..()
src.add_fingerprint(user)
-
M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])")
user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])")
log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])")
-
+*/
if (user.a_intent == "hurt")
if(!..()) return
playsound(src.loc, "swing_hit", 50, 1, -1)
@@ -90,13 +90,88 @@
M.Stun(8)
M.Weaken(8)
for(var/mob/O in viewers(M))
- if (O.client) O.show_message("\red [M] has been beaten with the police baton by [user]!", 1, "\red You hear someone fall", 2)
+ if (O.client) O.show_message("\red [M] has been beaten with \the [src] by [user]!", 1, "\red You hear someone fall", 2)
else
playsound(src.loc, 'sound/weapons/Genhit.ogg', 50, 1, -1)
M.Stun(5)
M.Weaken(5)
+ M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])")
+ user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])")
+ log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])")
+ src.add_fingerprint(user)
+
for(var/mob/O in viewers(M))
- if (O.client) O.show_message("\red [M] has been stunned with the police baton by [user]!", 1, "\red You hear someone fall", 2)
+ if (O.client) O.show_message("\red [M] has been stunned with \the [src] by [user]!", 1, "\red You hear someone fall", 2)
+
+//Telescopic baton
+/obj/item/weapon/melee/telebaton
+ name = "telescopic baton"
+ desc = "A compact yet robust personal defense weapon. Can be concealed when folded."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "telebaton_0"
+ item_state = "telebaton_0"
+ flags = FPRINT | TABLEPASS
+ slot_flags = SLOT_BELT
+ w_class = 2
+ force = 3
+ var/on = 0
+
+
+/obj/item/weapon/melee/telebaton/attack_self(mob/user as mob)
+ on = !on
+ if(on)
+ user.visible_message("\red With a flick of their wrist, [user] extends their telescopic baton.",\
+ "\red You extend the baton.",\
+ "You hear an ominous click.")
+ icon_state = "telebaton_1"
+ item_state = "telebaton_1"
+ w_class = 4
+ force = 15//quite robust
+ attack_verb = list("smacked", "struck", "slapped")
+ else
+ user.visible_message("\blue [user] collapses their telescopic baton.",\
+ "\blue You collapse the baton.",\
+ "You hear a click.")
+ icon_state = "telebaton_0"
+ item_state = "telebaton_0"
+ w_class = 2
+ force = 3//not so robust now
+ attack_verb = list("hit", "punched")
+ playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1)
+ add_fingerprint(user)
+
+ if(blood_overlay && (blood_DNA.len >= 1)) //updates blood overlay, if any
+ overlays.Cut()//this might delete other item overlays as well but eeeeeeeh
+
+ var/icon/I = new /icon(src.icon, src.icon_state)
+ I.Blend(new /icon('icons/effects/blood.dmi', rgb(255,255,255)),ICON_ADD)
+ I.Blend(new /icon('icons/effects/blood.dmi', "itemblood"),ICON_MULTIPLY)
+ blood_overlay = I
+
+ overlays += blood_overlay
+
+ return
+
+/obj/item/weapon/melee/telebaton/attack(mob/target as mob, mob/living/user as mob)
+ if(on)
+ if ((CLUMSY in user.mutations) && prob(50))
+ user << "\red You club yourself over the head."
+ user.Weaken(3 * force)
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ H.apply_damage(2*force, BRUTE, "head")
+ else
+ user.take_organ_damage(2*force)
+ return
+
+ if(!..()) return
+ playsound(src.loc, "swing_hit", 50, 1, -1)
+ //target.Stun(4) //naaah
+ target.Weaken(4)
+ return
+ else
+ return ..()
+
/*
*Energy Blade
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 8c6ee9461ef..e52cfa6f18e 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -17,7 +17,7 @@
/obj/item/weapon/nullrod
name = "null rod"
- desc = "A rod of pure obsidian, its very presence disrupts and dampens the powers of Nar-Sie's followers."
+ desc = "A rod of pure obsidian, its very presence disrupts and dampens the powers of paranormal phenomenae."
icon_state = "nullrod"
item_state = "nullrod"
flags = FPRINT | TABLEPASS
@@ -32,6 +32,46 @@
viewers(user) << "\red [user] is impaling \himself with the [src.name]! It looks like \he's trying to commit suicide."
return (BRUTELOSS|FIRELOSS)
+/obj/item/weapon/nullrod/attack(mob/M as mob, mob/living/user as mob) //Paste from old-code to decult with a null rod.
+
+ M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])")
+ user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])")
+
+ log_admin("ATTACK: [user] ([user.ckey]) attacked [M] ([M.ckey]) with [src].")
+ message_admins("ATTACK: [user] ([user.ckey]) attacked [M] ([M.ckey]) with [src].")
+ log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])")
+
+ if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
+ user << "\red You don't have the dexterity to do this!"
+ return
+
+ if ((CLUMSY in user.mutations) && prob(50))
+ user << "\red The rod slips out of your hand and hits your head."
+ user.take_organ_damage(10)
+ user.Paralyse(20)
+ return
+
+ if (M.stat !=2)
+ if((M.mind in ticker.mode.cult) && prob(33))
+ M << "\red The power of [src] clears your mind of the cult's influence!"
+ user << "\red You wave [src] over [M]'s head and see their eyes become clear, their mind returning to normal."
+ ticker.mode.remove_cultist(M.mind)
+ for(var/mob/O in viewers(M, null))
+ O.show_message(text("\red [] waves [] over []'s head.", user, src, M), 1)
+ else if(prob(10))
+ user << "\red The rod slips in your hand."
+ ..()
+ else
+ user << "\red The rod appears to do nothing."
+ for(var/mob/O in viewers(M, null))
+ O.show_message(text("\red [] waves [] over []'s head.", user, src, M), 1)
+ return
+
+/obj/item/weapon/nullrod/afterattack(atom/A, mob/user as mob)
+ if (istype(A, /turf/simulated/floor))
+ user << "\blue You hit the floor with the [src]."
+ call(/obj/effect/rune/proc/revealrunes)(src)
+
/obj/item/weapon/sord
name = "\improper SORD"
desc = "This thing is so unspeakably shitty you are having a hard time even holding it."
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 66cb1998d0a..d68a7b3c8d3 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -16,6 +16,8 @@
var/damtype = "brute"
var/force = 0
+/obj/item/proc/is_used_on(obj/O, mob/user)
+
/obj/proc/process()
processing_objects.Remove(src)
return 0
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 38662ddcf52..48c13eb8499 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -46,7 +46,7 @@
for(var/obj/effect/dummy/chameleon/AD in src)
AD.loc = src.loc
- for(var/obj/item/I in src)
+ for(var/obj/I in src)
I.loc = src.loc
for(var/mob/M in src)
diff --git a/code/game/objects/structures/crates_lockers/closets/fitness.dm b/code/game/objects/structures/crates_lockers/closets/fitness.dm
index 1aec0343fd7..182a9aa84c0 100644
--- a/code/game/objects/structures/crates_lockers/closets/fitness.dm
+++ b/code/game/objects/structures/crates_lockers/closets/fitness.dm
@@ -12,6 +12,11 @@
new /obj/item/clothing/under/shorts/red(src)
new /obj/item/clothing/under/shorts/blue(src)
new /obj/item/clothing/under/shorts/green(src)
+ new /obj/item/clothing/under/swimsuit/red(src)
+ new /obj/item/clothing/under/swimsuit/black(src)
+ new /obj/item/clothing/under/swimsuit/blue(src)
+ new /obj/item/clothing/under/swimsuit/green(src)
+ new /obj/item/clothing/under/swimsuit/purple(src)
/obj/structure/closet/boxinggloves
diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm
index 3c359125002..4342e231403 100644
--- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm
@@ -19,10 +19,12 @@
sleep(2)
new /obj/item/clothing/head/that(src)
new /obj/item/clothing/head/that(src)
+ new /obj/item/clothing/head/hairflower
new /obj/item/clothing/under/sl_suit(src)
new /obj/item/clothing/under/sl_suit(src)
new /obj/item/clothing/under/rank/bartender(src)
new /obj/item/clothing/under/rank/bartender(src)
+ new /obj/item/clothing/under/dress/dress_saloon
new /obj/item/clothing/suit/wcoat(src)
new /obj/item/clothing/suit/wcoat(src)
new /obj/item/clothing/shoes/black(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
index 7883038d5d8..3309b5b54d1 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
@@ -91,7 +91,10 @@
new /obj/item/clothing/under/rank/medical/purple(src)
new /obj/item/clothing/head/surgery/purple(src)
new /obj/item/clothing/under/rank/medical(src)
+ new /obj/item/clothing/under/rank/nurse(src)
+ new /obj/item/clothing/under/rank/orderly(src)
new /obj/item/clothing/suit/storage/labcoat(src)
+ new /obj/item/clothing/suit/storage/fr_jacket(src)
new /obj/item/clothing/shoes/white(src)
// new /obj/item/weapon/cartridge/medical(src)
new /obj/item/device/radio/headset/headset_med(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index 9da76e62c60..f6ad799900d 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -16,6 +16,7 @@
else
new /obj/item/weapon/storage/backpack/satchel_cap(src)
new /obj/item/clothing/suit/captunic(src)
+ new /obj/item/clothing/suit/captunic/capjacket(src)
new /obj/item/clothing/head/helmet/cap(src)
new /obj/item/clothing/under/rank/captain(src)
new /obj/item/clothing/suit/armor/vest(src)
@@ -26,6 +27,8 @@
new /obj/item/clothing/gloves/captain(src)
new /obj/item/weapon/gun/energy/gun(src)
new /obj/item/clothing/suit/armor/captain(src)
+ new /obj/item/weapon/melee/telebaton(src)
+ new /obj/item/clothing/under/dress/dress_cap(src)
return
@@ -43,17 +46,41 @@
New()
..()
sleep(2)
- new /obj/item/clothing/under/rank/head_of_personnel(src)
+ new /obj/item/clothing/glasses/sunglasses(src)
new /obj/item/clothing/suit/armor/vest(src)
new /obj/item/clothing/head/helmet(src)
new /obj/item/weapon/cartridge/hop(src)
new /obj/item/device/radio/headset/heads/hop(src)
- new /obj/item/clothing/shoes/brown(src)
new /obj/item/weapon/storage/box/ids(src)
new /obj/item/weapon/storage/box/ids( src )
new /obj/item/weapon/gun/energy/gun(src)
new /obj/item/device/flash(src)
- new /obj/item/clothing/glasses/sunglasses(src)
+ return
+
+/obj/structure/closet/secure_closet/hop2
+ name = "Head of Personnel's Attire"
+ req_access = list(access_hop)
+ icon_state = "hopsecure1"
+ icon_closed = "hopsecure"
+ icon_locked = "hopsecure1"
+ icon_opened = "hopsecureopen"
+ icon_broken = "hopsecurebroken"
+ icon_off = "hopsecureoff"
+
+ New()
+ ..()
+ sleep(2)
+ new /obj/item/clothing/under/rank/head_of_personnel(src)
+ new /obj/item/clothing/under/dress/dress_hop(src)
+ new /obj/item/clothing/under/dress/dress_hr(src)
+ new /obj/item/clothing/under/lawyer/female(src)
+ new /obj/item/clothing/under/lawyer/black(src)
+ new /obj/item/clothing/under/lawyer/red(src)
+ new /obj/item/clothing/under/lawyer/oldman(src)
+ new /obj/item/clothing/shoes/brown(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/shoes/leather(src)
+ new /obj/item/clothing/shoes/white(src)
return
@@ -75,6 +102,7 @@
new /obj/item/weapon/storage/backpack/security(src)
else
new /obj/item/weapon/storage/backpack/satchel_sec(src)
+ new /obj/item/clothing/head/helmet/HoS(src)
new /obj/item/clothing/suit/armor/vest(src)
new /obj/item/clothing/under/rank/head_of_security/jensen(src)
new /obj/item/clothing/suit/armor/hos/jensen(src)
@@ -90,6 +118,7 @@
new /obj/item/weapon/melee/baton(src)
new /obj/item/weapon/gun/energy/gun(src)
new /obj/item/clothing/tie/holster/waist(src)
+ new /obj/item/weapon/melee/telebaton(src)
return
diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
index 509a64662f1..5ee7383b654 100644
--- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm
+++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
@@ -22,6 +22,7 @@
new /obj/item/weapon/card/id/syndicate(src)
new /obj/item/device/multitool(src)
new /obj/item/weapon/shield/energy(src)
+ new /obj/item/clothing/shoes/magboots(src)
/obj/structure/closet/syndicate/nuclear
diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
index 71fc5324fde..dd3bb5a6b33 100644
--- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
+++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
@@ -26,6 +26,8 @@
new /obj/item/clothing/under/rank/security2(src)
new /obj/item/clothing/under/rank/security2(src)
new /obj/item/clothing/under/rank/security2(src)
+ new /obj/item/clothing/under/rank/dispatch(src)
+ new /obj/item/clothing/under/rank/dispatch(src)
new /obj/item/clothing/shoes/jackboots(src)
new /obj/item/clothing/shoes/jackboots(src)
new /obj/item/clothing/shoes/jackboots(src)
@@ -84,6 +86,7 @@
new /obj/item/clothing/suit/chaplain_hoodie(src)
new /obj/item/clothing/head/chaplain_hood(src)
new /obj/item/clothing/suit/holidaypriest(src)
+ new /obj/item/clothing/under/wedding/bride_white(src)
new /obj/item/weapon/storage/backpack/cultpack (src)
new /obj/item/weapon/storage/fancy/candle_box(src)
new /obj/item/weapon/storage/fancy/candle_box(src)
@@ -104,6 +107,19 @@
new /obj/item/clothing/shoes/black(src)
return
+/obj/structure/closet/wardrobe/xenos
+ name = "xenos wardrobe"
+ icon_state = "green"
+ icon_closed = "green"
+
+/obj/structure/closet/wardrobe/xenos/New()
+ new /obj/item/clothing/suit/unathi/mantle(src)
+ new /obj/item/clothing/suit/unathi/robe(src)
+ new /obj/item/clothing/shoes/sandal(src)
+ new /obj/item/clothing/shoes/sandal(src)
+ new /obj/item/clothing/shoes/sandal(src)
+ return
+
/obj/structure/closet/wardrobe/orange
name = "prison wardrobe"
@@ -328,13 +344,18 @@
icon_closed = "mixed"
/obj/structure/closet/wardrobe/mixed/New()
- new /obj/item/clothing/under/color/white(src)
new /obj/item/clothing/under/color/blue(src)
new /obj/item/clothing/under/color/yellow(src)
new /obj/item/clothing/under/color/green(src)
new /obj/item/clothing/under/color/orange(src)
new /obj/item/clothing/under/color/pink(src)
- new /obj/item/clothing/shoes/black(src)
- new /obj/item/clothing/shoes/brown(src)
- new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/under/dress/plaid_blue(src)
+ new /obj/item/clothing/under/dress/plaid_red(src)
+ new /obj/item/clothing/under/dress/plaid_purple(src)
+ new /obj/item/clothing/shoes/blue(src)
+ new /obj/item/clothing/shoes/yellow(src)
+ new /obj/item/clothing/shoes/green(src)
+ new /obj/item/clothing/shoes/orange(src)
+ new /obj/item/clothing/shoes/purple(src)
+ new /obj/item/clothing/shoes/leather(src)
return
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 05d8b4241b0..61b1750a82f 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -14,6 +14,20 @@
// mouse_drag_pointer = MOUSE_ACTIVE_POINTER //???
var/rigged = 0
+/obj/structure/closet/pcrate
+ name = "plastic crate"
+ desc = "A rectangular plastic crate."
+ icon = 'icons/obj/storage.dmi'
+ icon_state = "plasticcrate"
+ density = 1
+ icon_opened = "plasticcrateopen"
+ icon_closed = "plasticcrate"
+ req_access = null
+ opened = 0
+ flags = FPRINT
+// mouse_drag_pointer = MOUSE_ACTIVE_POINTER //???
+ var/rigged = 0
+
/obj/structure/closet/crate/internals
desc = "A internals crate."
name = "Internals crate"
@@ -175,15 +189,29 @@
redlight = "largemetalr"
greenlight = "largemetalg"
-/obj/structure/closet/crate/secure/large_reinforced
- name = "large crate"
+/obj/structure/closet/crate/secure/large/close()
+ //we can hold up to one large item
+ var/found = 0
+ for(var/obj/structure/S in src.loc)
+ if(S == src)
+ continue
+ if(!S.anchored)
+ found = 1
+ S.loc = src
+ break
+ if(!found)
+ for(var/obj/machinery/M in src.loc)
+ if(!M.anchored)
+ M.loc = src
+ break
+ ..()
+
+//fluff variant
+/obj/structure/closet/crate/secure/large/reinforced
desc = "A hefty, reinforced metal crate with an electronic locking system."
- icon = 'icons/obj/storage.dmi'
icon_state = "largermetal"
icon_opened = "largermetalopen"
icon_closed = "largermetal"
- redlight = "largemetalr"
- greenlight = "largemetalg"
/obj/structure/closet/crate/secure
desc = "A secure crate."
@@ -206,6 +234,23 @@
icon_opened = "largemetalopen"
icon_closed = "largemetal"
+/obj/structure/closet/crate/large/close()
+ //we can hold up to one large item
+ var/found = 0
+ for(var/obj/structure/S in src.loc)
+ if(S == src)
+ continue
+ if(!S.anchored)
+ found = 1
+ S.loc = src
+ break
+ if(!found)
+ for(var/obj/machinery/M in src.loc)
+ if(!M.anchored)
+ M.loc = src
+ break
+ ..()
+
/obj/structure/closet/crate/hydroponics
name = "Hydroponics crate"
desc = "All you need to destroy those pesky weeds and pests."
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index ea06d19ed60..7ece9970d55 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -349,7 +349,7 @@ obj/structure/door_assembly
src.state = 0
src.name = "Secured Airlock Assembly"
- else if(istype(W, /obj/item/weapon/airlock_electronics) && state == 1 )
+ else if(istype(W, /obj/item/weapon/airlock_electronics) && state == 1 && W:icon_state != "door_electronics_smoked")
playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
user.visible_message("[user] installs the electronics into the airlock assembly.", "You start to install electronics into the airlock assembly.")
user.drop_item()
diff --git a/code/game/objects/structures/lamarr_cage.dm b/code/game/objects/structures/lamarr_cage.dm
index eebe9fb343c..83df96a7280 100644
--- a/code/game/objects/structures/lamarr_cage.dm
+++ b/code/game/objects/structures/lamarr_cage.dm
@@ -89,9 +89,16 @@
/obj/structure/lamarr/proc/Break()
if(occupied)
- var/obj/item/clothing/mask/facehugger/A = new /obj/item/clothing/mask/facehugger( src.loc )
- A.sterile = 1
- A.name = "Lamarr"
+ new /obj/item/clothing/mask/facehugger/lamarr(src.loc)
occupied = 0
update_icon()
+ return
+
+/obj/item/clothing/mask/facehugger/lamarr
+ name = "Lamarr"
+ desc = "The worst she might do is attempt to... couple with your head."//hope we don't get sued over a harmless reference, rite?
+ sterile = 1
+ gender = FEMALE
+
+/obj/item/clothing/mask/facehugger/lamarr/New()//to prevent deleting it if aliums are disabled
return
\ No newline at end of file
diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm
new file mode 100644
index 00000000000..54630d3c4a3
--- /dev/null
+++ b/code/game/objects/structures/transit_tubes.dm
@@ -0,0 +1,632 @@
+
+// Basic transit tubes. Straight pieces, curved sections,
+// and basic splits/joins (no routing logic).
+// Mappers: you can use "Generate Instances from Icon-states"
+// to get the different pieces.
+/obj/structure/transit_tube
+ icon = 'icons/obj/pipes/transit_tube.dmi'
+ icon_state = "E-W"
+ density = 1
+ layer = 3.1
+ anchored = 1.0
+ var/list/tube_dirs = null
+ var/exit_delay = 2
+ var/enter_delay = 1
+
+ // alldirs in global.dm is the same list of directions, but since
+ // the specific order matters to get a usable icon_state, it is
+ // copied here so that, in the unlikely case that alldirs is changed,
+ // this continues to work.
+ var/global/list/tube_dir_list = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)
+
+
+// A place where tube pods stop, and people can get in or out.
+// Mappers: use "Generate Instances from Directions" for this
+// one.
+/obj/structure/transit_tube/station
+ icon = 'icons/obj/pipes/transit_tube_station.dmi'
+ icon_state = "closed"
+ exit_delay = 2
+ enter_delay = 3
+ var/pod_moving = 0
+ var/automatic_launch_time = 100
+
+ var/const/OPEN_DURATION = 6
+ var/const/CLOSE_DURATION = 6
+
+
+
+/obj/structure/transit_tube_pod
+ icon = 'icons/obj/pipes/transit_tube_pod.dmi'
+ icon_state = "pod"
+ animate_movement = FORWARD_STEPS
+ anchored = 1.0
+ density = 1
+ var/moving = 0
+ var/datum/gas_mixture/air_contents = new()
+
+
+
+/obj/structure/transit_tube_pod/Del()
+ for(var/atom/movable/AM in contents)
+ AM.loc = loc
+
+ ..()
+
+
+
+// When destroyed by explosions, properly handle contents.
+obj/structure/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ for(var/atom/movable/AM in contents)
+ AM.loc = loc
+ AM.ex_act(severity++)
+
+ del(src)
+ return
+ if(2.0)
+ if(prob(50))
+ for(var/atom/movable/AM in contents)
+ AM.loc = loc
+ AM.ex_act(severity++)
+
+ del(src)
+ return
+ if(3.0)
+ return
+
+
+
+/obj/structure/transit_tube_pod/New(loc)
+ ..(loc)
+
+ air_contents.oxygen = MOLES_O2STANDARD * 2
+ air_contents.nitrogen = MOLES_N2STANDARD
+ air_contents.temperature = T20C
+
+ // Give auto tubes time to align before trying to start moving
+ spawn(5)
+ follow_tube()
+
+
+
+/obj/structure/transit_tube/New(loc)
+ ..(loc)
+
+ if(tube_dirs == null)
+ init_dirs()
+
+
+
+/obj/structure/transit_tube/station/New(loc)
+ ..(loc)
+
+
+
+/obj/structure/transit_tube/station/Bumped(mob/AM as mob|obj)
+ if(!pod_moving && icon_state == "open" && istype(AM, /mob))
+ for(var/obj/structure/transit_tube_pod/pod in loc)
+ if(!pod.moving && pod.dir in directions())
+ AM.loc = pod
+ return
+
+
+
+/obj/structure/transit_tube/station/attack_hand(mob/user as mob)
+ if(!pod_moving)
+ for(var/obj/structure/transit_tube_pod/pod in loc)
+ if(!pod.moving && pod.dir in directions())
+ if(icon_state == "closed")
+ open_animation()
+
+ else if(icon_state == "open")
+ close_animation()
+
+
+
+/obj/structure/transit_tube/station/proc/open_animation()
+ if(icon_state == "closed")
+ icon_state = "opening"
+ spawn(OPEN_DURATION)
+ if(icon_state == "opening")
+ icon_state = "open"
+
+
+
+/obj/structure/transit_tube/station/proc/close_animation()
+ if(icon_state == "open")
+ icon_state = "closing"
+ spawn(CLOSE_DURATION)
+ if(icon_state == "closing")
+ icon_state = "closed"
+
+
+
+/obj/structure/transit_tube/station/proc/launch_pod()
+ for(var/obj/structure/transit_tube_pod/pod in loc)
+ if(!pod.moving && pod.dir in directions())
+ spawn(5)
+ pod_moving = 1
+ close_animation()
+ sleep(CLOSE_DURATION + 2)
+
+ //reverse directions for automated cycling
+ var/turf/next_loc = get_step(loc, pod.dir)
+ var/obj/structure/transit_tube/nexttube
+ for(var/obj/structure/transit_tube/tube in next_loc)
+ if(tube.has_entrance(pod.dir))
+ nexttube = tube
+ break
+ if(!nexttube)
+ pod.dir = turn(pod.dir, 180)
+
+ if(icon_state == "closed" && pod)
+ pod.follow_tube()
+
+ pod_moving = 0
+
+ return
+
+
+
+// Called to check if a pod should stop upon entering this tube.
+/obj/structure/transit_tube/proc/should_stop_pod(pod, from_dir)
+ return 0
+
+
+
+/obj/structure/transit_tube/station/should_stop_pod(pod, from_dir)
+ return 1
+
+
+
+// Called when a pod stops in this tube section.
+/obj/structure/transit_tube/proc/pod_stopped(pod, from_dir)
+ return
+
+
+
+/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir)
+ pod_moving = 1
+ spawn(5)
+ open_animation()
+ sleep(OPEN_DURATION + 2)
+ pod_moving = 0
+ pod.mix_air()
+
+ if(automatic_launch_time)
+ var/const/wait_step = 5
+ var/i = 0
+ while(i < automatic_launch_time)
+ sleep(wait_step)
+ i += wait_step
+
+ if(pod_moving || icon_state != "open")
+ return
+
+ launch_pod()
+
+
+
+// Returns a /list of directions this tube section can connect to.
+// Tubes that have some sort of logic or changing direction might
+// override it with additional logic.
+/obj/structure/transit_tube/proc/directions()
+ return tube_dirs
+
+
+
+/obj/structure/transit_tube/proc/has_entrance(from_dir)
+ from_dir = turn(from_dir, 180)
+
+ for(var/direction in directions())
+ if(direction == from_dir)
+ return 1
+
+ return 0
+
+
+
+/obj/structure/transit_tube/proc/has_exit(in_dir)
+ for(var/direction in directions())
+ if(direction == in_dir)
+ return 1
+
+ return 0
+
+
+
+// Searches for an exit direction within 45 degrees of the
+// specified dir. Returns that direction, or 0 if none match.
+/obj/structure/transit_tube/proc/get_exit(in_dir)
+ var/near_dir = 0
+ var/in_dir_cw = turn(in_dir, -45)
+ var/in_dir_ccw = turn(in_dir, 45)
+
+ for(var/direction in directions())
+ if(direction == in_dir)
+ return direction
+
+ else if(direction == in_dir_cw)
+ near_dir = direction
+
+ else if(direction == in_dir_ccw)
+ near_dir = direction
+
+ return near_dir
+
+
+
+// Return how many BYOND ticks to wait before entering/exiting
+// the tube section. Default action is to return the value of
+// a var, which wouldn't need a proc, but it makes it possible
+// for later tube types to interact in more interesting ways
+// such as being very fast in one direction, but slow in others
+/obj/structure/transit_tube/proc/exit_delay(pod, to_dir)
+ return exit_delay
+
+/obj/structure/transit_tube/proc/enter_delay(pod, to_dir)
+ return enter_delay
+
+
+
+/obj/structure/transit_tube_pod/proc/follow_tube()
+ if(moving)
+ return
+
+ moving = 1
+
+ spawn()
+ var/obj/structure/transit_tube/current_tube = null
+ var/next_dir
+ var/next_loc
+ var/last_delay = 0
+ var/exit_delay
+
+ for(var/obj/structure/transit_tube/tube in loc)
+ if(tube.has_exit(dir))
+ current_tube = tube
+ break
+
+ while(current_tube)
+ next_dir = current_tube.get_exit(dir)
+
+ if(!next_dir)
+ break
+
+ exit_delay = current_tube.exit_delay(src, dir)
+ last_delay += exit_delay
+
+ sleep(exit_delay)
+
+ next_loc = get_step(loc, next_dir)
+
+ current_tube = null
+ for(var/obj/structure/transit_tube/tube in next_loc)
+ if(tube.has_entrance(next_dir))
+ current_tube = tube
+ break
+
+ if(current_tube == null)
+ dir = next_dir
+ Move(get_step(loc, dir)) // Allow collisions when leaving the tubes.
+ break
+
+ last_delay = current_tube.enter_delay(src, next_dir)
+ sleep(last_delay)
+ dir = next_dir
+ loc = next_loc // When moving from one tube to another, skip collision and such.
+ density = current_tube.density
+
+ if(current_tube && current_tube.should_stop_pod(src, next_dir))
+ current_tube.pod_stopped(src, dir)
+ break
+
+ density = 1
+
+ // If the pod is no longer in a tube, move in a line until stopped or slowed to a halt.
+ // /turf/inertial_drift appears to only work on mobs, and re-implementing some of the
+ // logic allows a gradual slowdown and eventual stop when passing over non-space turfs.
+ if(!current_tube && last_delay <= 10)
+ do
+ sleep(last_delay)
+
+ if(!istype(loc, /turf/space))
+ last_delay++
+
+ if(last_delay > 10)
+ break
+
+ while(isturf(loc) && Move(get_step(loc, dir)))
+
+ moving = 0
+
+
+// Should I return a copy here? If the caller edits or del()s the returned
+// datum, there might be problems if I don't...
+/obj/structure/transit_tube_pod/return_air()
+ var/datum/gas_mixture/GM = new()
+ GM.oxygen = air_contents.oxygen
+ GM.carbon_dioxide = air_contents.carbon_dioxide
+ GM.nitrogen = air_contents.nitrogen
+ GM.toxins = air_contents.toxins
+ GM.temperature = air_contents.temperature
+ return GM
+
+// For now, copying what I found in an unused FEA file (and almost identical in a
+// used ZAS file). Means that assume_air and remove_air don't actually alter the
+// air contents.
+/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
+ return air_contents.merge(giver)
+
+/obj/structure/transit_tube_pod/remove_air(amount)
+ return air_contents.remove(amount)
+
+
+
+// Called when a pod arrives at, and before a pod departs from a station,
+// giving it a chance to mix its internal air supply with the turf it is
+// currently on.
+/obj/structure/transit_tube_pod/proc/mix_air()
+ var/datum/gas_mixture/environment = loc.return_air()
+ var/env_pressure = environment.return_pressure()
+ var/int_pressure = air_contents.return_pressure()
+ var/total_pressure = env_pressure + int_pressure
+
+ if(total_pressure == 0)
+ return
+
+ // Math here: Completely made up, not based on realistic equasions.
+ // Goal is to balance towards equal pressure, but ensure some gas
+ // transfer in both directions regardless.
+ // Feel free to rip this out and replace it with something better,
+ // I don't really know muhch about how gas transfer rates work in
+ // SS13.
+ var/transfer_in = max(0.1, 0.5 * (env_pressure - int_pressure) / total_pressure)
+ var/transfer_out = max(0.1, 0.3 * (int_pressure - env_pressure) / total_pressure)
+
+ var/datum/gas_mixture/from_env = loc.remove_air(environment.total_moles() * transfer_in)
+ var/datum/gas_mixture/from_int = air_contents.remove(air_contents.total_moles() * transfer_out)
+
+ loc.assume_air(from_int)
+ air_contents.merge(from_env)
+
+
+
+// When the player moves, check if the pos is currently stopped at a station.
+// if it is, check the direction. If the direction matches the direction of
+// the station, try to exit. If the direction matches one of the station's
+// tube directions, launch the pod in that direction.
+/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
+ if(istype(mob, /mob) && mob.client)
+ // If the pod is not in a tube at all, you can get out at any time.
+ if(!(locate(/obj/structure/transit_tube) in loc))
+ mob.loc = loc
+ mob.client.Move(get_step(loc, direction), direction)
+
+ //if(moving && istype(loc, /turf/space))
+ // Todo: If you get out of a moving pod in space, you should move as well.
+ // Same direction as pod? Direcion you moved? Halfway between?
+
+ if(!moving)
+ for(var/obj/structure/transit_tube/station/station in loc)
+ if(dir in station.directions())
+ if(!station.pod_moving)
+ if(direction == station.dir)
+ if(station.icon_state == "open")
+ mob.loc = loc
+ mob.client.Move(get_step(loc, direction), direction)
+
+ else
+ station.open_animation()
+
+ else if(direction in station.directions())
+ dir = direction
+ station.launch_pod()
+ return
+
+ for(var/obj/structure/transit_tube/tube in loc)
+ if(dir in tube.directions())
+ if(tube.has_exit(direction))
+ dir = direction
+ return
+
+
+
+// Parse the icon_state into a list of directions.
+// This means that mappers can use Dream Maker's built in
+// "Generate Instances from Icon-states" option to get all
+// variations. Additionally, as a separate proc, sub-types
+// can handle it more intelligently.
+/obj/structure/transit_tube/proc/init_dirs()
+ if(icon_state == "auto")
+ // Additional delay, for map loading.
+ spawn(1)
+ init_dirs_automatic()
+
+ else
+ tube_dirs = parse_dirs(icon_state)
+
+ if(copytext(icon_state, 1, 3) == "D-" || findtextEx(icon_state, "Pass"))
+ density = 0
+
+
+
+// Tube station directions are simply 90 to either side of
+// the exit.
+/obj/structure/transit_tube/station/init_dirs()
+ tube_dirs = list(turn(dir, 90), turn(dir, -90))
+
+
+
+// Initialize dirs by searching for tubes that do/might connect
+// on nearby turfs. Create corner pieces if nessecary.
+// Pick two directions, preferring tubes that already connect
+// to loc, or other auto tubes if there aren't enough connections.
+/obj/structure/transit_tube/proc/init_dirs_automatic()
+ var/list/connected = list()
+ var/list/connected_auto = list()
+
+ for(var/direction in tube_dir_list)
+ var/location = get_step(loc, direction)
+ for(var/obj/structure/transit_tube/tube in location)
+ if(tube.directions() == null && tube.icon_state == "auto")
+ connected_auto += direction
+ break
+
+ else if(turn(direction, 180) in tube.directions())
+ connected += direction
+ break
+
+ connected += connected_auto
+
+ tube_dirs = select_automatic_dirs(connected)
+
+ if(length(tube_dirs) == 2 && tube_dir_list.Find(tube_dirs[1]) > tube_dir_list.Find(tube_dirs[2]))
+ tube_dirs.Swap(1, 2)
+
+ generate_automatic_corners(tube_dirs)
+ select_automatic_icon_state(tube_dirs)
+
+
+
+// Given a list of directions, look a pair that forms a 180 or
+// 135 degree angle, and return a list containing the pair.
+// If none exist, return list(connected[1], turn(connected[1], 180)
+/obj/structure/transit_tube/proc/select_automatic_dirs(connected)
+ if(length(connected) < 1)
+ return list()
+
+ for(var/i = 1, i <= length(connected), i++)
+ for(var/j = i + 1, j <= length(connected), j++)
+ var/d1 = connected[i]
+ var/d2 = connected[j]
+
+ if(d1 == turn(d2, 135) || d1 == turn(d2, 180) || d1 == turn(d2, 225))
+ return list(d1, d2)
+
+ return list(connected[1], turn(connected[1], 180))
+
+
+
+/obj/structure/transit_tube/proc/select_automatic_icon_state(directions)
+ if(length(directions) == 2)
+ icon_state = "[dir2text_short(directions[1])]-[dir2text_short(directions[2])]"
+
+
+
+// Look for diagonal directions, generate the decorative corners in each.
+/obj/structure/transit_tube/proc/generate_automatic_corners(directions)
+ for(var/direction in directions)
+ if(direction == 5 || direction == 6 || direction == 9 || direction == 10)
+ if(direction & NORTH)
+ create_automatic_decorative_corner(get_step(loc, NORTH), direction ^ 3)
+
+ else
+ create_automatic_decorative_corner(get_step(loc, SOUTH), direction ^ 3)
+
+ if(direction & EAST)
+ create_automatic_decorative_corner(get_step(loc, EAST), direction ^ 12)
+
+ else
+ create_automatic_decorative_corner(get_step(loc, WEST), direction ^ 12)
+
+
+
+// Generate a corner, if one doesn't exist for the direction on the turf.
+/obj/structure/transit_tube/proc/create_automatic_decorative_corner(location, direction)
+ var/state = "D-[dir2text_short(direction)]"
+
+ for(var/obj/structure/transit_tube/tube in location)
+ if(tube.icon_state == state)
+ return
+
+ var/obj/structure/transit_tube/tube = new(location)
+ tube.icon_state = state
+ tube.init_dirs()
+
+
+
+// Uses a list() to cache return values. Since they should
+// never be edited directly, all tubes with a certain
+// icon_state can just reference the same list. In theory,
+// reduces memory usage, and improves CPU cache usage.
+// In reality, I don't know if that is quite how BYOND works,
+// but it is probably safer to assume the existence of, and
+// rely on, a sufficiently smart compiler/optimizer.
+/obj/structure/transit_tube/proc/parse_dirs(text)
+ var/global/list/direction_table = list()
+
+ if(text in direction_table)
+ return direction_table[text]
+
+ var/list/split_text = stringsplit(text, "-")
+
+ // If the first token is D, the icon_state represents
+ // a purely decorative tube, and doesn't actually
+ // connect to anything.
+ if(split_text[1] == "D")
+ direction_table[text] = list()
+ return null
+
+ var/list/directions = list()
+
+ for(var/text_part in split_text)
+ var/direction = text2dir_extended(text_part)
+
+ if(direction > 0)
+ directions += direction
+
+ direction_table[text] = directions
+ return directions
+
+
+
+// A copy of text2dir, extended to accept one and two letter
+// directions, and to clearly return 0 otherwise.
+/obj/structure/transit_tube/proc/text2dir_extended(direction)
+ switch(uppertext(direction))
+ if("NORTH", "N")
+ return 1
+ if("SOUTH", "S")
+ return 2
+ if("EAST", "E")
+ return 4
+ if("WEST", "W")
+ return 8
+ if("NORTHEAST", "NE")
+ return 5
+ if("NORTHWEST", "NW")
+ return 9
+ if("SOUTHEAST", "SE")
+ return 6
+ if("SOUTHWEST", "SW")
+ return 10
+ else
+ return 0
+
+
+
+// A copy of dir2text, which returns the short one or two letter
+// directions used in tube icon states.
+/obj/structure/transit_tube/proc/dir2text_short(direction)
+ switch(direction)
+ if(1)
+ return "N"
+ if(2)
+ return "S"
+ if(4)
+ return "E"
+ if(8)
+ return "W"
+ if(5)
+ return "NE"
+ if(6)
+ return "SE"
+ if(9)
+ return "NW"
+ if(10)
+ return "SW"
+ else
+ return
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 9064b51c930..28791229725 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -105,12 +105,12 @@
if(reinf) new /obj/item/stack/rods(loc)
del(src)
else if (usr.a_intent == "hurt")
- playsound(src.loc, 'Glassknock.ogg', 80, 1)
+ playsound(src.loc, 'glassknock.ogg', 80, 1)
usr.visible_message("\red [usr.name] bangs against the [src.name]!", \
"\red You bang against the [src.name]!", \
"You hear a banging sound.")
else
- playsound(src.loc, 'Glassknock.ogg', 80, 1)
+ playsound(src.loc, 'glassknock.ogg', 80, 1)
usr.visible_message("[usr.name] knocks on the [src.name].", \
"You knock on the [src.name].", \
"You hear a knocking sound.")
diff --git a/code/game/turfs/simulated/floor_types.dm b/code/game/turfs/simulated/floor_types.dm
index 93b25bd1c08..201fd974ade 100644
--- a/code/game/turfs/simulated/floor_types.dm
+++ b/code/game/turfs/simulated/floor_types.dm
@@ -160,6 +160,9 @@
name = "Water"
icon_state = "water"
+/turf/simulated/floor/beach/water/New()
+ ..()
+ overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1)
/turf/simulated/floor/grass
name = "Grass patch"
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 5d055f1a8cb..f06eb81ba32 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -3,6 +3,7 @@
desc = "A huge chunk of metal used to seperate rooms."
icon = 'icons/turf/walls.dmi'
var/mineral = "metal"
+ var/rotting = 0
opacity = 1
density = 1
blocks_air = 1
@@ -59,9 +60,11 @@
P.roll_and_drop(src)
else
O.loc = src
+
ChangeTurf(/turf/simulated/floor/plating)
/turf/simulated/wall/ex_act(severity)
+ if(rotting) severity = 1.0
switch(severity)
if(1.0)
//SN src = null
@@ -84,7 +87,7 @@
return
/turf/simulated/wall/blob_act()
- if(prob(50))
+ if(prob(50) || rotting)
dismantle_wall()
/turf/simulated/wall/attack_paw(mob/user as mob)
@@ -103,11 +106,11 @@
/turf/simulated/wall/attack_animal(mob/living/simple_animal/M as mob)
if(M.wall_smash)
- if (istype(src, /turf/simulated/wall/r_wall))
+ if (istype(src, /turf/simulated/wall/r_wall) && !rotting)
M << text("\blue This wall is far too strong for you to destroy.")
return
else
- if (prob(40))
+ if (prob(40) || rotting)
M << text("\blue You smash through the wall.")
dismantle_wall(1)
return
@@ -120,7 +123,7 @@
/turf/simulated/wall/attack_hand(mob/user as mob)
if (HULK in user.mutations)
- if (prob(40))
+ if (prob(40) || rotting)
usr << text("\blue You smash through the wall.")
usr.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
dismantle_wall(1)
@@ -129,6 +132,11 @@
usr << text("\blue You punch the wall.")
return
+ if(rotting)
+ user << "\blue The wall crumbles under your touch."
+ dismantle_wall()
+ return
+
user << "\blue You push the wall but nothing happens!"
playsound(src.loc, 'sound/weapons/Genhit.ogg', 25, 1)
src.add_fingerprint(user)
@@ -143,6 +151,21 @@
//get the user's location
if( !istype(user.loc, /turf) ) return //can't do this stuff whilst inside objects and such
+ if(rotting)
+ if(istype(W, /obj/item/weapon/weldingtool) )
+ var/obj/item/weapon/weldingtool/WT = W
+ if( WT.remove_fuel(0,user) )
+ user << "You burn away the fungi with \the [WT]."
+ playsound(src.loc, 'sound/items/Welder.ogg', 10, 1)
+ for(var/obj/effect/E in src) if(E.name == "Wallrot")
+ del E
+ rotting = 0
+ return
+ else if(!is_sharp(W) && W.force >= 10 || W.force >= 20)
+ user << "\The [src] crumbles away under the force of your [W.name]."
+ src.dismantle_wall(1)
+ return
+
//THERMITE related stuff. Calls src.thermitemelt() which handles melting simulated walls and the relevant effects
if( thermite )
if( istype(W, /obj/item/weapon/weldingtool) )
@@ -284,6 +307,24 @@
return attack_hand(user)
return
+// Wall-rot effect, a nasty fungus that destroys walls.
+/turf/simulated/wall/proc/rot()
+ if(!rotting)
+ rotting = 1
+
+ var/number_rots = rand(2,3)
+ for(var/i=0, iYou burn away the fungi with \the [WT].