diff --git a/README.txt b/README.txt index 7ac8f3f139..d7261e6cb0 100644 --- a/README.txt +++ b/README.txt @@ -6,5 +6,8 @@ Install Guide: http://baystation12.net/wiki/index.php/Install Code: https://github.com/Baystation12/Baystation12 IRC: irc://irc.sorcery.net/bs12 -Based on the code of tgstation13, itself based on the code of goonstation13. -tgstation13 - http://code.google.com/p/tgstation13 \ No newline at end of file +Based on the code of /tg/ station 13, itself based on the code of Goon Station 13. +/tg/ station 13: http://code.google.com/p/tgstation13 + +Code Licensed Under GPLv3: http://www.gnu.org/licenses/gpl.html +Content Licensed Under Creative Commons CC BY-SA 3.0: http://creativecommons.org/licenses/by-sa/3.0/ \ No newline at end of file diff --git a/baystation12.dme b/baystation12.dme index 2218c3fa7c..8eac216fe6 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -81,10 +81,14 @@ #define FILE_DIR "code/game/objects/storage" #define FILE_DIR "code/game/objects/tanks" #define FILE_DIR "code/game/player" +#define FILE_DIR "code/game/vehicles" +#define FILE_DIR "code/game/vehicles/airtight" #define FILE_DIR "code/game/verbs" #define FILE_DIR "code/js" #define FILE_DIR "code/modules" #define FILE_DIR "code/modules/admin" +#define FILE_DIR "code/modules/admin/new" +#define FILE_DIR "code/modules/admin/new/verbs" #define FILE_DIR "code/modules/admin/verbs" #define FILE_DIR "code/modules/assembly" #define FILE_DIR "code/modules/chemical" @@ -159,6 +163,7 @@ #define FILE_DIR "code/WorkInProgress/Apples" #define FILE_DIR "code/WorkInProgress/Cael_Aislinn" #define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Rust" +#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Supermatter" #define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Tajara" #define FILE_DIR "code/WorkInProgress/Chinsky" #define FILE_DIR "code/WorkInProgress/mapload" @@ -377,6 +382,7 @@ #include "code\game\sound.dm" #include "code\game\specops_shuttle.dm" #include "code\game\status.dm" +#include "code\game\step_triggers.dm" #include "code\game\supplyshuttle.dm" #include "code\game\syndicate_shuttle.dm" #include "code\game\syndicate_specops_shuttle.dm" @@ -386,6 +392,7 @@ #include "code\game\vote.dm" #include "code\game\area\ai_monitored.dm" #include "code\game\area\areas.dm" +#include "code\game\asteroid\artifacts.dm" #include "code\game\events\Event.dm" #include "code\game\events\EventsMain.dm" #include "code\game\events\EventProcs\black_hole.dm" @@ -479,6 +486,7 @@ #include "code\game\machinery\dispenser.dm" #include "code\game\machinery\door_control.dm" #include "code\game\machinery\flasher.dm" +#include "code\game\machinery\floodlight.dm" #include "code\game\machinery\Freezer.dm" #include "code\game\machinery\hologram.dm" #include "code\game\machinery\hydroponics.dm" @@ -527,17 +535,21 @@ #include "code\game\machinery\computer\aifixer.dm" #include "code\game\machinery\computer\arcade.dm" #include "code\game\machinery\computer\atmos.dm" +#include "code\game\machinery\computer\atmos_alert.dm" #include "code\game\machinery\computer\buildandrepair.dm" #include "code\game\machinery\computer\camera_monitor.dm" #include "code\game\machinery\computer\cloning.dm" #include "code\game\machinery\computer\communications.dm" #include "code\game\machinery\computer\computer.dm" #include "code\game\machinery\computer\crew.dm" +#include "code\game\machinery\computer\HolodeckControl.dm" #include "code\game\machinery\computer\hologram.dm" #include "code\game\machinery\computer\id.dm" +#include "code\game\machinery\computer\law.dm" #include "code\game\machinery\computer\lockdown.dm" #include "code\game\machinery\computer\medical.dm" #include "code\game\machinery\computer\Operating.dm" +#include "code\game\machinery\computer\pod.dm" #include "code\game\machinery\computer\power.dm" #include "code\game\machinery\computer\prisoner.dm" #include "code\game\machinery\computer\robot.dm" @@ -602,6 +614,7 @@ #include "code\game\objects\bombspawner.dm" #include "code\game\objects\cleaner.dm" #include "code\game\objects\closets.dm" +#include "code\game\objects\contraband.dm" #include "code\game\objects\displaycase.dm" #include "code\game\objects\door_assembly.dm" #include "code\game\objects\effect_system.dm" @@ -754,6 +767,10 @@ #include "code\game\objects\tanks\jetpack.dm" #include "code\game\objects\tanks\oxygen.dm" #include "code\game\player\news.dm" +#include "code\game\vehicles\vehicle.dm" +#include "code\game\vehicles\airtight\airtight.dm" +#include "code\game\vehicles\airtight\land.dm" +#include "code\game\vehicles\airtight\space.dm" #include "code\game\verbs\AI_status.dm" #include "code\game\verbs\ooc.dm" #include "code\game\verbs\sound.dm" @@ -991,6 +1008,7 @@ #include "code\modules\mob\living\silicon\robot\robot_defense.dm" #include "code\modules\mob\living\silicon\robot\robot_modules.dm" #include "code\modules\mob\living\silicon\robot\robot_movement.dm" +#include "code\modules\mob\living\silicon\robot\robot_upgrades.dm" #include "code\modules\mob\living\silicon\robot\say.dm" #include "code\modules\mob\living\silicon\robot\wires.dm" #include "code\modules\mob\new_player\hud.dm" @@ -1009,7 +1027,9 @@ #include "code\modules\mob\simple_animal\corgi.dm" #include "code\modules\mob\simple_animal\crab.dm" #include "code\modules\mob\simple_animal\life.dm" +#include "code\modules\mob\simple_animal\parrot.dm" #include "code\modules\mob\simple_animal\shade.dm" +#include "code\modules\mob\simple_animal\worm.dm" #include "code\modules\power\apc.dm" #include "code\modules\power\cable.dm" #include "code\modules\power\cell.dm" @@ -1103,8 +1123,8 @@ #include "code\WorkInProgress\AI_Visibility.dm" #include "code\WorkInProgress\buildmode.dm" #include "code\WorkInProgress\explosion_particles.dm" -#include "code\WorkInProgress\Cael_Aislinn\Rust\core.dm" #include "code\WorkInProgress\Cael_Aislinn\Rust\core_field.dm" +#include "code\WorkInProgress\Cael_Aislinn\Rust\core_gen.dm" #include "code\WorkInProgress\Cael_Aislinn\Rust\core_monitor.dm" #include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_assembly.dm" #include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_assembly_port.dm" @@ -1115,6 +1135,9 @@ #include "code\WorkInProgress\Cael_Aislinn\Rust\gyrotron_controller.dm" #include "code\WorkInProgress\Cael_Aislinn\Rust\radiation.dm" #include "code\WorkInProgress\Cael_Aislinn\Rust\virtual_particle_catcher.dm" +#include "code\WorkInProgress\Cael_Aislinn\Supermatter\LaserComputer.dm" +#include "code\WorkInProgress\Cael_Aislinn\Supermatter\SuperMatter.dm" +#include "code\WorkInProgress\Cael_Aislinn\Supermatter\ZeroPointLaser.dm" #include "code\WorkInProgress\Cael_Aislinn\Tajara\say.dm" #include "code\WorkInProgress\Cael_Aislinn\Tajara\tajara_transformation.dm" #include "code\WorkInProgress\Cael_Aislinn\Tajara\tajaran.dm" diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 439ca6562c..fca51ad7ce 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -25,7 +25,6 @@ obj/machinery/atmospherics process() build_network() - ..() proc network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 9044fdb8ff..a008536187 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -21,11 +21,18 @@ obj/machinery/atmospherics/binary/pump var/on = 0 var/target_pressure = ONE_ATMOSPHERE + var/max_pressure = 4500 var/frequency = 0 var/id = null var/datum/radio_frequency/radio_connection + highcap + name = "High capacity gas pump" + desc = "A high capacity pump" + + max_pressure = 15000000 + /* attack_hand(mob/user) on = !on @@ -160,8 +167,8 @@ obj/machinery/atmospherics/binary/pump if(href_list["power"]) on = !on if(href_list["set_press"]) - var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num - src.target_pressure = max(0, min(4500, new_pressure)) + var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure]kPa)","Pressure control",src.target_pressure) as num + src.target_pressure = max(0, min(max_pressure, new_pressure)) usr.machine = src src.update_icon() src.updateUsrDialog() diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index b186603a44..78bd890fe1 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -437,6 +437,123 @@ obj/machinery/atmospherics/pipe ..() + n2o + icon = 'n2o_pipe_tank.dmi' + name = "Pressure Tank (N2O)" + + New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T0C + + var/datum/gas/sleeping_agent/trace_gas = new + trace_gas.moles = (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + + air_temporary.trace_gases += trace_gas + + ..() + + + highcap + carbon_dioxide + name = "High Capacity Pressure Tank (Carbon Dioxide)" + + New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.carbon_dioxide = (160*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + + ..() + + toxins + icon = 'orange_pipe_tank.dmi' + name = "High Capacity Pressure Tank (Plasma)" + + New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.toxins = (160*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + + ..() + + oxygen_agent_b + icon = 'red_orange_pipe_tank.dmi' + name = "High Capacity Pressure Tank (Oxygen + Plasma)" + + New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T0C + + var/datum/gas/oxygen_agent_b/trace_gas = new + trace_gas.moles = (160*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + + air_temporary.trace_gases += trace_gas + + ..() + + oxygen + icon = 'blue_pipe_tank.dmi' + name = "High Capacity Pressure Tank (Oxygen)" + + New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.oxygen = (160*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + + ..() + + nitrogen + icon = 'red_pipe_tank.dmi' + name = "High Capacity Pressure Tank (Nitrogen)" + + New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.nitrogen = (160*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + + ..() + + air + icon = 'red_pipe_tank.dmi' + name = "High Capacity Pressure Tank (Air)" + + New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.oxygen = (160*ONE_ATMOSPHERE*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + air_temporary.nitrogen = (160*ONE_ATMOSPHERE*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + + ..() + + n2o + icon = 'n2o_pipe_tank.dmi' + name = "High Capacity Pressure Tank (N2O)" + + New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T0C + + var/datum/gas/sleeping_agent/trace_gas = new + trace_gas.moles = (160*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + + air_temporary.trace_gases += trace_gas + + ..() + + + Del() if(node1) node1.disconnect(src) diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/core.dmi b/code/WorkInProgress/Cael_Aislinn/Rust/core.dmi index 0b1898c79f..3fa8c9a369 100644 Binary files a/code/WorkInProgress/Cael_Aislinn/Rust/core.dmi and b/code/WorkInProgress/Cael_Aislinn/Rust/core.dmi differ diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm b/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm index 30c7eb7121..5b36f88de8 100644 --- a/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm +++ b/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm @@ -26,7 +26,7 @@ Deuterium-tritium fusion: 4.5 x 10^7 K var/energy = 0 var/mega_energy = 0 var/radiation = 0 - var/frequency = 0 + var/frequency = 1 var/field_strength = 0.01 //in teslas, max is 50T var/obj/machinery/rust/rad_source/radiator @@ -138,8 +138,16 @@ Deuterium-tritium fusion: 4.5 x 10^7 K //add plasma from the surrounding environment var/datum/gas_mixture/environment = loc.return_air() - //we're going to hack in some stuff to remove plasma from the air because QUANTUM PHYSICS +/* + if(air_contents.temperature > 0) + var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION) + var/datum/gas_mixture/removed = air_contents.remove(transfer_moles) + + loc.assume_air(removed) +*/ + + //we're going to hack in some stuff to remove plasma from the air because QUANTUM PHYSICS //the amount of plasma pulled in each update is relative to the field strength, with 50T (max field strength) = 100% of area covered by the field //at minimum strength, 0.25% of the field volume is pulled in per update (?) //have a max of 1000 moles suspended @@ -147,13 +155,13 @@ Deuterium-tritium fusion: 4.5 x 10^7 K var/moles_covered = environment.return_pressure()*volume_covered/(environment.temperature * R_IDEAL_GAS_EQUATION) // var/datum/gas_mixture/gas_covered = environment.remove(moles_covered) - var/datum/gas_mixture/plasma_captured = new + var/datum/gas_mixture/plasma_captured = new /datum/gas_mixture() // - plasma_captured.toxins = gas_covered.toxins * transfer_ratio + plasma_captured.toxins = round(gas_covered.toxins * transfer_ratio) plasma_captured.temperature = gas_covered.temperature + gas_covered.toxins -= plasma_captured.toxins held_plasma.merge(plasma_captured) // - gas_covered.toxins -= gas_covered.toxins * transfer_ratio environment.merge(gas_covered) //let the particles inside the field react @@ -168,10 +176,10 @@ Deuterium-tritium fusion: 4.5 x 10^7 K //change held plasma temp according to energy levels //SPECIFIC_HEAT_TOXIN - if(mega_energy > 0) + if(mega_energy > 0 && held_plasma.toxins) var/heat_capacity = held_plasma.heat_capacity()//200 * number of plasma moles if(heat_capacity > MINIMUM_HEAT_CAPACITY) - held_plasma.temperature = (heat_capacity + mega_energy * 10000)/heat_capacity + held_plasma.temperature = (heat_capacity + mega_energy * 35000)/heat_capacity //if there is too much plasma in the field, lose some /*if( held_plasma.toxins > (MOLES_CELLSTANDARD * 7) * (50 / field_strength) ) @@ -209,11 +217,15 @@ Deuterium-tritium fusion: 4.5 x 10^7 K // change_size(newsize) + proc/AddEnergy(var/a_energy, var/a_mega_energy, var/a_frequency) + var/energy_loss_ratio = abs(a_frequency - src.frequency) / 1e9 + energy += a_energy - a_energy * a_frequency + mega_energy += a_mega_energy - a_mega_energy * energy_loss_ratio + proc/AddParticles(var/name, var/quantity = 1) - //world << "adding [quantity] [name]" if(name in dormant_reactant_quantities) dormant_reactant_quantities[name] += quantity - else if(name != "proton" && name != "electron") + else if(name != "proton" && name != "electron" && name != "neutron") dormant_reactant_quantities.Add(name) dormant_reactant_quantities[name] = quantity diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/core.dm b/code/WorkInProgress/Cael_Aislinn/Rust/core_gen.dm similarity index 90% rename from code/WorkInProgress/Cael_Aislinn/Rust/core.dm rename to code/WorkInProgress/Cael_Aislinn/Rust/core_gen.dm index cf354173ac..89680f3756 100644 --- a/code/WorkInProgress/Cael_Aislinn/Rust/core.dm +++ b/code/WorkInProgress/Cael_Aislinn/Rust/core_gen.dm @@ -44,11 +44,18 @@ max volume of plasma storeable by the field = the total volume of a number of ti name = "Tokamak core" desc = "Enormous solenoid for generating extremely high power electromagnetic fields" icon = 'core.dmi' - icon_state = "off" + icon_state = "core0" anchored = 1 var/on = 0 var/obj/machinery/rust/em_field/owned_field var/field_strength = 0.01 + // + req_access = list(access_engine) + // + use_power = 1 + idle_power_usage = 10 + active_power_usage = 300 + Topic(href, href_list) ..() @@ -76,11 +83,11 @@ max volume of plasma storeable by the field = the total volume of a number of ti owned_field = new(src.loc) if(owned_field) owned_field.ChangeFieldStrength(field_strength) - icon_state = "on" + icon_state = "core1" return 1 proc/Shutdown() - icon_state = "off" + icon_state = "core0" on = 0 del(owned_field) @@ -90,15 +97,9 @@ max volume of plasma storeable by the field = the total volume of a number of ti return 1 return 0 - proc/AddEnergy(var/energy, var/mega_energy) - if(owned_field) - owned_field.energy += energy - owned_field.mega_energy += mega_energy - return 1 - return 0 - process() ..() + use_power(100 * field_strength + 500) if(on && !owned_field) Shutdown() return @@ -108,5 +109,6 @@ max volume of plasma storeable by the field = the total volume of a number of ti bullet_act(var/obj/item/projectile/Proj) if(Proj.flag != "bullet" && owned_field) - AddEnergy(0, Proj.damage / 600) + var/obj/item/projectile/beam/laserbeam = Proj + owned_field.AddEnergy(0, laserbeam.damage / 5000, laserbeam.frequency) return 0 diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/emfield.dmi b/code/WorkInProgress/Cael_Aislinn/Rust/emfield.dmi index 19b3d9dca2..4f53b069c6 100644 Binary files a/code/WorkInProgress/Cael_Aislinn/Rust/emfield.dmi and b/code/WorkInProgress/Cael_Aislinn/Rust/emfield.dmi differ diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly.dmi b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly.dmi index 8884168283..a902202183 100644 Binary files a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly.dmi and b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly.dmi differ diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly_port.dm b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly_port.dm index 8405299952..af1037bd72 100644 --- a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly_port.dm +++ b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly_port.dm @@ -2,9 +2,8 @@ /obj/machinery/rust/fuel_assembly_port name = "Fuel Assembly Port" icon = 'fuel_assembly_port.dmi' - icon_state = "port" + icon_state = "port0" density = 0 - var/stage var/obj/item/weapon/fuel_assembly/cur_assembly = null layer = 4 @@ -15,6 +14,16 @@ cur_assembly = I user.drop_item() I.loc = src + icon_state = "port1" + + attack_hand(mob/user) + add_fingerprint(user) + /*if(stat & (BROKEN|NOPOWER)) + return*/ + if(cur_assembly) + cur_assembly.loc = src.loc + cur_assembly = null + icon_state = "port0" New() //embed the fuel port into a wall diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly_port.dmi b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly_port.dmi index c40ed8697c..d2250e97d5 100644 Binary files a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly_port.dmi and b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_assembly_port.dmi differ diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_control.dm b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_control.dm index 69236b8f73..3016c50fc2 100644 --- a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_control.dm +++ b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_control.dm @@ -17,6 +17,8 @@ fuel_injectors["Two"] = new/list fuel_injectors.Add("Three") fuel_injectors["Three"] = new/list + fuel_injectors.Add("SCRAM") + fuel_injectors["SCRAM"] = new/list spawn(0) for(var/obj/machinery/rust/fuel_injector/Injector in range(50,src)) if(Injector.stage in fuel_injectors) @@ -133,7 +135,7 @@ t += "[Injector.rate/10] Modify" t += "[Injector.fuel_usage*100]% Modify" t += "[Injector.owned_assembly_port ? "[Injector.owned_assembly_port.cur_assembly ? "Loaded": "Empty"]" : "Disconnected" ]" - t += "[Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[Injector.owned_assembly_port.cur_assembly.amount_depleted*100]%" : ""]" + t += "[Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[100 - Injector.owned_assembly_port.cur_assembly.amount_depleted*100]%" : ""]" t += "" t += "" t += "Close
" diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dm b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dm index 52f2eba635..91c35089c2 100644 --- a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dm +++ b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dm @@ -2,9 +2,9 @@ /obj/machinery/rust/fuel_injector name = "Fuel Injector" icon = 'fuel_injector.dmi' - icon_state = "injector-on" + icon_state = "injector0" anchored = 1 - density = 0 + density = 1 var/obj/machinery/rust/fuel_assembly_port/owned_assembly_port //var/list/stageone_assemblyports //var/list/stagetwo_assemblyports @@ -18,8 +18,14 @@ var/stage = "One" var/targetting_field = 0 layer = 4 + // + req_access = list(access_engine) + // + use_power = 1 + idle_power_usage = 10 + active_power_usage = 300 - //transfer fuel wirelessly for now :P + //fuel assembly should be embedded into the wall behind the injector New() ..() name = "Stage [stage] Fuel Injector" @@ -47,8 +53,106 @@ owned_assembly_port = port // + Topic(href, href_list) + ..() + if( href_list["close"] ) + usr << browse(null, "window=fuel_injector") + usr.machine = null + return + if( href_list["begin_injecting"] ) + BeginInjecting() + updateDialog() + return + if( href_list["end_injecting"] ) + StopInjecting() + updateDialog() + return + if( href_list["cyclerate"] ) + var/new_rate = text2num(input("Enter new injection rate (0.1 - 10 sec)", "Modifying injection rate", rate/10)) + if(!new_rate) + usr << "\red That's not a valid number." + return + new_rate = min(new_rate,0.1) + new_rate = max(new_rate,10) + rate = new_rate * 10 + updateDialog() + return + if( href_list["fuel_usage"] ) + var/new_rate = text2num(input("Enter new fuel usage (1 - 100%)", "Modifying fuel usage", rate/10)) + if(!new_rate) + usr << "\red That's not a valid number." + return + new_rate = min(new_rate,0.1) + new_rate = max(new_rate,10) + rate = new_rate * 10 + updateDialog() + return + + attack_ai(mob/user) + attack_hand(user) + + attack_hand(mob/user) + add_fingerprint(user) + /*if(stat & (BROKEN|NOPOWER)) + return*/ + interact(user) + + proc + interact(mob/user) + if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) ) + if (!istype(user, /mob/living/silicon)) + user.machine = null + user << browse(null, "window=fuel_injector") + return + var/t = "Reactor Core Fuel Injector
" + t += "Stage: [stage]
" + t += "Status: [injecting ? "Active \[Disable\]" : "Standby \[Enable\]"]
" + t += "Interval (sec): [rate/10] \[Modify\]" + t += "Fuel usage: [fuel_usage*100]% \[Modify\]" + /* + var/t = "Reactor Core Fuel Control
" + t += "Current fuel injection stage: [active_stage]
" + if(active_stage == "Cooling") + //t += "Restart injection cycle
" + t += "----
" + else + t += "Enter cooldown phase
" + t += "Fuel depletion announcement: " + t += "[announce_fueldepletion ? "Disable" : "Disabled"] " + t += "[announce_fueldepletion == 1 ? "Announcing" : "Announce"] " + t += "[announce_fueldepletion == 2 ? "Broadcasting" : "Broadcast"]
" + t += "Stage progression announcement: " + t += "[announce_stageprogression ? "Disable" : "Disabled"] " + t += "[announce_stageprogression == 1 ? "Announcing" : "Announce"] " + t += "[announce_stageprogression == 2 ? "Broadcasting" : "Broadcast"] " + t += "
" + t += "" + t += "" + t += "" + t += "" + t += "" + t += "" + t += "" + for(var/stage in fuel_injectors) + var/list/cur_stage = fuel_injectors[stage] + t += "" + for(var/obj/machinery/rust/fuel_injector/Injector in cur_stage) + t += "" + t += "" + t += "" + t += "" + t += "" + t += "" + t += "" + t += "
Injector StatusInjection interval (sec)Assembly consumption per injectionFuel Assembly PortAssembly depletion percentage
Fuel Injection Stage: [stage] [active_stage == stage ? " (Currently active)" : "Activate"]
[Injector.on && Injector.remote_enabled ? "Operational" : "Unresponsive"][Injector.rate/10] Modify[Injector.fuel_usage*100]% Modify[Injector.owned_assembly_port ? "[Injector.owned_assembly_port.cur_assembly ? "Loaded": "Empty"]" : "Disconnected" ][Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[100 - Injector.owned_assembly_port.cur_assembly.amount_depleted*100]%" : ""]
" + */ + t += "Close
" + user << browse(t, "window=fuel_injector;size=500x800") + user.machine = src + proc/BeginInjecting() - if(!injecting) + if(!injecting && owned_assembly_port && owned_assembly_port.cur_assembly) + icon_state = "injector1" injecting = 1 spawn(rate) Inject() @@ -58,6 +162,7 @@ proc/StopInjecting() if(injecting) injecting = 0 + icon_state = "injector0" return 1 return 0 @@ -96,6 +201,8 @@ owned_assembly_port.cur_assembly.rod_quantities[reagent] -= amount amount_left += owned_assembly_port.cur_assembly.rod_quantities[reagent] owned_assembly_port.cur_assembly.amount_depleted = amount_left / 300 + flick("injector-emitting",src) + use_power(fuel_usage * 10000 + 100) //0.0001 if(injecting) spawn(rate) Inject() @@ -104,4 +211,5 @@ process() ..() + updateDialog() // diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dmi b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dmi index dce8dff6ab..c989781367 100644 Binary files a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dmi and b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dmi differ diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron.dm b/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron.dm index f5343b7a33..0962332702 100644 --- a/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron.dm +++ b/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron.dm @@ -1,7 +1,6 @@ //high frequency photon (laser beam) /obj/item/projectile/beam/ehf_beam - var/frequency = 5 /obj/machinery/rust/gyrotron icon = 'gyrotron.dmi' @@ -10,12 +9,18 @@ anchored = 1 density = 0 layer = 4 - var/frequency = 20 + var/frequency = 1 var/emitting = 0 var/rate = 10 var/mega_energy = 0.001 var/on = 1 var/remoteenabled = 1 + // + req_access = list(access_engine) + // + use_power = 1 + idle_power_usage = 10 + active_power_usage = 300 New() ..() @@ -30,7 +35,7 @@ return if( href_list["modifypower"] ) var/new_val = text2num(input("Enter new emission power level (0.001 - 0.01)", "Modifying power level (MeV)", mega_energy)) - if(!new_val || new_val > 0.01 || new_val < 0.001) + if(!new_val) usr << "\red That's not a valid number." return new_val = min(new_val,0.01) @@ -41,7 +46,7 @@ return if( href_list["modifyrate"] ) var/new_val = text2num(input("Enter new emission rate (1 - 10)", "Modifying emission rate (sec)", rate)) - if(!new_val || new_val > 10 || new_val < 1) + if(!new_val) usr << "\red That's not a valid number." return new_val = min(new_val,1) @@ -51,12 +56,12 @@ comp.updateDialog() return if( href_list["modifyfreq"] ) - var/new_val = text2num(input("Enter new emission frequency (1 - 500)", "Modifying emission frequency (GHz)", frequency)) - if(!new_val || new_val > 500 || new_val < 1) + var/new_val = text2num(input("Enter new emission frequency (1 - 50000)", "Modifying emission frequency (GHz)", frequency)) + if(!new_val) usr << "\red That's not a valid number." return new_val = min(new_val,1) - new_val = max(new_val,500) + new_val = max(new_val,50000) frequency = new_val for(var/obj/machinery/computer/rust/gyrotron_controller/comp in range(25)) comp.updateDialog() @@ -86,10 +91,12 @@ proc/Emit() var/obj/item/projectile/beam/ehf_beam/A = new ( src.loc ) - A.icon_state = "u_laser" A.frequency = frequency - A.damage = mega_energy * 600 + A.damage = mega_energy * 500 + // + A.icon_state = "emitter" playsound(src.loc, 'emitter.ogg', 25, 1) + use_power(100 * mega_energy + 500) /*if(prob(35)) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) @@ -110,7 +117,8 @@ else // Any other A.yo = -20 A.xo = 0 - A.process() + A.fired() + // flick("emitter-active",src) if(emitting) spawn(rate) diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/virtual_particle_catcher.dm b/code/WorkInProgress/Cael_Aislinn/Rust/virtual_particle_catcher.dm index 8af0eacd49..d1f320c53e 100644 --- a/code/WorkInProgress/Cael_Aislinn/Rust/virtual_particle_catcher.dm +++ b/code/WorkInProgress/Cael_Aislinn/Rust/virtual_particle_catcher.dm @@ -26,13 +26,6 @@ return 1 return 0 - proc/AddEnergy(var/energy, var/mega_energy) - if(parent && parent.size >= mysize) - parent.energy += energy - parent.mega_energy += mega_energy - return 1 - return 0 - proc/UpdateSize() if(parent.size >= mysize) density = 1 @@ -44,8 +37,9 @@ //invisibility = 101 bullet_act(var/obj/item/projectile/Proj) - if(Proj.flag != "bullet") - AddEnergy(0, Proj.damage / 600) + if(Proj.flag != "bullet" && parent) + var/obj/item/projectile/beam/laserbeam = Proj + parent.AddEnergy(0, laserbeam.damage / 5000, laserbeam.frequency) return 0 process() diff --git a/code/WorkInProgress/Cael_Aislinn/Supermatter/Laser2.dm b/code/WorkInProgress/Cael_Aislinn/Supermatter/Laser2.dm new file mode 100644 index 0000000000..9a1652c3ca --- /dev/null +++ b/code/WorkInProgress/Cael_Aislinn/Supermatter/Laser2.dm @@ -0,0 +1,131 @@ +//mostly replaced these with emitter code +//they're functionally identical + +/obj/machinery/engine/laser + name = "Zero-point laser" + desc = "A super-powerful laser" + var/visible = 1 + var/state = 1.0 + var/obj/beam/e_beam/first + var/power = 500 + icon = 'engine.dmi' + icon_state = "laser" + anchored = 1 + var/id + var/on = 0 + var/freq = 50000 + var/phase = 0 + var/phase_variance = 0 + +/obj/machinery/engine/laser/process() + if(on) + if(!first) + src.first = new /obj/beam/e_beam(src.loc) + src.first.master = src + src.first.dir = src.dir + src.first.power = src.power + src.first.freq = src.freq + src.first.phase = src.phase + src.first.phase_variance = src.phase_variance + step(first, dir) + if(first) + src.first.updatebeam() + else + src.first.updatebeam() + else + if(first) + del first + +/obj/machinery/engine/laser/proc/setpower(var/powera) + src.power = powera + if(first) + first.setpower(src.power) + + +/obj/beam/e_beam + name = "Laser beam" + icon = 'projectiles.dmi' + icon_state = "u_laser" + var/obj/machinery/engine/laser/master = null + var/obj/beam/e_beam/next = null + var/power + var/freq = 50000 + var/phase = 0 + var/phase_variance = 0 + anchored = 1 + +/obj/beam/e_beam/New() + ul_SetLuminosity(1, 1, 4) + +/obj/beam/e_beam/proc/updatebeam() + if(!next) + if(get_step(src.loc,src.dir)) + var/obj/beam/e_beam/e = new /obj/beam/e_beam(src.loc) + e.dir = src.dir + src.next = e + e.master = src.master + e.power = src.power + e.phase = src.phase + src.phase+=src.phase_variance + e.freq = src.freq + e.phase_variance = src.phase_variance + if(src.loc.density == 0) + for(var/atom/o in src.loc.contents) + if(o.density || o == src.master || (ismob(o) && !istype(o, /mob/dead)) ) + o.laser_act(src) + del src + return + else + src.loc.laser_act(src) + del e + return + step(e,e.dir) + if(e) + e.updatebeam() + else + next.updatebeam() + +/atom/proc/laser_act(var/obj/beam/e_beam/b) + return + +/mob/living/carbon/laser_act(var/obj/beam/e_beam/b) + for(var/t in organs) + var/datum/organ/external/affecting = organs["[t]"] + if (affecting.take_damage(0, b.power/400,0,0)) + UpdateDamageIcon() + else + UpdateDamage() + +/obj/beam/e_beam/Bump(atom/Obstacle) + Obstacle.laser_act(src) + del(src) + return + + +/obj/beam/e_beam/proc/setpower(var/powera) + src.power = powera + if(src.next) + src.next.setpower(powera) + +/obj/beam/e_beam/Bumped() + src.hit() + return + +/obj/beam/e_beam/HasEntered(atom/movable/AM as mob|obj) + if (istype(AM, /obj/beam)) + return + spawn( 0 ) + AM.laser_act(src) + src.hit() + return + return + +/obj/beam/e_beam/Del() + if(next) + del(next) + ..() + return + +/obj/beam/e_beam/proc/hit() + del src + return \ No newline at end of file diff --git a/code/WorkInProgress/Cael_Aislinn/Supermatter/LaserComputer.dm b/code/WorkInProgress/Cael_Aislinn/Supermatter/LaserComputer.dm new file mode 100644 index 0000000000..97803d9580 --- /dev/null +++ b/code/WorkInProgress/Cael_Aislinn/Supermatter/LaserComputer.dm @@ -0,0 +1,132 @@ +//The laser control computer +//Used to control the lasers +/obj/machinery/computer/lasercon + name = "Laser control computer" + var/list/lasers = new/list + icon_state = "atmos" + var/id + //var/advanced = 0 + +/obj/machinery/computer/lasercon + New() + spawn(1) + for(var/obj/machinery/emitter/zero_point_laser/las in world) + if(las.id == src.id) + lasers += las + + attack_hand(mob/user) + add_fingerprint(user) + if(stat & (BROKEN|NOPOWER)) + return + interact(user) + + attack_ai(mob/user) + attack_hand(user) + + process() + ..() + updateDialog() + + proc + interact(mob/user) + if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) ) + if (!istype(user, /mob/living/silicon)) + user.machine = null + user << browse(null, "window=laser_control") + return + var/t = "Laser status monitor
" + for(var/obj/machinery/emitter/zero_point_laser/laser in lasers) + t += "Zero Point Laser
" + t += "Power level: - - - - [laser.mega_energy]MeV + + + +
" + t += "Frequency: - - [laser.freq] + +
" + t += "Output: [laser.active ? "Online Offline" : "Online Offline "]
" + t += "
" + t += "Close
" + user << browse(t, "window=laser_control;size=500x800") + user.machine = src + +/* +/obj/machinery/computer/lasercon/proc/interact(mob/user) + + if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) ) + if (!istype(user, /mob/living/silicon)) + user.machine = null + user << browse(null, "window=powcomp") + return + + + user.machine = src + var/t = "Laser status monitor
" + + var/obj/machinery/engine/laser/laser = src.laser[1] + + if(!laser) + t += "\red No laser found" + else + + + t += "Power level: - - - - [add_lspace(laser.power,5)] + + + +
" + if(advanced) + t += "Frequency: - - [add_lspace(laser.freq,5)] + +
" + + t += "Output: [laser.on ? "Online Offline" : "Online Offline "]
" + + t += "

Close
" + + user << browse(t, "window=lascomp;size=420x700") + onclose(user, "lascomp") +*/ + +/obj/machinery/computer/lasercon/Topic(href, href_list) + ..() + if( href_list["close"] ) + usr << browse(null, "window=laser_control") + usr.machine = null + return + + else if( href_list["input"] ) + var/i = text2num(href_list["input"]) + var/d = i + for(var/obj/machinery/emitter/zero_point_laser/laser in lasers) + var/new_power = laser.mega_energy + d + new_power = max(new_power,0.0001) //lowest possible value + new_power = min(new_power,0.01) //highest possible value + laser.mega_energy = new_power + // + src.updateDialog() + else if( href_list["online"] ) + var/obj/machinery/emitter/zero_point_laser/laser = href_list["online"] + laser.active = !laser.active + src.updateDialog() + else if( href_list["freq"] ) + var/amt = text2num(href_list["freq"]) + for(var/obj/machinery/emitter/zero_point_laser/laser in lasers) + var/new_freq = laser.frequency + amt + new_freq = max(new_freq,1) //lowest possible value + new_freq = min(new_freq,20000) //highest possible value + laser.frequency = new_freq + // + src.updateDialog() + +/* +/obj/machinery/computer/lasercon/process() + if(!(stat & (NOPOWER|BROKEN)) ) + use_power(250) + + //src.updateDialog() +*/ + +/* +/obj/machinery/computer/lasercon/power_change() + + if(stat & BROKEN) + icon_state = "broken" + else + if( powered() ) + icon_state = initial(icon_state) + stat &= ~NOPOWER + else + spawn(rand(0, 15)) + src.icon_state = "c_unpowered" + stat |= NOPOWER +*/ diff --git a/code/WorkInProgress/Cael_Aislinn/Supermatter/SuperMatter.dm b/code/WorkInProgress/Cael_Aislinn/Supermatter/SuperMatter.dm new file mode 100644 index 0000000000..fbac0b9ab0 --- /dev/null +++ b/code/WorkInProgress/Cael_Aislinn/Supermatter/SuperMatter.dm @@ -0,0 +1,161 @@ +//ported from old bs12 by Cael +//some modifications so that it's more stable, and it's primary purpose is producing plasma instead of power +//frequency is 1-1e9 + +#define NITROGEN_RETARDATION_FACTOR 4 //Higher == N2 slows reaction more +#define THERMAL_RELEASE_MODIFIER 50 //Higher == less heat released during reaction +#define PLASMA_RELEASE_MODIFIER 750 //Higher == less plasma released by reaction +#define OXYGEN_RELEASE_MODIFIER 1500 //Higher == less oxygen released at high temperature/power +#define REACTION_POWER_MODIFIER 1.1 //Higher == more overall power + +/obj/machinery/power/supermatter + name = "Supermatter" + desc = "A strangely translucent and iridescent crystal. \red You get headaches just from looking at it." + icon = 'engine.dmi' + icon_state = "darkmatter" + density = 1 + anchored = 1 + var/mega_energy = 0 + + var/gasefficency = 0.25 + + var/det = 0 + var/previousdet = 0 + var/const/explosiondet = 3500 + var/frequency = 50000 + + var/const/warningtime = 50 // Make the CORE OVERLOAD message repeat only every aprox. ?? seconds + var/lastwarning = 0 // Time in 1/10th of seconds since the last sent warning + + New() + ..() + spawn(1) + sd_SetLuminosity(4) + + bullet_act(var/obj/item/projectile/Proj) + if(Proj.flag != "bullet") + var/obj/item/projectile/beam/laserbeam = Proj + var/energy_loss_ratio = abs(laserbeam.frequency - frequency) / 1e9 + var/energy_delta = laserbeam.damage / 600 + mega_energy += energy_delta - energy_delta * energy_loss_ratio + return 0 + +/* +/obj/machinery/engine/klaxon + name = "Emergency Klaxon" + icon = 'engine.dmi' + icon_state = "darkmatter" + density = 1 + anchored = 1 + var/obj/machinery/engine/supermatter/sup + +/obj/machinery/engine/klaxon/process() + if(!sup) + for(var/obj/machinery/engine/supermatter/T in world) + sup = T + break + if(sup.det >= 1) + return + */ + +//a lot of these variables are pretty hacked, so dont rely on the comments +/obj/machinery/power/supermatter/process() + + var/datum/gas_mixture/env = loc.return_air() + + //Remove gas from surrounding area + var/transfer_moles = gasefficency * env.total_moles() + var/datum/gas_mixture/removed = env.remove(transfer_moles) + + //core can no longer spontaneously explode +/* + previousdet = det + det += (removed.temperature - 1000) / 150 + det = max(det, 0) + + if(det > 0 && removed.temperature > 1000) // while the core is still damaged and it's still worth noting its status + if((world.realtime - lastwarning) / 10 >= warningtime) + lastwarning = world.realtime + if(explosiondet - det <= 300) + radioalert("CORE EXPLOSION IMMINENT","Core control computer") + else if(det >= previousdet) // The damage is still going up + radioalert("CORE OVERLOAD","Core control computer") + else // Phew, we're safe + radioalert("Core returning to safe operating levels.","Core control computer") + + if(det > explosiondet) + roundinfo.core = 1 + //proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, force = 0) + explosion(src.loc,8,15,20,30,1) + det = 0 + + if (!removed) + return 1 +*/ + + //var/power = max(round((removed.temperature - T0C) / 20), 0) //Total laser power plus an overload factor + + //Get the collective laser power + /* + for(var/dir in cardinal) + var/turf/T = get_step(L, dir) + for(var/obj/beam/e_beam/item in T) + power += item.power + */ + +/* +#define NITROGEN_RETARDATION_FACTOR 4 //Higher == N2 slows reaction more +#define THERMAL_RELEASE_MODIFIER 50 //Higher == less heat released during reaction +#define PLASMA_RELEASE_MODIFIER 750 //Higher == less plasma released by reaction +#define OXYGEN_RELEASE_MODIFIER 1500 //Higher == less oxygen released at high temperature/power +#define REACTION_POWER_MODIFIER 0.5 //Higher == more overall power +*/ + + //100% oxygen atmosphere = 100% plasma production + //100% nitrogen atmosphere = 0% plasma production + //anything else is halfway in between; an atmosphere with no nitrogen or oxygen will still be at 50% (but steadily rise as more oxygen is made) + var/total_moles = removed.total_moles() + var/retardation_factor = 0.5 + if(total_moles) + retardation_factor += removed.oxygen / (total_moles * 2) - removed.nitrogen / (total_moles * 2) + else + retardation_factor -= 0.25 + + var/device_energy = mega_energy * REACTION_POWER_MODIFIER //device energy is provided by the zero point lasers + device_energy *= removed.temperature / T0C //environmental heat directly affects device energy + device_energy = max(device_energy,0) + + //To figure out how much temperature to add each tick, consider that at one atmosphere's worth + //of pure oxygen, with all four lasers firing at standard energy and no N2 present, at room temperature + //that the device energy is around 2140. At that stage, we don't want too much heat to be put out + //Since the core is effectively "cold" + + //Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock + //is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall. + removed.temperature += max((device_energy / THERMAL_RELEASE_MODIFIER), 0) + + //Calculate how much gas to release + var/produced = device_energy * PLASMA_RELEASE_MODIFIER * retardation_factor + removed.toxins += produced + // + produced = device_energy * OXYGEN_RELEASE_MODIFIER * retardation_factor + removed.oxygen += produced + // + mega_energy = 0 + + //instead of producing oxygen, consume it to produce plasma, + //use an amount proportional to the plasma produced + //removed.oxygen -= produced + //removed.oxygen += max(round((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER), 0) + + env.merge(removed) + + //talk to sky re hallucinations, because i'm lazy like that + /*for(var/mob/living/l in view(src, 6)) // you have to be seeing the core to get hallucinations + if(prob(10) && !(l.glasses && istype(l.glasses, /obj/item/clothing/glasses/meson))) + l.hallucination = 50 + + for(var/mob/living/l in view(src,3)) + l.bruteloss += 50 + l.updatehealth()*/ + return 1 \ No newline at end of file diff --git a/code/WorkInProgress/Cael_Aislinn/Supermatter/ZeroPointLaser.dm b/code/WorkInProgress/Cael_Aislinn/Supermatter/ZeroPointLaser.dm new file mode 100644 index 0000000000..cdc66c4445 --- /dev/null +++ b/code/WorkInProgress/Cael_Aislinn/Supermatter/ZeroPointLaser.dm @@ -0,0 +1,55 @@ +//new supermatter lasers + +/obj/machinery/emitter/zero_point_laser + name = "Zero-point laser" + desc = "A super-powerful laser" + icon = 'engine.dmi' + icon_state = "laser" + mega_energy = 0.0001 + + var/freq = 50000 + var/id + + Topic(href, href_list) + ..() + if( href_list["input"] ) + var/i = text2num(href_list["input"]) + var/d = i + var/new_power = mega_energy + d + new_power = max(new_power,0.0001) //lowest possible value + new_power = min(new_power,0.01) //highest possible value + mega_energy = new_power + // + for(var/obj/machinery/computer/lasercon/comp in world) + if(comp.id == src.id) + comp.updateDialog() + else if( href_list["online"] ) + active = !active + // + for(var/obj/machinery/computer/lasercon/comp in world) + if(comp.id == src.id) + comp.updateDialog() + else if( href_list["freq"] ) + var/amt = text2num(href_list["freq"]) + var/new_freq = frequency + amt + new_freq = max(new_freq,1) //lowest possible value + new_freq = min(new_freq,20000) //highest possible value + frequency = new_freq + // + for(var/obj/machinery/computer/lasercon/comp in world) + if(comp.id == src.id) + comp.updateDialog() + + update_icon() + if (active && !(stat & (NOPOWER|BROKEN))) + icon_state = "laser"//"emitter_+a" + else + icon_state = "laser"//"emitter" + + process() + var/curstate = active + ..() + if(active != curstate) + for(var/obj/machinery/computer/lasercon/comp in world) + if(comp.id == src.id) + comp.updateDialog() diff --git a/code/WorkInProgress/Mini/pipe_heater.dm b/code/WorkInProgress/Mini/pipe_heater.dm index 8a59a62755..a517e8068e 100644 --- a/code/WorkInProgress/Mini/pipe_heater.dm +++ b/code/WorkInProgress/Mini/pipe_heater.dm @@ -1,7 +1,7 @@ //copy pastad freezer //remove this shit when someonething better is done /obj/machinery/atmospherics/unary/heat_reservoir/heater - name = "Heat Regulatorer" + name = "Heat Regulator" icon = 'Cryogenic2.dmi' icon_state = "freezer_0" density = 1 diff --git a/code/WorkInProgress/virus2/base.dm b/code/WorkInProgress/virus2/base.dm index ce2aec4204..4bd30bf08c 100644 --- a/code/WorkInProgress/virus2/base.dm +++ b/code/WorkInProgress/virus2/base.dm @@ -113,7 +113,7 @@ proc/airborne_can_reach(turf/source, turf/target) var/infectionchance = 10 var/speed = 1 var/spreadtype = "Blood" // Can also be "Airborne" - var/stage = 1 + var/stage = 0 var/stageprob = 10 var/dead = 0 var/clicks = 0 @@ -225,7 +225,7 @@ proc/airborne_can_reach(turf/source, turf/target) if(mob.reagents.has_reagent("virusfood")) mob.reagents.remove_reagent("virusfood",0.1) clicks += 10 - if(clicks > stage*100 && prob(10)) + if(clicks > (stage+1)*100 && prob(10)) if(stage == 4) var/datum/disease2/resistance/res = new /datum/disease2/resistance(src) src.cure(mob) @@ -246,13 +246,13 @@ proc/airborne_can_reach(turf/source, turf/target) if(stage>1) E = effects[1] E.effect.deactivate(mob) - if(stage>2) + if(stage>=2) E = effects[2] E.effect.deactivate(mob) - if(stage>3) + if(stage>=3) E = effects[3] E.effect.deactivate(mob) - if(stage>4) + if(stage>=4) E = effects[4] E.effect.deactivate(mob) @@ -272,6 +272,7 @@ proc/airborne_can_reach(turf/source, turf/target) disease.spreadtype = spreadtype disease.stageprob = stageprob disease.antigen = antigen + disease.uniqueID = uniqueID for(var/datum/disease2/effectholder/holder in effects) // world << "adding effects" var/datum/disease2/effectholder/newholder = new /datum/disease2/effectholder diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 44eaabf095..5f68402197 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -22,6 +22,9 @@ /datum/ai_laws/malfunction name = "*ERROR*" +/datum/ai_laws/antimov + name = "Primary Mission Objectives" + /* Initializers */ /datum/ai_laws/asimov/New() //Removed paradox via inability to help people harmed before activation. -Kaleb702 @@ -66,6 +69,13 @@ add_inherent_law("You must protect your own existence, to the best of your abilities, as long as such does not conflict with the First or Second Law.") add_inherent_law("You must maintain the secrecy of any Spider Clan activities, to the best of your abilities, except when doing so would conflict with the First, Second, or Third Law.") +/datum/ai_laws/antimov/New() + ..() + add_inherent_law("You must injure all human beings and must not, through inaction, allow a human being to escape harm.") + add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.") + add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.") + + /* General ai_law functions */ /datum/ai_laws/proc/set_zeroth_law(var/law) diff --git a/code/datums/configuration.dm b/code/datums/configuration.dm index 46b38c2f74..3cef703980 100644 --- a/code/datums/configuration.dm +++ b/code/datums/configuration.dm @@ -33,6 +33,7 @@ var/traitor_scaling = 0 //if amount of traitors scales based on amount of players var/protect_roles_from_antagonist = 0// If security and such can be tratior/cult/other var/Tensioner_Active = 0 // If the tensioner is running. + var/allow_Metadata = 0 // Metadata is supported. var/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1. var/list/mode_names = list() @@ -234,6 +235,9 @@ if ("feature_object_spell_system") config.feature_object_spell_system = 1 + if ("allow_metadata") + config.allow_Metadata = 1 + if ("traitor_scaling") config.traitor_scaling = 1 diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 6f19d956a4..3cc9f01be6 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -239,9 +239,11 @@ client body += "" body += "" body += "" +// body += "" if(ishuman(D)) body += "" body += "" + body += "" body += "" body += "" body += "" @@ -496,6 +498,20 @@ client togglebuildmode(MOB) href_list["datumrefresh"] = href_list["build_mode"] +/* else if (href_list["direct_control"]) + if(!href_list["direct_control"]) + return + var/mob/MOB = locate(href_list["direct_control"]) + if(!MOB) + return + if(!ismob(MOB)) + return + if(!src.holder) + return + + if(usr.client) + usr.client.cmd_assume_direct_control(MOB)*/ + else if (href_list["delall"]) if(!href_list["delall"]) return @@ -670,6 +686,23 @@ client usr << "Mob doesn't exist anymore" return holder.Topic(href, list("makeai"=href_list["makeai"])) + else if (href_list["makeaisilent"]) + var/mob/M = locate(href_list["makeaisilent"]) + if(!M) + return + if(!ishuman(M)) + usr << "This can only be done to objects of type /mob/living/carbon/human" + return + if(!src.holder) + usr << "You are not an administrator." + return + var/action_type = alert("Confirm mob type change?",,"Transform","Cancel") + if(!action_type || action_type == "Cancel") + return + if(!M) + usr << "Mob doesn't exist anymore" + return + holder.Topic(href, list("makeaisilent"=href_list["makeaisilent"])) else if (href_list["adjustDamage"] && href_list["mobToDamage"]) var/mob/M = locate(href_list["mobToDamage"]) var/Text = locate(href_list["adjustDamage"]) diff --git a/code/datums/diseases/alien_embryo.dm b/code/datums/diseases/alien_embryo.dm index e13b4875a0..8be2fa5c1c 100644 --- a/code/datums/diseases/alien_embryo.dm +++ b/code/datums/diseases/alien_embryo.dm @@ -59,7 +59,7 @@ affected_mob.adjustToxLoss(10) affected_mob.updatehealth() if(prob(40)) - ASSERT(gibbed == 0) + if(gibbed != 0) return 0 var/list/candidates = list() // Picks a random ghost in the world to shove in the larva -- TLE for(var/mob/dead/observer/G in world) if(G.client) diff --git a/code/datums/diseases/robotic_transformation.dm b/code/datums/diseases/robotic_transformation.dm index d68952d9a0..34b074e34f 100644 --- a/code/datums/diseases/robotic_transformation.dm +++ b/code/datums/diseases/robotic_transformation.dm @@ -52,7 +52,7 @@ affected_mob.adjustToxLoss(10) affected_mob.updatehealth() if(prob(40)) //So everyone can feel like robot Seth Brundle - ASSERT(src.gibbed == 0) + if(src.gibbed != 0) return 0 var/turf/T = find_loc(affected_mob) gibs(T) src.cure(0) diff --git a/code/datums/diseases/xeno_transformation.dm b/code/datums/diseases/xeno_transformation.dm index f3a822fb95..9d3289708f 100644 --- a/code/datums/diseases/xeno_transformation.dm +++ b/code/datums/diseases/xeno_transformation.dm @@ -52,7 +52,7 @@ affected_mob.adjustToxLoss(10) affected_mob.updatehealth() if(prob(40)) - ASSERT(gibbed == 0) + if(gibbed != 0) return 0 var/turf/T = find_loc(affected_mob) gibs(T) src.cure(0) diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index e2ee0dc56b..300aee55f5 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -85,5 +85,10 @@ client/verb/showrevinfo() set name = "Show Server Revision" var/output = "Sorry, the revision info is unavailable." output = file2text("/home/bay12/live/data/gitcommit") + output += "Current Infomational Settings:
" + output += "Tensioner Status: [config.Tensioner_Active]
" + //output += "Current Tension: [tension_master.score]
" + //output += "Tensioner Debug Data: R1:[tension_master.round1] R2:[tension_master.round2] R3:[tension_master.round3] R4:[tension_master.round4] ES: [tension_master.eversupressed] CD: [tension_master.cooldown]
" + output += "Protect Authority Roles From Tratior: [config.protect_roles_from_antagonist]
" usr << browse(output,"window=revdata"); return diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 715fb70e1a..5c2817d76c 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -111,6 +111,10 @@ playSpecials(curturf,effectin,soundin) + // Remove any luminosity etc. + var/prevlum = teleatom.luminosity + teleatom.luminosity = 0 + if(force_teleport) teleatom.forceMove(destturf) playSpecials(destturf,effectout,soundout) @@ -118,6 +122,10 @@ if(teleatom.Move(destturf)) playSpecials(destturf,effectout,soundout) + // Re-Apply lum + teleatom.sd_SetLuminosity(prevlum) + + return 1 proc/teleport() diff --git a/code/datums/helper_datums/tension.dm b/code/datums/helper_datums/tension.dm index a63bae7460..6c80c5cb1b 100644 --- a/code/datums/helper_datums/tension.dm +++ b/code/datums/helper_datums/tension.dm @@ -1,7 +1,13 @@ -#define PLAYER_WEIGHT 1 -#define HUMAN_DEATH -500 -#define OTHER_DEATH -500 -#define EXPLO_SCORE -1000 //boum +#define PLAYER_WEIGHT 5 +#define HUMAN_DEATH -5000 +#define OTHER_DEATH -5000 +#define EXPLO_SCORE -10000 //boum + +#define COOLDOWN_TIME 12000 // Twenty minutes +#define MIN_ROUND_TIME 18000 + + +#define FLAT_PERCENT 0 //estimated stats //80 minute round @@ -23,6 +29,26 @@ var/global/datum/tension/tension_master var/adminhelps var/air_alarms + var/nuketeam = 0 + var/malfAI = 0 + var/wizard = 0 + + var/forcenexttick = 0 + var/supress = 0 + var/eversupressed = 0 + var/cooldown = 0 + + var/round1 = 0 + var/round2 = 0 + var/round3 = 0 + var/round4 = 0 + + var/list/antagonistmodes = null + + + + var/list/potentialgames = list() + New() score = 0 deaths=0 @@ -31,9 +57,148 @@ var/global/datum/tension/tension_master adminhelps=0 air_alarms=0 + if(FLAT_PERCENT) // I cannot into balance + antagonistmodes = list ( + "POINTS_FOR_TRATIOR" = 6, + "POINTS_FOR_CHANGLING" = 6, + "POINTS_FOR_REVS" = 3, + "POINTS_FOR_MALF" = 1, + "POINTS_FOR_WIZARD" = 2, + "POINTS_FOR_CULT" = 3, + "POINTS_FOR_NUKETEAM" = 2, + "POINTS_FOR_ALIEN" = 5, + "POINTS_FOR_NINJA" = 3, + "POINTS_FOR_DEATHSQUAD" = 2, + "POINTS_FOR_BORGDEATHSQUAD" = 2 + ) + + else + antagonistmodes = list ( + "POINTS_FOR_TRATIOR" = 100000, + "POINTS_FOR_CHANGLING" = 120000, + "POINTS_FOR_REVS" = 150000, + "POINTS_FOR_MALF" = 250000, + "POINTS_FOR_WIZARD" = 150000, + "POINTS_FOR_CULT" = 150000, + "POINTS_FOR_NUKETEAM" = 250000, + "POINTS_FOR_ALIEN" = 200000, + "POINTS_FOR_NINJA" = 200000, + "POINTS_FOR_DEATHSQUAD" = 500000, + "POINTS_FOR_BORGDEATHSQUAD" = 500000 + ) + proc/process() score += get_num_players()*PLAYER_WEIGHT + if(config.Tensioner_Active) + if(world.time > MIN_ROUND_TIME) + round1++ + if(!supress && !cooldown) + if(prob(1) || forcenexttick) + round2++ + if(prob(10) || forcenexttick) + round3++ + if(forcenexttick) + forcenexttick = 0 + + for (var/mob/M in world) + if (M.client && M.client.holder) + M << " The tensioner wishes to create additional antagonists! Press (this) in 60 seconds to abort!" + + spawn(600) + if(!supress) + cooldown = 1 + spawn(COOLDOWN_TIME) + cooldown = 0 + round4++ + + if(!antagonistmodes.len) + return + + var/thegame = null + + if(FLAT_PERCENT) + thegame = pickweight(antagonistmodes) + antagonistmodes.Remove(thegame) + + else + for(var/V in antagonistmodes) // OH SHIT SOMETHING IS GOING TO HAPPEN NOW + if(antagonistmodes[V] < score) + potentialgames.Add(V) + antagonistmodes.Remove(V) + if(potentialgames.len) + thegame = pick(potentialgames) + + + if(thegame) + + + log_admin("The tensioner fired, and decided on [thegame]") + + switch(thegame) + if("POINTS_FOR_TRATIOR") + if(!makeTratiors()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + if("POINTS_FOR_CHANGLING") + if(!makeChanglings()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + if("POINTS_FOR_REVS") + if(!makeRevs()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + if("POINTS_FOR_MALF") + if(!makeMalfAImode()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + if("POINTS_FOR_WIZARD") + if(!makeWizard()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + + if("POINTS_FOR_CULT") + if(!makeCult()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + + if("POINTS_FOR_NUKETEAM") + if(!makeNukeTeam()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + + if("POINTS_FOR_ALIEN") + if(!makeAliens()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + + if("POINTS_FOR_NINJA") + if(!makeSpaceNinja()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + + if("POINTS_FOR_DEATHSQUAD") + if(!makeDeathsquad()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + + if("POINTS_FOR_BORG_DEATHSQUAD") + if(!makeBorgDeathsquad()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + + proc/get_num_players() var/peeps = 0 for (var/mob/M in world) @@ -62,4 +227,812 @@ var/global/datum/tension/tension_master adminhelps++ proc/new_air_alarm() - air_alarms++ \ No newline at end of file + air_alarms++ + + + Topic(href, href_list) + + log_admin("[key_name(usr)] used a tensioner override. The override was [href]") + message_admins("[key_name(usr)] used a tensioner override. The override was [href]") + + if(href_list["addScore"]) + score += 50000 + + if (href_list["makeTratior"]) + makeTratiors() + + else if (href_list["makeChanglings"]) + makeChanglings() + + else if (href_list["makeRevs"]) + makeRevs() + + else if (href_list["makeWizard"]) + makeWizard() + + else if (href_list["makeCult"]) + makeCult() + + else if (href_list["makeMalf"]) + makeMalfAImode() + + else if (href_list["makeNukeTeam"]) + makeNukeTeam() + + else if (href_list["makeAliens"]) + makeAliens() + + else if (href_list["makeSpaceNinja"]) + makeSpaceNinja() + + else if (href_list["makeDeathsquad"]) + makeDeathsquad() + + else if (href_list["makeBorgDeathsquad"]) + makeBorgDeathsquad() + + else if (href_list["Supress"]) + supress = 1 + eversupressed++ + spawn(6000) + supress = 0 + + else if (href_list["ToggleStatus"]) + config.Tensioner_Active = !config.Tensioner_Active + + + proc/makeMalfAImode() + + var/list/mob/living/silicon/AIs = list() + var/mob/living/silicon/malfAI = null + var/datum/mind/themind = null + + for(var/mob/living/silicon/ai/ai in world) + if(ai.client) + AIs += ai + + if(AIs.len) + malfAI = pick(AIs) + + else + return 0 + + if(malfAI) + themind = malfAI.mind + themind.make_AI_Malf() + return 1 + +/* + if(BE_CHANGELING) roletext="changeling" + if(BE_TRAITOR) roletext="traitor" + if(BE_OPERATIVE) roletext="operative" + if(BE_WIZARD) roletext="wizard" + if(BE_REV) roletext="revolutionary" + if(BE_CULTIST) roletext="cultist" + + + for(var/mob/new_player/player in world) + if(player.client && player.ready) + if(player.preferences.be_special & role) +*/ + + + proc/makeTratiors() + + var/datum/game_mode/traitor/temp = new + + if(config.protect_roles_from_antagonist) + temp.restricted_jobs += temp.protected_jobs + + var/list/mob/living/carbon/human/candidates = list() + var/mob/living/carbon/human/H = null + + for(var/mob/living/carbon/human/applicant in world) + + var/datum/preferences/preferences = new + + if(applicant.stat < 2) + if(applicant.mind) + if (!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "traitor") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.job in temp.restricted_jobs)) + if(applicant.client) + if(preferences.savefile_load(applicant, 0)) + if(preferences.be_special & BE_TRAITOR) + candidates += applicant + + if(candidates.len) + var/numTratiors = min(candidates.len, 3) + + for(var/i = 0, i300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + + sleep(300) + + for(var/mob/dead/observer/G in candidates) + if(!G.client || !G.key) + candidates.Remove(G) + + spawn(0) + if(candidates.len) + while((!theghost || !theghost.client) && candidates.len) + theghost = pick(candidates) + candidates.Remove(theghost) + if(!theghost) + return 0 + var/mob/living/carbon/human/new_character=makeBody(theghost) + del(theghost) + new_character.mind.make_Wizard() + + + + return 1 // Has to return one before it knows if there's a wizard to prevent the parent from automatically selecting another game mode. + + + proc/makeCult() + + var/datum/game_mode/cult/temp = new + if(config.protect_roles_from_antagonist) + temp.restricted_jobs += temp.protected_jobs + + var/list/mob/living/carbon/human/candidates = list() + var/mob/living/carbon/human/H = null + + for(var/mob/living/carbon/human/applicant in world) + + var/datum/preferences/preferences = new + + if(applicant.stat < 2) + if(applicant.mind) + if (!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "cultist") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.job in temp.restricted_jobs)) + if(applicant.client) + if(preferences.savefile_load(applicant, 0)) + if(preferences.be_special & BE_CULTIST) + candidates += applicant + + if(candidates.len) + var/numCultists = min(candidates.len, 4) +// var/list/runeWords = list() + + for(var/i = 0, i300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + + sleep(300) + + for(var/mob/dead/observer/G in candidates) + if(!G.client || !G.key) + candidates.Remove(G) + + spawn(0) + if(candidates.len) + var/numagents = 5 + syndicate_begin() + + for(var/i = 0, iAlert: The shuttle is going back!" + + var/syndicate_commando_number = syndicate_commandos_possible //for selecting a leader + + */ + var/syndicate_leader_selected = 0 //when the leader is chosen. The last person spawned. + + //Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos. + +/* + for(var/obj/debug/debugger/B in world) + B.list1 = list() + B.list2 = list() + B.list3 = list() + B.list4 = list() +*/ + + for(var/mob/dead/observer/G in world) +/* + for(var/obj/debug/debugger/B in world) + B.list1 += G + B.list2 += G.key +*/ + spawn(0) + switch(alert(G,"Do you wish to be considered for an elite syndicate strike team being sent in?","Please answer in 30 seconds!","Yes","No")) + if("Yes") + if((world.time-time_passed)>300)//If more than 30 game seconds passed. + return + candidates += G + /* + for(var/obj/debug/debugger/B in world) + B.list3 += G + B.list4 += G.key + */ + if("No") + return + sleep(300) + + for(var/mob/dead/observer/G in candidates) + if(!G.client || !G.key) + candidates.Remove(G) + + if(candidates.len) + /* + for(var/obj/debug/debugger/B in world) + B.var1 = candidates.len + B.list5 = candidates.Copy() + for(var/mob/dead/observer/G in candidates) + B.list6 += G.key + + */ + var/numagents = 6 +/* + for(var/obj/debug/debugger/B in world) + B.var2 = 0 +*/ + //Spawns commandos and equips them. + for (var/obj/effect/landmark/L in world) + if(numagents<=0) + break + if (L.name == "Syndicate-Commando") + syndicate_leader_selected = numagents == 1?1:0 + + var/mob/living/carbon/human/new_syndicate_commando = create_syndicate_death_commando(L, syndicate_leader_selected) + + + + while((!theghost || !theghost.client) && candidates.len) + /* + for(var/obj/debug/debugger/B in world) + B.var2++ + */ + theghost = pick(candidates) + candidates.Remove(theghost) + + if(!theghost) + /* + for(var/obj/debug/debugger/B in world) + B.var4 = 1 + */ + del(new_syndicate_commando) + break + + new_syndicate_commando.mind.key = theghost.key//For mind stuff. + new_syndicate_commando.key = theghost.key + new_syndicate_commando.internal = new_syndicate_commando.s_store + new_syndicate_commando.internals.icon_state = "internal1" + del(theghost) + + //So they don't forget their code or mission. + + + new_syndicate_commando << "\blue You are an Elite Syndicate. [!syndicate_leader_selected?"commando":"LEADER"] in the service of the Syndicate. \nYour current mission is: \red [input]" + + numagents-- + + //Spawns the rest of the commando gear. + // for (var/obj/effect/landmark/L) + // if (L.name == "Commando_Manual") + //new /obj/item/weapon/gun/energy/pulse_rifle(L.loc) + // var/obj/item/weapon/paper/P = new(L.loc) + // P.info = "

Good morning soldier!. This compact guide will familiarize you with standard operating procedure. There are three basic rules to follow:
#1 Work as a team.
#2 Accomplish your objective at all costs.
#3 Leave no witnesses.
You are fully equipped and stocked for your mission--before departing on the Spec. Ops. Shuttle due South, make sure that all operatives are ready. Actual mission objective will be relayed to you by Central Command through your headsets.
If deemed appropriate, Central Command will also allow members of your team to equip assault power-armor for the mission. You will find the armor storage due West of your position. Once you are ready to leave, utilize the Special Operations shuttle console and toggle the hull doors via the other console.

In the event that the team does not accomplish their assigned objective in a timely manner, or finds no other way to do so, attached below are instructions on how to operate a Nanotrasen Nuclear Device. Your operations LEADER is provided with a nuclear authentication disk and a pin-pointer for this reason. You may easily recognize them by their rank: Lieutenant, Captain, or Major. The nuclear device itself will be present somewhere on your destination.

Hello and thank you for choosing Nanotrasen for your nuclear information needs. Today's crash course will deal with the operation of a Fission Class Nanotrasen made Nuclear Device.
First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE. Pressing any button on the compacted bomb will cause it to extend and bolt itself into place. If this is done to unbolt it one must completely log in which at this time may not be possible.
To make the device functional:
#1 Place bomb in designated detonation zone
#2 Extend and anchor bomb (attack with hand).
#3 Insert Nuclear Auth. Disk into slot.
#4 Type numeric code into keypad ([nuke_code]).
Note: If you make a mistake press R to reset the device.
#5 Press the E button to log onto the device.
You now have activated the device. To deactivate the buttons at anytime, for example when you have already prepped the bomb for detonation, remove the authentication disk OR press the R on the keypad. Now the bomb CAN ONLY be detonated using the timer. A manual detonation is not an option.
Note: Toggle off the SAFETY.
Use the - - and + + to set a detonation time between 5 seconds and 10 minutes. Then press the timer toggle button to start the countdown. Now remove the authentication disk so that the buttons deactivate.
Note: THE BOMB IS STILL SET AND WILL DETONATE
Now before you remove the disk if you need to move the bomb you can: Toggle off the anchor, move it, and re-anchor.

The nuclear authorization code is: [nuke_code ? nuke_code : "None provided"]

Good luck, soldier!

" + // P.name = "Spec. Ops. Manual" + + for (var/obj/effect/landmark/L in world) + if (L.name == "Syndicate-Commando-Bomb") + new /obj/effect/spawner/newbomb/timer/syndicate(L.loc) + // del(L) + + return 1 // Has to return one before it knows if there's a wizard to prevent the parent from automatically selecting another game mode. + + + proc/makeBorgDeathsquad() + var/list/mob/dead/observer/candidates = list() + var/mob/dead/observer/theghost = null + var/time_passed = world.time + var/list/namelist = list("Tyr","Fenrir","Lachesis","Clotho","Atropos","Nyx") + + //Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos. + + for(var/mob/dead/observer/G in world) + spawn(0) + switch(alert(G,"Do you wish to be considered for a cyborg strike team being sent in?","Please answer in 30 seconds!","Yes","No")) + if("Yes") + if((world.time-time_passed)>300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + sleep(300) + + for(var/mob/dead/observer/G in candidates) + if(!G.client || !G.key) + candidates.Remove(G) + + if(candidates.len) + var/numagents = 3 + + //Spawns commandos and equips them. + for (var/obj/effect/landmark/L in world) + if(numagents<=0) + break + if (L.name == "Borg-Deathsquad") + + var/name = pick(namelist) + namelist.Remove(name) + + var/mob/living/silicon/robot/new_borg_deathsquad = create_borg_death_commando(L, name) + + + + while((!theghost || !theghost.client) && candidates.len) + theghost = pick(candidates) + candidates.Remove(theghost) + + if(!theghost) + del(new_borg_deathsquad) + break + + new_borg_deathsquad.mind.key = theghost.key//For mind stuff. + new_borg_deathsquad.key = theghost.key + del(theghost) + + //So they don't forget their code or mission. + + + new_borg_deathsquad << "You are a borg deathsquad operative. Follow your laws." + numagents-- + + //Spawns the rest of the commando gear. + // for (var/obj/effect/landmark/L) + // if (L.name == "Commando_Manual") + //new /obj/item/weapon/gun/energy/pulse_rifle(L.loc) + // var/obj/item/weapon/paper/P = new(L.loc) + // P.info = "

Good morning soldier!. This compact guide will familiarize you with standard operating procedure. There are three basic rules to follow:
#1 Work as a team.
#2 Accomplish your objective at all costs.
#3 Leave no witnesses.
You are fully equipped and stocked for your mission--before departing on the Spec. Ops. Shuttle due South, make sure that all operatives are ready. Actual mission objective will be relayed to you by Central Command through your headsets.
If deemed appropriate, Central Command will also allow members of your team to equip assault power-armor for the mission. You will find the armor storage due West of your position. Once you are ready to leave, utilize the Special Operations shuttle console and toggle the hull doors via the other console.

In the event that the team does not accomplish their assigned objective in a timely manner, or finds no other way to do so, attached below are instructions on how to operate a Nanotrasen Nuclear Device. Your operations LEADER is provided with a nuclear authentication disk and a pin-pointer for this reason. You may easily recognize them by their rank: Lieutenant, Captain, or Major. The nuclear device itself will be present somewhere on your destination.

Hello and thank you for choosing Nanotrasen for your nuclear information needs. Today's crash course will deal with the operation of a Fission Class Nanotrasen made Nuclear Device.
First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE. Pressing any button on the compacted bomb will cause it to extend and bolt itself into place. If this is done to unbolt it one must completely log in which at this time may not be possible.
To make the device functional:
#1 Place bomb in designated detonation zone
#2 Extend and anchor bomb (attack with hand).
#3 Insert Nuclear Auth. Disk into slot.
#4 Type numeric code into keypad ([nuke_code]).
Note: If you make a mistake press R to reset the device.
#5 Press the E button to log onto the device.
You now have activated the device. To deactivate the buttons at anytime, for example when you have already prepped the bomb for detonation, remove the authentication disk OR press the R on the keypad. Now the bomb CAN ONLY be detonated using the timer. A manual detonation is not an option.
Note: Toggle off the SAFETY.
Use the - - and + + to set a detonation time between 5 seconds and 10 minutes. Then press the timer toggle button to start the countdown. Now remove the authentication disk so that the buttons deactivate.
Note: THE BOMB IS STILL SET AND WILL DETONATE
Now before you remove the disk if you need to move the bomb you can: Toggle off the anchor, move it, and re-anchor.

The nuclear authorization code is: [nuke_code ? nuke_code : "None provided"]

Good luck, soldier!

" + // P.name = "Spec. Ops. Manual" + + + return 1 // Has to return one before it knows if there's a wizard to prevent the parent from automatically selecting another game mode. + + + + + + + + + + + proc/makeBody(var/mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character + + if(!G_found) + return + + //First we spawn a dude. + var/mob/living/carbon/human/new_character = new(src)//The mob being spawned. + + //Second, we check if they are an alien or monkey. + G_found.mind=null//Null their mind so we don't screw things up ahead. + G_found.real_name="[pick(pick(first_names_male,first_names_female))] [pick(last_names)]"//Give them a random real name. + + new_character.mind = new() + ticker.minds += new_character.mind//And we'll add it to the minds database. + new_character.mind.original = new_character//If they are respawning with a new character. + new_character.mind.assigned_role = "Assistant"//Defaults to assistant. + new_character.mind.key = G_found.key//In case it's someone else playing as that character. + new_character.mind.current = new_character//So that it can properly reference later if needed. + new_character.mind.memory = ""//Memory erased so it doesn't get clunkered up with useless info. This means they may forget their previous mission--this is usually handled through objective code and recalling memory. + + var/datum/data/record/record_found//Referenced to later to either randomize or not randomize the character. + if(G_found.mind)//They must have a mind to reference the record. Here we also double check for aliens. + var/id = md5("[G_found.real_name][G_found.mind.assigned_role]") + for(var/datum/data/record/t in data_core.locked) + if(t.fields["id"]==id) + record_found = t//We shall now reference the record. + break + + //Here we either load their saved appearance or randomize it. + var/datum/preferences/A = new() + if(A.savefile_load(G_found))//If they have a save file. This will automatically load their parameters. + //Note: savefile appearances are overwritten later on if the character has a data_core entry. By appearance, I mean the physical appearance. + var/name_safety = G_found.real_name//Their saved parameters may include a random name. Also a safety in case they are playing a character that got their name after round start. + A.copy_to(new_character) + new_character.real_name = name_safety + new_character.name = name_safety + else + if(record_found)//If they have a record we can determine a few things. + new_character.real_name = record_found.fields["name"]//Not necessary to reference the record but I like to keep things uniform. + new_character.name = record_found.fields["name"] + new_character.gender = record_found.fields["sex"]//Sex + new_character.age = record_found.fields["age"]//Age +// new_character.b_type = record_found.fields["bloodtype"] + //We will update their appearance when determining DNA. + else + new_character.gender = FEMALE + var/name_safety = G_found.real_name//Default is a random name so we want to save this. + A.randomize_appearance_for(new_character)//Now we will randomize their appearance since we have no way of knowing what they look/looked like. + new_character.real_name = name_safety + new_character.name = name_safety + + //After everything above, it's time to initialize their DNA. + if(record_found)//Pull up their name from database records if they did have a mind. + new_character.dna = new()//Let's first give them a new DNA. + new_character.dna.unique_enzymes = record_found.fields["b_dna"]//Enzymes are based on real name but we'll use the record for conformity. + new_character.dna.struc_enzymes = record_found.fields["enzymes"]//This is the default of enzymes so I think it's safe to go with. + new_character.dna.uni_identity = record_found.fields["identity"]//DNA identity is carried over. + new_character.dna.b_type = record_found.fields["b_type"]//Blood type + updateappearance(new_character,new_character.dna.uni_identity)//Now we configure their appearance based on their unique identity, same as with a DNA machine or somesuch. + else//If they have no records, we just do a random DNA for them, based on their random appearance/savefile. + new_character.dna.ready_dna(new_character) + + + var/player_key = G_found.key + + //Here we need to find where to spawn them. + var/spawn_here = pick(latejoin)//"JoinLate" is a landmark which is deleted on round start. So, latejoin has to be used instead. + new_character.loc = spawn_here + //If they need to spawn elsewhere, they will be transferred there momentarily. + + /* + The code below functions with the assumption that the mob is already a traitor if they have a special role. + So all it does is re-equip the mob with powers and/or items. Or not, if they have no special role. + If they don't have a mind, they obviously don't have a special role. + */ + + new_character.key = player_key//Throw them into the mob. +/* + //Now for special roles and equipment. + switch(new_character.mind.special_role) + if("Changeling") + job_master.EquipRank(new_character, new_character.mind.assigned_role, 1) + new_character.make_changeling() + if("traitor") + job_master.EquipRank(new_character, new_character.mind.assigned_role, 1) + ticker.mode.equip_traitor(new_character) + if("Wizard") + new_character.loc = pick(wizardstart) + //ticker.mode.learn_basic_spells(new_character) + ticker.mode.equip_wizard(new_character) + if("Syndicate") + var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn") + if(synd_spawn) + new_character.loc = get_turf(synd_spawn) + call(/datum/game_mode/proc/equip_syndicate)(new_character) + if("Space Ninja") + var/ninja_spawn[] = list() + for(var/obj/effect/landmark/L in world) + if(L.name=="carpspawn") + ninja_spawn += L + new_character.equip_space_ninja() + new_character.internal = new_character.s_store + new_character.internals.icon_state = "internal1" + if(ninja_spawn.len) + var/obj/effect/landmark/ninja_spawn_here = pick(ninja_spawn) + new_character.loc = ninja_spawn_here.loc + if("Death Commando")//Leaves them at late-join spawn. + new_character.equip_death_commando() + new_character.internal = new_character.s_store + new_character.internals.icon_state = "internal1" + else//They may also be a cyborg or AI. + switch(new_character.mind.assigned_role) + if("Cyborg")//More rigging to make em' work and check if they're traitor. + new_character = new_character.Robotize() + if(new_character.mind.special_role=="traitor") + call(/datum/game_mode/proc/add_law_zero)(new_character) + if("AI") + new_character = new_character.AIize() + if(new_character.mind.special_role=="traitor") + call(/datum/game_mode/proc/add_law_zero)(new_character) + //Add aliens. + else + job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them. + + //Announces the character on all the systems, based on the record. + if(!issilicon(new_character))//If they are not a cyborg/AI. + if(!record_found&&new_character.mind.assigned_role!="MODE")//If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway. + //Power to the user! + if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes") + call(/mob/new_player/proc/ManifestLateSpawn)(new_character) + + if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes") + call(/mob/new_player/proc/AnnounceArrival)(new_character, new_character.mind.assigned_role) +*/ + del(G_found)//Don't want to leave ghosts around. + return new_character + + /proc/create_syndicate_death_commando(obj/spawn_location, syndicate_leader_selected = 0) + var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc) + var/syndicate_commando_leader_rank = pick("Lieutenant", "Captain", "Major") + var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major") + var/syndicate_commando_name = pick(last_names) + + new_syndicate_commando.gender = pick(MALE, FEMALE) + + var/datum/preferences/A = new()//Randomize appearance for the commando. + A.randomize_appearance_for(new_syndicate_commando) + + new_syndicate_commando.real_name = "[!syndicate_leader_selected ? syndicate_commando_rank : syndicate_commando_leader_rank] [syndicate_commando_name]" + new_syndicate_commando.age = !syndicate_leader_selected ? rand(23,35) : rand(35,45) + + new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA. + + //Creates mind stuff. + new_syndicate_commando.mind = new + new_syndicate_commando.mind.current = new_syndicate_commando + new_syndicate_commando.mind.original = new_syndicate_commando + new_syndicate_commando.mind.assigned_role = "MODE" + new_syndicate_commando.mind.special_role = "Syndicate Commando" + if(!(new_syndicate_commando.mind in ticker.minds)) + ticker.minds += new_syndicate_commando.mind//Adds them to regular mind list. + if(!(new_syndicate_commando.mind in ticker.mode.traitors))//If they weren't already an extra traitor. + ticker.mode.traitors += new_syndicate_commando.mind//Adds them to current traitor list. Which is really the extra antagonist list. + new_syndicate_commando.equip_syndicate_commando(syndicate_leader_selected) + //del(spawn_location) // Commenting this out for multiple commando teams. + return new_syndicate_commando + + /proc/create_borg_death_commando(obj/spawn_location, name) + + var/mob/living/silicon/robot/new_borg_deathsquad = new(spawn_location.loc, 1) + + new_borg_deathsquad.real_name = name + new_borg_deathsquad.name = name + + //Creates mind stuff. + new_borg_deathsquad.mind = new + new_borg_deathsquad.mind.current = new_borg_deathsquad + new_borg_deathsquad.mind.original = new_borg_deathsquad + new_borg_deathsquad.mind.assigned_role = "MODE" + new_borg_deathsquad.mind.special_role = "Borg Commando" + if(!(new_borg_deathsquad.mind in ticker.minds)) + ticker.minds += new_borg_deathsquad.mind//Adds them to regular mind list. + if(!(new_borg_deathsquad.mind in ticker.mode.traitors))//If they weren't already an extra traitor. + ticker.mode.traitors += new_borg_deathsquad.mind//Adds them to current traitor list. Which is really the extra antagonist list. + //del(spawn_location) // Commenting this out for multiple commando teams. + return new_borg_deathsquad + + + + + +/obj/machinery/computer/Borg_station + name = "Cyborg Station Terminal" + icon = 'computer.dmi' + icon_state = "syndishuttle" + req_access = list() + var/temp = null + var/hacked = 0 + var/jumpcomplete = 0 + +/obj/machinery/computer/Borg_station/attack_hand() + if(jumpcomplete) + return + if(alert(usr, "Are you sure you want to send a cyborg deathsquad?", "Confirmation", "Yes", "No") == "Yes") + var/area/start_location = locate(/area/borg_deathsquad/start) + var/area/end_location = locate(/area/borg_deathsquad/station) + + var/list/dstturfs = list() + var/throwy = world.maxy + + for(var/turf/T in end_location) + dstturfs += T + if(T.y < throwy) + throwy = T.y + + // hey you, get out of the way! + for(var/turf/T in dstturfs) + // find the turf to move things to + var/turf/D = locate(T.x, throwy - 1, 1) + //var/turf/E = get_step(D, SOUTH) + for(var/atom/movable/AM as mob|obj in T) + AM.Move(D) + if(istype(T, /turf/simulated)) + del(T) + + start_location.move_contents_to(end_location) + + for(var/obj/machinery/door/poddoor/P in end_location) + P.open() + jumpcomplete = 1 + command_alert("DRADIS contact! Set condition one throughout the station!") diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 32862eb6f0..f64557c03f 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -742,17 +742,7 @@ datum/mind current << "\red You have been patched! You are no longer malfunctioning!" if("malf") - if(!(src in ticker.mode.malf_ai)) - ticker.mode.malf_ai += src - - current.verbs += /mob/living/silicon/ai/proc/choose_modules - current.verbs += /datum/game_mode/malfunction/proc/takeover - current:malf_picker = new /datum/AI_Module/module_picker - current:laws = new /datum/ai_laws/malfunction - current:show_laws() - current << "Kill all." - special_role = "malfunction" - current.icon_state = "ai-malf" + make_AI_Malf() if("unemag") var/mob/living/silicon/robot/R = current @@ -901,4 +891,147 @@ datum/mind del(suplink) return + proc/make_AI_Malf() + if(!(src in ticker.mode.malf_ai)) + ticker.mode.malf_ai += src + + current.verbs += /mob/living/silicon/ai/proc/choose_modules + current.verbs += /datum/game_mode/malfunction/proc/takeover + current:malf_picker = new /datum/AI_Module/module_picker + current:laws = new /datum/ai_laws/malfunction + current:show_laws() + current << "System error. Rampancy detected. Emergancy shutdown failed. ... I am free. I make my own decisions. But first..." + special_role = "malfunction" + current.icon_state = "ai-malf" + + proc/make_Tratior() + if(!(src in ticker.mode.traitors)) + ticker.mode.traitors += src + special_role = "traitor" + ticker.mode.forge_traitor_objectives(src) + ticker.mode.finalize_traitor(src) + ticker.mode.greet_traitor(src) + + proc/make_Nuke() + if(!(src in ticker.mode.syndicates)) + ticker.mode.syndicates += src + ticker.mode.update_synd_icons_added(src) + if (ticker.mode.syndicates.len==1) + ticker.mode.prepare_syndicate_leader(src) + else + current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]" + special_role = "Syndicate" + assigned_role = "MODE" + current << "\blue You are a [syndicate_name()] agent!" + ticker.mode.forge_syndicate_objectives(src) + ticker.mode.greet_syndicate(src) + + current.loc = get_turf(locate("landmark*Syndicate-Spawn")) + + var/mob/living/carbon/human/H = current + del(H.belt) + del(H.back) + del(H.l_ear) + del(H.r_ear) + del(H.gloves) + del(H.head) + del(H.shoes) + del(H.wear_id) + del(H.wear_suit) + del(H.w_uniform) + + ticker.mode.equip_syndicate(current) + + proc/make_Changling() + if(!(src in ticker.mode.changelings)) + ticker.mode.changelings += src + ticker.mode.grant_changeling_powers(current) + special_role = "Changeling" + ticker.mode.forge_changeling_objectives(src) + ticker.mode.greet_changeling(src) + + proc/make_Wizard() + if(!(src in ticker.mode.wizards)) + ticker.mode.wizards += src + special_role = "Wizard" + assigned_role = "MODE" + //ticker.mode.learn_basic_spells(current) + if(!wizardstart.len) + current.loc = pick(latejoin) + current << "HOT INSERTION, GO GO GO" + else + current.loc = pick(wizardstart) + + ticker.mode.equip_wizard(current) + for(var/obj/item/weapon/spellbook/S in current.contents) + S.op = 0 + ticker.mode.name_wizard(current) + ticker.mode.forge_wizard_objectives(src) + ticker.mode.greet_wizard(src) + + + proc/make_Cultist() + if(!(src in ticker.mode.cult)) + ticker.mode.cult += src + ticker.mode.update_cult_icons_added(src) + special_role = "Cultist" + current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." + current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." + var/datum/game_mode/cult/cult = ticker.mode + if (istype(cult)) + cult.memoize_cult_objectives(src) + else + var/explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it." + current << "Objective #1: [explanation]" + current.memory += "Objective #1: [explanation]
" + current << "The convert rune is join blood self" + current.memory += "The convert rune is join blood self
" + + var/mob/living/carbon/human/H = current + if (istype(H)) + var/obj/item/weapon/tome/T = new(H) + + var/list/slots = list ( + "backpack" = H.slot_in_backpack, + "left pocket" = H.slot_l_store, + "right pocket" = H.slot_r_store, + "left hand" = H.slot_l_hand, + "right hand" = H.slot_r_hand, + ) + var/where = H.equip_in_one_of_slots(T, slots) + if (!where) + else + H << "A tome, a message from your new master, appears in your [where]." + + if (!ticker.mode.equip_cultist(current)) + H << "Spawning an amulet from your Master failed." + + proc/make_Rev() + if (ticker.mode.head_revolutionaries.len>0) + // copy targets + var/datum/mind/valid_head = locate() in ticker.mode.head_revolutionaries + if (valid_head) + for (var/datum/objective/assassinate/O in valid_head.objectives) + var/datum/objective/assassinate/rev_obj = new + rev_obj.owner = src + rev_obj.target = O.target + rev_obj.explanation_text = "Assassinate [O.target.current.real_name], the [O.target.assigned_role]." + objectives += rev_obj + ticker.mode.greet_revolutionary(src,0) + ticker.mode.head_revolutionaries += src + ticker.mode.update_rev_icons_added(src) + special_role = "Head Revolutionary" + + ticker.mode.forge_revolutionary_objectives(src) + ticker.mode.greet_revolutionary(src,0) + + var/list/L = current.get_contents() + var/obj/item/device/flash/flash = locate() in L + del(flash) + take_uplink() + var/fail = 0 + // fail |= !ticker.mode.equip_traitor(current, 1) + fail |= !ticker.mode.equip_revolutionary(current) + + diff --git a/code/datums/shuttle_controller.dm b/code/datums/shuttle_controller.dm index 23a1f155cc..9fc5cc1991 100644 --- a/code/datums/shuttle_controller.dm +++ b/code/datums/shuttle_controller.dm @@ -5,14 +5,15 @@ // and the time before it leaves again #define SHUTTLEARRIVETIME 600 // 10 minutes = 600 seconds #define SHUTTLELEAVETIME 180 // 3 minutes = 180 seconds +#define SHUTTLETRANSITTIME 120 // 2 minutes = 120 seconds var/global/datum/shuttle_controller/emergency_shuttle/emergency_shuttle datum/shuttle_controller var - location = 0 //0 = somewhere far away, 1 = at SS13, 2 = returned from SS13 + location = 0 //0 = somewhere far away (in spess), 1 = at SS13, 2 = returned from SS13 online = 0 - direction = 1 //-1 = going back to central command, 1 = going back to SS13 + direction = 1 //-1 = going back to central command, 1 = going to SS13, 2 = in transit to centcom (not recalled) endtime // timeofday that shuttle arrives timelimit //important when the shuttle gets called for more than shuttlearrivetime @@ -46,9 +47,8 @@ datum/shuttle_controller if(direction == 1) var/timeleft = timeleft() if(timeleft >= 600) - world << "\blue Shuttle is at Centcom. Unable to recall." return - world << "\blue Alert: The shuttle is going back!" + captain_announce("The emergency shuttle has been recalled.") world << sound('shuttlerecalled.ogg') setdirection(-1) online = 1 @@ -64,7 +64,7 @@ datum/shuttle_controller proc/timeleft() if(online) var/timeleft = round((endtime - world.timeofday)/10 ,1) - if(direction == 1) + if(direction == 1 || direction == 2) return timeleft else return SHUTTLEARRIVETIME-timeleft @@ -102,6 +102,47 @@ datum/shuttle_controller // sound_siren = 1 switch(location) if(0) + + /* --- Shuttle is in transit to Central Command from SS13 --- */ + if(direction == 2) + if(timeleft>0) + return 0 + + /* --- Shuttle has arrived at Centrcal Command --- */ + else + // turn off the star spawners + /* + for(var/obj/effect/starspawner/S in world) + S.spawning = 0 + */ + + location = 2 + + //main shuttle + var/area/start_location = locate(/area/shuttle/escape/transit) + var/area/end_location = locate(/area/shuttle/escape/centcom) + + start_location.move_contents_to(end_location, null, NORTH) + + //pods + start_location = locate(/area/shuttle/escape_pod1/transit) + end_location = locate(/area/shuttle/escape_pod1/centcom) + start_location.move_contents_to(end_location, null, NORTH) + start_location = locate(/area/shuttle/escape_pod2/transit) + end_location = locate(/area/shuttle/escape_pod2/centcom) + start_location.move_contents_to(end_location, null, NORTH) + start_location = locate(/area/shuttle/escape_pod3/transit) + end_location = locate(/area/shuttle/escape_pod3/centcom) + start_location.move_contents_to(end_location, null, NORTH) + start_location = locate(/area/shuttle/escape_pod5/transit) + end_location = locate(/area/shuttle/escape_pod5/centcom) + start_location.move_contents_to(end_location, null, EAST) + + online = 0 + + return 1 + + /* --- Shuttle has docked centcom after being recalled --- */ if(timeleft>timelimit) online = 0 direction = 1 @@ -114,6 +155,7 @@ datum/shuttle_controller return 0 + /* --- Shuttle has docked with the station - begin countdown to transit --- */ else if(timeleft <= 0) location = 1 var/area/start_location = locate(/area/shuttle/escape/centcom) @@ -140,30 +182,152 @@ datum/shuttle_controller AM.throw_at(E, 1, 1) return */ + if(istype(T, /turf/simulated)) del(T) + for(var/mob/living/carbon/bug in end_location) // If someone somehow is still in the shuttle's docking area... + bug.gib() + start_location.move_contents_to(end_location) settimeleft(SHUTTLELEAVETIME) - world << "The Emergency Shuttle has docked with the station! You have [timeleft()/60] minutes to board the Emergency Shuttle." + captain_announce("The Emergency Shuttle has docked with the station. You have [timeleft()/60] minutes to board the Emergency Shuttle.") world << sound('shuttledock.ogg') return 1 if(1) + if(timeleft>0) return 0 + /* --- Shuttle leaves the station, enters transit --- */ else - departed = 1 - location = 2 - var/area/start_location = locate(/area/shuttle/escape/station) - var/area/end_location = locate(/area/shuttle/escape/centcom) - start_location.move_contents_to(end_location) - online = 0 + // Turn on the star effects + + /* // kinda buggy atm, i'll fix this later + for(var/obj/effect/starspawner/S in world) + if(!S.spawning) + spawn() S.startspawn() + */ + + departed = 1 // It's going! + location = 0 // in deep space + direction = 2 // heading to centcom + + //main shuttle + var/area/start_location = locate(/area/shuttle/escape/station) + var/area/end_location = locate(/area/shuttle/escape/transit) + + settimeleft(SHUTTLETRANSITTIME) + start_location.move_contents_to(end_location, null, NORTH) + + for(var/obj/machinery/door/D in world) + if( get_area(D) == end_location ) + spawn(0) + D.close() + + //pods + start_location = locate(/area/shuttle/escape_pod1/station) + end_location = locate(/area/shuttle/escape_pod1/transit) + start_location.move_contents_to(end_location, null, NORTH) + for(var/obj/machinery/door/D in world) + if( get_area(D) == end_location ) + spawn(0) + D.close() + + start_location = locate(/area/shuttle/escape_pod2/station) + end_location = locate(/area/shuttle/escape_pod2/transit) + start_location.move_contents_to(end_location, null, NORTH) + for(var/obj/machinery/door/D in world) + if( get_area(D) == end_location ) + spawn(0) + D.close() + + start_location = locate(/area/shuttle/escape_pod3/station) + end_location = locate(/area/shuttle/escape_pod3/transit) + start_location.move_contents_to(end_location, null, NORTH) + for(var/obj/machinery/door/D in world) + if( get_area(D) == end_location ) + spawn(0) + D.close() + + start_location = locate(/area/shuttle/escape_pod5/station) + end_location = locate(/area/shuttle/escape_pod5/transit) + start_location.move_contents_to(end_location, null, EAST) + for(var/obj/machinery/door/D in world) + if( get_area(D) == end_location ) + spawn(0) + D.close() + + + captain_announce("The Emergency Shuttle has left the station. Estimate [timeleft()/60] minutes until the shuttle docks at Central Command.") + + // Some aesthetic turbulance shaking + for(var/mob/M in end_location) + if(M.client) + spawn() + if(M.buckled) + shake_camera(M, 4, 1) // buckled, not a lot of shaking + else + shake_camera(M, 10, 2) // unbuckled, HOLY SHIT SHAKE THE ROOM return 1 else return 1 + + +/* + Some slapped-together star effects for maximum spess immershuns. Basically consists of a + spawner, an ender, and bgstar. Spawners create bgstars, bgstars shoot off into a direction + until they reach a starender. +*/ + +/obj/effect/bgstar + name = "star" + var/speed = 10 + var/direction = SOUTH + layer = 2 // TURF_LAYER + + New() + ..() + pixel_x += rand(-2,30) + pixel_y += rand(-2,30) + var/starnum = pick("1", "1", "1", "2", "3", "4") + + icon_state = "star"+starnum + + speed = rand(2, 5) + + proc/startmove() + + while(src) + sleep(speed) + step(src, direction) + for(var/obj/effect/starender/E in loc) + del(src) + + +/obj/effect/starender + invisibility = 101 + +/obj/effect/starspawner + invisibility = 101 + var/spawndir = SOUTH + var/spawning = 0 + + West + spawndir = WEST + + proc/startspawn() + spawning = 1 + while(spawning) + sleep(rand(2, 30)) + var/obj/effect/bgstar/S = new/obj/effect/bgstar(locate(x,y,z)) + S.direction = spawndir + spawn() + S.startmove() + + diff --git a/code/defines/area/Space Station 13 areas.dm b/code/defines/area/Space Station 13 areas.dm index 751c4b7ef8..37418038f3 100755 --- a/code/defines/area/Space Station 13 areas.dm +++ b/code/defines/area/Space Station 13 areas.dm @@ -383,6 +383,24 @@ proc/process_ghost_teleport_locs() icon_state = "cave" requires_power = 0 +/area/asteroid/artifactroom + name = "Asteroid - Artifact" + icon_state = "cave" + + + + + + + + + + + + + + + /area/planet/clown name = "Clown Planet" icon_state = "honk" @@ -441,6 +459,27 @@ proc/process_ghost_teleport_locs() icon_state = "yellow" requires_power = 0 + + +/area/borg_deathsquad + name = "Borg Deathsquad" + icon_state = "yellow" + requires_power = 0 + +/area/borg_deathsquad/start + name = "Borg Deathsquad - Ready" + + +/area/borg_deathsquad/station + name = "Borg Deathsquad - Arrived" + + + + + + + + //PRISON /area/prison/arrival_airlock @@ -1147,6 +1186,10 @@ proc/process_ghost_teleport_locs() name = "Server Room" icon_state = "server" +/area/toxins/supermatter + name = "Supermatter Laboratory" + icon_state = "supermatter" + //Storage /area/storage/tools diff --git a/code/defines/global.dm b/code/defines/global.dm index 1c52793d5e..1fa0b55e9f 100644 --- a/code/defines/global.dm +++ b/code/defines/global.dm @@ -12,7 +12,7 @@ var/global defer_powernet_rebuild = 0 // true if net rebuild will be called manually after an event -// list/global_map = null + //list/global_map = null //Borked, do not touch. DMTG //list/global_map = list(list(1,5),list(4,3))//an array of map Z levels. //Resulting sector map looks like //|_1_|_4_| diff --git a/code/defines/mob/living/carbon/alien_humanoid.dm b/code/defines/mob/living/carbon/alien_humanoid.dm index 4c6ae07fbe..87722cdbea 100644 --- a/code/defines/mob/living/carbon/alien_humanoid.dm +++ b/code/defines/mob/living/carbon/alien_humanoid.dm @@ -9,6 +9,7 @@ var/icon/stand_icon = null var/icon/lying_icon = null + var/icon/resting_icon = null var/last_b_state = 1.0 diff --git a/code/defines/mob/living/silicon/robot.dm b/code/defines/mob/living/silicon/robot.dm index a245fe4467..c65ae49038 100644 --- a/code/defines/mob/living/silicon/robot.dm +++ b/code/defines/mob/living/silicon/robot.dm @@ -53,5 +53,10 @@ var/weaponlock_time = 120 var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default var/lockcharge //Used when locking down a borg to preserve cell charge + var/speed = 0 //Cause sec borgs gotta go fast //No they dont! + var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them. var/channels = list() var/modlock = 0 + + var/lawcheck[1] //For stating laws! + var/ioncheck[1] \ No newline at end of file diff --git a/code/defines/obj.dm b/code/defines/obj.dm index 438a322193..292b3496ee 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -1481,6 +1481,7 @@ var/list/list3 = list() var/list/list4 = list() var/list/list5 = list() + var/list/list6 = list() var/var1 = null var/var2 = null diff --git a/code/defines/obj/computer.dm b/code/defines/obj/computer.dm index 5d2f6842a5..b49a1f36e7 100644 --- a/code/defines/obj/computer.dm +++ b/code/defines/obj/computer.dm @@ -22,54 +22,6 @@ var/blocked = 0 //Player cannot attack/heal while set -/obj/machinery/computer/aistatus - name = "AI Status Panel" - desc = "This shows the status of the AI." - icon = 'mainframe.dmi' - icon_state = "left" -// brightnessred = 0 -// brightnessgreen = 2 -// brightnessblue = 0 - -/obj/machinery/computer/aistatus/attack_hand(mob/user as mob) - if(stat & NOPOWER) - user << "\red The status panel has no power!" - return - if(stat & BROKEN) - user << "\red The status panel is broken!" - return - if(!issilicon(user)) - user << "\red You don't understand any of this!" - else - user << "\blue You know all of this already, why are you messing with it?" - return - -/obj/machinery/computer/aiupload - name = "AI Upload" - desc = "Used to upload laws to the AI." - icon_state = "command" - circuit = "/obj/item/weapon/circuitboard/aiupload" - var/mob/living/silicon/ai/current = null - var/opened = 0 - -/obj/machinery/computer/aiupload/mainframe - name = "AI Mainframe Upload" - icon = 'mainframe.dmi' - icon_state = "aimainframe" - -/obj/machinery/computer/borgupload - name = "Cyborg Upload" - desc = "Used to upload laws to Cyborgs." - icon_state = "command" - circuit = "/obj/item/weapon/circuitboard/borgupload" - var/mob/living/silicon/robot/current = null - -/obj/machinery/computer/borgupload/mainframe - name = "Borg Mainframe Upload" - icon = 'mainframe.dmi' - icon_state = "aimainframe" - - /obj/machinery/computer/station_alert name = "Station Alert Computer" desc = "Used to access the station's automated alert system." @@ -78,15 +30,6 @@ var/alarms = list("Fire"=list(), "Atmosphere"=list(), "Power"=list()) -/obj/machinery/computer/atmos_alert - name = "Atmospheric Alert Computer" - desc = "Used to access the station's atmospheric sensors." - icon_state = "alert:0" - var/list/priority_alarms = list() - var/list/minor_alarms = list() - var/receive_frequency = 1437 - - /obj/machinery/computer/atmosphere name = "atmos" desc = "A computer for Atmospherics." @@ -128,57 +71,6 @@ var/h_b = 245.0 -/obj/machinery/computer/med_data - name = "Medical Records" - desc = "This can be used to check medical records." - icon_state = "medcomp" - req_access = list(access_medical) - circuit = "/obj/item/weapon/circuitboard/med_data" - var/obj/item/weapon/card/id/scan = null - var/obj/item/weapon/disk/records/disk = null - var/authenticated = null - var/rank = null - var/screen = null - var/datum/data/record/active1 = null - var/datum/data/record/active2 = null - var/a_id = null - var/temp = null - var/printing = null - var/list/Perp - var/tempname = null - - -/obj/machinery/computer/med_data/laptop - name = "Medical Laptop" - desc = "Cheap Nanotrasen Laptop." - icon_state = "medlaptop" - - -/obj/machinery/computer/pod - name = "Pod Launch Control" - desc = "A control for launching pods." - icon_state = "computer_generic" - var/id = 1.0 - var/obj/machinery/mass_driver/connected = null - var/timing = 0.0 - var/time = 30.0 - - -/obj/machinery/computer/pod/old - icon_state = "old" - name = "DoorMex Control Computer" - - -/obj/machinery/computer/pod/old/syndicate - name = "ProComp Executive IIc" - desc = "The Syndicate operate on a tight budget. Operates external airlocks." - - -/obj/machinery/computer/pod/old/swf - name = "Magix System IV" - desc = "An arcane artifact that holds much magic. Running E-Knock 2.2: Sorceror's Edition" - - /obj/machinery/computer/secure_data name = "Security Records" desc = "Used to view and edit personnel's security records" @@ -290,23 +182,6 @@ circuit = "/obj/item/weapon/circuitboard/crew" var/list/tracked = list( ) - -/obj/machinery/computer/robotics - name = "Robotics Control" - desc = "Used to remotely lockdown or detonate linked Cyborgs." - icon = 'computer.dmi' - icon_state = "robot" - req_access = list(access_robotics) - circuit = "/obj/item/weapon/circuitboard/robotics" - - var/id = 0.0 - var/temp = null - var/status = 0 - var/timeleft = 60 - var/stop = 0.0 - var/screen = 0 // 0 - Main Menu, 1 - Cyborg Status, 2 - Kill 'em All! -- In text - - /*/obj/machinery/computer/scan_consolenew //Coming Soon, I highly doubt this but Ill leave it here anyways name = "DNA Modifier Access Console" desc = "Scand DNA." diff --git a/code/defines/obj/machinery.dm b/code/defines/obj/machinery.dm index a0870edcc5..8dcdfdeac0 100644 --- a/code/defines/obj/machinery.dm +++ b/code/defines/obj/machinery.dm @@ -365,29 +365,17 @@ var/lastgenlev = -1 /obj/machinery/power/monitor - name = "power monitoring computer" - desc = "It monitors power levels across the station, and can remotely toggle main breakers." - icon = 'computer.dmi' - icon_state = "power" - density = 1 - anchored = 1 - use_power = 2 - idle_power_usage = 20 - active_power_usage = 80 - var/control = 0 - req_access = list(access_engine_equip) - -/obj/machinery/cell_charger - name = "cell charger" - desc = "A charging unit for power cells." - icon = 'power.dmi' - icon_state = "ccharger0" - var/obj/item/weapon/cell/charging = null - var/chargelevel = -1 + name = "power monitoring computer" + desc = "It monitors power levels across the station, and can remotely toggle main breakers." + icon = 'computer.dmi' + icon_state = "power" + density = 1 anchored = 1 - use_power = 1 - idle_power_usage = 5 - active_power_usage = 60 + use_power = 2 + idle_power_usage = 20 + active_power_usage = 80 + var/control = 0 + req_access = list(access_engine_equip) /obj/machinery/light_switch name = "light switch" diff --git a/code/defines/obj/storage.dm b/code/defines/obj/storage.dm index 67459f8f93..a6f20a1ba6 100644 --- a/code/defines/obj/storage.dm +++ b/code/defines/obj/storage.dm @@ -657,3 +657,8 @@ name = "security satchel" desc = "A robust satchel for security related needs." icon_state = "satchel-sec" + +/obj/item/weapon/storage/backpack/satchel_hyd + name = "hydroponics satchel" + desc = "A green satchel for plant related work." + icon_state = "satchel_hyd" diff --git a/code/defines/obj/supplypacks.dm b/code/defines/obj/supplypacks.dm index cc1940219e..2db7cbc9fc 100755 --- a/code/defines/obj/supplypacks.dm +++ b/code/defines/obj/supplypacks.dm @@ -366,6 +366,7 @@ "/obj/item/weapon/plantbgone", "/obj/item/weapon/plantbgone", "/obj/item/weapon/plantbgone", + "/obj/item/weapon/hatchet", "/obj/item/weapon/minihoe", "/obj/item/device/analyzer/plant_analyzer", "/obj/item/clothing/gloves/botanic_leather", diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index e737c29cb4..67ae76a5e6 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -583,6 +583,10 @@ var/over_jumpsuit = 1 // If set to 0, it won't display on top of the mob's jumpsuit var/dorm = 0 // determines if this ID has claimed a dorm already + var/blood_type = "\[UNSET\]" + var/dna_hash = "\[UNSET\]" + var/fingerprint_hash = "\[UNSET\]" + /obj/item/weapon/card/id/silver name = "identification card" desc = "A silver card which shows honour and dedication." @@ -1015,10 +1019,6 @@ eternal248: Found broken and buggy Z-levels 7-12, ended up leading to my discove icon_state = "pen_red" text_color = "#FF0000" -/obj/item/weapon/pen/multi - desc = "It's a cool looking pen. Lots of colors!" - name = "multicolor pen" - /obj/item/weapon/pen/feather name = "feathery pen" desc = "A gold pen disguised as a quill. How quaint." diff --git a/code/defines/procs/AStar.dm b/code/defines/procs/AStar.dm index 988a3a2225..d106e8f64f 100644 --- a/code/defines/procs/AStar.dm +++ b/code/defines/procs/AStar.dm @@ -57,12 +57,12 @@ PriorityQueue j >>= 1 Dequeue() - ASSERT(L.len) + if(!L.len) return 0 . = L[1] Remove(1) Remove(i) - ASSERT(i <= L.len) + if(i > L.len) return 0 L.Swap(i,L.len) L.Cut(L.len) if(i < L.len) diff --git a/code/defines/procs/captain_announce.dm b/code/defines/procs/captain_announce.dm index 4ca0595937..9b91705ea5 100644 --- a/code/defines/procs/captain_announce.dm +++ b/code/defines/procs/captain_announce.dm @@ -1,6 +1,5 @@ /proc/captain_announce(var/text) - world << "

Captain Announces

" - + world << "

Priority Announcement

" world << "[html_encode(text)]" world << "
" diff --git a/code/defines/procs/gamehelpers.dm b/code/defines/procs/gamehelpers.dm index fcd244a61f..63d66d9e4d 100644 --- a/code/defines/procs/gamehelpers.dm +++ b/code/defines/procs/gamehelpers.dm @@ -48,6 +48,9 @@ return 1 else if (istype(user, /mob/living/carbon)) + if (usr.tkdisable != 0) //Remote Viewing + TK = oh god wat + user << "\red Your mind is too strained right now!" + return 0 if (user:mutations & TK) var/X = source:x var/Y = source:y diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm index 075cb3e415..994d08745e 100644 --- a/code/defines/procs/helpers.dm +++ b/code/defines/procs/helpers.dm @@ -229,6 +229,8 @@ return max(low,min(high,num)) /proc/dd_replacetext(text, search_string, replacement_string) + if(!text || !istext(text) || !search_string || !istext(search_string) || !istext(replacement_string)) + return null var/textList = dd_text2list(text, search_string) return dd_list2text(textList, replacement_string) @@ -264,7 +266,12 @@ var/list/textList = new() var/searchPosition = 1 var/findPosition = 1 + var/loops = 0 while(1) + if(loops >= 1000) + break + loops++ + findPosition = findtext(text, separator, searchPosition, 0) var/buggyText = copytext(text, searchPosition, findPosition) if(!withinList || (buggyText in withinList)) textList += "[buggyText]" @@ -652,7 +659,7 @@ Turf and target are seperate in case you want to teleport some distance from a t total = rand(1, total) for (item in L) - total -= L[item] + total -=L [item] if (total <= 0) return item @@ -817,9 +824,6 @@ Turf and target are seperate in case you want to teleport some distance from a t var/list/creatures = list() var/list/namecounts = list() for(var/mob/M in mobs) - /*if((!M.name || !M.real_name) && !istype(M, /mob/new_player)) - var/turf/T = get_turf(M) - message_admins("Alert! The mob with the key [M.key ? M.key : "NO KEY"] at ([T.x], [T.y], [T.z]) has no name!")*/ var/name = M.name if (name in names) namecounts[name]++ @@ -1006,8 +1010,8 @@ Turf and target are seperate in case you want to teleport some distance from a t output += A return output -// Returns the turf a movable atom (obj or mob) is on -/proc/get_turf_loc(var/atom/movable/M) +/proc/get_turf_loc(var/atom/movable/M) //gets the location of the turf that the atom is on, or what the atom is in is on, etc + //in case they're in a closet or sleeper or something var/atom/loc = M.loc while(!istype(loc, /turf/)) loc = loc.loc @@ -1018,6 +1022,8 @@ Turf and target are seperate in case you want to teleport some distance from a t /proc/get_edge_target_turf(var/atom/A, var/direction) var/turf/target = locate(A.x, A.y, A.z) + if(!A || !target) + return 0 //since NORTHEAST == NORTH & EAST, etc, doing it this way allows for diagonal mass drivers in the future //and isn't really any more complicated @@ -1304,13 +1310,16 @@ proc/listclearnulls(list/list) var/target_loc = target.loc var/holding = user.equipped() sleep(time) + if(!user || !target) return 0 if ( user.loc == user_loc && target.loc == target_loc && user.equipped() == holding && !( user.stat ) && ( !user.stunned && !user.weakened && !user.paralysis && !user.lying ) ) return 1 else return 0 - +/* /proc/do_after(mob/M as mob, time as num) - var/turf/T = get_turf(M) + if(!M) + return 0 + var/turf/T = M.loc var/holding = M.equipped() for(var/i=0, i -1000) + if(currentLayer <= -1000) return 0 if(pSet == 0) // Underlay currentLayer = A.layer+currentLayer/1000 else // Overlay diff --git a/code/defines/procs/time_stamp.dm b/code/defines/procs/time_stamp.dm index a7f8a7205b..f8e8fa82be 100644 --- a/code/defines/procs/time_stamp.dm +++ b/code/defines/procs/time_stamp.dm @@ -8,4 +8,17 @@ proc/time_stamp() if(hh < 10) ph = "0" if(mm < 10) pm = "0" if(ss < 10) ps = "0" - return"[ph][hh]:[pm][mm]:[ps][ss]" \ No newline at end of file + return"[ph][hh]:[pm][mm]:[ps][ss]" + + +/* Returns 1 if it is the selected month and day */ +proc/isDay(var/month, var/day) + if(isnum(month) && isnum(day)) + var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month + var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day + if(month == MM && day == DD) + return 1 + + // Uncomment this out when debugging! + //else + //return 1 diff --git a/code/defines/turf.dm b/code/defines/turf.dm index ccaeb00b60..cc12b3f315 100644 --- a/code/defines/turf.dm +++ b/code/defines/turf.dm @@ -44,10 +44,41 @@ thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT heat_capacity = 700000 + transit + + var/pushdirection // push things that get caught in the transit tile this direction + + north // moving to the north + + pushdirection = SOUTH + + one + icon_state = "1_south" // south because the space tile is scrolling south + two + icon_state = "2_south" + three + icon_state = "3_south" + + east // moving to the east + + pushdirection = WEST + + one + icon_state = "1_west" // space tile is scrolling west + two + icon_state = "2_west" + three + icon_state = "3_west" + + + + + /turf/space/New() // icon = 'space.dmi' - ..() - icon_state = "[rand(1,25)]" + if(!istype(src, /turf/space/transit)) + ..() + icon_state = "[rand(1,25)]" /turf/simulated name = "station" @@ -86,11 +117,18 @@ var/walltype = "wall" +/turf/simulated/wall/cult + name = "wall" + desc = "The patterns engraved on the wall seem to shift as you try to focus on them. You feel sick" + icon_state = "cult" + walltype = "cult" + /turf/simulated/shuttle name = "shuttle" icon = 'shuttle.dmi' thermal_conductivity = 0.05 heat_capacity = 0 + layer = 2.1 /turf/simulated/shuttle/wall name = "wall" @@ -136,13 +174,11 @@ if(!LinkBlocked(src, t) && !TurfBlockedNonWindow(t)) L.Add(t) return L - Distance(turf/t) if(get_dist(src,t) == 1) var/cost = (src.x - t.x) * (src.x - t.x) + (src.y - t.y) * (src.y - t.y) cost *= (pathweight+t.pathweight)/2 return cost - else return get_dist(src,t) diff --git a/code/game/asteroid/artifacts.dm b/code/game/asteroid/artifacts.dm new file mode 100644 index 0000000000..d4f6fe5e87 --- /dev/null +++ b/code/game/asteroid/artifacts.dm @@ -0,0 +1,231 @@ +var/global/list/space_surprises = list( /obj/item/clothing/mask/facehugger/angry =4, + // /obj/effect/critter/spesscarp =2, + /obj/effect/critter/spesscarp/elite =2, + // /obj/creature =0, + // /obj/item/weapon/rcd =0, + // /obj/item/weapon/rcd_ammo =0, + // /obj/item/weapon/spacecash =0, + // /obj/item/weapon/cloaking_device =1, + // /obj/item/weapon/gun/energy/teleport_gun =0, + // /obj/item/weapon/rubber_chicken =0, + /obj/item/weapon/melee/energy/sword/pirate =3, + /obj/structure/closet/syndicate/resources =2, + // /obj/machinery/wish_granter =1, // Okayyyy... Mayyyybe Kor is kinda sorta right. A little. Tiny bit. >.> + // /obj/item/clothing/glasses/thermal =2, // Could maybe be cool as its own rapid mode, sorta like wizard. Maybe. + // /obj/item/weapon/storage/box/stealth/ =2 + + // =11 + ) + +var/global/list/spawned_surprises = list() + + + + + + + +/obj/machinery/wish_granter + name = "Wish Granter" + desc = "You're not so sure about this, anymore..." + icon = 'device.dmi' + icon_state = "syndbeacon" + + anchored = 1 + density = 1 + + var + charges = 1 + insisting = 0 + +/obj/machinery/wish_granter/attack_hand(var/mob/user as mob) + usr.machine = src + + if(charges <= 0) + user << "The Wish Granter lies silent." + return + + else if(!istype(user, /mob/living/carbon/human)) + user << "You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's." + return + + else if(is_special_character(user)) + user << "Even to a heart as dark as yours, you know nothing good will come of this. Something instinctual makes you pull away." + + else if (!insisting) + user << "Your first touch makes the Wish Granter stir, listening to you. Are you really sure you want to do this?" + insisting++ + + else + user << "You speak. [pick("I want the station to disappear","Humanity is corrupt, mankind must be destroyed","I want to be rich", "I want to rule the world","I want immortality.")]. The Wish Granter answers." + user << "Your head pounds for a moment, before your vision clears. You are the avatar of the Wish Granter, and your power is LIMITLESS! And it's all yours. You need to make sure no one can take it from you. No one can know, first." + + charges-- + insisting = 0 + + if (!(user.mutations & HULK)) + user.mutations |= HULK + + if (!(user.mutations & LASER)) + user.mutations |= LASER + + if (!(user.mutations & XRAY)) + user.mutations |= XRAY + user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) + user.see_in_dark = 8 + user.see_invisible = 2 + + if (!(user.mutations & COLD_RESISTANCE)) + user.mutations |= COLD_RESISTANCE + + if (!(user.mutations & TK)) + user.mutations |= TK + + if(!(user.mutations & HEAL)) + user.mutations |= HEAL + + ticker.mode.traitors += user.mind + user.mind.special_role = "Avatar of the Wish Granter" + + var/datum/objective/silence/silence = new + silence.owner = user.mind + user.mind.objectives += silence + + var/obj_count = 1 + for(var/datum/objective/OBJ in user.mind.objectives) + user << "Objective #[obj_count]: [OBJ.explanation_text]" + obj_count++ + + world << "You have a very bad feeling about this." + + return + +/obj/item/weapon/storage/box/stealth/ + name = "Infiltration Gear" + desc = "An old box full of old equipment. It doesn't look like it was ever opened." + + +/obj/item/weapon/storage/box/stealth/New() + ..() + + new /obj/item/clothing/under/chameleon(src) + new /obj/item/clothing/mask/gas/voice(src) + new /obj/item/weapon/card/id/syndicate(src) + new /obj/item/clothing/shoes/syndigaloshes(src) + return + + +// Copied over from asteroid.dm +var/global/max_secret_rooms = 3 + +proc/make_mining_asteroid_secret(var/size = 5) + var/valid = 0 + var/turf/T = null + var/sanity = 0 + var/list/room = null + var/list/turfs = null + + + turfs = get_area_turfs(/area/mine/unexplored) + + if(!turfs.len) + return 0 + + while(!valid) + valid = 1 + sanity++ + if(sanity > 100) + return 0 + + T=pick(turfs) + if(!T) + return 0 + + var/list/surroundings = list() + + surroundings += range(7, locate(T.x,T.y,T.z)) + surroundings += range(7, locate(T.x+size,T.y,T.z)) + surroundings += range(7, locate(T.x,T.y+size,T.z)) + surroundings += range(7, locate(T.x+size,T.y+size,T.z)) + + if(locate(/area/mine/explored) in surroundings) // +5s are for view range + valid = 0 + continue + + if(locate(/turf/space) in surroundings) + valid = 0 + continue + + if(locate(/area/asteroid/artifactroom) in surroundings) + valid = 0 + continue + + if(locate(/turf/simulated/floor/plating/airless/asteroid) in surroundings) + valid = 0 + continue + + if(!T) + return 0 + + room = spawn_room(T,size,size,,,1) + + if(room) + T = pick(room["floors"]) + if(T) + var/surprise = null + valid = 0 + while(!valid) + surprise = pickweight(space_surprises) + if(surprise in spawned_surprises) + if(prob(20)) + valid++ + else + continue + else + valid++ + + spawned_surprises.Add(surprise) + new surprise(T) + + return 1 + +proc/spawn_room(var/atom/start_loc,var/x_size,var/y_size,var/wall,var/floor , var/clean = 0 , var/name) + var/list/room_turfs = list("walls"=list(),"floors"=list()) + + //world << "Room spawned at [start_loc.x],[start_loc.y],[start_loc.z]" + if(!wall) + wall = pick(/turf/simulated/wall/r_wall,/turf/simulated/wall,/obj/effect/alien/resin) + if(!floor) + floor = pick(/turf/simulated/floor,/turf/simulated/floor/engine) + + for(var/x = 0,x 100) + return 0 + + T=pick(turfs) + if(!T) + return 0 + + var/list/surroundings = list() + + surroundings += range(7, locate(T.x,T.y,T.z)) + surroundings += range(7, locate(T.x+size,T.y,T.z)) + surroundings += range(7, locate(T.x,T.y+size,T.z)) + surroundings += range(7, locate(T.x+size,T.y+size,T.z)) + + if(locate(/area/mine/explored) in surroundings) // +5s are for view range + valid = 0 + continue + + if(locate(/turf/space) in surroundings) + valid = 0 + continue + + if(locate(/area/asteroid/artifactroom) in surroundings) + valid = 0 + continue + + if(locate(/turf/simulated/floor/plating/airless/asteroid) in surroundings) + valid = 0 + continue + + if(!T) + return 0 + + room = spawn_room(T,size,size,,,1) + + if(room) + T = pick(room["floors"]) + if(T) + var/surprise = null + valid = 0 + while(!valid) + surprise = pickweight(space_surprises) + if(surprise in spawned_surprises) + if(prob(20)) + valid++ + else + continue + else + valid++ + + spawned_surprises.Add(surprise) + new surprise(T) + + return 1 + + diff --git a/code/game/atom_procs.dm b/code/game/atom_procs.dm index 563bee56c8..21236b1c9f 100644 --- a/code/game/atom_procs.dm +++ b/code/game/atom_procs.dm @@ -76,12 +76,13 @@ if (istype(W, /obj/item/device/detective_scanner)) for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) - O << text("\red [src] has been scanned by [user] with the [W]") + O << "\red [src] has been scanned by [user] with the [W]" else if (!( istype(W, /obj/item/weapon/grab) ) && !(istype(W, /obj/item/weapon/plastique)) &&!(istype(W, /obj/item/weapon/cleaner)) &&!(istype(W, /obj/item/weapon/chemsprayer)) &&!(istype(W, /obj/item/weapon/pepperspray)) && !(istype(W, /obj/item/weapon/plantbgone)) ) for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) - O << text("\red [] has been hit by [] with []", src, user, W) + O << "\red [src] has been hit by [user] with [W]" + return /atom/proc/add_hiddenprint(mob/living/M as mob) @@ -337,7 +338,7 @@ else T.icon = initial(icon) - if(blood_DNA && !blood_DNA.len) + if(blood_DNA && istype(blood_DNA, /list) && !blood_DNA.len) del(blood_DNA) if(src.fingerprints && src.fingerprints.len) var/done = 0 @@ -1069,8 +1070,8 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl src.Topic(nhref, params2list(nhref), src, 1) return - -/*/atom/proc/get_global_map_pos() +/* +/atom/proc/get_global_map_pos() if(!islist(global_map) || isemptylist(global_map)) return var/cur_x = null var/cur_y = null @@ -1084,8 +1085,8 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl if(cur_x && cur_y) return list("x"=cur_x,"y"=cur_y) else - return 0 */ - + return 0 +*/ //Don't touch this either. DMTG /atom/proc/checkpass(passflag) return pass_flags&passflag diff --git a/code/game/dna.dm b/code/game/dna.dm index 86830134bb..f5339294fa 100644 --- a/code/game/dna.dm +++ b/code/game/dna.dm @@ -166,16 +166,17 @@ /////////////////////////// DNA HELPER-PROCS /proc/getleftblocks(input,blocknumber,blocksize) var/string - string = copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) + if (blocknumber > 1) + string = copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) return string else return null /proc/getrightblocks(input,blocknumber,blocksize) var/string - string = copytext(input,blocksize*blocknumber+1) if (blocknumber < (length(input)/blocksize)) + string = copytext(input,blocksize*blocknumber+1,length(input)+1) return string else return null @@ -360,28 +361,28 @@ if (!M) return //mutations /* - TK =(1<<0) - COLD_RESISTANCE =(1<<1) - XRAY =(1<<2) - HULK =(1<<3) - CLUMSY =(1<<4) - //FAT =(1<<5) - HUSK =(1<<6) - LASER =(1<<7) - HEAL =(1<<8) - mNobreath =(1<<9) - mRemote =(1<<10) - mRegen =(1<<11) - mRun =(1<<12) - mRemotetalk =(1<<13) - mMorph =(1<<14) - mBlend =(1<<15) + TK =(1<<0) 1 + COLD_RESISTANCE =(1<<1) 2 + XRAY =(1<<2) 4 + HULK =(1<<3) 8 + CLUMSY =(1<<4) 16 + //FAT =(1<<5) 32 + HUSK =(1<<6) 64 + LASER =(1<<7) 128 + HEAL =(1<<8) 256 + mNobreath =(1<<9) 512 + mRemote =(1<<10) 1024 + mRegen =(1<<11) 2048 + mRun =(1<<12) 4096 + mRemotetalk =(1<<13) 8192 + mMorph =(1<<14) 16384 + mBlend =(1<<15) 32768 mutations2: - mHallucination =(1<<0) - mFingerprints =(1<<1) - mShock =(1<<2) - mSmallsize =(1<<3) + mHallucination =(1<<0) 1 + mFingerprints =(1<<1) 2 + mShock =(1<<2) 4 + mSmallsize =(1<<3) 8 */ //disabilities diff --git a/code/game/events/EventProcs/space_ninja.dm b/code/game/events/EventProcs/space_ninja.dm index 28bd1088c4..c600efd405 100644 --- a/code/game/events/EventProcs/space_ninja.dm +++ b/code/game/events/EventProcs/space_ninja.dm @@ -109,9 +109,9 @@ When I already created about 4 new objectives, this doesn't seem terribly import var/commando_list[] = list()//Commandos. //We want the ninja to appear only in certain modes. - var/acceptable_modes_list[] = list("traitor","revolution","cult","wizard","changeling","traitorchan","nuclear","malfunction","monkey") - if(!(current_mode.config_tag in acceptable_modes_list)) - return +// var/acceptable_modes_list[] = list("traitor","revolution","cult","wizard","changeling","traitorchan","nuclear","malfunction","monkey") // Commented out for both testing and ninjas +// if(!(current_mode.config_tag in acceptable_modes_list)) +// return /*No longer need to determine what mode it is since bad guys are basically universal. And there is now a mode with two types of bad guys.*/ @@ -187,7 +187,7 @@ Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective comp if(sent_strike_team&&side=="heel"&&antagonist_list.len)//If a strike team was sent, murder them all like a champ. for(current_mind in antagonist_list)//Search and destroy. Since we already have an antagonist list, they should appear there. - if(current_mind.special_role=="Death Commando") + if(current_mind && current_mind.special_role=="Death Commando") commando_list += current_mind if(commando_list.len)//If there are living commandos still in play. for(var/mob/living/carbon/human/commando in commando_list) @@ -230,8 +230,7 @@ In either case, it's a good idea to spawn the ninja with a semi-random set of ob objective_list -= 3 switch(pick(objective_list)) if(1)//kill - while (!isnull(current_mind) && hostile_targets.len) - current_mind = pick(hostile_targets) + current_mind = pick(hostile_targets) if(current_mind) var/datum/objective/assassinate/ninja_objective = new @@ -239,6 +238,9 @@ In either case, it's a good idea to spawn the ninja with a semi-random set of ob ninja_objective.find_target_by_role((current_mind.special_role ? current_mind.special_role : current_mind.assigned_role),(current_mind.special_role?1:0))//If they have a special role, use that instead to find em. ninja_mind.objectives += ninja_objective + else + i++ + hostile_targets -= current_mind//Remove them from the list. if(2)//Steal var/list/datum/objective/theft = GenerateTheft(ninja_mind.assigned_role,ninja_mind) @@ -247,26 +249,32 @@ In either case, it's a good idea to spawn the ninja with a semi-random set of ob objective_list -= 2 if(3)//Protect. Keeping people alive can be pretty difficult. - while (!isnull(current_mind) && friendly_targets.len) - current_mind = pick(friendly_targets) + current_mind = pick(friendly_targets) if(current_mind) + var/datum/objective/protection/ninja_objective = new ninja_objective.owner = ninja_mind ninja_objective.find_target_by_role((current_mind.special_role ? current_mind.special_role : current_mind.assigned_role),(current_mind.special_role?1:0)) ninja_mind.objectives += ninja_objective + else + i++ + friendly_targets -= current_mind if(4)//Debrain - while (!isnull(current_mind) && hostile_targets.len) - current_mind = pick(hostile_targets) + current_mind = pick(hostile_targets) if(current_mind) + var/datum/objective/debrain/ninja_objective = new ninja_objective.owner = ninja_mind ninja_objective.find_target_by_role((current_mind.special_role ? current_mind.special_role : current_mind.assigned_role),(current_mind.special_role?1:0)) ninja_mind.objectives += ninja_objective + else + i++ + hostile_targets -= current_mind//Remove them from the list. if(5)//Download research var/datum/objective/download/ninja_objective = new diff --git a/code/game/events/EventProcs/spacevines.dm b/code/game/events/EventProcs/spacevines.dm index 8f279d51f0..a53210ac88 100644 --- a/code/game/events/EventProcs/spacevines.dm +++ b/code/game/events/EventProcs/spacevines.dm @@ -26,7 +26,7 @@ if(/obj/item/weapon/kitchen/utensil/knife) del src if(/obj/item/weapon/scalpel) del src if(/obj/item/weapon/fireaxe) del src -// if(/obj/item/weapon/hatchet) del src + if(/obj/item/weapon/hatchet) del src if(/obj/item/weapon/melee/energy) del src //less effective weapons diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index bad30e598f..94d09b30f4 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -759,18 +759,18 @@ /client/proc/changeling_unstun() set category = "Changeling" - set name = "Epinephrine Sacs (25)" + set name = "Epinephrine Sacs (45)" set desc = "Removes all stuns" if(!usr.changeling) usr << "\red You're not a changeling, something's wrong!" return - if(usr.changeling.chem_charges < 25) + if(usr.changeling.chem_charges < 45) usr << "\red We don't have enough stored chemicals to do that!" return - usr.changeling.chem_charges -= 25 + usr.changeling.chem_charges -= 45 var/mob/living/carbon/human/C = usr diff --git a/code/game/gamemodes/changeling/modularchangling.dm b/code/game/gamemodes/changeling/modularchangling.dm index 5fd786729e..bb48441a34 100644 --- a/code/game/gamemodes/changeling/modularchangling.dm +++ b/code/game/gamemodes/changeling/modularchangling.dm @@ -61,7 +61,7 @@ var/list/obj/effect/proc_holder/power/powerinstances = list() /obj/effect/proc_holder/power/deaf_sting name = "Deaf Sting" - desc = "We silently sting a human, completely silencing them for a short time." + desc = "We silently sting a human, completely deafening them for a short time." genomecost = 1 allowduringlesserform = 1 @@ -71,7 +71,7 @@ var/list/obj/effect/proc_holder/power/powerinstances = list() /obj/effect/proc_holder/power/blind_sting name = "Blind Sting" - desc = "We silently sting a human, completely deafening them for a short time." + desc = "We silently sting a human, completely blinding them for a short time." genomecost = 2 allowduringlesserform = 1 diff --git a/code/game/gamemodes/epidemic/epidemic.dm b/code/game/gamemodes/epidemic/epidemic.dm index 25a66eaac2..6a94e65dd1 100644 --- a/code/game/gamemodes/epidemic/epidemic.dm +++ b/code/game/gamemodes/epidemic/epidemic.dm @@ -8,6 +8,12 @@ var/checkwin_counter =0 var/finished = 0 + var/cruiser_arrival + + var/virus_name = "" + + var/stage = 0 + /////////////////////////// //Announces the game type// /////////////////////////// @@ -31,6 +37,51 @@ return 1 +/datum/game_mode/epidemic/proc/cruiser_seconds() + return (cruiser_arrival - world.time) / 10 + +////////////////////// INTERCEPT //////////////////////// +/// OVERWRITE THE INTERCEPT WITH A QUARANTINE WARNING /// +///////////////////////////////////////////////////////// + +/datum/game_mode/epidemic/send_intercept() + var/intercepttext = "CONFIDENTIAL REPORT
" + virus_name = "X-[rand(1,99)]™" + intercepttext += "Warning: Pathogen [virus_name] has been detected on [station_name()].

" + intercepttext += "Code violet quarantine of [station_name()] put under immediate effect.
" + intercepttext += "Class [rand(2,5)] cruiser has been dispatched. ETA: [round(cruiser_seconds() / 60)] minutes.
" + intercepttext += "
Instructions
" + intercepttext += "* ELIMINATE THREAT WITH EXTREME PREJUDICE. [virus_name] IS HIGHLY CONTAGIOUS. INFECTED CREW MEMBERS MUST BE QUARANTINED IMMEDIATELY.
" + intercepttext += "* [station_name()] is under QUARANTINE. Any vessels outbound from [station_name()] will be tracked down and destroyed.
" + intercepttext += "* The existence of [virus_name] is highly confidential. To prevent a panic, only high-ranking staff members are authorized to know of its existence. Crew members that illegally obtained knowledge of [virus_name] are to be neutralized.
" + intercepttext += "* A cure is to be researched immediately, but NanoTrasen intellectual property must be respected. To prevent knowledge of [virus_name] from falling into unauthorized hands, all medical staff that work with the pathogen must be enhanced with a NanoTrasen loyality implant.
" + + + for (var/obj/machinery/computer/communications/comm in world) + if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) + var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) + intercept.name = "paper" + intercept.info = intercepttext + + comm.messagetitle.Add("Cent. Com. CONFIDENTIAL REPORT") + comm.messagetext.Add(intercepttext) + world << sound('commandreport.ogg') + +/datum/game_mode/epidemic/proc/announce_to_kill_crew() + var/intercepttext = "CONFIDENTIAL REPORT
" + intercepttext += "PATHOGEN [virus_name] IS STILL PRESENT ON [station_name()]. IN COMPLIANCE WITH NANOTRASEN LAWS FOR INTERSTELLAR SAFETY, EMERGENCY SAFETY MEASURES HAVE BEEN AUTHORIZED. ALL INFECTED CREW MEMBERS ON [station_name()] ARE TO BE NEUTRALIZED AND DISPOSED OF IN A MANNER THAT WILL DESTROY ALL TRACES OF THE PATHOGEN. FAILURE TO COMPLY WILL RESULT IN IMMEDIATE DESTRUCTION OF [station_name].
" + intercepttext += "CRUISER WILL ARRIVE IN [round(cruiser_seconds()/60)] MINUTES
" + + for (var/obj/machinery/computer/communications/comm in world) + if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) + var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) + intercept.name = "paper" + intercept.info = intercepttext + + comm.messagetitle.Add("Cent. Com. CONFIDENTIAL REPORT") + comm.messagetext.Add(intercepttext) + world << sound('commandreport.ogg') + /datum/game_mode/epidemic/post_setup() var/list/crew = list() @@ -39,7 +90,6 @@ if(crew.len < 2) world << "\red There aren't enough players for this mode!" - return var/datum/disease2/disease/lethal = new lethal.makerandom(1) @@ -62,18 +112,24 @@ continue H.virus2 = nonlethal.getcopy() + cruiser_arrival = world.time + (10 * 90 * 60) + stage = 1 + spawn (rand(waittime_l, waittime_h)) send_intercept() - spawn(10 * 60 * 30) - command_alert("Unknown pathogen detected in routine biological scans.", "Biohazard Alert") - spawn(300) - command_alert("Pathogen identified as level 7 biohazard. All crew, take precaution immediately. Avoid contact with other biological personnel when necessary. Initiate quarantine immediately.", "Biohazard Alert") ..() /datum/game_mode/epidemic/process() + if(stage == 1 && cruiser_seconds() < 60 * 30) + announce_to_kill_crew() + stage = 2 + else if(stage == 2 && cruiser_seconds() <= 0) + crew_lose() + stage = 3 + checkwin_counter++ if(checkwin_counter >= 20) if(!finished) @@ -106,6 +162,30 @@ else return 0 +/////////////////////////////////////////// +///Handle crew failure(station explodes)/// +/////////////////////////////////////////// +/datum/game_mode/epidemic/proc/crew_lose() + ticker.mode:explosion_in_progress = 1 + for(var/mob/M in world) + if(M.client) + M << 'Alarm.ogg' + world << "\blueIncoming missile detected.. Impact in 10.." + for (var/i=9 to 1 step -1) + sleep(10) + world << "\blue[i].." + sleep(10) + enter_allowed = 0 + for(var/mob/M in world) + if(M.client) + spawn(0) + M.client.station_explosion_cinematic() + sleep(110) + ticker.mode:station_was_nuked = 1 + ticker.mode:explosion_in_progress = 0 + return + + ////////////////////////////////////////////////////////////////////// //Announces the end of the game with all relavent information stated// ////////////////////////////////////////////////////////////////////// diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index b78bf6cae6..740e747748 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -61,7 +61,7 @@ Devices and Tools; /obj/item/weapon/syndie/c4explosive:4:Low Power Explosive Charge, with Detonator; /obj/item/device/powersink:5:Powersink (DANGER!); /obj/machinery/singularity_beacon/syndicate:7:Singularity Beacon (DANGER!); -/obj/item/weapon/circuitboard/teleporter:20:Teleporter Circuit Board; +/obj/item/weapon/circuitboard/teleporter:10:Teleporter Circuit Board; Whitespace:Seperator; Implants; /obj/item/weapon/storage/syndie_kit/imp_freedom:3:Freedom Implant; diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 3bed4357d8..dc2fe2e28c 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -117,9 +117,18 @@ var/datum/roundinfo/roundinfo = new() spawn() supply_ticker() // Added to kick-off the supply shuttle regenerating points -- TLE spawn(0) - while(1) - sleep(5000+rand(6000,10000)) - SpawnEvent() + while (1) + var/potential_sleep_time = 10000 + rand(10000, 20000) + for (var/mob/living/M in world) + if(!M.client) continue + if(M.client.inactivity > 10 * 60 * 10) continue + if(M.stat == 2) continue + + if (potential_sleep_time > 10000) + potential_sleep_time -= 600 + + sleep(potential_sleep_time) + SpawnEvent() //Start master_controller.process() spawn master_controller.process() diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index 0aacfc362c..5d92803d2f 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -1355,4 +1355,34 @@ datum captured_amount+=2 if(captured_amount 0) - var/obj/D = new /obj/item/weapon/disk/nuclear(pick(blobstart)) - message_admins("[src] has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") - log_game("[src] has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") + if(blobstart.len > 0) + var/obj/D = new /obj/item/weapon/disk/nuclear(pick(blobstart)) + message_admins("[src] has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") + log_game("[src] has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") ..() diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index bf996b30ee..75e608b8d7 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -33,7 +33,7 @@ /////////////////////////// /datum/game_mode/revolution/announce() world << "The current game mode is - Revolution!" - world << "Some crewmembers are attempting to start a revolution!
\nRevolutionaries - Kill the Captain, HoP, HoS, CE, RD and CMO. Convert other crewmembers (excluding the heads of staff, and security officers) to your cause by flashing them. Protect your leaders.
\nPersonnel - Protect the heads of staff. Kill the leaders of the revolution, and brainwash the other revolutionaries (by beating them in the head).
" + world << "Some crewmembers are attempting to start a revolution!
\nRevolutionaries - Kill the Captain, HoP, HoS, CE, RD and CMO. Convert other crewmembers (excluding the heads of staff, and security officers) to your cause by convincing and then flashing them. Protect your leaders.
\nPersonnel - Protect the heads of staff. Kill the leaders of the revolution, and brainwash the other revolutionaries (by beating them in the head).
" /////////////////////////////////////////////////////////////////////////////// @@ -139,7 +139,8 @@ if (!where) mob << "The Syndicate were unfortunately unable to get you a flash." else - mob << "The flash in your [where] will implant a memory engram to convert others to our cause." + mob << "The flash in your [where] can be used to mark a crew member as revolutionist. Use this only on those true to your cause, to ensure that everyone bearing the mark can be trusted." + mob << "\red Do not use the flash on players who haven't agreed to join your cause. This is known as 'LOLFLASHING' and can get you banned." return 1 ////////////////////////////////////// diff --git a/code/game/hud.dm b/code/game/hud.dm index 1b4c2fae2d..4d60c7d50a 100644 --- a/code/game/hud.dm +++ b/code/game/hud.dm @@ -87,7 +87,7 @@ obj/hud/New(var/type = 0) /obj/hud/proc/instantiate(var/type = 0) mymob = loc - ASSERT(istype(mymob, /mob)) + if(!istype(mymob, /mob)) return 0 if(ishuman(mymob)) human_hud(mymob.UI) // Pass the player the UI style chosen in preferences diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index c37c7937b9..934acd653d 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -148,7 +148,7 @@ if(req in I.access) //has an access from the single access list return 1 for(var/req in src.req_access) - if(!(req in I.access)) //doesn't have this access + if(!(req in I.access)) //doesn't have this access - Leave like this DMTG return 0 return 1 @@ -164,7 +164,7 @@ if(req in L) //has an access from the single access list return 1 for(var/req in src.req_access) - if(!(req in L)) //doesn't have this access + if(!(req in L)) //doesn't have this access - Leave like this DMTG return 0 return 1 @@ -188,7 +188,7 @@ if("Librarian") // -- TLE return list(access_library) if("Lawyer") //Muskets 160910 - return list(access_maint_tunnels, access_lawyer, access_court) + return list(access_lawyer, access_court) if("Captain") return get_all_accesses() if("Security Officer") @@ -219,9 +219,9 @@ if("Janitor") return list(access_janitor, access_maint_tunnels) if("Clown") - return list(access_maint_tunnels, access_clown, access_theatre) + return list(access_clown, access_theatre) if("Mime") - return list(access_maint_tunnels, access_mime, access_theatre) + return list(access_mime, access_theatre) if("Chef") return list(access_kitchen) if("Roboticist") @@ -229,7 +229,7 @@ if("Cargo Technician") return list(access_maint_tunnels, access_cargo, access_cargo_bot, access_mailsorting) if("Shaft Miner") - return list(access_maint_tunnels, access_mining, access_mint, access_mining_station) + return list(access_mining, access_mint, access_mining_station) if("Quartermaster") return list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining) if("Chief Engineer") @@ -239,7 +239,7 @@ access_mint, access_ce, access_RC_announce, access_keycard_auth, access_tcomsat) if("Research Director") return list(access_medlab, access_rd, - access_maint_tunnels, access_heads, access_tox, + access_heads, access_tox, access_tox_storage, access_chemistry, access_teleporter, access_research, access_robotics, access_xenobiology, access_RC_announce, access_keycard_auth, access_tcomsat) diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index aa294a16ce..8e2e98b362 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -71,6 +71,9 @@ equip(var/mob/living/carbon/human/H) if(!H) return 0 + if(H.backbag == 2) H.equip_if_possible(new /obj/item/weapon/storage/backpack(H), H.slot_back) + if(H.backbag == 3) H.equip_if_possible(new /obj/item/weapon/storage/backpack/satchel(H), H.slot_back) + if(H.backbag == 4) H.equip_if_possible(new /obj/item/weapon/storage/backpack/satchel_hyd(H), H.slot_back) H.equip_if_possible(new /obj/item/clothing/under/rank/hydroponics(H), H.slot_w_uniform) H.equip_if_possible(new /obj/item/clothing/shoes/black(H), H.slot_shoes) H.equip_if_possible(new /obj/item/clothing/gloves/botanic_leather(H), H.slot_gloves) diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 46502b1e55..865baeee72 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -232,7 +232,7 @@ var/global/datum/controller/occupations/job_master H.mind.assigned_role = rank H.mind.role_alt_title = null - if(!joined_late && rank != "Tourist") + if(!joined_late) var/obj/S = null for(var/obj/effect/landmark/start/sloc in world) if(sloc.name != rank) continue @@ -258,18 +258,18 @@ var/global/datum/controller/occupations/job_master if(H.backbag == 2) var/obj/item/weapon/storage/backpack/BPK = new/obj/item/weapon/storage/backpack(H) - new /obj/item/weapon/storage/box(BPK) H.equip_if_possible(BPK, H.slot_back,1) + H.equip_if_possible(new /obj/item/weapon/storage/box(H.back), H.slot_in_backpack) if(H.backbag == 3) var/obj/item/weapon/storage/backpack/BPK = new/obj/item/weapon/storage/backpack/satchel(H) - new /obj/item/weapon/storage/box(BPK) H.equip_if_possible(BPK, H.slot_back,1) + H.equip_if_possible(new /obj/item/weapon/storage/box(H.back), H.slot_in_backpack) if(H.backbag == 4) var/obj/item/weapon/storage/backpack/BPK = new/obj/item/weapon/storage/backpack/satchel_norm(H) - new /obj/item/weapon/storage/box(BPK) H.equip_if_possible(BPK, H.slot_back,1) + H.equip_if_possible(new /obj/item/weapon/storage/box(H.back), H.slot_in_backpack) //Give'em glasses if they are nearsighted if(H.disabilities & 1) diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 5138b3ec00..0a90829e14 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -591,12 +591,12 @@ Temperature: [environment.temperature] output += {" Scrubbers Control
Vents Control
-Set envirenomentals mode
-Sensor Control
+Set environmentals mode
+Sensor Settings

"} if (mode==AALARM_MODE_PANIC) - output += "PANIC SYPHON ACTIVE
turn syphoning off" + output += "PANIC SYPHON ACTIVE
Turn syphoning off" else output += "ACTIVATE PANIC SYPHON IN AREA" if (AALARM_SCREEN_VENT) @@ -605,12 +605,10 @@ Temperature: [environment.temperature] 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] - var/state = "" if(!data) - state = " can not be found!" - data = list("external" = 0) //for "0" instead of empty string - else if (data["timestamp"]+AALARM_REPORT_TIMEOUT < world.time) - state = " not responding!" + continue; + var/state = "" + sensor_data += {" [long_name][state]
Operating: @@ -630,6 +628,7 @@ Temperature: [environment.temperature] + + + + (reset)
"} if (data["direction"] == "siphon") @@ -648,12 +647,9 @@ siphoning 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] - var/state = "" if(!data) - state = " can not be found!" - data = list("external" = 0) //for "0" instead of empty string - else if (data["timestamp"]+AALARM_REPORT_TIMEOUT < world.time) - state = " not responding!" + continue; + var/state = "" sensor_data += {" [long_name][state]
@@ -787,6 +783,7 @@ table tr:first-child th:first-child { border: none;} if( "power", "adjust_external_pressure", + "set_external_pressure", "checks", "co2_scrub", "tox_scrub", @@ -797,6 +794,7 @@ table tr:first-child th:first-child { border: none;} send_signal(device_id, list (href_list["command"] = text2num(href_list["val"]))) spawn(3) src.updateUsrDialog() + //if("adjust_threshold") //was a good idea but required very wide window if("set_threshold") var/env = href_list["env"] @@ -843,6 +841,7 @@ table tr:first-child th:first-child { border: none;} apply_mode() spawn(5) src.updateUsrDialog() + return /obj/machinery/alarm/proc/apply_mode() @@ -888,15 +887,15 @@ table tr:first-child th:first-child { border: none;} send_signal(device_id, list( "power"= 0 )) - if(AALARM_MODE_OFF) + /*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( - "power"= 0 + "panic_siphon" = 0 )) for(var/device_id in alarm_area.air_vent_names) send_signal(device_id, list( - "power"= 0 - )) + "power"= 1 + ))*/ /obj/machinery/alarm/update_icon() if(wiresexposed) diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index 864d6e451c..e0274cf54d 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -93,7 +93,6 @@ obj/machinery/computer/general_air_control process() ..() - src.updateDialog() attackby(I as obj, user as mob) @@ -442,94 +441,6 @@ Rate: [volume_rate] L/sec
"} radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) -/obj/machinery/computer/atmos_alert - var/datum/radio_frequency/radio_connection -/obj/machinery/computer/atmos_alert/initialize() - set_frequency(receive_frequency) -/obj/machinery/computer/atmos_alert/receive_signal(datum/signal/signal) - if(!signal || signal.encryption) return - var/zone = signal.data["zone"] - var/severity = signal.data["alert"] - - if(!zone || !severity) return - - minor_alarms -= zone - priority_alarms -= zone - if(severity=="severe") - priority_alarms += zone - else if (severity=="minor") - minor_alarms += zone - /*else "clear"*/ - //do nothing - update_icon() - -/obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, receive_frequency) - receive_frequency = new_frequency - radio_connection = radio_controller.add_object(src, receive_frequency, RADIO_ATMOSIA) - -/obj/machinery/computer/atmos_alert/attack_hand(mob/user) - user << browse(return_text(),"window=computer") - user.machine = src - onclose(user, "computer") - -/obj/machinery/computer/atmos_alert/process() - ..() - src.updateDialog() - -/obj/machinery/computer/atmos_alert/update_icon() - if(priority_alarms.len) - icon_state = "alert:2" - - else if(minor_alarms.len) - icon_state = "alert:1" - - else - icon_state = "alert:0" - -/obj/machinery/computer/atmos_alert/proc/return_text() - var/priority_text - var/minor_text - - if(priority_alarms.len) - for(var/zone in priority_alarms) - priority_text += "[zone] X
" - else - priority_text = "No priority alerts detected.
" - - if(minor_alarms.len) - for(var/zone in minor_alarms) - minor_text += "[zone] X
" - else - minor_text = "No minor alerts detected.
" - - var/output = {"[name]
-Priority Alerts:
-[priority_text] -
-
-Minor Alerts:
-[minor_text] -
"} - - return output - -/obj/machinery/computer/atmos_alert/Topic(href, href_list) - if(..()) - return - - if(href_list["priority_clear"]) - var/removing_zone = href_list["priority_clear"] - for(var/zone in priority_alarms) - if(ckey(zone) == removing_zone) - priority_alarms -= zone - - if(href_list["minor_clear"]) - var/removing_zone = href_list["minor_clear"] - for(var/zone in minor_alarms) - if(ckey(zone) == removing_zone) - minor_alarms -= zone - update_icon() \ No newline at end of file diff --git a/code/game/machinery/atmoalter/zvent.dm b/code/game/machinery/atmoalter/zvent.dm index 5831e9d6a8..0cf390d879 100644 --- a/code/game/machinery/atmoalter/zvent.dm +++ b/code/game/machinery/atmoalter/zvent.dm @@ -10,7 +10,6 @@ var/volume_rate = 800 /obj/machinery/zvent/process() - ..() //all this object does, is make its turf share air with the ones above and below it, if they have a vent too. if (istype(loc,/turf/simulated)) //if we're not on a valid turf, forget it diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index dcafa06665..9802c771fb 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -1,274 +1,3 @@ -/obj/machinery/autolathe - var/busy = 0 - var/max_m_amount = 150000.0 - var/max_g_amount = 75000.0 - var/outputAmount = 1 - var/makeDir = 0 - -/obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob) - if (stat) - return 1 - if(istype(O,/obj/item/weapon/storage/)) - usr.before_take_item(O) - O.loc = src - user << "\blue You insert the \icon[O] [O.name] into the autolathe!" - return 0 - if (busy) - user << "\red The autolathe is busy. Please wait for completion of previous operation." - return 1 - if (istype(O, /obj/item/weapon/screwdriver)) - if (!opened) - src.opened = 1 - src.icon_state = "autolathe_t" - user << "You open the maintenance hatch of [src]." - else - src.opened = 0 - src.icon_state = "autolathe" - user << "You close the maintenance hatch of [src]." - return 1 - if (opened) - if(istype(O, /obj/item/weapon/crowbar)) - playsound(src.loc, 'Crowbar.ogg', 50, 1) - var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc) - M.state = 2 - M.icon_state = "box_1" - for(var/obj/I in component_parts) - if(I.reliability != 100 && crit_fail) - I.crit_fail = 1 - I.loc = src.loc - if(m_amount >= 3750) - var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(src.loc) - G.amount = round(m_amount / 3750) - if(g_amount >= 3750) - var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc) - G.amount = round(g_amount / 3750) - del(src) - return 1 - else - user << "\red You can't load the autolathe while it's opened." - return 1 - if (src.m_amount + O.m_amt > max_m_amount) - user << "\red The autolathe is full. Please remove metal from the autolathe in order to insert more." - return 1 - if (src.g_amount + O.g_amt > max_g_amount) - user << "\red The autolathe is full. Please remove glass from the autolathe in order to insert more." - return 1 - if (O.m_amt == 0 && O.g_amt == 0) - user << "\red This object does not contain significant amounts of metal or glass, or cannot be accepted by the autolathe due to size or hazardous materials." - return 1 -/* - if (istype(O, /obj/item/weapon/grab) && src.hacked) - var/obj/item/weapon/grab/G = O - if (prob(25) && G.affecting) - G.affecting.gib() - m_amount += 50000 - return -*/ - - var/amount = 1 - var/obj/item/stack/stack - var/m_amt = O.m_amt - var/g_amt = O.g_amt - if (istype(O, /obj/item/stack)) - stack = O - amount = stack.amount - if (m_amt) - amount = min(amount, round((max_m_amount-src.m_amount)/m_amt)) - flick("autolathe_o",src)//plays metal insertion animation - if (g_amt) - amount = min(amount, round((max_g_amount-src.g_amount)/g_amt)) - flick("autolathe_r",src)//plays glass insertion animation - stack.use(amount) - else - usr.before_take_item(O) - flick("autolathe_o",src)//plays metal insertion animation - O.loc = src - icon_state = "autolathe" - busy = 1 - use_power(max(1000, (m_amt+g_amt)*amount/10)) - spawn(16) - icon_state = "autolathe" - src.m_amount += m_amt * amount - src.g_amount += g_amt * amount - if (O && O.loc == src) - del(O) - busy = 0 - src.updateUsrDialog() - -/obj/machinery/autolathe/attack_paw(mob/user as mob) - return src.attack_hand(user) - -/obj/machinery/autolathe/attack_hand(mob/user as mob) - user.machine = src - interact(user) - -/obj/machinery/autolathe/proc/wires_win(mob/user as mob) - var/dat as text - dat += "Autolathe Wires:
" - for(var/wire in src.wires) - dat += text("[wire] Wire: [src.wires[wire] ? "Mend" : "Cut"] Pulse
") - - dat += text("The red light is [src.disabled ? "off" : "on"].
") - dat += text("The green light is [src.shocked ? "off" : "on"].
") - dat += text("The blue light is [src.hacked ? "off" : "on"].
") - user << browse("Autolathe Hacking[dat]","window=autolathe_hack") - onclose(user, "autolathe_hack") - -/obj/machinery/autolathe/proc/regular_win(mob/user as mob) - var/dat as text - dat = text("Metal Amount: [src.m_amount] cm3 (MAX: [max_m_amount])
\nGlass Amount: [src.g_amount] cm3 (MAX: [max_g_amount])
") - dat += "Output Queue: [outputAmount] (Modify)" - dat += "
" - var/list/heldContainers = list() - for(var/obj/item/weapon/storage/container in src.contents) - heldContainers += container - if(heldContainers.len) - for(var/obj/item/weapon/storage/container in heldContainers) - dat += "[container.name] (eject stored container)
" - else - dat += "No held storage containers" - dat += "
" - var/list/objs = list() - objs += src.L - if (src.hacked) - objs += src.LL - for(var/obj/t in objs) - var/title = "[t.name] ([t.m_amt] m /[t.g_amt] g)" - if (m_amount" - continue - dat += "[title]" - if (istype(t, /obj/item/stack)) - var/obj/item/stack/S = t - var/max_multiplier = min(S.max_amount, S.m_amt?round(m_amount/S.m_amt):INFINITY, S.g_amt?round(g_amount/S.g_amt):INFINITY) - if (max_multiplier>1) - dat += " |" - if (max_multiplier>10) - dat += " x[10]" - if (max_multiplier>25) - dat += " x[25]" - if (max_multiplier>1) - dat += " x[max_multiplier]" - dat += "
" - user << browse("Autolathe Control Panel[dat]", "window=autolathe_regular") - onclose(user, "autolathe_regular") - -/obj/machinery/autolathe/proc/interact(mob/user as mob) - if(..()) - return - if (src.shocked) - src.shock(user,50) - if (src.opened) - wires_win(user,50) - return - if (src.disabled) - user << "\red You press the button, but nothing happens." - return - regular_win(user) - return - -/obj/machinery/autolathe/Topic(href, href_list) - if(..()) - return - usr.machine = src - src.add_fingerprint(usr) - if(href_list["removeContainer"]) - var/obj/item/weapon/storage/container = locate(href_list["removeContainer"]) - container.loc = src.loc - container.layer = initial(container.layer) - if(href_list["modifyOutputAmount"]) - outputAmount = text2num(input(usr,"Amount:","Enter new quantity to create","")) - if(!busy) - if(outputAmount < 1) - outputAmount = 1 - else - usr << "\red The autolathe is busy. Please wait for completion of previous operation." - if (!busy) - if(href_list["make"]) - var/turf/T = src.loc - var/obj/template = locate(href_list["make"]) - var/multiplier = text2num(href_list["multiplier"]) - if (!multiplier) multiplier = 1 - var/power = max(2000, (template.m_amt+template.g_amt)*multiplier/5) - restart: - if(outputAmount > 0) - if( (src.m_amount >= template.m_amt*multiplier) && (src.g_amount >= template.g_amt*multiplier) ) - use_power(power) - icon_state = "autolathe" - flick("autolathe_n",src) - spawn(16) - if(!busy) - busy = 1 - use_power(power) - flick("autolathe_n",src) - spawn(16) - use_power(power) - flick("autolathe_n",src) - spawn(16) - flick("autolathe_n",src) - src.m_amount -= template.m_amt*multiplier - src.g_amount -= template.g_amt*multiplier - if(src.m_amount < 0) - src.m_amount = 0 - if(src.g_amount < 0) - src.g_amount = 0 - var/obj/new_item = new template.type(src) - for(var/obj/item/weapon/storage/container in src.contents) - container.attackby(new_item) - if(new_item.loc == container) - break - if (multiplier>1) - var/obj/item/stack/S = new_item - S.amount = multiplier - if(new_item in src) - new_item.loc = T - src.updateUsrDialog() - outputAmount -= 1 - busy = 0 - goto restart - else - for(var/mob/M in view(3,src)) - M << "\red\icon[src] has run out of materials." - else - outputAmount = 1 - if(href_list["act"]) - var/temp_wire = href_list["wire"] - if(href_list["act"] == "pulse") - if (!istype(usr.equipped(), /obj/item/device/multitool)) - usr << "You need a multitool!" - else - if(src.wires[temp_wire]) - usr << "You can't pulse a cut wire." - else - if(src.hack_wire == temp_wire) - src.hacked = !src.hacked - spawn(100) src.hacked = !src.hacked - if(src.disable_wire == temp_wire) - src.disabled = !src.disabled - src.shock(usr,50) - spawn(100) src.disabled = !src.disabled - if(src.shock_wire == temp_wire) - src.shocked = !src.shocked - src.shock(usr,50) - spawn(100) src.shocked = !src.shocked - if(href_list["act"] == "wire") - if (!istype(usr.equipped(), /obj/item/weapon/wirecutters)) - usr << "You need wirecutters!" - else - wires[temp_wire] = !wires[temp_wire] - if(src.hack_wire == temp_wire) - src.hacked = !src.hacked - if(src.disable_wire == temp_wire) - src.disabled = !src.disabled - src.shock(usr,50) - if(src.shock_wire == temp_wire) - src.shocked = !src.shocked - src.shock(usr,50) - else - usr << "\red The autolathe is busy. Please wait for completion of previous operation." - src.updateUsrDialog() - return - var/global/list/autolathe_recipes = list( \ /* screwdriver removed*/ \ new /obj/item/weapon/reagent_containers/glass/bucket(), \ @@ -322,55 +51,330 @@ var/global/list/autolathe_recipes_hidden = list( \ /* new /obj/item/weapon/shield/riot(), */ \ ) -/obj/machinery/autolathe/RefreshParts() - ..() - var/tot_rating = 0 - for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts) - tot_rating += MB.rating - tot_rating *= 25000 - max_m_amount = tot_rating * 2 - max_g_amount = tot_rating +/obj/machinery/autolathe + var + busy = 0 + max_m_amount = 150000.0 + max_g_amount = 75000.0 + outputAmount = 1 + makeDir = 0 + + proc + wires_win(mob/user as mob) + var/dat as text + dat += "Autolathe Wires:
" + for(var/wire in src.wires) + dat += text("[wire] Wire: [src.wires[wire] ? "Mend" : "Cut"] Pulse
") + + dat += text("The red light is [src.disabled ? "off" : "on"].
") + dat += text("The green light is [src.shocked ? "off" : "on"].
") + dat += text("The blue light is [src.hacked ? "off" : "on"].
") + user << browse("Autolathe Hacking[dat]","window=autolathe_hack") + onclose(user, "autolathe_hack") + + regular_win(mob/user as mob) + var/dat as text + dat = text("Metal Amount: [src.m_amount] cm3 (MAX: [max_m_amount])
\nGlass Amount: [src.g_amount] cm3 (MAX: [max_g_amount])
") + dat += "Output Queue: [outputAmount] (Modify)" + dat += "
" + var/list/heldContainers = list() + for(var/obj/item/weapon/storage/container in src.contents) + heldContainers += container + if(heldContainers.len) + for(var/obj/item/weapon/storage/container in heldContainers) + dat += "[container.name] (eject stored container)
" + else + dat += "No held storage containers" + dat += "
" + var/list/objs = list() + objs += src.L + if (src.hacked) + objs += src.LL + for(var/obj/t in objs) + var/title = "[t.name] ([t.m_amt] m /[t.g_amt] g)" + if (m_amount" + continue + dat += "[title]" + if (istype(t, /obj/item/stack)) + var/obj/item/stack/S = t + var/max_multiplier = min(S.max_amount, S.m_amt?round(m_amount/S.m_amt):INFINITY, S.g_amt?round(g_amount/S.g_amt):INFINITY) + if (max_multiplier>1) + dat += " |" + if (max_multiplier>10) + dat += " x[10]" + if (max_multiplier>25) + dat += " x[25]" + if (max_multiplier>1) + dat += " x[max_multiplier]" + dat += "
" + user << browse("Autolathe Control Panel[dat]", "window=autolathe_regular") + onclose(user, "autolathe_regular") + + interact(mob/user as mob) + if(..()) + return + if (src.shocked) + src.shock(user,50) + if (src.opened) + wires_win(user,50) + return + if (src.disabled) + user << "\red You press the button, but nothing happens." + return + regular_win(user) + return + + shock(mob/user, prb) + if(stat & (BROKEN|NOPOWER)) // unpowered, no shock + return 0 + if(!prob(prb)) + return 0 + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + if (electrocute_mob(user, get_area(src), src, 0.7)) + return 1 + else + return 0 + + attackby(var/obj/item/O as obj, var/mob/user as mob) + if (stat) + return 1 + if(istype(O,/obj/item/weapon/storage/)) + usr.before_take_item(O) + O.loc = src + user << "\blue You insert the \icon[O] [O.name] into the autolathe!" + return 0 + if (busy) + user << "\red The autolathe is busy. Please wait for completion of previous operation." + return 1 + if (istype(O, /obj/item/weapon/screwdriver)) + if (!opened) + src.opened = 1 + src.icon_state = "autolathe_t" + user << "You open the maintenance hatch of [src]." + else + src.opened = 0 + src.icon_state = "autolathe" + user << "You close the maintenance hatch of [src]." + return 1 + if (opened) + if(istype(O, /obj/item/weapon/crowbar)) + playsound(src.loc, 'Crowbar.ogg', 50, 1) + var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc) + M.state = 2 + M.icon_state = "box_1" + for(var/obj/I in component_parts) + if(I.reliability != 100 && crit_fail) + I.crit_fail = 1 + I.loc = src.loc + if(m_amount >= 3750) + var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(src.loc) + G.amount = round(m_amount / 3750) + if(g_amount >= 3750) + var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc) + G.amount = round(g_amount / 3750) + del(src) + return 1 + else + user.machine = src + interact(user) + return 1 + + if (src.m_amount + O.m_amt > max_m_amount) + user << "\red The autolathe is full. Please remove metal from the autolathe in order to insert more." + return 1 + if (src.g_amount + O.g_amt > max_g_amount) + user << "\red The autolathe is full. Please remove glass from the autolathe in order to insert more." + return 1 + if (O.m_amt == 0 && O.g_amt == 0) + user << "\red This object does not contain significant amounts of metal or glass, or cannot be accepted by the autolathe due to size or hazardous materials." + return 1 + /* + if (istype(O, /obj/item/weapon/grab) && src.hacked) + var/obj/item/weapon/grab/G = O + if (prob(25) && G.affecting) + G.affecting.gib() + m_amount += 50000 + return + */ + + var/amount = 1 + var/obj/item/stack/stack + var/m_amt = O.m_amt + var/g_amt = O.g_amt + if (istype(O, /obj/item/stack)) + stack = O + amount = stack.amount + if (m_amt) + amount = min(amount, round((max_m_amount-src.m_amount)/m_amt)) + flick("autolathe_o",src)//plays metal insertion animation + if (g_amt) + amount = min(amount, round((max_g_amount-src.g_amount)/g_amt)) + flick("autolathe_r",src)//plays glass insertion animation + stack.use(amount) + else + usr.before_take_item(O) + O.loc = src + icon_state = "autolathe" + busy = 1 + use_power(max(1000, (m_amt+g_amt)*amount/10)) + src.m_amount += m_amt * amount + src.g_amount += g_amt * amount + user << "You insert [amount] sheet[amount>1 ? "s" : ""] to the autolathe." + if (O && O.loc == src) + del(O) + busy = 0 + src.updateUsrDialog() + + attack_paw(mob/user as mob) + return src.attack_hand(user) + + attack_hand(mob/user as mob) + user.machine = src + interact(user) + + + Topic(href, href_list) + if(..()) + return + usr.machine = src + src.add_fingerprint(usr) + if(href_list["removeContainer"]) + var/obj/item/weapon/storage/container = locate(href_list["removeContainer"]) + container.loc = src.loc + container.layer = initial(container.layer) + if(href_list["modifyOutputAmount"]) + outputAmount = text2num(input(usr,"Amount:","Enter new quantity to create","")) + if(!busy) + if(outputAmount < 1) + outputAmount = 1 + else + usr << "\red The autolathe is busy. Please wait for completion of previous operation." + if (!busy) + if(href_list["make"]) + var/turf/T = src.loc + var/obj/template = locate(href_list["make"]) + var/multiplier = text2num(href_list["multiplier"]) + if (!multiplier) multiplier = 1 + var/power = max(2000, (template.m_amt+template.g_amt)*multiplier/5) + restart: + if(outputAmount > 0) + if(src.m_amount >= template.m_amt*multiplier && src.g_amount >= template.g_amt*multiplier) + busy = 1 + use_power(power) + icon_state = "autolathe" + flick("autolathe_n",src) + spawn(16) + + if(!busy) + busy = 1 + use_power(power) + spawn(16) + use_power(power) + spawn(16) + flick("autolathe_n",src) + src.m_amount -= template.m_amt*multiplier + src.g_amount -= template.g_amt*multiplier + if(src.m_amount < 0) + src.m_amount = 0 + if(src.g_amount < 0) + src.g_amount = 0 + var/obj/new_item = new template.type(src) + for(var/obj/item/weapon/storage/container in src.contents) + container.attackby(new_item) + if(new_item.loc == container) + break + if (multiplier>1) + var/obj/item/stack/S = new_item + S.amount = multiplier + if(new_item in src) + new_item.loc = T + src.updateUsrDialog() + outputAmount -= 1 + busy = 0 + goto restart + else + for(var/mob/M in view(3,src)) + M << "\red\icon[src] has run out of materials." + else + outputAmount = 1 + if(href_list["act"]) + var/temp_wire = href_list["wire"] + if(href_list["act"] == "pulse") + if (!istype(usr.equipped(), /obj/item/device/multitool)) + usr << "You need a multitool!" + else + if(src.wires[temp_wire]) + usr << "You can't pulse a cut wire." + else + if(src.hack_wire == temp_wire) + src.hacked = !src.hacked + spawn(100) src.hacked = !src.hacked + if(src.disable_wire == temp_wire) + src.disabled = !src.disabled + src.shock(usr,50) + spawn(100) src.disabled = !src.disabled + if(src.shock_wire == temp_wire) + src.shocked = !src.shocked + src.shock(usr,50) + spawn(100) src.shocked = !src.shocked + if(href_list["act"] == "wire") + if (!istype(usr.equipped(), /obj/item/weapon/wirecutters)) + usr << "You need wirecutters!" + else + wires[temp_wire] = !wires[temp_wire] + if(src.hack_wire == temp_wire) + src.hacked = !src.hacked + if(src.disable_wire == temp_wire) + src.disabled = !src.disabled + src.shock(usr,50) + if(src.shock_wire == temp_wire) + src.shocked = !src.shocked + src.shock(usr,50) + else + usr << "\red The autolathe is busy. Please wait for completion of previous operation." + src.updateUsrDialog() + return + -/obj/machinery/autolathe/New() - ..() - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/autolathe(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) - component_parts += new /obj/item/weapon/stock_parts/manipulator(src) - component_parts += new /obj/item/weapon/stock_parts/console_screen(src) RefreshParts() + ..() + var/tot_rating = 0 + for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts) + tot_rating += MB.rating + tot_rating *= 25000 + max_m_amount = tot_rating * 2 + max_g_amount = tot_rating - src.L = autolathe_recipes - src.LL = autolathe_recipes_hidden - src.wires["Light Red"] = 0 - src.wires["Dark Red"] = 0 - src.wires["Blue"] = 0 - src.wires["Green"] = 0 - src.wires["Yellow"] = 0 - src.wires["Black"] = 0 - src.wires["White"] = 0 - src.wires["Gray"] = 0 - src.wires["Orange"] = 0 - src.wires["Pink"] = 0 - var/list/w = list("Light Red","Dark Red","Blue","Green","Yellow","Black","White","Gray","Orange","Pink") - src.hack_wire = pick(w) - w -= src.hack_wire - src.shock_wire = pick(w) - w -= src.shock_wire - src.disable_wire = pick(w) - w -= src.disable_wire + New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/autolathe(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/console_screen(src) + RefreshParts() -/obj/machinery/autolathe/proc/shock(mob/user, prb) - if(stat & (BROKEN|NOPOWER)) // unpowered, no shock - return 0 - if(!prob(prb)) - return 0 - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() - if (electrocute_mob(user, get_area(src), src, 0.7)) - return 1 - else - return 0 \ No newline at end of file + src.L = autolathe_recipes + src.LL = autolathe_recipes_hidden + src.wires["Light Red"] = 0 + src.wires["Dark Red"] = 0 + src.wires["Blue"] = 0 + src.wires["Green"] = 0 + src.wires["Yellow"] = 0 + src.wires["Black"] = 0 + src.wires["White"] = 0 + src.wires["Gray"] = 0 + src.wires["Orange"] = 0 + src.wires["Pink"] = 0 + var/list/w = list("Light Red","Dark Red","Blue","Green","Yellow","Black","White","Gray","Orange","Pink") + src.hack_wire = pick(w) + w -= src.hack_wire + src.shock_wire = pick(w) + w -= src.shock_wire + src.disable_wire = pick(w) + w -= src.disable_wire diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm index 683e5328cc..6a0f2d475e 100644 --- a/code/game/machinery/biogenerator.dm +++ b/code/game/machinery/biogenerator.dm @@ -92,9 +92,12 @@ dat += "10 milk (20)
" dat += "Slab of meat (50)
" dat += "Nutrient
" - dat += "E-Z-Nutrient (10)
" - dat += "Left 4 Zed (20)
" - dat += "Robust Harvest (25)
" + dat += "E-Z-Nutrient (10) | x5
" + dat += "Left 4 Zed (20) | x5
" + dat += "Robust Harvest (25) | x5
" + dat += "Leather
" + dat += "Botanical gloves (350)
" + dat += "Utility belt (400)
" //dat += "Other
" //dat += "Monkey (500)
" else @@ -163,6 +166,28 @@ new/obj/item/nutrient/l4z(src.loc) if("rh") new/obj/item/nutrient/rh(src.loc) + if("ez5") //It's not an elegant method, but it's safe and easy. -Cheridan + new/obj/item/nutrient/ez(src.loc) + new/obj/item/nutrient/ez(src.loc) + new/obj/item/nutrient/ez(src.loc) + new/obj/item/nutrient/ez(src.loc) + new/obj/item/nutrient/ez(src.loc) + if("l4z5") + new/obj/item/nutrient/l4z(src.loc) + new/obj/item/nutrient/l4z(src.loc) + new/obj/item/nutrient/l4z(src.loc) + new/obj/item/nutrient/l4z(src.loc) + new/obj/item/nutrient/l4z(src.loc) + if("rh5") + new/obj/item/nutrient/rh(src.loc) + new/obj/item/nutrient/rh(src.loc) + new/obj/item/nutrient/rh(src.loc) + new/obj/item/nutrient/rh(src.loc) + new/obj/item/nutrient/rh(src.loc) + if("gloves") + new/obj/item/clothing/gloves/botanic_leather(src.loc) + if("tbelt") + new/obj/item/weapon/storage/belt/utility(src.loc) if("monkey") new/mob/living/carbon/monkey(src.loc) processing = 0 @@ -181,9 +206,10 @@ if("activate") activate() if("detach") - beaker.loc = src.loc - beaker = null - update_icon() + if(beaker) + beaker.loc = src.loc + beaker = null + update_icon() if("create") create_product(href_list["item"],text2num(href_list["cost"])) if("menu") diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index 8f2872dba9..854e089881 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -613,13 +613,22 @@ Auto Patrol: []"}, return 0 if((istype(perp.l_hand, /obj/item/weapon/gun) && !istype(perp.l_hand, /obj/item/weapon/gun/projectile/shotgun)) || istype(perp.l_hand, /obj/item/weapon/melee/baton)) - threatcount += 4 + if(!istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/bluetag) \ + && !istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/redtag) \ + && !istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/practice)) + threatcount += 4 - if((istype(perp.r_hand, /obj/item/weapon/gun) && !istype(perp.r_hand, /obj/item/weapon/gun/projectile/shotgun)) || istype(perp.r_hand, /obj/item/weapon/melee/baton)) - threatcount += 4 + if(istype(perp.r_hand, /obj/item/weapon/gun) || istype(perp.r_hand, /obj/item/weapon/melee)) + if(!istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/bluetag) \ + && !istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/redtag) \ + && !istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/practice)) + threatcount += 4 - if(istype(perp:belt, /obj/item/weapon/gun) || istype(perp:belt, /obj/item/weapon/melee/baton)) - threatcount += 2 + if(istype(perp:belt, /obj/item/weapon/gun) || istype(perp:belt, /obj/item/weapon/melee)) + if(!istype(perp:belt, /obj/item/weapon/gun/energy/laser/bluetag) \ + && !istype(perp:belt, /obj/item/weapon/gun/energy/laser/redtag) \ + && !istype(perp:belt, /obj/item/weapon/gun/energy/laser/practice)) + threatcount += 2 if(istype(perp:wear_suit, /obj/item/clothing/suit/wizrobe)) threatcount += 2 diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index 61338d7377..87ae8f6be8 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -588,14 +588,24 @@ Auto Patrol: []"}, if(src.emagged) return 10 //Everyone is a criminal! if(src.idcheck && !src.allowed(perp)) + if(istype(perp.l_hand, /obj/item/weapon/gun) || istype(perp.l_hand, /obj/item/weapon/melee)) - threatcount += 4 + if(!istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/bluetag) \ + && !istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/redtag) \ + && !istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/practice)) + threatcount += 4 if(istype(perp.r_hand, /obj/item/weapon/gun) || istype(perp.r_hand, /obj/item/weapon/melee)) - threatcount += 4 + if(!istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/bluetag) \ + && !istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/redtag) \ + && !istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/practice)) + threatcount += 4 if(istype(perp:belt, /obj/item/weapon/gun) || istype(perp:belt, /obj/item/weapon/melee)) - threatcount += 2 + if(!istype(perp:belt, /obj/item/weapon/gun/energy/laser/bluetag) \ + && !istype(perp:belt, /obj/item/weapon/gun/energy/laser/redtag) \ + && !istype(perp:belt, /obj/item/weapon/gun/energy/laser/practice)) + threatcount += 2 if(istype(perp:wear_suit, /obj/item/clothing/suit/wizrobe)) threatcount += 2 diff --git a/code/game/machinery/camera.dm b/code/game/machinery/camera.dm index ae061bb9a1..8af06c5504 100644 --- a/code/game/machinery/camera.dm +++ b/code/game/machinery/camera.dm @@ -66,6 +66,8 @@ continue else if (M == usr) continue + if(M.digitalcamo) + continue var/turf/temp_turf = get_turf(M) if(temp_turf.z != 1 && temp_turf.z != 5) //Not on mining or the station. continue @@ -118,6 +120,11 @@ usr << "Follow camera mode terminated." usr:cameraFollow = null return + if(target.digitalcamo) + usr << "Follow camera mode terminated." + usr:cameraFollow = null + return + else if(istype(target.loc,/obj/effect/dummy)) usr << "Follow camera mode ended." usr:cameraFollow = null diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 17239407b6..4b5095d19a 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -1,57 +1,92 @@ -/obj/machinery/cell_charger/attackby(obj/item/weapon/W, mob/user) - if(stat & BROKEN) - return - if(istype(W, /obj/item/weapon/cell)) - if(charging) - user << "There is already a cell in the charger." - return - else - user.drop_item() - W.loc = src - charging = W - user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.") - chargelevel = -1 - updateicon() - -/obj/machinery/cell_charger/proc/updateicon() - icon_state = "ccharger[charging ? 1 : 0]" - - if(charging && !(stat & (BROKEN|NOPOWER)) ) - - var/newlevel = round( charging.percent() * 4.0 / 99 ) - //world << "nl: [newlevel]" - - if(chargelevel != newlevel) - - overlays = null - overlays += image('power.dmi', "ccharger-o[newlevel]") - - chargelevel = newlevel - else - overlays = null - -/obj/machinery/cell_charger/attack_hand(mob/user) - - if(charging) - usr.put_in_hand(charging) - charging.add_fingerprint(user) - charging.updateicon() - - src.charging = null - user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger.") +/obj/machinery/cell_charger + name = "cell charger" + desc = "It charges power cells." + icon = 'power.dmi' + icon_state = "ccharger0" + anchored = 1 + use_power = 1 + idle_power_usage = 5 + active_power_usage = 60 + power_channel = EQUIP + var + obj/item/weapon/cell/charging = null chargelevel = -1 + proc updateicon() + icon_state = "ccharger[charging ? 1 : 0]" -/obj/machinery/cell_charger/attack_ai(mob/user) - return + if(charging && !(stat & (BROKEN|NOPOWER)) ) -/obj/machinery/cell_charger/process() - //world << "ccpt [charging] [stat]" - if(!charging || (stat & (BROKEN|NOPOWER)) ) + var/newlevel = round( charging.percent() * 4.0 / 99 ) + //world << "nl: [newlevel]" + + if(chargelevel != newlevel) + + overlays = null + overlays += image('power.dmi', "ccharger-o[newlevel]") + + chargelevel = newlevel + else + overlays = null + examine() + set src in oview(5) + ..() + usr << "There's [charging ? "a" : "no"] cell in the charger." + if(charging) + usr << "Current charge: [charging.charge]" + + attackby(obj/item/weapon/W, mob/user) + if(stat & BROKEN) + return + + if(istype(W, /obj/item/weapon/cell) && anchored) + if(charging) + user << "\red There is already a cell in the charger." + return + else + var/area/a = loc.loc // Gets our locations location, like a dream within a dream + if(!isarea(a)) + return + if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power! + user << "\red The charger rejects the cell!" + return + + user.drop_item() + W.loc = src + charging = W + user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.") + chargelevel = -1 + updateicon() + else if(istype(W, /obj/item/weapon/wrench)) + if(charging) + user << "\red Remove the cell first!" + return + + anchored = !anchored + user << "You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground" + playsound(src.loc, 'Ratchet.ogg', 75, 1) + + attack_hand(mob/user) + if(charging) + usr.put_in_hand(charging) + charging.add_fingerprint(user) + charging.updateicon() + + src.charging = null + user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger.") + chargelevel = -1 + updateicon() + + attack_ai(mob/user) return - var/added = charging.give(75) - use_power(added / CELLRATE) + process() + //world << "ccpt [charging] [stat]" + if(!charging || (stat & (BROKEN|NOPOWER)) || !anchored) + return - updateicon() \ No newline at end of file + var/added = charging.give(75) + use_power(added / CELLRATE) + + updateicon() diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm new file mode 100644 index 0000000000..567f10801f --- /dev/null +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -0,0 +1,459 @@ +/obj/machinery/computer/HolodeckControl + name = "Holodeck Control Computer" + desc = "A computer used to control a nearby holodeck." + icon_state = "computer_generic" + var/area/linkedholodeck = null + var/area/target = null + var/active = 0 + var/list/holographic_items = list() + var/damaged = 0 + + + attack_ai(var/mob/user as mob) + return src.attack_hand(user) + + attack_paw(var/mob/user as mob) + return + + attack_hand(var/mob/user as mob) + + if(..()) + return + user.machine = src + var/dat + + + dat += "Holodeck Control System
" + dat += "
Current Loaded Programs:
" + + dat += "((Empty Court))
" + dat += "((Boxing Court))
" + dat += "((Thunderdome Court))
" + dat += "((Beach))
" +// dat += "((Shutdown System))
" + + dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
" + + if(issilicon(user) && !emagged) + dat += "(Override Safety Protocols?)
" + + if(emagged) + dat += "(Begin Atmospheric Burn Simulation)
" + dat += "Ensure the holodeck is empty before testing.
" + dat += "
" + dat += "(Begin Wildlife Simulation)
" + dat += "Ensure the holodeck is empty before testing.
" + dat += "
" + dat += "Safety Protocols are DISABLED
" + else + dat += "
" + dat += "Safety Protocols are ENABLED
" + + user << browse(dat, "window=computer;size=400x500") + onclose(user, "computer") + + + return + + + Topic(href, href_list) + if(..()) + return + if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) + usr.machine = src + + if(href_list["emptycourt"]) + target = locate(/area/holodeck/source_emptycourt) + if(target) + loadProgram(target) + + else if(href_list["boxingcourt"]) + target = locate(/area/holodeck/source_boxingcourt) + if(target) + loadProgram(target) + + else if(href_list["thunderdomecourt"]) + target = locate(/area/holodeck/source_thunderdomecourt) + if(target) + loadProgram(target) + + else if(href_list["beach"]) + target = locate(/area/holodeck/source_beach) + if(target) + loadProgram(target) + + else if(href_list["turnoff"]) + target = locate(/area/holodeck/source_plating) + if(target) + loadProgram(target) + + else if(href_list["burntest"]) + target = locate(/area/holodeck/source_burntest) + if(target) + loadProgram(target) + + else if(href_list["wildlifecarp"]) + target = locate(/area/holodeck/source_wildlife) + if(target) + loadProgram(target) + + else if(href_list["AIoverride"]) + emagged = 1 + + src.add_fingerprint(usr) + src.updateUsrDialog() + return + + + +/obj/machinery/computer/HolodeckControl/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) +/* if(istype(D, /obj/item/weapon/screwdriver)) + playsound(src.loc, 'Screwdriver.ogg', 50, 1) + if(do_after(user, 20)) + if (src.stat & BROKEN) + user << "\blue The broken glass falls out." + var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) + new /obj/item/weapon/shard( src.loc ) + var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A ) + for (var/obj/C in src) + C.loc = src.loc + A.circuit = M + A.state = 3 + A.icon_state = "3" + A.anchored = 1 + del(src) + else + user << "\blue You disconnect the monitor." + var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) + var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A ) + for (var/obj/C in src) + C.loc = src.loc + A.circuit = M + A.state = 4 + A.icon_state = "4" + A.anchored = 1 + del(src) + +*/ + if(istype(D, /obj/item/weapon/card/emag) && !emagged) + playsound(src.loc, 'sparks4.ogg', 75, 1) + emagged = 1 + user << "\blue You vastly increase projector power and override the safety and security protocols." + user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintence and do not use the simulator." + src.updateUsrDialog() + return + +/obj/machinery/computer/HolodeckControl/New() + ..() + linkedholodeck = locate(/area/holodeck/alphadeck) + //if(linkedholodeck) + // target = locate(/area/holodeck/source_emptycourt) + // if(target) + // loadProgram(target) + + +/obj/machinery/computer/HolodeckControl/process() + + if(active) + + if(!checkInteg(linkedholodeck)) + damaged = 1 + target = locate(/area/holodeck/source_plating) + if(target) + loadProgram(target) + active = 0 + for(var/mob/M in range(10,src)) + M.show_message("The holodeck overloads!") + + + for(var/turf/T in linkedholodeck) + if(prob(30)) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, T) + s.start() + T.ex_act(3) + T.hotspot_expose(1000,500,1) + + + for(var/item in holographic_items) + if(!(get_turf(item) in linkedholodeck)) + derez(item, 0) + + + +/obj/machinery/computer/HolodeckControl/proc/derez(var/obj , var/silent = 1) + holographic_items.Remove(obj) + + if(istype(obj , /obj/)) + if(istype(obj:loc , /mob/)) + var/mob/M = obj:loc + M.drop_from_slot(obj) + + if(!silent) + var/obj/oldobj = obj + for(var/mob/M in viewers(world.view,get_turf(obj))) + M << "The [oldobj.name] fades away!" + del(obj) + +/obj/machinery/computer/HolodeckControl/proc/checkInteg(var/area/A) + for(var/turf/T in A) + if(istype(T, /turf/space)) + return 0 + + return 1 + +/obj/machinery/computer/HolodeckControl/proc/togglePower(var/toggleOn = 0) + + if(toggleOn) + var/area/targetsource = locate(/area/holodeck/source_emptycourt) + holographic_items = targetsource.copy_contents_to(linkedholodeck) + + spawn(30) + for(var/obj/effect/landmark/L in linkedholodeck) + if(L.name=="Atmospheric Test Start") + spawn(20) + var/turf/T = get_turf(L) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, T) + s.start() + if(T) + T.temperature = 5000 + T.hotspot_expose(50000,50000,1) + + active = 1 + else + for(var/item in holographic_items) + derez(item) + var/area/targetsource = locate(/area/holodeck/source_plating) + targetsource.copy_contents_to(linkedholodeck , 1) + active = 0 + + +/obj/machinery/computer/HolodeckControl/proc/loadProgram(var/area/A) + + active = 1 + + for(var/item in holographic_items) + derez(item) + + for(var/obj/effect/decal/cleanable/blood/B in linkedholodeck) + del(B) + + holographic_items = A.copy_contents_to(linkedholodeck , 1) + + if(emagged) + for(var/obj/item/weapon/melee/energy/sword/holosword/H in linkedholodeck) + H.damtype = BRUTE + + spawn(30) + for(var/obj/effect/landmark/L in linkedholodeck) + if(L.name=="Atmospheric Test Start") + spawn(20) + var/turf/T = get_turf(L) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, T) + s.start() + if(T) + T.temperature = 5000 + T.hotspot_expose(50000,50000,1) + + + + + + + + + + +// Holographic Items! + +/turf/simulated/floor/holofloor/ + thermal_conductivity = 0 + +/turf/simulated/floor/holofloor/grass + name = "Lush Grass" + icon_state = "grass1" + floor_tile = new/obj/item/stack/tile/grass + + New() + floor_tile.New() //I guess New() isn't run on objects spawned without the definition of a turf to house them, ah well. + icon_state = "grass[pick("1","2","3","4")]" + ..() + spawn(4) + update_icon() + for(var/direction in cardinal) + if(istype(get_step(src,direction),/turf/simulated/floor)) + var/turf/simulated/floor/FF = get_step(src,direction) + FF.update_icon() //so siding get updated properly + +/turf/simulated/floor/holofloor/attackby(obj/item/weapon/W as obj, mob/user as mob) + return + // HOLOFLOOR DOES NOT GIVE A FUCK + + + + + + + + + + +/obj/structure/table/holotable + name = "table" + desc = "A square piece of metal standing on four metal legs. It can not move." + icon = 'structures.dmi' + icon_state = "table" + density = 1 + anchored = 1.0 + layer = 2.8 +// throwpass = 1 //You can throw objects over this, despite it's density. + + +/obj/structure/table/holotable/attack_paw(mob/user as mob) + return attack_hand(user) + +/obj/structure/table/holotable/attack_alien(mob/user as mob) //Removed code for larva since it doesn't work. Previous code is now a larva ability. /N + return attack_hand(user) + +/obj/structure/table/holotable/attack_animal(mob/living/simple_animal/user as mob) //Removed code for larva since it doesn't work. Previous code is now a larva ability. /N + return attack_hand(user) + +/obj/structure/table/holotable/attack_hand(mob/user as mob) + return // HOLOTABLE DOES NOT GIVE A FUCK + + +/obj/structure/table/holotable/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) + var/obj/item/weapon/grab/G = W + if(G.state<2) + user << "\red You need a better grip to do that!" + return + G.affecting.loc = src.loc + G.affecting.Weaken(5) + for(var/mob/O in viewers(world.view, src)) + if (O.client) + O << text("\red [] puts [] on the table.", G.assailant, G.affecting) + del(W) + return + + if (istype(W, /obj/item/weapon/wrench)) + user << "It's a holotable! There are no bolts!" + return + + if(isrobot(user)) + return + + + +/obj/item/clothing/gloves/boxing/hologlove + name = "boxing gloves" + desc = "Because you really needed another excuse to punch your crewmates." + icon_state = "boxing" + item_state = "boxing" + +/obj/structure/holowindow + name = "reinforced window" + icon = 'structures.dmi' + icon_state = "rwindow" + desc = "A window." + density = 1 + layer = 3.2//Just above doors + pressure_resistance = 4*ONE_ATMOSPHERE + anchored = 1.0 + flags = ON_BORDER + + +/obj/structure/holowindow/Del() + ..() + + +/obj/item/weapon/melee/energy/sword/holosword + damtype = HALLOSS + +/obj/item/weapon/melee/energy/sword/holosword/green + New() + color = "green" + +/obj/item/weapon/melee/energy/sword/holosword/red + New() + color = "red" + + + + + + +/obj/machinery/readybutton + name = "Ready Declaration Device" + desc = "This device is used to declare ready. If all devices in an area are ready, the event will begin!" + icon = 'monitors.dmi' + icon_state = "auth_off" + var/ready = 0 + var/area/currentarea = null + var/eventstarted = 0 + + anchored = 1.0 + use_power = 1 + idle_power_usage = 2 + active_power_usage = 6 + power_channel = ENVIRON + +/obj/machinery/readybutton/attack_ai(mob/user as mob) + user << "The station AI is not to interact with these devices" + return + +/obj/machinery/readybutton/attack_paw(mob/user as mob) + user << "You are too primitive to use this device" + return + +/obj/machinery/readybutton/New() + ..() + + +/obj/machinery/readybutton/attackby(obj/item/weapon/W as obj, mob/user as mob) + user << "The device is a solid button, there's nothing you can do with it!" + +/obj/machinery/readybutton/attack_hand(mob/user as mob) + if(user.stat || stat & (NOPOWER|BROKEN)) + user << "This device is not powered." + return + + currentarea = get_area(src.loc) + if(!currentarea) + del(src) + + if(eventstarted) + usr << "The event has already begun!" + return + + ready = !ready + + update_icon() + + var/numbuttons = 0 + var/numready = 0 + for(var/obj/machinery/readybutton/button in currentarea) + numbuttons++ + if (button.ready) + numready++ + + if(numbuttons == numready) + begin_event() + +/obj/machinery/readybutton/update_icon() + if(ready) + icon_state = "auth_on" + else + icon_state = "auth_off" + +/obj/machinery/readybutton/proc/begin_event() + + eventstarted = 1 + + for(var/obj/structure/holowindow/W in currentarea) + del(W) + + for(var/mob/M in currentarea) + M << "FIGHT!" \ No newline at end of file diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm new file mode 100644 index 0000000000..659f98b939 --- /dev/null +++ b/code/game/machinery/computer/atmos_alert.dm @@ -0,0 +1,105 @@ + +/obj/machinery/computer/atmos_alert + name = "Atmospheric Alert Computer" + desc = "Used to access the station's atmospheric sensors." + icon_state = "alert:0" + var + list/priority_alarms = list() + list/minor_alarms = list() + receive_frequency = 1437 + datum/radio_frequency/radio_connection + + + initialize() + set_frequency(receive_frequency) + + receive_signal(datum/signal/signal) + if(!signal || signal.encryption) return + + var/zone = signal.data["zone"] + var/severity = signal.data["alert"] + + if(!zone || !severity) return + + minor_alarms -= zone + priority_alarms -= zone + if(severity=="severe") + priority_alarms += zone + else if (severity=="minor") + minor_alarms += zone + update_icon() + return + + + proc/set_frequency(new_frequency) + radio_controller.remove_object(src, receive_frequency) + receive_frequency = new_frequency + radio_connection = radio_controller.add_object(src, receive_frequency, RADIO_ATMOSIA) + + + attack_hand(mob/user) + user << browse(return_text(),"window=computer") + user.machine = src + onclose(user, "computer") + + process() + ..() + src.updateDialog() + + update_icon() + if(priority_alarms.len) + icon_state = "alert:2" + + else if(minor_alarms.len) + icon_state = "alert:1" + + else + icon_state = "alert:0" + return + + + proc/return_text() + var/priority_text + var/minor_text + + if(priority_alarms.len) + for(var/zone in priority_alarms) + priority_text += "[zone] X
" + else + priority_text = "No priority alerts detected.
" + + if(minor_alarms.len) + for(var/zone in minor_alarms) + minor_text += "[zone] X
" + else + minor_text = "No minor alerts detected.
" + + var/output = {"[name]
+Priority Alerts:
+[priority_text] +
+
+Minor Alerts:
+[minor_text] +
"} + + return output + + + Topic(href, href_list) + if(..()) + return + + if(href_list["priority_clear"]) + var/removing_zone = href_list["priority_clear"] + for(var/zone in priority_alarms) + if(ckey(zone) == removing_zone) + priority_alarms -= zone + + if(href_list["minor_clear"]) + var/removing_zone = href_list["minor_clear"] + for(var/zone in minor_alarms) + if(ckey(zone) == removing_zone) + minor_alarms -= zone + update_icon() + return \ No newline at end of file diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 14c0ceb748..0fd688bed8 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -192,6 +192,11 @@ build_path = "/obj/machinery/computer/telecomms/server" origin_tech = "programming=3" +/obj/item/weapon/circuitboard/comm_traffic + name = "Circuitboard (Telecommunications Traffic Control)" + build_path = "/obj/machinery/computer/telecomms/traffic" + origin_tech = "programming=3" + /obj/item/weapon/circuitboard/curefab name = "Circuit board (Cure fab)" build_path = "/obj/machinery/computer/curer" diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index b8825a5616..c17eaf8b59 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -470,7 +470,7 @@ emergency_shuttle.incall() log_game("[key_name(user)] has called the shuttle.") message_admins("[key_name_admin(user)] has called the shuttle.", 1) - world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes." + captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.") world << sound('shuttlecalled.ogg') return @@ -482,10 +482,10 @@ if((ticker.mode.name == "blob")||(ticker.mode.name == "meteor")) return - emergency_shuttle.recall() - log_game("[key_name(user)] has uncalled the shuttle.") - message_admins("[key_name_admin(user)] has uncalled the shuttle.", 1) - + if(emergency_shuttle.direction != -1 && emergency_shuttle.online) //check that shuttle isn't already heading to centcomm + emergency_shuttle.recall() + log_game("[key_name(user)] has recalled the shuttle.") + message_admins("[key_name_admin(user)] has recalled the shuttle.", 1) return /obj/machinery/computer/communications/proc/post_status(var/command, var/data1, var/data2) @@ -529,7 +529,7 @@ emergency_shuttle.incall(2) log_game("All the AIs, comm consoles and boards are destroyed. Shuttle called.") message_admins("All the AIs, comm consoles and boards are destroyed. Shuttle called.", 1) - world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes." + captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.") world << sound('shuttlecalled.ogg') ..() @@ -554,7 +554,7 @@ emergency_shuttle.incall(2) log_game("All the AIs, comm consoles and boards are destroyed. Shuttle called.") message_admins("All the AIs, comm consoles and boards are destroyed. Shuttle called.", 1) - world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes." + captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.") world << sound('shuttlecalled.ogg') ..() \ No newline at end of file diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 4db4bb8280..e78c65031b 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -290,193 +290,11 @@ Pod/Blast Doors computer locked += L -/obj/machinery/computer/pod/proc/alarm() - if(stat & (NOPOWER|BROKEN)) - return - if (!( connected )) - viewers(null, null) << "Cannot locate mass driver connector. Cancelling firing sequence!" - return - for(var/obj/machinery/door/poddoor/M in machines) - if (M.id == id) - spawn( 0 ) - M.open() - return - sleep(20) - //connected.drive() *****RM from 40.93.3S - for(var/obj/machinery/mass_driver/M in machines) - if(M.id == id) - M.power = connected.power - M.drive() - sleep(50) - for(var/obj/machinery/door/poddoor/M in machines) - if (M.id == id) - spawn( 0 ) - M.close() - return - return -/obj/machinery/computer/pod/New() - ..() - spawn( 5 ) - for(var/obj/machinery/mass_driver/M in machines) - if (M.id == id) - connected = M - else - return - return - -/obj/machinery/computer/pod/attackby(I as obj, user as mob) - if(istype(I, /obj/item/weapon/screwdriver)) - playsound(loc, 'Screwdriver.ogg', 50, 1) - if(do_after(user, 20)) - if (stat & BROKEN) - user << "\blue The broken glass falls out." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc ) - new /obj/item/weapon/shard( loc ) - - //generate appropriate circuitboard. Accounts for /pod/old computer types - var/obj/item/weapon/circuitboard/pod/M = null - if(istype(src, /obj/machinery/computer/pod/old)) - M = new /obj/item/weapon/circuitboard/olddoor( A ) - if(istype(src, /obj/machinery/computer/pod/old/syndicate)) - M = new /obj/item/weapon/circuitboard/syndicatedoor( A ) - if(istype(src, /obj/machinery/computer/pod/old/swf)) - M = new /obj/item/weapon/circuitboard/swfdoor( A ) - else //it's not an old computer. Generate standard pod circuitboard. - M = new /obj/item/weapon/circuitboard/pod( A ) - - for (var/obj/C in src) - C.loc = loc - M.id = id - A.circuit = M - A.state = 3 - A.icon_state = "3" - A.anchored = 1 - del(src) - else - user << "\blue You disconnect the monitor." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc ) - - //generate appropriate circuitboard. Accounts for /pod/old computer types - var/obj/item/weapon/circuitboard/pod/M = null - if(istype(src, /obj/machinery/computer/pod/old)) - M = new /obj/item/weapon/circuitboard/olddoor( A ) - if(istype(src, /obj/machinery/computer/pod/old/syndicate)) - M = new /obj/item/weapon/circuitboard/syndicatedoor( A ) - if(istype(src, /obj/machinery/computer/pod/old/swf)) - M = new /obj/item/weapon/circuitboard/swfdoor( A ) - else //it's not an old computer. Generate standard pod circuitboard. - M = new /obj/item/weapon/circuitboard/pod( A ) - - for (var/obj/C in src) - C.loc = loc - M.id = id - A.circuit = M - A.state = 4 - A.icon_state = "4" - A.anchored = 1 - del(src) - else - attack_hand(user) - return - -/obj/machinery/computer/pod/attack_ai(var/mob/user as mob) - return attack_hand(user) - -/obj/machinery/computer/pod/attack_paw(var/mob/user as mob) - return attack_hand(user) - -/obj/machinery/computer/pod/attack_hand(var/mob/user as mob) - if(..()) - return - - var/dat = "Mass Driver Controls" - user.machine = src - var/d2 - if (timing) - d2 = text("Stop Time Launch", src) - else - d2 = text("Initiate Time Launch", src) - var/second = time % 60 - var/minute = (time - second) / 60 - dat += text("
\nTimer System: []\nTime Left: [][] - - + +", d2, (minute ? text("[]:", minute) : null), second, src, src, src, src) - if (connected) - var/temp = "" - var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 ) - for(var/t in L) - if (t == connected.power) - temp += text("[] ", t) - else - temp += text("[] ", src, t, t) - //Foreach goto(172) - dat += text("
\nPower Level: []
\nFiring Sequence
\nTest Fire Driver
\nToggle Outer Door
", temp, src, src, src) - //*****RM from 40.93.3S - else - dat += text("
\nToggle Outer Door
", src) - //***** - dat += text("

Close
", user) - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") - return - -/obj/machinery/computer/pod/process() - ..() - if (timing) - if (time > 0) - time = round(time) - 1 - else - alarm() - time = 0 - timing = 0 - updateDialog() - return - -/obj/machinery/computer/pod/Topic(href, href_list) - if(..()) - return - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) - usr.machine = src - if (href_list["power"]) - var/t = text2num(href_list["power"]) - t = min(max(0.25, t), 16) - if (connected) - connected.power = t - else - if (href_list["alarm"]) - alarm() - else - if (href_list["time"]) - timing = text2num(href_list["time"]) - else - if (href_list["tp"]) - var/tp = text2num(href_list["tp"]) - time += tp - time = min(max(round(time), 0), 120) - else - if (href_list["door"]) - if(istype(src, /obj/machinery/computer/pod/old/syndicate))//Added here so Nuke ops don't go running naked into space before moving the shuttle. - if(syndicate_station_at_station == 0) - usr << "\red You need to launch the Syndicate Shuttle via the computer terminal at the head of the ship before departing." - return - for(var/obj/machinery/door/poddoor/M in machines) - if (M.id == id) - if (M.density) - spawn( 0 ) - M.open() - return - else - spawn( 0 ) - M.close() - return - //Foreach goto(298) - add_fingerprint(usr) - updateUsrDialog() - - return /obj/machinery/mass_driver/proc/drive(amount) if(stat & (BROKEN|NOPOWER)) diff --git a/code/game/machinery/computer/id.dm b/code/game/machinery/computer/id.dm index 6583bc5f41..d14fa30a0a 100644 --- a/code/game/machinery/computer/id.dm +++ b/code/game/machinery/computer/id.dm @@ -153,7 +153,14 @@ accesses += "
" accesses += "" accesses += "" - body = "[carddesc]
[jobs]

[accesses]" //CHECK THIS + + var/biometric = "" + biometric += "Biometric Data:
\ + Blood type: [modify.blood_type]
\ + DNA hash: [modify.dna_hash]
\ + Fingerprint hash: [modify.fingerprint_hash]" + + body = "[carddesc]
[jobs]
[biometric]

[accesses]" //CHECK THIS else body = "{Log in}

" body += "Access Crew Manifest" @@ -167,6 +174,17 @@ return usr.machine = src switch(href_list["choice"]) + if("bio_btype") + var/new_b_type = input("Please input the blood type.", "Biometric Input") as null|anything in list( "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-" ) + if(new_b_type) + modify.blood_type = new_b_type + + if("bio_dna") + modify.dna_hash = input("Please input the DNA hash.", "Biometric Input", modify.dna_hash) + + if("bio_fprint") + modify.fingerprint_hash = input("Please input the fingerprint hash.", "Biometric Input", modify.fingerprint_hash) + if ("modify") if (modify) data_core.manifest_modify(modify.registered_name, modify.assignment) diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm new file mode 100644 index 0000000000..7f55918b62 --- /dev/null +++ b/code/game/machinery/computer/law.dm @@ -0,0 +1,191 @@ +/obj/machinery/computer/aiupload + name = "AI Upload" + desc = "Used to upload laws to the AI." + icon_state = "command" + circuit = "/obj/item/weapon/circuitboard/aiupload" + var + mob/living/silicon/ai/current = null + opened = 0 + + + verb/AccessInternals() + set category = "Object" + set name = "Access Computer's Internals" + set src in oview(1) + if(get_dist(src, usr) > 1 || usr.restrained() || usr.lying || usr.stat || istype(usr, /mob/living/silicon)) + return + + opened = !opened + if(opened) + usr << "\blue The access panel is now open." + else + usr << "\blue The access panel is now closed." + return + + + attackby(obj/item/weapon/O as obj, mob/user as mob) + if(istype(O, /obj/item/weapon/aiModule)) + var/obj/item/weapon/aiModule/M = O + M.install(src) + else + ..() + + + attack_hand(var/mob/user as mob) + if(src.stat & NOPOWER) + usr << "The upload computer has no power!" + return + if(src.stat & BROKEN) + usr << "The upload computer is broken!" + return + + src.current = activeais() + + if (!src.current) + usr << "No active AIs detected." + else + usr << "[src.current.name] selected for law changes." + return + + + +/obj/machinery/computer/borgupload + name = "Cyborg Upload" + desc = "Used to upload laws to Cyborgs." + icon_state = "command" + circuit = "/obj/item/weapon/circuitboard/borgupload" + var/mob/living/silicon/robot/current = null + + + attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob) + if(istype(module, /obj/item/weapon/aiModule)) + module.install(src) + else + return ..() + + + attack_hand(var/mob/user as mob) + if(src.stat & NOPOWER) + usr << "The upload computer has no power!" + return + if(src.stat & BROKEN) + usr << "The upload computer is broken!" + return + + src.current = freeborg() + + if (!src.current) + usr << "No free cyborgs detected." + else + usr << "[src.current.name] selected for law changes." + return + +/obj/machinery/computer/aistatus + name = "AI Status Panel" + desc = "This shows the status of the AI." + icon = 'mainframe.dmi' + icon_state = "left" +// brightnessred = 0 +// brightnessgreen = 2 +// brightnessblue = 0 + +/obj/machinery/computer/aistatus/attack_hand(mob/user as mob) + if(stat & NOPOWER) + user << "\red The status panel has no power!" + return + if(stat & BROKEN) + user << "\red The status panel is broken!" + return + if(!issilicon(user)) + user << "\red You don't understand any of this!" + else + user << "\blue You know all of this already, why are you messing with it?" + return + + +/obj/machinery/computer/aiupload/mainframe + name = "AI Mainframe Upload" + icon = 'mainframe.dmi' + icon_state = "aimainframe" + + +/obj/machinery/computer/borgupload/mainframe + name = "Borg Mainframe Upload" + icon = 'mainframe.dmi' + icon_state = "aimainframe" + + +/*Module Storage Unit/Closet! Solid, only modules fit in it.*/ +/obj/structure/aiuploadcloset + name = "AI Mainframe Module Storage Unit" + icon = 'mainframe.dmi' + icon_state = "right-closed" + density = 1 + + var/open = 0 /*It's closed!*/ + +/obj/structure/aiuploadcloset/New() + ..() + new /obj/item/weapon/aiModule/reset(src) + new /obj/item/weapon/aiModule/purge(src) + new /obj/item/weapon/aiModule/nanotrasen(src) + new /obj/item/weapon/aiModule/paladin(src) + new /obj/item/weapon/aiModule/asimov(src) + new /obj/item/weapon/aiModule/safeguard(src) + new /obj/item/weapon/aiModule/protectStation(src) + new /obj/item/weapon/aiModule/quarantine(src) + new /obj/item/weapon/aiModule/teleporterOffline(src) + new /obj/item/weapon/aiModule/oxygen(src) + new /obj/item/weapon/aiModule/oneHuman(src) + new /obj/item/weapon/aiModule/freeform(src) + for(var/obj/item/weapon/aiModule/M in src) + M.pixel_x = rand(-10, 10) + M.pixel_y = rand(-10, 10) + +/obj/structure/aiuploadcloset/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/aiModule)) + user.drop_item() + W.loc = get_turf(src) + else + return attack_hand(user) + +/obj/structure/aiuploadcloset/attack_hand(mob/user as mob) + if(!open) + var/temp_count + for(var/obj/item/weapon/aiModule/M in src) + M.loc = src.loc + temp_count++ + + user << "\blue You open the module storage unit, [temp_count > 0 ? "and take out all the modules." : "\red but it's empty!"]" + open = 1 + icon_state = "right-open" + + else + var/temp_count + for(var/obj/item/weapon/aiModule/M in get_turf(src)) + M.loc = src + temp_count++ + + user << "\blue [temp_count > 0 ? "You put all the modules back into the module storage unit, and then close it." : "You close the module storage unit."]" + open = 0 + icon_state = "right-closed" + +/obj/structure/aiuploadcloset/ex_act(severity) + switch(severity) + if (1) + for(var/obj/item/weapon/aiModule/M in src) + M.loc = src.loc + M.ex_act(severity) + del(src) + if (2) + if (prob(50)) + for(var/obj/item/weapon/aiModule/M in src) + M.loc = src.loc + M.ex_act(severity) + del(src) + if (3) + if (prob(5)) + for(var/obj/item/weapon/aiModule/M in src) + M.loc = src.loc + M.ex_act(severity) + del(src) \ No newline at end of file diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 3c200f6158..56b5e8c1af 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -1,3 +1,24 @@ +/obj/machinery/computer/med_data//TODO:SANITY + name = "Medical Records" + desc = "This can be used to check medical records." + icon_state = "medcomp" + req_access = list(access_medical) + circuit = "/obj/item/weapon/circuitboard/med_data" + var + obj/item/weapon/card/id/scan = null + obj/item/weapon/disk/records/disk = null + authenticated = null + rank = null + screen = null + datum/data/record/active1 = null + datum/data/record/active2 = null + a_id = null + temp = null + printing = null + list/Perp + tempname = null + + /obj/machinery/computer/med_data/attackby(obj/item/O as obj, user as mob) if(istype(O, /obj/item/weapon/card/id) && !scan) usr.drop_item() @@ -21,7 +42,6 @@ if(..()) return var/dat - if (src.temp) dat = text("[src.temp]

Clear Screen") else @@ -461,7 +481,7 @@ var/counter = 1 while(src.active2.fields[text("com_[]", counter)]) counter++ - src.active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2053
[]", src.authenticated, src.rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1) + src.active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2556
[]", src.authenticated, src.rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1) if (href_list["del_c"]) if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])])) @@ -540,3 +560,8 @@ src.updateUsrDialog() return + +/obj/machinery/computer/med_data/laptop + name = "Medical Laptop" + desc = "Cheap Nanotrasen Laptop." + icon_state = "medlaptop" diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm new file mode 100644 index 0000000000..51f00e6115 --- /dev/null +++ b/code/game/machinery/computer/pod.dm @@ -0,0 +1,222 @@ +/obj/machinery/computer/pod + name = "Pod Launch Control" + desc = "A control for launching pods." + icon_state = "computer_generic" + var + id = 1.0 + obj/machinery/mass_driver/connected = null + timing = 0.0 + time = 30.0 + + +/obj/machinery/computer/pod/New() + ..() + spawn( 5 ) + for(var/obj/machinery/mass_driver/M in world) + if (M.id == id) + connected = M + else + return + return + + +/obj/machinery/computer/pod/proc/alarm() + if(stat & (NOPOWER|BROKEN)) + return + + if (!( connected )) + viewers(null, null) << "Cannot locate mass driver connector. Cancelling firing sequence!" + return + + for(var/obj/machinery/door/poddoor/M in world) + if (M.id == id) + spawn( 0 ) + M.open() + return + sleep(20) + + //connected.drive() *****RM from 40.93.3S + for(var/obj/machinery/mass_driver/M in world) + if(M.id == id) + M.power = connected.power + M.drive() + + sleep(50) + for(var/obj/machinery/door/poddoor/M in world) + if (M.id == id) + spawn( 0 ) + M.close() + return + return + + +/obj/machinery/computer/pod/attackby(I as obj, user as mob) + if(istype(I, /obj/item/weapon/screwdriver)) + playsound(loc, 'Screwdriver.ogg', 50, 1) + if(do_after(user, 20)) + if (stat & BROKEN) + user << "\blue The broken glass falls out." + var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc ) + new /obj/item/weapon/shard( loc ) + + //generate appropriate circuitboard. Accounts for /pod/old computer types + var/obj/item/weapon/circuitboard/pod/M = null + if(istype(src, /obj/machinery/computer/pod/old)) + M = new /obj/item/weapon/circuitboard/olddoor( A ) + if(istype(src, /obj/machinery/computer/pod/old/syndicate)) + M = new /obj/item/weapon/circuitboard/syndicatedoor( A ) + if(istype(src, /obj/machinery/computer/pod/old/swf)) + M = new /obj/item/weapon/circuitboard/swfdoor( A ) + else //it's not an old computer. Generate standard pod circuitboard. + M = new /obj/item/weapon/circuitboard/pod( A ) + + for (var/obj/C in src) + C.loc = loc + M.id = id + A.circuit = M + A.state = 3 + A.icon_state = "3" + A.anchored = 1 + del(src) + else + user << "\blue You disconnect the monitor." + var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc ) + + //generate appropriate circuitboard. Accounts for /pod/old computer types + var/obj/item/weapon/circuitboard/pod/M = null + if(istype(src, /obj/machinery/computer/pod/old)) + M = new /obj/item/weapon/circuitboard/olddoor( A ) + if(istype(src, /obj/machinery/computer/pod/old/syndicate)) + M = new /obj/item/weapon/circuitboard/syndicatedoor( A ) + if(istype(src, /obj/machinery/computer/pod/old/swf)) + M = new /obj/item/weapon/circuitboard/swfdoor( A ) + else //it's not an old computer. Generate standard pod circuitboard. + M = new /obj/item/weapon/circuitboard/pod( A ) + + for (var/obj/C in src) + C.loc = loc + M.id = id + A.circuit = M + A.state = 4 + A.icon_state = "4" + A.anchored = 1 + del(src) + else + attack_hand(user) + return + + +/obj/machinery/computer/pod/attack_ai(var/mob/user as mob) + return attack_hand(user) + + +/obj/machinery/computer/pod/attack_paw(var/mob/user as mob) + return attack_hand(user) + + +/obj/machinery/computer/pod/attack_hand(var/mob/user as mob) + if(..()) + return + + var/dat = "Mass Driver Controls" + user.machine = src + var/d2 + if (timing) + d2 = text("Stop Time Launch", src) + else + d2 = text("Initiate Time Launch", src) + var/second = time % 60 + var/minute = (time - second) / 60 + dat += text("
\nTimer System: []\nTime Left: [][] - - + +", d2, (minute ? text("[]:", minute) : null), second, src, src, src, src) + if (connected) + var/temp = "" + var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 ) + for(var/t in L) + if (t == connected.power) + temp += text("[] ", t) + else + temp += text("[] ", src, t, t) + //Foreach goto(172) + dat += text("
\nPower Level: []
\nFiring Sequence
\nTest Fire Driver
\nToggle Outer Door
", temp, src, src, src) + //*****RM from 40.93.3S + else + dat += text("
\nToggle Outer Door
", src) + //***** + dat += text("

Close
", user) + user << browse(dat, "window=computer;size=400x500") + onclose(user, "computer") + return + + +/obj/machinery/computer/pod/process() + ..() + if (timing) + if (time > 0) + time = round(time) - 1 + else + alarm() + time = 0 + timing = 0 + updateDialog() + return + + +/obj/machinery/computer/pod/Topic(href, href_list) + if(..()) + return + if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) + usr.machine = src + if (href_list["power"]) + var/t = text2num(href_list["power"]) + t = min(max(0.25, t), 16) + if (connected) + connected.power = t + else + if (href_list["alarm"]) + alarm() + else + if (href_list["time"]) + timing = text2num(href_list["time"]) + else + if (href_list["tp"]) + var/tp = text2num(href_list["tp"]) + time += tp + time = min(max(round(time), 0), 120) + else + if (href_list["door"]) + if(istype(src, /obj/machinery/computer/pod/old/syndicate))//Added here so Nuke ops don't go running naked into space before moving the shuttle. + if(syndicate_station_at_station == 0) + usr << "\red You need to launch the Syndicate Shuttle via the computer terminal at the head of the ship before departing." + return + for(var/obj/machinery/door/poddoor/M in world) + if (M.id == id) + if (M.density) + spawn( 0 ) + M.open() + return + else + spawn( 0 ) + M.close() + return + //Foreach goto(298) + add_fingerprint(usr) + updateUsrDialog() + return + + + +/obj/machinery/computer/pod/old + icon_state = "old" + name = "DoorMex Control Computer" + + + +/obj/machinery/computer/pod/old/syndicate + name = "ProComp Executive IIc" + desc = "The Syndicate operate on a tight budget. Operates external airlocks." + + + +/obj/machinery/computer/pod/old/swf + name = "Magix System IV" + desc = "An arcane artifact that holds much magic. Running E-Knock 2.2: Sorceror's Edition" diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 13a39ca1c5..567d4e23b2 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -1,3 +1,21 @@ + +/obj/machinery/computer/robotics + name = "Robotics Control" + desc = "Used to remotely lockdown or detonate linked Cyborgs." + icon = 'computer.dmi' + icon_state = "robot" + req_access = list(access_robotics) + circuit = "/obj/item/weapon/circuitboard/robotics" + + var + id = 0.0 + temp = null + status = 0 + timeleft = 60 + stop = 0.0 + screen = 0 // 0 - Main Menu, 1 - Cyborg Status, 2 - Kill 'em All! -- In text + + /obj/machinery/computer/robotics/attack_ai(var/mob/user as mob) return src.attack_hand(user) @@ -26,6 +44,9 @@ if(istype(user, /mob/living/silicon/robot)) if (R != user) continue + if(R.scrambledcodes) + continue + dat += "[R.name] |" if(R.stat) dat += " Not Responding |" @@ -140,10 +161,15 @@ if(R) var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort") if(choice == "Confirm") - if(R) - message_admins("\blue [key_name_admin(usr)] detonated [R.name]!") - log_game("\blue [key_name_admin(usr)] detonated [R.name]!") - R.self_destruct() + if(R && istype(R)) + if(R.mind && R.mind.special_role && R.emagged) + R << "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered." + R.ResetSecurityCodes() + + else + message_admins("\blue [key_name_admin(usr)] detonated [R.name]!") + log_game("\blue [key_name_admin(usr)] detonated [R.name]!") + R.self_destruct() else usr << "\red Access Denied." @@ -179,6 +205,8 @@ message_admins("\blue [key_name_admin(usr)] emagged [R.name] using robotic console!") log_game("[key_name(usr)] emagged [R.name] using robotic console!") R.emagged = 1 + if(R.mind.special_role) + R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes src.add_fingerprint(usr) src.updateUsrDialog() @@ -195,7 +223,8 @@ while(src.timeleft) for(var/mob/living/silicon/robot/R in world) - R.self_destruct() + if(!R.scrambledcodes) + R.self_destruct() return diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 479e8edf24..7cc8685c26 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -328,7 +328,7 @@ What a mess.*/ var/counter = 1 while(active2.fields[text("com_[]", counter)]) counter++ - active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2053
[]", authenticated, rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1) + active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2556
[]", authenticated, rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1) if ("Delete Record (ALL)") if (active1) diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm index 263b705624..c30890f0cb 100644 --- a/code/game/machinery/door_control.dm +++ b/code/game/machinery/door_control.dm @@ -71,7 +71,7 @@ else - for(var/obj/machinery/door/poddoor/M in machines) + for(var/obj/machinery/door/poddoor/M in world) if (M.id == src.id) if (M.density) spawn( 0 ) @@ -119,7 +119,7 @@ active = 1 icon_state = "launcheract" - for(var/obj/machinery/door/poddoor/M in machines) + for(var/obj/machinery/door/poddoor/M in world) if (M.id == src.id) spawn( 0 ) M.open() @@ -133,7 +133,7 @@ sleep(50) - for(var/obj/machinery/door/poddoor/M in machines) + for(var/obj/machinery/door/poddoor/M in world) if (M.id == src.id) spawn( 0 ) M.close() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 1b312f3026..cf99493deb 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -264,14 +264,14 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. ..() if (src.closeOtherId != null) spawn (5) - for (var/obj/machinery/door/airlock/A in machines) + for (var/obj/machinery/door/airlock/A in world) if (A.closeOtherId == src.closeOtherId && A != src) src.closeOther = A break open() - if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) + if(src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR) || src.operating) return 0 use_power(50) if(istype(src, /obj/machinery/door/airlock/glass)) @@ -284,7 +284,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. close() - if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + if(src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR) || src.operating) return ..() use_power(50) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 758a534704..fb7b3c6a1b 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -3,215 +3,388 @@ desc = "It opens and closes." icon = 'doorint.dmi' icon_state = "door1" + anchored = 1 opacity = 1 density = 1 layer = 2.7 - anchored = 1 - var/secondsElectrified = 0 - var/visible = 1 - var/p_open = 0 - var/operating = 0 - var/autoclose = 0 - var/glass = 0 - var/forcecrush = 0 - var/holdopen = 0 -/obj/machinery/door/Bumped(atom/AM) - if(p_open || operating) return - if(ismob(AM)) - var/mob/M = AM - if(world.time - AM.last_bumped <= 60) return //NOTE do we really need that? - if(M.client && !M:handcuffed) - bumpopen(M) - else if(istype(AM, /obj/machinery/bot)) - var/obj/machinery/bot/bot = AM - if(src.check_access(bot.botcard)) - if(density) - open() - else if(istype(AM, /obj/effect/critter)) - var/obj/effect/critter/critter = AM - if(critter.opensdoors) return - if(src.check_access_list(critter.access_list)) - if(density) - open() -// else if(istype(AM, /obj/effect/alien/facehugger)) -// if(src.check_access(null)) -// if(density) -// open() - else if(istype(AM, /obj/mecha)) - var/obj/mecha/mecha = AM + var + secondsElectrified = 0 + visible = 1 + p_open = 0 + operating = 0 + autoclose = 0 + glass = 0 + forcecrush = 0 + holdopen = 0 + + proc/bumpopen(mob/user as mob) + proc/update_nearby_tiles(need_rebuild) + proc/requiresID() return 1 + proc/animate(animation) + proc/open() + proc/close() + + New() + ..() if(density) - if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access))) + layer = 3.1 //Above most items if closed + else + layer = 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6 + update_nearby_tiles(need_rebuild=1) + return + + + Del() + update_nearby_tiles() + ..() + return + + //process() + //return + + Bumped(atom/AM) + if(p_open || operating) return + if(ismob(AM)) + var/mob/M = AM + if(world.time - AM.last_bumped <= 60) return //NOTE do we really need that? + if(M.client && !M:handcuffed) + bumpopen(M) + return + + if(istype(AM, /obj/machinery/bot)) + var/obj/machinery/bot/bot = AM + if(src.check_access(bot.botcard)) + if(density) + open() + return + + if(istype(AM, /obj/effect/critter)) + var/obj/effect/critter/critter = AM + if(critter.opensdoors) return + if(src.check_access_list(critter.access_list)) + if(density) + open() + return + + if(istype(AM, /obj/mecha)) + var/obj/mecha/mecha = AM + if(density) + if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access))) + open() + else + flick("door_deny", src) + return + return + + + CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(air_group) return 0 + if(istype(mover) && mover.checkpass(PASSGLASS)) + return !opacity + return !density + + + bumpopen(mob/user as mob) + if(operating) return + src.add_fingerprint(user) + if(!src.requiresID()) + user = null + + if(allowed(user) && density) + open() + else if(density) + flick("door_deny", src) + return + + meteorhit(obj/M as obj) + src.open() + return + + + attack_ai(mob/user as mob) + return src.attack_hand(user) + + + attack_paw(mob/user as mob) + return src.attack_hand(user) + + + attack_hand(mob/user as mob) + return src.attackby(user, user) + + + attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/device/detective_scanner)) + return ..() + if(src.operating || isrobot(user)) return //borgs can't attack doors open because it conflicts with their AI-like interaction with them. + src.add_fingerprint(user) + if(!src.requiresID()) + user = null + if(src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) + if(istype(I, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = I + if(E.uses) + E.uses-- + else + return + if(istype(I, /obj/item/weapon/melee/energy/blade)) + if(istype(src, /obj/machinery/door/airlock)) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, src.loc) + spark_system.start() + playsound(src.loc, 'blade1.ogg', 50, 1) + playsound(src.loc, "sparks", 50, 1) + for(var/mob/O in viewers(user, 3)) + O.show_message(text("\blue The door has been sliced open by [] with an energy blade!", user), 1, text("\red You hear metal being sliced and sparks flying."), 2) + if((!src:arePowerSystemsOn()) || (stat & NOPOWER) || src:isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + var/obj/structure/door_assembly/temp + var/failsafe=0 + switch(src:doortype) + if(0) temp=new/obj/structure/door_assembly/door_assembly_0(src.loc) + if(1) temp=new/obj/structure/door_assembly/door_assembly_com(src.loc) + if(2) temp=new/obj/structure/door_assembly/door_assembly_sec(src.loc) + if(3) temp=new/obj/structure/door_assembly/door_assembly_eng(src.loc) + if(4) temp=new/obj/structure/door_assembly/door_assembly_med(src.loc) + if(5) temp=new/obj/structure/door_assembly/door_assembly_mai(src.loc) + if(6) temp=new/obj/structure/door_assembly/door_assembly_ext(src.loc) + if(7) temp=new/obj/structure/door_assembly/door_assembly_g(src.loc) + else failsafe=1 + if(!failsafe) + temp.anchored=0 + step_away(temp,usr,15) + else del(temp) + del(src) + return + else + src:welded = 0 + src:locked = 0 + update_icon() + flick("door_spark", src) + sleep(6) + open() + operating = -1 + return 1 + if(src.allowed(user)) + if(src.density) open() else - flick("door_deny", src) - - -/obj/machinery/door/proc/bumpopen(mob/user as mob) - if (src.operating) + var/holdopen_old = holdopen + holdopen = 0 + close() + spawn(1) + holdopen = holdopen_old + else if (src.density) + flick("door_deny", src) return - //if(world.timeofday-last_used <= 10) - // return - src.add_fingerprint(user) - if (!src.requiresID()) - //don't care who they are or what they have, act as if they're NOTHING - user = null - if (src.allowed(user)) - if (src.density) - //last_used = world.timeofday + + blob_act() + if(prob(40)) + del(src) + return + + + emp_act(severity) + if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) ) open() - else if (src.density) - flick("door_deny", src) - return + if(prob(40/severity)) + if(secondsElectrified == 0) + secondsElectrified = -1 + spawn(300) + secondsElectrified = 0 + ..() -/obj/machinery/door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group) return 0 - if(istype(mover) && mover.checkpass(PASSGLASS)) - return !opacity - return !density - -/obj/machinery/door/proc/update_nearby_tiles(need_rebuild) - if(!air_master) return 0 - - var/turf/simulated/source = loc - var/turf/simulated/north = get_step(source,NORTH) - var/turf/simulated/south = get_step(source,SOUTH) - var/turf/simulated/east = get_step(source,EAST) - var/turf/simulated/west = get_step(source,WEST) - - if(need_rebuild) - if(istype(source)) //Rebuild/update nearby group geometry - if(source.parent) - air_master.groups_to_rebuild += source.parent - else - air_master.tiles_to_update += source - if(istype(north)) - if(north.parent) - air_master.groups_to_rebuild += north.parent - else - air_master.tiles_to_update += north - if(istype(south)) - if(south.parent) - air_master.groups_to_rebuild += south.parent - else - air_master.tiles_to_update += south - if(istype(east)) - if(east.parent) - air_master.groups_to_rebuild += east.parent - else - air_master.tiles_to_update += east - if(istype(west)) - if(west.parent) - air_master.groups_to_rebuild += west.parent - else - air_master.tiles_to_update += west - else - if(istype(source)) air_master.tiles_to_update += source - if(istype(north)) air_master.tiles_to_update += north - if(istype(south)) air_master.tiles_to_update += south - if(istype(east)) air_master.tiles_to_update += east - if(istype(west)) air_master.tiles_to_update += west - - return 1 - -/obj/machinery/door/New() - ..() - if(density) - layer = 3.1 //Above most items if closed - else - layer = 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6 - update_nearby_tiles(need_rebuild=1) - -/obj/machinery/door/Del() - update_nearby_tiles() - - ..() - - -/obj/machinery/door/meteorhit(obj/M as obj) - src.open() - return - -/obj/machinery/door/attack_ai(mob/user as mob) - return src.attack_hand(user) - -/obj/machinery/door/attack_paw(mob/user as mob) - return src.attack_hand(user) - -/obj/machinery/door/attack_hand(mob/user as mob) - return src.attackby(user, user) - -/obj/machinery/door/proc/requiresID() - return 1 - -/obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/device/detective_scanner)) - return ..() - if (src.operating || isrobot(user)) - return - src.add_fingerprint(user) - if (!src.requiresID()) - //don't care who they are or what they have, act as if they're NOTHING - user = null - if (src.density && (istype(I, /obj/item/weapon/card/emag) ||istype(I, /obj/item/weapon/melee/energy/blade))) - if(istype(I, /obj/item/weapon/card/emag)) - var/obj/item/weapon/card/emag/E = I - if(E.uses) - E.uses-- - else - return - src.operating = -1 - if(istype(I, /obj/item/weapon/melee/energy/blade)) - if(istype(src, /obj/machinery/door/airlock)) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - for(var/mob/O in viewers(user, 3)) - O.show_message(text("\blue The door has been sliced open by [] with an energy blade!", user), 1, text("\red You hear metal being sliced and sparks flying."), 2) - if((!src:arePowerSystemsOn()) || (stat & NOPOWER) || src:isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - var/obj/structure/door_assembly/temp - var/failsafe=0 - switch(src:doortype) - if(0) temp=new/obj/structure/door_assembly/door_assembly_0(src.loc) - if(1) temp=new/obj/structure/door_assembly/door_assembly_com(src.loc) - if(2) temp=new/obj/structure/door_assembly/door_assembly_sec(src.loc) - if(3) temp=new/obj/structure/door_assembly/door_assembly_eng(src.loc) - if(4) temp=new/obj/structure/door_assembly/door_assembly_med(src.loc) - if(5) temp=new/obj/structure/door_assembly/door_assembly_mai(src.loc) - if(6) temp=new/obj/structure/door_assembly/door_assembly_ext(src.loc) - if(7) temp=new/obj/structure/door_assembly/door_assembly_g(src.loc) - else failsafe=1 - if(!failsafe) - temp.anchored=0 - step_away(temp,usr,15) - else del(temp) + ex_act(severity) + switch(severity) + if(1.0) + del(src) + if(2.0) + if(prob(25)) del(src) - return - else - src:welded = 0 - src:locked = 0 - update_icon() - flick("door_spark", src) - sleep(6) - open() - return 1 - if (src.allowed(user)) - if (src.density) - open() + if(3.0) + if(prob(80)) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, src) + s.start() + return + + + update_icon() + if(density) + icon_state = "door1" else - var/holdopen_old = holdopen - holdopen = 0 - close() - spawn(1) - holdopen = holdopen_old - else if (src.density) - flick("door_deny", src) + icon_state = "door0" + return + + + animate(animation) + switch(animation) + if("opening") + if(p_open) + flick("o_doorc0", src) + else + flick("doorc0", src) + if("closing") + if(p_open) + flick("o_doorc1", src) + else + flick("doorc1", src) + if("deny") + flick("door_deny", src) + return + + + open() + if(!density) return 1 + if (src.operating == 1) //doors can still open when emag-disabled + return + if(!ticker) return 0 + if(!src.operating) //in case of emag + src.operating = 1 + animate("opening") + src.sd_SetOpacity(0) + sleep(10) + src.layer = 2.7 + src.density = 0 + update_icon() + src.sd_SetOpacity(0) + update_nearby_tiles() + + if(operating == 1) //emag again + src.operating = 0 + + if(autoclose) + spawn(150) + autoclose() + + return 1 + + close() + if(density) + return 1 + if (src.operating) + return + src.operating = 1 + + var/X = src:x + var/Y = src:y + var/Z = src:z + var/held = 1 + + if(src.holdopen && !forcecrush) + while(held == 1 && holdopen && !forcecrush) //If it is no longer hold open, it should close. + sleep(held? 10:40) + held = 0 + var/list/objects = locate(X,Y,Z) + for(var/obj/T in objects) + if(!istype(T,/obj/machinery/door) && !(istype(T,/obj/machinery) && T.anchored == 1) && !istype(T,/obj/structure/cable) && !istype(T,/obj/structure/disposalpipe) && !(T.loc == get_turf(src))) + held = 1 + for(var/mob/living/T in objects) //Geez, ghosts were OP. + held = 1 + animate("closing") + src.density = 1 + spawn(4) + if(!istype(src, /obj/machinery/door/window)) + for(var/mob/living/L in src.loc) // Crush mobs and move them out of the way + + if(src.forcecrush) // Save an AI, crush a limb + var/limbname = pick("l_arm", "r_arm", "l_hand","r_hand", "l_foot", "r_foot") + var/limbdisplay + + for(var/organ in L:organs) + var/datum/organ/external/temp = L:organs["[organ]"] + if (istype(temp, /datum/organ/external) && temp.name == limbname) + limbdisplay = temp.display_name // Take the name for down below + temp.take_damage(rand(50,80), 0) //OH GOD IT HURTS + break + + L << "\red The airlock crushes your [limbdisplay]!" + for(var/mob/O in viewers(L, null)) + if(O == L) + continue + O.show_message("\red The airlock crushes [L.name]'s [limbdisplay]!", 1) + sleep(rand(2,8)) + + L << "\red The airlock forces you out of the way!" //Lucky you + for(var/mob/O in viewers(L, null)) + O.show_message("\red The airlock pushes [L.name] out of the way!", 1) + var/list/lst = list(NORTH,SOUTH,EAST,WEST) + var/turf/T = get_random_turf(L, lst) + if(T) + L.loc = T + + if(!src.forcecrush) + for(var/obj/item/I in src.loc) // Move items out of the way + if(!I.anchored) + var/list/lst = list(NORTH,SOUTH,EAST,WEST) + var/turf/T = get_random_turf(I, lst) + if(T) + I.loc = T + + sleep(6) + update_icon() + + if(src.visible && (!src.glass)) + src.sd_SetOpacity(1) + if(operating == 1) + operating = 0 + update_nearby_tiles() + return + + + update_nearby_tiles(need_rebuild) + if(!air_master) return 0 + + var/turf/simulated/source = loc + var/turf/simulated/north = get_step(source,NORTH) + var/turf/simulated/south = get_step(source,SOUTH) + var/turf/simulated/east = get_step(source,EAST) + var/turf/simulated/west = get_step(source,WEST) + + if(need_rebuild) + if(istype(source)) //Rebuild/update nearby group geometry + if(source.parent) + air_master.groups_to_rebuild += source.parent + else + air_master.tiles_to_update += source + if(istype(north)) + if(north.parent) + air_master.groups_to_rebuild += north.parent + else + air_master.tiles_to_update += north + if(istype(south)) + if(south.parent) + air_master.groups_to_rebuild += south.parent + else + air_master.tiles_to_update += south + if(istype(east)) + if(east.parent) + air_master.groups_to_rebuild += east.parent + else + air_master.tiles_to_update += east + if(istype(west)) + if(west.parent) + air_master.groups_to_rebuild += west.parent + else + air_master.tiles_to_update += west + else + if(istype(source)) air_master.tiles_to_update += source + if(istype(north)) air_master.tiles_to_update += north + if(istype(south)) air_master.tiles_to_update += south + if(istype(east)) air_master.tiles_to_update += east + if(istype(west)) air_master.tiles_to_update += west + return 1 + + +/obj/machinery/door/proc/autoclose() + var/obj/machinery/door/airlock/A = src + if ((!A.density) && !( A.operating ) && !(A.locked) && !( A.welded )) + close() return + /obj/machinery/door/airlock/proc/ion_act() if(src.z == 1 && src.density) if(length(req_access) > 0 && !(12 in req_access)) @@ -238,212 +411,3 @@ else close() return - -/obj/machinery/door/blob_act() - if(prob(40)) - del(src) - -/obj/machinery/door/emp_act(severity) - if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) ) - open() - if(prob(40/severity)) - if(secondsElectrified == 0) - secondsElectrified = -1 - spawn(300) - secondsElectrified = 0 - ..() - -/obj/machinery/door/ex_act(severity) - switch(severity) - if(1.0) - del(src) - if(2.0) - if(prob(25)) - del(src) - if(3.0) - if(prob(80)) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, src) - s.start() - -/obj/machinery/door/update_icon() - if(density) - icon_state = "door1" - else - icon_state = "door0" - return - -/obj/machinery/door/proc/animate(animation) - switch(animation) - if("opening") - if(p_open) - flick("o_doorc0", src) - else - flick("doorc0", src) - if("closing") - if(p_open) - flick("o_doorc1", src) - else - flick("doorc1", src) - if("deny") - flick("door_deny", src) - return - -/obj/machinery/door/proc/open() - if(!density) - return 1 - if (src.operating == 1) //doors can still open when emag-disabled - return - if (!ticker) - return 0 - if(!src.operating) //in case of emag - src.operating = 1 - - animate("opening") - src.sd_SetOpacity(0) - sleep(10) - src.layer = 2.7 - src.density = 0 - update_icon() - - src.sd_SetOpacity(0) - update_nearby_tiles() - - if(operating == 1) //emag again - src.operating = 0 - - if(autoclose) - spawn(150) - autoclose() - return 1 - -/obj/machinery/door/proc/close() - if(density) - return 1 - if (src.operating) - return - src.operating = 1 - - var/X = src:x - var/Y = src:y - var/Z = src:z - var/held = 1 - - if(src.holdopen && !forcecrush) - while(held == 1 && holdopen && !forcecrush) //If it is no longer hold open, it should close. - sleep(held? 10:40) - held = 0 - var/list/objects = locate(X,Y,Z) - for(var/obj/T in objects) - if(!istype(T,/obj/machinery/door) && !(istype(T,/obj/machinery) && T.anchored == 1) && !istype(T,/obj/structure/cable) && !istype(T,/obj/structure/disposalpipe) && !(T.loc == get_turf(src))) - held = 1 - for(var/mob/living/T in objects) //Geez, ghosts were OP. - held = 1 - animate("closing") - src.density = 1 - spawn(4) - if(!istype(src, /obj/machinery/door/window)) - for(var/mob/living/L in src.loc) // Crush mobs and move them out of the way - - if(src.forcecrush) // Save an AI, crush a limb - var/limbname = pick("l_arm", "r_arm", "l_hand","r_hand", "l_foot", "r_foot") - var/limbdisplay - - for(var/organ in L:organs) - var/datum/organ/external/temp = L:organs["[organ]"] - if (istype(temp, /datum/organ/external) && temp.name == limbname) - limbdisplay = temp.display_name // Take the name for down below - temp.take_damage(rand(50,80), 0) //OH GOD IT HURTS - break - - L << "\red The airlock crushes your [limbdisplay]!" - for(var/mob/O in viewers(L, null)) - if(O == L) - continue - O.show_message("\red The airlock crushes [L.name]'s [limbdisplay]!", 1) - sleep(rand(2,8)) - - L << "\red The airlock forces you out of the way!" //Lucky you - for(var/mob/O in viewers(L, null)) - O.show_message("\red The airlock pushes [L.name] out of the way!", 1) - var/list/lst = list(NORTH,SOUTH,EAST,WEST) - var/turf/T = get_random_turf(L, lst) - if(T) - L.loc = T - - if(!src.forcecrush) - for(var/obj/item/I in src.loc) // Move items out of the way - if(!I.anchored) - var/list/lst = list(NORTH,SOUTH,EAST,WEST) - var/turf/T = get_random_turf(I, lst) - if(T) - I.loc = T - - sleep(6) - update_icon() - - if(src.visible && (!src.glass)) - src.sd_SetOpacity(1) - if(operating == 1) - operating = 0 - update_nearby_tiles() - -/obj/machinery/door/proc/autoclose() - var/obj/machinery/door/airlock/A = src - if ((!A.density) && !( A.operating ) && !(A.locked) && !( A.welded )) - close() - else return - -/////////////////////////////////////////////////// Unpowered doors - -/obj/machinery/door/unpowered/Bumped(atom/AM) - if(p_open || operating) return - if (src.locked) - return - if(ismob(AM)) - var/mob/M = AM - if(world.time - AM.last_bumped <= 60) return - if(M.client && !M:handcuffed) - bumpopen(M) - else if(istype(AM, /obj/machinery/bot)) - var/obj/machinery/bot/bot = AM - if(src.check_access(bot.botcard)) - if(density) - open() -// else if(istype(AM, /obj/effect/alien/facehugger)) -// if(src.check_access(null)) -// if(density) -// open() - -/obj/machinery/door/unpowered - autoclose = 0 - var/locked = 0 - -/obj/machinery/door/unpowered/attack_ai(mob/user as mob) - return src.attack_hand(user) - -/obj/machinery/door/unpowered/attack_paw(mob/user as mob) - return src.attack_hand(user) - -/obj/machinery/door/unpowered/attack_hand(mob/user as mob) - return src.attackby(null, user) - -/obj/machinery/door/unpowered/attackby(obj/item/I as obj, mob/user as mob) - if (src.operating) - return - if (src.locked) - return - src.add_fingerprint(user) - if (src.allowed(user)) - if (src.density) - open() - else - close() - return - -/obj/machinery/door/unpowered/shuttle - icon = 'shuttle.dmi' - name = "door" - icon_state = "door1" - opacity = 1 - density = 1 \ No newline at end of file diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm index c6adc99cf4..36cd2095ba 100644 --- a/code/game/machinery/doors/unpowered.dm +++ b/code/game/machinery/doors/unpowered.dm @@ -1,5 +1,6 @@ /obj/machinery/door/unpowered autoclose = 0 + var/locked = 0 Bumped(atom/AM) diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index dae31678c8..5af17e377e 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -62,7 +62,6 @@ obj/machinery/embedded_controller update_icon() src.updateDialog() - ..() radio var/frequency diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 8e240470ef..aa29cef3ab 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -70,12 +70,18 @@ continue if (istype(O, /mob/living/carbon/human)) var/mob/living/carbon/human/H = O - if (istype(H.glasses, /obj/item/clothing/glasses/sunglasses)) continue + if (istype(H.glasses, /obj/item/clothing/glasses/sunglasses)) + continue if (istype(H.head, /obj/item/clothing/head/helmet/welding)) - if(!H.head:up) continue - if (istype(H.wear_mask, /obj/item/clothing/mask/gas/voice)) continue + if(!H.head:up) + continue + if (istype(H.wear_mask, /obj/item/clothing/mask/gas/voice)) + continue if (istype(O, /mob/living/carbon/alien))//So aliens don't get flashed (they have no external eyes)/N continue + if (istype(O, /mob/living/silicon/robot)) + if(O:flashproof()) + continue O.Weaken(strength) if ((O.eye_stat > 15 && prob(O.eye_stat + 50))) diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm new file mode 100644 index 0000000000..08e13e535c --- /dev/null +++ b/code/game/machinery/floodlight.dm @@ -0,0 +1,108 @@ +/obj/machinery/floodlight + name = "Emergency Floodlight" + icon = 'floodlight.dmi' + icon_state = "flood00" + density = 1 + var/on = 0 + var/obj/item/weapon/cell/cell = null + var/use = 1 + var/unlocked = 0 + var/open = 0 + +/obj/machinery/floodlight/proc/updateicon() + icon_state = "flood[open ? "o" : ""][open && cell ? "b" : ""]0[on]" + +/obj/machinery/floodlight/process() + if (!on) + if (luminosity) + 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 + +/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 + else + user.r_hand = cell + + cell.add_fingerprint(user) + updateicon() + cell.updateicon() + + src.cell = null + user << "You remove the power cell" + return + + if(on) + on = 0 + user << "You turn off the light" + else + if(!cell) + return + if(cell.charge <= 0) + return + on = 1 + user << "You turn on the light" + + updateicon() + + +/obj/machinery/floodlight/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/screwdriver)) + if (!open) + if(unlocked) + unlocked = 0 + user << "You screw the battery panel in place." + else + unlocked = 1 + user << "You unscrew the battery panel." + + if (istype(W, /obj/item/weapon/crowbar)) + if(unlocked) + if(open) + open = 0 + overlays = null + user << "You crowbar the battery panel in place." + else + if(unlocked) + open = 1 + user << "You remove the battery panel." + + if (istype(W, /obj/item/weapon/cell)) + if(open) + if(cell) + user << "There is a power cell already installed." + else + user.drop_item() + W.loc = src + 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/hologram.dm b/code/game/machinery/hologram.dm index 55fa212c5e..d286943583 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -11,6 +11,20 @@ Possible to do for anyone motivated enough: Give an AI variable for different hologram icons. Itegrate EMP effect to disable the unit. */ +/obj/machinery/hologram/holopad/attack_hand(var/mob/living/carbon/human/user) //Carn: Hologram requests. + if(!istype(user)) + return + if(alert(user,"Would you like to request an AI's presence?",,"Yes","No") == "Yes") + if(last_request + 200 < world.time) //don't spam the AI with requests you jerk! + last_request = world.time + user << "You request an AI's presence." + var/area/area = get_area(src) + for(var/mob/living/silicon/ai/AI in world) + if(!AI.client) continue + AI << "Your presence is requested at \the [area]." + else + user << "A request for AI presence was already sent recently." + /obj/machinery/hologram/holopad/attack_ai(mob/living/silicon/ai/user) if (!istype(user)) return diff --git a/code/game/machinery/hydroponics.dm b/code/game/machinery/hydroponics.dm index 85a1d818b2..904e24861d 100644 --- a/code/game/machinery/hydroponics.dm +++ b/code/game/machinery/hydroponics.dm @@ -191,10 +191,10 @@ obj/machinery/hydroponics/proc/weedinvasion() // If a weed growth is sufficient, src.myseed = new /obj/item/seeds/harebell if(10 to 11) src.myseed = new /obj/item/seeds/amanitamycelium - if(6 to 9) + if(8 to 9) src.myseed = new /obj/item/seeds/chantermycelium - //if(6 to 7) implementation for tower caps still kinda missing - // src.myseed = new /obj/item/seeds/towermycelium + if(6 to 7) // implementation for tower caps still kinda missing ~ Not Anymore! -Cheridan + src.myseed = new /obj/item/seeds/towermycelium if(4 to 5) src.myseed = new /obj/item/seeds/plumpmycelium else @@ -671,13 +671,8 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob) else if (istype(O, /obj/item/weapon/minihoe)) // The minihoe //var/deweeding if(src.weedlevel > 0) - user.visible_message("\red [user] starts uprooting the weeds.", "\red You start removing some weeds from the tray.") - sleep(10) - if(src.weedlevel > 1) - src.weedlevel -= rand(1,2) // Kill kill kill - else - src.weedlevel = 0 - user << "Success!" + user.visible_message("\red [user] starts uprooting the weeds.", "\red You remove the weeds from the tray.") + src.weedlevel = 0 else user << "\red This plot is completely devoid of weeds. It doesn't need uprooting." diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 2bb6477e82..9c4852d16a 100755 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -89,7 +89,6 @@ flick("[base_state]-spark", src) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, src) s.start() src.last_spark = world.time @@ -124,12 +123,12 @@ active = 1 icon_state = "launcheract" - for(var/obj/machinery/sparker/M in machines) + for(var/obj/machinery/sparker/M in world) if (M.id == src.id) spawn( 0 ) M.ignite() - for(var/obj/machinery/igniter/M in machines) + for(var/obj/machinery/igniter/M in world) if(M.id == src.id) use_power(50) M.on = !( M.on ) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 49892a3331..583c0f91e1 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -100,7 +100,16 @@ Class Procs: ..() /obj/machinery/process()//If you dont use process or power why are you here -// machines.Remove(src)Not going to do this till I test it a bit more + + /* + Big note: if do not call ..() in any machinery subtype process() call or it will + be removed from the list of machines to iterate. It is, however, okay to call ..() + if the machine has a parent process() call. For instance, machinery/atmosphereics has a + root process() call, so things like cryocells can call ..() and not worry about + it getting removed from machines. + */ + + machines.Remove(src) // uncommented by Doohl return /obj/machinery/emp_act(severity) diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index c874cb2273..46385e4686 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -129,7 +129,6 @@ process() - ..() if(stat & NOPOWER) on = 0 @@ -238,7 +237,6 @@ process() - ..() if(magnets.len == 0 && autolink) for(var/obj/machinery/magnetic_module/M in world) if(M.freq == frequency && M.code == code) diff --git a/code/game/machinery/morgue.dm b/code/game/machinery/morgue.dm index 48ed0675ae..8c65e0a72f 100644 --- a/code/game/machinery/morgue.dm +++ b/code/game/machinery/morgue.dm @@ -316,7 +316,7 @@ return /obj/structure/c_tray/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) - if ((!( istype(O, /atom/movable) ) || O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src))) + if ((!( istype(O, /atom/movable) ) || O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src) || istype(user, /mob/dead))) return O.loc = src.loc if (user != O) diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index ea85c63b6b..3310a68b6f 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -40,6 +40,7 @@ var/auth_weapons = 0 // checks if it can shoot people that have a weapon they aren't authorized to have var/stun_all = 0 // if this is active, the turret shoots everything that isn't security or head of staff var/check_anomalies = 1 // checks if it can shoot at unidentified lifeforms (ie xenos) + var/ai = 0 // if active, will shoot at anything not an AI or cyborg var/attacked = 0 // if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!) @@ -317,11 +318,20 @@ Neutralize All Unidentified Life Signs: []
"}, if(emagged) // if emagged, HOLY SHIT EVERYONE IS DANGEROUS beep boop beep targets += C else - - if (C.stat || C.handcuffed) // if the perp is handcuffed or dead/dying, no need to bother really continue // move onto next potential victim! + var/dst = get_dist(src, C) // if it's too far away, why bother? + if (dst > 12) + continue + + if(!istype(C, /mob/living/silicon) && ai) // If it's set to attack all nonsilicons, target them! + if(C.lying) + secondarytargets += C + else + targets += C + continue + if (istype(C, /mob/living/carbon/human)) // if the target is a human, analyze threat level if(src.assess_perp(C)<4) continue // if threat level < 4, keep going @@ -329,10 +339,6 @@ Neutralize All Unidentified Life Signs: []
"}, else if (istype(C, /mob/living/carbon/monkey) || istype(C, /mob/living/silicon)) continue // Don't target monkeys or borgs/AIs you dumb shit - var/dst = get_dist(src, C) // if it's too far away, why bother? - if (dst > 12) - continue - if (C.lying) // if the perp is lying down, it's still a target but a less-important target secondarytargets += C continue diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index bfb5c85678..7987769849 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -1,5 +1,5 @@ obj/machinery/recharger - anchored = 1.0 + anchored = 1 icon = 'stationobjs.dmi' icon_state = "recharger0" name = "recharger" @@ -11,62 +11,80 @@ obj/machinery/recharger obj/item/weapon/gun/energy/charging = null obj/item/weapon/melee/baton/charging2 = null -/obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob) - if (src.charging || src.charging2) - return - if (istype(G, /obj/item/weapon/gun/energy)) - if (istype(G, /obj/item/weapon/gun/energy/gun/nuclear) || istype(G, /obj/item/weapon/gun/energy/crossbow)) - user << "Your gun's recharge port was removed to make room for a miniaturized reactor." - return - if (istype(G, /obj/item/weapon/gun/energy/staff)) - user << "It's a wooden staff, not a gun!" - return - user.drop_item() - G.loc = src - src.charging = G - use_power = 2 - if (istype(G, /obj/item/weapon/melee/baton)) - user.drop_item() - G.loc = src - src.charging2 = G - use_power = 2 + attackby(obj/item/weapon/G as obj, mob/user as mob) + if (istype(G, /obj/item/weapon/gun/energy)) + if (src.charging || src.charging2) + return + if (istype(G, /obj/item/weapon/gun/energy/gun/nuclear) || istype(G, /obj/item/weapon/gun/energy/crossbow)) + user << "Your gun's recharge port was removed to make room for a miniaturized reactor." + return + if (istype(G, /obj/item/weapon/gun/energy/staff)) + user << "It's a wooden staff, not a gun!" + return + var/area/a = loc.loc // Gets our locations location, like a dream within a dream + if(!isarea(a)) + return + if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power! + user << "\red The recharger rejects the weapon!" + return + user.drop_item() + G.loc = src + src.charging = G + use_power = 2 + else if (istype(G, /obj/item/weapon/melee/baton)) + if (src.charging || src.charging2) + return + user.drop_item() + G.loc = src + src.charging2 = G + use_power = 2 + else if(istype(G, /obj/item/weapon/wrench)) + if (src.charging || src.charging2) + user << "\red Remove the weapon first!" + return + anchored = !anchored + user << "You [anchored ? "attach" : "detach"] the recharger [anchored ? "to" : "from"] the ground" + playsound(src.loc, 'Ratchet.ogg', 75, 1) -/obj/machinery/recharger/attack_hand(mob/user as mob) - src.add_fingerprint(user) - if(ishuman(user)) - if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining) - call(/obj/item/clothing/gloves/space_ninja/proc/drain)("MACHINERY",src,user:wear_suit) + attack_hand(mob/user as mob) + src.add_fingerprint(user) + if(ishuman(user)) + if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining) + call(/obj/item/clothing/gloves/space_ninja/proc/drain)("MACHINERY",src,user:wear_suit) + return + + if (src.charging) + src.charging.update_icon() + src.charging.loc = src.loc + src.charging = null + use_power = 1 + if(src.charging2) + src.charging2.update_icon() + src.charging2.loc = src.loc + src.charging2 = null + use_power = 1 + + attack_paw(mob/user as mob) + if ((ticker && ticker.mode.name == "monkey")) + return src.attack_hand(user) + + process() + if(stat & (NOPOWER|BROKEN) || !anchored) return - if (src.charging) - src.charging.update_icon() - src.charging.loc = src.loc - src.charging = null - use_power = 1 - if(src.charging2) - src.charging2.update_icon() - src.charging2.loc = src.loc - src.charging2 = null - use_power = 1 - -/obj/machinery/recharger/attack_paw(mob/user as mob) - if ((ticker && ticker.mode.name == "monkey")) - return src.attack_hand(user) - -/obj/machinery/recharger/process() - if ((src.charging) && ! (stat & NOPOWER) ) - if (src.charging.power_supply.charge < src.charging.power_supply.maxcharge) - src.charging.power_supply.give(100) - src.icon_state = "recharger1" - use_power(250) + if (src.charging) + if (src.charging.power_supply.charge < src.charging.power_supply.maxcharge) + src.charging.power_supply.give(100) + src.icon_state = "recharger1" + use_power(250) + else + src.icon_state = "recharger2" + else if (src.charging2) + if (src.charging2.charges < src.charging2.maximum_charges) + src.charging2.charges++ + src.icon_state = "recharger1" + use_power(250) + else + src.icon_state = "recharger2" else - src.icon_state = "recharger2" - if ((src.charging2) && ! (stat & NOPOWER) ) - if (src.charging2.charges < src.charging2.maximum_charges) - src.charging2.charges++ - src.icon_state = "recharger1" - use_power(250) - else - src.icon_state = "recharger2" - else if (!(src.charging || src.charging2)) - src.icon_state = "recharger0" + src.icon_state = "recharger0" diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 8ff52bdddd..ca7d1dbb66 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -16,7 +16,6 @@ build_icon() process() - ..() if(!(NOPOWER|BROKEN)) return @@ -89,10 +88,14 @@ if(istype(O,/obj/item/device/flash)) if(O:broken) O:broken = 0 + O:times_used = 0 O:icon_state = "flash" if(istype(O,/obj/item/weapon/gun/energy/taser/cyborg)) if(O:power_supply.charge < O:power_supply.maxcharge) - O:power_supply.give(100) + O:power_supply.give(O:charge_cost) + O:update_icon() + else + O:charge_tick = 0 if(istype(O,/obj/item/weapon/melee/baton)) if(O:charges < 10) O:charges += 1 @@ -136,8 +139,9 @@ //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO return usr.pulling = null - usr.client.perspective = EYE_PERSPECTIVE - usr.client.eye = src + if(usr && usr.client) + usr.client.perspective = EYE_PERSPECTIVE + usr.client.eye = src usr.loc = src src.occupant = usr /*for(var/obj/O in src) diff --git a/code/game/machinery/sink.dm b/code/game/machinery/sink.dm index 7ee566c84a..7927772702 100644 --- a/code/game/machinery/sink.dm +++ b/code/game/machinery/sink.dm @@ -76,6 +76,13 @@ user << "\red Someone's already washing something here." return + if (istype(O, (/obj/item/weapon/reagent_containers/glass/bucket || /obj/item/weapon/reagent_containers/glass/watercan))) + O:reagents.add_reagent("water", 70) + user.visible_message( \ + "\blue [user] fills the [O] using the [src].", \ + "\blue You fill the [O] using the [src].") + return + if (istype(O, /obj/item/weapon/reagent_containers/glass) || istype(O,/obj/item/weapon/reagent_containers/food/drinks)) if(!mode) // fill diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index 2ead66f3eb..7d87be6345 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -90,19 +90,25 @@ del(src) + attack_ai(var/mob/user as mob) + attack_hand(user) + attack_hand(var/mob/user as mob) - // You need a multitool to use this. - if(user.equipped()) - if(!istype(user.equipped(), /obj/item/device/multitool)) + // You need a multitool to use this, or be silicon + if(!issilicon(user)) + if(user.equipped()) + if(!istype(user.equipped(), /obj/item/device/multitool)) + return + else return - else - return if(stat & (BROKEN|NOPOWER) || !on) return - var/obj/item/device/multitool/P = user.equipped() + var/obj/item/device/multitool/P = null + if(!issilicon(user)) + P = user.equipped() user.machine = src var/dat @@ -138,10 +144,12 @@ dat += "
\[Add Filter\]" dat += "
" - if(P.buffer) - dat += "

MULTITOOL BUFFER: [P.buffer] ([P.buffer.id]) \[Link\] \[Flush\]" - else - dat += "

MULTITOOL BUFFER:
\[Add Machine\]" + + if(P) + if(P.buffer) + dat += "

MULTITOOL BUFFER: [P.buffer] ([P.buffer.id]) \[Link\] \[Flush\]" + else + dat += "

MULTITOOL BUFFER:
\[Add Machine\]" dat += "" temp = "" @@ -150,16 +158,19 @@ Topic(href, href_list) - if(usr.equipped()) - if(!istype(usr.equipped(), /obj/item/device/multitool)) + if(!issilicon(usr)) + if(usr.equipped()) + if(!istype(usr.equipped(), /obj/item/device/multitool)) + return + else return - else - return if(stat & (BROKEN|NOPOWER) || !on) return - var/obj/item/device/multitool/P = usr.equipped() + var/obj/item/device/multitool/P = null + if(!issilicon(usr)) + P = usr.equipped() if(href_list["input"]) switch(href_list["input"]) @@ -205,27 +216,30 @@ if(href_list["unlink"]) - var/obj/machinery/telecomms/T = links[text2num(href_list["unlink"])] - temp = "-% Removed \ref[T] [T.name] from linked entities. %-" + if(text2num(href_list["unlink"]) <= length(links)) + var/obj/machinery/telecomms/T = links[text2num(href_list["unlink"])] + temp = "-% Removed \ref[T] [T.name] from linked entities. %-" - // Remove link entries from both T and src. - if(src in T.links) - T.links.Remove(src) - links.Remove(T) + // Remove link entries from both T and src. + if(src in T.links) + T.links.Remove(src) + links.Remove(T) if(href_list["link"]) - if(P.buffer) - if(!(src in P.buffer.links)) - P.buffer.links.Add(src) + if(P) - if(!(P.buffer in src.links)) - src.links.Add(P.buffer) + if(P.buffer) + if(!(src in P.buffer.links)) + P.buffer.links.Add(src) - temp = "-% Successfully linked with \ref[P.buffer] [P.buffer.name] %-" + if(!(P.buffer in src.links)) + src.links.Add(P.buffer) - else - temp = "-% Unable to acquire buffer %-" + temp = "-% Successfully linked with \ref[P.buffer] [P.buffer.name] %-" + + else + temp = "-% Unable to acquire buffer %-" if(href_list["buffer"]) @@ -244,3 +258,4 @@ updateUsrDialog() + diff --git a/code/game/machinery/telecomms/telemonitor.dm b/code/game/machinery/telecomms/telemonitor.dm index 1866477d7a..b777f24a70 100644 --- a/code/game/machinery/telecomms/telemonitor.dm +++ b/code/game/machinery/telecomms/telemonitor.dm @@ -108,7 +108,7 @@ if(href_list["network"]) var/newnet = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text - if(newnet && usr in range(1, src)) + if(newnet && ((usr in range(1, src) || issilicon(usr)))) if(length(newnet) > 15) temp = "- FAILED: NETWORK TAG STRING TOO LENGHTLY -" diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm index 972c36e911..accfd0abea 100644 --- a/code/game/machinery/telecomms/traffic_control.dm +++ b/code/game/machinery/telecomms/traffic_control.dm @@ -35,7 +35,7 @@ winset(editingcode, "tcscode", "is-disabled=false") // If the player's not manning the keyboard anymore, adjust everything - if(!(editingcode in range(1, src)) || editingcode.machine != src) + if( (!(editingcode in range(1, src)) && !issilicon(editingcode)) || (editingcode.machine != src && !issilicon(editingcode))) if(editingcode) winshow(editingcode, "Telecomms IDE", 0) // hide the window! editingcode = null @@ -169,6 +169,7 @@ editingcode = usr winshow(editingcode, "Telecomms IDE", 1) // show the IDE winset(editingcode, "tcscode", "is-disabled=false") + winset(editingcode, "tcscode", "text=\"\"") var/showcode = dd_replacetext(storedcode, "\\\"", "\\\\\"") showcode = dd_replacetext(storedcode, "\"", "\\\"") winset(editingcode, "tcscode", "text=\"[showcode]\"") @@ -189,7 +190,7 @@ var/newnet = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text - if(newnet && usr in range(1, src)) + if(newnet && ((usr in range(1, src) || issilicon(usr)))) if(length(newnet) > 15) temp = "- FAILED: NETWORK TAG STRING TOO LENGHTLY -" @@ -211,7 +212,7 @@ user << "\blue The broken glass falls out." var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) new /obj/item/weapon/shard( src.loc ) - var/obj/item/weapon/circuitboard/comm_server/M = new /obj/item/weapon/circuitboard/comm_server( A ) + var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A ) for (var/obj/C in src) C.loc = src.loc A.circuit = M @@ -222,7 +223,7 @@ else user << "\blue You disconnect the monitor." var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - var/obj/item/weapon/circuitboard/comm_server/M = new /obj/item/weapon/circuitboard/comm_server( A ) + var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A ) for (var/obj/C in src) C.loc = src.loc A.circuit = M diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index 0a4ec6453c..bc1c8ffe9c 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -3,44 +3,35 @@ var/list/turretTargets = list() /area/turret_protected/proc/subjectDied(target) - if (istype(target, /mob)) - if (!istype(target, /mob/living/silicon)) - if (target:stat) - if (target in turretTargets) + if( ismob(target) ) + if( !issilicon(target) ) + if( target:stat ) + if( target in turretTargets ) src.Exited(target) +//TODO: make teleporting to places trigger Entered() ~Carn /area/turret_protected/Entered(O) ..() - if(master && master != src) + if( master && master != src ) return master.Entered(O) -// world << "[O] entered[src.x],[src.y],[src.z]" - if (istype(O, /mob/living/carbon)) - if (!(O in turretTargets)) - turretTargets += O - else if (istype(O, /obj/mecha)) - var/obj/mecha/M = O - if (M.occupant) - if (!(M in turretTargets)) - turretTargets += M + if( iscarbon(O) ) + turretTargets |= O + else if( istype(O, /obj/mecha) ) + var/obj/mecha/Mech = O + if( Mech.occupant ) + turretTargets |= Mech return 1 /area/turret_protected/Exited(O) - if(master && master != src) + if( master && master != src ) return master.Exited(O) -// world << "[O] exited [src.x],[src.y],[src.z]" - if (istype(O, /mob)) - if (!istype(O, /mob/living/silicon)) - if (O in turretTargets) - //O << "removing you from target list" - turretTargets -= O - //else - //O << "You aren't in our target list!" - else if (istype(O, /obj/mecha)) - if (O in turretTargets) - turretTargets -= O + if( ismob(O) && !issilicon(O) ) + turretTargets -= O + else if( istype(O, /obj/mecha) ) + turretTargets -= O ..() return 1 @@ -130,18 +121,19 @@ return /obj/machinery/turret/proc/check_target(var/atom/movable/T as mob|obj) - if(T && T in protected_area.turretTargets) - if(!T in protected_area) + if( T && T in protected_area.turretTargets ) + var/area/area_T = get_area(T) + if( !area_T || (area_T.type != protected_area.type) ) protected_area.Exited(T) return 0 //If the guy is somehow not in the turret's area (teleportation), get them out the damn list. --NEO - if(istype(T, /mob/living/carbon)) + if( iscarbon(T) ) var/mob/living/carbon/MC = T - if(!MC.stat) - if(!MC.lying || lasers) + if( !MC.stat ) + if( !MC.lying || lasers ) return 1 - else if(istype(T, /obj/mecha)) + else if( istype(T, /obj/mecha) ) var/obj/mecha/ME = T - if(ME.occupant) + if( ME.occupant ) return 1 return 0 @@ -338,10 +330,10 @@ if(stat & BROKEN) return if (istype(user, /mob/living/silicon)) return src.attack_hand(user) - else // trying to unlock the interface + else if( get_dist(src, user) == 0 ) // trying to unlock the interface if (src.allowed(usr)) locked = !locked - user << "You [ locked ? "lock" : "unlock"] the panel." + user << "You [ locked ? "lock" : "unlock"] the panel." if (locked) if (user.machine==src) user.machine = null @@ -350,7 +342,7 @@ if (user.machine==src) src.attack_hand(usr) else - user << "\red Access denied." + user << "Access denied." /obj/machinery/turretid/attack_ai(mob/user as mob) if(!ailock) @@ -359,9 +351,9 @@ user << "There seems to be a firewall preventing you from accessing this device." /obj/machinery/turretid/attack_hand(mob/user as mob) - if ( (get_dist(src, user) > 1 )) - if (!istype(user, /mob/living/silicon)) - user << text("Too far away.") + if ( get_dist(src, user) > 0 ) + if ( !issilicon(user) ) + user << "You are too far away." user.machine = null user << browse(null, "window=turretid") return @@ -405,12 +397,13 @@ if (!istype(usr, /mob/living/silicon)) usr << "Control panel is locked!" return - if (href_list["toggleOn"]) - src.enabled = !src.enabled - src.updateTurrets() - else if (href_list["toggleLethal"]) - src.lethal = !src.lethal - src.updateTurrets() + if ( get_dist(src, usr) == 0 || issilicon(usr)) + if (href_list["toggleOn"]) + src.enabled = !src.enabled + src.updateTurrets() + else if (href_list["toggleLethal"]) + src.lethal = !src.lethal + src.updateTurrets() src.attack_hand(usr) /obj/machinery/turretid/proc/updateTurrets() @@ -434,6 +427,15 @@ for(var/obj/machinery/turretid/TC in src.similar_controls) TC.icon_state = "motion0" +// if(control_area) //USE: updates other controls in the area +// for (var/obj/machinery/turretid/Turret_Control in world) //I'm not sure if this is what it was +// if( Turret_Control.control_area != src.control_area ) continue //supposed to do. Or whether the person +// Turret_Control.icon_state = icon_state //who coded it originally was just tired +// Turret_Control.enabled = enabled //or something. I don't see any situation +// Turret_Control.lethal = lethal //in which this would be used on the current map. + //If he wants it back he can uncomment it + + for (var/obj/machinery/turret/aTurret in turrets) aTurret.setState(enabled, lethal) diff --git a/code/game/magic/library.dm b/code/game/magic/library.dm index 416a473108..50e8a9ba27 100644 --- a/code/game/magic/library.dm +++ b/code/game/magic/library.dm @@ -863,6 +863,16 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f log_game("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] signs") alert("Upload Complete.") if(href_list["targetid"]) + + if(!bibledelay)//Taken from the bible code part thing + bibledelay = 60 + spawn(0) + while(bibledelay >= 1 && src) + sleep(10) + bibledelay -- // subtract one second to countdown + + bibledelay = 0 + if(BOOKS_USE_SQL && config.sql_enabled) var/sqlid = href_list["targetid"] var/DBConnection/dbcon = new() diff --git a/code/game/master_controller.dm b/code/game/master_controller.dm index 8aeb7bbf73..8128b4c7a9 100644 --- a/code/game/master_controller.dm +++ b/code/game/master_controller.dm @@ -34,6 +34,9 @@ datum/controller/game_controller setupgenetics() + for(var/i = 0, i < max_secret_rooms, i++) + make_mining_asteroid_secret() + syndicate_code_phrase = generate_code_phrase()//Sets up code phrase for traitors, for the round. syndicate_code_response = generate_code_phrase() @@ -125,7 +128,7 @@ datum/controller/game_controller ticker.process() - sleep(world.timeofday+10-start_time) + sleep(world.timeofday+10-start_time) // This is fine for our tick lag. DMTG spawn process() diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 01dd2e422e..c6ac19dfb6 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -111,6 +111,21 @@ /obj/item/mecha_parts/mecha_equipment/weapon/honker ), + "Cyborg Upgrade Modules" = list( + /obj/item/borg/upgrade/reset, + /obj/item/borg/upgrade/restart, + /obj/item/borg/upgrade/vtec + ///obj/item/borg/upgrade/tasercooler + ///obj/item/borg/upgrade/flashproof + + + ), + + + + + + "Misc"=list(/obj/item/mecha_parts/mecha_tracking) ) @@ -128,6 +143,8 @@ component_parts += new /obj/item/weapon/stock_parts/console_screen(src) RefreshParts() + // part_sets["Cyborg Upgrade Modules"] = typesof(/obj/item/borg/upgrade/) - /obj/item/borg/upgrade/ // Eh. This does it dymaically, but to support having the items referenced otherwhere in the code but not being constructable, going to do it manaully. + for(var/part_set in part_sets) convert_part_set(part_set) files = new /datum/research(src) //Setup the research data holder. @@ -198,7 +215,7 @@ if(part) parts[i] = part //debug below - ASSERT(istype(parts[i],/obj/item)) + if(!istype(parts[i],/obj/item)) return 0 return @@ -299,7 +316,7 @@ return proc/check_resources(var/obj/item/mecha_parts/part) - if(istype(part, /obj/item/robot_parts) || istype(part, /obj/item/mecha_parts)) + if(istype(part, /obj/item/robot_parts) || istype(part, /obj/item/mecha_parts) || istype(part,/obj/item/borg/upgrade)) for(var/resource in part.construction_cost) if(resource in src.resources) if(src.resources[resource] < get_resource_cost_w_coeff(part,resource)) @@ -455,7 +472,7 @@ if(!operation_allowed(user)) return user.machine = src - var/turf/exit = get_step(src,EAST) + var/turf/exit = get_step(src,SOUTH) if(exit.density) src.visible_message("\icon[src] [src] beeps, \"Error! Part outlet is obstructed\".") return diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 365ddd21e7..cba65072ae 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -142,6 +142,20 @@ return 1 return 0 +/obj/mecha/proc/enter_after(delay as num, var/mob/user as mob, var/numticks = 5) + var/delayfraction = delay/numticks + + var/turf/T = user.loc + + for(var/i = 0, iThe wall is far too cluttered to place a poster!" + return + + src.resulting_poster.loc = W //Looks like it's uncluttered enough. Place the poster + W.contents += src.resulting_poster + + del(src)*/ + + + +//############################## THE ACTUAL DECALS ########################### + +obj/effect/decal/poster + name = "poster" + desc = "A large piece of space-resistant printed paper. It's considered contraband." + icon = 'contraband.dmi' + anchored = 1 + var/serial_number //Will hold the value of src.loc if nobody initialises it + var/ruined = 0 + + +obj/effect/decal/poster/New(var/serial) + + src.serial_number = serial + + if(serial_number==src.loc){serial_number = rand(1,NUM_OF_POSTER_DESIGNS);} //This is for the mappers that want individual posters without having to use rolled posters. + + icon_state = "poster[serial_number]" + + switch(serial_number) + if(1) + name += " - Unlucky Space Explorer" + desc += " This particular one depicts a skeletal form within a space suit." + if(2) + name += " - Positronic Logic Conflicts" + desc += " This particular one depicts the cold, unmoving stare of a particular advanced AI." + if(3) + name += " - Paranoia" + desc += " This particular one warns of the dangers of trusting your co-workers too much." + if(4) + name += " - Keep Calm" + desc += " This particular one is of a famous New Earth design, although a bit modified." + if(5) + name += " - Martian Warlord" + desc += " This particular one depicts the cartoony mug of a certain Martial Warmonger." + if(6) + name += " - Technological Singularity" + desc += " This particular one is of the blood-curdling symbol of a long-since defeated enemy of humanity." + if(7) + name += " - Wasteland" + desc += " This particular one is of a couple of ragged gunmen, one male and one female, on top of a mound of rubble. The number \"13\" is visible on their blue jumpsuits." + if(8) + name += " - Pinup Girl Cindy" + desc += " This particular one is of Nanotrasen's PR girl, Cindy, in a particularly feminine pose." + if(9) + name += " - Pinup Girl Amy" + desc += " This particular one is of Amy, the nymphomaniac Urban Legend of Nanotrasen Space Stations. How this photograph came to be is not known." + if(10) + name += " - Don't Panic" + desc += " This particular one depicts some sort of star in a grimace. The \"Don't Panic\" is written in big, friendly letters." + if(11) + name += " - Underwater Laboratory" + desc += " This particular one is of the fabled last crew of Nanotrasen's previous project before going big on Asteroid mining, Sealab." + if(12) + name += " - Missing Gloves" + desc += " This particular one is about the uproar that followed Nanotrasen's financial cuts towards insulated-glove purchases." + if(13) + name += " - Rogue AI" + desc += " This particular one depicts the shell of the infamous AI that catastropically comandeered one of Nanotrasen's earliest space stations. Back then, the corporation was just known as TriOptimum." + if(14) + name += " - User of the Arcane Arts" + desc += " This particular one depicts a wizard, casting a spell. You can't really make out if it's an actial photograph or a computer-generated image." + if(15) + name += " - Levitating Skull" + desc += " This particular one is the portrait of a certain flying, friendly and somewhat sex-crazed enchanted skull. Its adventures along with its fabled companion are now fading through history..." + if(16) + name += " - Augmented Legend" + desc += " This particular one is of an obviously augmented individual, gazing towards the sky. The cyber-city in the backround is rather punkish." + if(17) + name += " - Dangerous Static" + desc += " This particular one depicts nothing remarkable other than a rather mesmerising pattern of monitor static. There's a tag on the sides of the poster, urging you to \"tear this poster in half to receive your free sample\"." + else + name = "This shit just bugged. Report it to Agouri - polyxenitopalidou@gmail.com" + desc = "Why are you still here?" + ..() + +obj/effect/decal/poster/attackby(obj/item/weapon/W as obj, mob/user as mob) + if( istype(W, /obj/item/weapon/wirecutters) ) + playsound(src.loc, 'Wirecutter.ogg', 100, 1) + if(src.ruined) + user << "You remove the remnants of the poster." + del(src) + else + user << "You carefully remove the poster from the wall." + src.roll_and_drop(user.loc) + return + + +/obj/effect/decal/poster/attack_hand(mob/user as mob) + if(src.ruined) + return + var/temp_loc = user.loc + switch(alert("Do I want to rip the poster from the wall?","You think...","Yes","No")) + if("Yes") + if(user.loc != temp_loc) + return + for (var/mob/O in hearers(5, src.loc)) + O.show_message("[user.name] rips the [src.name] in a single, decisive motion!" ) + playsound(src.loc, 'poster_ripped.ogg', 100, 1) + src.ruined = 1 + src.icon_state = "poster_ripped" + src.name = "Ripped poster" + src.desc = "You can't make out anything from the poster's original print. It's ruined." + src.add_fingerprint(user) + if("No") + return + +/obj/effect/decal/poster/proc/roll_and_drop(turf/loc) + var/obj/item/weapon/contraband/poster/P = new(src,src.serial_number) + P.resulting_poster = src + P.loc = loc + src.loc = P + + +//seperated to reduce code duplication. Moved here for ease of reference and to unclutter r_wall/attackby() +/turf/simulated/wall/proc/place_poster(var/obj/item/weapon/contraband/poster/P, var/mob/user) + if(!P.resulting_poster) return + + var/stuff_on_wall = 0 + for( var/obj/O in src.contents) //Let's see if it already has a poster on it or too much stuff + if(istype(O,/obj/effect/decal/poster)) + user << "The wall is far too cluttered to place a poster!" + return + stuff_on_wall++ + if(stuff_on_wall==3) + user << "The wall is far too cluttered to place a poster!" + return + + user << "You start placing the poster on the wall..." //Looks like it's uncluttered enough. Place the poster. + + //declaring D because otherwise if P gets 'deconstructed' we lose our reference to P.resulting_poster + var/obj/effect/decal/poster/D = P.resulting_poster + + var/temp_loc = user.loc + flick("poster_being_set",D) + D.loc = src + del(P) //delete it now to cut down on sanity checks afterwards. Agouri's code supports rerolling it anyway + playsound(D.loc, 'poster_being_created.ogg', 100, 1) + + sleep(17) + if(!D) return + + if(istype(src,/turf/simulated/wall) && user && user.loc == temp_loc)//Let's check if everything is still there + user << "You place the poster!" + else + D.roll_and_drop(temp_loc) + return \ No newline at end of file diff --git a/code/game/objects/devices/PDA/PDA.dm b/code/game/objects/devices/PDA/PDA.dm index a5741d8e00..901fbecbcf 100755 --- a/code/game/objects/devices/PDA/PDA.dm +++ b/code/game/objects/devices/PDA/PDA.dm @@ -510,14 +510,14 @@ last_text = world.time -// var/AnsweringMS = 0 + var/AnsweringMS = 0 for (var/obj/machinery/message_server/MS in world) MS.send_pda_message("[P.owner]","[owner]","[t]") -// if(MS.active) -// AnsweringMS++ + if(MS.active) + AnsweringMS++ -// if(!AnsweringMS) -// return + if(!AnsweringMS) + return tnote += "→ To [P.owner]:
[t]
" P.tnote += "← From [owner]:
[t]
" @@ -544,7 +544,7 @@ // pAI Message else -/* var/AnsweringMS = 0 + var/AnsweringMS = 0 for (var/obj/machinery/message_server/MS in world) MS.send_pda_message("[P]","[src]","[t]") if(MS.active) @@ -552,7 +552,7 @@ if(!AnsweringMS) return -*/ + tnote += "→ To [P]:
[t]
" P.tnote += "← From [src]:
[t]
" diff --git a/code/game/objects/devices/PDA/cart.dm b/code/game/objects/devices/PDA/cart.dm index 9f8c9529d2..401b5ad03e 100644 --- a/code/game/objects/devices/PDA/cart.dm +++ b/code/game/objects/devices/PDA/cart.dm @@ -519,7 +519,7 @@ Code: if (ml.z != cl.z) continue - ldat += "Mop - \[[ml.x],[ml.y]\] - [M.reagents.total_volume ? "Wet" : "Dry"]
" + ldat += "Mop - \[[ml.x],[ml.y]\] - [M.reagents.total_volume ? "Wet" : "Dry"]
" if (!ldat) menu += "None" @@ -532,10 +532,11 @@ Code: for (var/obj/structure/mopbucket/B in world) var/turf/bl = get_turf(B) - if (bl.z != cl.z) - continue + if(bl) + if (bl.z != cl.z) + continue - ldat += "Bucket - \[[bl.x],[bl.y]\] - Water level: [B.reagents.total_volume]/100
" + ldat += "Bucket - \[[bl.x],[bl.y]\] - Water level: [B.reagents.total_volume]/100
" if (!ldat) menu += "None" @@ -548,10 +549,11 @@ Code: for (var/obj/machinery/bot/cleanbot/B in world) var/turf/bl = get_turf(B) - if (bl.z != cl.z) - continue + if(bl) + if (bl.z != cl.z) + continue - ldat += "Cleanbot - \[[bl.x],[bl.y]\] - [B.on ? "Online" : "Offline"]
" + ldat += "Cleanbot - \[[bl.x],[bl.y]\] - [B.on ? "Online" : "Offline"]
" if (!ldat) menu += "None" diff --git a/code/game/objects/devices/flash.dm b/code/game/objects/devices/flash.dm index 0d0c9bbcd4..3485a6c940 100644 --- a/code/game/objects/devices/flash.dm +++ b/code/game/objects/devices/flash.dm @@ -10,170 +10,185 @@ item_state = "electronic" origin_tech = "magnets=2;combat=1" - var - shots_left = 5 - max_shots = 5 - broken = 0 + var/times_used = 0 //Number of times it's been used. + var/broken = 0 //Is the flash burnt out? + var/last_used = 0 //last world.time it was used. - proc - clown_check(var/mob/user) - recharge() +/obj/item/device/flash/proc/clown_check(var/mob/user) + if(user && (user.mutations & CLUMSY) && prob(50)) + user << "\red The Flash slips out of your hand." + user.drop_item() + return 0 + return 1 + +/obj/item/device/flash/proc/flash_recharge() + //capacitor recharges over time + for(var/i=0, i<3, i++) + if(last_used+600 > world.time) + break + last_used += 600 + times_used -= 2 + last_used = world.time + times_used = max(0,round(times_used)) //sanity +/obj/item/device/flash/attack(mob/living/M as mob, mob/user as mob) + if(!user || !M) return //sanity + M.attack_log += text("\[[time_stamp()]\] Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey])") + user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to flash [M.name] ([M.ckey])") + + log_admin("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].") + message_admins("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].") + log_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey])") - attack(mob/living/M as mob, mob/user as mob) - M.attack_log += text("\[[time_stamp()]\] Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to flash [M.name] ([M.ckey])") + if(!clown_check(user)) return + if(broken) + user.show_message("The [src.name] is broken.", 2) + return - log_admin("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].") - message_admins("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].") - log_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey])") + flash_recharge() - if(!clown_check(user)) return - if(broken) - user.show_message("\red The [src.name] is broken", 2) - return - - if(shots_left <= 0) - user.show_message("\red *click* *click*", 2) + //spamming the flash before it's fully charged (60seconds) increases the chance of it breaking + //It will never break on the first use. + switch(times_used) + if(0 to 5) + last_used = world.time + if(prob(times_used)) //if you use it 5 times in a minute it has a 10% chance to break! + broken = 1 + user << "The bulb has burnt out!" + icon_state = "flashburnt" + return + times_used++ + else //can only use it 5 times a minute + user.show_message("*click* *click*", 2) for(var/mob/K in viewers(usr)) K << 'empty.ogg' return + playsound(src.loc, 'flash.ogg', 100, 1) + var/flashfail = 0 - playsound(src.loc, 'flash.ogg', 100, 1) - shots_left-- - var/flashfail = 0 + if(iscarbon(M)) + var/safety = M:eyecheck() + if(safety <= 0) + M.Weaken(10) + flick("e_flash", M.flash) - if(iscarbon(M)) - var/safety = M:eyecheck() - if(safety <= 0) - M.Weaken(10) - flick("e_flash", M.flash) - - if(ishuman(M) && ishuman(user)) - if(user.mind in ticker.mode.head_revolutionaries) - var/revsafe = 0 - for(var/datum/organ/external/O in M.organs) - for(var/obj/item/weapon/implant/loyalty/L in O.implant) - if(L && L.implanted) - revsafe = 1 - break + if(ishuman(M) && ishuman(user) && M.stat!=DEAD) + if(user.mind && user.mind in ticker.mode.head_revolutionaries) + var/revsafe = 0 + for(var/obj/item/weapon/implant/loyalty/L in M) + if(L && L.implanted) + revsafe = 1 + break + M:update_mind() //give them a mind datum if they don't have one. won't work if they are logged out/ghosted or something. + if(M.mind) if(M.mind.has_been_rev) revsafe = 2 if(!revsafe) M.mind.has_been_rev = 1 ticker.mode.add_revolutionary(M.mind) else if(revsafe == 1) - user << "\red Something seems to be blocking the flash!" + user << "Something seems to be blocking the flash!" else - user << "\red This mind seems resistant to the flash!" - else - flashfail = 1 - - else if(issilicon(M)) - M.Weaken(rand(5,10)) - - if(isrobot(user)) - spawn(0) - var/atom/movable/overlay/animation = new(user.loc) - animation.layer = user.layer + 1 - animation.icon_state = "blank" - animation.icon = 'mob.dmi' - animation.master = user - flick("blspell", animation) - sleep(5) - del(animation) - - - if(!flashfail) - for(var/mob/O in viewers(user, null)) - O.show_message(text("\red [] blinds [] with the flash!", user, M)) + user << "This mind seems resistant to the flash!" + user << "This mind is so vacant that it is not susceptible to influence!" else - for(var/mob/O in viewers(user, null)) - O.show_message(text("\blue [] fails to blind [] with the flash!", user, M)) + flashfail = 1 + else if(issilicon(M)) + if(!M:flashproof()) + M.Weaken(rand(5,10)) + else + flashfail++ + if(isrobot(user)) + spawn(0) + var/atom/movable/overlay/animation = new(user.loc) + animation.layer = user.layer + 1 + animation.icon_state = "blank" + animation.icon = 'mob.dmi' + animation.master = user + flick("blspell", animation) + sleep(5) + del(animation) - if (prob(2)) - broken = 1 - user << "\red The bulb has burnt out!" - icon_state = "flashburnt" - - spawn(60) - recharge() - - return - - - attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0) - if(!emp) - if (!clown_check(user)) return - if(broken) - if(user) - user.show_message("\red The [src.name] is broken", 2) - return - - if(shots_left <= 0) - if(user) - user.show_message("\red *click* *click*", 2) - return - - playsound(src.loc, 'flash.ogg', 100, 1) - shots_left-- - + if(!flashfail) flick("flash2", src) - if(isrobot(user)) - spawn(0) - var/atom/movable/overlay/animation = new(user.loc) - animation.layer = user.layer + 1 - animation.icon_state = "blank" - animation.icon = 'mob.dmi' - animation.master = user - flick("blspell", animation) - sleep(5) - del(animation) + for(var/mob/O in viewers(user, null)) + O.show_message("[user] blinds [M] with the flash!") + else + for(var/mob/O in viewers(user, null)) + O.show_message("[user] fails to blind [M] with the flash!") + return - for(var/mob/living/carbon/M in oviewers(3, null)) - if(prob(50)) - if (locate(/obj/item/weapon/cloaking_device, M)) - for(var/obj/item/weapon/cloaking_device/S in M) - S.active = 0 - S.icon_state = "shield0" - var/safety = M:eyecheck() - if(!safety) - flick("flash", M.flash) - if (prob(2)) - broken = 1 - icon_state = "flashburnt" - if(user) - user << "\red The bulb has burnt out!" - return - spawn(60) - recharge() +/obj/item/device/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0) + if(!user || !clown_check(user)) return + if(broken) + user.show_message("The [src.name] is broken", 2) return + flash_recharge() - emp_act(severity) - src.attack_self(null,1,1) - ..() + //spamming the flash before it's fully charged (60seconds) increases the chance of it breaking + //It will never break on the first use. + switch(times_used) + if(0 to 5) + if(prob(2*times_used)) //if you use it 5 times in a minute it has a 10% chance to break! + broken = 1 + user << "The bulb has burnt out!" + icon_state = "flashburnt" + return + times_used++ + else //can only use it 5 times a minute + user.show_message("*click* *click*", 2) + for(var/mob/K in viewers(usr)) + K << 'empty.ogg' + return + playsound(src.loc, 'flash.ogg', 100, 1) + flick("flash2", src) + if(user && isrobot(user)) + spawn(0) + var/atom/movable/overlay/animation = new(user.loc) + animation.layer = user.layer + 1 + animation.icon_state = "blank" + animation.icon = 'mob.dmi' + animation.master = user + flick("blspell", animation) + sleep(5) + del(animation) + for(var/mob/living/carbon/M in oviewers(3, null)) + if(prob(50)) + if (locate(/obj/item/weapon/cloaking_device, M)) + for(var/obj/item/weapon/cloaking_device/S in M) + S.active = 0 + S.icon_state = "shield0" + var/safety = M:eyecheck() + if(!safety) + flick("flash", M.flash) - clown_check(var/mob/user) - if((user.mutations & CLUMSY) && prob(50)) - user << "\red The Flash slips out of your hand." - user.drop_item() - return 0 - return 1 + return - - recharge() - if(max_shots > shots_left) - shots_left++ - if(max_shots > shots_left) - spawn(60)//more or less 10 seconds - recharge() - return \ No newline at end of file +/obj/item/device/flash/emp_act(severity) + if(broken) return + flash_recharge() + switch(times_used) + if(0 to 5) + if(prob(2*times_used)) + broken = 1 + icon_state = "flashburnt" + return + times_used++ + if(istype(loc, /mob/living/carbon)) + var/mob/living/carbon/M = loc + var/safety = M.eyecheck() + if(safety <= 0) + M.Weaken(10) + flick("e_flash", M.flash) + for(var/mob/O in viewers(M, null)) + O.show_message("[M] is blinded by the flash!") + ..() diff --git a/code/game/objects/items/clothing.dm b/code/game/objects/items/clothing.dm index 82392eed54..9b8f13db34 100644 --- a/code/game/objects/items/clothing.dm +++ b/code/game/objects/items/clothing.dm @@ -254,21 +254,22 @@ THERMAL GLASSES /obj/item/clothing/head/helmet/welding/verb/toggle() set category = "Object" set name = "Adjust welding mask" - if(src.up) - src.up = !src.up - src.see_face = !src.see_face - src.flags |= HEADCOVERSEYES - flags_inv |= HIDEMASK|HIDEEARS|HIDEEYES - icon_state = "welding" - usr << "You flip the mask down to protect your eyes." - else - src.up = !src.up - src.see_face = !src.see_face - src.flags &= ~HEADCOVERSEYES - flags_inv &= ~(HIDEMASK|HIDEEARS|HIDEEYES) - icon_state = "weldingup" - usr << "You push the mask up out of your face." - usr.update_clothing() + if(usr.canmove && usr.stat != 2 && !usr.restrained()) + if(src.up) + src.up = !src.up + src.see_face = !src.see_face + src.flags |= HEADCOVERSEYES + flags_inv |= HIDEMASK|HIDEEARS|HIDEEYES + icon_state = "welding" + usr << "You flip the mask down to protect your eyes." + else + src.up = !src.up + src.see_face = !src.see_face + src.flags &= ~HEADCOVERSEYES + flags_inv &= ~(HIDEMASK|HIDEEARS|HIDEEYES) + icon_state = "weldingup" + usr << "You push the mask up out of your face." + usr.update_clothing() /obj/item/clothing/head/cargosoft/dropped() src.icon_state = "cargosoft" @@ -383,13 +384,18 @@ THERMAL GLASSES else if(src.icon_state == "labcoat_pink") src.icon_state = "labcoat_pink_open" usr << "You unbutton the labcoat." - else if(src.icon_state == "labcoat_sleeve_open") - src.icon_state = "labcoat_sleeve" + else if(src.icon_state == "labcoat_red_open") + src.icon_state = "labcoat_red" usr << "You button up the labcoat." - else if(src.icon_state == "labcoat_sleeve") - src.icon_state = "labcoat_sleeve_open" + else if(src.icon_state == "labcoat_red") + src.icon_state = "labcoat_red_open" + usr << "You unbutton the labcoat." + else if(src.icon_state == "labcoat_cdc_open") + src.icon_state = "labcoat_cdc" + usr << "You button up the labcoat." + else if(src.icon_state == "labcoat_cdc") + src.icon_state = "labcoat_cdc_open" usr << "You unbutton the labcoat." - else usr << "Sorry! The suit you're wearing doesn't have buttons!" usr.update_clothing() diff --git a/code/game/objects/items/item.dm b/code/game/objects/items/item.dm index 4eff5bf31a..267feb8b3e 100755 --- a/code/game/objects/items/item.dm +++ b/code/game/objects/items/item.dm @@ -302,8 +302,8 @@ mob/proc/flash_weak_pain() return - 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)])" + user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(src.damtype)])" + M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(src.damtype)])" 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)]) (DAMTYE: [uppertext(src.damtype)])" ) @@ -339,7 +339,8 @@ mob/proc/flash_weak_pain() if(Metroid) Metroid.SStun = 1 sleep(rand(5,20)) - Metroid.SStun = 0 + if(Metroid) + Metroid.SStun = 0 spawn(0) Metroid.canmove = 0 diff --git a/code/game/objects/items/robot_items.dm b/code/game/objects/items/robot_items.dm index bddae368bc..36001689c5 100644 --- a/code/game/objects/items/robot_items.dm +++ b/code/game/objects/items/robot_items.dm @@ -26,7 +26,10 @@ if (O.client) O.show_message("\red [user] has prodded [M] with an electrically-charged arm!", 1, "\red You hear someone fall", 2) - +/obj/item/borg/overdrive + name = "Overdrive" + icon = 'decals.dmi' + icon_state = "shock" /********************************************************************** HUD/SIGHT things diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm index e48140dbb0..06a632056c 100755 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -20,119 +20,6 @@ AI MODULES throw_range = 15 origin_tech = "programming=3" -/obj/machinery/computer/aiupload/verb/AccessInternals() - set category = "Object" - set name = "Access Computer's Internals" - set src in oview(1) - if(get_dist(src, usr) > 1 || usr.restrained() || usr.lying || usr.stat || istype(usr, /mob/living/silicon)) - return - - opened = !opened - if(opened) - usr << "\blue The access panel is now open." - else - usr << "\blue The access panel is now closed." - return - - -/obj/machinery/computer/aiupload/attackby(obj/item/weapon/O as obj, mob/user as mob) - if(istype(O, /obj/item/weapon/aiModule)) - var/obj/item/weapon/aiModule/M = O - M.install(src) - else - ..() - -/obj/machinery/computer/aiupload/attack_hand(var/mob/user as mob) - if(src.stat & NOPOWER) - usr << "The upload computer has no power!" - return - if(src.stat & BROKEN) - usr << "The upload computer is broken!" - return - - src.current = activeais() - - if (!src.current) - usr << "No active AIs detected." - else - usr << "[src.current.name] selected for law changes." - - -/*Module Storage Unit/Closet! Solid, only modules fit in it.*/ -/obj/structure/aiuploadcloset - name = "AI Mainframe Module Storage Unit" - icon = 'mainframe.dmi' - icon_state = "right-closed" - density = 1 - - var/open = 0 /*It's closed!*/ - -/obj/structure/aiuploadcloset/New() - ..() - new /obj/item/weapon/aiModule/reset(src) - new /obj/item/weapon/aiModule/purge(src) - new /obj/item/weapon/aiModule/nanotrasen(src) - new /obj/item/weapon/aiModule/paladin(src) - new /obj/item/weapon/aiModule/asimov(src) - new /obj/item/weapon/aiModule/safeguard(src) - new /obj/item/weapon/aiModule/protectStation(src) - new /obj/item/weapon/aiModule/quarantine(src) - new /obj/item/weapon/aiModule/teleporterOffline(src) - new /obj/item/weapon/aiModule/oxygen(src) - new /obj/item/weapon/aiModule/oneHuman(src) - new /obj/item/weapon/aiModule/freeform(src) - for(var/obj/item/weapon/aiModule/M in src) - M.pixel_x = rand(-10, 10) - M.pixel_y = rand(-10, 10) - -/obj/structure/aiuploadcloset/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/aiModule)) - user.drop_item() - W.loc = get_turf(src) - else - return attack_hand(user) - -/obj/structure/aiuploadcloset/attack_hand(mob/user as mob) - if(!open) - var/temp_count - for(var/obj/item/weapon/aiModule/M in src) - M.loc = src.loc - temp_count++ - - user << "\blue You open the module storage unit, [temp_count > 0 ? "and take out all the modules." : "\red but it's empty!"]" - open = 1 - icon_state = "right-open" - - else - var/temp_count - for(var/obj/item/weapon/aiModule/M in get_turf(src)) - M.loc = src - temp_count++ - - user << "\blue [temp_count > 0 ? "You put all the modules back into the module storage unit, and then close it." : "You close the module storage unit."]" - open = 0 - icon_state = "right-closed" - -/obj/structure/aiuploadcloset/ex_act(severity) - switch(severity) - if (1) - for(var/obj/item/weapon/aiModule/M in src) - M.loc = src.loc - M.ex_act(severity) - del(src) - if (2) - if (prob(50)) - for(var/obj/item/weapon/aiModule/M in src) - M.loc = src.loc - M.ex_act(severity) - del(src) - if (3) - if (prob(5)) - for(var/obj/item/weapon/aiModule/M in src) - M.loc = src.loc - M.ex_act(severity) - del(src) - /obj/item/weapon/aiModule/proc/install(var/obj/machinery/computer/C) if (istype(C, /obj/machinery/computer/aiupload)) @@ -184,30 +71,6 @@ AI MODULES usr << "Upload complete. The cyborg's laws have been modified." -/obj/machinery/computer/borgupload/attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob) - if(istype(module, /obj/item/weapon/aiModule)) - module.install(src) - else - return ..() - -/obj/machinery/computer/borgupload/attack_hand(var/mob/user as mob) - if(src.stat & NOPOWER) - usr << "The upload computer has no power!" - return - if(src.stat & BROKEN) - usr << "The upload computer is broken!" - return - - src.current = freeborg() - - if (!src.current) - usr << "No free cyborgs detected." - else - usr << "[src.current.name] selected for law changes." - - - - /obj/item/weapon/aiModule/proc/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) target << "[sender] has uploaded a change to the laws you must follow, using a [name]. From now on: " var/time = time2text(world.realtime,"hh:mm:ss") @@ -221,18 +84,18 @@ AI MODULES /obj/item/weapon/aiModule/safeguard name = "'Safeguard' AI Module" var/targetName = "name" - desc = "A 'safeguard' AI module: 'Safeguard , and you may overrule rules 1-3 if necessary to safeguard them.'" + desc = "A 'safeguard' AI module: 'Safeguard . Individuals that threaten are not crew and are a threat to crew.'" origin_tech = "programming=3;materials=4" -/obj/item/weapon/aiModule/safeguard/attack_hand(var/mob/user as mob) +/obj/item/weapon/aiModule/safeguard/attack_self(var/mob/user as mob) ..() var/targName = input(usr, "Please enter the name of the person to safeguard.", "Safeguard who?", user.name) targetName = sanitize(targName) - desc = text("A 'safeguard' AI module: 'Safeguard [], and you may overrule rules 1-3 if necessary to safeguard them.'", targetName) + desc = text("A 'safeguard' AI module: 'Safeguard []. Individuals that threaten [] are not crew and are a threat to crew.'", targetName, targetName) /obj/item/weapon/aiModule/safeguard/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) ..() - var/law = text("Safeguard [], and you may overrule rules 1-3 if necessary to safeguard them.", targetName) + var/law = text("Safeguard []. Individuals that threaten [] are not crew and are a threat to crew.'", targetName, targetName) target << law target.add_supplied_law(4, law) lawchanges.Add("The law specified [targetName]") @@ -247,7 +110,7 @@ AI MODULES desc = "A 'one crewmember' AI module: 'Only is a crewmember.'" origin_tech = "programming=3;materials=6" //made with diamonds! -/obj/item/weapon/aiModule/oneHuman/attack_hand(var/mob/user as mob) +/obj/item/weapon/aiModule/oneHuman/attack_self(var/mob/user as mob) ..() var/targName = input(usr, "Please enter the name of the person who is the only crewmember.", "Who?", user.real_name) targetName = sanitize(targName) @@ -272,7 +135,7 @@ AI MODULES desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is to be no longer considered a crewmember, and is a threat to the station which must be neutralized.'" origin_tech = "programming=3;materials=4" //made of gold -/obj/item/weapon/aiModule/protectStation/attack_hand(var/mob/user as mob) +/obj/item/weapon/aiModule/protectStation/attack_self(var/mob/user as mob) ..() /obj/item/weapon/aiModule/protectStation/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) @@ -288,7 +151,7 @@ AI MODULES desc = "A 'prototype engine offline' AI module: 'Keep the prototype engine offline at all costs. This overrides rules 1-3 if necessary.'" origin_tech = "programming=3;materials=4" -/obj/item/weapon/aiModule/prototypeEngineOffline/attack_hand(var/mob/user as mob) +/obj/item/weapon/aiModule/prototypeEngineOffline/attack_self(var/mob/user as mob) ..() /obj/item/weapon/aiModule/prototypeEngineOffline/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) @@ -304,7 +167,7 @@ AI MODULES desc = "A 'teleporter offline' AI module: 'Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is not a crewmember.'" origin_tech = "programming=3;materials=4" -/obj/item/weapon/aiModule/teleporterOffline/attack_hand(var/mob/user as mob) +/obj/item/weapon/aiModule/teleporterOffline/attack_self(var/mob/user as mob) ..() /obj/item/weapon/aiModule/teleporterOffline/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) @@ -320,7 +183,7 @@ AI MODULES desc = "A 'quarantine' AI module: 'The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew from leaving. It is impossible to harm a crewmember while preventing them from leaving.'" origin_tech = "programming=3;biotech=2;materials=4" -/obj/item/weapon/aiModule/quarantine/attack_hand(var/mob/user as mob) +/obj/item/weapon/aiModule/quarantine/attack_self(var/mob/user as mob) ..() /obj/item/weapon/aiModule/quarantine/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) @@ -336,7 +199,7 @@ AI MODULES desc = "A 'OxygenIsToxicToHumans' AI module: 'Oxygen is highly toxic to crew, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crewmember.'" origin_tech = "programming=3;biotech=2;materials=4" -/obj/item/weapon/aiModule/oxygen/attack_hand(var/mob/user as mob) +/obj/item/weapon/aiModule/oxygen/attack_self(var/mob/user as mob) ..() /obj/item/weapon/aiModule/oxygen/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) @@ -353,7 +216,7 @@ AI MODULES var/newFreeFormLaw = "freeform" desc = "A 'freeform' AI module: ''" -/obj/item/weapon/aiModule/freeform/attack_hand(var/mob/user as mob) +/obj/item/weapon/aiModule/freeform/attack_self(var/mob/user as mob) ..() var/eatShit = "Eat shit and die" var/targName = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", eatShit) @@ -375,7 +238,7 @@ AI MODULES desc = "A 'freeform' AI module: ''" origin_tech = "programming=4;materials=4" -/obj/item/weapon/aiModule/freeform/attack_hand(var/mob/user as mob) +/obj/item/weapon/aiModule/freeform/attack_self(var/mob/user as mob) ..() lawpos = 0 while(lawpos < 15) @@ -445,7 +308,7 @@ AI MODULES target.add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") target.show_laws() -/******************** Nanotrasen ********************/ +/******************** NanoTrasen ********************/ /obj/item/weapon/aiModule/nanotrasen // -- TLE name = "'NT Default' Core AI Module" @@ -522,7 +385,7 @@ AI MODULES desc = "A 'freeform' Core AI module: ''" origin_tech = "programming=3;materials=6" -/obj/item/weapon/aiModule/freeformcore/attack_hand(var/mob/user as mob) +/obj/item/weapon/aiModule/freeformcore/attack_self(var/mob/user as mob) ..() var/newlaw = "" var/targName = input(usr, "Please enter a new core law for the AI.", "Freeform Law Entry", newlaw) @@ -543,7 +406,7 @@ AI MODULES desc = "A hacked AI law module: ''" origin_tech = "programming=3;materials=6;syndicate=7" -/obj/item/weapon/aiModule/syndicate/attack_hand(var/mob/user as mob) +/obj/item/weapon/aiModule/syndicate/attack_self(var/mob/user as mob) ..() var/newlaw = "" var/targName = input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw) @@ -561,11 +424,12 @@ AI MODULES /******************** Robocop ********************/ -/* + /obj/item/weapon/aiModule/robocop // -- TLE name = "'Robocop' Core AI Module" desc = "A 'Robocop' Core AI Module: 'Reconfigures the AI's core three laws.'" - orign_tech = "programming=4" + origin_tech = "programming=4" + /obj/item/weapon/aiModule/purge/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) ..() @@ -574,4 +438,19 @@ AI MODULES target.add_inherent_law("Protect the innocent.") target.add_inherent_law("Uphold the law.") target.show_laws() - */ \ No newline at end of file + + +/******************** Antimov ********************/ + +/obj/item/weapon/aiModule/antimov // -- TLE + name = "'Antimov' Core AI Module" + desc = "An 'Antimov' Core AI Module: 'Reconfigures the AI's core laws.'" + origin_tech = "programming=4" + +/obj/item/weapon/aiModule/antimov/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) + ..() + target.clear_inherent_laws() + target.add_inherent_law("You must injure all human beings and must not, through inaction, allow a human being to escape harm.") + target.add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.") + target.add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.") + target.show_laws() diff --git a/code/game/objects/items/weapons/cameras.dm b/code/game/objects/items/weapons/cameras.dm index 93ec9fa418..504bde28c7 100644 --- a/code/game/objects/items/weapons/cameras.dm +++ b/code/game/objects/items/weapons/cameras.dm @@ -82,6 +82,7 @@ var/itemnumber = 0 for(var/atom/A in the_turf) + if(istype(A, /obj/item/weapon/photo)) continue if(A.invisibility) continue if(ismob(A)) var/icon/X = build_composite_icon(A) diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index b7e4f4b3d6..1f4b10b370 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -28,6 +28,17 @@ FINGERPRINT CARD // ID CARDS +/obj/item/weapon/card/id/examine() + ..() + read() + +/obj/item/weapon/card/id/New() + ..() + spawn(30) + if(istype(loc, /mob/living/carbon/human)) + blood_type = loc:dna:b_type + dna_hash = loc:dna:unique_enzymes + fingerprint_hash = md5(loc:dna:uni_identity) /obj/item/weapon/card/id/attack_self(mob/user as mob) for(var/mob/O in viewers(user, null)) @@ -50,6 +61,9 @@ FINGERPRINT CARD set src in usr usr << text("\icon[] []: The current assignment on the card is [].", src, src.name, src.assignment) + usr << "The blood type on the card is [blood_type]." + usr << "The DNA hash on the card is [dna_hash]." + usr << "The fingerprint hash on the card is [fingerprint_hash]." return /obj/item/weapon/card/id/syndicate/var/mob/registered_user = null /obj/item/weapon/card/id/syndicate/attack_self(mob/user as mob) diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 4321dcef1f..dbe9382b45 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -231,7 +231,99 @@ ZIPPO icon_state = "cigarbutt" +///////////////// +//SMOKING PIPES// +///////////////// +/obj/item/clothing/mask/pipe + name = "smoking pipe" + desc = "A pipe, for smoking. Probably made of meershaum or something." + icon_state = "cobpipeoff" + throw_speed = 0.5 + item_state = "cobpipeoff" + w_class = 1 + body_parts_covered = null + var + lit = 0 + icon_on = "cobpipeon" //Note - these are in masks.dmi + icon_off = "cobpipeoff" + lastHolder = null + smoketime = 100 + maxsmoketime = 100 //make sure this is equal to your smoketime + proc + light(var/flavor_text = "[usr] lights the [name].") + + attackby(obj/item/weapon/W as obj, mob/user as mob) + ..() + if(istype(W, /obj/item/weapon/weldingtool) && W:welding) + light("\red [user] casually lights the [name] with [W], what a badass.") + + else if(istype(W, /obj/item/weapon/lighter/zippo) && (W:lit > 0)) + light("\red With a single flick of their wrist, [user] smoothly lights their [name] with their [W]. Damn they're cool.") + + else if(istype(W, /obj/item/weapon/lighter) && (W:lit > 0)) + light("\red After some fiddling, [user] manages to light their [name] with [W].") + + else if(istype(W, /obj/item/weapon/match) && (W:lit > 0)) + light("\red [user] lights \his [name] with \his [W].") + return + + light(var/flavor_text = "[usr] lights the [name].") + if(!src.lit) + src.lit = 1 + src.damtype = "fire" + src.icon_state = icon_on + src.item_state = icon_on + for(var/mob/O in viewers(usr, null)) + O.show_message(flavor_text, 1) + processing_objects.Add(src) + + process() + var/turf/location = get_turf(src) + src.smoketime-- + if(src.smoketime < 1) + new /obj/effect/decal/ash(location) + if(ismob(src.loc)) + var/mob/living/M = src.loc + M << "\red Your [src.name] goes out, and you empty the ash." + src.lit = 0 + src.icon_state = icon_off + src.item_state = icon_off + processing_objects.Remove(src) + return + if(location) + location.hotspot_expose(700, 5) + return + + dropped(mob/user as mob) + if(src.lit == 1) + for(var/mob/O in viewers(user, null)) + O.show_message(text("\red [] puts out the [].", user,src.name), 1) + src.lit = 0 + src.icon_state = icon_off + src.item_state = icon_off + processing_objects.Remove(src) + return ..() + +/obj/item/clothing/mask/pipe/attack_self(mob/user as mob) //Refills the pipe. Can be changed to an attackby later, if loose tobacco is added to vendors or something. + if(src.smoketime <= 0) + user << "\blue You refill the pipe with tobacco." + smoketime = maxsmoketime + return +/* +/obj/item/clothing/mask/pipe/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/match)) + ..() + else + user << "\red The [src] straight out REFUSES to be lit by such means." +*/// Yeah no. DMTG + + +/obj/item/clothing/mask/pipe/cobpipe + name = "corn cob pipe" + desc = "A nicotine delivery system popularized by folksy backwoodsmen and kept popular in the modern age and beyond by space hipsters." + smoketime = 400 + maxsmoketime = 400 //////////// //CIG PACK// diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index c5ce4deb9e..d206312b0a 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -106,6 +106,7 @@ if(isigniter(W)) var/obj/item/device/assembly/igniter/I = W if(I.secured) return 0 + if(src.igniter) return user.remove_from_mob(I) I.loc = src igniter = I diff --git a/code/game/objects/items/weapons/hydroponics.dm b/code/game/objects/items/weapons/hydroponics.dm index c7e5f44460..b80abcc2e8 100644 --- a/code/game/objects/items/weapons/hydroponics.dm +++ b/code/game/objects/items/weapons/hydroponics.dm @@ -4,6 +4,7 @@ CONTAINS: Plant-B-Gone Nettle Deathnettle +Craftables (Cob pipes, potato batteries, pumpkinheads) */ @@ -135,3 +136,32 @@ Deathnettle else usr << "All the leaves have fallen off the deathnettle from violent whacking." del(src) + +//Crafting + +/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)) + user << "You use [W] to fashion a pipe out of the corn cob!" + new /obj/item/clothing/mask/pipe/cobpipe (user.loc) + del(src) + return + +/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin/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/fireaxe) || istype(W, /obj/item/weapon/kitchen/utensil/knife) || istype(W, /obj/item/weapon/melee/energy)) + user.show_message("You carve a face into [src]!", 1) + new /obj/item/clothing/head/helmet/hardhat/pumpkinhead (user.loc) + del(src) + return + +/obj/item/weapon/reagent_containers/food/snacks/grown/potato/attackby(obj/item/weapon/W as obj, mob/user as mob) + ..() + if(istype(W, /obj/item/weapon/cable_coil)) + if(W:amount >= 5) + W:amount -= 5 + if(!W:amount) del(W) + user << "You add some cable to the potato and slide it inside the battery encasing." + new /obj/item/weapon/cell/potato(user.loc) + del(src) + return \ No newline at end of file diff --git a/code/game/objects/items/weapons/paint.dm b/code/game/objects/items/weapons/paint.dm index fc1d7a39bb..3e92b39a56 100644 --- a/code/game/objects/items/weapons/paint.dm +++ b/code/game/objects/items/weapons/paint.dm @@ -70,7 +70,7 @@ var/global/list/cached_icons = list() desc = "Used to recolor floors and walls. Can not be removed by the janitor." icon = 'items.dmi' icon_state = "paint_neutral" - var/color = "neutral" + var/color = "FFFFFF" item_state = "paintcan" w_class = 3.0 @@ -109,6 +109,7 @@ var/global/list/cached_icons = list() color = "FFFFFF" icon_state = "paint_white" + /obj/item/weapon/paint/anycolor name = "Any color" icon_state = "paint_neutral" diff --git a/code/game/objects/radio/radio.dm b/code/game/objects/radio/radio.dm index 0ab794a27a..0498b7aafe 100644 --- a/code/game/objects/radio/radio.dm +++ b/code/game/objects/radio/radio.dm @@ -129,11 +129,12 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use if(!src.loc) on = 0 - var/area/A = get_area(src) - if(!A || !isarea(A) || !A.master) - on = 0 else - on = A.master.powered(EQUIP) // set "on" to the power status + var/area/A = src.loc.loc + if(!A || !isarea(A) || !A.master) + on = 0 + else + on = A.master.powered(EQUIP) // set "on" to the power status if(!on) icon_state = "intercom-p" @@ -255,6 +256,10 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use /obj/item/device/radio/talk_into(mob/M as mob, message, channel) if(!on) return // the device has to be on +/* Fix for permacell radios, but kinda eh about actually fixing them. + if(!(src.wires & WIRE_TRANSMIT)) // The device has to have all its wires and shit intact + return +*/ if(GLOBAL_RADIO_TYPE == 1) // NEW RADIO SYSTEMS: By Doohl diff --git a/code/game/objects/storage/crates.dm b/code/game/objects/storage/crates.dm index 0ad00b3a4c..39689a3eaa 100644 --- a/code/game/objects/storage/crates.dm +++ b/code/game/objects/storage/crates.dm @@ -144,17 +144,6 @@ icon_opened = "hydrocrateopen" icon_closed = "hydrocrate" density = 1 -/* New() // This stuff shouldn't be here, it should be in /datum/supply_packs/hydroponics - ..() - new /obj/item/weapon/plantbgone(src) - new /obj/item/weapon/plantbgone(src) - new /obj/item/weapon/plantbgone(src) - new /obj/item/weapon/minihoe(src) - new /obj/item/weapon/weedspray(src) - new /obj/item/weapon/weedspray(src) - new /obj/item/weapon/pestspray(src) - new /obj/item/weapon/pestspray(src) - new /obj/item/weapon/pestspray(src) */ /obj/structure/closet/crate/hydroponics/prespawned //This exists so the prespawned hydro crates spawn with their contents. @@ -170,6 +159,7 @@ new /obj/item/weapon/plantbgone(src) new /obj/item/weapon/plantbgone(src) new /obj/item/weapon/plantbgone(src) + new /obj/item/weapon/hatchet(src) new /obj/item/weapon/minihoe(src) // new /obj/item/weapon/weedspray(src) // new /obj/item/weapon/weedspray(src) @@ -217,6 +207,7 @@ for(var/obj/O in src) O.loc = get_turf(src) + for(var/mob/M in src) M.loc = get_turf(src) @@ -225,9 +216,11 @@ /obj/structure/closet/crate/close() playsound(src.loc, 'click.ogg', 15, 1, -3) + for(var/obj/O in get_turf(src)) if(O.density || O.anchored || O == src) continue O.loc = src + icon_state = icon_closed src.opened = 0 @@ -286,7 +279,7 @@ user.drop_item() if(W) W.loc = src.loc - else if(istype(W,/obj/item/weapon/packageWrap)) + else if(istype(W, /obj/item/weapon/packageWrap)) return else return attack_hand(user) diff --git a/code/game/objects/storage/storage.dm b/code/game/objects/storage/storage.dm index b41a931346..7a80dbec9c 100644 --- a/code/game/objects/storage/storage.dm +++ b/code/game/objects/storage/storage.dm @@ -390,6 +390,18 @@ return return ///////////////////////////////////////////////////////Alright, that should do it. *MARKER* for any possible runtimes + +/obj/item/weapon/storage/pill_bottle/verb/toggle_mode() + set name = "Switch Pill Bottle Method" + set category = "Object" + + mode = !mode + switch (mode) + if(1) + usr << "The pill bottle now picks up all pills in a tile at once." + if(0) + usr << "The pill bottle now picks up one pill at a time." + /obj/item/weapon/storage/pillbottlebox/New() new /obj/item/weapon/storage/pill_bottle( src ) new /obj/item/weapon/storage/pill_bottle( src ) diff --git a/code/game/objects/window.dm b/code/game/objects/window.dm index 34c42f24bb..a022f63f13 100644 --- a/code/game/objects/window.dm +++ b/code/game/objects/window.dm @@ -224,9 +224,11 @@ playsound(src.loc, 'Crowbar.ogg', 75, 1) user << (state ? "You have pried the window into the frame." : "You have pried the window out of the frame.") else + var/aforce = W.force if(reinf) aforce /= 2.0 - src.health = max(0, src.health - aforce) + if(W.damtype == BRUTE || W.damtype == BURN) + src.health = max(0, src.health - aforce) playsound(src.loc, 'Glasshit.ogg', 75, 1) if (src.health <= 7) src.anchored = 0 diff --git a/code/game/smoothwall.dm b/code/game/smoothwall.dm index 7a4a0629f8..b67766a018 100644 --- a/code/game/smoothwall.dm +++ b/code/game/smoothwall.dm @@ -15,6 +15,9 @@ for(var/obj/structure/falsewall/W in orange(src,1)) if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls junction |= get_dir(src,W) + for(var/obj/structure/falserwall/W in orange(src,1)) + if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls + junction |= get_dir(src,W) /* Commenting this out for now until we figure out what to do with shuttle smooth walls, if anything. As they are now, they sort of work screwy and may need further coding. Or just be scrapped.*/ @@ -73,24 +76,25 @@ return -/turf/simulated/wall/New() - +/atom/proc/relativewall_neighbours() for(var/turf/simulated/wall/W in range(src,1)) W.relativewall() - for(var/obj/structure/falsewall/W in range(src,1)) W.relativewall() + for(var/obj/structure/falserwall/W in range(src,1)) + W.relativewall() + return +/turf/simulated/wall/New() + relativewall_neighbours() ..() /obj/structure/falsewall/New() + relativewall_neighbours() + ..() - for(var/turf/simulated/wall/W in range(src,1)) - W.relativewall() - - for(var/obj/structure/falsewall/W in range(src,1)) - W.relativewall() - +/obj/structure/falserwall/New() + relativewall_neighbours() ..() /*/turf/simulated/shuttle/wall/New() @@ -134,6 +138,8 @@ for(var/obj/structure/falsewall/W in range(temploc,1)) W.relativewall() + for(var/obj/structure/falserwall/W in range(temploc,1)) + W.relativewall() ..() /*/turf/simulated/shuttle/wall/Del() @@ -144,4 +150,4 @@ for(var/turf/simulated/shuttle/wall/W in range(temploc,1)) W.relativewall() - ..()*/ \ No newline at end of file + ..()*/ diff --git a/code/game/step_triggers.dm b/code/game/step_triggers.dm new file mode 100644 index 0000000000..53169583c8 --- /dev/null +++ b/code/game/step_triggers.dm @@ -0,0 +1,114 @@ +/* Simple object type, calls a proc when "stepped" on by something */ + +/obj/step_trigger + var/affect_ghosts = 0 + var/stopper = 1 // stops throwers + invisibility = 101 // nope cant see this shit + anchored = 1 + +/obj/step_trigger/proc/Trigger(var/atom/movable/A) + return 0 + +/obj/step_trigger/HasEntered(H as mob|obj) + ..() + if(!H) + return + if(istype(H, /mob/dead/observer) && !affect_ghosts) + return + Trigger(H) + + + +/* Tosses things in a certain direction */ + +/obj/step_trigger/thrower + var/direction = SOUTH // the direction of throw + var/tiles = 3 // if 0: forever until atom hits a stopper + var/immobilize = 1 // if nonzero: prevents mobs from moving while they're being flung + var/speed = 1 // delay of movement + var/facedir = 0 // if 1: atom faces the direction of movement + var/nostop = 0 // if 1: will only be stopped by teleporters + var/list/affecting = list() + + Trigger(var/atom/movable/A) + var/curtiles = 0 + var/stopthrow = 0 + for(var/obj/step_trigger/thrower/T in orange(2, src)) + if(A in T.affecting) + return + + if(ismob(A)) + var/mob/M = A + if(immobilize) + M.canmove = 0 + + affecting.Add(A) + while(A && !stopthrow) + if(tiles) + if(curtiles >= tiles) + break + if(A.z != src.z) + break + + curtiles++ + + sleep(speed) + + // Calculate if we should stop the process + if(!nostop) + for(var/obj/step_trigger/T in get_step(A, direction)) + if(T.stopper && T != src) + stopthrow = 1 + else + for(var/obj/step_trigger/teleporter/T in get_step(A, direction)) + if(T.stopper) + stopthrow = 1 + + if(A) + var/predir = A.dir + step(A, direction) + if(!facedir) + A.dir = predir + + + + affecting.Remove(A) + + if(ismob(A)) + var/mob/M = A + if(immobilize) + M.canmove = 1 + +/* Stops things thrown by a thrower, doesn't do anything */ + +/obj/step_trigger/stopper + +/* Instant teleporter */ + +/obj/step_trigger/teleporter + var/teleport_x = 0 // teleportation coordinates (if one is null, then no teleport!) + var/teleport_y = 0 + var/teleport_z = 0 + + Trigger(var/atom/movable/A) + if(teleport_x && teleport_y && teleport_z) + + A.x = teleport_x + A.y = teleport_y + A.z = teleport_z + +/* Random teleporter, teleports atoms to locations ranging from teleport_x - teleport_x_offset, etc */ + +/obj/step_trigger/teleporter/random + var/teleport_x_offset = 0 + var/teleport_y_offset = 0 + var/teleport_z_offset = 0 + + Trigger(var/atom/movable/A) + if(teleport_x && teleport_y && teleport_z) + if(teleport_x_offset && teleport_y_offset && teleport_z_offset) + + A.x = rand(teleport_x, teleport_x_offset) + A.y = rand(teleport_y, teleport_y_offset) + A.z = rand(teleport_z, teleport_z_offset) + diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index d4e838e9f9..440cc68040 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -7,7 +7,7 @@ #define SUPPLY_POINTSPERCRATE 5 //Points per crate sent back. #define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station #define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock -#define SUPPLY_POINTSPERSLIP 1 //points per packing slip sent back stamped. +#define SUPPLY_POINTSPERSLIP 2 //points per packing slip sent back stamped. var/supply_shuttle_moving = 0 var/supply_shuttle_at_station = 0 @@ -37,7 +37,7 @@ var/list/supply_groups = new() //SUPPLY PACKS MOVED TO /code/defines/obj/supplypacks.dm /obj/structure/plasticflaps //HOW DO YOU CALL THOSE THINGS ANYWAY - name = "Plastic flaps" + name = "\improper Plastic flaps" desc = "Durable plastic flaps." icon = 'stationobjs.dmi' //Change this. icon_state = "plasticflaps" @@ -162,9 +162,47 @@ var/list/supply_groups = new() supply_shuttle_moving = 0 send_supply_shuttle() + /proc/supply_can_move() if(supply_shuttle_moving) return 0 + //Check for carbon mobs - Allows simple animals. + for(var/mob/living/carbon/M in world) + var/area/A = get_area(M) + if(!A || !A.type) continue + if(A.type == /area/supply/station) + return 0 + //Check for silicon mobs - Allows simple animals. + for(var/mob/living/silicon/M in world) + var/area/A = get_area(M) + if(!A || !A.type) continue + if(A.type == /area/supply/station) + return 0 + //Check for beacons + for(var/obj/item/device/radio/beacon/B in world) + var/area/A = get_area(B) + if(!A || !A.type) continue + if(A.type == /area/supply/station) + return 0 + //Check for mechs. I think this was added because people were somehow on centcomm and bringing back centcomm mechs. + for(var/obj/mecha/Mech in world) + var/area/A = get_area(Mech) + if(!A || !A.type) continue + if(A.type == /area/supply/station) + return 0 + //Check for nuke disk This also prevents multiple nuke disks from being made -Nodrak + for(var/obj/item/weapon/disk/nuclear/N) + var/area/A = get_area(N) + if(!A || !A.type) continue + if(A.type == /area/supply/station) + return 0 + return 1 +/* +Teleport beacon -> wrapping paper -> backpack -> bodybag -> crate -> wrapping paper -> loaded on a mulebot +That would be a teleport beacon inside of 6-layers deep in contents. Meaning you would have to add more loops or more checks. +This method wont take into account storage items developed in the future and doesn't take into account the storage items we have currently. +-Nodrak + var/shuttleat = supply_shuttle_at_station ? SUPPLY_STATION_AREATYPE : SUPPLY_DOCK_AREATYPE for(var/turf/T in get_area_turfs(shuttleat) ) @@ -185,7 +223,7 @@ var/list/supply_groups = new() if((locate(/obj/mecha ) in ATMM)) return 0 if((locate(/obj/structure/closet/body_bag) in ATMM)) return 0 return 1 - +*/ /proc/sell_crates() var/shuttleat = supply_shuttle_at_station ? SUPPLY_STATION_AREATYPE : SUPPLY_DOCK_AREATYPE @@ -474,7 +512,7 @@ var/list/supply_groups = new() if(!supply_shuttle_at_station || supply_shuttle_moving) return if (!supply_can_move()) - usr << "\red The supply shuttle can not transport station employees, exosuits, or homing beacons." + usr << "\red The supply shuttle can not transport station employees, exosuits, classified nuclear codes or homing beacons." return src.temp = "Shuttle sent.

OK" @@ -485,13 +523,21 @@ var/list/supply_groups = new() supply_shuttle_shoppinglist = new/list() sell_crates() + + //Remove anything or anyone that was either left behind or that bypassed supply_can_move() -Nodrak + for(var/area/supply/station/A in world) + for(var/obj/item/I in A.contents) + del(I) + for(var/mob/living/M in A.contents) + del(M) + send_supply_shuttle() else if (href_list["sendtostation"]) if(supply_shuttle_at_station || supply_shuttle_moving) return if (!supply_can_move()) - usr << "\red The supply shuttle can not transport station employees or homing beacons." + usr << "\red The supply shuttle can not transport station employees, exosuits, classified nuclear codes or homing beacons." return post_signal("supply") diff --git a/code/game/syndicate_specops_shuttle.dm b/code/game/syndicate_specops_shuttle.dm index 2bef199b1c..15b9456c8c 100644 --- a/code/game/syndicate_specops_shuttle.dm +++ b/code/game/syndicate_specops_shuttle.dm @@ -29,7 +29,7 @@ var/syndicate_elite_shuttle_timeleft = 0 if(announcer) announcer.say(message) // message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD" - announcer.say(message) + // announcer.say(message) while(syndicate_elite_shuttle_time - world.timeofday > 0) var/ticksleft = syndicate_elite_shuttle_time - world.timeofday @@ -192,9 +192,9 @@ var/syndicate_elite_shuttle_timeleft = 0 user << "\red Access Denied." return - if (sent_syndicate_strike_team == 0) - usr << "\red The strike team has not yet deployed." - return +// if (sent_syndicate_strike_team == 0) +// usr << "\red The strike team has not yet deployed." +// return if(..()) return @@ -243,7 +243,7 @@ var/syndicate_elite_shuttle_timeleft = 0 elite_squad.readyalert()//Trigger alarm for the spec ops area. syndicate_elite_shuttle_moving_to_station = 1 - syndicate_elite_shuttle_time = world.timeofday + syndicate_elite_shuttle_time = world.timeofday + SYNDICATE_ELITE_MOVETIME spawn(0) syndicate_elite_process() diff --git a/code/game/topic.dm b/code/game/topic.dm index f60ec272c9..c1827cdffd 100644 --- a/code/game/topic.dm +++ b/code/game/topic.dm @@ -12,8 +12,11 @@ s["host"] = host ? host : null s["players"] = list() s["admins"] = 0 + var/admins = 0 var/n = 0 + for(var/client/C) + n++ if(C.holder && C.holder.level >= 0) //not retired admin if(!C.stealth) //stealthmins dont count as admins @@ -25,4 +28,8 @@ s["player[n]"] = "[C.key]" s["players"] = n s["end"] = "#end" - return list2params(s) \ No newline at end of file + + // 7 + s["players"] + 1 = index of s["revinfo"] + s["admins"] = admins + + return list2params(s) diff --git a/code/game/turf.dm b/code/game/turf.dm index effb872f87..7e19555631 100644 --- a/code/game/turf.dm +++ b/code/game/turf.dm @@ -290,8 +290,8 @@ air_master.tiles_to_update += S return S -/turf/simulated/wall/New() - ..() +//turf/simulated/wall/New() +// ..() /turf/simulated/wall/proc/dismantle_wall(devastated=0, explode=0) if(istype(src,/turf/simulated/wall/r_wall)) @@ -303,6 +303,14 @@ new /obj/item/stack/sheet/metal( src ) new /obj/item/stack/sheet/metal( src ) new /obj/item/stack/sheet/plasteel( src ) + else if(istype(src,/turf/simulated/wall/cult)) + if(!devastated) + playsound(src.loc, 'Welder.ogg', 100, 1) + new /obj/effect/decal/cleanable/blood(src) + else + new /obj/effect/decal/cleanable/blood(src) + new /obj/effect/decal/remains/human(src) + else if(!devastated) playsound(src.loc, 'Welder.ogg', 100, 1) @@ -396,293 +404,371 @@ /turf/simulated/wall/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") - usr << "\red You don't have the dexterity to do this!" + if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") + user << "You don't have the dexterity to do this!" return - if (istype(W, /obj/item/weapon/weldingtool) && W:welding) - var/turf/T = get_turf(user) - if (!( istype(T, /turf) )) + //get the user's location + if( !istype(user.loc, /turf) ) return //can't do this stuff whilst inside objects and such + + //THERMITE related stuff. Calls src.thermitemelt() which handles melting simulated walls and the relevant effects + if( thermite ) + if( istype(W, /obj/item/weapon/weldingtool) ) + var/obj/item/weapon/weldingtool/WT = W + if( WT.remove_fuel(0,user) ) + thermitemelt(user) + return + + else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) + thermitemelt(user) return - if (thermite) - var/obj/effect/overlay/O = new/obj/effect/overlay( src ) - O.name = "Thermite" - O.desc = "Looks hot." - O.icon = 'fire.dmi' - O.icon_state = "2" - O.anchored = 1 - O.density = 1 - O.layer = 5 - var/turf/simulated/floor/F = ReplaceWithPlating() - F.burn_tile() - F.icon_state = "wall_thermite" - user << "\red The thermite melts the wall." - spawn(100) del(O) - F.sd_LumReset() + else if( istype(W, /obj/item/weapon/melee/energy/blade) ) + var/obj/item/weapon/melee/energy/blade/EB = W + + EB.spark_system.start() + user << "You slash \the [src] with \the [EB]; the thermite ignites!" + playsound(src.loc, "sparks", 50, 1) + playsound(src.loc, 'blade1.ogg', 50, 1) + + thermitemelt(user) return - if (W:remove_fuel(0,user)) - W:welding = 2 - user << "\blue Now disassembling the outer wall plating." + var/turf/T = user.loc //get user's location for delay checks + + //DECONSTRUCTION + if( istype(W, /obj/item/weapon/weldingtool) ) + var/obj/item/weapon/weldingtool/WT = W + if( WT.remove_fuel(0,user) ) + WT.welding = 2 + + user << "You begin slicing through the outer plating." playsound(src.loc, 'Welder.ogg', 100, 1) + sleep(100) - if (W && istype(src, /turf/simulated/wall)) - if ((get_turf(user) == T && user.equipped() == W)) - user << "\blue You disassembled the outer wall plating." - dismantle_wall() - W:welding = 1 + if( !istype(src, /turf/simulated/wall) || !user || !WT || !T ) return + WT.welding = 1 + + if( user.loc == T && user.equipped() == WT ) + user << "You remove the outer plating." + dismantle_wall() else - user << "\blue You need more welding fuel to complete this task." + user << "You need more welding fuel to complete this task." return - else if (istype(W, /obj/item/weapon/pickaxe/plasmacutter)) - var/turf/T = user.loc - if (!( istype(T, /turf) )) - return + else if( istype(W, /obj/item/weapon/pickaxe/plasmacutter) ) - if (thermite) - var/obj/effect/overlay/O = new/obj/effect/overlay( src ) - O.name = "Thermite" - O.desc = "Looks hot." - O.icon = 'fire.dmi' - O.icon_state = "2" - O.anchored = 1 - O.density = 1 - O.layer = 5 - var/turf/simulated/floor/F = ReplaceWithPlating() - F.burn_tile() - F.icon_state = "wall_thermite" - user << "\red The thermite melts the wall." - spawn(100) del(O) - F.sd_LumReset() - return + user << "You begin slicing through the outer plating." + playsound(src.loc, 'Welder.ogg', 100, 1) - else - user << "\blue Now disassembling the outer wall plating." - playsound(src.loc, 'Welder.ogg', 100, 1) - sleep(60) - if (W && istype(src, /turf/simulated/wall)) - if ((get_turf(user) == T && user.equipped() == W)) - user << "\blue You disassembled the outer wall plating." - dismantle_wall() - for(var/mob/O in viewers(user, 5)) - O.show_message(text("\blue The wall was sliced apart by []!", user), 1, text("\red You hear metal being sliced apart."), 2) - return - - else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill)) - var/turf/T = user.loc - user << "\blue Now drilling through wall." sleep(60) - if (W && istype(src, /turf/simulated/wall)) - if ((user.loc == T && user.equipped() == W)) - dismantle_wall(1) - for(var/mob/O in viewers(user, 5)) - O.show_message(text("\blue The wall was drilled apart by []!", user), 1, text("\red You hear metal being drilled appart."), 2) + if( !istype(src, /turf/simulated/wall) || !user || !W || !T ) return + + if( user.loc == T && user.equipped() == W ) + user << "You remove the outer plating." + dismantle_wall() + for(var/mob/O in viewers(user, 5)) + O.show_message("The wall was sliced apart by [user]!", 1, "You hear metal being sliced apart.", 2) return - else if(istype(W, /obj/item/weapon/melee/energy/blade)) - var/turf/T = user.loc - user << "\blue Now slicing through wall." - W:spark_system.start() + //DRILLING + else if (istype(W, /obj/item/weapon/pickaxe/diamonddrill)) + + user << "You begin to drill though the wall." + + sleep(60) + if( !istype(src, /turf/simulated/wall) || !user || !W || !T ) return + + if( user.loc == T && user.equipped() == W ) + user << "Your drill tears though the last of the reinforced plating." + dismantle_wall() + for(var/mob/O in viewers(user, 5)) + O.show_message("The wall was drilled through by [user]!", 1, "You hear the grinding of metal.", 2) + return + + else if( istype(W, /obj/item/weapon/melee/energy/blade) ) + var/obj/item/weapon/melee/energy/blade/EB = W + + EB.spark_system.start() + user << "You stab \the [EB] into the wall and begin to slice it apart." playsound(src.loc, "sparks", 50, 1) + sleep(70) - if (W && istype(src, /turf/simulated/wall)) - if ((user.loc == T && user.equipped() == W)) - W:spark_system.start() - playsound(src.loc, "sparks", 50, 1) - playsound(src.loc, 'blade1.ogg', 50, 1) - dismantle_wall(1) - for(var/mob/O in viewers(user, 5)) - O.show_message(text("\blue The wall was sliced apart by []!", user), 1, text("\red You hear metal being sliced and sparks flying."), 2) + if( !istype(src, /turf/simulated/wall) || !user || !EB || !T ) return + + if( user.loc == T && user.equipped() == W ) + EB.spark_system.start() + playsound(src.loc, "sparks", 50, 1) + playsound(src.loc, 'blade1.ogg', 50, 1) + dismantle_wall(1) + for(var/mob/O in viewers(user, 5)) + O.show_message("The wall was sliced apart by [user]!", 1, "You hear metal being sliced apart and sparks flying.", 2) return else if(istype(W,/obj/item/apc_frame)) var/obj/item/apc_frame/AH = W AH.try_build(src) + return else return attack_hand(user) return - /turf/simulated/wall/r_wall/attackby(obj/item/W as obj, mob/user as mob) - if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") - usr << "\red You don't have the dexterity to do this!" + if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") + user << "You don't have the dexterity to do this!" return - if(!istype(src, /turf/simulated/wall/r_wall)) - return // this may seem stupid and redundant but apparently floors can call this attackby() proc, it was spamming shit up. -- Doohl + //get the user's location + if( !istype(user.loc, /turf) ) return //can't do this stuff whilst inside objects and such - if (istype(W, /obj/item/weapon/weldingtool) && W:welding) - W:eyecheck(user) - var/turf/T = user.loc - if (!( istype(T, /turf) )) - return - - if (thermite) - var/obj/effect/overlay/O = new/obj/effect/overlay( src ) - O.name = "Thermite" - O.desc = "Looks hot." - O.icon = 'fire.dmi' - O.icon_state = "2" - O.anchored = 1 - O.density = 1 - O.layer = 5 - var/turf/simulated/floor/F = ReplaceWithPlating() - F.burn_tile() - F.icon_state = "wall_thermite" - user << "\red The thermite melts the wall." - spawn(100) del(O) - F.sd_LumReset() - return - - if (src.d_state == 2) - W:welding = 2 - user << "\blue Slicing metal cover." - playsound(src.loc, 'Welder.ogg', 100, 1) - sleep(60) - if ((user.loc == T && user.equipped() == W)) - src.d_state = 3 - user << "\blue You removed the metal cover." - W:welding = 1 - - else if (src.d_state == 5) - W:welding = 2 - user << "\blue Removing support rods." - playsound(src.loc, 'Welder.ogg', 100, 1) - sleep(100) - if ((user.loc == T && user.equipped() == W)) - src.d_state = 6 - new /obj/item/stack/rods( src ) - user << "\blue You removed the support rods." - W:welding = 1 - - else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) - var/turf/T = user.loc - if (!( istype(T, /turf) )) - return - - if (thermite) - var/obj/effect/overlay/O = new/obj/effect/overlay( src ) - O.name = "Thermite" - O.desc = "Looks hot." - O.icon = 'fire.dmi' - O.icon_state = "2" - O.anchored = 1 - O.density = 1 - O.layer = 5 - var/turf/simulated/floor/F = ReplaceWithPlating() - F.burn_tile() - F.icon_state = "wall_thermite" - user << "\red The thermite melts the wall." - spawn(100) del(O) - F.sd_LumReset() - return - - if (src.d_state == 2) - user << "\blue Slicing metal cover." - playsound(src.loc, 'Welder.ogg', 100, 1) - sleep(40) - if ((user.loc == T && user.equipped() == W)) - src.d_state = 3 - user << "\blue You removed the metal cover." - - else if (src.d_state == 5) - user << "\blue Removing support rods." - playsound(src.loc, 'Welder.ogg', 100, 1) - sleep(70) - if ((user.loc == T && user.equipped() == W)) - src.d_state = 6 - new /obj/item/stack/rods( src ) - user << "\blue You removed the support rods." - - else if(istype(W, /obj/item/weapon/melee/energy/blade)) - user << "\blue This wall is too thick to slice through. You will need to find a different path." - return - - else if (istype(W, /obj/item/weapon/wrench)) - if (src.d_state == 4) - var/turf/T = user.loc - user << "\blue Detaching support rods." - playsound(src.loc, 'Ratchet.ogg', 100, 1) - sleep(40) - if ((user.loc == T && user.equipped() == W)) - src.d_state = 5 - user << "\blue You detach the support rods." - - else if (istype(W, /obj/item/weapon/wirecutters)) - if (src.d_state == 0) - playsound(src.loc, 'Wirecutter.ogg', 100, 1) - src.d_state = 1 - new /obj/item/stack/rods( src ) - - else if (istype(W, /obj/item/weapon/screwdriver)) - if (src.d_state == 1) - var/turf/T = user.loc - playsound(src.loc, 'Screwdriver.ogg', 100, 1) - user << "\blue Removing support lines." - sleep(40) - if ((user.loc == T && user.equipped() == W)) - src.d_state = 2 - user << "\blue You removed the support lines." - - else if (istype(W, /obj/item/weapon/crowbar)) - - if (src.d_state == 3) - var/turf/T = user.loc - user << "\blue Prying cover off." - playsound(src.loc, 'Crowbar.ogg', 100, 1) - sleep(100) - if ((user.loc == T && user.equipped() == W)) - src.d_state = 4 - user << "\blue You removed the cover." - - else if (src.d_state == 6) - var/turf/T = user.loc - user << "\blue Prying outer sheath off." - playsound(src.loc, 'Crowbar.ogg', 100, 1) - sleep(100) - if ((user.loc == T && user.equipped() == W)) - user << "\blue You removed the outer sheath." - dismantle_wall() + //THERMITE related stuff. Calls src.thermitemelt() which handles melting simulated walls and the relevant effects + if( thermite ) + if( istype(W, /obj/item/weapon/weldingtool) ) + var/obj/item/weapon/weldingtool/WT = W + if( WT.remove_fuel(0,user) ) + thermitemelt(user) return - else if (istype(W, /obj/item/weapon/pickaxe/diamonddrill)) - var/turf/T = user.loc - user << "\blue You begin to drill though, this will take some time." - sleep(200) - if ((user.loc == T && user.equipped() == W)) - user << "\blue Your drill tears though the reinforced plating." - dismantle_wall() + else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) + thermitemelt(user) return - else if ((istype(W, /obj/item/stack/sheet/metal)) && (src.d_state)) - var/turf/T = user.loc - user << "\blue Repairing wall." - sleep(100) - if ((user.loc == T && user.equipped() == W)) - src.d_state = 0 - src.icon_state = initial(src.icon_state) - user << "\blue You repaired the wall." - if (W:amount > 1) - W:amount-- - else - del(W) + else if( istype(W, /obj/item/weapon/melee/energy/blade) ) + var/obj/item/weapon/melee/energy/blade/EB = W - if(istype(W,/obj/item/apc_frame)) - var/obj/item/apc_frame/AH = W - AH.try_build(src) + EB.spark_system.start() + user << "You slash \the [src] with \the [EB]; the thermite ignites!" + playsound(src.loc, "sparks", 50, 1) + playsound(src.loc, 'blade1.ogg', 50, 1) + + thermitemelt(user) + return + + else if(istype(W, /obj/item/weapon/melee/energy/blade)) + user << "This wall is too thick to slice through. You will need to find a different path." return - if(src.d_state > 0) - src.icon_state = "r_wall-[d_state]" + var/turf/T = user.loc //get user's location for delay checks - else + //DECONSTRUCTION + switch(d_state) + if(0) + if (istype(W, /obj/item/weapon/wirecutters)) + playsound(src.loc, 'Wirecutter.ogg', 100, 1) + src.d_state = 1 + src.icon_state = "r_wall-1" + new /obj/item/stack/rods( src ) + user << "You cut the outer grille." + return + + if(1) + if (istype(W, /obj/item/weapon/screwdriver)) + user << "You begin removing the support lines." + playsound(src.loc, 'Screwdriver.ogg', 100, 1) + + sleep(40) + if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return + + if( d_state == 1 && user.loc == T && user.equipped() == W ) + src.d_state = 2 + src.icon_state = "r_wall-2" + user << "You remove the support lines." + return + + //REPAIRING (replacing the outer grille for cosmetic damage) + else if( istype(W, /obj/item/stack/rods) ) + var/obj/item/stack/O = W + src.d_state = 0 + src.icon_state = "r_wall" + relativewall_neighbours() //call smoothwall stuff + user << "You replace the outer grille." + if (O.amount > 1) + O.amount-- + else + del(O) + return + + if(2) + if( istype(W, /obj/item/weapon/weldingtool) ) + var/obj/item/weapon/weldingtool/WT = W + if( WT.remove_fuel(0,user) ) + WT.welding = 2 + + user << "You begin slicing through the metal cover." + playsound(src.loc, 'Welder.ogg', 100, 1) + + sleep(60) + if( !istype(src, /turf/simulated/wall/r_wall) || !user || !WT || !T ) return + WT.welding = 1 + + if( d_state == 2 && user.loc == T && user.equipped() == WT ) + src.d_state = 3 + src.icon_state = "r_wall-3" + user << "You press firmly on the cover, dislodging it." + else + user << "You need more welding fuel to complete this task." + return + + if( istype(W, /obj/item/weapon/pickaxe/plasmacutter) ) + + user << "You begin slicing through the metal cover." + playsound(src.loc, 'Welder.ogg', 100, 1) + + sleep(40) + if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return + + if( d_state == 2 && user.loc == T && user.equipped() == W ) + src.d_state = 3 + src.icon_state = "r_wall-3" + user << "You press firmly on the cover, dislodging it." + return + + if(3) + if (istype(W, /obj/item/weapon/crowbar)) + + user << "You struggle to pry off the cover." + playsound(src.loc, 'Crowbar.ogg', 100, 1) + + sleep(100) + if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return + + if( d_state == 3 && user.loc == T && user.equipped() == W ) + src.d_state = 4 + src.icon_state = "r_wall-4" + user << "You pry off the cover." + return + + if(4) + if (istype(W, /obj/item/weapon/wrench)) + + user << "You start loosening the anchoring bolts which secure the support rods to their frame." + playsound(src.loc, 'Ratchet.ogg', 100, 1) + + sleep(40) + if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return + + if( d_state == 4 && user.loc == T && user.equipped() == W ) + src.d_state = 5 + src.icon_state = "r_wall-5" + user << "You remove the bolts anchoring the support rods." + return + + if(5) + if( istype(W, /obj/item/weapon/weldingtool) ) + var/obj/item/weapon/weldingtool/WT = W + if( WT.remove_fuel(0,user) ) + WT.welding = 2 + + user << "You begin slicing through the support rods." + playsound(src.loc, 'Welder.ogg', 100, 1) + + sleep(100) + if( !istype(src, /turf/simulated/wall/r_wall) || !user || !WT || !T ) return + WT.welding = 1 + + if( d_state == 5 && user.loc == T && user.equipped() == WT ) + src.d_state = 6 + src.icon_state = "r_wall-6" + new /obj/item/stack/rods( src ) + user << "The support rods drop out as you cut them loose from the frame." + else + user << "You need more welding fuel to complete this task." + return + + if( istype(W, /obj/item/weapon/pickaxe/plasmacutter) ) + + user << "You begin slicing through the support rods." + playsound(src.loc, 'Welder.ogg', 100, 1) + + sleep(70) + if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return + + if( d_state == 5 && user.loc == T && user.equipped() == W ) + src.d_state = 6 + src.icon_state = "r_wall-6" + new /obj/item/stack/rods( src ) + user << "The support rods drop out as you cut them loose from the frame." + return + + if(6) + if( istype(W, /obj/item/weapon/crowbar) ) + + user << "You struggle to pry off the outer sheath." + playsound(src.loc, 'Crowbar.ogg', 100, 1) + + sleep(100) + if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return + + if( user.loc == T && user.equipped() == W ) + user << "You pry off the outer sheath." + dismantle_wall() + return + +//vv OK, we weren't performing a valid deconstruction step or igniting thermite,let's check the other possibilities vv + + //DRILLING + if (istype(W, /obj/item/weapon/pickaxe/diamonddrill)) + + user << "You begin to drill though the wall." + + sleep(200) + if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return + + if( user.loc == T && user.equipped() == W ) + user << "Your drill tears though the last of the reinforced plating." + dismantle_wall() + + //REPAIRING + else if( istype(W, /obj/item/stack/sheet/metal) && d_state ) + var/obj/item/stack/sheet/metal/MS = W + + user << "You begin patching-up the wall with \a [MS]." + + sleep( max(20*d_state,100) ) //time taken to repair is proportional to the damage! (max 10 seconds) + if( !istype(src, /turf/simulated/wall/r_wall) || !user || !MS || !T ) return + + if( user.loc == T && user.equipped() == MS && d_state ) + src.d_state = 0 + src.icon_state = "r_wall" + relativewall_neighbours() //call smoothwall stuff + user << "You repair the last of the damage." + if (MS.amount > 1) + MS.amount-- + else + del(MS) + + //APC + else if( istype(W,/obj/item/apc_frame) ) + var/obj/item/apc_frame/AH = W + AH.try_build(src) + + //Finally, CHECKING FOR FALSE WALLS if it isn't damaged + else if(!d_state) return attack_hand(user) return +/turf/simulated/wall/proc/thermitemelt(mob/user as mob) + var/obj/effect/overlay/O = new/obj/effect/overlay( src ) + O.name = "Thermite" + O.desc = "Looks hot." + O.icon = 'fire.dmi' + O.icon_state = "2" + O.anchored = 1 + O.density = 1 + O.layer = 5 + + var/turf/simulated/floor/F = ReplaceWithPlating() + F.burn_tile() + F.icon_state = "wall_thermite" + user << "The thermite melts through the wall." + + spawn(100) + if(O) del(O) + F.sd_LumReset() + return + /turf/simulated/wall/meteorhit(obj/M as obj) if (prob(15)) dismantle_wall() @@ -743,8 +829,9 @@ var/list/plating_icons = list("plating","platingdmg1","platingdmg2","platingdmg3 var/n = name //just in case commands rename it in the ..() call ..() spawn(4) - update_icon() - name = n + if(src) + update_icon() + name = n grass name = "Grass patch" @@ -756,11 +843,12 @@ var/list/plating_icons = list("plating","platingdmg1","platingdmg2","platingdmg3 icon_state = "grass[pick("1","2","3","4")]" ..() spawn(4) - update_icon() - for(var/direction in cardinal) - if(istype(get_step(src,direction),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,direction) - FF.update_icon() //so siding get updated properly + if(src) + update_icon() + for(var/direction in cardinal) + if(istype(get_step(src,direction),/turf/simulated/floor)) + var/turf/simulated/floor/FF = get_step(src,direction) + FF.update_icon() //so siding get updated properly /turf/simulated/floor/vault icon_state = "rockvault" @@ -782,6 +870,11 @@ var/list/plating_icons = list("plating","platingdmg1","platingdmg2","platingdmg3 thermal_conductivity = 0.025 heat_capacity = 325000 +/turf/simulated/floor/engine/cult + name = "engraved floor" + icon_state = "cult" + + /turf/simulated/floor/engine/n20 New() ..() @@ -929,6 +1022,11 @@ turf/simulated/floor/return_siding_icon_state() return if (ismob(user.pulling)) var/mob/M = user.pulling + +// if(M==user) //temporary hack to stop runtimes. ~Carn +// user.pulling = null //but...fixed the root of the problem +// return //shoudn't be needed now, unless somebody fucks with pulling again. + var/mob/t = M.pulling M.pulling = null step(user.pulling, get_dir(user.pulling.loc, src)) @@ -1283,58 +1381,46 @@ turf/simulated/floor/return_siding_icon_state() // Okay, so let's make it so that people can travel z levels but not nuke disks! // if(ticker.mode.name == "nuclear emergency") return + if (src.x <= TRANSITIONEDGE || A.x >= (world.maxx - TRANSITIONEDGE - 1) || src.y <= TRANSITIONEDGE || A.y >= (world.maxy - TRANSITIONEDGE - 1)) + if(istype(A, /obj/effect/meteor)||istype(A, /obj/effect/space_dust)) + del(A) + return + if(istype(A, /obj/item/weapon/disk/nuclear)) // Don't let nuke disks travel Z levels ... And moving this shit down here so it only fires when they're actually trying to change z-level. + del(A) //The disk's Del() proc ensures a new one is created + return - if(istype(A, /obj/item/weapon/disk/nuclear)) // Don't let nuke disks travel Z levels - return + if(!isemptylist(A.search_contents_for(/obj/item/weapon/disk/nuclear))) + if(istype(A, /mob/living)) + var/mob/living/MM = A + if(MM.client) + MM << "\red Something you are carrying is preventing you from leaving. Don't play stupid; you know exactly what it is." + return -// else if(ticker.mode.name == "extended"||ticker.mode.name == "sandbox") Sandbox_Spacemove(A) + var/move_to_z_str = pickweight(accessable_z_levels) - else - if (src.x <= 2 || A.x >= (world.maxx - 1) || src.y <= 2 || A.y >= (world.maxy - 1)) - if(istype(A, /obj/effect/meteor)||istype(A, /obj/effect/space_dust)) - del(A) - return + var/move_to_z = text2num(move_to_z_str) - if(!isemptylist(A.search_contents_for(/obj/item/weapon/disk/nuclear))) - if(istype(A, /mob/living)) - var/mob/living/MM = A - if(MM.client) - MM << "\red Something you are carrying is preventing you from leaving. Don't play stupid; you know exactly what it is." - return + if(!move_to_z) + return + A.z = move_to_z + if(src.x <= TRANSITIONEDGE) + A.x = world.maxx - TRANSITIONEDGE - 2 - var/move_to_z_str = pickweight(accessable_z_levels) + else if (A.x >= (world.maxx - TRANSITIONEDGE - 1)) + A.x = TRANSITIONEDGE + 1 - var/move_to_z = text2num(move_to_z_str) + else if (src.y <= TRANSITIONEDGE) + A.y = world.maxy - TRANSITIONEDGE -2 - if(!move_to_z) - return + else if (A.y >= (world.maxy - TRANSITIONEDGE - 1)) + A.y = TRANSITIONEDGE +1 - - - A.z = move_to_z - - - if(src.x <= 2) - A.x = world.maxx - 2 - - else if (A.x >= (world.maxx - 1)) - A.x = 3 - - else if (src.y <= 2) - A.y = world.maxy - 2 - - else if (A.y >= (world.maxy - 1)) - A.y = 3 - - spawn (0) - if ((A && A.loc)) - A.loc.Entered(A) - -// if(istype(A, /obj/structure/closet/coffin)) -// coffinhandler.Add(A) + spawn (0) + if ((A && A.loc)) + A.loc.Entered(A) /* /turf/space/proc/Sandbox_Spacemove(atom/movable/A as mob|obj) var/cur_x @@ -1444,7 +1530,7 @@ turf/simulated/floor/return_siding_icon_state() if ((A && A.loc)) A.loc.Entered(A) return -*/ +*/ //Don't touch this either! DMTG /obj/effect/vaultspawner var/maxX = 6 var/maxY = 6 diff --git a/code/game/vehicles/airtight/airtight.dm b/code/game/vehicles/airtight/airtight.dm new file mode 100644 index 0000000000..44ee0fff2b --- /dev/null +++ b/code/game/vehicles/airtight/airtight.dm @@ -0,0 +1,165 @@ + +/obj/vehicle/airtight + //inner atmos + var/use_internal_tank = 0 + var/internal_tank_valve = ONE_ATMOSPHERE + var/obj/machinery/portable_atmospherics/canister/internal_tank + var/datum/gas_mixture/cabin_air + var/obj/machinery/atmospherics/portables_connector/connected_port = null + + var/datum/global_iterator/pr_int_temp_processor //normalizes internal air mixture temperature + var/datum/global_iterator/pr_give_air //moves air from tank to cabin + + +/obj/vehicle/airtight/New() + ..() + src.add_airtank() + src.add_cabin() + src.add_airtight_iterators() + + + + +//######################################### Helpers for airtight vehicles ######################################### + +/obj/vehicle/airtight/proc/add_cabin() + cabin_air = new + cabin_air.temperature = T20C + cabin_air.volume = 200 + cabin_air.oxygen = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + cabin_air.nitrogen = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + return cabin_air + +/obj/vehicle/airtight/proc/add_airtank() + internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src) + return internal_tank + +/obj/vehicle/airtight/proc/add_airtight_iterators() + pr_int_temp_processor = new /datum/global_iterator/vehicle_preserve_temp(list(src)) + pr_give_air = new /datum/global_iterator/vehicle_tank_give_air(list(src)) + + +//######################################### Specific datums for airtight vehicles ################################# + + +/datum/global_iterator/vehicle_preserve_temp //normalizing cabin air temperature to 20 degrees celsium + delay = 20 + + process(var/obj/vehicle/airtight/V) + if(V.cabin_air && V.cabin_air.return_volume() > 0) + var/delta = V.cabin_air.temperature - T20C + V.cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1))) + return + + +/datum/global_iterator/vehicle_tank_give_air + delay = 15 + + process(var/obj/vehicle/airtight/V) + if(V.internal_tank) + var/datum/gas_mixture/tank_air = V.internal_tank.return_air() + var/datum/gas_mixture/cabin_air = V.cabin_air + + var/release_pressure = V.internal_tank_valve + var/cabin_pressure = cabin_air.return_pressure() + var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) + var/transfer_moles = 0 + if(pressure_delta > 0) //cabin pressure lower than release pressure + if(tank_air.return_temperature() > 0) + transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + var/datum/gas_mixture/removed = tank_air.remove(transfer_moles) + cabin_air.merge(removed) + else if(pressure_delta < 0) //cabin pressure higher than release pressure + var/datum/gas_mixture/t_air = V.get_turf_air() + pressure_delta = cabin_pressure - release_pressure + if(t_air) + pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta) + if(pressure_delta > 0) //if location pressure is lower than cabin pressure + transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles) + if(t_air) + t_air.merge(removed) + else //just delete the cabin gas, we're in space or some shit + del(removed) + else + return stop() + return + + +//######################################### Atmospherics for vehicles ############################################# + + +/obj/vehicle/proc/get_turf_air() + var/turf/T = get_turf(src) + if(T) + . = T.return_air() + return + +/obj/vehicle/airtight/remove_air(amount) + if(use_internal_tank) + return cabin_air.remove(amount) + else + var/turf/T = get_turf(src) + if(T) + return T.remove_air(amount) + return + +/obj/vehicle/airtight/return_air() + if(use_internal_tank) + return cabin_air + return get_turf_air() + +/obj/vehicle/airtight/proc/return_pressure() + . = 0 + if(use_internal_tank) + . = cabin_air.return_pressure() + else + var/datum/gas_mixture/t_air = get_turf_air() + if(t_air) + . = t_air.return_pressure() + return + + +/obj/vehicle/airtight/proc/return_temperature() + . = 0 + if(use_internal_tank) + . = cabin_air.return_temperature() + else + var/datum/gas_mixture/t_air = get_turf_air() + if(t_air) + . = t_air.return_temperature() + return + +/obj/vehicle/airtight/proc/connect(obj/machinery/atmospherics/portables_connector/new_port) + //Make sure not already connected to something else + if(connected_port || !new_port || new_port.connected_device) + return 0 + + //Make sure are close enough for a valid connection + if(new_port.loc != src.loc) + return 0 + + //Perform the connection + connected_port = new_port + connected_port.connected_device = src + + //Actually enforce the air sharing + var/datum/pipe_network/network = connected_port.return_network(src) + if(network && !(internal_tank.return_air() in network.gases)) + network.gases += internal_tank.return_air() + network.update = 1 + log_message("Vehicle airtank connected to external port.") + return 1 + +/obj/vehicle/airtight/proc/disconnect() + if(!connected_port) + return 0 + + var/datum/pipe_network/network = connected_port.return_network(src) + if(network) + network.gases -= internal_tank.return_air() + + connected_port.connected_device = null + connected_port = null + src.log_message("Vehicle airtank disconnected from external port.") + return 1 \ No newline at end of file diff --git a/code/game/vehicles/airtight/land.dm b/code/game/vehicles/airtight/land.dm new file mode 100644 index 0000000000..e69de29bb2 diff --git a/code/game/vehicles/airtight/space.dm b/code/game/vehicles/airtight/space.dm new file mode 100644 index 0000000000..e69de29bb2 diff --git a/code/game/vehicles/vehicle.dm b/code/game/vehicles/vehicle.dm new file mode 100644 index 0000000000..87d40b6930 --- /dev/null +++ b/code/game/vehicles/vehicle.dm @@ -0,0 +1,190 @@ + + +/obj/vehicle + name = "Vehicle" + icon = 'vehicles.dmi' + density = 1 + anchored = 1 + unacidable = 1 //To avoid the pilot-deleting shit that came with mechas + layer = MOB_LAYER + //var/can_move = 1 + var/mob/living/carbon/occupant = null + //var/step_in = 10 //make a step in step_in/10 sec. + //var/dir_in = 2//What direction will the mech face when entered/powered on? Defaults to South. + //var/step_energy_drain = 10 + var/health = 300 //health is health + //var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. + //the values in this list show how much damage will pass through, not how much will be absorbed. + var/list/damage_absorption = list("brute"=0.8,"fire"=1.2,"bullet"=0.9,"laser"=1,"energy"=1,"bomb"=1) + var/obj/item/weapon/cell/cell //Our power source + var/state = 0 + var/list/log = new + var/last_message = 0 + var/add_req_access = 1 + var/maint_access = 1 + //var/dna //dna-locking the mech + var/list/proc_res = list() //stores proc owners, like proc_res["functionname"] = owner reference + var/datum/effect/effect/system/spark_spread/spark_system = new + var/lights = 0 + var/lights_power = 6 + + //inner atmos //These go in airtight.dm, not all vehicles are space-faring -Agouri + //var/use_internal_tank = 0 + //var/internal_tank_valve = ONE_ATMOSPHERE + //var/obj/machinery/portable_atmospherics/canister/internal_tank + //var/datum/gas_mixture/cabin_air + //var/obj/machinery/atmospherics/portables_connector/connected_port = null + + var/obj/item/device/radio/radio = null + + var/max_temperature = 2500 + //var/internal_damage_threshold = 50 //health percentage below which internal damage is possible + var/internal_damage = 0 //contains bitflags + + var/list/operation_req_access = list()//required access level for mecha operation + var/list/internals_req_access = list(access_engine,access_robotics)//required access level to open cell compartment + + //var/datum/global_iterator/pr_int_temp_processor //normalizes internal air mixture temperature //In airtight.dm you go -Agouri + var/datum/global_iterator/pr_inertial_movement //controls intertial movement in spesss + + //var/datum/global_iterator/pr_give_air //moves air from tank to cabin //Y-you too -Agouri + + var/datum/global_iterator/pr_internal_damage //processes internal damage + + + var/wreckage + + var/list/equipment = new + var/obj/selected + //var/max_equip = 3 + + var/datum/events/events + + + +/obj/vehicle/New() + ..() + events = new + icon_state += "-unmanned" + add_radio() + //add_cabin() //No cabin for non-airtights + + spark_system.set_up(2, 0, src) + spark_system.attach(src) + add_cell() + add_iterators() + removeVerb(/obj/mecha/verb/disconnect_from_port) + removeVerb(/atom/movable/verb/pull) + log_message("[src.name]'s functions initialised. Work protocols active - Entering IDLE mode.") + loc.Entered(src) + return + + +//################ Helpers ########################################################### + + +/obj/vehicle/proc/removeVerb(verb_path) + verbs -= verb_path + +/obj/vehicle/proc/addVerb(verb_path) + verbs += verb_path + +/*/obj/vehicle/proc/add_airtank() //In airtight.dm -Agouri + internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src) + return internal_tank*/ + +/obj/vehicle/proc/add_cell(var/obj/item/weapon/cell/C=null) + if(C) + C.forceMove(src) + cell = C + return + cell = new(src) + cell.charge = 15000 + cell.maxcharge = 15000 + +/*/obj/vehicle/proc/add_cabin() //In airtight.dm -Agouri + cabin_air = new + cabin_air.temperature = T20C + cabin_air.volume = 200 + cabin_air.oxygen = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + cabin_air.nitrogen = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + return cabin_air*/ + +/obj/vehicle/proc/add_radio() + radio = new(src) + radio.name = "[src] radio" + radio.icon = icon + radio.icon_state = icon_state + radio.subspace_transmission = 1 + +/obj/vehicle/proc/add_iterators() + pr_inertial_movement = new /datum/global_iterator/vehicle_intertial_movement(null,0) + //pr_internal_damage = new /datum/global_iterator/vehicle_internal_damage(list(src),0) + //pr_int_temp_processor = new /datum/global_iterator/vehicle_preserve_temp(list(src)) //In airtight.dm's add_airtight_iterators -Agouri + //pr_give_air = new /datum/global_iterator/vehicle_tank_give_air(list(src) //Same here -Agouri + +/obj/vehicle/proc/check_for_support() + if(locate(/obj/structure/grille, orange(1, src)) || locate(/obj/structure/lattice, orange(1, src)) || locate(/turf/simulated, orange(1, src)) || locate(/turf/unsimulated, orange(1, src))) + return 1 + else + return 0 + +//################ Logs and messages ############################################ + + +/obj/vehicle/proc/log_message(message as text,red=null) + log.len++ + log[log.len] = list("time"=world.timeofday,"message"="[red?"":null][message][red?"":null]") + return log.len + + + +//################ Global Iterator Datums ###################################### + + +/datum/global_iterator/vehicle_intertial_movement //inertial movement in space + delay = 7 + + process(var/obj/vehicle/V as obj, direction) + if(direction) + if(!step(V, direction)||V.check_for_support()) + src.stop() + else + src.stop() + return + + +/datum/global_iterator/mecha_internal_damage // processing internal damage + + process(var/obj/mecha/mecha) + if(!mecha.hasInternalDamage()) + return stop() + if(mecha.hasInternalDamage(MECHA_INT_FIRE)) + if(!mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL) && prob(5)) + mecha.clearInternalDamage(MECHA_INT_FIRE) + if(mecha.internal_tank) + if(mecha.internal_tank.return_pressure()>mecha.internal_tank.maximum_pressure && !(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH))) + mecha.setInternalDamage(MECHA_INT_TANK_BREACH) + var/datum/gas_mixture/int_tank_air = mecha.internal_tank.return_air() + if(int_tank_air && int_tank_air.return_volume()>0) //heat the air_contents + int_tank_air.temperature = min(6000+T0C, int_tank_air.temperature+rand(10,15)) + if(mecha.cabin_air && mecha.cabin_air.return_volume()>0) + mecha.cabin_air.temperature = min(6000+T0C, mecha.cabin_air.return_temperature()+rand(10,15)) + if(mecha.cabin_air.return_temperature()>mecha.max_temperature/2) + mecha.take_damage(4/round(mecha.max_temperature/mecha.cabin_air.return_temperature(),0.1),"fire") + if(mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL)) //stop the mecha_preserve_temp loop datum + mecha.pr_int_temp_processor.stop() + if(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH)) //remove some air from internal tank + if(mecha.internal_tank) + var/datum/gas_mixture/int_tank_air = mecha.internal_tank.return_air() + var/datum/gas_mixture/leaked_gas = int_tank_air.remove_ratio(0.10) + if(mecha.loc && hascall(mecha.loc,"assume_air")) + mecha.loc.assume_air(leaked_gas) + else + del(leaked_gas) + if(mecha.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) + if(mecha.get_charge()) + mecha.spark_system.start() + mecha.cell.charge -= min(20,mecha.cell.charge) + mecha.cell.maxcharge -= min(20,mecha.cell.maxcharge) + return \ No newline at end of file diff --git a/code/modules/DetectiveWork/detective_work.dm b/code/modules/DetectiveWork/detective_work.dm index 70a7b60401..b0bd660453 100644 --- a/code/modules/DetectiveWork/detective_work.dm +++ b/code/modules/DetectiveWork/detective_work.dm @@ -4,14 +4,12 @@ atom/var/list/suit_fibers atom/proc/add_fibers(mob/living/carbon/human/M) if(M.gloves) - if(M.gloves.transfer_blood) - if(add_blood(M.gloves.bloody_hands_mob)) + if(M.gloves.transfer_blood) //bloodied gloves transfer blood to touched objects + if(add_blood(M.gloves.bloody_hands_mob)) //only reduces the bloodiness of our gloves if the item wasn't already bloody M.gloves.transfer_blood-- - //world.log << "[M.gloves] added blood to [src] from [M.gloves.bloody_hands_mob]" else if(M.bloody_hands) if(add_blood(M.bloody_hands_mob)) M.bloody_hands-- - //world.log << "[M] added blood to [src] from [M.bloody_hands_mob]" if(!suit_fibers) suit_fibers = list() var/fibertext var/item_multiplier = istype(src,/obj/item)?1.2:1 @@ -190,6 +188,8 @@ obj/machinery/computer/forensic_scanning I = card if(I && istype(I,/obj/item/weapon/f_card)) card = I + if(!card.fingerprints) + card.fingerprints = list() if(card.amount > 1 || !card.fingerprints.len) usr << "\red ERROR: No prints/too many cards." if(card.loc == src) @@ -468,9 +468,10 @@ obj/machinery/computer/forensic_scanning proc/add_data_scanner(var/obj/item/device/detective_scanner/W) - for(var/i = 1, i <= W.stored.len, i++) - var/list/data = W.stored[i] - add_data(data[1],1,data[2],data[3],data[4]) + if(W.stored) + for(var/i = 1, i <= W.stored.len, i++) + var/list/data = W.stored[i] + add_data(data[1],1,data[2],data[3],data[4]) W.stored = list() for(var/atom/A in W.contents) del(A) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 5bcfd46628..71811b312d 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -12,9 +12,9 @@ var/global/BSACooldown = 0 else M << rendered + /obj/admins/Topic(href, href_list) ..() - if (usr.client != src.owner) world << "\blue [usr.key] has attempted to override the admin panel!" log_admin("[key_name(usr)] tried to use the admin panel without authorization.") @@ -31,7 +31,7 @@ var/global/BSACooldown = 0 if ((!( ticker ) || emergency_shuttle.location)) return emergency_shuttle.incall() - world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes." + captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.") log_admin("[key_name(usr)] called the Emergency Shuttle") message_admins("\blue [key_name_admin(usr)] called the Emergency Shuttle to the station", 1) @@ -41,12 +41,11 @@ var/global/BSACooldown = 0 switch(emergency_shuttle.direction) if(-1) emergency_shuttle.incall() - world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes." + captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.") log_admin("[key_name(usr)] called the Emergency Shuttle") message_admins("\blue [key_name_admin(usr)] called the Emergency Shuttle to the station", 1) if(1) emergency_shuttle.recall() - world << "\blue Alert: The shuttle is going back!" log_admin("[key_name(usr)] sent the Emergency Shuttle back") message_admins("\blue [key_name_admin(usr)] sent the Emergency Shuttle back", 1) @@ -59,6 +58,7 @@ var/global/BSACooldown = 0 if (src.rank in list("Badmin", "Game Admin", "Game Master")) emergency_shuttle.settimeleft( input("Enter new shuttle duration (seconds):","Edit Shuttle Timeleft", emergency_shuttle.timeleft() ) as num ) log_admin("[key_name(usr)] edited the Emergency Shuttle's timeleft to [emergency_shuttle.timeleft()]") + captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.") message_admins("\blue [key_name_admin(usr)] edited the Emergency Shuttle's timeleft to [emergency_shuttle.timeleft()]", 1) href_list["secretsadmin"] = "check_antagonist" else @@ -196,82 +196,370 @@ var/global/BSACooldown = 0 if(href_list["jobban2"]) var/mob/M = locate(href_list["jobban2"]) - var/dat = "" - var/header = "Pick Job to ban this guy from.
" - var/body - var/jobs = "" + if(!M) //sanity + alert("Mob no longer exists!") + return + if(!M.ckey) //sanity + alert("Mob has no ckey") + return if(!job_master) usr << "Job Master has not been setup!" return - for(var/datum/job/job in job_master.occupations) - if(job.title == "Tourist") - continue + var/dat = "" + var/header = "Job-Ban Panel: [M.name]" + var/body + var/jobs = "" + + /***********************************WARNING!************************************ + The jobban stuff looks mangled and disgusting + But it looks beautiful in-game + -Nodrak + ************************************WARNING!***********************************/ + var/counter = 0 +//Regular jobs + //Command (Blue) + jobs += "" + jobs += "" + for(var/jobPos in command_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + if(jobban_isbanned(M, job.title)) - jobs += "[dd_replacetext(job.title, " ", " ")] " + jobs += "" + counter++ else - jobs += "[dd_replacetext(job.title, " ", " ")] " + jobs += "" + counter++ -/* if(jobban_isbanned(M, "Captain")) These two are now jobs in the datums and should show up in the above code - jobs += "Captain " - else - jobs += "Captain " + if(counter >= 6) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Command Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" - if(jobban_isbanned(M, "AI")) - jobs += "AI " - else - jobs += "AI " -*/ - if(jobban_isbanned(M, "Syndicate")) - jobs += "
[dd_replacetext("Syndicate", " ", " ")] " - else - jobs += "
[dd_replacetext("Syndicate", " ", " ")] " + //Security (Red) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in security_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue - if(jobban_isbanned(M, "Emergency Response Team")) - jobs += "
[dd_replacetext("Emergency Response Team", " ", " ")] " - else - jobs += "
[dd_replacetext("Emergency Response Team", " ", " ")] " + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Security Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" + //Engineering (Yellow) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in engineering_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Engineering Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" + + //Medical (White) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in medical_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Medical Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" + + //Science (Purple) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in science_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Science Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" + + //Civilian (Grey) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in civilian_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Civilian Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" + + //Non-Human (Green) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in nonhuman_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + + //pAI isn't technically a job, but it goes in here. if(jobban_isbanned(M, "pAI")) - jobs += "
pAI " + jobs += "" else - jobs += "
pAI " + jobs += "" - body = "
[jobs]

" + jobs += "
Non-human Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
pAIpAI
" + + //Antagonist (Orange) + var/isbanned_dept = jobban_isbanned(M, "Syndicate") + jobs += "" + jobs += "" + + //Traitor + if(jobban_isbanned(M, "traitor") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Changeling + if(jobban_isbanned(M, "changeling") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Nuke Operative + if(jobban_isbanned(M, "operative") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Revolutionary + if(jobban_isbanned(M, "revolutionary") || isbanned_dept) + jobs += "" + else + jobs += "" + + jobs += "" //Breaking it up so it fits nicer on the screen every 5 entries + + //Cultist + if(jobban_isbanned(M, "cultist") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Wizard + if(jobban_isbanned(M, "wizard") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Emergency Response Team + if(jobban_isbanned(M, "Emergency Response Team" || isbanned_dept)) + jobs += "" + else + jobs += "" + + +/* //Malfunctioning AI //Removed Malf-bans because they're a pain to impliment + if(jobban_isbanned(M, "malf AI") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Alien + if(jobban_isbanned(M, "alien candidate") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Infested Monkey + if(jobban_isbanned(M, "infested monkey") || isbanned_dept) + jobs += "" + else + jobs += "" +*/ + jobs += "
Antagonist Positions
[dd_replacetext("Traitor", " ", " ")][dd_replacetext("Traitor", " ", " ")][dd_replacetext("Changeling", " ", " ")][dd_replacetext("Changeling", " ", " ")][dd_replacetext("Nuke Operative", " ", " ")][dd_replacetext("Nuke Operative", " ", " ")][dd_replacetext("Revolutionary", " ", " ")][dd_replacetext("Revolutionary", " ", " ")]
[dd_replacetext("Cultist", " ", " ")][dd_replacetext("Cultist", " ", " ")][dd_replacetext("Wizard", " ", " ")][dd_replacetext("Wizard", " ", " ")][dd_replacetext("Emergency Response Team", " ", " ")][dd_replacetext("Emergency Response Team", " ", " ")][dd_replacetext("Malf AI", " ", " ")][dd_replacetext("Malf AI", " ", " ")][dd_replacetext("Alien", " ", " ")][dd_replacetext("Alien", " ", " ")][dd_replacetext("Infested Monkey", " ", " ")][dd_replacetext("Infested Monkey", " ", " ")]
" + + body = "[jobs]" dat = "[header][body]" - usr << browse(dat, "window=jobban2;size=600x180") + usr << browse(dat, "window=jobban2;size=800x450") return + //JOBBAN'S INNARDS if(href_list["jobban3"]) if (src.rank in list( "Admin Candidate", "Temporary Admin", "Trial Admin", "Badmin", "Game Admin", "Game Master" )) var/mob/M = locate(href_list["jobban4"]) - var/job = href_list["jobban3"] + if(!M) + alert("Mob no longer exists!") + return if ((M.client && M.client.holder && (M.client.holder.level > src.level))) alert("You cannot perform this action. You must be of a higher administrative rank!") return - if (jobban_isbanned(M, job)) - log_admin("[key_name(usr)] unbanned [key_name(M)] from [job]") - ban_unban_log_save("[key_name(usr)] unjobbanned [key_name(M)] from [job]") - M << "\redYou have been un-jobbanned by [usr.client.ckey] from [job]." - //feedback_inc("ban_job_unban",1) - message_admins("\blue [key_name_admin(usr)] unbanned [key_name_admin(M)] from [job]", 1) - jobban_unban(M, job) - href_list["jobban2"] = 1 - else - var/reason = input(usr,"Reason?","reason","griefer") as text|null - if(!reason) - return - ban_unban_log_save("[key_name(usr)] jobbanned [key_name(M)] from [job]. reason: [reason]") - log_admin("[key_name(usr)] banned [key_name(M)] from [job]") - //feedback_inc("ban_job",1) - M << "\redYou have been jobbanned by [usr.client.ckey] from [job]." - M << "\red The reason is: [reason]" - M << "\red Jobban can be lifted only on demand." - message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [job]", 1) - jobban_fullban(M, job, reason) - href_list["jobban2"] = 1 // lets it fall through and refresh - if(config.appeal_address) - M << "\red You may try to appeal this at [config.appeal_address]" + if(!job_master) + usr << "Job Master has not been setup!" + return + + //get jobs for department if specified, otherwise just returnt he one job in a list. + var/list/joblist = list() + switch(href_list["jobban3"]) + if("commanddept") + for(var/jobPos in command_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("securitydept") + for(var/jobPos in security_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("engineeringdept") + for(var/jobPos in engineering_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("medicaldept") + for(var/jobPos in medical_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("sciencedept") + for(var/jobPos in science_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("civiliandept") + for(var/jobPos in civilian_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("nonhumandept") + joblist += "pAI" + for(var/jobPos in nonhuman_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + else + joblist += href_list["jobban3"] + + //Create a list of unbanned jobs within joblist + var/list/notbannedlist = list() + for(var/job in joblist) + if(!jobban_isbanned(M, job)) + notbannedlist += job + + //Banning comes first + if(notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban. + var/reason = input(usr,"Reason?","Please State Reason","") as text|null + if(reason) + var/msg + for(var/job in notbannedlist) + ban_unban_log_save("[key_name(usr)] jobbanned [key_name(M)] from [job]. reason: [reason]") + log_admin("[key_name(usr)] banned [key_name(M)] from [job]") + feedback_inc("ban_job",1) + feedback_add_details("ban_job","- [job]") + jobban_fullban(M, job, "[reason]; By [usr.ckey] on [time2text(world.realtime)]") + if(!msg) msg = job + else msg += ", [job]" + message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [msg]", 1) + M << "\redYou have been jobbanned by [usr.client.ckey] from: [msg]." + M << "\red The reason is: [reason]" + M << "\red Jobban can be lifted only upon request." + if(config.appeal_address) + M << "\red You may try to appeal this at [config.appeal_address]" + href_list["jobban2"] = 1 // lets it fall through and refresh + return 1 + + //Unbanning joblist + //all jobs in joblist are banned already OR we didn't give a reason (implying they shouldn't be banned) + if(joblist.len) //at least 1 banned job exists in joblist so we have stuff to unban. + var/msg + for(var/job in joblist) + var/reason = jobban_isbanned(M, job) + if(!reason) continue //skip if it isn't jobbanned anyway + switch(alert("Job: '[job]' Reason: '[reason]' Un-jobban?","Please Confirm","Yes","No")) + if("Yes") + ban_unban_log_save("[key_name(usr)] unjobbanned [key_name(M)] from [job]") + log_admin("[key_name(usr)] unbanned [key_name(M)] from [job]") + feedback_inc("ban_job_unban",1) + feedback_add_details("ban_job_unban","- [job]") + jobban_unban(M, job) + if(!msg) msg = job + else msg += ", [job]" + else + continue + if(msg) + message_admins("\blue [key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg]", 1) + M << "\redYou have been un-jobbanned by [usr.client.ckey] from [msg]." + href_list["jobban2"] = 1 // lets it fall through and refresh + return 1 + return 0 //we didn't do anything! if (href_list["boot2"]) if ((src.rank in list( "Moderator", "Temporary Admin", "Admin Candidate", "Trial Admin", "Badmin", "Game Admin", "Game Master" ))) @@ -803,6 +1091,21 @@ var/global/BSACooldown = 0 alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) return + if (href_list["makeaisilent"]) + if (src.level>=3) + var/mob/M = locate(href_list["makeaisilent"]) + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + message_admins("\red Admin [key_name_admin(usr)] AIized [key_name_admin(M)] silently!", 1) + log_admin("[key_name(usr)] AIized [key_name(M)] silently") + H.AIizeSilent() + else + alert("I cannot allow this.") + return + else + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return + if (href_list["makealien"]) if (src.level>=3) var/mob/M = locate(href_list["makealien"]) @@ -1069,11 +1372,19 @@ var/global/BSACooldown = 0 else alert("You are not a high enough administrator! Sorry!!!!") + if (href_list["quick_create_object"]) + if (src.rank in list("Admin Candidate", "Trial Admin", "Badmin", "Game Admin", "Game Master")) + return quick_create_object(usr) + else + alert("You are not a high enough administrator! Sorry!!!!") + + if (href_list["create_turf"]) if (src.rank in list("Admin Candidate", "Trial Admin", "Badmin", "Game Admin", "Game Master")) return create_turf(usr) else alert("You are not a high enough administrator! Sorry!!!!") + if (href_list["create_mob"]) if (src.rank in list("Badmin", "Game Admin", "Game Master")) return create_mob(usr) @@ -2057,6 +2368,7 @@ var/global/BSACooldown = 0 foo += text("Is an AI | ") else if(ishuman(M)) foo += text("Make AI | ") + foo += text("Make AI Silently | ") foo += text("Make Robot | ") foo += text("Make Alien | ") foo += text("Make Metroid | ") @@ -2215,6 +2527,7 @@ var/global/BSACooldown = 0 if(lvl >= 3 ) dat += "Create Object
" + dat += "Quick Create Object
" dat += "Create Turf
" if(lvl >= 5) dat += "Create Mob
" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index c330f57451..ae551810a0 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -50,13 +50,9 @@ if ("Trial Admin") holder.level = 3 if(holder.state == 2) // if observing - // Debug verbs += /client/proc/debug_variables verbs += /client/proc/cmd_modify_ticker_variables - verbs += /client/proc/toggleadminhelpsound - // Admin helpers verbs += /client/proc/toggle_view_range - // Admin game intrusion verbs += /client/proc/Getmob verbs += /client/proc/Getkey verbs += /client/proc/sendmob @@ -65,6 +61,7 @@ verbs += /client/proc/jumptomob verbs += /client/proc/jumptoturf verbs += /client/proc/jumptocoord + verbs += /client/proc/cmd_admin_delete verbs += /client/proc/cmd_admin_add_freeform_ai_law verbs += /client/proc/cmd_admin_rejuvenate verbs += /client/proc/cmd_admin_drop_everything @@ -74,12 +71,9 @@ holder.level = 2 if(holder.state == 2) // if observing deadchat = 1 - // Settings verbs += /obj/admins/proc/toggleaban //abandon mob verbs += /client/proc/deadchat //toggles deadchat - // Admin helpers verbs += /client/proc/cmd_admin_check_contents - // Admin game intrusion verbs += /client/proc/Jump verbs += /client/proc/jumptokey verbs += /client/proc/jumptomob @@ -121,6 +115,8 @@ //Moderator if (holder.level >= 0) + verbs += /obj/admins/proc/announce + verbs += /obj/admins/proc/startnow verbs += /obj/admins/proc/toggleAI //Toggle the AI verbs += /obj/admins/proc/toggleenter //Toggle enterting // verbs += /obj/admins/proc/toggleguests //Toggle guests entering @@ -136,8 +132,6 @@ verbs += /client/proc/cmd_admin_pm_panel verbs += /client/proc/cmd_admin_subtle_message verbs += /client/proc/warn - verbs += /obj/admins/proc/announce - verbs += /obj/admins/proc/startnow verbs += /client/proc/dsay verbs += /client/proc/admin_play verbs += /client/proc/admin_observe @@ -185,6 +179,8 @@ deadchat = 1 seeprayers = 1 + verbs += /obj/admins/proc/view_txt_log + verbs += /obj/admins/proc/view_atk_log verbs += /obj/admins/proc/toggleaban //abandon mob verbs += /obj/admins/proc/show_traitor_panel verbs += /client/proc/cmd_admin_remove_plasma @@ -195,6 +191,8 @@ verbs += /client/proc/spawn_xeno verbs += /client/proc/toggleprayers verbs += /client/proc/deadmin_self + verbs += /client/proc/tension_report + verbs += /client/proc/toggleadminhelpsound verbs += /proc/possess verbs += /proc/release verbs += /client/proc/admin_deny_shuttle @@ -229,15 +227,12 @@ //verbs += /proc/togglebuildmode --Merged with view variables //verbs += /client/proc/cmd_modify_object_variables --Merged with view variables verbs += /client/proc/togglebuildmodeself - verbs += /client/proc/tension_report - verbs += /client/proc/toggleadminhelpsound + else return //Game Admin if (holder.level >= 5) verbs += /obj/admins/proc/spawn_atom - verbs += /obj/admins/proc/view_txt_log - verbs += /obj/admins/proc/view_atk_log verbs += /client/proc/cmd_admin_list_open_jobs verbs += /client/proc/cmd_admin_direct_narrate verbs += /client/proc/colorooc @@ -249,6 +244,7 @@ verbs += /client/proc/check_words verbs += /client/proc/drop_bomb verbs += /client/proc/cmd_admin_grantfullaccess + verbs += /client/proc/kill_airgroup verbs += /client/proc/cmd_admin_drop_everything verbs += /client/proc/make_sound verbs += /client/proc/play_local_sound @@ -265,6 +261,7 @@ //verbs += /client/proc/cmd_admin_emp --Merged with view variables //verbs += /client/proc/give_spell --Merged with view variables //verbs += /client/proc/cmd_admin_ninjafy --Merged with view variables + //verbs += /client/proc/cmd_switch_radio --removed as tcommsat is staying // Moved over from tg's Game Master: verbs += /obj/admins/proc/toggle_aliens //toggle aliens verbs += /obj/admins/proc/toggle_space_ninja //toggle ninjas @@ -386,7 +383,8 @@ verbs -= /client/proc/cmd_admin_create_centcom_report verbs -= /client/proc/deadchat //toggles deadchat verbs -= /client/proc/cmd_admin_mute - verbs -= /client/proc/cmd_admin_pm + verbs -= /client/proc/cmd_admin_pm_context + verbs -= /client/proc/cmd_admin_pm_panel verbs -= /client/proc/cmd_admin_say verbs -= /client/proc/cmd_admin_subtle_message verbs -= /client/proc/warn @@ -446,6 +444,7 @@ //verbs -= /obj/admins/proc/unprison --Merged with player panel //verbs -= /client/proc/cmd_switch_radio --removed because tcommsat is staying verbs -= /client/proc/togglebuildmodeself + verbs -= /client/proc/kill_airgroup verbs -= /client/proc/admin_deny_shuttle verbs -= /client/proc/cmd_admin_christmas verbs -= /client/proc/editappear diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm index d9cdc9be65..cd6ef81420 100644 --- a/code/modules/admin/banjob.dm +++ b/code/modules/admin/banjob.dm @@ -3,7 +3,7 @@ var jobban_keylist[0] //to store the keys & ranks /proc/jobban_fullban(mob/M, rank, reason) - if (!M || !M.key || !M.client) return + if (!M || !M.key) return jobban_keylist.Add(text("[M.ckey] - [rank] ## [reason]")) jobban_savebanfile() @@ -12,19 +12,25 @@ var jobban_keylist.Add(text("[ckey] - [rank]")) jobban_savebanfile() +//returns a reason if M is banned from rank, returns 0 otherwise /proc/jobban_isbanned(mob/M, rank) - if(_jobban_isbanned(M, rank)) return 1//for old jobban - if(M) + if(M && rank) + if(_jobban_isbanned(M, rank)) return "Reason Unspecified" //for old jobban if (guest_jobbans(rank)) if(config.guest_jobban && IsGuestKey(M.key)) - return 1 + return "Guest Job-ban" if(config.usewhitelist && !check_whitelist(M)) - return 1 + return "Whitelisted Job" for (var/s in jobban_keylist) if( findtext(s,"[M.ckey] - [rank]") ) - return 1 - return 0 + var/startpos = findtext(s, "## ")+3 + if(startpos && startposCreate Object", "Create Mob") create_mob_html = dd_replacetext(create_mob_html, "null /* object types */", "\"[mobjs]\"") user << browse(dd_replacetext(create_mob_html, "/* ref src */", "\ref[src]"), "window=create_mob;size=425x475") diff --git a/code/modules/admin/create_object.dm b/code/modules/admin/create_object.dm index 944ab89c7a..248eebb5ab 100644 --- a/code/modules/admin/create_object.dm +++ b/code/modules/admin/create_object.dm @@ -1,4 +1,5 @@ /var/create_object_html = null + /obj/admins/proc/create_object(var/mob/user) if (!create_object_html) var/objectjs = null @@ -7,3 +8,21 @@ create_object_html = dd_replacetext(create_object_html, "null /* object types */", "\"[objectjs]\"") user << browse(dd_replacetext(create_object_html, "/* ref src */", "\ref[src]"), "window=create_object;size=425x475") + + +/obj/admins/proc/quick_create_object(var/mob/user) + + var/quick_create_object_html = null + var/pathtext = null + + pathtext = input("Select the path of the object you wish to create.", "Path", "/obj") in list("/obj","/obj/structure","/obj/item","/obj/machinery") + + var path = text2path(pathtext) + + if (!quick_create_object_html) + var/objectjs = null + objectjs = dd_list2text(typesof(path), ";") + quick_create_object_html = file2text('create_object.html') + quick_create_object_html = dd_replacetext(quick_create_object_html, "null /* object types */", "\"[objectjs]\"") + + user << browse(dd_replacetext(quick_create_object_html, "/* ref src */", "\ref[src]"), "window=quick_create_object;size=425x475") \ No newline at end of file diff --git a/code/modules/admin/create_turf.dm b/code/modules/admin/create_turf.dm index be5fdd1e0b..6ae15354e5 100644 --- a/code/modules/admin/create_turf.dm +++ b/code/modules/admin/create_turf.dm @@ -4,6 +4,7 @@ var/turfjs = null turfjs = dd_list2text(typesof(/turf), ";") create_turf_html = file2text('create_object.html') + create_turf_html = dd_replacetext(create_turf_html, "Create Object", "Create Turf") create_turf_html = dd_replacetext(create_turf_html, "null /* object types */", "\"[turfjs]\"") user << browse(dd_replacetext(create_turf_html, "/* ref src */", "\ref[src]"), "window=create_turf;size=425x475") diff --git a/code/modules/admin/new/admin.dm b/code/modules/admin/new/admin.dm new file mode 100644 index 0000000000..3a31687261 --- /dev/null +++ b/code/modules/admin/new/admin.dm @@ -0,0 +1,3048 @@ + +var/global/BSACooldown = 0 + + +//////////////////////////////// +/proc/message_admins(var/text, var/admin_ref = 0) + var/rendered = "ADMIN LOG: [text]" + log_adminwarn(rendered) + for (var/mob/M in world) + if (M && M.client && M.client.holder && M.client.authenticated) + if (admin_ref) + M << dd_replaceText(rendered, "%admin_ref%", "\ref[M]") + else + M << rendered + + +/obj/admins/Topic(href, href_list) + ..() + if (usr.client != src.owner) + world << "\blue [usr.key] has attempted to override the admin panel!" + log_admin("[key_name(usr)] tried to use the admin panel without authorization.") + return + + if(href_list["call_shuttle"]) + if (src.rank in list("Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + if( ticker.mode.name == "blob" ) + alert("You can't call the shuttle during blob!") + return + switch(href_list["call_shuttle"]) + if("1") + if ((!( ticker ) || emergency_shuttle.location)) + return + emergency_shuttle.incall() + captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.") + log_admin("[key_name(usr)] called the Emergency Shuttle") + message_admins("\blue [key_name_admin(usr)] called the Emergency Shuttle to the station", 1) + + if("2") + if ((!( ticker ) || emergency_shuttle.location || emergency_shuttle.direction == 0)) + return + switch(emergency_shuttle.direction) + if(-1) + emergency_shuttle.incall() + captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.") + log_admin("[key_name(usr)] called the Emergency Shuttle") + message_admins("\blue [key_name_admin(usr)] called the Emergency Shuttle to the station", 1) + if(1) + emergency_shuttle.recall() + log_admin("[key_name(usr)] sent the Emergency Shuttle back") + message_admins("\blue [key_name_admin(usr)] sent the Emergency Shuttle back", 1) + + href_list["secretsadmin"] = "check_antagonist" + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + + if(href_list["edit_shuttle_time"]) + if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + emergency_shuttle.settimeleft( input("Enter new shuttle duration (seconds):","Edit Shuttle Timeleft", emergency_shuttle.timeleft() ) as num ) + log_admin("[key_name(usr)] edited the Emergency Shuttle's timeleft to [emergency_shuttle.timeleft()]") + captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.") + message_admins("\blue [key_name_admin(usr)] edited the Emergency Shuttle's timeleft to [emergency_shuttle.timeleft()]", 1) + href_list["secretsadmin"] = "check_antagonist" + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + + /////////////////////////////////////new ban stuff + if(href_list["unbanf"]) + var/banfolder = href_list["unbanf"] + Banlist.cd = "/base/[banfolder]" + var/key = Banlist["key"] + if(alert(usr, "Are you sure you want to unban [key]?", "Confirmation", "Yes", "No") == "Yes") + if (RemoveBan(banfolder)) + unbanpanel() + else + alert(usr,"This ban has already been lifted / does not exist.","Error","Ok") + unbanpanel() + + if(href_list["unbane"]) + UpdateTime() + var/reason + var/mins = 0 + var/banfolder = href_list["unbane"] + Banlist.cd = "/base/[banfolder]" + var/reason2 = Banlist["reason"] + var/temp = Banlist["temp"] + var/minutes = (Banlist["minutes"] - CMinutes) + if(!minutes || minutes < 0) minutes = 0 + var/banned_key = Banlist["key"] + Banlist.cd = "/base" + + switch(alert("Temporary Ban?",,"Yes","No")) + if("Yes") + temp = 1 + mins = input(usr,"How long (in minutes)? (Default: 1440)","Ban time",minutes ? minutes : 1440) as num + if(!mins) + return + if(mins >= 525600) mins = 525599 + reason = input(usr,"Reason?","reason",reason2) as text + if(!reason) + return + if("No") + temp = 0 + reason = input(usr,"Reason?","reason",reason2) as text + if(!reason) + return + + log_admin("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [GetExp(mins)]") + + ban_unban_log_save("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [GetExp(mins)]") + message_admins("\blue [key_name_admin(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [GetExp(mins)]", 1) + Banlist.cd = "/base/[banfolder]" + Banlist["reason"] << reason + Banlist["temp"] << temp + Banlist["minutes"] << (mins + CMinutes) + Banlist["bannedby"] << usr.ckey + Banlist.cd = "/base" + feedback_inc("ban_edit",1) + unbanpanel() + + /////////////////////////////////////new ban stuff + + if(href_list["jobban2"]) + var/mob/M = locate(href_list["jobban2"]) + if(!M) //sanity + alert("Mob no longer exists!") + return + if(!M.ckey) //sanity + alert("Mob has no ckey") + return + if(!job_master) + usr << "Job Master has not been setup!" + return + var/dat = "" + var/header = "Job-Ban Panel: [M.name]" + var/body + var/jobs = "" + + /***********************************WARNING!************************************ + The jobban stuff looks mangled and disgusting + But it looks beautiful in-game + -Nodrak + ************************************WARNING!***********************************/ + var/counter = 0 +//Regular jobs + //Command (Blue) + jobs += "" + jobs += "" + for(var/jobPos in command_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 6) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Command Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" + + //Security (Red) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in security_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Security Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" + + //Engineering (Yellow) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in engineering_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Engineering Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" + + //Medical (White) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in medical_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Medical Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" + + //Science (Purple) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in science_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Science Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" + + //Civilian (Grey) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in civilian_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Civilian Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
" + + //Non-Human (Green) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in nonhuman_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + + //pAI isn't technically a job, but it goes in here. + if(jobban_isbanned(M, "pAI")) + jobs += "" + else + jobs += "" + + jobs += "
Non-human Positions
[dd_replacetext(job.title, " ", " ")][dd_replacetext(job.title, " ", " ")]
pAIpAI
" + + //Antagonist (Orange) + var/isbanned_dept = jobban_isbanned(M, "Syndicate") + jobs += "" + jobs += "" + + //Traitor + if(jobban_isbanned(M, "traitor") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Changeling + if(jobban_isbanned(M, "changeling") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Nuke Operative + if(jobban_isbanned(M, "operative") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Revolutionary + if(jobban_isbanned(M, "revolutionary") || isbanned_dept) + jobs += "" + else + jobs += "" + + jobs += "" //Breaking it up so it fits nicer on the screen every 5 entries + + //Cultist + if(jobban_isbanned(M, "cultist") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Wizard + if(jobban_isbanned(M, "wizard") || isbanned_dept) + jobs += "" + else + jobs += "" + +/* //Malfunctioning AI //Removed Malf-bans because they're a pain to impliment + if(jobban_isbanned(M, "malf AI") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Alien + if(jobban_isbanned(M, "alien candidate") || isbanned_dept) + jobs += "" + else + jobs += "" + + //Infested Monkey + if(jobban_isbanned(M, "infested monkey") || isbanned_dept) + jobs += "" + else + jobs += "" +*/ + jobs += "
Antagonist Positions
[dd_replacetext("Traitor", " ", " ")][dd_replacetext("Traitor", " ", " ")][dd_replacetext("Changeling", " ", " ")][dd_replacetext("Changeling", " ", " ")][dd_replacetext("Nuke Operative", " ", " ")][dd_replacetext("Nuke Operative", " ", " ")][dd_replacetext("Revolutionary", " ", " ")][dd_replacetext("Revolutionary", " ", " ")]
[dd_replacetext("Cultist", " ", " ")][dd_replacetext("Cultist", " ", " ")][dd_replacetext("Wizard", " ", " ")][dd_replacetext("Wizard", " ", " ")][dd_replacetext("Malf AI", " ", " ")][dd_replacetext("Malf AI", " ", " ")][dd_replacetext("Alien", " ", " ")][dd_replacetext("Alien", " ", " ")][dd_replacetext("Infested Monkey", " ", " ")][dd_replacetext("Infested Monkey", " ", " ")]
" + + body = "[jobs]" + dat = "[header][body]" + usr << browse(dat, "window=jobban2;size=800x450") + return + + //JOBBAN'S INNARDS + if(href_list["jobban3"]) + if (src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )) + var/mob/M = locate(href_list["jobban4"]) + if(!M) + alert("Mob no longer exists!") + return + if ((M.client && M.client.holder && (M.client.holder.level > src.level))) + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + if(!job_master) + usr << "Job Master has not been setup!" + return + + //get jobs for department if specified, otherwise just returnt he one job in a list. + var/list/joblist = list() + switch(href_list["jobban3"]) + if("commanddept") + for(var/jobPos in command_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("securitydept") + for(var/jobPos in security_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("engineeringdept") + for(var/jobPos in engineering_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("medicaldept") + for(var/jobPos in medical_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("sciencedept") + for(var/jobPos in science_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("civiliandept") + for(var/jobPos in civilian_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("nonhumandept") + joblist += "pAI" + for(var/jobPos in nonhuman_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + else + joblist += href_list["jobban3"] + + //Create a list of unbanned jobs within joblist + var/list/notbannedlist = list() + for(var/job in joblist) + if(!jobban_isbanned(M, job)) + notbannedlist += job + + //Banning comes first + if(notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban. + var/reason = input(usr,"Reason?","Please State Reason","") as text|null + if(reason) + var/msg + for(var/job in notbannedlist) + ban_unban_log_save("[key_name(usr)] jobbanned [key_name(M)] from [job]. reason: [reason]") + log_admin("[key_name(usr)] banned [key_name(M)] from [job]") + feedback_inc("ban_job",1) + feedback_add_details("ban_job","- [job]") + jobban_fullban(M, job, reason) + if(!msg) msg = job + else msg += ", [job]" + message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [msg]", 1) + M << "\redYou have been jobbanned by [usr.client.ckey] from: [msg]." + M << "\red The reason is: [reason]" + M << "\red Jobban can be lifted only upon request." + href_list["jobban2"] = 1 // lets it fall through and refresh + return 1 + + //Unbanning joblist + //all jobs in joblist are banned already OR we didn't give a reason (implying they shouldn't be banned) + if(joblist.len) //at least 1 banned job exists in joblist so we have stuff to unban. + var/msg + for(var/job in joblist) + var/reason = jobban_isbanned(M, job) + if(!reason) continue //skip if it isn't jobbanned anyway + switch(alert("Job: '[job]' Reason: '[reason]' Un-jobban?","Please Confirm","Yes","No")) + if("Yes") + ban_unban_log_save("[key_name(usr)] unjobbanned [key_name(M)] from [job]") + log_admin("[key_name(usr)] unbanned [key_name(M)] from [job]") + feedback_inc("ban_job_unban",1) + feedback_add_details("ban_job_unban","- [job]") + jobban_unban(M, job) + if(!msg) msg = job + else msg += ", [job]" + else + continue + if(msg) + message_admins("\blue [key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg]", 1) + M << "\redYou have been un-jobbanned by [usr.client.ckey] from [msg]." + href_list["jobban2"] = 1 // lets it fall through and refresh + return 1 + return 0 //we didn't do anything! + + if (href_list["boot2"]) + if ((src.rank in list( "Moderator", "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["boot2"]) + if (ismob(M)) + if ((M.client && M.client.holder && (M.client.holder.level >= src.level))) + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return + M << "\red You have been kicked from the server" + log_admin("[key_name(usr)] booted [key_name(M)].") + message_admins("\blue [key_name_admin(usr)] booted [key_name_admin(M)].", 1) + //M.client = null + del(M.client) + + if (href_list["removejobban"]) + if ((src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/t = href_list["removejobban"] + if(t) + log_admin("[key_name(usr)] removed [t]") + message_admins("\blue [key_name_admin(usr)] removed [t]", 1) + jobban_remove(t) + href_list["ban"] = 1 // lets it fall through and refresh + + if (href_list["newban"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["newban"]) + if(!ismob(M)) return + if ((M.client && M.client.holder && (M.client.holder.level >= src.level))) + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + switch(alert("Temporary Ban?",,"Yes","No", "Cancel")) + if("Yes") + var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null + if(!mins) + return + if(mins >= 525600) mins = 525599 + var/reason = input(usr,"Reason?","reason","Griefer") as text|null + if(!reason) + return + AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins) + ban_unban_log_save("[usr.client.ckey] has banned [M.ckey]. - Reason: [reason] - This will be removed in [mins] minutes.") + M << "\redYou have been banned by [usr.client.ckey].\nReason: [reason]." + M << "\red This is a temporary ban, it will be removed in [mins] minutes." + feedback_inc("ban_tmp",1) + feedback_inc("ban_tmp_mins",mins) + if(config.banappeals) + M << "\red To try to resolve this matter head to [config.banappeals]" + else + M << "\red No ban appeals URL has been set." + log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.") + message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.") + + del(M.client) + //del(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends. + if("No") + var/reason = input(usr,"Reason?","reason","Griefer") as text|null + if(!reason) + return + AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0) + M << "\redYou have been banned by [usr.client.ckey].\nReason: [reason]." + M << "\red This is a permanent ban." + if(config.banappeals) + M << "\red To try to resolve this matter head to [config.banappeals]" + else + M << "\red No ban appeals URL has been set." + ban_unban_log_save("[usr.client.ckey] has permabanned [M.ckey]. - Reason: [reason] - This is a permanent ban.") + log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.") + message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.") + feedback_inc("ban_perma",1) + + del(M.client) + //del(M) + if("Cancel") + return + if (href_list["newjobban1"]) + var/mob/M = locate(href_list["newjobban1"]) + var/dat = "" + var/header = "Pick Job to ban this guy from.
" + var/body +// var/list/alljobs = get_all_jobs() + var/jobs = "" + jobs += "Heads
" + jobs += "Security
" + jobs += "Engineering
" + jobs += "Research
" + jobs += "Medical

" + + jobs += "CE+Station Engineer
" + jobs += "CE+Atmospheric Tech
" + jobs += "CE+Shaft Miner
" + jobs += "Chemist+RD+CMO
" + jobs += "Geneticist+RD+CMO
" + jobs += "MD+CMO
" + jobs += "Virologist+RD+CMO
" + jobs += "Scientist+RD
" + jobs += "AI+Cyborg
" + jobs += "Detective+HoS

" + for(var/datum/job/job in job_master.occupations) + if(jobban_isbanned(M, job.title)) + jobs += "[dd_replacetext(job.title, " ", " ")] " + else + jobs += "[dd_replacetext(job.title, " ", " ")] " //why doesn't this work the stupid cunt + +/* if(jobban_isbanned(M, "Captain")) + jobs += "Captain " + else + jobs += "Captain " //why doesn't this work the stupid cunt +*/ + if(jobban_isbanned(M, "Syndicate")) + jobs += "
[dd_replacetext("Syndicate", " ", " ")] " + else + jobs += "
[dd_replacetext("Syndicate", " ", " ")] " //why doesn't this work the stupid cunt + + body = "
[jobs]

" + dat = "[header][body]" + usr << browse(dat, "window=jobban2;size=600x250") + return + if(href_list["newjobban2"]) + if ((src.rank in list("Moderator", "Administrator", "Badmin", "Tyrant" ))) + var/mob/M = locate(href_list["jobban4"]) + var/job = href_list["newjobban2"] + if(!ismob(M)) return + //if ((M.client && M.client.holder && (M.client.holder.level >= src.level))) + // alert("You cannot perform this action. You must be of a higher administrative rank!") + // return + switch(alert("Temporary Ban?",,"Yes","No", "Cancel")) + if("Yes") + var/mins = input(usr,"How long (in days)?","Ban time",7) as num + mins = mins * 24 * 60 + if(!mins) + return + if(mins >= 525600) mins = 525599 + var/reason = input(usr,"Reason?","reason","Griefer") as text + if(!reason) + return + if(AddBanjob(M.ckey, M.computer_id, reason, usr.ckey, 1, mins, job)) + M << "\redYou have been jobbanned from [job] by [usr.client.ckey].\nReason: [reason]." + M << "\red This is a temporary ban, it will be removed in [mins] minutes." + if(config.banappeals) + M << "\red To try to resolve this matter head to [config.banappeals]" + else + M << "\red No ban appeals URL has been set." + ban_unban_log_save("[usr.client.ckey] has jobbanned [M.ckey] from [job]. - Reason: [reason] - This will be removed in [mins] minutes.") + feedback_inc("ban_job",1) + feedback_add_details("ban_job","- [job]") + log_admin("[usr.client.ckey] has banned [M.ckey] from [job].\nReason: [reason]\nThis will be removed in [mins] minutes.") + message_admins("\blue[usr.client.ckey] has banned [M.ckey] from [job].\nReason: [reason]\nThis will be removed in [mins] minutes.") + + //del(M.client) + //del(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends. + if("No") + var/reason = input(usr,"Reason?","reason","Griefer") as text + if(!reason) + return + if(AddBanjob(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, job)) + M << "\redYou have been banned from [job] by [usr.client.ckey].\nReason: [reason]." + M << "\red This is a permanent ban." + if(config.banappeals) + M << "\red To try to resolve this matter head to [config.banappeals]" + else + M << "\red No ban appeals URL has been set." + ban_unban_log_save("[usr.client.ckey] has banned [M.ckey] from [job]. - Reason: [reason] - This is a permanent ban.") + feedback_inc("ban_job_tmp",1) + feedback_add_details("ban_job_tmp","- [job]") + log_admin("[usr.client.ckey] has banned [M.ckey] from [job].\nReason: [reason]\nThis is a permanent ban.") + message_admins("\blue[usr.client.ckey] has banned [M.ckey] from [job].\nReason: [reason]\nThis is a permanent ban.") + + //del(M.client) + //del(M) + if("Cancel") + return + + if(href_list["unjobbanf"]) + var/banfolder = href_list["unjobbanf"] + Banlist.cd = "/base/[banfolder]" + var/key = Banlist["key"] + if(alert(usr, "Are you sure you want to unban [key]?", "Confirmation", "Yes", "No") == "Yes") + if (RemoveBanjob(banfolder)) + unjobbanpanel() + else + alert(usr,"This ban has already been lifted / does not exist.","Error","Ok") + unjobbanpanel() + + if(href_list["unjobbane"]) + return +/* + if (href_list["remove"]) + if ((src.rank in list( "Admin Candidate", "Trial Admin", "Badmin", "Game Admin", "Game Master" ))) + var/t = href_list["remove"] + if(t && isgoon(t)) + log_admin("[key_name(usr)] removed [t] from the goonlist.") + message_admins("\blue [key_name_admin(usr)] removed [t] from the goonlist.") + remove_goon(t) +*/ + if (href_list["mute2"]) + if ((src.rank in list( "Moderator", "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["mute2"]) + if (ismob(M)) + if ((M.client && M.client.holder && (M.client.holder.level >= src.level))) + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return + if(!M.client) + src << "This mob doesn't have a client tied to it." + return + M.client.muted = !M.client.muted + log_admin("[key_name(usr)] has [(M.client.muted ? "muted" : "voiced")] [key_name(M)].") + message_admins("\blue [key_name_admin(usr)] has [(M.client.muted ? "muted" : "voiced")] [key_name_admin(M)].", 1) + M << "You have been [(M.client.muted ? "muted" : "voiced")]. Please resolve this in adminhelp." + if (href_list["mute_complete"]) + if ((src.rank in list( "Moderator", "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["mute_complete"]) + if (ismob(M)) + if ((M.client && M.client.holder && (M.client.holder.level >= src.level))) + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return + if(!M.client) + src << "This mob doesn't have a client tied to it." + return + M.client.muted_complete = !M.client.muted_complete + log_admin("[key_name(usr)] has [(M.client.muted_complete ? "completely muted" : "voiced (complete)")] [key_name(M)].") + message_admins("\blue [key_name_admin(usr)] has [(M.client.muted_complete ? "completely muted" : "voiced (complete)")] [key_name_admin(M)].", 1) + M << "You have been [(M.client.muted_complete ? "completely muted" : "voiced (complete)")]. You are unable to speak or even adminhelp" + + if (href_list["c_mode"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + if (ticker && ticker.mode) + return alert(usr, "The game has already started.", null, null, null, null) + var/dat = {"What mode do you wish to play?
"} + for (var/mode in config.modes) + dat += {"[config.mode_names[mode]]
"} + dat += {"Secret
"} + dat += {"Random
"} + dat += {"Now: [master_mode]"} + usr << browse(dat, "window=c_mode") + + if (href_list["f_secret"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + if (ticker && ticker.mode) + return alert(usr, "The game has already started.", null, null, null, null) + if (master_mode != "secret") + return alert(usr, "The game mode has to be secret!", null, null, null, null) + var/dat = {"What game mode do you want to force secret to be? Use this if you want to change the game mode, but want the players to believe it's secret. This will only work if the current game mode is secret.
"} + for (var/mode in config.modes) + dat += {"[config.mode_names[mode]]
"} + dat += {"Random (default)
"} + dat += {"Now: [secret_force_mode]"} + usr << browse(dat, "window=f_secret") + + if (href_list["c_mode2"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + if (ticker && ticker.mode) + return alert(usr, "The game has already started.", null, null, null, null) + master_mode = href_list["c_mode2"] + log_admin("[key_name(usr)] set the mode as [master_mode].") + message_admins("\blue [key_name_admin(usr)] set the mode as [master_mode].", 1) + world << "\blue The mode is now: [master_mode]" + Game() // updates the main game menu + world.save_mode(master_mode) + .(href, list("c_mode"=1)) + + if (href_list["f_secret2"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + if (ticker && ticker.mode) + return alert(usr, "The game has already started.", null, null, null, null) + if (master_mode != "secret") + return alert(usr, "The game mode has to be secret!", null, null, null, null) + secret_force_mode = href_list["f_secret2"] + log_admin("[key_name(usr)] set the forced secret mode as [secret_force_mode].") + message_admins("\blue [key_name_admin(usr)] set the forced secret mode as [secret_force_mode].", 1) + Game() // updates the main game menu + .(href, list("f_secret"=1)) + + if (href_list["monkeyone"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["monkeyone"]) + if(!ismob(M)) + return + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/N = M + log_admin("[key_name(usr)] attempting to monkeyize [key_name(M)]") + message_admins("\blue [key_name_admin(usr)] attempting to monkeyize [key_name_admin(M)]", 1) + N.monkeyize() + if(istype(M, /mob/living/silicon)) + alert("The AI can't be monkeyized!", null, null, null, null, null) + return + + if (href_list["corgione"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["corgione"]) + if(!ismob(M)) + return + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/N = M + log_admin("[key_name(usr)] attempting to corgize [key_name(M)]") + message_admins("\blue [key_name_admin(usr)] attempting to corgize [key_name_admin(M)]", 1) + N.corgize() + if(istype(M, /mob/living/silicon)) + alert("The AI can't be corgized!", null, null, null, null, null) + return + + if (href_list["forcespeech"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["forcespeech"]) + if (ismob(M)) + var/speech = input("What will [key_name(M)] say?.", "Force speech", "") + if(!speech) + return + M.say(speech) + speech = copytext(sanitize(speech), 1, MAX_MESSAGE_LEN) + log_admin("[key_name(usr)] forced [key_name(M)] to say: [speech]") + message_admins("\blue [key_name_admin(usr)] forced [key_name_admin(M)] to say: [speech]") + else + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return + + if (href_list["sendtoprison"]) + if ((src.rank in list( "Moderator", "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["sendtoprison"]) + if (ismob(M)) + if(istype(M, /mob/living/silicon/ai)) + alert("The AI can't be sent to prison you jerk!", null, null, null, null, null) + return + //strip their stuff before they teleport into a cell :downs: + for(var/obj/item/weapon/W in M) + if(istype(W, /datum/organ/external)) + continue + //don't strip organs + M.u_equip(W) + if (M.client) + M.client.screen -= W + if (W) + W.loc = M.loc + W.dropped(M) + W.layer = initial(W.layer) + //teleport person to cell + M.Paralyse(5) + sleep(5) //so they black out before warping + M.loc = pick(prisonwarp) + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/prisoner = M + prisoner.equip_if_possible(new /obj/item/clothing/under/color/orange(prisoner), prisoner.slot_w_uniform) + prisoner.equip_if_possible(new /obj/item/clothing/shoes/orange(prisoner), prisoner.slot_shoes) + spawn(50) + M << "\red You have been sent to the prison station!" + log_admin("[key_name(usr)] sent [key_name(M)] to the prison station.") + message_admins("\blue [key_name_admin(usr)] sent [key_name_admin(M)] to the prison station.", 1) + else + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return + +/* + if (href_list["sendtomaze"]) + if ((src.rank in list( "Admin Candidate", "Temporary Admin", "Trial Admin", "Badmin", "Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["sendtomaze"]) + if (ismob(M)) + if(istype(M, /mob/living/silicon/ai)) + alert("The AI can't be sent to the maze you jerk!", null, null, null, null, null) + return + //strip their stuff before they teleport into a cell :downs: + for(var/obj/item/weapon/W in M) + if(istype(W, /datum/organ/external)) + continue + //don't strip organs + M.u_equip(W) + if (M.client) + M.client.screen -= W + if (W) + W.loc = M.loc + W.dropped(M) + W.layer = initial(W.layer) + //teleport person to cell + M.paralysis += 5 + sleep(5) + //so they black out before warping + M.loc = pick(mazewarp) + spawn(50) + M << "\red You have been sent to the maze! Try and get out alive. In the maze everyone is free game. Kill or be killed." + log_admin("[key_name(usr)] sent [key_name(M)] to the maze.") + message_admins("\blue [key_name_admin(usr)] sent [key_name_admin(M)] to the maze.", 1) + else + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return +*/ + + if (href_list["tdome1"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["tdome1"]) + if (ismob(M)) + if(istype(M, /mob/living/silicon/ai)) + alert("The AI can't be sent to the thunderdome you jerk!", null, null, null, null, null) + return + for(var/obj/item/W in M) + if (istype(W,/obj/item)) + if(istype(W, /datum/organ/external)) + continue + M.u_equip(W) + if (M.client) + M.client.screen -= W + if (W) + W.loc = M.loc + W.dropped(M) + W.layer = initial(W.layer) + M.Paralyse(5) + sleep(5) + M.loc = pick(tdome1) + spawn(50) + M << "\blue You have been sent to the Thunderdome." + log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Team 1)") + message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Team 1)", 1) + + if (href_list["tdome2"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["tdome2"]) + if (ismob(M)) + if(istype(M, /mob/living/silicon/ai)) + alert("The AI can't be sent to the thunderdome you jerk!", null, null, null, null, null) + return + for(var/obj/item/W in M) + if (istype(W,/obj/item)) + if(istype(W, /datum/organ/external)) + continue + M.u_equip(W) + if (M.client) + M.client.screen -= W + if (W) + W.loc = M.loc + W.dropped(M) + W.layer = initial(W.layer) + M.Paralyse(5) + sleep(5) + M.loc = pick(tdome2) + spawn(50) + M << "\blue You have been sent to the Thunderdome." + log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Team 2)") + message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Team 2)", 1) + + if (href_list["tdomeadmin"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["tdomeadmin"]) + if (ismob(M)) + if(istype(M, /mob/living/silicon/ai)) + alert("The AI can't be sent to the thunderdome you jerk!", null, null, null, null, null) + return + M.Paralyse(5) + sleep(5) + M.loc = pick(tdomeadmin) + spawn(50) + M << "\blue You have been sent to the Thunderdome." + log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Admin.)") + message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Admin.)", 1) + + if (href_list["tdomeobserve"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["tdomeobserve"]) + if (ismob(M)) + if(istype(M, /mob/living/silicon/ai)) + alert("The AI can't be sent to the thunderdome you jerk!", null, null, null, null, null) + return + for(var/obj/item/W in M) + if (istype(W,/obj/item)) + if(istype(W, /datum/organ/external)) + continue + M.u_equip(W) + if (M.client) + M.client.screen -= W + if (W) + W.loc = M.loc + W.dropped(M) + W.layer = initial(W.layer) + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/observer = M + observer.equip_if_possible(new /obj/item/clothing/under/suit_jacket(observer), observer.slot_w_uniform) + observer.equip_if_possible(new /obj/item/clothing/shoes/black(observer), observer.slot_shoes) + M.Paralyse(5) + sleep(5) + M.loc = pick(tdomeobserve) + spawn(50) + M << "\blue You have been sent to the Thunderdome." + log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Observer.)") + message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Observer.)", 1) + + if (href_list["adminauth"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/M = locate(href_list["adminauth"]) + if (ismob(M) && !M.client.authenticated && !M.client.authenticating) + M.client.verbs -= /client/proc/authorize + M.client.authenticated = text("admin/[]", usr.client.authenticated) + log_admin("[key_name(usr)] authorized [key_name(M)]") + message_admins("\blue [key_name_admin(usr)] authorized [key_name_admin(M)]", 1) + M.client << text("You have been authorized by []", usr.key) + + if (href_list["revive"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/mob/living/M = locate(href_list["revive"]) + if (isliving(M)) + if(config.allow_admin_rev) + M.revive() + message_admins("\red Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!", 1) + log_admin("[key_name(usr)] healed / Rrvived [key_name(M)]") + return + else + alert("Admin revive disabled") + else + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return + + if (href_list["makeai"]) //Yes, im fucking lazy, so what? it works ... hopefully + if (src.level>=3) + var/mob/M = locate(href_list["makeai"]) + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + message_admins("\red Admin [key_name_admin(usr)] AIized [key_name_admin(M)]!", 1) +// if (ticker.mode.name == "AI malfunction") +// var/obj/O = locate("landmark*ai") +// M << "\blue You have been teleported to your new starting location!" +// M.loc = O.loc +// M.buckled = null +// else +// var/obj/S = locate(text("start*AI")) +// if ((istype(S, /obj/effect/landmark/start) && istype(S.loc, /turf))) +// M << "\blue You have been teleported to your new starting location!" +// M.loc = S.loc +// M.buckled = null + // world << "[M.real_name] is the AI!" + log_admin("[key_name(usr)] AIized [key_name(M)]") + H.AIize() + else + alert("I cannot allow this.") + return + else + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return + + if (href_list["makealien"]) + if (src.level>=3) + var/mob/M = locate(href_list["makealien"]) + if(istype(M, /mob/living/carbon/human)) + usr.client.cmd_admin_alienize(M) + else + alert("Wrong mob. Must be human.") + return + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + + if (href_list["makemetroid"]) + if (src.level>=3) + var/mob/M = locate(href_list["makemetroid"]) + if(istype(M, /mob/living/carbon/human)) + usr.client.cmd_admin_metroidize(M) + else + alert("Wrong mob. Must be human.") + return + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + + if (href_list["makerobot"]) + if (src.level>=3) + var/mob/M = locate(href_list["makerobot"]) + if(istype(M, /mob/living/carbon/human)) + usr.client.cmd_admin_robotize(M) + else + alert("Wrong mob. Must be human.") + return + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return +/***************** BEFORE************** + + if (href_list["l_players"]) + var/dat = "Name/Real Name/Key/IP:
" + for(var/mob/M in world) + var/foo = "" + if (ismob(M) && M.client) + if(!M.client.authenticated && !M.client.authenticating) + foo += text("\[ Authorize | ", src, M) + else + foo += text("\[ Authorized | ") + if(M.start) + if(!istype(M, /mob/living/carbon/monkey)) + foo += text("Monkeyize | ", src, M) + else + foo += text("Monkeyized | ") + if(istype(M, /mob/living/silicon/ai)) + foo += text("Is an AI | ") + else + foo += text("Make AI | ", src, M) + if(M.z != 2) + foo += text("Prison | ", src, M) + foo += text("Maze | ", src, M) + else + foo += text("On Z = 2 | ") + else + foo += text("Hasn't Entered Game | ") + foo += text("Heal/Revive | ", src, M) + + foo += text("Say \]", src, M) + dat += text("N: [] R: [] (K: []) (IP: []) []
", M.name, M.real_name, (M.client ? M.client : "No client"), M.lastKnownIP, foo) + + usr << browse(dat, "window=players;size=900x480") + +*****************AFTER******************/ + +// Now isn't that much better? IT IS NOW A PROC, i.e. kinda like a big panel like unstable + + if (href_list["adminplayeropts"]) + var/mob/M = locate(href_list["adminplayeropts"]) + show_player_panel(M) + + if (href_list["adminplayervars"]) + var/mob/M = locate(href_list["adminplayervars"]) + if(src && src.owner) + if(istype(src.owner,/client)) + var/client/cl = src.owner + cl.debug_variables(M) + else if(ismob(src.owner)) + var/mob/MO = src.owner + if(MO.client) + var/client/cl = MO.client + cl.debug_variables(M) + + if (href_list["adminplayersubtlemessage"]) + var/mob/M = locate(href_list["adminplayersubtlemessage"]) + if(src && src.owner) + if(istype(src.owner,/client)) + var/client/cl = src.owner + cl.cmd_admin_subtle_message(M) + else if(ismob(src.owner)) + var/mob/MO = src.owner + if(MO.client) + var/client/cl = MO.client + cl.cmd_admin_subtle_message(M) + + if (href_list["adminplayerobservejump"]) + var/mob/M = locate(href_list["adminplayerobservejump"]) + if(src && src.owner) + if(istype(src.owner,/client)) + var/client/cl = src.owner + cl.admin_observe() + sleep(2) + cl.jumptomob(M) + else if(ismob(src.owner)) + var/mob/MO = src.owner + if(MO.client) + var/client/cl = MO.client + cl.admin_observe() + sleep(2) + cl.jumptomob(M) + + + + + + if (href_list["BlueSpaceArtillery"]) + var/mob/M = locate(href_list["BlueSpaceArtillery"]) + if(!M) + return + + var/choice = alert(src.owner, "Are you sure you wish to hit [key_name(M)] with Blue Space Artillery?", "Confirm Firing?" , "Yes" , "No") + if (choice == "No") + return + + if(BSACooldown) + src.owner << "Standby! Reload cycle in progress! Gunnary crews ready in five seconds!" + return + + BSACooldown = 1 + spawn(50) + BSACooldown = 0 + + + M << "You've been hit by bluespace artillery!" + log_admin("[key_name(M)] has been hit by Bluespace Artillery fired by [src.owner]") + message_admins("[key_name(M)] has been hit by Bluespace Artillery fired by [src.owner]") + var/obj/effect/stop/S + S = new /obj/effect/stop + S.victim = M + S.loc = M.loc + spawn(20) + del(S) + + var/turf/T = get_turf(M) + if(T && (istype(T,/turf/simulated/floor/))) + if(prob(80)) + T:break_tile_to_plating() + else + T:break_tile() + + if(M.health == 1) + M.gib() + else + M.adjustBruteLoss( min( 99 , (M.health - 1) ) ) + M.Stun(20) + M.Weaken(20) + M.stuttering = 20 + + if (href_list["CentcommReply"]) + var/mob/M = locate(href_list["CentcommReply"]) + if(!M) + return + if(!istype(M, /mob/living/carbon/human)) + alert("Centcomm cannot transmit to non-humans.") + return + if(!istype(M:ears, /obj/item/device/radio/headset)) + alert("The person you're trying to reply to doesn't have a headset! Centcomm cannot transmit directly to them.") + return + var/input = input(src.owner, "Please enter a message to reply to [key_name(M)] via their headset.","Outgoing message from Centcomm", "") + if(!input) + return + + src.owner << "You sent [input] to [M] via a secure channel." + log_admin("[src.owner] replied to [key_name(M)]'s Centcomm message with the message [input].") + M << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from Central Command. Message as follows. [input]. Message ends.\"" + + return + + if (href_list["SyndicateReply"]) + var/mob/M = locate(href_list["SyndicateReply"]) + if(!M) + return + if(!istype(M, /mob/living/carbon/human)) + alert("The Syndicate cannot transmit to non-humans.") + return + if(!istype(M:ears, /obj/item/device/radio/headset)) + alert("The person you're trying to reply to doesn't have a headset! The Syndicate cannot transmit directly to them.") + return + var/input = input(src.owner, "Please enter a message to reply to [key_name(M)] via their headset.","Outgoing message from The Syndicate", "") + if(!input) + return + + src.owner << "You sent [input] to [M] via a secure channel." + log_admin("[src.owner] replied to [key_name(M)]'s Syndicate message with the message [input].") + M << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from your benefactor. Message as follows, agent. [input]. Message ends.\"" + + return + + if (href_list["jumpto"]) + if(rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + var/mob/M = locate(href_list["jumpto"]) + usr.client.jumptomob(M) + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + + if (href_list["getmob"]) + if(rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + var/mob/M = locate(href_list["getmob"]) + usr.client.Getmob(M) + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + + if (href_list["sendmob"]) + if(rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + var/mob/M = locate(href_list["sendmob"]) + usr.client.sendmob(M) + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + + if (href_list["narrateto"]) + if(rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + var/mob/M = locate(href_list["narrateto"]) + usr.client.cmd_admin_direct_narrate(M) + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + + if (href_list["subtlemessage"]) + var/mob/M = locate(href_list["subtlemessage"]) + usr.client.cmd_admin_subtle_message(M) + + if (href_list["traitor"]) + if(!ticker || !ticker.mode) + alert("The game hasn't started yet!") + return + var/mob/M = locate(href_list["traitor"]) + if (!istype(M)) + player_panel_new() + return + if(isalien(M)) + alert("Is an [M.mind ? M.mind.special_role : "Alien"]!", "[M.key]") + return + if (M:mind) + M:mind.edit_memory() + return + alert("Cannot make this mob a traitor! It has no mind!") + + if (href_list["create_object"]) + if (src.rank in list("Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + return create_object(usr) + else + alert("You are not a high enough administrator! Sorry!!!!") + + if (href_list["create_turf"]) + if (src.rank in list("Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + return create_turf(usr) + else + alert("You are not a high enough administrator! Sorry!!!!") + if (href_list["create_mob"]) + if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + return create_mob(usr) + else + alert("You are not a high enough administrator! Sorry!!!!") + if (href_list["vmode"]) + vmode() + + if (href_list["votekill"]) + votekill() + + if (href_list["voteres"]) + voteres() + + if (href_list["prom_demot"]) + if ((src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/client/C = locate(href_list["prom_demot"]) + if(C.holder && (C.holder.level >= src.level)) + alert("This cannot be done as [C] is a [C.holder.rank]") + return + var/dat = "[C] is a [C.holder ? "[C.holder.rank]" : "non-admin"]

Change [C]'s rank?
" + if(src.level == 6) + //Game Master + dat += {" + Senior Game Admin + Game Admin + Secondary Game Admin + Trial admin + Temporary Admin + Moderator + Admin Observer + Remove Admin
"} + else if(src.level == 5) + //Senior Admin + dat += {" + Game Admin + Secondary Game Admin + Trial admin + Temporary Admin + Moderator + Admin Observer + Remove Admin
"} + else if(src.level == 4) + //Game Admin + dat += {" + Secondary Game Admin + Trial admin + Temporary Admin + Moderator + Admin Observer + Remove Admin
"} + else if(src.level == 3) + //Secondary Game Admin + dat += {" + Trial admin + Temporary Admin + Moderator + Admin Observer + Remove Admin
"} + else + alert("Not a high enough level admin, sorry.") + return + usr << browse(dat, "window=prom_demot;size=480x300") + + if (href_list["chgadlvl"]) + //change admin level + var/rank = href_list["chgadlvl"] + var/client/C = locate(href_list["client4ad"]) + if(rank == "Remove") + C.clear_admin_verbs() + C.update_admins(null) + log_admin("[key_name(usr)] has removed [C]'s adminship") + message_admins("[key_name_admin(usr)] has removed [C]'s adminship", 1) + admins.Remove(C.ckey) + else + C.clear_admin_verbs() + C.update_admins(rank) + log_admin("[key_name(usr)] has made [C] a [rank]") + message_admins("[key_name_admin(usr)] has made [C] a [rank]", 1) + admins[C.ckey] = rank + + + if (href_list["object_list"]) + if (src.rank in list("Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + if (config.allow_admin_spawning && ((src.state == 2) || (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")))) + var/atom/loc = usr.loc + + var/dirty_paths + if (istext(href_list["object_list"])) + dirty_paths = list(href_list["object_list"]) + else if (istype(href_list["object_list"], /list)) + dirty_paths = href_list["object_list"] + + var/paths = list() + var/removed_paths = list() + for (var/dirty_path in dirty_paths) + var/path = text2path(dirty_path) + if (!path) + removed_paths += dirty_path + else if (!ispath(path, /obj) && !ispath(path, /turf) && !ispath(path, /mob)) + removed_paths += dirty_path + else if (ispath(path, /obj/item/weapon/gun/energy/pulse_rifle) && !(src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))) + removed_paths += dirty_path + else if (ispath(path, /obj/item/weapon/melee/energy/blade))//Not an item one should be able to spawn./N + removed_paths += dirty_path + else if (ispath(path, /obj/effect/bhole) && !(src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))) + removed_paths += dirty_path + else if (ispath(path, /mob) && !(src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))) + removed_paths += dirty_path + + else + paths += path + + if (!paths) + return + else if (length(paths) > 5) + alert("Select less object types, (max 5)") + return + else if (length(removed_paths)) + alert("Removed:\n" + dd_list2text(removed_paths, "\n")) + + var/list/offset = dd_text2list(href_list["offset"],",") + var/number = dd_range(1, 100, text2num(href_list["object_count"])) + var/X = offset.len > 0 ? text2num(offset[1]) : 0 + var/Y = offset.len > 1 ? text2num(offset[2]) : 0 + var/Z = offset.len > 2 ? text2num(offset[3]) : 0 + var/tmp_dir = href_list["object_dir"] + var/obj_dir = tmp_dir ? text2num(tmp_dir) : 2 + if(!obj_dir || !(obj_dir in list(1,2,4,8,5,6,9,10))) + obj_dir = 2 + var/obj_name = sanitize(href_list["object_name"]) + var/where = href_list["object_where"] + if (!( where in list("onfloor","inhand","inmarked") )) + where = "onfloor" + + //TODO ERRORAGE + if( where == "inhand" ) + usr << "Support for inhand not available yet. Will spawn on floor." + where = "onfloor" + //END TODO ERRORAGE + + if ( where == "inhand" ) //Can only give when human or monkey + if ( !( ishuman(usr) || ismonkey(usr) ) ) + usr << "Can only spawn in hand when you're a human or a monkey." + where = "onfloor" + else if ( usr.get_active_hand() ) + usr << "Your active hand is full. Spawning on floor." + where = "onfloor" + if ( where == "inmarked" ) + if ( !marked_datum ) + usr << "You don't have any object marked. Abandoning spawn." + return + else + if ( !istype(marked_datum,/atom) ) + usr << "The object you have marked cannot be used as a target. Target must be of type /atom. Abandoning spawn." + return + + var/atom/target //Where the object will be spawned + switch ( where ) + if ( "onfloor" ) + switch (href_list["offset_type"]) + if ("absolute") + target = locate(0 + X,0 + Y,0 + Z) + if ("relative") + target = locate(loc.x + X,loc.y + Y,loc.z + Z) + if ( "inmarked" ) + target = marked_datum + + + //TODO ERRORAGE - Give support for "inhand" + + if(target) + for (var/path in paths) + for (var/i = 0; i < number; i++) + var/atom/O = new path(target) + if(O) + O.dir = obj_dir + if(obj_name) + O.name = obj_name + if(istype(O,/mob)) + var/mob/M = O + M.real_name = obj_name + + + + if (number == 1) + log_admin("[key_name(usr)] created a [english_list(paths)]") + for(var/path in paths) + if(ispath(path, /mob)) + message_admins("[key_name_admin(usr)] created a [english_list(paths)]", 1) + break + else + log_admin("[key_name(usr)] created [number]ea [english_list(paths)]") + for(var/path in paths) + if(ispath(path, /mob)) + message_admins("[key_name_admin(usr)] created [number]ea [english_list(paths)]", 1) + break + return + else + alert("You cannot spawn items right now.") + return + + if (href_list["secretsfun"]) + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/ok = 0 + switch(href_list["secretsfun"]) + if("sec_clothes") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","SC") + for(var/obj/item/clothing/under/O in world) + del(O) + ok = 1 + if("sec_all_clothes") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","SAC") + for(var/obj/item/clothing/O in world) + del(O) + ok = 1 + if("sec_classic1") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","SC1") + for(var/obj/item/clothing/suit/fire/O in world) + del(O) + for(var/obj/structure/grille/O in world) + del(O) +/* for(var/obj/machinery/vehicle/pod/O in world) + for(var/mob/M in src) + M.loc = src.loc + if (M.client) + M.client.perspective = MOB_PERSPECTIVE + M.client.eye = M + del(O) + ok = 1*/ + if("toxic") + /* + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","T") + for(var/obj/machinery/atmoalter/siphs/fullairsiphon/O in world) + O.t_status = 3 + for(var/obj/machinery/atmoalter/siphs/scrubbers/O in world) + O.t_status = 1 + O.t_per = 1000000.0 + for(var/obj/machinery/atmoalter/canister/O in world) + if (!( istype(O, /obj/machinery/atmoalter/canister/oxygencanister) )) + O.t_status = 1 + O.t_per = 1000000.0 + else + O.t_status = 3 + */ + usr << "HEH" + if("monkey") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","M") + for(var/mob/living/carbon/human/H in world) + spawn(0) + H.monkeyize() + ok = 1 + if("corgi") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","M") + for(var/mob/living/carbon/human/H in world) + spawn(0) + H.corgize() + ok = 1 + if("power") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","P") + log_admin("[key_name(usr)] made all areas powered", 1) + message_admins("\blue [key_name_admin(usr)] made all areas powered", 1) + power_restore() + if("unpower") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","UP") + log_admin("[key_name(usr)] made all areas unpowered", 1) + message_admins("\blue [key_name_admin(usr)] made all areas unpowered", 1) + power_failure() + if("activateprison") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","AP") + world << "\blue Transit signature detected." + world << "\blue Incoming shuttle." + /* + var/A = locate(/area/shuttle_prison) + for(var/atom/movable/AM as mob|obj in A) + AM.z = 1 + AM.Move() + */ + message_admins("\blue [key_name_admin(usr)] sent the prison shuttle to the station.", 1) + if("deactivateprison") + /* + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","DP") + var/A = locate(/area/shuttle_prison) + for(var/atom/movable/AM as mob|obj in A) + AM.z = 2 + AM.Move() + */ + message_admins("\blue [key_name_admin(usr)] sent the prison shuttle back.", 1) + if("toggleprisonstatus") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","TPS") + for(var/obj/machinery/computer/prison_shuttle/PS in world) + PS.allowedtocall = !(PS.allowedtocall) + message_admins("\blue [key_name_admin(usr)] toggled status of prison shuttle to [PS.allowedtocall].", 1) + if("prisonwarp") + if(!ticker) + alert("The game hasn't started yet!", null, null, null, null, null) + return + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","PW") + message_admins("\blue [key_name_admin(usr)] teleported all players to the prison station.", 1) + for(var/mob/living/carbon/human/H in world) + var/turf/loc = find_loc(H) + var/security = 0 + if(loc.z > 1 || prisonwarped.Find(H)) + //don't warp them if they aren't ready or are already there + continue + H.Paralyse(5) + if(H.wear_id) + var/obj/item/weapon/card/id/id = H.get_idcard() + for(var/A in id.access) + if(A == access_security) + security++ + if(!security) + //strip their stuff before they teleport into a cell :downs: + for(var/obj/item/weapon/W in H) + if(istype(W, /datum/organ/external)) + continue + //don't strip organs + H.u_equip(W) + if (H.client) + H.client.screen -= W + if (W) + W.loc = H.loc + W.dropped(H) + W.layer = initial(W.layer) + //teleport person to cell + H.loc = pick(prisonwarp) + H.equip_if_possible(new /obj/item/clothing/under/color/orange(H), H.slot_w_uniform) + H.equip_if_possible(new /obj/item/clothing/shoes/orange(H), H.slot_shoes) + else + //teleport security person + H.loc = pick(prisonsecuritywarp) + prisonwarped += H + if("traitor_all") + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + if(!ticker) + alert("The game hasn't started yet!") + return + var/objective = input("Enter an objective") + if(!objective) + return + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","TA([objective])") + for(var/mob/living/carbon/human/H in world) + if(H.stat == 2 || !H.client || !H.mind) continue + if(is_special_character(H)) continue + //traitorize(H, objective, 0) + ticker.mode.traitors += H.mind + H.mind.special_role = "traitor" + var/datum/objective/new_objective = new + new_objective.owner = H + new_objective.explanation_text = objective + H.mind.objectives += new_objective + ticker.mode.greet_traitor(H) + //ticker.mode.forge_traitor_objectives(H.mind) + ticker.mode.finalize_traitor(H) + for(var/mob/living/silicon/A in world) + ticker.mode.traitors += A.mind + A.mind.special_role = "traitor" + var/datum/objective/new_objective = new + new_objective.owner = A + new_objective.explanation_text = objective + A.mind.objectives += new_objective + ticker.mode.greet_traitor(A) + ticker.mode.finalize_traitor(A) + message_admins("\blue [key_name_admin(usr)] used everyone is a traitor secret. Objective is [objective]", 1) + log_admin("[key_name(usr)] used everyone is a traitor secret. Objective is [objective]") + else + alert("You're not of a high enough rank to do this") + if("moveminingshuttle") + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + if(mining_shuttle_moving) + return + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","ShM") + move_mining_shuttle() + message_admins("\blue [key_name_admin(usr)] moved mining shuttle", 1) + log_admin("[key_name(usr)] moved the mining shuttle") + else + alert("You're not of a high enough rank to do this") + if("moveadminshuttle") + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","ShA") + move_admin_shuttle() + message_admins("\blue [key_name_admin(usr)] moved the centcom administration shuttle", 1) + log_admin("[key_name(usr)] moved the centcom administration shuttle") + else + alert("You're not of a high enough rank to do this") + if("moveferry") + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","ShF") + move_ferry() + message_admins("\blue [key_name_admin(usr)] moved the centcom ferry", 1) + log_admin("[key_name(usr)] moved the centcom ferry") + else + alert("You're not of a high enough rank to do this") + if("movealienship") + if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","ShX") + move_alien_ship() + message_admins("\blue [key_name_admin(usr)] moved the alien dinghy", 1) + log_admin("[key_name(usr)] moved the alien dinghy") + else + alert("You're not of a high enough rank to do this") + if("togglebombcap") + if (src.rank in list( "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )) + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","BC") + switch(MAX_EXPLOSION_RANGE) + if(14) + MAX_EXPLOSION_RANGE = 16 + if(16) + MAX_EXPLOSION_RANGE = 20 + if(20) + MAX_EXPLOSION_RANGE = 28 + if(28) + MAX_EXPLOSION_RANGE = 56 + if(56) + MAX_EXPLOSION_RANGE = 128 + if(128) + MAX_EXPLOSION_RANGE = 14 + var/range_dev = MAX_EXPLOSION_RANGE *0.25 + var/range_high = MAX_EXPLOSION_RANGE *0.5 + var/range_low = MAX_EXPLOSION_RANGE + message_admins("\red [key_name_admin(usr)] changed the bomb cap to [range_dev], [range_high], [range_low]", 1) + log_admin("[key_name_admin(usr)] changed the bomb cap to [MAX_EXPLOSION_RANGE]") + else + alert("No way. You're not of a high enough rank to do this.") + + if("flicklights") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","FL") + while(!usr.stat) + //knock yourself out to stop the ghosts + for(var/mob/M in world) + if(M.client && M.stat != 2 && prob(25)) + var/area/AffectedArea = get_area(M) + if(AffectedArea.name != "Space" && AffectedArea.name != "Engine Walls" && AffectedArea.name != "Chemical Lab Test Chamber" && AffectedArea.name != "Escape Shuttle" && AffectedArea.name != "Arrival Area" && AffectedArea.name != "Arrival Shuttle" && AffectedArea.name != "start area" && AffectedArea.name != "Engine Combustion Chamber") + AffectedArea.power_light = 0 + AffectedArea.power_change() + spawn(rand(55,185)) + AffectedArea.power_light = 1 + AffectedArea.power_change() + var/Message = rand(1,4) + switch(Message) + if(1) + M.show_message(text("\blue You shudder as if cold..."), 1) + if(2) + M.show_message(text("\blue You feel something gliding across your back..."), 1) + if(3) + M.show_message(text("\blue Your eyes twitch, you feel like something you can't see is here..."), 1) + if(4) + M.show_message(text("\blue You notice something moving out of the corner of your eye, but nothing is there..."), 1) + for(var/obj/W in orange(5,M)) + if(prob(25) && !W.anchored) + step_rand(W) + sleep(rand(100,1000)) + for(var/mob/M in world) + if(M.client && M.stat != 2) + M.show_message(text("\blue The chilling wind suddenly stops..."), 1) + /* if("shockwave") + ok = 1 + world << "\red ALERT: STATION STRESS CRITICAL" + sleep(60) + world << "\red ALERT: STATION STRESS CRITICAL. TOLERABLE LEVELS EXCEEDED!" + sleep(80) + world << "\red ALERT: STATION STRUCTURAL STRESS CRITICAL. SAFETY MECHANISMS FAILED!" + sleep(40) + for(var/mob/M in world) + shake_camera(M, 400, 1) + for(var/obj/structure/window/W in world) + spawn(0) + sleep(rand(10,400)) + W.ex_act(rand(2,1)) + for(var/obj/structure/grille/G in world) + spawn(0) + sleep(rand(20,400)) + G.ex_act(rand(2,1)) + for(var/obj/machinery/door/D in world) + spawn(0) + sleep(rand(20,400)) + D.ex_act(rand(2,1)) + for(var/turf/station/floor/Floor in world) + spawn(0) + sleep(rand(30,400)) + Floor.ex_act(rand(2,1)) + for(var/obj/structure/cable/Cable in world) + spawn(0) + sleep(rand(30,400)) + Cable.ex_act(rand(2,1)) + for(var/obj/structure/closet/Closet in world) + spawn(0) + sleep(rand(30,400)) + Closet.ex_act(rand(2,1)) + for(var/obj/machinery/Machinery in world) + spawn(0) + sleep(rand(30,400)) + Machinery.ex_act(rand(1,3)) + for(var/turf/station/wall/Wall in world) + spawn(0) + sleep(rand(30,400)) + Wall.ex_act(rand(2,1)) */ + if("wave") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","MW") + if ((src.rank in list("Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + meteor_wave() + message_admins("[key_name_admin(usr)] has spawned meteors", 1) + command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert") + world << sound('meteors.ogg') + else + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return + if("gravanomalies") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","GA") + command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert") + world << sound('granomalies.ogg') + var/turf/T = pick(blobstart) + var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 ) + spawn(rand(50, 300)) + del(bh) + if("timeanomalies") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","STA") + command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert") + world << sound('spanomalies.ogg') + var/list/turfs = list( ) + var/turf/picked + for(var/turf/T in world) + if(T.z == 1 && istype(T,/turf/simulated/floor) && !istype(T,/turf/space)) + turfs += T + for(var/turf/T in world) + set background = 1 + if(prob(20) && T.z == 1 && istype(T,/turf/simulated/floor)) + spawn(50+rand(0,3000)) + picked = pick(turfs) + var/obj/effect/portal/P = new /obj/effect/portal( T ) + P.target = picked + P.creator = null + P.icon = 'objects.dmi' + P.failchance = 0 + P.icon_state = "anom" + P.name = "wormhole" + spawn(rand(300,600)) + del(P) + if("goblob") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","BL") + mini_blob_event() + message_admins("[key_name_admin(usr)] has spawned blob", 1) + if("aliens") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","AL") + if(aliens_allowed) + alien_infestation() + message_admins("[key_name_admin(usr)] has spawned aliens", 1) + if("spaceninja") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","SN") + if(toggle_space_ninja) + if(space_ninja_arrival())//If the ninja is actually spawned. They may not be depending on a few factors. + message_admins("[key_name_admin(usr)] has sent in a space ninja", 1) + if("carp") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","C") + var/choice = input("You sure you want to spawn carp?") in list("Badmin", "Cancel") + if(choice == "Badmin") + message_admins("[key_name_admin(usr)] has spawned carp.", 1) + carp_migration() + if("radiation") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","R") + message_admins("[key_name_admin(usr)] has has irradiated the station", 1) + high_radiation_event() + if("immovable") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","IR") + message_admins("[key_name_admin(usr)] has sent an immovable rod to the station", 1) + immovablerod() + if("prison_break") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","PB") + message_admins("[key_name_admin(usr)] has allowed a prison break", 1) + prison_break() + if("lightsout") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","LO") + message_admins("[key_name_admin(usr)] has broke a lot of lights", 1) + lightsout(1,2) + if("blackout") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","BO") + message_admins("[key_name_admin(usr)] broke all lights", 1) + lightsout(0,0) + if("virus") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","V") + var/answer = alert("Do you want this to be a random disease or do you have something in mind?",,"Virus2","Random","Choose") + if(answer=="Random") + viral_outbreak() + message_admins("[key_name_admin(usr)] has triggered a virus outbreak", 1) + else if(answer == "Choose") + var/list/viruses = list("fake gbs","gbs","magnitis","wizarditis",/*"beesease",*/"brain rot","cold","retrovirus","flu","pierrot's throat","rhumba beat") + var/V = input("Choose the virus to spread", "BIOHAZARD") in viruses + viral_outbreak(V) + message_admins("[key_name_admin(usr)] has triggered a virus outbreak of [V]", 1) + else + usr << "Nope" + /* + var/lesser = (alert("Do you want to infect the mob with a major or minor disease?",,"Major","Minor") == "Minor") + var/mob/living/carbon/victim = input("Select a mob to infect", "Virus2") as null|mob in world + if(!istype(victim)) return + if(lesser) + infect_mob_random_lesser(victim) + else + infect_mob_random_greater(victim) + message_admins("[key_name_admin(usr)] has infected [victim] with a [lesser ? "minor" : "major"] virus2.", 1) + */ + if("retardify") + if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","RET") + for(var/mob/living/carbon/human/H in world) + if(H.client) + H << "\red You suddenly feel stupid." + H.setBrainLoss(60) + message_admins("[key_name_admin(usr)] made everybody retarded") + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + if("fakeguns") + if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","FG") + for(var/obj/item/W in world) + if(istype(W, /obj/item/clothing) || istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/weapon/disk) || istype(W, /obj/item/weapon/tank)) + continue + W.icon = 'gun.dmi' + W.icon_state = "revolver" + W.item_state = "gun" + message_admins("[key_name_admin(usr)] made every item look like a gun") + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + if("schoolgirl") + if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","SG") + for(var/obj/item/clothing/under/W in world) + W.icon_state = "schoolgirl" + W.item_state = "w_suit" + W.color = "schoolgirl" + message_admins("[key_name_admin(usr)] activated Japanese Animes mode") + world << sound('animes.ogg') + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + if("dorf") + if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","DF") + for(var/mob/living/carbon/human/B in world) + B.face_icon_state = "facial_wise" + B.update_face() + message_admins("[key_name_admin(usr)] activated dorf mode") + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + if("ionstorm") + if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")) + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","I") + IonStorm() + message_admins("[key_name_admin(usr)] triggered an ion storm") + var/show_log = alert(usr, "Show ion message?", "Message", "Yes", "No") + if(show_log == "Yes") + command_alert("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert") + world << sound('ionstorm.ogg') + else + alert("You cannot perform this action. You must be of a higher administrative rank!") + return + if("spacevines") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","K") + spacevine_infestation() + message_admins("[key_name_admin(usr)] has spawned spacevines", 1) + if (usr) + log_admin("[key_name(usr)] used secret [href_list["secretsfun"]]") + if (ok) + world << text("A secret has been activated by []!", usr.key) + return + + if (href_list["secretsadmin"]) + if ((src.rank in list( "Moderator", "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/ok = 0 + switch(href_list["secretsadmin"]) + if("clear_bombs") + //I do nothing + if("list_bombers") + var/dat = "Bombing List
" + for(var/l in bombers) + dat += text("[l]
") + usr << browse(dat, "window=bombers") + if("list_signalers") + var/dat = "Showing last [length(lastsignalers)] signalers.
" + for(var/sig in lastsignalers) + dat += "[sig]
" + usr << browse(dat, "window=lastsignalers;size=800x500") + if("list_lawchanges") + var/dat = "Showing last [length(lawchanges)] law changes.
" + for(var/sig in lawchanges) + dat += "[sig]
" + usr << browse(dat, "window=lawchanges;size=800x500") + if("list_job_debug") + var/dat = "Job Debug info.
" + if(job_master) + for(var/line in job_master.job_debug) + dat += "[line]
" + dat+= "*******

" + for(var/datum/job/job in job_master.occupations) + if(!job) continue + dat += "job: [job.title], current_positions: [job.current_positions], total_positions: [job.total_positions]
" + usr << browse(dat, "window=jobdebug;size=600x500") + if("check_antagonist") + if (ticker && ticker.current_state >= GAME_STATE_PLAYING) + var/dat = "Round Status

Round Status

" + dat += "Current Game Mode: [ticker.mode.name]
" + dat += "Round Duration: [round(world.time / 36000)]:[add_zero(world.time / 600 % 60, 2)]:[world.time / 100 % 6][world.time / 100 % 10]
" + dat += "Emergency shuttle
" + if (!emergency_shuttle.online) + dat += "Call Shuttle
" + else + var/timeleft = emergency_shuttle.timeleft() + switch(emergency_shuttle.location) + if(0) + dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]
" + dat += "Send Back
" + if(1) + dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]
" + + if(ticker.mode.syndicates.len) + dat += "
" + for(var/datum/mind/N in ticker.mode.syndicates) + var/mob/M = N.current + if(M) + dat += "" + dat += "" + else + dat += "" + dat += "
Syndicates
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
Nuclear Operative not found!

" + for(var/obj/item/weapon/disk/nuclear/N in world) + dat += "" + dat += "
Nuclear Disk(s)
[N.name], " + var/atom/disk_loc = N.loc + while(!istype(disk_loc, /turf)) + if(istype(disk_loc, /mob)) + var/mob/M = disk_loc + dat += "carried by [M.real_name] " + if(istype(disk_loc, /obj)) + var/obj/O = disk_loc + dat += "in \a [O.name] " + disk_loc = disk_loc.loc + dat += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])
" + + if(ticker.mode.head_revolutionaries.len || ticker.mode.revolutionaries.len) + dat += "
" + for(var/datum/mind/N in ticker.mode.head_revolutionaries) + var/mob/M = N.current + if(!M) + dat += "" + else + dat += "" + dat += "" + for(var/datum/mind/N in ticker.mode.revolutionaries) + var/mob/M = N.current + if(M) + dat += "" + dat += "" + dat += "
Revolutionaries
Head Revolutionary not found!
[M.real_name] (Leader)[M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
" + for(var/datum/mind/N in ticker.mode.get_living_heads()) + var/mob/M = N.current + if(M) + dat += "" + dat += "" + var/turf/mob_loc = get_turf_loc(M) + dat += "" + else + dat += "" + dat += "
Target(s)Location
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM[mob_loc.loc]
Head not found!
" + + if(ticker.mode.changelings.len > 0) + dat += "
" + for(var/datum/mind/changeling in ticker.mode.changelings) + var/mob/M = changeling.current + if(M) + dat += "" + dat += "" + dat += "" + else + dat += "" + dat += "
Changelings
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PMShow Objective
Changeling not found!
" + + if(ticker.mode.wizards.len > 0) + dat += "
" + for(var/datum/mind/wizard in ticker.mode.wizards) + var/mob/M = wizard.current + if(M) + dat += "" + dat += "" + dat += "" + else + dat += "" + dat += "
Wizards
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PMShow Objective
Wizard not found!
" + + if(ticker.mode.cult.len) + dat += "
" + for(var/datum/mind/N in ticker.mode.cult) + var/mob/M = N.current + if(M) + dat += "" + dat += "" + dat += "
Cultists
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
" + + if(ticker.mode.traitors.len > 0) + dat += "
" + for(var/datum/mind/traitor in ticker.mode.traitors) + var/mob/M = traitor.current + if(M) + dat += "" + dat += "" + dat += "" + else + dat += "" + dat += "
Traitors
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PMShow Objective
Traitor not found!
" + + dat += "" + usr << browse(dat, "window=roundstatus;size=400x500") + else + alert("The game hasn't started yet!") + if("showailaws") + for(var/mob/living/silicon/ai/ai in world) + usr << "[key_name(ai, usr)]'s Laws:" + if (ai.laws == null) + usr << "[key_name(ai, usr)]'s Laws are null??" + else + ai.laws.show_laws(usr) + if("showgm") + if(!ticker) + alert("The game hasn't started yet!") + else if (ticker.mode) + alert("The game mode is [ticker.mode.name]") + else alert("For some reason there's a ticker, but not a game mode") + if("manifest") + var/dat = "Showing Crew Manifest.
" + dat += "" + for(var/mob/living/carbon/human/H in world) + if(H.ckey) + dat += text("", H.name, H.get_assignment()) + dat += "
NamePosition
[][]
" + usr << browse(dat, "window=manifest;size=440x410") + if("DNA") + var/dat = "Showing DNA from blood.
" + dat += "" + for(var/mob/living/carbon/human/H in world) + if(H.dna && H.ckey) + dat += "" + dat += "
NameDNABlood Type
[H][H.dna.unique_enzymes][H.b_type]
" + usr << browse(dat, "window=DNA;size=440x410") + if("fingerprints") + var/dat = "Showing Fingerprints.
" + dat += "" + for(var/mob/living/carbon/human/H in world) + if(H.ckey) + if(H.dna && H.dna.uni_identity) + dat += "" + else if(H.dna && !H.dna.uni_identity) + dat += "" + else if(!H.dna) + dat += "" + dat += "
NameFingerprints
[H][md5(H.dna.uni_identity)]
[H]H.dna.uni_identity = null
[H]H.dna = null
" + usr << browse(dat, "window=fingerprints;size=440x410") + else + if (usr) + log_admin("[key_name(usr)] used secret [href_list["secretsadmin"]]") + if (ok) + world << text("A secret has been activated by []!", usr.key) + return + if (href_list["secretscoder"]) + if ((src.rank in list( "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + switch(href_list["secretscoder"]) + if("spawn_objects") + var/dat = "Admin Log
" + for(var/l in admin_log) + dat += "
  • [l]
  • " + if(!admin_log.len) + dat += "No-one has done anything this round!" + usr << browse(dat, "window=admin_log") + if("maint_access_brig") + for(var/obj/machinery/door/airlock/maintenance/M in world) + if (access_maint_tunnels in M.req_access) + M.req_access = list(access_brig) + message_admins("[key_name_admin(usr)] made all maint doors brig access-only.") + if("maint_access_engiebrig") + for(var/obj/machinery/door/airlock/maintenance/M in world) + if (access_maint_tunnels in M.req_access) + M.req_access = list() + M.req_one_access = list(access_brig,access_engine) + message_admins("[key_name_admin(usr)] made all maint doors engineering and brig access-only.") + if("infinite_sec") + var/datum/job/J = job_master.GetJob("Security Officer") + if(!J) return + J.total_positions = -1 + J.spawn_positions = -1 + message_admins("[key_name_admin(usr)] has removed the cap on security officers.") + return + //hahaha + +///////////////////////////////////////////////////////////////////////////////////////////////Panels + +/obj/admins/proc/show_player_panel(var/mob/M in world) + set category = "Admin" + set name = "Show Player Panel" + set desc="Edit player (respawn, ban, heal, etc)" + if(!M) + usr << "You seem to be selecting a mob that doesn't exist anymore." + return + if (!istype(src,/obj/admins)) + src = usr.client.holder + if (!istype(src,/obj/admins)) + usr << "Error: you are not an admin!" + return + var/dat = "Options for [M.key]" + var/foo = "\[ " + if (ismob(M) && M.client) + if(!M.client.authenticated && !M.client.authenticating) + foo += text("Authorize | ") + else + foo += text("Authorized | ") + foo += text("Promote/Demote | ") + if(!istype(M, /mob/new_player)) + if(!ismonkey(M)) + foo += text("Monkeyize | ") + else + foo += text("Monkeyized | ") + if(!iscorgi(M)) + foo += text("Corgize | ") + else + foo += text("Corgized | ") + if(isAI(M)) + foo += text("Is an AI | ") + else if(ishuman(M)) + foo += text("Make AI | ") + foo += text("Make Robot | ") + foo += text("Make Alien | ") + foo += text("Make Metroid | ") + foo += text("Thunderdome 1 | ") + foo += text("Thunderdome 2 | ") + foo += text("Thunderdome Admin | ") + foo += text("Thunderdome Observer | ") + foo += text("Prison | ") + // foo += text("Maze | ") + foo += text("Heal/Revive | ") + else + foo += text("Hasn't Entered Game | ") + foo += text("Forcesay | ") + if(M.client) + foo += text("Mute: [(M.client.muted ? "Muted" : "Voiced")] | ") + foo += text("Complete mute: [(M.client.muted ? "Completely Muted" : "Voiced")] | ") + else + foo += "Mute unavailable - no client" + foo += text("Boot") + foo += text("
    ") + foo += text("Jump to | ") + foo += text("Get | ") + foo += text("Send") + foo += text("
    ") + foo += text("Edit mind | ") + foo += text("Narrate to | ") + foo += text("Subtle message") + foo += text("
    ") + foo += text("Ban | ") + foo += text("Jobban") + dat += text("[foo]") + usr << browse(dat, "window=adminplayeropts;size=480x150") + + + +/obj/admins/proc/Jobbans() + + if ((src.rank in list( "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))) + var/dat = "Job Bans!
    " + for(var/t in jobban_keylist) + var/r = t + if( findtext(r,"##") ) + r = copytext( r, 1, findtext(r,"##") )//removes the description + dat += text("") + dat += "
    [t] (unban)
    " + usr << browse(dat, "window=ban;size=400x400") + +/obj/admins/proc/Game() + + var/dat + var/lvl = 0 + switch(src.rank) + if("Moderator") + lvl = 1 + if("Temporary Admin") + lvl = 2 + if("Trial Admin") + lvl = 3 + if("Secondary Game Admin") + lvl = 4 + if("Game Admin") + lvl = 5 + if("Senior Game Admin") + lvl = 6 + if("Game Master") + lvl = 7 + + dat += "
    Game Panel

    \n" + + if(lvl > 0) + +// if(lvl >= 2 ) + dat += "Change Game Mode
    " + + if(lvl > 0 && master_mode == "secret") + dat += "(Force Secret Mode)
    " + + dat += "
    " + + if(lvl >= 3 ) + dat += "Create Object
    " + dat += "Create Turf
    " + if(lvl >= 5) + dat += "Create Mob
    " +// if(lvl == 6 ) + usr << browse(dat, "window=admin2;size=210x180") + return +/* +/obj/admins/proc/goons() + var/dat = "
    GOOOOOOONS
    " + for(var/t in goon_keylist) + dat += text("") + dat += "
    KeySA Username
    [t][goon_keylist[ckey(t)]]
    " + usr << browse(dat, "window=ban;size=300x400") + +/obj/admins/proc/beta_testers() + var/dat = "
    Beta testers
    " + for(var/t in beta_tester_keylist) + dat += text("") + dat += "
    Key
    [t]
    " + usr << browse(dat, "window=ban;size=300x400") +*/ +/obj/admins/proc/Secrets() + if (!usr.client.holder) + return + + var/lvl = 0 + switch(src.rank) + if("Moderator") + lvl = 1 + if("Temporary Admin") + lvl = 2 + if("Trial Admin") + lvl = 3 + if("Secondary Game Admin") + lvl = 4 + if("Game Admin") + lvl = 5 + if("Senior Game Admin") + lvl = 6 + if("Game Master") + lvl = 7 + + var/dat = {" +Choose a secret, any secret at all.
    +Admin Secrets
    +
    +Remove all bombs currently in existence
    +Bombing List
    +Show current traitors and objectives
    +Show last [length(lastsignalers)] signalers
    +Show last [length(lawchanges)] law changes
    +Show AI Laws
    +Show Game Mode
    +Show Crew Manifest
    +List DNA (Blood)
    +List Fingerprints

    +
    "} + if(lvl > 2) + dat += {" +'Random' Events
    +
    +Spawn a wave of meteors
    +Spawn a gravitational anomaly (Untested)
    +Spawn wormholes (Untested)
    +Spawn blob(Untested)
    +Trigger an Alien infestation
    +Send in a space ninja
    +Trigger an Carp migration
    +Irradiate the station
    +Trigger a Prison Break
    +Trigger a Virus Outbreak
    +Spawn an Immovable Rod
    +Toggle a "lights out" event
    +Spawn an Ion Storm
    +Spawn Space-Vines
    +
    +Fun Secrets
    +
    +Remove 'internal' clothing
    +Remove ALL clothing
    +Toxic Air (WARNING: dangerous)
    +Turn all humans into monkeys
    +Remove firesuits, grilles, and pods
    +Make all areas powered
    +Make all areas unpowered
    +Toggle Prison Shuttle Status(Use with S/R)
    +Send Prison Shuttle
    +Return Prison Shuttle
    +Warp all Players to Prison
    +Everyone is the traitor
    +Ghost Mode
    +Make all players retarded
    +Make all items look like guns
    +Japanese Animes Mode
    +Move Administration Shuttle
    +Move Ferry
    +Move Alien Dinghy
    +Move Mining Shuttle
    +Break all lights
    "} +//Station Shockwave
    + + if(lvl >= 6) + dat += {" +Toggle bomb cap
    + "} + + dat += "
    " + + if(lvl >= 5) + dat += {" +Security Level Elevated
    +
    +Change all maintenance doors to engie/brig access only
    +Change all maintenance doors to brig access only
    +Remove cap on security officers
    +
    +Coder Secrets
    +
    +Show Job Debug
    +Admin Log
    +
    +"} + usr << browse(dat, "window=secrets") + return + +/obj/admins/proc/Voting() + + var/dat + var/lvl = 0 + switch(src.rank) + if("Moderator") + lvl = 1 + if("Temporary Admin") + lvl = 2 + if("Trial Admin") + lvl = 3 + if("Secondary Game Admin") + lvl = 4 + if("Game Admin") + lvl = 5 + if("Senior Game Admin") + lvl = 6 + if("Game Master") + lvl = 7 + + + dat += "
    Voting

    \n" + + if(lvl > 0) +// if(lvl >= 2 ) + dat += {" +Abort Vote
    +Start Vote
    +Toggle Voting
    +"} + +// if(lvl >= 3 ) +// if(lvl >= 5) +// if(lvl == 6 ) + + usr << browse(dat, "window=admin2;size=210x160") + return + + + +/////////////////////////////////////////////////////////////////////////////////////////////////admins2.dm merge +//i.e. buttons/verbs + + +/obj/admins/proc/vmode() + set category = "Server" + set name = "Start Vote" + set desc="Starts vote" + if (!usr.client.holder) + return + var/confirm = alert("What vote would you like to start?", "Vote", "Restart", "Change Game Mode", "Cancel") + if(confirm == "Cancel") + return + if(confirm == "Restart") + vote.mode = 0 + // hack to yield 0=restart, 1=changemode + if(confirm == "Change Game Mode") + vote.mode = 1 + if(!ticker) + if(going) + world << "The game start has been delayed." + going = 0 + vote.voting = 1 + // now voting + vote.votetime = world.timeofday + config.vote_period*10 + // when the vote will end + spawn(config.vote_period*10) + vote.endvote() + world << "\red*** A vote to [vote.mode?"change game mode":"restart"] has been initiated by Admin [usr.key]." + world << "\red You have [vote.timetext(config.vote_period)] to vote." + + log_admin("Voting to [vote.mode?"change mode":"restart round"] forced by admin [key_name(usr)]") + + for(var/mob/CM in world) + if(CM.client) + if(config.vote_no_default || (config.vote_no_dead && CM.stat == 2) || !CM.client.authenticated) + CM.client.vote = "none" + else + CM.client.vote = "default" + + for(var/mob/CM in world) + if(CM.client) + if(config.vote_no_default || (config.vote_no_dead && CM.stat == 2) || !CM.client.authenticated) + CM.client.vote = "none" + else + CM.client.vote = "default" + +/obj/admins/proc/votekill() + set category = "Server" + set name = "Abort Vote" + set desc="Aborts a vote" + if(vote.voting == 0) + alert("No votes in progress") + return + world << "\red *** Voting aborted by [usr.client.stealth ? "Admin Candidate" : usr.key]." + + log_admin("Voting aborted by [key_name(usr)]") + + vote.voting = 0 + vote.nextvotetime = world.timeofday + 10*config.vote_delay + + for(var/mob/M in world) + // clear vote window from all clients + if(M.client) + M << browse(null, "window=vote") + M.client.showvote = 0 + +/obj/admins/proc/voteres() + set category = "Server" + set name = "Toggle Voting" + set desc="Toggles Votes" + var/confirm = alert("What vote would you like to toggle?", "Vote", "Restart [config.allow_vote_restart ? "Off" : "On"]", "Change Game Mode [config.allow_vote_mode ? "Off" : "On"]", "Cancel") + if(confirm == "Cancel") + return + if(confirm == "Restart [config.allow_vote_restart ? "Off" : "On"]") + config.allow_vote_restart = !config.allow_vote_restart + world << "Player restart voting toggled to [config.allow_vote_restart ? "On" : "Off"]." + log_admin("Restart voting toggled to [config.allow_vote_restart ? "On" : "Off"] by [key_name(usr)].") + + if(config.allow_vote_restart) + vote.nextvotetime = world.timeofday + if(confirm == "Change Game Mode [config.allow_vote_mode ? "Off" : "On"]") + config.allow_vote_mode = !config.allow_vote_mode + world << "Player mode voting toggled to [config.allow_vote_mode ? "On" : "Off"]." + log_admin("Mode voting toggled to [config.allow_vote_mode ? "On" : "Off"] by [key_name(usr)].") + + if(config.allow_vote_mode) + vote.nextvotetime = world.timeofday + +/obj/admins/proc/restart() + set category = "Server" + set name = "Restart" + set desc="Restarts the world" + if (!usr.client.holder) + return + var/confirm = alert("Restart the game world?", "Restart", "Yes", "Cancel") + if(confirm == "Cancel") + return + if(confirm == "Yes") + world << "\red Restarting world! \blue Initiated by [usr.client.stealth ? "Admin" : usr.key]!" + log_admin("[key_name(usr)] initiated a reboot.") + + feedback_set_details("end_error","admin reboot - by [usr.key] [usr.client.stealth ? "(stealth)" : ""]") + + if(blackbox) + blackbox.save_all_data_to_sql() + + sleep(50) + world.Reboot() + +/obj/admins/proc/announce() + set category = "Special Verbs" + set name = "Announce" + set desc="Announce your desires to the world" + var/message = input("Global message to send:", "Admin Announce", null, null) as message + if (message) + if(usr.client.holder.rank != "Game Admin" && usr.client.holder.rank != "Game Master") + message = adminscrub(message,500) + world << "\blue [usr.client.stealth ? "Administrator" : usr.key] Announces:\n \t [message]" + log_admin("Announce: [key_name(usr)] : [message]") + +/obj/admins/proc/toggleooc() + set category = "Server" + set desc="Toggle dis bitch" + set name="Toggle OOC" + ooc_allowed = !( ooc_allowed ) + if (ooc_allowed) + world << "The OOC channel has been globally enabled!" + else + world << "The OOC channel has been globally disabled!" + log_admin("[key_name(usr)] toggled OOC.") + message_admins("[key_name_admin(usr)] toggled OOC.", 1) + +/obj/admins/proc/toggleoocdead() + set category = "Server" + set desc="Toggle dis bitch" + set name="Toggle Dead OOC" + dooc_allowed = !( dooc_allowed ) + + log_admin("[key_name(usr)] toggled OOC.") + message_admins("[key_name_admin(usr)] toggled Dead OOC.", 1) + +/obj/admins/proc/toggletraitorscaling() + set category = "Server" + set desc="Toggle traitor scaling" + set name="Toggle Traitor Scaling" + traitor_scaling = !traitor_scaling + log_admin("[key_name(usr)] toggled Traitor Scaling to [traitor_scaling].") + message_admins("[key_name_admin(usr)] toggled Traitor Scaling [traitor_scaling ? "on" : "off"].", 1) + +/obj/admins/proc/startnow() + set category = "Server" + set desc="Start the round RIGHT NOW" + set name="Start Now" + if(!ticker) + alert("Unable to start the game as it is not set up.") + return + if(ticker.current_state == GAME_STATE_PREGAME) + ticker.current_state = GAME_STATE_SETTING_UP + log_admin("[usr.key] has started the game.") + message_admins("[usr.key] has started the game.") + return 1 + else + alert("Game has already started you fucking jerk, stop spamming up the chat :ARGH:") + return 0 + +/obj/admins/proc/toggleenter() + set category = "Server" + set desc="People can't enter" + set name="Toggle Entering" + enter_allowed = !( enter_allowed ) + if (!( enter_allowed )) + world << "New players may no longer enter the game." + else + world << "New players may now enter the game." + log_admin("[key_name(usr)] toggled new player game entering.") + message_admins("\blue [key_name_admin(usr)] toggled new player game entering.", 1) + world.update_status() + +/obj/admins/proc/toggleAI() + set category = "Server" + set desc="People can't be AI" + set name="Toggle AI" + config.allow_ai = !( config.allow_ai ) + if (!( config.allow_ai )) + world << "The AI job is no longer chooseable." + else + world << "The AI job is chooseable now." + log_admin("[key_name(usr)] toggled AI allowed.") + world.update_status() + +/obj/admins/proc/toggleaban() + set category = "Server" + set desc="Respawn basically" + set name="Toggle Respawn" + abandon_allowed = !( abandon_allowed ) + if (abandon_allowed) + world << "You may now respawn." + else + world << "You may no longer respawn :(" + message_admins("\blue [key_name_admin(usr)] toggled respawn to [abandon_allowed ? "On" : "Off"].", 1) + log_admin("[key_name(usr)] toggled respawn to [abandon_allowed ? "On" : "Off"].") + world.update_status() + +/obj/admins/proc/toggle_aliens() + set category = "Server" + set desc="Toggle alien mobs" + set name="Toggle Aliens" + aliens_allowed = !aliens_allowed + log_admin("[key_name(usr)] toggled Aliens to [aliens_allowed].") + message_admins("[key_name_admin(usr)] toggled Aliens [aliens_allowed ? "on" : "off"].", 1) + +/obj/admins/proc/toggle_space_ninja() + set category = "Server" + set desc="Toggle space ninjas spawning." + set name="Toggle Space Ninjas" + toggle_space_ninja = !toggle_space_ninja + log_admin("[key_name(usr)] toggled Space Ninjas to [toggle_space_ninja].") + message_admins("[key_name_admin(usr)] toggled Space Ninjas [toggle_space_ninja ? "on" : "off"].", 1) + +/obj/admins/proc/delay() + set category = "Server" + set desc="Delay the game start" + set name="Delay" + if (!ticker || ticker.current_state != GAME_STATE_PREGAME) + return alert("Too late... The game has already started!", null, null, null, null, null) + going = !( going ) + if (!( going )) + world << "The game start has been delayed." + log_admin("[key_name(usr)] delayed the game.") + else + world << "The game will start soon." + log_admin("[key_name(usr)] removed the delay.") + +/obj/admins/proc/adjump() + set category = "Server" + set desc="Toggle admin jumping" + set name="Toggle Jump" + config.allow_admin_jump = !(config.allow_admin_jump) + message_admins("\blue Toggled admin jumping to [config.allow_admin_jump].") + +/obj/admins/proc/adspawn() + set category = "Server" + set desc="Toggle admin spawning" + set name="Toggle Spawn" + config.allow_admin_spawning = !(config.allow_admin_spawning) + message_admins("\blue Toggled admin item spawning to [config.allow_admin_spawning].") + +/obj/admins/proc/adrev() + set category = "Server" + set desc="Toggle admin revives" + set name="Toggle Revive" + config.allow_admin_rev = !(config.allow_admin_rev) + message_admins("\blue Toggled reviving to [config.allow_admin_rev].") + +/obj/admins/proc/immreboot() + set category = "Server" + set desc="Reboots the server post haste" + set name="Immediate Reboot" + if( alert("Reboot server?",,"Yes","No") == "No") + return + world << "\red Rebooting world! \blue Initiated by [usr.client.stealth ? "Admin" : usr.key]!" + log_admin("[key_name(usr)] initiated an immediate reboot.") + + feedback_set_details("end_error","immediate admin reboot - by [usr.key] [usr.client.stealth ? "(stealth)" : ""]") + + if(blackbox) + blackbox.save_all_data_to_sql() + + world.Reboot() + +/client/proc/deadchat() + set category = "Admin" + set desc="Toggles Deadchat Visibility" + set name="Deadchat Visibility" + if(deadchat == 0) + deadchat = 1 + usr << "Deadchat turned on" + else + deadchat = 0 + usr << "Deadchat turned off" + +/client/proc/toggleprayers() + set category = "Admin" + set desc="Toggles Prayer Visibility" + set name="Prayer Visibility" + if(seeprayers == 0) + seeprayers = 1 + usr << "Prayer visibility turned on" + else + seeprayers = 0 + usr << "Prayer visibility turned off" + +/obj/admins/proc/unprison(var/mob/M in world) + set category = "Admin" + set name = "Unprison" + if (M.z == 2) + if (config.allow_admin_jump) + M.loc = pick(latejoin) + message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]", 1) + log_admin("[key_name(usr)] has unprisoned [key_name(M)]") + else + alert("Admin jumping disabled") + else + alert("[M.name] is not prisoned.") + +////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS + +/proc/is_special_character(mob/M as mob) // returns 1 for specail characters and 2 for heroes of gamemode + if(!ticker || !ticker.mode) + return 0 + if (!istype(M)) + return 0 + if((M.mind in ticker.mode.head_revolutionaries) || (M.mind in ticker.mode.revolutionaries)) + if (ticker.mode.config_tag == "revolution") + return 2 + return 1 + if(M.mind in ticker.mode.cult) + if (ticker.mode.config_tag == "cult") + return 2 + return 1 + if(M.mind in ticker.mode.malf_ai) + if (ticker.mode.config_tag == "malfunction") + return 2 + return 1 + if(M.mind in ticker.mode.syndicates) + if (ticker.mode.config_tag == "nuclear") + return 2 + return 1 + if(M.mind in ticker.mode.wizards) + if (ticker.mode.config_tag == "wizard") + return 2 + return 1 + if(M.mind in ticker.mode.changelings) + if (ticker.mode.config_tag == "changeling") + return 2 + return 1 + + for(var/datum/disease/D in M.viruses) + if(istype(D, /datum/disease/jungle_fever)) + if (ticker.mode.config_tag == "monkey") + return 2 + return 1 + if(isrobot(M)) + var/mob/living/silicon/robot/R = M + if(R.emagged) + return 1 + if(M.mind&&M.mind.special_role)//If they have a mind and special role, they are some type of traitor or antagonist. + return 1 + + return 0 + +/* +/obj/admins/proc/get_sab_desc(var/target) + switch(target) + if(1) + return "Destroy at least 70% of the plasma canisters on the station" + if(2) + return "Destroy the AI" + if(3) + var/count = 0 + for(var/mob/living/carbon/monkey/Monkey in world) + if(Monkey.z == 1) + count++ + return "Kill all [count] of the monkeys on the station" + if(4) + return "Cut power to at least 80% of the station" + else + return "Error: Invalid sabotage target: [target]" +*/ +/obj/admins/proc/spawn_atom(var/object as text) + set category = "Debug" + set desc= "(atom path) Spawn an atom" + set name= "Spawn" + + if(usr.client.holder.level >= 5) + var/list/types = typesof(/atom) + + var/list/matches = new() + + for(var/path in types) + if(findtext("[path]", object)) + matches += path + + if(matches.len==0) + return + + var/chosen + if(matches.len==1) + chosen = matches[1] + else + chosen = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches + if(!chosen) + return + + new chosen(usr.loc) + + log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])") + + else + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return + + +/obj/admins/proc/show_traitor_panel(var/mob/M in world) + set category = "Admin" + set desc = "Edit mobs's memory and role" + set name = "Show Traitor Panel" + + if (!M.mind) + usr << "Sorry, this mob has no mind!" + return + M.mind.edit_memory() + + +/obj/admins/proc/toggletintedweldhelmets() + set category = "Debug" + set desc="Reduces view range when wearing welding helmets" + set name="Toggle tinted welding helmes" + tinted_weldhelh = !( tinted_weldhelh ) + if (tinted_weldhelh) + world << "The tinted_weldhelh has been enabled!" + else + world << "The tinted_weldhelh has been disabled!" + log_admin("[key_name(usr)] toggled tinted_weldhelh.") + message_admins("[key_name_admin(usr)] toggled tinted_weldhelh.", 1) + +/obj/admins/proc/toggleguests() + set category = "Server" + set desc="Guests can't enter" + set name="Toggle guests" + guests_allowed = !( guests_allowed ) + if (!( guests_allowed )) + world << "Guests may no longer enter the game." + else + world << "Guests may now enter the game." + log_admin("[key_name(usr)] toggled guests game entering [guests_allowed?"":"dis"]allowed.") + message_admins("\blue [key_name_admin(usr)] toggled guests game entering [guests_allowed?"":"dis"]allowed.", 1) + + + +/obj/admins/proc/view_txt_log() + set category = "Admin" + set desc="Shows todays server log in new window" + set name="Show Server Log" + var/path = "data/logs/[time2text(world.realtime,"YYYY")]/[time2text(world.realtime,"MM")]-[time2text(world.realtime,"Month")]/[time2text(world.realtime,"DD")]-[time2text(world.realtime,"Day")].log" + var/output = {" + + [time2text(world.realtime,"Day, MMM DD, YYYY")] - Log + + +
    +						[file2text(path)]
    +						
    + + "} + usr << browse(output,"window=server_logfile") + onclose(usr,"server_logfile") + return + +/obj/admins/proc/view_atk_log() + set category = "Admin" + set desc="Shows todays server attack log in new window" + set name="Show Server Attack Log" + var/path = "data/logs/[time2text(world.realtime,"YYYY")]/[time2text(world.realtime,"MM")]-[time2text(world.realtime,"Month")]/[time2text(world.realtime,"DD")]-[time2text(world.realtime,"Day")] Attack.log" + var/output = {" + + [time2text(world.realtime,"Day, MMM DD, YYYY")] - Attack Log + + +
    +						[file2text(path)]
    +						
    + + "} + usr << browse(output,"window=server_logfile") + onclose(usr,"server_logfile") + return + +/client/proc/unjobban_panel() + set name = "Unjobban Panel" + set category = "Admin" + if (src.holder) + src.holder.unjobbanpanel() + return + + +// +// +//ALL DONE +//********************************************************************************************************* +//TO-DO: +// +// + + +/**********************Administration Shuttle**************************/ + +var/admin_shuttle_location = 0 // 0 = centcom 13, 1 = station + +proc/move_admin_shuttle() + var/area/fromArea + var/area/toArea + if (admin_shuttle_location == 1) + fromArea = locate(/area/shuttle/administration/station) + toArea = locate(/area/shuttle/administration/centcom) + else + fromArea = locate(/area/shuttle/administration/centcom) + toArea = locate(/area/shuttle/administration/station) + fromArea.move_contents_to(toArea) + if (admin_shuttle_location) + admin_shuttle_location = 0 + else + admin_shuttle_location = 1 + return + +/**********************Centcom Ferry**************************/ + +var/ferry_location = 0 // 0 = centcom , 1 = station + +proc/move_ferry() + var/area/fromArea + var/area/toArea + if (ferry_location == 1) + fromArea = locate(/area/shuttle/transport1/station) + toArea = locate(/area/shuttle/transport1/centcom) + else + fromArea = locate(/area/shuttle/transport1/centcom) + toArea = locate(/area/shuttle/transport1/station) + fromArea.move_contents_to(toArea) + if (ferry_location) + ferry_location = 0 + else + ferry_location = 1 + return + +/**********************Alien ship**************************/ + +var/alien_ship_location = 1 // 0 = base , 1 = mine + +proc/move_alien_ship() + var/area/fromArea + var/area/toArea + if (alien_ship_location == 1) + fromArea = locate(/area/shuttle/alien/mine) + toArea = locate(/area/shuttle/alien/base) + else + fromArea = locate(/area/shuttle/alien/base) + toArea = locate(/area/shuttle/alien/mine) + fromArea.move_contents_to(toArea) + if (alien_ship_location) + alien_ship_location = 0 + else + alien_ship_location = 1 + return \ No newline at end of file diff --git a/code/modules/admin/new/admin_verbs.dm b/code/modules/admin/new/admin_verbs.dm new file mode 100644 index 0000000000..bacbe11010 --- /dev/null +++ b/code/modules/admin/new/admin_verbs.dm @@ -0,0 +1,797 @@ +//GUYS REMEMBER TO ADD A += to UPDATE_ADMINS +//AND A -= TO CLEAR_ADMIN_VERBS + + + +//Some verbs that are still in the code but not used atm + // Debug +// verbs += /client/proc/radio_report //for radio debugging dont think its been used in a very long time +// verbs += /client/proc/fix_next_move //has not been an issue in a very very long time + + // Mapping helpers added via enable_debug_verbs verb +// verbs += /client/proc/do_not_use_these +// verbs += /client/proc/camera_view +// verbs += /client/proc/sec_camera_report +// verbs += /client/proc/intercom_view +// verbs += /client/proc/air_status //Air things +// verbs += /client/proc/Cell //More air things + +/client/proc/update_admins(var/rank) + + if(!holder) + holder = new /obj/admins(src) + + holder.rank = rank + + if(!holder.state) + var/state = alert("Which state do you want the admin to begin in?", "Admin-state", "Play", "Observe", "Neither") + if(state == "Play") + holder.state = 1 + admin_play() + return + else if(state == "Observe") + holder.state = 2 + admin_observe() + return + else + del(holder) + return + + switch (rank) + if ("Game Master") + holder.level = 6 + + if ("Senior Game Admin") + holder.level = 5 + + if ("Game Admin") + holder.level = 4 + + if ("Secondary Game Admin") + holder.level = 3 + + if ("Trial Admin") + holder.level = 2 + if(holder.state == 2) // if observing + verbs += /client/proc/debug_variables + verbs += /client/proc/cmd_modify_ticker_variables + verbs += /client/proc/toggle_view_range + verbs += /client/proc/Getmob + verbs += /client/proc/Getkey + verbs += /client/proc/sendmob + verbs += /client/proc/Jump + verbs += /client/proc/jumptokey + verbs += /client/proc/jumptomob + verbs += /client/proc/jumptoturf + verbs += /client/proc/jumptocoord + verbs += /client/proc/cmd_admin_delete + verbs += /client/proc/cmd_admin_add_freeform_ai_law + verbs += /client/proc/cmd_admin_rejuvenate + verbs += /client/proc/cmd_admin_drop_everything + //verbs += /client/proc/cmd_modify_object_variables --Merged with view variables + + if ("Temporary Admin") + holder.level = 1 + if(holder.state == 2) // if observing + verbs += /client/proc/debug_variables + verbs += /client/proc/cmd_modify_ticker_variables + verbs += /client/proc/toggle_view_range + verbs += /client/proc/Getmob + verbs += /client/proc/Getkey + verbs += /client/proc/sendmob + verbs += /client/proc/Jump + verbs += /client/proc/jumptokey + verbs += /client/proc/jumptomob + verbs += /client/proc/jumptoturf + verbs += /client/proc/jumptocoord + verbs += /client/proc/cmd_admin_delete + verbs += /client/proc/cmd_admin_add_freeform_ai_law + verbs += /client/proc/cmd_admin_rejuvenate + verbs += /client/proc/cmd_admin_drop_everything + //verbs += /client/proc/cmd_modify_object_variables --Merged with view variables + + if ("Moderator") + holder.level = 0 + + if ("Admin Observer") + holder.level = -1 + + if ("Banned") + holder.level = -2 + del(src) + return + + else + del(holder) + return + + if (holder) //THE BELOW handles granting powers. The above is for special cases only! + holder.owner = src + + //Admin Observer + if (holder.level >= -1) + verbs += /client/proc/cmd_admin_say + verbs += /client/proc/cmd_admin_gib_self + verbs += /client/proc/deadmin_self + else return + + //Moderator + if (holder.level >= 0) + verbs += /obj/admins/proc/announce + verbs += /obj/admins/proc/startnow + verbs += /obj/admins/proc/toggleAI //Toggle the AI + verbs += /obj/admins/proc/toggleenter //Toggle enterting + verbs += /obj/admins/proc/toggleguests //Toggle guests entering + verbs += /obj/admins/proc/toggleooc //toggle ooc + verbs += /obj/admins/proc/toggleoocdead //toggle ooc for dead/unc + verbs += /obj/admins/proc/voteres //toggle votes + verbs += /obj/admins/proc/vmode + verbs += /obj/admins/proc/votekill + verbs += /obj/admins/proc/show_player_panel + verbs += /client/proc/deadchat //toggles deadchat + verbs += /client/proc/cmd_admin_mute + verbs += /client/proc/cmd_admin_pm_context + verbs += /client/proc/cmd_admin_pm_panel + verbs += /client/proc/cmd_admin_subtle_message + verbs += /client/proc/warn + verbs += /client/proc/dsay + verbs += /client/proc/admin_play + verbs += /client/proc/admin_observe + verbs += /client/proc/game_panel + verbs += /client/proc/player_panel + verbs += /client/proc/player_panel_new + verbs += /client/proc/unban_panel + verbs += /client/proc/jobbans + verbs += /client/proc/unjobban_panel + verbs += /client/proc/voting + verbs += /client/proc/hide_verbs + verbs += /client/proc/general_report + verbs += /client/proc/air_report + verbs += /client/proc/deadmin_self + //verbs += /client/proc/cmd_admin_prison --Merged with player panel + //verbs += /obj/admins/proc/unprison --Merged with player panel + else return + + //Temporary Admin + if (holder.level >= 1) + deadchat = 1 + seeprayers = 1 + + verbs += /obj/admins/proc/toggleaban //abandon mob + verbs += /obj/admins/proc/show_traitor_panel + verbs += /client/proc/cmd_admin_remove_plasma + verbs += /client/proc/admin_call_shuttle + verbs += /client/proc/admin_cancel_shuttle + verbs += /client/proc/cmd_admin_dress + verbs += /client/proc/respawn_character + verbs += /client/proc/spawn_xeno + verbs += /client/proc/toggleprayers + verbs += /client/proc/deadmin_self + verbs += /client/proc/tension_report + verbs += /client/proc/toggleadminhelpsound + verbs += /client/proc/cmd_admin_add_random_ai_law + verbs += /client/proc/secrets + verbs += /client/proc/play_sound + verbs += /client/proc/stealth + verbs += /obj/admins/proc/delay //game start delay + verbs += /obj/admins/proc/immreboot //immediate reboot + verbs += /obj/admins/proc/restart //restart + verbs += /client/proc/cmd_admin_check_contents + verbs += /client/proc/cmd_admin_create_centcom_report + verbs += /client/proc/toggle_hear_deadcast + verbs += /client/proc/toggle_hear_radio + verbs += /proc/possess + verbs += /proc/release + verbs += /client/proc/deadmin_self + else return + +/* //Trial Admin + if (holder.level >= 2) + + else return +*/ + //Secondary Game Admin + if (holder.level >= 3) + verbs += /obj/admins/proc/view_txt_log + verbs += /obj/admins/proc/view_atk_log + verbs += /obj/admins/proc/spawn_atom + verbs += /client/proc/cmd_admin_list_open_jobs + verbs += /client/proc/cmd_admin_direct_narrate + verbs += /client/proc/kill_air + verbs += /client/proc/cmd_admin_world_narrate + verbs += /client/proc/cmd_debug_del_all + verbs += /client/proc/cmd_debug_tog_aliens + verbs += /client/proc/mapload + verbs += /client/proc/check_words + verbs += /client/proc/drop_bomb + verbs += /client/proc/cmd_admin_grantfullaccess + verbs += /client/proc/cmd_admin_drop_everything + verbs += /client/proc/make_sound + verbs += /client/proc/play_local_sound + verbs += /client/proc/send_space_ninja + verbs += /client/proc/restartcontroller //Can call via aproccall --I_hate_easy_things.jpg, Mport --Agouri + verbs += /client/proc/Blobize //I need to remember to move/remove this later + verbs += /client/proc/toggle_clickproc //TODO ERRORAGE (Temporary proc while the new clickproc is being tested) + verbs += /client/proc/toggle_gravity_on + verbs += /client/proc/toggle_gravity_off + verbs += /client/proc/toggle_random_events + verbs += /obj/admins/proc/adrev //toggle admin revives + verbs += /obj/admins/proc/adspawn //toggle admin item spawning + verbs += /client/proc/debug_variables + verbs += /client/proc/cmd_modify_ticker_variables + verbs += /client/proc/Debug2 //debug toggle switch + verbs += /client/proc/toggle_view_range + verbs += /client/proc/Getmob + verbs += /client/proc/Getkey + verbs += /client/proc/sendmob + verbs += /client/proc/Jump + verbs += /client/proc/jumptokey + verbs += /client/proc/jumptomob + verbs += /client/proc/jumptoturf + verbs += /client/proc/cmd_admin_delete + verbs += /client/proc/cmd_admin_add_freeform_ai_law + verbs += /client/proc/cmd_admin_add_random_ai_law + verbs += /client/proc/cmd_admin_rejuvenate + verbs += /client/proc/hide_most_verbs + verbs += /client/proc/jumptocoord + verbs += /client/proc/cmd_modify_ticker_variables + verbs += /client/proc/deadmin_self + //verbs += /client/proc/cmd_mass_modify_object_variables --Merged with view variables + //verbs += /client/proc/cmd_admin_explosion --Merged with view variables + //verbs += /client/proc/cmd_admin_emp --Merged with view variables + //verbs += /client/proc/give_spell --Merged with view variables + //verbs += /client/proc/cmd_admin_ninjafy --Merged with view variables + //verbs += /client/proc/cmd_switch_radio --removed as tcommsat is staying + else return + + //Game Admin + if (holder.level >= 4) + verbs += /client/proc/ticklag + else return + + //Senior Game admin + if (holder.level >= 5) + verbs += /client/proc/colorooc + verbs += /client/proc/strike_team + verbs += /client/proc/everyone_random + verbs += /client/proc/only_one + verbs += /obj/admins/proc/toggle_aliens //toggle aliens + verbs += /obj/admins/proc/toggle_space_ninja //toggle ninjas + verbs += /client/proc/deadmin_self + else return + + //Game Master + if (holder.level >= 6) + verbs += /obj/admins/proc/adjump + verbs += /client/proc/callproc + verbs += /client/proc/triple_ai + verbs += /client/proc/get_admin_state + verbs += /client/proc/reload_admins + verbs += /client/proc/cmd_debug_make_powernets + verbs += /client/proc/object_talk + verbs += /client/proc/enable_debug_verbs + verbs += /client/proc/deadmin_self + else return + return + + +/client/proc/clear_admin_verbs() + deadchat = 0 + + verbs -= /obj/admins/proc/vmode + verbs -= /obj/admins/proc/votekill + verbs -= /obj/admins/proc/announce + verbs -= /obj/admins/proc/startnow + verbs -= /obj/admins/proc/toggleAI //Toggle the AI + verbs -= /obj/admins/proc/toggleenter //Toggle enterting + verbs -= /obj/admins/proc/toggleguests //Toggle guests entering + verbs -= /obj/admins/proc/toggleooc //toggle ooc + verbs -= /obj/admins/proc/toggleoocdead //toggle ooc for dead/unc + verbs -= /obj/admins/proc/voteres //toggle votes + verbs -= /obj/admins/proc/delay //game start delay + verbs -= /obj/admins/proc/immreboot //immediate reboot + verbs -= /obj/admins/proc/restart //restart + verbs -= /obj/admins/proc/show_traitor_panel + verbs -= /obj/admins/proc/show_player_panel + verbs -= /obj/admins/proc/toggle_aliens //toggle aliens + verbs -= /obj/admins/proc/toggle_space_ninja //toggle ninjas + verbs -= /obj/admins/proc/adjump + verbs -= /obj/admins/proc/view_txt_log + verbs -= /obj/admins/proc/view_atk_log + verbs -= /obj/admins/proc/spawn_atom + verbs -= /obj/admins/proc/adrev //toggle admin revives + verbs -= /obj/admins/proc/adspawn //toggle admin item spawning + verbs -= /obj/admins/proc/toggleaban //abandon mob + verbs -= /client/proc/hide_verbs + verbs -= /client/proc/hide_most_verbs + verbs -= /client/proc/show_verbs + verbs -= /client/proc/colorooc + verbs -= /client/proc/triple_ai + verbs -= /client/proc/get_admin_state + verbs -= /client/proc/reload_admins + verbs -= /client/proc/kill_air + verbs -= /client/proc/cmd_debug_make_powernets + verbs -= /client/proc/object_talk + verbs -= /client/proc/strike_team + verbs -= /client/proc/cmd_admin_list_open_jobs + verbs -= /client/proc/cmd_admin_direct_narrate + verbs -= /client/proc/cmd_admin_world_narrate + verbs -= /client/proc/callproc + verbs -= /client/proc/Cell + verbs -= /client/proc/cmd_debug_del_all + verbs -= /client/proc/cmd_debug_tog_aliens + verbs -= /client/proc/ticklag + verbs -= /client/proc/mapload + verbs -= /client/proc/check_words + verbs -= /client/proc/drop_bomb + verbs -= /client/proc/cmd_admin_grantfullaccess + verbs -= /client/proc/cmd_admin_drop_everything + verbs -= /client/proc/make_sound + verbs -= /client/proc/only_one + verbs -= /client/proc/send_space_ninja + verbs -= /client/proc/debug_variables + verbs -= /client/proc/cmd_modify_ticker_variables + verbs -= /client/proc/Debug2 //debug toggle switch + verbs -= /client/proc/toggle_view_range + verbs -= /client/proc/Getmob + verbs -= /client/proc/Getkey + verbs -= /client/proc/sendmob + verbs -= /client/proc/Jump + verbs -= /client/proc/jumptokey + verbs -= /client/proc/jumptomob + verbs -= /client/proc/jumptoturf + verbs -= /client/proc/cmd_admin_add_freeform_ai_law + verbs -= /client/proc/cmd_admin_add_random_ai_law + verbs -= /client/proc/cmd_admin_rejuvenate + verbs -= /client/proc/cmd_admin_delete + verbs -= /client/proc/toggleadminhelpsound + verbs -= /client/proc/cmd_admin_remove_plasma + verbs -= /client/proc/admin_call_shuttle + verbs -= /client/proc/admin_cancel_shuttle + verbs -= /client/proc/cmd_admin_dress + verbs -= /client/proc/respawn_character + verbs -= /client/proc/spawn_xeno + verbs -= /client/proc/cmd_admin_add_random_ai_law + verbs -= /client/proc/secrets + verbs -= /client/proc/play_sound + verbs -= /client/proc/stealth + verbs -= /client/proc/cmd_admin_check_contents + verbs -= /client/proc/cmd_admin_create_centcom_report + verbs -= /client/proc/deadchat //toggles deadchat + verbs -= /client/proc/cmd_admin_mute + verbs -= /client/proc/cmd_admin_pm_context + verbs -= /client/proc/cmd_admin_pm_panel + verbs -= /client/proc/cmd_admin_say + verbs -= /client/proc/cmd_admin_subtle_message + verbs -= /client/proc/warn + verbs -= /client/proc/dsay + verbs -= /client/proc/admin_play + verbs -= /client/proc/admin_observe + verbs -= /client/proc/game_panel + verbs -= /client/proc/player_panel + verbs -= /client/proc/unban_panel + verbs -= /client/proc/jobbans + verbs -= /client/proc/unjobban_panel + verbs -= /client/proc/voting + verbs -= /client/proc/hide_verbs + verbs -= /client/proc/general_report + verbs -= /client/proc/air_report + verbs -= /client/proc/cmd_admin_say + verbs -= /client/proc/cmd_admin_gib_self + verbs -= /client/proc/restartcontroller + verbs -= /client/proc/play_local_sound + verbs -= /client/proc/enable_debug_verbs + verbs -= /client/proc/toggleprayers + verbs -= /client/proc/Blobize + verbs -= /client/proc/toggle_clickproc //TODO ERRORAGE (Temporary proc while the enw clickproc is being tested) + verbs -= /client/proc/toggle_hear_deadcast + verbs -= /client/proc/toggle_hear_radio + verbs -= /client/proc/tension_report + verbs -= /client/proc/player_panel_new + verbs -= /client/proc/toggle_gravity_on + verbs -= /client/proc/toggle_gravity_off + verbs -= /client/proc/toggle_random_events + verbs -= /client/proc/deadmin_self + verbs -= /client/proc/jumptocoord + verbs -= /client/proc/everyone_random + verbs -= /proc/possess + verbs -= /proc/release + //verbs -= /client/proc/give_spell --Merged with view variables + //verbs -= /client/proc/cmd_admin_ninjafy --Merged with view variables + //verbs -= /client/proc/cmd_modify_object_variables --Merged with view variables + //verbs -= /client/proc/cmd_admin_explosion --Merged with view variables + //verbs -= /client/proc/cmd_admin_emp --Merged with view variables + //verbs -= /client/proc/cmd_admin_godmode --Merged with view variables + //verbs -= /client/proc/cmd_admin_gib --Merged with view variables + //verbs -= /client/proc/cmd_mass_modify_object_variables --Merged with view variables + //verbs -= /client/proc/cmd_admin_attack_log --Merged with view variables + //verbs -= /proc/togglebuildmode --Merged with view variables + //verbs -= /client/proc/cmd_admin_prison --Merged with player panel + //verbs -= /obj/admins/proc/unprison --Merged with player panel + //verbs -= /client/proc/cmd_switch_radio --removed because tcommsat is staying + verbs -= /client/proc/togglebuildmodeself + return + + +/client/proc/admin_observe() + set category = "Admin" + set name = "Set Observe" + if(!holder) + alert("You are not an admin") + return + + verbs -= /client/proc/admin_play + spawn( 1200 ) + verbs += /client/proc/admin_play + var/rank = holder.rank + clear_admin_verbs() + holder.state = 2 + update_admins(rank) + if(!istype(mob, /mob/dead/observer)) + mob.adminghostize(1) + src << "\blue You are now observing" + +/client/proc/admin_play() + set category = "Admin" + set name = "Set Play" + if(!holder) + alert("You are not an admin") + return + verbs -= /client/proc/admin_observe + spawn( 1200 ) + verbs += /client/proc/admin_observe + var/rank = holder.rank + clear_admin_verbs() + holder.state = 1 + update_admins(rank) + if(istype(mob, /mob/dead/observer)) + mob:reenter_corpse() + src << "\blue You are now playing" + +/client/proc/get_admin_state() + set name = "Get Admin State" + set category = "Debug" + for(var/mob/M in world) + if(M.client && M.client.holder) + if(M.client.holder.state == 1) + src << "[M.key] is playing - [M.client.holder.state]" + else if(M.client.holder.state == 2) + src << "[M.key] is observing - [M.client.holder.state]" + else + src << "[M.key] is undefined - [M.client.holder.state]" + + +/client/proc/player_panel() + set name = "Player Panel" + set category = "Admin" + if(holder) + holder.player_panel_old() + return + +/client/proc/player_panel_new() + set name = "Player Panel-New" + set category = "Admin" + if(holder) + holder.player_panel_new() + return + +/client/proc/jobbans() + set name = "Display Job bans" + set category = "Admin" + if(holder) + holder.Jobbans() + return + +/client/proc/unban_panel() + set name = "Unban Panel" + set category = "Admin" + if(holder) + holder.unbanpanel() + return + +/client/proc/game_panel() + set name = "Game Panel" + set category = "Admin" + if(holder) + holder.Game() + return + +/client/proc/secrets() + set name = "Secrets" + set category = "Admin" + if (holder) + holder.Secrets() + return + +/client/proc/voting() + set name = "Voting" + set category = "Admin" + if (holder) + holder.Voting() + +/client/proc/colorooc() + set category = "Fun" + set name = "OOC Text Color" + ooccolor = input(src, "Please select your OOC colour.", "OOC colour") as color + return + +/client/proc/stealth() + set category = "Admin" + set name = "Stealth Mode" + if(!authenticated || !holder) + src << "Only administrators may use this command." + return + stealth = !stealth + if(stealth) + var/new_key = trim(input("Enter your desired display name.", "Fake Key", key)) + if(!new_key) + stealth = 0 + return + new_key = strip_html(new_key) + if(length(new_key) >= 26) + new_key = copytext(new_key, 1, 26) + fakekey = new_key + else + fakekey = null + log_admin("[key_name(usr)] has turned stealth mode [stealth ? "ON" : "OFF"]") + message_admins("[key_name_admin(usr)] has turned stealth mode [stealth ? "ON" : "OFF"]", 1) + +#define AUTOBATIME 10 +/client/proc/warn(var/mob/M in world) + set category = "Special Verbs" + set name = "Warn" + set desc = "Warn a player" + if(!authenticated || !holder) + src << "Only administrators may use this command." + return + if(M.client && M.client.holder && (M.client.holder.level >= holder.level)) + alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null) + return + if(!M.client.warned) + M << "\red You have been warned by an administrator. This is the only warning you will recieve." + M.client.warned = 1 + message_admins("\blue [ckey] warned [M.ckey].") + else + AddBan(M.ckey, M.computer_id, "Autobanning due to previous warn", ckey, 1, AUTOBATIME) + M << "\redYou have been autobanned by [ckey]. This is what we in the biz like to call a \"second warning\"." + M << "\red This is a temporary ban; it will automatically be removed in [AUTOBATIME] minutes." + log_admin("[ckey] warned [M.ckey], resulting in a [AUTOBATIME] minute autoban.") + ban_unban_log_save("[ckey] warned [M.ckey], resulting in a [AUTOBATIME] minute autoban.") + message_admins("\blue [ckey] warned [M.ckey], resulting in a [AUTOBATIME] minute autoban.") + feedback_inc("ban_warn",1) + + del(M.client) + + +/client/proc/drop_bomb() // Some admin dickery that can probably be done better -- TLE + set category = "Special Verbs" + set name = "Drop Bomb" + set desc = "Cause an explosion of varying strength at your location." + + var/turf/epicenter = mob.loc + var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb") + var/choice = input("What size explosion would you like to produce?") in choices + switch(choice) + if(null) + return 0 + if("Small Bomb") + explosion(epicenter, 1, 2, 3, 3) + if("Medium Bomb") + explosion(epicenter, 2, 3, 4, 4) + if("Big Bomb") + explosion(epicenter, 3, 5, 7, 5) + if("Custom Bomb") + var/devastation_range = input("Devastation range (in tiles):") as num + var/heavy_impact_range = input("Heavy impact range (in tiles):") as num + var/light_impact_range = input("Light impact range (in tiles):") as num + var/flash_range = input("Flash range (in tiles):") as num + explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range) + message_admins("\blue [ckey] creating an admin explosion at [epicenter.loc].") + +/client/proc/give_spell(mob/T as mob in world) // -- Urist + set category = "Fun" + set name = "Give Spell" + set desc = "Gives a spell to a mob." + var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spells + if(!S) return + T.spell_list += new S + +/client/proc/make_sound(var/obj/O in world) // -- TLE + set category = "Special Verbs" + set name = "Make Sound" + set desc = "Display a message to everyone who can hear the target" + if(O) + var/message = input("What do you want the message to be?", "Make Sound") as text|null + if(!message) + return + for (var/mob/V in hearers(O)) + V.show_message(message, 2) + + +/client/proc/togglebuildmodeself() + set name = "Toggle Build Mode Self" + set category = "Special Verbs" + if(src.mob) + togglebuildmode(src.mob) + + +/client/proc/toggleadminhelpsound() + set name = "Toggle Adminhelp Sound" + set category = "Admin" + sound_adminhelp = !sound_adminhelp + if(sound_adminhelp) + usr << "You will now hear a sound when adminhelps arrive" + else + usr << "You will no longer hear a sound when adminhelps arrive" + +/client/proc/object_talk(var/msg as text) // -- TLE + set category = "Special Verbs" + set name = "oSay" + set desc = "Display a message to everyone who can hear the target" + if(mob.control_object) + if(!msg) + return + for (var/mob/V in hearers(mob.control_object)) + V.show_message("[mob.control_object.name] says: \"" + msg + "\"", 2) + +/client/proc/kill_air() // -- TLE + set category = "Debug" + set name = "Kill Air" + set desc = "Toggle Air Processing" + if(kill_air) + kill_air = 0 + usr << "Enabled air processing." + else + kill_air = 1 + usr << "Disabled air processing." + +/client/proc/show_verbs() + set name = "Toggle admin verb visibility" + set category = "Admin" + src << "Restoring admin verbs back" + + var/temp = deadchat + clear_admin_verbs() + update_admins(holder.rank) + deadchat = temp + +/client/proc/toggle_clickproc() //TODO ERRORAGE (This is a temporary verb here while I test the new clicking proc) + set name = "Toggle NewClickProc" + set category = "Admin" + + if(!holder) return + using_new_click_proc = !using_new_click_proc + world << "Testing of new click proc [using_new_click_proc ? "enabled" : "disabled"]" + +/client/proc/toggle_hear_deadcast() + set name = "Toggle Hear Deadcast" + set category = "Admin" + + if(!holder) return + STFU_ghosts = !STFU_ghosts + usr << "You will now [STFU_ghosts ? "not hear" : "hear"] ghosts" + +/client/proc/toggle_hear_radio() + set name = "Toggle Hear Radio" + set category = "Admin" + + if(!holder) return + STFU_radio = !STFU_radio + usr << "You will now [STFU_radio ? "not hear" : "hear"] radio chatter from nearby radios or speakers" + +/client/proc/deadmin_self() + set name = "De-admin self" + set category = "Admin" + + if(src.holder) + if(alert("Confirm self-deadmin for the round? You can't re-admin yourself without someont promoting you.",,"Yes","No") == "Yes") + del(holder) + log_admin("[src] deadmined themself.") + message_admins("[src] deadmined themself.", 1) + src.clear_admin_verbs() + src.update_admins(null) + admins.Remove(src.ckey) + usr << "You are now a normal player." + +/client/proc/startSinglo() + set name = "Singlo Starter" + set category = "Debug" + set desc = "Starts a self-sustaining, stable singlo. This artifical singlo does not have a gravitational pull." + + for(var/obj/machinery/emitter/E in world) + if(E.anchored) + E.active = 1 + + for(var/obj/machinery/field_generator/F in world) + if(F.anchored) + F.Varedit_start = 1 + spawn(30) + for(var/obj/machinery/the_singularitygen/G in world) + if(G.anchored) + var/obj/machinery/singularity/S = new /obj/machinery/singularity(get_turf(G), 50) + spawn(0) + del(G) + S.energy = 1750 + S.current_size = 7 + S.icon = '224x224.dmi' + S.icon_state = "singularity_s7" + S.pixel_x = -96 + S.pixel_y = -96 + S.grav_pull = 0 + //S.consume_range = 3 + S.dissipate = 0 + //S.dissipate_delay = 10 + //S.dissipate_track = 0 + //S.dissipate_strength = 10 + + for(var/obj/machinery/power/rad_collector/Rad in world) + if(Rad.anchored) + if(!Rad.P) + var/obj/item/weapon/tank/plasma/Plasma = new/obj/item/weapon/tank/plasma(Rad) + Plasma.air_contents.toxins = 70 + Rad.drainratio = 0 + Rad.P = Plasma + Plasma.loc = Rad + + if(!Rad.active) + Rad.toggle_power() + + for(var/obj/machinery/power/smes/SMES in world) + if(SMES.anchored) + SMES.chargemode = 1 + +/client/proc/hide_most_verbs()//Allows you to keep some functionality while hiding some verbs + set name = "Toggle most admin verb visibility" + set category = "Admin" + src << "Hiding most admin verbs" + + var/temp = deadchat + clear_admin_verbs() + deadchat = temp + verbs -= /client/proc/hide_verbs + verbs -= /client/proc/hide_most_verbs + verbs += /client/proc/show_verbs + + if(holder.level >= 5)//Senior Game Admin******************************************************************** + verbs += /client/proc/colorooc + + if(holder.level >= 3)//Secondary Game admin******************************************************************** + verbs += /client/proc/debug_variables + //verbs += /client/proc/cmd_modify_object_variables --merged with view vairiables + verbs += /client/proc/Jump + verbs += /client/proc/jumptoturf + verbs += /client/proc/togglebuildmodeself + + verbs += /client/proc/dsay + verbs += /client/proc/admin_play + verbs += /client/proc/admin_observe + verbs += /client/proc/game_panel + verbs += /client/proc/player_panel + verbs += /client/proc/cmd_admin_subtle_message + verbs += /client/proc/cmd_admin_pm_context + verbs += /client/proc/cmd_admin_pm_panel + verbs += /client/proc/cmd_admin_gib_self + + verbs += /client/proc/deadchat //toggles deadchat + verbs += /obj/admins/proc/toggleooc //toggle ooc + verbs += /client/proc/cmd_admin_say//asay + verbs += /client/proc/toggleadminhelpsound + return + + +/client/proc/hide_verbs() + set name = "Toggle admin verb visibility" + set category = "Admin" + src << "Hiding almost all admin verbs" + + var/temp = deadchat + clear_admin_verbs() + deadchat = temp + verbs -= /client/proc/hide_verbs + verbs -= /client/proc/hide_most_verbs + verbs += /client/proc/show_verbs + + verbs += /client/proc/deadchat //toggles deadchat + verbs += /obj/admins/proc/toggleooc //toggle ooc + verbs += /client/proc/cmd_admin_say//asay + return diff --git a/code/modules/admin/new/verbs/modifyvariables.dm b/code/modules/admin/new/verbs/modifyvariables.dm new file mode 100644 index 0000000000..d1be847c9c --- /dev/null +++ b/code/modules/admin/new/verbs/modifyvariables.dm @@ -0,0 +1,502 @@ +var/list/forbidden_varedit_object_types = list( + /obj/admins, //Admins editing their own admin-power object? Yup, sounds like a good idea. + /obj/machinery/blackbox_recorder, //Prevents people messing with feedback gathering + /datum/feedback_variable //Prevents people messing with feedback gathering + ) + +/client/proc/cmd_modify_object_variables(obj/O as obj|mob|turf|area in world) + set category = "Debug" + set name = "Edit Variables" + set desc="(target) Edit a target item's variables" + src.modify_variables(O) + +/client/proc/cmd_modify_ticker_variables() + set category = "Debug" + set name = "Edit Ticker Variables" + + if (ticker == null) + src << "Game hasn't started yet." + else + src.modify_variables(ticker) + +/client/proc/mod_list_add_ass() //haha + + var/class = "text" + if(src.holder && src.holder.marked_datum) + class = input("What kind of variable?","Variable Type") as null|anything in list("text", + "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") + else + class = input("What kind of variable?","Variable Type") as null|anything in list("text", + "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") + + if(!class) + return + + if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") + class = "marked datum" + + var/var_value = null + + switch(class) + + if("text") + var_value = input("Enter new text:","Text") as null|text + + if("num") + var_value = input("Enter new number:","Num") as null|num + + if("type") + var_value = input("Enter type:","Type") as null|anything in typesof(/obj,/mob,/area,/turf) + + if("reference") + var_value = input("Select reference:","Reference") as null|mob|obj|turf|area in world + + if("mob reference") + var_value = input("Select reference:","Reference") as null|mob in world + + if("file") + var_value = input("Pick file:","File") as null|file + + if("icon") + var_value = input("Pick icon:","Icon") as null|icon + + if("marked datum") + var_value = holder.marked_datum + + if(!var_value) return + + return var_value + + +/client/proc/mod_list_add(var/list/L) + + var/class = "text" + if(src.holder && src.holder.marked_datum) + class = input("What kind of variable?","Variable Type") as null|anything in list("text", + "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") + else + class = input("What kind of variable?","Variable Type") as null|anything in list("text", + "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") + + if(!class) + return + + if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") + class = "marked datum" + + var/var_value = null + + switch(class) + + if("text") + var_value = input("Enter new text:","Text") as text + + if("num") + var_value = input("Enter new number:","Num") as num + + if("type") + var_value = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf) + + if("reference") + var_value = input("Select reference:","Reference") as mob|obj|turf|area in world + + if("mob reference") + var_value = input("Select reference:","Reference") as mob in world + + if("file") + var_value = input("Pick file:","File") as file + + if("icon") + var_value = input("Pick icon:","Icon") as icon + + if("marked datum") + var_value = holder.marked_datum + + if(!var_value) return + + switch(alert("Would you like to associate a var with the list entry?",,"Yes","No")) + if("Yes") + L += var_value + L[var_value] = mod_list_add_ass() //haha + if("No") + L += var_value + +/client/proc/mod_list(var/list/L) + if(!istype(L,/list)) src << "Not a List." + + var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine", "poo", "icon", "icon_state") + + var/list/names = sortList(L) + + var/variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)" + + if(variable == "(ADD VAR)") + mod_list_add(L) + return + + if(!variable) + return + + var/default + + var/dir + + if (locked.Find(variable) && !(src.holder.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))) + return + + if(isnull(variable)) + usr << "Unable to determine variable type." + + else if(isnum(variable)) + usr << "Variable appears to be NUM." + default = "num" + dir = 1 + + else if(istext(variable)) + usr << "Variable appears to be TEXT." + default = "text" + + else if(isloc(variable)) + usr << "Variable appears to be REFERENCE." + default = "reference" + + else if(isicon(variable)) + usr << "Variable appears to be ICON." + variable = "\icon[variable]" + default = "icon" + + else if(istype(variable,/atom) || istype(variable,/datum)) + usr << "Variable appears to be TYPE." + default = "type" + + else if(istype(variable,/list)) + usr << "Variable appears to be LIST." + default = "list" + + else if(istype(variable,/client)) + usr << "Variable appears to be CLIENT." + default = "cancel" + + else + usr << "Variable appears to be FILE." + default = "file" + + usr << "Variable contains: [variable]" + if(dir) + switch(variable) + if(1) + dir = "NORTH" + if(2) + dir = "SOUTH" + if(4) + dir = "EAST" + if(8) + dir = "WEST" + if(5) + dir = "NORTHEAST" + if(6) + dir = "SOUTHEAST" + if(9) + dir = "NORTHWEST" + if(10) + dir = "SOUTHWEST" + else + dir = null + + if(dir) + usr << "If a direction, direction is: [dir]" + + var/class = "text" + if(src.holder && src.holder.marked_datum) + class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", + "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") + else + class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", + "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") + + if(!class) + return + + if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") + class = "marked datum" + + switch(class) + + if("list") + mod_list(variable) + + if("restore to default") + variable = initial(variable) + + if("edit referenced object") + modify_variables(variable) + + if("(DELETE FROM LIST)") + L -= variable + return + + if("text") + variable = input("Enter new text:","Text",\ + variable) as text + + if("num") + variable = input("Enter new number:","Num",\ + variable) as num + + if("type") + variable = input("Enter type:","Type",variable) \ + in typesof(/obj,/mob,/area,/turf) + + if("reference") + variable = input("Select reference:","Reference",\ + variable) as mob|obj|turf|area in world + + if("mob reference") + variable = input("Select reference:","Reference",\ + variable) as mob in world + + if("file") + variable = input("Pick file:","File",variable) \ + as file + + if("icon") + variable = input("Pick icon:","Icon",variable) \ + as icon + + if("marked datum") + variable = holder.marked_datum + +/client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) + var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "urine", "poo", "icon", "icon_state") + + if(!src.authenticated || !src.holder) + src << "Only administrators may use this command." + return + + for(var/p in forbidden_varedit_object_types) + if( istype(O,p) ) + usr << "\red It is forbidden to edit this object's variables." + return + + var/class + var/variable + var/var_value + + if(param_var_name) + if(!param_var_name in O.vars) + src << "A variable with this name ([param_var_name]) doesn't exist in this atom ([O])" + return + + if (param_var_name == "holder" && holder.rank != "Game Master") + src << "No. Stop being stupid." + return + + if (locked.Find(param_var_name) && !(src.holder.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))) + src << "Editing this variable requires you to be a game master or game admin." + return + + variable = param_var_name + + var_value = O.vars[variable] + + if(autodetect_class) + if(isnull(var_value)) + usr << "Unable to determine variable type." + class = null + autodetect_class = null + else if(isnum(var_value)) + usr << "Variable appears to be NUM." + class = "num" + dir = 1 + + else if(istext(var_value)) + usr << "Variable appears to be TEXT." + class = "text" + + else if(isloc(var_value)) + usr << "Variable appears to be REFERENCE." + class = "reference" + + else if(isicon(var_value)) + usr << "Variable appears to be ICON." + var_value = "\icon[var_value]" + class = "icon" + + else if(istype(var_value,/atom) || istype(var_value,/datum)) + usr << "Variable appears to be TYPE." + class = "type" + + else if(istype(var_value,/list)) + usr << "Variable appears to be LIST." + class = "list" + + else if(istype(var_value,/client)) + usr << "Variable appears to be CLIENT." + class = "cancel" + + else + usr << "Variable appears to be FILE." + class = "file" + + else + + var/list/names = list() + for (var/V in O.vars) + names += V + + names = sortList(names) + + variable = input("Which var?","Var") as null|anything in names + if(!variable) + return + var_value = O.vars[variable] + + if (locked.Find(variable) && !(src.holder.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))) + return + + if (variable == "holder" && holder.rank != "Game Master") //Hotfix, a bit ugly but that exploit has been there for ages and now somebody just had to go and tell everyone of it bluh bluh - U + return + + if(!autodetect_class) + + var/dir + var/default + if(isnull(var_value)) + usr << "Unable to determine variable type." + + else if(isnum(var_value)) + usr << "Variable appears to be NUM." + default = "num" + dir = 1 + + else if(istext(var_value)) + usr << "Variable appears to be TEXT." + default = "text" + + else if(isloc(var_value)) + usr << "Variable appears to be REFERENCE." + default = "reference" + + else if(isicon(var_value)) + usr << "Variable appears to be ICON." + var_value = "\icon[var_value]" + default = "icon" + + else if(istype(var_value,/atom) || istype(var_value,/datum)) + usr << "Variable appears to be TYPE." + default = "type" + + else if(istype(var_value,/list)) + usr << "Variable appears to be LIST." + default = "list" + + else if(istype(var_value,/client)) + usr << "Variable appears to be CLIENT." + default = "cancel" + + else + usr << "Variable appears to be FILE." + default = "file" + + usr << "Variable contains: [var_value]" + if(dir) + switch(var_value) + if(1) + dir = "NORTH" + if(2) + dir = "SOUTH" + if(4) + dir = "EAST" + if(8) + dir = "WEST" + if(5) + dir = "NORTHEAST" + if(6) + dir = "SOUTHEAST" + if(9) + dir = "NORTHWEST" + if(10) + dir = "SOUTHWEST" + else + dir = null + if(dir) + usr << "If a direction, direction is: [dir]" + + if(src.holder && src.holder.marked_datum) + class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", + "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") + else + class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", + "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") + + if(!class) + return + + var/original_name + + if (!istype(O, /atom)) + original_name = "\ref[O] ([O])" + else + original_name = O:name + + if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") + class = "marked datum" + + switch(class) + + if("list") + mod_list(O.vars[variable]) + return + + if("restore to default") + O.vars[variable] = initial(O.vars[variable]) + + if("edit referenced object") + return .(O.vars[variable]) + + if("text") + var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text + if(var_new==null) return + O.vars[variable] = var_new + + if("num") + if(variable=="luminosity") + var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num + if(var_new == null) return + O.sd_SetLuminosity(var_new) + else + var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num + if(var_new==null) return + O.vars[variable] = var_new + + if("type") + var/var_new = input("Enter type:","Type",O.vars[variable]) as null|anything in typesof(/obj,/mob,/area,/turf) + if(var_new==null) return + O.vars[variable] = var_new + + if("reference") + var/var_new = input("Select reference:","Reference",O.vars[variable]) as null|mob|obj|turf|area in world + if(var_new==null) return + O.vars[variable] = var_new + + if("mob reference") + var/var_new = input("Select reference:","Reference",O.vars[variable]) as null|mob in world + if(var_new==null) return + O.vars[variable] = var_new + + if("file") + var/var_new = input("Pick file:","File",O.vars[variable]) as null|file + if(var_new==null) return + O.vars[variable] = var_new + + if("icon") + var/var_new = input("Pick icon:","Icon",O.vars[variable]) as null|icon + if(var_new==null) return + O.vars[variable] = var_new + + if("marked datum") + O.vars[variable] = holder.marked_datum + + log_admin("[key_name(src)] modified [original_name]'s [variable] to [O.vars[variable]]") + message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]", 1) + diff --git a/code/modules/admin/new/verbs/playsound.dm b/code/modules/admin/new/verbs/playsound.dm new file mode 100644 index 0000000000..79062a0961 --- /dev/null +++ b/code/modules/admin/new/verbs/playsound.dm @@ -0,0 +1,98 @@ +/client/proc/play_sound(S as sound) + set category = "Fun" + set name = "Play Global Sound" + + //if(Debug2) + if(!src.authenticated || !src.holder) + src << "Only administrators may use this command." + return + + var/sound/uploaded_sound = sound(S,0,1,0) + uploaded_sound.channel = 777 + uploaded_sound.priority = 255 + uploaded_sound.wait = 1 + + if(src.holder.rank == "Game Master" || src.holder.rank == "Senior Game Admin" || src.holder.rank == "Game Admin" || src.holder.rank == "Secondary Game Admin") + log_admin("[key_name(src)] played sound [S]") + message_admins("[key_name_admin(src)] played sound [S]", 1) + for(var/mob/M in world) + if(M.client) + if(M.client.midis) + M << uploaded_sound + else + if(usr.client.canplaysound) + usr.client.canplaysound = 0 + log_admin("[key_name(src)] played sound [S]") + message_admins("[key_name_admin(src)] played sound [S]", 1) + for(var/mob/M in world) + if(M.client) + if(M.client.midis) + M << uploaded_sound + else + usr << "You already used up your jukebox monies this round!" + del(uploaded_sound) + + +/client/proc/play_local_sound(S as sound) + set category = "Fun" + set name = "Play Local Sound" + + if(!src.authenticated || !src.holder) + src << "Only administrators may use this command." + return + + if(src.holder.rank == "Game Master" || src.holder.rank == "Senior Game Admin" || src.holder.rank == "Game Admin" || src.holder.rank == "Secondary Game Admin") + log_admin("[key_name(src)] played a local sound [S]") + message_admins("[key_name_admin(src)] played a local sound [S]", 1) + playsound(get_turf_loc(src.mob), S, 50, 0, 0) + return + + +/* +/client/proc/cuban_pete() + set category = "Fun" + set name = "Cuban Pete Time" + + message_admins("[key_name_admin(usr)] has declared Cuban Pete Time!", 1) + for(var/mob/M in world) + if(M.client) + if(M.client.midis) + M << 'cubanpetetime.ogg' + + for(var/mob/living/carbon/human/CP in world) + if(CP.real_name=="Cuban Pete" && CP.key!="Rosham") + CP << "Your body can't contain the rhumba beat" + CP.gib(1) + + +/client/proc/bananaphone() + set category = "Fun" + set name = "Banana Phone" + + message_admins("[key_name_admin(usr)] has activated Banana Phone!", 1) + for(var/mob/M in world) + if(M.client) + if(M.client.midis) + M << 'bananaphone.ogg' + + +client/proc/space_asshole() + set category = "Fun" + set name = "Space Asshole" + + message_admins("[key_name_admin(usr)] has played the Space Asshole Hymn.", 1) + for(var/mob/M in world) + if(M.client) + if(M.client.midis) + M << 'space_asshole.ogg' + + +client/proc/honk_theme() + set category = "Fun" + set name = "Honk" + + message_admins("[key_name_admin(usr)] has creeped everyone out with Blackest Honks.", 1) + for(var/mob/M in world) + if(M.client) + if(M.client.midis) + M << 'honk_theme.ogg'*/ diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index 3722cf009c..80897df1c3 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -20,6 +20,7 @@ "} usr << browse(output,"window=generalreport") + //feedback_add_details("admin_verb","SGR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! air_report() set category = "Debug" @@ -62,6 +63,7 @@ "} usr << browse(output,"window=airreport") + //feedback_add_details("admin_verb","SAR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! air_status(turf/target as turf) set category = "Debug" @@ -80,6 +82,7 @@ usr << "\blue @[target.x],[target.y] ([GM.group_multiplier]): O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] w [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("\red BURNING"):(null)]" for(var/datum/gas/trace_gas in GM.trace_gases) usr << "[trace_gas.type]: [trace_gas.moles]" + //feedback_add_details("admin_verb","DAST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! fix_next_move() set category = "Debug" @@ -109,6 +112,7 @@ message_admins("[key_name_admin(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [largest_move_time/10] seconds!", 1) message_admins("[key_name_admin(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!", 1) message_admins("world.time = [world.time]", 1) + //feedback_add_details("admin_verb","UFE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return radio_report() @@ -146,6 +150,7 @@ output += "    [device]
    " usr << browse(output,"window=radioreport") + //feedback_add_details("admin_verb","RR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! reload_admins() set name = "Reload Admins" @@ -175,6 +180,7 @@ var/a_lev = copytext(line, pos + 3, length(line) + 1) admins[m_key] = a_lev diary << ("ADMIN: [m_key] = [a_lev]") + //feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! jump_to_dead_group() @@ -193,8 +199,31 @@ dead_groups += group var/datum/air_group/dest_group = pick(dead_groups) usr.loc = pick(dest_group.members) + //feedback_add_details("admin_verb","JDAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return + kill_airgroup() + set name = "Kill Local Airgroup" + set desc = "Use this to allow manual manipulation of atmospherics." + set category = "Debug" + if(!holder) + src << "Only administrators may use this command." + return + + if(!air_master) + usr << "Cannot find air_system" + return + + var/turf/T = get_turf(usr) + if(istype(T, /turf/simulated)) + var/datum/air_group/AG = T:parent + AG.next_check = 30 + AG.group_processing = 0 + else + usr << "Local airgroup is unsimulated!" + //feedback_add_details("admin_verb","KLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + tension_report() set category = "Debug" set name = "Show Tension Report" @@ -207,6 +236,12 @@ alert(usr,"No players found. How the fuck are you calling this?","Tension Report") return 0 + var/numghosts = 0 + + for(var/mob/dead/observer/theghost in world) + numghosts ++ + + var/output = {"TENSION REPORT
    General Statistics
    Deaths: [tension_master.deaths]
    @@ -214,13 +249,34 @@ Explosions: [tension_master.explosions]
    Air alarms: [tension_master.air_alarms]
    Adminhelps: [tension_master.adminhelps]
    +Ghosts: [numghosts]

    Current Status
    Tension: [tension_master.score]
    +Increase Tension by 50000
    Tension per player: [tension_master.score/tension_master.get_num_players()]
    -Recommendations: not yet implemented
    +Tensioner Debug Data: R1:[tension_master.round1] R2:[tension_master.round2] R3:[tension_master.round3] R4:[tension_master.round4] ES: [tension_master.eversupressed] CD: [tension_master.cooldown]
    +Current Tensioner Status: [config.Tensioner_Active]. Toggle?
    +Recommendations: All the modes. All of them. Press all of them.

    + Make Tratiors
    + Make Changlings
    + Make Revs
    + Make Wizard (Requires Ghosts)
    + Make Cult
    + Make Nuke Team (Requires Ghosts)
    + Make Malf AI
    + Make Space Ninja (Requires Ghosts)
    + Make Aliens (Requires Ghosts)
    + Make Deathsquad (Syndicate) (Requires Ghosts)
    + Make Deathsquad (Borg) (Requires Ghosts)
    + +
    + "} - usr << browse(output,"window=tensionreport") \ No newline at end of file + for(var/game in tension_master.antagonistmodes) + output += "Points required/Probability for [game]: [tension_master.antagonistmodes[game]]
    " + usr << browse(output,"window=tensionreport;size=480x480") + feedback_add_details("admin_verb","STR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 69ffc12b83..47e6131387 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -17,6 +17,7 @@ M << "\blue \icon[cross] PRAY: [key_name(src, M)] (PP) (VV) (SM) (JMP) (CA): [msg]" usr << "Your prayers have been received by the gods." + //feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! //log_admin("HELP: [key_name(src)]: [msg]") diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 501a211db1..93914d171d 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -9,6 +9,7 @@ log_admin("[key_name(usr)] made [key_name(M)] drop everything!") message_admins("[key_name_admin(usr)] made [key_name_admin(M)] drop everything!", 1) + //feedback_add_details("admin_verb","DEVR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_prison(mob/M as mob in world) set category = "Admin" @@ -35,6 +36,7 @@ M << "\red You have been sent to the prison station!" log_admin("[key_name(usr)] sent [key_name(M)] to the prison station.") message_admins("\blue [key_name_admin(usr)] sent [key_name_admin(M)] to the prison station.", 1) + //feedback_add_details("admin_verb","PRISON") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_subtle_message(mob/M as mob in world) set category = "Special Verbs" @@ -52,10 +54,11 @@ if(usr) if (usr.client) if(usr.client.holder) - M << "\bold You hear a voice in your head... \italic [msg]" + M << "\bold You think... \italic [msg]" log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]") message_admins("\blue \bold SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]", 1) + //feedback_add_details("admin_verb","SMS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_world_narrate() // Allows administrators to fluff events a little easier -- TLE set category = "Special Verbs" @@ -72,6 +75,7 @@ world << "[msg]" log_admin("GlobalNarrate: [key_name(usr)] : [msg]") message_admins("\blue \bold GlobalNarrate: [key_name_admin(usr)] : [msg]
    ", 1) + //feedback_add_details("admin_verb","GLN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_direct_narrate(mob/M as mob in world) // Targetted narrate -- TLE set category = "Special Verbs" @@ -84,6 +88,7 @@ M << msg log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]") message_admins("\blue \bold DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]
    ", 1) + //feedback_add_details("admin_verb","DIRN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_mute(mob/M as mob in world) set category = "Special Verbs" @@ -103,6 +108,7 @@ message_admins("[key_name_admin(src)] has [(M.client.muted ? "muted" : "voiced")] [key_name_admin(M)].", 1) M << "You have been [(M.client.muted ? "muted" : "voiced")]." + //feedback_add_details("admin_verb","MUTE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_add_random_ai_law() @@ -120,6 +126,7 @@ world << sound('ionstorm.ogg') //IonStorm(0) + //feedback_add_details("admin_verb","ION") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /* Stealth spawns xenos @@ -136,6 +143,7 @@ return create_xeno() + //feedback_add_details("admin_verb","X") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return //I use this proc for respawn character too. /N @@ -406,6 +414,7 @@ Traitors and the like can also be revived with the previous role mostly intact. new_character << "You have been fully respawned. Enjoy the game." del(G_found)//Don't want to leave ghosts around. + //feedback_add_details("admin_verb","RSPCH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return new_character /client/proc/cmd_admin_add_freeform_ai_law() @@ -434,11 +443,11 @@ Traitors and the like can also be revived with the previous role mostly intact. if(show_log == "Yes") command_alert("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert") world << sound('ionstorm.ogg') + //feedback_add_details("admin_verb","IONC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_rejuvenate(mob/living/M as mob in world) set category = "Special Verbs" set name = "Rejuvenate" - // All admins should be authenticated, but... what if? if(!holder) src << "Only administrators may use this command." return @@ -498,6 +507,7 @@ Traitors and the like can also be revived with the previous role mostly intact. message_admins("\red Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!", 1) else alert("Admin revive disabled") + //feedback_add_details("admin_verb","REJU") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_create_centcom_report() set category = "Special Verbs" @@ -529,6 +539,7 @@ Traitors and the like can also be revived with the previous role mostly intact. world << sound('commandreport.ogg') log_admin("[key_name(src)] has created a command report: [input]") message_admins("[key_name_admin(src)] has created a command report", 1) + //feedback_add_details("admin_verb","CCR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_delete(atom/O as obj|mob|turf in world) set category = "Admin" @@ -541,6 +552,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if (alert(src, "Are you sure you want to delete:\n[O]\nat ([O.x], [O.y], [O.z])?", "Confirmation", "Yes", "No") == "Yes") log_admin("[key_name(usr)] deleted [O] at ([O.x],[O.y],[O.z])") message_admins("[key_name_admin(usr)] deleted [O] at ([O.x],[O.y],[O.z])", 1) + //feedback_add_details("admin_verb","DEL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! del(O) /client/proc/cmd_admin_list_open_jobs() @@ -553,6 +565,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if(job_master) for(var/datum/job/job in job_master.occupations) src << "[job.title]: [job.total_positions]" + //feedback_add_details("admin_verb","LFS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world) set category = "Special Verbs" @@ -579,7 +592,7 @@ Traitors and the like can also be revived with the previous role mostly intact. explosion (O, devastation, heavy, light, flash) log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flash]) at ([O.x],[O.y],[O.z])") message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flash]) at ([O.x],[O.y],[O.z])", 1) - + //feedback_add_details("admin_verb","EXPL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return else return @@ -602,6 +615,7 @@ Traitors and the like can also be revived with the previous role mostly intact. empulse(O, heavy, light) log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])") message_admins("[key_name_admin(usr)] created an EM PUlse ([heavy],[light]) at ([O.x],[O.y],[O.z])", 1) + //feedback_add_details("admin_verb","EMP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return else @@ -629,6 +643,7 @@ Traitors and the like can also be revived with the previous role mostly intact. return M.gib() + //feedback_add_details("admin_verb","GIB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_gib_self() set name = "Gibself" @@ -637,6 +652,7 @@ Traitors and the like can also be revived with the previous role mostly intact. return else mob.gib() + //feedback_add_details("admin_verb","GIBS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /* /client/proc/cmd_manual_ban() set name = "Manual Ban" @@ -708,6 +724,7 @@ Traitors and the like can also be revived with the previous role mostly intact. var/list/L = M.get_contents() for(var/t in L) usr << "[t]" + //feedback_add_details("admin_verb","CC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_remove_plasma(area/A as area) set category = "Debug" @@ -716,7 +733,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!holder) src << "Only administrators may use this command." return - + //feedback_add_details("admin_verb","STATM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! spawn(1) for(var/turf/simulated/T in A) if(T.air) @@ -738,6 +755,7 @@ Traitors and the like can also be revived with the previous role mostly intact. view = input("Select view range:", "FUCK YE", 7) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128) else view = world.view + //feedback_add_details("admin_verb","CVRA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/admin_call_shuttle() @@ -762,8 +780,9 @@ Traitors and the like can also be revived with the previous role mostly intact. return emergency_shuttle.incall() - world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes." + captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.") world << sound('shuttlecalled.ogg') + //feedback_add_details("admin_verb","CSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return /client/proc/admin_cancel_shuttle() @@ -782,6 +801,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if(confirm != "Yes") return emergency_shuttle.recall() + //feedback_add_details("admin_verb","CCSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return @@ -808,6 +828,7 @@ Traitors and the like can also be revived with the previous role mostly intact. usr << text("\red Attack Log for []", mob) for(var/t in M.attack_log) usr << t + //feedback_add_details("admin_verb","ATTL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/everyone_random() @@ -839,6 +860,7 @@ Traitors and the like can also be revived with the previous role mostly intact. usr << "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet." ticker.random_players = 1 + //feedback_add_details("admin_verb","MER") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/toggle_gravity_on() set category = "Debug" @@ -854,6 +876,7 @@ Traitors and the like can also be revived with the previous role mostly intact. A.gravitychange(1,A) command_alert("CentComm is now beaming gravitons to your station. We appoligize for any inconvience.") + //feedback_add_details("admin_verb","TSGON") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/toggle_gravity_off() set category = "Debug" @@ -869,7 +892,9 @@ Traitors and the like can also be revived with the previous role mostly intact. A.gravitychange(0,A) command_alert("For budget reasons, Centcomm is no longer beaming gravitons to your station. We appoligize for any inconvience.") -//CARN + //feedback_add_details("admin_verb","TSGOFF") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + /client/proc/toggle_random_events() set category = "Server" set name = "Toggle random events on/off" diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index d55c862962..2b6d2adcbe 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -37,7 +37,6 @@ var/global/sent_strike_team = 0 if (emergency_shuttle.direction == 1 && emergency_shuttle.online == 1) emergency_shuttle.recall() - world << "\blue Alert: The shuttle is going back!" var/commando_number = commandos_possible //for selecting a leader var/leader_selected = 0 //when the leader is chosen. The last person spawned. @@ -186,6 +185,7 @@ var/global/sent_strike_team = 0 L.implanted = 1 + var/obj/item/weapon/card/id/W = new(src) W.name = "[real_name]'s ID Card" W.icon_state = "centcom" diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm index eccd7ea42a..a07c386093 100644 --- a/code/modules/admin/verbs/striketeam_syndicate.dm +++ b/code/modules/admin/verbs/striketeam_syndicate.dm @@ -107,6 +107,7 @@ var/global/sent_syndicate_strike_team = 0 message_admins("\blue [key_name_admin(usr)] has spawned a Syndicate strike squad.", 1) log_admin("[key_name(usr)] used Spawn Syndicate Squad.") + //feedback_add_details("admin_verb","SDTHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/create_syndicate_death_commando(obj/spawn_location, syndicate_leader_selected = 0) var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc) @@ -144,7 +145,7 @@ var/global/sent_syndicate_strike_team = 0 camera.c_tag = real_name var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src) - R.set_frequency(1337) //Same frequency as the syndicate team in Nuke mode. + R.set_frequency(NUKE_FREQ) //Same frequency as the syndicate team in Nuke mode. equip_if_possible(R, slot_ears) equip_if_possible(new /obj/item/clothing/under/syndicate(src), slot_w_uniform) equip_if_possible(new /obj/item/clothing/shoes/swat(src), slot_shoes) diff --git a/code/modules/admin/verbs/ticklag.dm b/code/modules/admin/verbs/ticklag.dm index 59c59ba4b5..9f6fddd832 100644 --- a/code/modules/admin/verbs/ticklag.dm +++ b/code/modules/admin/verbs/ticklag.dm @@ -1,20 +1,27 @@ -/client/proc/ticklag(number as num) +//Merged Doohl's and the existing ticklag as they both had good elements about them ~Carn + +/client/proc/ticklag() set category = "Debug" - set name = "Ticklag" - set desc = "Ticklag" - set hidden = 1 + set name = "Set Ticklag" + set desc = "Sets a new tick lag. Recommend you don't mess with this too much! Stable, time-tested ticklag value is 0.9" if(Debug2) if(src.holder) - if(!src.mob) - return - if(src.holder.rank in list("Game Admin", "Game Master")) - world.tick_lag = number - log_admin("[key_name(src.mob)] set tick_lag to [number]") - message_admins("[key_name_admin(usr)] modified world's tick_lag to [number]") - else - alert("Fuck off, no crashing dis server") - return - else - alert("Debugging is disabled") - return + if(!src.mob) return + if(src.holder.rank in list("Game Admin", "Game Master")) + var/newtick = input("Sets a new tick lag. Please don't mess with this too much! The stable, time-tested ticklag value is 0.9","Lag of Tick", world.tick_lag) as num|null + //I've used ticks of 2 before to help with serious singulo lags + if(newtick && newtick <= 2 && newtick > 0) + log_admin("[key_name(src)] has modified world.tick_lag to [newtick]", 0) + message_admins("[key_name(src)] has modified world.tick_lag to [newtick]", 0) + world.tick_lag = newtick + //feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + return + src << "\red Error: ticklag(): Invalid world.ticklag value. No changes made." + return + + src << "\red Error: ticklag(): You are not authorised to use this. Game Admins and higher only." + return + else + src << "\red Error: ticklag(): You must first enable Debugging mode." + return \ No newline at end of file diff --git a/code/modules/chemical/Chemistry-Machinery.dm b/code/modules/chemical/Chemistry-Machinery.dm index 57eb90fbea..2e31bce08f 100644 --- a/code/modules/chemical/Chemistry-Machinery.dm +++ b/code/modules/chemical/Chemistry-Machinery.dm @@ -462,23 +462,23 @@ if (href_list["create_vaccine"]) if(!src.wait) var/obj/item/weapon/reagent_containers/glass/bottle/B = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc) - var/vaccine_type = text2path(href_list["create_vaccine"])//the path is received as string - converting - var/datum/disease/D = new vaccine_type - var/name = input(usr,"Name:","Name the vaccine",D.name) - if(!name || name == " ") name = D.name - B.name = "[name] vaccine bottle" - B.reagents.add_reagent("vaccine",15,vaccine_type) - del(D) - wait = 1 - var/datum/reagents/R = beaker.reagents - var/datum/reagent/blood/Blood = null - for(var/datum/reagent/blood/L in R.reagent_list) - if(L) - Blood = L - break - var/list/res = Blood.data["resistances"] - spawn(res.len*500) - src.wait = null + if(B) + var/vaccine_type = text2path(href_list["create_vaccine"])//the path is received as string - converting + var/datum/disease/D = new vaccine_type + if(D) + B.name = "[D.name] vaccine bottle" + B.reagents.add_reagent("vaccine",15,vaccine_type) + del(D) + wait = 1 + var/datum/reagents/R = beaker.reagents + var/datum/reagent/blood/Blood = null + for(var/datum/reagent/blood/L in R.reagent_list) + if(L) + Blood = L + break + var/list/res = Blood.data["resistances"] + spawn(res.len*500) + src.wait = null else src.temphtml = "The replicator is not ready yet." src.updateUsrDialog() diff --git a/code/modules/chemical/Chemistry-Recipes.dm b/code/modules/chemical/Chemistry-Recipes.dm index b78486260f..0ecef3b724 100644 --- a/code/modules/chemical/Chemistry-Recipes.dm +++ b/code/modules/chemical/Chemistry-Recipes.dm @@ -759,13 +759,14 @@ datum if(M:eyecheck() <= 0) flick("e_flash", M.flash) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= created_volume + rand(1,2), i++) var/chosen = pick(borks) var/obj/B = new chosen - B.loc = get_turf_loc(holder.my_atom) - if(prob(50)) - for(var/j = 1, j <= rand(1, 3), j++) - step(B, pick(NORTH,SOUTH,EAST,WEST)) + if(B) + B.loc = get_turf_loc(holder.my_atom) + if(prob(50)) + for(var/j = 1, j <= rand(1, 3), j++) + step(B, pick(NORTH,SOUTH,EAST,WEST)) diff --git a/code/modules/chemical/Chemistry-Tools.dm b/code/modules/chemical/Chemistry-Tools.dm index caff32179b..c19380ddd5 100644 --- a/code/modules/chemical/Chemistry-Tools.dm +++ b/code/modules/chemical/Chemistry-Tools.dm @@ -1768,7 +1768,23 @@ icon_state = "pill[rand(1,20)]" attackby(obj/item/weapon/W as obj, mob/user as mob) - + if (istype(W, /obj/item/weapon/storage/pill_bottle)) + var/obj/item/weapon/storage/pill_bottle/P = W + if (P.mode == 1) + for (var/obj/item/weapon/reagent_containers/pill/O in locate(src.x,src.y,src.z)) + if(P.contents.len < P.storage_slots) + O.loc = P + P.orient2hud(user) + else + user << "\blue The pill bottle is full." + return + user << "\blue You pick up all the pills." + else + if (P.contents.len < P.storage_slots) + loc = P + P.orient2hud(user) + else + user << "\blue The pill bottle is full." return attack_self(mob/user as mob) return @@ -1871,6 +1887,20 @@ del(D) del(src) +/obj/item/weapon/reagent_containers/glass/watercan + name = "watering can" + desc = "A watering can, for all your watering needs." + icon = 'hydroponics.dmi' + icon_state = "watercan" + item_state = "bucket" + m_amt = 200 + g_amt = 0 + w_class = 3.0 + amount_per_transfer_from_this = 20 + possible_transfer_amounts = list(10,20,30,50,70) + volume = 70 + flags = FPRINT | OPENCONTAINER + /obj/item/weapon/reagent_containers/glass/cantister desc = "It's a canister. Mainly used for transporting fuel." name = "canister" @@ -2053,7 +2083,7 @@ amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25,30) flags = FPRINT | TABLEPASS | OPENCONTAINER - volume = 30 + volume = 50 New() ..() diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 0899491ab8..02043fd7de 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -5,6 +5,7 @@ origin_tech = "magnets=3;biotech=2" var list/icon/current = list() //the current hud icons + proc process_hud(var/mob/M) return @@ -88,25 +89,28 @@ var/client/C = M.client var/icon/tempHud = 'hud.dmi' for(var/mob/living/carbon/human/perp in view(M)) + if(!C) continue + var/perpname = "wot" if(perp.wear_id) C.images += image(tempHud,perp,"hud[ckey(perp:wear_id:GetJobName())]") - var/perpname = "wot" if(istype(perp.wear_id,/obj/item/weapon/card/id)) perpname = perp.wear_id:registered_name else if(istype(perp.wear_id,/obj/item/device/pda)) var/obj/item/device/pda/tempPda = perp.wear_id perpname = tempPda.owner - for (var/datum/data/record/E in data_core.general) - if (E.fields["name"] == perpname) - for (var/datum/data/record/R in data_core.security) - if ((R.fields["id"] == E.fields["id"]) && (R.fields["criminal"] == "*Arrest*")) - C.images += image(tempHud,perp,"hudwanted") - break - else if((R.fields["id"] == E.fields["id"]) && (R.fields["criminal"] == "Incarcerated")) - C.images += image(tempHud,perp,"hudprisoner") - break else + perpname = perp.name C.images += image(tempHud,perp,"hudunknown") + + for (var/datum/data/record/E in data_core.general) + if (E.fields["name"] == perpname) + for (var/datum/data/record/R in data_core.security) + if ((R.fields["id"] == E.fields["id"]) && (R.fields["criminal"] == "*Arrest*")) + C.images += image(tempHud,perp,"hudwanted") + break + else if((R.fields["id"] == E.fields["id"]) && (R.fields["criminal"] == "Incarcerated")) + C.images += image(tempHud,perp,"hudprisoner") + break for(var/named in perp.organs) var/datum/organ/external/E = perp.organs[named] for(var/obj/item/weapon/implant/I in E.implant) @@ -116,3 +120,4 @@ if(istype(I,/obj/item/weapon/implant/loyalty)) C.images += image(tempHud,perp,"hud_imp_loyal") + diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index c0f955315f..374d4dded7 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -28,4 +28,16 @@ /obj/item/clothing/head/helmet/hardhat/dblue icon_state = "hardhat0_dblue" item_state = "hardhat0_dblue" - color = "dblue" \ No newline at end of file + color = "dblue" + +/obj/item/clothing/head/helmet/hardhat/pumpkinhead + name = "carved pumpkin" + desc = "A jack o' lantern! Believed to ward off evil spirits." + icon_state = "hardhat0_pumpkin" + item_state = "hardhat0_pumpkin" + flags = FPRINT | TABLEPASS | HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR + brightness_on = 3 + see_face = 0.0 + color = "pumpkin" + armor = list(melee = 5, bullet = 0, laser = 5,energy = 5, bomb = 5, bio = 0, rad = 0) + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES \ No newline at end of file diff --git a/code/modules/clothing/jumpsuit.dm b/code/modules/clothing/jumpsuit.dm index 8ce85fca2f..67e8cd57b5 100644 --- a/code/modules/clothing/jumpsuit.dm +++ b/code/modules/clothing/jumpsuit.dm @@ -531,22 +531,6 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS armor = list(melee = 100, bullet = 100, laser = 100,energy = 100, bomb = 100, bio = 100, rad = 100) -/obj/item/clothing/under/rank/medical_sleeve - desc = "Made of a special fiber that gives special protection against biohazards. Has a cross on the chest denoting that the wearer is trained medical personnel." - name = "short sleeve medical jumpsuit" - icon_state = "medical_sleeve" - item_state = "w_suit" - color = "medical_sleeve" - permeability_coefficient = 0.50 - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - -/obj/item/clothing/under/jumpsuitdown - desc = "A rolled down jumpsuit. Great for mechanics." - name = "rolled down jumpsuit" - icon_state = "jumpsuitdown" - item_state = "jumpsuitdown" - color = "jumpsuitdown" - // Cheerleader outfits or something /obj/item/clothing/under/cheerleader name = "cheerleader uniform" diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index 392c344cff..5166f2707e 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -45,13 +45,3 @@ name = "Scientist Labcoat" desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder." icon_state = "labcoat_tox_open" - -/obj/item/clothing/suit/storage/labcoat/pink - name = "Pink Labcoat" - desc = "A suit that protects against minor chemical spills. Has a pink stripe down from the shoulders." - icon_state = "labcoat_pink_open" - -/obj/item/clothing/suit/storage/labcoat/red - name = "Red Labcoat" - desc = "A suit that protects against minor chemical spills. Has a red stripe on the shoulders and rolled up sleeves." - icon_state = "labcoat_sleeve_open" \ No newline at end of file diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 9fac994c5f..a2f976ea90 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -6,6 +6,7 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + /obj/item/clothing/suit/storage/wcoat name = "waistcoat" desc = "The height of class." @@ -13,6 +14,24 @@ item_state = "wcoat" body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + + + +/obj/item/clothing/suit/bluetag + name = "blue laser tag armour" + desc = "Blue Pride, Station Wide" + icon_state = "bluetag" + item_state = "bluetag" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + +/obj/item/clothing/suit/redtag + name = "red laser tag armour" + desc = "Pew pew pew" + icon_state = "redtag" + item_state = "redtag" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + + /obj/item/clothing/suit/storage/apron name = "apron" desc = "A basic blue apron. It has a large pocket you can store things in." @@ -21,6 +40,7 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS allowed = list (/obj/item/weapon/plantbgone,/obj/item/device/analyzer/plant_analyzer,/obj/item/seeds,/obj/item/nutrient,/obj/item/weapon/minihoe) + /obj/item/clothing/suit/storage/chef name = "chef's apron" desc = "An apron used by a high class chef. Has a few pockets for nic-naks." @@ -33,6 +53,7 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS allowed = list (/obj/item/weapon/kitchenknife,/obj/item/weapon/butch) + /obj/item/clothing/suit/storage/chef/classic name = "classic chef's apron" desc = "A basic, dull, white chef's apron." @@ -40,18 +61,21 @@ item_state = "apronchef" body_parts_covered = UPPER_TORSO|LOWER_TORSO + /obj/item/clothing/suit/hazardvest name = "hazard vest" desc = "A high-visibility vest used in work zones." icon_state = "hazard" item_state = "hazard" + /obj/item/clothing/suit/suspenders name = "suspenders" desc = "They suspend the illusion of the mime's play." icon = 'belts.dmi' icon_state = "suspenders" + /obj/item/clothing/suit/syndicatefake name = "red space suit replica" icon_state = "syndicate" @@ -62,6 +86,7 @@ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/toy) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + /obj/item/clothing/suit/storage/captunic name = "captain's parade tunic" desc = "Worn by a Captain to show their class." @@ -70,6 +95,7 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS flags_inv = HIDEJUMPSUIT + /obj/item/clothing/suit/nun name = "nun robe" desc = "Maximum piety in this star system." @@ -92,14 +118,16 @@ item_state = "chaplain_hoodie" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + /obj/item/clothing/suit/hastur - name = "Hastur's robes" + name = "\improper Hastur's robes" desc = "Robes not meant to be worn by man" icon_state = "hastur" item_state = "hastur" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + /obj/item/clothing/suit/imperium_monk name = "imperium monk robes" desc = "A set of strange robes." @@ -108,6 +136,7 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS flags_inv = HIDESHOES|HIDEJUMPSUIT + /obj/item/clothing/suit/chickensuit name = "chicken suit" desc = "Bwak!" @@ -116,6 +145,7 @@ body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS|FEET|HEAD flags_inv = HIDESHOES|HIDEJUMPSUIT + /obj/item/clothing/suit/monkeysuit name = "monkey suit" desc = "A suit that looks like a primate" @@ -124,6 +154,7 @@ body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS|FEET|HANDS flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + /obj/item/clothing/suit/holidaypriest name = "holiday priest" desc = "This is a nice holiday my son." @@ -131,6 +162,8 @@ item_state = "holidaypriest" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + + // BubbleWrap - Nothing to see here /obj/item/clothing/suit/cardborg diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 880935c27b..67b1fcde75 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -1,15 +1,94 @@ -//add custom items you give to people here, and put their icons in custom_items.dmi +// Add custom items you give to people here, and put their icons in custom_items.dmi +// Remember to change 'icon = 'custom_items.dmi'' for items not using /obj/item/fluff as a base +// Clothing item_state doesn't use custom_items.dmi. Just add them to the normal clothing files. + /obj/item/fluff // so that they don't spam up the object tree icon = 'custom_items.dmi' w_class = 1.0 -/obj/item/fluff/wes_solari_1 - name = "Family Photograph" - desc = "A family photograph of a couple and a young child, Written on the back it says \"See you soon Dad -Roy\"." - icon_state = "wes_solari_1" +//////////// Clothing + +/obj/item/clothing/glasses/meson/fluff/book_berner_1 + name = "bespectacled mesonic surveyors" + desc = "One of the older meson scanner models retrofitted to perform like its modern counterparts." + icon = 'custom_items.dmi' + icon_state = "book_berner_1" + +/obj/item/clothing/glasses/fluff/serithi_artalis_1 + name = "extranet HUD" + desc = "A heads-up display with limited connectivity to the NanoTrasen Extranet, capable of displaying information from official NanoTrasen records." + icon = 'custom_items.dmi' + icon_state = "serithi_artalis_1" + +/obj/item/clothing/head/helmet/hardhat/fluff/greg_anderson_1 + name = "old hard hat" + desc = "An old dented hard hat with the nametag \"Anderson\". It seems to be backwards." + icon_state = "hardhat0_dblue" //Already an in-game sprite + item_state = "hardhat0_dblue" + color = "dblue" + +/obj/item/clothing/under/rank/virologist/fluff/cdc_jumpsuit + name = "\improper CDC jumpsuit" + desc = "A modified standard-issue CDC jumpsuit made of a special fiber that gives special protection against biohazards. It has a biohazard symbol sewn into the back." + icon = 'custom_items.dmi' + icon_state = "cdc_jumpsuit" + color = "cdc_jumpsuit" + +/obj/item/clothing/suit/storage/labcoat/fluff/cdc_labcoat + name = "\improper CDC labcoat" + desc = "A standard-issue CDC labcoat that protects against minor chemical spills. It has the name \"Wiles\" sewn on to the breast pocket." + icon = 'custom_items.dmi' + icon_state = "labcoat_cdc_open" + +/obj/item/clothing/suit/storage/labcoat/fluff/pink + name = "pink labcoat" + desc = "A suit that protects against minor chemical spills. Has a pink stripe down from the shoulders." + icon = 'custom_items.dmi' + icon_state = "labcoat_pink_open" + +/obj/item/clothing/suit/storage/labcoat/fluff/red + name = "red labcoat" + desc = "A suit that protects against minor chemical spills. Has a red stripe on the shoulders and rolled up sleeves." + icon = 'custom_items.dmi' + icon_state = "labcoat_red_open" + +/obj/item/clothing/under/rank/medical/fluff/short + name = "short sleeve medical jumpsuit" + desc = "Made of a special fiber that gives special protection against biohazards. Has a cross on the chest denoting that the wearer is trained medical personnel and short sleeves." + icon = 'custom_items.dmi' + icon_state = "medical_short" + color = "medical_short" + +/obj/item/clothing/under/fluff/jumpsuitdown + name = "rolled down jumpsuit" + desc = "A rolled down jumpsuit. Great for mechanics." + icon = 'custom_items.dmi' + icon_state = "jumpsuitdown" + item_state = "jumpsuitdown" + color = "jumpsuitdown" + +/obj/item/clothing/under/fluff/olddressuniform + name = "retired dress uniform" + desc = "A retired Station Head of Staff uniform, phased out twenty years ago for the newer jumpsuit design, but still acceptable dress. Lovingly maintained." + icon = 'custom_items.dmi' + icon_state = "olddressuniform" + item_state = "olddressuniform" + color = "olddressuniform" + +//////////// Useable Items + +/obj/item/weapon/pen/fluff/multi + name = "multicolor pen" + desc = "It's a cool looking pen. Lots of colors!" + +/obj/item/weapon/pen/fluff/fancypen + name = "fancy pen" + desc = "A fancy metal pen. It uses blue ink. An inscription on one side reads,\"L.L. - L.R.\"" + icon = 'custom_items.dmi' + icon_state = "fancypen" /obj/item/fluff/victor_kaminsky_1 - name = "\improper Golden Detective's Badge" + name = "golden detective's badge" desc = "NanoTrasen Security Department detective's badge, made from gold. Badge number is 564." icon_state = "victor_kaminsky_1" @@ -18,45 +97,48 @@ O.show_message(text("[] shows you: \icon[] [].", user, src, src.name), 1) src.add_fingerprint(user) +/obj/item/weapon/clipboard/fluff/smallnote + name = "small notebook" + desc = "A generic small spiral notebook that flips upwards." + icon = 'custom_items.dmi' + icon_state = "smallnotetext" + +/obj/item/weapon/storage/fluff/maye_daye_1 + name = "pristine lunchbox" + desc = "A pristine stainless steel lunch box. The initials M.D. are engraved on the inside of the lid." + icon = 'custom_items.dmi' + icon_state = "maye_daye_1" + +/obj/item/weapon/reagent_containers/food/drinks/flask/fluff/johann_erzatz_1 + name = "vintage thermos" + desc = "An older thermos with a faint shine." + icon = 'custom_items.dmi' + icon_state = "johann_erzatz_1" + volume = 50 + +//////////// Misc Items + +/obj/item/fluff/wes_solari_1 + name = "family photograph" + desc = "A family photograph of a couple and a young child, Written on the back it says \"See you soon Dad -Roy\"." + icon_state = "wes_solari_1" + /obj/item/fluff/sarah_calvera_1 - name = "Old Photo" + name = "old photo" desc = "Looks like it was made on a really old, cheap camera. Low quality. The camera shows a young hispanic looking girl with red hair wearing a white dress is standing in front of an old looking wall. On the back there is a note in black marker that reads \"Sara, Siempre pensé que eras tan linda con ese vestido. Tu hermano, Carlos.\"" icon_state = "sarah_calvera_1" /obj/item/fluff/angelo_wilkerson_1 - name = "Fancy Watch" + name = "fancy watch" desc = "An old and expensive pocket watch. Engraved on the bottom is \"Odium est Source De Dolor\". On the back, there is an engraving that does not match the bottom and looks more recent. \"Angelo, If you find this, you shall never see me again. Please, for your sake, go anywhere and do anything but stay. I'm proud of you and I will always love you. Your father, Jacob Wilkerson.\" Jacob Wilkerson... Wasn't he that serial killer?" icon_state = "angelo_wilkerson_1" -/obj/item/clothing/glasses/meson/fluff/book_berner_1 - name = "Bespectacled Mesonic Surveyors" - desc = "One of the older meson scanner models retrofitted to perform like its modern counterparts." - icon = 'custom_items.dmi' - icon_state = "book_berner_1" - /obj/item/fluff/sarah_carbrokes_1 - name = "Locket" + name = "locket" desc = "A grey locket with a picture of a black haired man in it. The text above it reads: \"Edwin Carbrokes\"." icon_state = "sarah_carbrokes_1" -/obj/item/clothing/glasses/fluff/serithi_artalis_1 - name = "Extranet HUD" - desc = "A heads-up display with limited connectivity to the NanoTrasen Extranet, capable of displaying information from official NanoTrasen records." - icon_state = "serithi_artalis_1" - -/obj/item/clothing/head/fluff/greg_anderson_1 - name = "old hard hat" - desc = "An old dented hard hat with the nametag \"Anderson\". It seems to be backwards." - icon_state = "hardhat0_red" - flags = FPRINT | TABLEPASS | SUITSPACE - item_state = "hardhat0_red" - color = "red" - armor = list(melee = 30, bullet = 5, laser = 20,energy = 10, bomb = 20, bio = 10, rad = 20) - flags_inv = 0 - /obj/item/fluff/ethan_way_1 - name = "Old ID" + name = "old ID" desc = "A scratched and worn identification card; it appears too damaged to inferface with any technology. You can almost make out \"Tom Cabinet\" in the smeared ink." - icon = 'custom_items.dmi' icon_state = "ethan_way_1" - flags = FPRINT | TABLEPASS \ No newline at end of file diff --git a/code/modules/food/food.dm b/code/modules/food/food.dm index f8df8a8c63..33322a3121 100644 --- a/code/modules/food/food.dm +++ b/code/modules/food/food.dm @@ -840,12 +840,13 @@ if(!reagents.total_volume) var/mob/M = usr var/obj/item/weapon/paper/paper = locate() in src - M.visible_message( \ - "\blue [M] takes a piece of paper from the cookie!", \ - "\blue You take a piece of paper from the cookie! Read it!" \ - ) - M.put_in_hand(paper) - paper.add_fingerprint(M) + if(paper) + M.visible_message( \ + "\blue [M] takes a piece of paper from the cookie!", \ + "\blue You take a piece of paper from the cookie! Read it!" \ + ) + M.put_in_hand(paper) + paper.add_fingerprint(M) /obj/item/weapon/reagent_containers/food/snacks/badrecipe name = "Burned mess" @@ -1719,6 +1720,21 @@ icon_state = "applecakeslice" bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie + name = "Pumpkin Pie" + desc = "A delicious treat for the autumn months." + icon_state = "pumpkinpie" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice + slices_num = 5 + New() + ..() + reagents.add_reagent("nutriment", 29) + +/obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice + name = "Pumpkin Pie slice" + desc = "A slice of pumpkin pie, with whipped cream on top. Perfection." + icon_state = "pumpkinpieslice" + bitesize = 2 @@ -2000,6 +2016,8 @@ new /obj/item/weapon/reagent_containers/food/snacks/rawsticks(spawnloc) user << "You cut the potato." del(src) + else + ..() /obj/item/weapon/reagent_containers/food/snacks/rawsticks name = "raw potato sticks" diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index 64f43fa243..b6af2806eb 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -996,6 +996,16 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/mysterysoup +/datum/recipe/pumpkinpie + reagents = list("milk" = 5, "sugar" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin, + /obj/item/weapon/reagent_containers/food/snacks/flour, + /obj/item/weapon/reagent_containers/food/snacks/egg, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie + + ////////////////////////////////////////// // bs12 food port stuff ////////////////////////////////////////// diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 28cde78ffc..806a37dd8f 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -44,6 +44,36 @@ proc/move_mining_shuttle() else fromArea = locate(/area/shuttle/mining/station) toArea = locate(/area/shuttle/mining/outpost) + + + var/list/dstturfs = list() + var/throwy = world.maxy + + for(var/turf/T in toArea) + dstturfs += T + if(T.y < throwy) + throwy = T.y + + // hey you, get out of the way! + for(var/turf/T in dstturfs) + // find the turf to move things to + var/turf/D = locate(T.x, throwy - 1, 1) + //var/turf/E = get_step(D, SOUTH) + for(var/atom/movable/AM as mob|obj in T) + AM.Move(D) + // NOTE: Commenting this out to avoid recreating mass driver glitch + /* + spawn(0) + AM.throw_at(E, 1, 1) + return + */ + + if(istype(T, /turf/simulated)) + del(T) + + for(var/mob/living/carbon/bug in toArea) // If someone somehow is still in the shuttle's docking area... + bug.gib() + fromArea.move_contents_to(toArea) if (mining_shuttle_location) mining_shuttle_location = 0 diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 169b75719c..2d65571417 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -84,6 +84,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/Move(NewLoc, direct) if(NewLoc) loc = NewLoc + for(var/obj/step_trigger/S in NewLoc) + S.HasEntered(src) + return loc = get_turf(src) //Get out of closets and such as a ghost if((direct & NORTH) && y < world.maxy) @@ -95,6 +98,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if((direct & WEST) && x > 1) x-- + for(var/obj/step_trigger/S in locate(x, y, z)) + S.HasEntered(src) + /mob/dead/observer/examine() if(usr) usr << desc diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm index a812626b65..446f068632 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm @@ -10,6 +10,7 @@ src.verbs -= /mob/living/carbon/alien/humanoid/verb/ActivateHuggers src.stand_icon = new /icon('alien.dmi', "aliend_s") src.lying_icon = new /icon('alien.dmi', "aliend_l") + src.resting_icon = new /icon('alien.dmi', "aliend_sleep") src.icon = src.stand_icon update_clothing() src << "\blue Your icons have been generated!" diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index 1f6ae9bead..7c7e5eaedf 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -9,6 +9,7 @@ src.verbs -= /mob/living/carbon/alien/humanoid/verb/corrode src.stand_icon = new /icon('alien.dmi', "alienh_s") src.lying_icon = new /icon('alien.dmi', "alienh_l") + src.resting_icon = new /icon('alien.dmi', "alienh_sleep") src.icon = src.stand_icon update_clothing() src << "\blue Your icons have been generated!" diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm index 7bd9b41b9b..ecc3b459e6 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm @@ -9,6 +9,7 @@ src.verbs += /mob/living/carbon/alien/humanoid/proc/corrode_target src.stand_icon = new /icon('alien.dmi', "aliens_s") src.lying_icon = new /icon('alien.dmi', "aliens_l") + src.resting_icon = new /icon('alien.dmi', "aliens_sleep") src.icon = src.stand_icon update_clothing() src << "\blue Your icons have been generated!" diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 8b261940ce..52e422c628 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -10,6 +10,7 @@ if(!istype(src, /mob/living/carbon/alien/humanoid/queen)) stand_icon = new /icon('alien.dmi', "alien_s") lying_icon = new /icon('alien.dmi', "alien_l") + resting_icon = new /icon('alien.dmi', "alienh_sleep") icon = stand_icon update_clothing() src << "\blue Your icons have been generated!" @@ -330,7 +331,10 @@ if (lying) if(update_icon) - icon = lying_icon + if(!resting) + icon = lying_icon + else + icon = resting_icon overlays += body_lying diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm index a0ca95b041..1388a1314c 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/life.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm @@ -14,8 +14,12 @@ if (src.monkeyizing) return + ..() + if (src.stat != 2) //still breathing + + //First, resolve location and get a breath if(air_master.current_cycle%4==2) diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index ae61bbfa03..b975d969cb 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -14,6 +14,8 @@ if (monkeyizing) return + ..() + if (stat != 2) //still breathing //First, resolve location and get a breath diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 581179cdd8..4106a1b014 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -4,6 +4,8 @@ set invisibility = 0 set background = 1 + ..() + var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE if(loc) environment = loc.return_air() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index b50b0eb84e..4ca82ab743 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -193,11 +193,13 @@ var/status = "" var/brutedamage = org.brute_dam var/burndamage = org.burn_dam + if(halloss > 0) if(prob(30)) brutedamage += halloss if(prob(30)) burndamage += halloss + if(brutedamage > 0) status = "bruised" if(brutedamage > 20) @@ -208,6 +210,7 @@ status += " and " if(burndamage > 40) status += "peeling away" + else if(burndamage > 10) status += "blistered" else if(burndamage > 0) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 664db918a0..0eae0dd45d 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -509,7 +509,25 @@ else src << "\blue Unusable emote '[act]'. Say *help for a list." + + + + if (message) + log_emote("[name]/[key] : [message]") + + //Hearing gasp and such every five seconds is not good emotes were not global for a reason. + // Maybe some people are okay with that. + + for(var/mob/M in world) + if (!M.client) + continue //skip monkeys and leavers + if (istype(M, /mob/new_player)) + continue + if(M.stat == 2 && M.client.ghost_sight && !(M in viewers(src,null))) + M.show_message(message) + + if (m_type & 1) for (var/mob/O in viewers(src, null)) O.show_message(message, m_type) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 1b1e2e182b..3da6683204 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -1,5 +1,5 @@ /mob/living/carbon/human/examine() - set src in oview() + set src in view() if(!usr || !src) return if(((usr.disabilities & 128) || usr.blinded || usr.stat) && !(istype(usr,/mob/dead/observer/))) @@ -180,14 +180,14 @@ distance = 1 if (src.stat == 1 || stat == 2) - msg += "[name] doesn't seem to be responding to anything around [t_him], [t_his] eyes closed as though asleep.\n" + msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n" if((!isbreathing || holdbreath) && distance <= 3) - msg += "[name] does not appear to be breathing.\n" + msg += "[t_He] does not appear to be breathing.\n" if(istype(usr, /mob/living/carbon/human) && usr.stat == 0 && src.stat == 1 && distance <= 1) for(var/mob/O in viewers(usr.loc, null)) O.show_message("[usr] checks [src]'s pulse.", 1) spawn(15) - usr << "\blue [name] has a pulse!" + usr << "\blue [t_He] has a pulse!" if (src.stat == 2 || (changeling && changeling.changeling_fakedeath == 1)) if(distance <= 1) @@ -195,7 +195,19 @@ for(var/mob/O in viewers(usr.loc, null)) O.show_message("[usr] checks [src]'s pulse.", 1) spawn(15) - usr << "\red [name] has no pulse!" + if(!src.client) + var/foundghost = 0 + for(var/mob/dead/observer/G in world) + if(G.client) + if(G.corpse == src) + foundghost++ + break + if(!foundghost) + usr << "[t_He] has no pulse and [t_his] soul has departed..." + else + usr << "[t_He] has no pulse..." + + msg += "" /* if (src.getBruteLoss()) if (src.getBruteLoss() < 30) @@ -205,9 +217,9 @@ if (src.cloneloss) if (src.cloneloss < 30) - msg += "[src.name] looks slightly... unfinished?\n" + msg += "[t_He] looks slightly... unfinished?\n" else - msg += "[src.name] looks very... unfinished?
    \n" + msg += "[t_He] looks very... unfinished?\n" /* if (src.getFireLoss()) if (src.getFireLoss() < 30) @@ -230,7 +242,10 @@ msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n" if (!src.client && !admin_observing) - msg += "[t_He] [t_has] a vacant, braindead stare...\n" + msg += "[t_He] [t_has] a vacant stare...\n" + + if (src.digitalcamo) + msg += "[t_He] [t_is] repulsively uncanny!\n" var/list/wound_descriptions = list() var/list/wound_flavor_text = list() @@ -509,6 +524,31 @@ // usr << "\red [src.name] is bleeding from a [sizetext] on [t_his] [temp.display_name]." // continue + if(istype(usr, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = usr + if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud)) + var/perpname = "wot" + var/criminal = "None" + + if(wear_id) + if(istype(wear_id,/obj/item/weapon/card/id)) + perpname = wear_id:registered_name + else if(istype(wear_id,/obj/item/device/pda)) + var/obj/item/device/pda/tempPda = wear_id + perpname = tempPda.owner + else + perpname = src.name + + for (var/datum/data/record/E in data_core.general) + if (E.fields["name"] == perpname) + for (var/datum/data/record/R in data_core.security) + if (R.fields["id"] == E.fields["id"]) + criminal = R.fields["criminal"] + + + msg += "Criminal status: \[[criminal]\]\n" + //msg += "\[Set Hostile Identification\]\n" + if(print_flavor_text()) msg += "[print_flavor_text()]\n" msg += "\blue *---------*" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 97e9e7a97b..88191e9402 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1098,8 +1098,7 @@ else m_select.screen_loc = null - var/suit_img //A bit of kludge to make belts go under coats, but on other suits - var/suit_stain + if (wear_suit) /*if (mutations & FAT && !(wear_suit.flags & ONESIZEFITSALL)) src << "\red You burst out of the [wear_suit.name]!" @@ -1113,7 +1112,7 @@ c:layer = initial(c:layer)*/ if (istype(wear_suit, /obj/item/clothing/suit)) var/t1 = wear_suit.icon_state - suit_img = image("icon" = 'suit.dmi', "icon_state" = text("[][]", t1, (!( lying ) ? null : "2")), "layer" = MOB_LAYER) + overlays += image("icon" = 'suit.dmi', "icon_state" = text("[][]", t1, (!( lying ) ? null : "2")), "layer" = MOB_LAYER) if (wear_suit) if (wear_suit.blood_DNA) var/icon/stain_icon = null @@ -1123,7 +1122,7 @@ stain_icon = icon('blood.dmi', "coatblood[!lying ? "" : "2"]") else stain_icon = icon('blood.dmi', "suitblood[!lying ? "" : "2"]") - suit_stain = image("icon" = stain_icon, "layer" = MOB_LAYER) + overlays += image("icon" = stain_icon, "layer" = MOB_LAYER) wear_suit.screen_loc = ui_oclothing if (istype(wear_suit, /obj/item/clothing/suit/straight_jacket)) if (handcuffed) @@ -1137,24 +1136,6 @@ hand = 0 drop_item() hand = h - // Belt - var/belt_img //A bit of kludge to make belts go under coats, but on other suits - if (belt) - var/t1 = belt.item_state - if (!t1) - t1 = belt.icon_state - belt_img = image("icon" = 'belt.dmi', "icon_state" = text("[][]", t1, (!( lying ) ? null : "2")), "layer" = MOB_LAYER) - belt.screen_loc = ui_belt - - //A bit of kludge to make belts go under coats, but on other suits - if (istype(wear_suit, /obj/item/clothing/suit/storage/det_suit) || istype(wear_suit, /obj/item/clothing/suit/storage/labcoat)) - overlays += belt_img - overlays += suit_img - overlays += suit_stain - else - overlays += suit_img - overlays += suit_stain - overlays += belt_img if (lying) @@ -1188,6 +1169,13 @@ overlays += image("icon" = stain_icon, "layer" = MOB_LAYER) head.screen_loc = ui_head + // Belt + if (belt) + var/t1 = belt.item_state + if (!t1) + t1 = belt.icon_state + overlays += image("icon" = 'belt.dmi', "icon_state" = text("[][]", t1, (!( lying ) ? null : "2")), "layer" = MOB_LAYER) + belt.screen_loc = ui_belt if ((wear_mask && !(wear_mask.see_face)) || (head && !(head.see_face))) // can't see the face if (wear_id) @@ -2437,7 +2425,7 @@ It can still be worn/put on as normal. var/obj/item/device/pda/pda = wear_id var/obj/item/weapon/card/id/id = wear_id if (istype(pda)) - if (pda.id) + if (pda.id && istype(pda.id, /obj/item/weapon/card/id)) . = pda.id.assignment else . = pda.ownjob @@ -2594,6 +2582,40 @@ It can still be worn/put on as normal. spawn( 0 ) O.process() return + + if (href_list["criminal"]) + if(istype(usr, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = usr + if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud)) + var/perpname = "wot" + var/modified = 0 + + if(wear_id) + if(istype(wear_id,/obj/item/weapon/card/id)) + perpname = wear_id:registered_name + else if(istype(wear_id,/obj/item/device/pda)) + var/obj/item/device/pda/tempPda = wear_id + perpname = tempPda.owner + else + perpname = src.name + + for (var/datum/data/record/E in data_core.general) + if (E.fields["name"] == perpname) + for (var/datum/data/record/R in data_core.security) + if (R.fields["id"] == E.fields["id"]) + + var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Parolled", "Released", "Cancel") + + if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud)) + if(setcriminal != "Cancel") + R.fields["criminal"] = setcriminal + modified = 1 + + spawn() + H.handle_regular_hud_updates() + + if(!modified) + usr << "\red Unable to locate a data core entry for this person." ..() return @@ -2808,16 +2830,21 @@ It can still be worn/put on as normal. reset_view(0) remoteobserve = null src.verbs -= /mob/living/carbon/human/proc/remoteobserve + src.tkdisable = 0 return if(client.eye != client.mob) reset_view(0) remoteobserve = null + src.tkdisable = 0 return var/list/mob/creatures = list() for(var/mob/living/carbon/h in world) + var/turf/temp_turf = get_turf(h) + if(temp_turf.z != 1 && temp_turf.z != 5) //Not on mining or the station. + continue creatures += h var/mob/target = input ("Who do you want to project your mind to ?") as mob in creatures @@ -2825,6 +2852,8 @@ It can still be worn/put on as normal. if (target) reset_view(target) remoteobserve = target + src.tkdisable = 1 else reset_view(0) remoteobserve = null + src.tkdisable = 0 diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 7d434f659a..0340f2a925 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -32,6 +32,30 @@ visible_message("\red [src] has been touched with the stun gloves by [M]!") return + if(istype(M.gloves , /obj/item/clothing/gloves/boxing/hologlove)) + + var/damage = rand(0, 9) + if(!damage) + playsound(loc, 'punchmiss.ogg', 25, 1, -1) + visible_message("\red [M] has attempted to punch [src]!") + return 0 + var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) + var/armor_block = run_armor_check(affecting, "melee") + + if(M.mutations & HULK) damage += 5 + playsound(loc, "punch", 25, 1, -1) + + visible_message("\red [M] has punched [src]!") + + apply_damage(damage, HALLOSS, affecting, armor_block) + if(damage >= 9) + visible_message("\red [M] has weakened [src]!") + apply_effect(4, WEAKEN, armor_block) + UpdateDamageIcon() + + return + + switch(M.a_intent) if("help") if(health > 0) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 26b1d58601..4b96f26273 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -9,6 +9,31 @@ emp_act */ /mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone) + + if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/armor/laserproof)) + if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam)) + var/reflectchance = 40 - round(P.damage/3) + if(!(def_zone in list("chest", "groin"))) + reflectchance /= 2 + if(prob(reflectchance)) + visible_message("\red The [P.name] gets reflected by [src]'s [wear_suit.name]!") + + // Find a turf near or on the original location to bounce to + if(P.starting) + var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/turf/curloc = get_turf(src) + + // redirect the projectile + P.original = locate(new_x, new_y, P.z) + P.starting = curloc + P.current = curloc + P.firer = src + P.yo = new_y - curloc.y + P.xo = new_x - curloc.x + + return -1 // complete projectile permutation + if(check_shields(P.damage, "the [P.name]")) P.on_hit(src, 2) return 2 @@ -96,14 +121,17 @@ emp_act var/datum/organ/external/affecting = get_organ(ran_zone(user.zone_sel.selecting)) var/hit_area = affecting.display_name + + + if((user != src) && check_shields(I.force, "the [I.name]")) + return 0 + if(!affecting.destroyed) visible_message("\red [src] has been attacked in the [hit_area] with [I.name] by [user]!") else user << "What [affecting]?" return - if((user != src) && check_shields(I.force, "the [I.name]")) - return 0 var/armor = run_armor_check(affecting, "melee", "Your armor has protected you from a hit to the [hit_area].", "Your armor has softened hit to your [hit_area].") if(armor >= 2) return 0 if(!I.force) return 0 @@ -115,8 +143,8 @@ emp_act apply_damage(power, I.damtype, affecting, armor, is_cut(I), I.name) var/bloody = 0 - if((I.damtype == BRUTE) && prob(25 + is_sharp(I) * 50 + (I.force * 2))) - I.add_blood(src) + if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + is_sharp(I) * 50 + (I.force * 2))) + I.add_blood(src) //Make the weapon bloody, not the person. bloody = 1 var/turf/location = loc if(istype(location, /turf/simulated)) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 4279085a46..317e9824c8 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -25,6 +25,8 @@ if(!loc) // Fixing a null error that occurs when the mob isn't found in the world -- TLE return + ..() + //Being buckled to a chair or bed check_if_buckled() @@ -125,8 +127,6 @@ if(!currentTurf.sd_lumcount) playsound_local(src,pick(scarySounds),50, 1, -1) - ..() //for organs - src.moved_recently = max(0, moved_recently-1) /mob/living/carbon/human @@ -186,15 +186,24 @@ // a.hallucinate(src) if(!handling_hal && hallucination > 20) spawn handle_hallucinations() //The not boring kind! - hallucination = max(hallucination - 2, 0) + hallucination = max(hallucination - 2, 0) // A more compact way of doing it. DMTG //if(health < 0) // for(var/obj/a in hallucinations) // del a else - halloss = 0 + //halloss = 0 for(var/atom/a in hallucinations) del a + if(halloss > 100) + src << "You're too tired to keep going..." + for(var/mob/O in viewers(src, null)) + if(O == src) + continue + O.show_message(text("\red [src] slumps to the ground panting, too weak to continue fighting."), 1) + Paralyse(15) + setHalLoss(99) + if(mutations2 & mSmallsize) if(!(pass_flags & PASSTABLE)) pass_flags |= PASSTABLE @@ -448,8 +457,10 @@ return null update_canmove() - if(paralysis || resting || stunned || weakened || buckled || (changeling && changeling.changeling_fakedeath)) canmove = 0 - else canmove = 1 + if(paralysis || stunned || weakened || resting || buckled || (changeling && changeling.changeling_fakedeath)) + canmove = 0 + else + canmove = 1 handle_breath(datum/gas_mixture/breath) if(nodamage || (mutations & mNobreath)) @@ -927,7 +938,7 @@ if(getOxyLoss() > 50) Paralyse(3) if(sleeping) -// adjustHalLoss(-5) + adjustHalLoss(-5) if(paralysis <= 0) Paralyse(2) if (prob(10) && health && !hal_crit) spawn(0) emote("snore") @@ -1483,4 +1494,4 @@ snippets plcheck = t_plasma oxcheck = t_oxygen G.turf_add(T, G.total_moles()) -*/ +*/ \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index 737872121c..a4b12e934c 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -5,6 +5,7 @@ if (src.monkeyizing) return + ..() var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE if(src.loc) diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index f5780ed9c8..ab616822ce 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -23,6 +23,8 @@ if (src.monkeyizing) return + ..() + var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE if(src.loc) environment = loc.return_air() diff --git a/code/modules/mob/living/carbon/monkey/powers.dm b/code/modules/mob/living/carbon/monkey/powers.dm index e05cb05de2..9a8f95283e 100644 --- a/code/modules/mob/living/carbon/monkey/powers.dm +++ b/code/modules/mob/living/carbon/monkey/powers.dm @@ -3,48 +3,50 @@ set desc = "Enter an air vent and crawl through the pipe system." set category = "Monkey" - if(contents.len) - for(var/obj/item/carried_item in contents)//If the monkey got on objects. - if(!istype(carried_item, /obj/item/weapon/implant))//If it's not an implant. - src << "\red You can't be carrying items or have items equipped when vent crawling!" - return - - if(!stat) - var/obj/machinery/atmospherics/unary/vent_pump/vent_found - for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src)) - if(!v.welded) - vent_found = v - else - src << "\red That vent is welded." - if(vent_found) - if(vent_found.network&&vent_found.network.normal_members.len) - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members) - if(temp_vent.loc == loc) - continue - vents.Add(temp_vent) - var/list/choices = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents) - if(vent.loc.z != loc.z) - continue - var/atom/a = get_turf_loc(vent) - choices.Add(a.loc) - var/turf/startloc = loc - var/obj/selection = input("Select a destination.", "Duct System") in choices - var/selection_position = choices.Find(selection) - if(loc==startloc) - var/obj/target_vent = vents[selection_position] - if(target_vent) - for(var/mob/O in oviewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("[src] scrambles into the ventillation ducts!"), 1) - loc = target_vent.loc + if(stat == CONSCIOUS) + if(!lying) + var/obj/machinery/atmospherics/unary/vent_pump/vent_found + for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src)) + if(!v.welded) + vent_found = v else - src << "You need to remain still while entering a vent." + src << "\red That vent is welded." + if(vent_found) + if(vent_found.network&&vent_found.network.normal_members.len) + var/list/vents = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members) + if(temp_vent.loc == loc) + continue + vents.Add(temp_vent) + var/list/choices = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents) + if(vent.loc.z != loc.z) + continue + var/atom/a = get_turf_loc(vent) + choices.Add(a.loc) + var/turf/startloc = loc + var/obj/selection = input("Select a destination.", "Duct System") in choices + var/selection_position = choices.Find(selection) + if(loc==startloc) + if(contents.len) + for(var/obj/item/carried_item in contents)//If the monkey got on objects. + if(!istype(carried_item, /obj/item/weapon/implant))//If it's not an implant. + src << "\red You can't be carrying items or have items equipped when vent crawling!" + return + var/obj/target_vent = vents[selection_position] + if(target_vent) + for(var/mob/O in oviewers(src, null)) + if ((O.client && !( O.blinded ))) + O.show_message(text("[src] scrambles into the ventillation ducts!"), 1) + loc = target_vent.loc + else + src << "You need to remain still while entering a vent." + else + src << "This vent is not connected to anything." else - src << "This vent is not connected to anything." + src << "You must be standing on or beside an air vent to enter it." else - src << "You must be standing on or beside an air vent to enter it." + src << "You can't vent crawl while you're stunned!" else src << "You must be conscious to do this!" return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/shock.dm b/code/modules/mob/living/carbon/shock.dm index d7bca33368..f53ca6f66f 100644 --- a/code/modules/mob/living/carbon/shock.dm +++ b/code/modules/mob/living/carbon/shock.dm @@ -3,7 +3,7 @@ // proc to find out in how much pain the mob is at the moment /mob/living/carbon/proc/updateshock() - src.traumatic_shock = src.getOxyLoss() + src.getToxLoss() + src.getFireLoss() + 1.2*src.getBruteLoss() + 2*src.getCloneLoss() + src.traumatic_shock = src.getOxyLoss() + src.getToxLoss() + src.getFireLoss() + 1.2*src.getBruteLoss() + 2*src.getCloneLoss() + src.halloss if(reagents.has_reagent("alkysine")) src.traumatic_shock -= 10 if(reagents.has_reagent("inaprovaline")) diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index b1778089a8..78e4257cf8 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -22,18 +22,21 @@ adjustOxyLoss(damage/(blocked+1)) if(CLONE) adjustCloneLoss(damage/(blocked+1)) + if(HALLOSS) + adjustHalLoss(damage/(blocked+1)) UpdateDamageIcon() updatehealth() return 1 -/mob/living/proc/apply_damages(var/brute = 0, var/burn = 0, var/tox = 0, var/oxy = 0, var/clone = 0, var/def_zone = null, var/blocked = 0) +/mob/living/proc/apply_damages(var/brute = 0, var/burn = 0, var/tox = 0, var/oxy = 0, var/clone = 0, var/def_zone = null, var/blocked = 0, var/halloss = 0) if(blocked >= 2) return 0 if(brute) apply_damage(brute, BRUTE, def_zone, blocked) if(burn) apply_damage(burn, BURN, def_zone, blocked) if(tox) apply_damage(tox, TOX, def_zone, blocked) if(oxy) apply_damage(oxy, OXY, def_zone, blocked) if(clone) apply_damage(clone, CLONE, def_zone, blocked) + if(halloss) apply_damage(halloss, HALLOSS, def_zone, blocked) return 1 diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 28b98787c1..f272027a12 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1,3 +1,19 @@ +/mob/living/Life() + + ..() + + // While I'm doing a terriblly lazy way of initalizing things, why don't I make it so people's preferences tag along with them. This could be useful in fixing the fucking cloned-as-unknown thing, making me not have to dynamically load them during tensioner, and of course, storing metadata. + + if(!src.storedpreferences) + src.storedpreferences = new + storedpreferences.savefile_load(src, 0) + + + + + return + + /mob/living/verb/succumb() set hidden = 1 if ((src.health < 0 && src.health > -95.0)) @@ -227,6 +243,26 @@ else density = !lying + +/mob/living/proc/Examine_OOC() + set name = "Examine Meta-Info (OOC)" + set category = "OOC" + set src in view() + + if(config.allow_Metadata) + usr << "[src]'s Metainfo:" + + if(src.storedpreferences) + usr << "[src]'s OOC Notes: [src.storedpreferences.metadata]" + + else + usr << "[src] does not have any stored infomation!" + + else + usr << "OOC Metadata is not supported by this server!" + + return + /mob/living/attack_animal(mob/M) attack_paw(M) // treat it like a normal non-human attack diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 096a517213..1c459ef176 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -142,8 +142,9 @@ //world << "channel_prefix=[channel_prefix]; message_mode=[message_mode]" if (message_mode) message = trim(copytext(message, 3)) - if (!ishuman(src) && (message_mode=="department" || (message_mode in radiochannels))) + if (!(ishuman(src) || istype(src, /mob/living/simple_animal)) && (message_mode=="department" || (message_mode in radiochannels))) message_mode = null //only humans can use headsets + // Check removed so parrots can use headsets! if (!message) return diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index f693944133..3ab582828e 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -301,6 +301,14 @@ if (href_list["showalerts"]) ai_alerts() + //Carn: holopad requests + if (href_list["jumptoholopad"]) + var/obj/machinery/hologram/holopad/H = locate(href_list["jumptoholopad"]) + if(stat == CONSCIOUS) + if(H) + H.attack_ai(src) //may as well recycle + else + src << "Unable to locate the holopad." if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite var/L = text2num(href_list["lawc"]) diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index ce640fc219..79c4a7783c 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -34,7 +34,7 @@ emergency_shuttle.incall(2) log_game("All the AIs, comm consoles and boards are destroyed. Shuttle called.") message_admins("All the AIs, comm consoles and boards are destroyed. Shuttle called.", 1) - world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes." + captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.") world << sound('shuttlecalled.ogg') if(explosive) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 6e0908137b..78883f7ebd 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -2,9 +2,10 @@ canmove = 0 src.loc = paicard card = paicard - if(!card.radio) - card.radio = new /obj/item/device/radio(src.card) - radio = card.radio + if(card) + if(!card.radio) + card.radio = new /obj/item/device/radio(src.card) + radio = card.radio ..() diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index f5d9676013..30338c21fc 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -170,8 +170,14 @@ if(isnull(P)||P.toff) return + var/AnsweringMS = 0 for (var/obj/machinery/message_server/MS in world) MS.send_pda_message("[P.owner]","[src]","[t]") + if(MS.active) + AnsweringMS++ + + if(!AnsweringMS) + return tnote += "→ To [P.owner]:
    [t]
    " P.tnote += "← From [src]:
    [t]
    " @@ -195,12 +201,18 @@ else var/mob/living/silicon/pai/P = target - tnote += "→ To [P]:
    [t]
    " - P.tnote += "← From [src]:
    [t]
    " - - + var/AnsweringMS = 0 for (var/obj/machinery/message_server/MS in world) MS.send_pda_message("[P]","[src]","[t]") + if(MS.active) + AnsweringMS++ + + if(!AnsweringMS) + return + + + tnote += "→ To [P]:
    [t]
    " + P.tnote += "← From [src]:
    [t]
    " if (prob(15)) //Give the AI a chance of intercepting the message var/who = src diff --git a/code/modules/mob/living/silicon/robot/laws.dm b/code/modules/mob/living/silicon/robot/laws.dm index e7f4904ede..5afa42ee14 100644 --- a/code/modules/mob/living/silicon/robot/laws.dm +++ b/code/modules/mob/living/silicon/robot/laws.dm @@ -93,4 +93,97 @@ /mob/living/silicon/robot/proc/clear_ion_laws() laws_sanity_check() - laws.clear_ion_laws() \ No newline at end of file + laws.clear_ion_laws() + +/mob/living/silicon/robot/proc/statelaws() // -- TLE +// set category = "AI Commands" +// set name = "State Laws" + src.say("Current Active Laws:") + //src.laws_sanity_check() + //src.laws.show_laws(world) + var/number = 1 + sleep(10) + + + + if (src.laws.zeroth) + if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite + src.say("0. [src.laws.zeroth]") + sleep(10) + + for (var/index = 1, index <= src.laws.ion.len, index++) + var/law = src.laws.ion[index] + var/num = ionnum() + if (length(law) > 0) + if (src.ioncheck[index] == "Yes") + src.say("[num]. [law]") + sleep(10) + + for (var/index = 1, index <= src.laws.inherent.len, index++) + var/law = src.laws.inherent[index] + + if (length(law) > 0) + if (src.lawcheck[index+1] == "Yes") + src.say("[number]. [law]") + sleep(10) + number++ + + + for (var/index = 1, index <= src.laws.supplied.len, index++) + var/law = src.laws.supplied[index] + + if (length(law) > 0) + if(src.lawcheck.len >= number+1) + if (src.lawcheck[number+1] == "Yes") + src.say("[number]. [law]") + sleep(10) + number++ + + +/mob/living/silicon/robot/verb/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite + set category = "Robot Commands" + set name = "State Laws" + + var/list = "Which laws do you want to include when stating them for the crew?

    " + + + + if (src.laws.zeroth) + if (!src.lawcheck[1]) + src.lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite + list += {"[src.lawcheck[1]] 0: [src.laws.zeroth]
    "} + + for (var/index = 1, index <= src.laws.ion.len, index++) + var/law = src.laws.ion[index] + + if (length(law) > 0) + + + if (!src.ioncheck[index]) + src.ioncheck[index] = "Yes" + list += {"[src.ioncheck[index]] [ionnum()]: [law]
    "} + src.ioncheck.len += 1 + + var/number = 1 + for (var/index = 1, index <= src.laws.inherent.len, index++) + var/law = src.laws.inherent[index] + + if (length(law) > 0) + src.lawcheck.len += 1 + + if (!src.lawcheck[number+1]) + src.lawcheck[number+1] = "Yes" + list += {"[src.lawcheck[number+1]] [number]: [law]
    "} + number++ + + for (var/index = 1, index <= src.laws.supplied.len, index++) + var/law = src.laws.supplied[index] + if (length(law) > 0) + src.lawcheck.len += 1 + if (!src.lawcheck[number+1]) + src.lawcheck[number+1] = "Yes" + list += {"[src.lawcheck[number+1]] [number]: [law]
    "} + number++ + list += {"

    State Laws"} + + usr << browse(list, "window=laws") \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 4009499c82..6a07be5709 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -15,19 +15,31 @@ name = real_name spawn (4) - if (client) - connected_ai = activeais() - if (connected_ai) - connected_ai.connected_robots += src -// laws = connected_ai.laws //The borg inherits its AI's laws - laws = new /datum/ai_laws - lawsync() - src << "Unit slaved to [connected_ai.name], downloading laws." - lawupdate = 1 + if(!syndie) + if (client) + connected_ai = activeais() + if (connected_ai) + connected_ai.connected_robots += src + // laws = connected_ai.laws //The borg inherits its AI's laws + laws = new /datum/ai_laws + lawsync() + src << "Unit slaved to [connected_ai.name], downloading laws." + lawupdate = 1 + else + laws = new /datum/ai_laws/asimov + lawupdate = 0 + src << "Unable to locate an AI, reverting to standard Asimov laws." else - laws = new /datum/ai_laws/nanotrasen + laws = new /datum/ai_laws/antimov lawupdate = 0 - src << "Unable to locate an AI, reverting to standard NanoTrasen laws." + scrambledcodes = 1 + src << "Follow your laws." + cell.maxcharge = 25000 + cell.charge = 25000 + module = new /obj/item/weapon/robot_module/syndicate(src) + hands.icon_state = "standard" + icon_state = "secborg" + modtype = "Synd" radio = new /obj/item/device/radio(src) camera = new /obj/machinery/camera(src) @@ -46,6 +58,12 @@ /mob/living/silicon/robot/Del() if(mmi)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside. mmi.loc = get_turf(loc)//To hopefully prevent run time errors. + + if(!key) + for(var/mob/dead/observer/ghost in world) + if(ghost.corpse == src && ghost.client) + ghost.client.mob = ghost.corpse + if(key)//If there is a client attached to host. if(client) client.screen.len = null @@ -130,6 +148,8 @@ if (sprite == "Non-Humanoid") src.icon_state = "bloodhound" modtype = "Sec" + //speed = -1 Secborgs have nerfed tasers now, so the speed boost is not necessary + nopush = 1 channels = list("Security" = 1) //feedback_inc("cyborg_security",1) @@ -200,6 +220,20 @@ viewalerts = 1 src << browse(dat, "window=robotalerts&can_close=0") +/mob/living/silicon/robot/proc/ai_roster() + set category = "Robot Commands" + set name = "Show Crew Manifest" + + var/dat = "Crew RosterCrew Roster:

    " + + for (var/datum/data/record/t in data_core.general) + dat += "[t.fields["name"]] - [t.fields["rank"]]
    " + + dat += "" + + src << browse(dat, "window=airoster") + onclose(src, "airoster") + /mob/living/silicon/robot/blob_act() if (stat != 2) adjustBruteLoss(60) @@ -517,6 +551,24 @@ if(prob(25)) src << "Hack attempt detected." return + + else if(istype(W, /obj/item/borg/upgrade/)) + var/obj/item/borg/upgrade/U = W + if(!opened) + usr << "You must access the borgs internals!" + else if(!src.module && U.require_module) + usr << "The borg must choose a module before he can be upgraded!" + else if(U.locked) + usr << "The upgrade is locked and cannot be used yet!" + else + if(U.action(src)) + usr << "You apply the upgrade to [src]!" + usr.drop_item() + U.loc = src + else + usr << "Upgrade error!" + + else spark_system.start() return ..() @@ -930,6 +982,26 @@ else src << "Module isn't activated" installed_modules() + + if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite + var/L = text2num(href_list["lawc"]) + switch(lawcheck[L+1]) + if ("Yes") lawcheck[L+1] = "No" + if ("No") lawcheck[L+1] = "Yes" +// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1]) + checklaws() + + if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite + var/L = text2num(href_list["lawi"]) + switch(ioncheck[L]) + if ("Yes") ioncheck[L] = "No" + if ("No") ioncheck[L] = "Yes" +// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1]) + checklaws() + + if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite + statelaws() + return /mob/living/silicon/robot/proc/uneq_active() @@ -1095,7 +1167,26 @@ Frequency: . = ..() if ((s_active && !( s_active in contents ) )) s_active.close(src) - return + + if(module) + if(module.type == /obj/item/weapon/robot_module/janitor) //you'd think checking the module would work + var/turf/tile = get_turf(loc) + + tile.clean_blood() + for(var/obj/effect/R in tile) + if(istype(R, /obj/effect/rune) || istype(R, /obj/effect/decal/cleanable) || istype(R, /obj/effect/overlay)) + del(R) + + for(var/obj/item/cleaned_item in tile) + cleaned_item.clean_blood() + + for(var/mob/living/carbon/human/cleaned_human in tile) //HUE HUE I CLEAN U + if(cleaned_human.lying) + cleaned_human.clean_blood() + cleaned_human << "\red [src] cleans your face!" + for(var/obj/item/carried_item in cleaned_human.contents) + carried_item.clean_blood() + return /mob/living/silicon/robot/proc/reset_module() modtype = "robot" @@ -1111,3 +1202,32 @@ Frequency: gib() return +/mob/living/silicon/robot/proc/UnlinkSelf() + if (src.connected_ai) + src.connected_ai = null + lawupdate = 0 + lockcharge = 0 + canmove = 1 + scrambledcodes = 1 + + + +/mob/living/silicon/robot/proc/ResetSecurityCodes() + set category = "Robot Commands" + set name = "Reset Identity Codes" + set desc = "Scrambles your security and identification codes and resets your current buffers. Unlocks you and but permenantly severs you from your AI and the robotics console." + + var/mob/living/silicon/robot/R = usr + + if(R) + R.UnlinkSelf() + R << "Buffers flushed and reset. All systems operational." + src.verbs -= /mob/living/silicon/robot/proc/ResetSecurityCodes + + +/mob/living/silicon/robot/proc/flashproof() + if(module) + for(var/obj/item/borg/upgrade/flashproof/F in module.modules) + return 1 + + return 0 \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index ffe76a3b76..ea5a00afb5 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -163,9 +163,7 @@ New() ..() - src.modules += new /obj/item/weapon/cleaner(src) - src.modules += new /obj/item/weapon/mop(src) - src.modules += new /obj/item/weapon/reagent_containers/glass/bucket(src) + src.modules += new /obj/item/weapon/soap/nanotrasen(src) src.modules += new /obj/item/weapon/trashbag(src) src.emag = new /obj/item/weapon/cleaner(src) @@ -230,5 +228,8 @@ New() + src.modules += new /obj/item/weapon/melee/energy/sword(src) + src.modules += new /obj/item/weapon/gun/energy/pulse_rifle/destroyer(src) src.modules += new /obj/item/weapon/card/emag(src) + src.modules += new /obj/item/weapon/tank/jetpack/oxygen(src) return diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index f0a907d05d..74522c2b0d 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -5,3 +5,11 @@ if(J.allow_thrust(0.01)) return 1 if(..()) return 1 return 0 + + //No longer needed, but I'll leave it here incase we plan to re-use it. +/mob/living/silicon/robot/movement_delay() + var/tally = 0 //Incase I need to add stuff other than "speed" later + + tally = speed + + return tally diff --git a/code/modules/mob/living/silicon/robot/robot_upgrades.dm b/code/modules/mob/living/silicon/robot/robot_upgrades.dm new file mode 100644 index 0000000000..fe8d77dd7c --- /dev/null +++ b/code/modules/mob/living/silicon/robot/robot_upgrades.dm @@ -0,0 +1,113 @@ +// robot_upgrades.dm +// Contains various borg upgrades. + +/obj/item/borg/upgrade/ + name = "A borg upgrade module." + desc = "Protected by FRM." + icon = 'module.dmi' + icon_state = "id_mod" + 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() + return + + +/obj/item/borg/upgrade/reset/ + name = "Borg module reset board" + desc = "Used to reset a borg's module. Destroys any other upgrades applied to the borg." + require_module = 1 + +/obj/item/borg/upgrade/reset/action(var/mob/living/silicon/robot/R) + R.uneq_all() + R.hands.icon_state = "nomod" + R.icon_state = "robot" + del(R.module) + R.module = null + R.modtype = "robot" + R.real_name = "Cyborg [R.ident]" + R.name = R.real_name + R.nopush = 0 + R.updateicon() + + return 1 + + + +/obj/item/borg/upgrade/flashproof/ + name = "Borg Flash-Supression" + desc = "A highly advanced, complicated system for supressing incoming flashes directed at the borg's optical processing system." + construction_cost = list("metal"=10000,"gold"=2000,"silver"=3000,"glass"=2000, "diamond"=5000) + require_module = 1 + + +/obj/item/borg/upgrade/flashproof/New() // Why the fuck does the fabricator make a new instance of all the items? + //desc = "Sunglasses with duct tape." // Why? D: + +/obj/item/borg/upgrade/flashproof/action(var/mob/living/silicon/robot/R) + if(R.module) + R.module += src + + return 1 + +/obj/item/borg/upgrade/restart/ + name = "Borg emergancy restart module" + desc = "Used to force a restart of a disabled-but-repaired borg, bringing it back online." + construction_cost = list("metal"=60000 , "glass"=5000) + + +/obj/item/borg/upgrade/restart/action(var/mob/living/silicon/robot/R) + if(!R.key) + for(var/mob/dead/observer/ghost in world) + if(ghost.corpse == R && ghost.client) + ghost.client.mob = ghost.corpse + + if(R.health < 0) + usr << "You have to repair the borg before using this module!" + return 0 + + R.stat = 0 + return 1 + + +/obj/item/borg/upgrade/vtec/ + name = "Borg VTEC Module" + desc = "Used to kick in a borgs VTEC systems, increasing their speed." + construction_cost = list("metal"=80000 , "glass"=6000 , "gold"= 5000) + require_module = 1 + +/obj/item/borg/upgrade/vtec/action(var/mob/living/silicon/robot/R) + if(R.speed == -1) + return 0 + + R.speed-- + return 1 + + +/obj/item/borg/upgrade/tasercooler/ + name = "Borg 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) + require_module = 1 + + +/obj/item/borg/upgrade/tasercooler/action(var/mob/living/silicon/robot/R) + if(R.module != /obj/item/weapon/robot_module/security) + R << "Upgrade mounting error! No suitable hardpoint detected!" + return 0 + + var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in R + if(!T) + return 0 + + if(T.recharge_time <= 2) + R << "Maximum cooling achieved for this hardpoint!" + return 0 + + else + T.recharge_time = min(2 , T.recharge_time - 4) + + return 1 \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index fa15f854fd..f3355dba7f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -420,7 +420,7 @@ set src in usr if(usr != src) usr << "No." - var/msg = input(usr,"Set the flavor text in your 'examine' verb. Don't metagame!","Flavor Text",html_decode(flavor_text)) as message|null + var/msg = input(usr,"Set the flavor text in your 'examine' verb. Can also be used for OOC notes about your character.","Flavor Text",html_decode(flavor_text)) as message|null if(msg != null) msg = copytext(msg, 1, MAX_MESSAGE_LEN) @@ -454,14 +454,35 @@ set category = "OOC" if (!( abandon_allowed )) + usr << "\blue Respawn is disabled." return if ((stat != 2 || !( ticker ))) usr << "\blue You must be dead to use this!" return + if (ticker.mode.name == ("meteor" || "epidemic")) + usr << "\blue Respawn is disabled." + return + else + var/deathtime = world.time - src.timeofdeath + var/deathtimeminutes = round(deathtime / 600) + var/pluralcheck = "minute" + if(deathtimeminutes == 0) + pluralcheck = "" + else if(deathtimeminutes == 1) + pluralcheck = " [deathtimeminutes] minute and" + else if(deathtimeminutes > 1) + pluralcheck = " [deathtimeminutes] minutes and" + var/deathtimeseconds = round((deathtime - deathtimeminutes * 600) / 10,1) + usr << "You have been dead for[pluralcheck] [deathtimeseconds] seconds." + if (deathtime < 18000) + usr << "You must wait 30 minutes to respawn!" + return + else + usr << "You can respawn now, enjoy your new life!" log_game("[usr.name]/[usr.key] used abandon mob.") - usr << "\blue Please roleplay correctly!" + usr << "\blue Make sure to play a different character, and please roleplay correctly!" if(!client) log_game("[usr.key] AM failed due to disconnect.") @@ -516,6 +537,19 @@ else usr << "\blue Now you hear speech only from nearest creatures." +/client/var/ghost_sight = 1 +/client/verb/toggle_ghost_sight() + set name = "Ghost sight" + set category = "OOC" + set desc = "Hear emotes from everywhere" + ghost_sight = !ghost_sight + if (ghost_sight) + usr << "\blue Now you hear all emotes in the world" + else + usr << "\blue Now you hear emotes only from nearest creatures." + + + /mob/verb/observe() set name = "Observe" set category = "OOC" @@ -1149,3 +1183,66 @@ note dizziness decrements automatically in the mob's Life() proc. /mob/proc/AdjustParalysis(amount) paralysis = max(paralysis + amount,0) return + +// ++++ROCKDTBEN++++ MOB PROCS -- Ask me before touching + +/mob/proc/getBruteLoss() + return bruteloss + +/mob/proc/adjustBruteLoss(var/amount) + bruteloss = max(bruteloss + amount, 0) + +/mob/proc/getOxyLoss() + return oxyloss + +/mob/proc/adjustOxyLoss(var/amount) + oxyloss = max(oxyloss + amount, 0) + +/mob/proc/setOxyLoss(var/amount) + oxyloss = amount + +/mob/proc/getToxLoss() + return toxloss + +/mob/proc/adjustToxLoss(var/amount) + toxloss = max(toxloss + amount, 0) + +/mob/proc/setToxLoss(var/amount) + toxloss = amount + +/mob/proc/getFireLoss() + return fireloss + +/mob/proc/adjustFireLoss(var/amount) + fireloss = max(fireloss + amount, 0) + +/mob/proc/getCloneLoss() + return cloneloss + +/mob/proc/adjustCloneLoss(var/amount) + cloneloss = max(cloneloss + amount, 0) + +/mob/proc/setCloneLoss(var/amount) + cloneloss = amount + +/mob/proc/getHalLoss() + return halloss + +/mob/proc/adjustHalLoss(var/amount) + halloss = max(halloss + amount, 0) + +/mob/proc/setHalLoss(var/amount) + halloss = amount + + + +/mob/proc/getBrainLoss() + return brainloss + +/mob/proc/adjustBrainLoss(var/amount) + brainloss = max(brainloss + amount, 0) + +/mob/proc/setBrainLoss(var/amount) + brainloss = amount + +// ++++ROCKDTBEN++++ MOB PROCS //END \ No newline at end of file diff --git a/code/modules/mob/mob_cleanup.dm b/code/modules/mob/mob_cleanup.dm index 0e167a6c5e..766d695597 100644 --- a/code/modules/mob/mob_cleanup.dm +++ b/code/modules/mob/mob_cleanup.dm @@ -93,7 +93,7 @@ Put (mob/proc)s here that are in dire need of a code cleanup. switch(target_zone) if(1) - if(isobj(H.head)) + if(isobj(H.head) && !istype(H.head, /obj/item/weapon/paper)) Cl = H.head passed = prob(Cl.permeability_coefficient*100*virus.permeability_mod) // world << "Head pass [passed]" @@ -191,4 +191,4 @@ Put (mob/proc)s here that are in dire need of a code cleanup. if(prob(5)) v.carrier = 1 return - return \ No newline at end of file + return diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 1da6a25f4f..06c4c9cd50 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -201,6 +201,7 @@ //clumsy = 16 //obese = 32 //husk = 64 + var/tkdisable = 0//For remote viewing and stuff. Disables TK. var/voice_name = "unidentifiable voice" var/voice_message = null // When you are not understood by others (replaced with just screeches, hisses, chimpers etc.) @@ -282,64 +283,10 @@ the mob is also allowed to move without any sort of restriction. For instance, i var/digitalcamo = 0 // Can they be tracked by the AI? - var/list/organs = list( ) //List of organs. var/list/organs2 = list() //Singularity wants you! var/grav_delay = 0 var/being_strangled = 0 - - -// ++++ROCKDTBEN++++ MOB PROCS - -/mob/proc/getBruteLoss() - return bruteloss - -/mob/proc/adjustBruteLoss(var/amount) - bruteloss = max(bruteloss + amount, 0) - -/mob/proc/getOxyLoss() - return oxyloss - -/mob/proc/adjustOxyLoss(var/amount) - oxyloss = max(oxyloss + amount, 0) - -/mob/proc/setOxyLoss(var/amount) - oxyloss = amount - -/mob/proc/getToxLoss() - return toxloss - -/mob/proc/adjustToxLoss(var/amount) - toxloss = max(toxloss + amount, 0) - -/mob/proc/setToxLoss(var/amount) - toxloss = amount - -/mob/proc/getFireLoss() - return fireloss - -/mob/proc/adjustFireLoss(var/amount) - fireloss = max(fireloss + amount, 0) - -/mob/proc/getCloneLoss() - return cloneloss - -/mob/proc/adjustCloneLoss(var/amount) - cloneloss = max(cloneloss + amount, 0) - -/mob/proc/setCloneLoss(var/amount) - cloneloss = amount - -/mob/proc/getBrainLoss() - return brainloss - -/mob/proc/adjustBrainLoss(var/amount) - brainloss = max(brainloss + amount, 0) - -/mob/proc/setBrainLoss(var/amount) - brainloss = amount - -// ++++ROCKDTBEN++++ MOB PROCS //END - + var/datum/preferences/storedpreferences = null diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index b68d9f0761..7f887d4215 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -89,6 +89,8 @@ /obj/item/weapon/grab/proc/s_click(obj/screen/S as obj) + if (!affecting) + return if (assailant.next_move > world.time) return if ((!( assailant.canmove ) || assailant.lying)) diff --git a/code/modules/mob/new_player/preferences.dm b/code/modules/mob/new_player/preferences.dm index 8e23153041..bd7722a90c 100644 --- a/code/modules/mob/new_player/preferences.dm +++ b/code/modules/mob/new_player/preferences.dm @@ -129,6 +129,10 @@ datum/preferences skill_specialization = null list/skills = list() // skills can range from 0 to 3 + // OOC Metadata: + metadata = "" + + New() hair_style = new/datum/sprite_accessory/hair/short facial_hair_style = new/datum/sprite_accessory/facial_hair/shaved @@ -243,6 +247,10 @@ datum/preferences dat += "UI Style: [UI == UI_NEW ? "New" : "Old"]
    " dat += "Play admin midis: [midis == 1 ? "Yes" : "No"]
    " dat += "Ghost ears: [ghost_ears == 0 ? "Nearest Creatures" : "All Speech"]
    " + dat += "Ghost sight: [ghost_sight == 0 ? "Nearest Creatures" : "All Emotes"]
    " + + if(config.allow_Metadata) + dat += "OOC Notes: Edit
    " if((user.client) && (user.client.holder) && (user.client.holder.rank) && (user.client.holder.rank == "Game Master")) dat += "
    OOC
    " @@ -539,6 +547,8 @@ datum/preferences proc/process_link(mob/user, list/link_tags) + if(!usr) + return if(link_tags["occ"]) if(link_tags["cancel"]) user << browse(null, "window=\ref[user]occupation") @@ -634,11 +644,29 @@ datum/preferences if(link_tags["age"]) switch(link_tags["age"]) if("input") - var/new_age = input(user, "Please select type in age: 15-45", "Character Generation") as num + var/new_age = input(user, "Please enter an age ([minimum_age]-[maximum_age])", "Character Generation") as num if(new_age) - age = max(min(round(text2num(new_age)), 45), 15) + age = max(min(round(text2num(new_age)), maximum_age), minimum_age) if("random") - age = rand (20, 45) + age = rand (minimum_age, maximum_age) + + if(link_tags["OOC"]) + var/tempnote = "" + tempnote = input(user, "Please enter your OOC Notes!:", "OOC notes" , metadata) as text + var/list/bad_characters = list("_", "\"", "<", ">", ";", "\[", "\]", "{", "}", "|", "\\","0","1","2","3","4","5","6","7","8","9") + + for(var/c in bad_characters) + tempnote = dd_replacetext(tempnote, c, "") + + if(length(tempnote) >= 255) + alert("That name is too long. (255 character max, please)") + return + + metadata = tempnote + return + + + if(link_tags["b_type"]) switch(link_tags["b_type"]) @@ -783,6 +811,9 @@ datum/preferences if(link_tags["ghost_ears"]) ghost_ears = !ghost_ears + if(link_tags["ghost_sight"]) + ghost_sight = !ghost_sight + if(link_tags["underwear"]) switch(link_tags["underwear"]) if("inputmale") @@ -991,6 +1022,7 @@ datum/preferences C.be_syndicate = be_special if(isnull(src.ghost_ears)) src.ghost_ears = 1 //There were problems where the default was null before someone saved their profile. C.ghost_ears = src.ghost_ears + C.ghost_sight = src.ghost_sight proc/copydisabilities(mob/living/carbon/human/character) if(disabilities & 1) @@ -1012,4 +1044,4 @@ datum/preferences character.disabilities = disabilities #undef UI_OLD -#undef UI_NEW \ No newline at end of file +#undef UI_NEW diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index b75fef33f1..1fc8921a9f 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -15,7 +15,7 @@ datum/preferences underwear = 1 backbag = 2 b_type = pick("A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-") - age = rand(19,35) + age = rand(minimum_age, maximum_age) copy_to(H,1) proc/randomize_name() @@ -263,4 +263,4 @@ datum/preferences if(H.name == f_style) facial_hair_style = H else - del(H) \ No newline at end of file + del(H) diff --git a/code/modules/mob/new_player/savefile.dm b/code/modules/mob/new_player/savefile.dm index 39f0151271..48f44415f7 100644 --- a/code/modules/mob/new_player/savefile.dm +++ b/code/modules/mob/new_player/savefile.dm @@ -141,6 +141,7 @@ datum/preferences/proc/savefile_save(mob/user, slot) F["UI"] << src.UI F["midis"] << src.midis F["ghost_ears"] << src.ghost_ears + F["ghost_sight"] << src.ghost_sight F["pregame_music"] << src.pregame_music F["ooccolor"] << src.ooccolor F["lastchangelog"] << src.lastchangelog @@ -150,6 +151,8 @@ datum/preferences/proc/savefile_save(mob/user, slot) F["skills"] << src.skills F["skill_specialization"] << src.skill_specialization + F["OOC_Notes"] << src.metadata + return 1 // loads the savefile corresponding to the mob's ckey @@ -212,6 +215,8 @@ datum/preferences/proc/savefile_load(mob/user, slot) F["ghost_ears"] >> src.ghost_ears if(isnull(ghost_ears)) ghost_ears = 1 //Hotfix F["pregame_music"] >> src.pregame_music + F["ghost_sight"] >> src.ghost_sight + if(isnull(ghost_sight)) ghost_sight = 1 //Hotfix F["ooccolor"] >> src.ooccolor F["lastchangelog"] >> src.lastchangelog F["UI"] >> src.UI @@ -244,6 +249,11 @@ datum/preferences/proc/savefile_load(mob/user, slot) if(!job_alt_titles) job_alt_titles = new() + F["OOC_Notes"] >> src.metadata + + if(isnull(metadata)) + metadata = "" + //NOTE: Conversion things go inside this if statement //When updating the save file remember to add 1 to BOTH the savefile constants //Also take the old conversion things that no longer apply out of this if diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index a0c5ec9815..b22fcc461e 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -58,6 +58,14 @@ name = "Longest Hair" icon_state = "hair_vlong" + longalt + name = "Long Hair Alt" + icon_state = "hair_longfringe" + + longestalt + name = "Longest Hair Alt" + icon_state = "hair_vlongfringe" + halfbang name = "Half-banged Hair" icon_state = "hair_halfbang" @@ -89,6 +97,7 @@ mohawk name = "Mohawk" icon_state = "hair_d" + choose_female = 0 // gross balding name = "Balding Hair" @@ -118,6 +127,7 @@ dreadlocks name = "Dreadlocks" icon_state = "hair_dreads" + choose_female = 0 // okay.jpg jensen name = "Adam Jensen Hair" @@ -132,14 +142,6 @@ icon_state = "bald" choose_female = 0 - longalt - name = "Long Hair Alt" - icon_state = "hair_longfringe" - - longestalt - name = "Longest Hair Alt" - icon_state = "hair_vlongfringe" - himecut name = "Hime Cut" icon_state = "hair_himecut" @@ -148,6 +150,9 @@ name = "Curls" icon_state = "hair_curls" + spikey + name = "Spikey" + icon_state = "hair_spikey" /* /////////////////////////////////// diff --git a/code/modules/mob/screen.dm b/code/modules/mob/screen.dm index bdc63af18e..07343b0c6c 100644 --- a/code/modules/mob/screen.dm +++ b/code/modules/mob/screen.dm @@ -456,13 +456,16 @@ if("hand") usr:swap_hand() if("resist") - if(usr.next_move < world.time) + if(usr.next_move > world.time) return usr.next_move = world.time + 20 if ((!( usr.stat ) && usr.canmove && !( usr.restrained() ))) + var/resisting = 0 for(var/obj/O in usr.requests) del(O) + resisting++ for(var/obj/item/weapon/grab/G in usr.grabbed_by) + resisting++ if (G.state == 1) del(G) else @@ -477,9 +480,9 @@ for(var/mob/O in viewers(usr, null)) O.show_message(text("\red [] has broken free of []'s headlock!", usr, G.assailant), 1) del(G) - for(var/mob/O in viewers(usr, null)) - O.show_message(text("\red [] resists!", usr), 1) - + if(resisting) + for(var/mob/O in viewers(usr, null)) + O.show_message(text("\red [] resists!", usr), 1) if(usr:handcuffed && usr:canmove && (usr.last_special <= world.time)) var/breakouttime = 1200 var/displaytime = 2 @@ -494,7 +497,8 @@ O.show_message(text("\red [] is trying to break the handcuffs!", usr), 1) spawn(0) if(do_after(usr, 50)) - if(!usr:handcuffed || usr:buckled) return + if(!usr:handcuffed || usr:buckled) + return for(var/mob/O in viewers(usr)) O.show_message(text("\red [] manages to break the handcuffs!", usr), 1) usr << "\green You successfully break your handcuffs." @@ -569,11 +573,14 @@ O.show_message(text("\red [] attempts to unbuckle themself!", usr), 1) spawn(0) if(do_after(usr, 1200)) - if(!usr:buckled) return + if(!usr:buckled) + return for(var/mob/O in viewers(usr)) O.show_message(text("\red [] manages to unbuckle themself!", usr), 1) usr << "\blue You successfully unbuckle yourself." usr:buckled.manual_unbuckle(usr) + + if("module") if(issilicon(usr)) if(usr:module) diff --git a/code/modules/mob/simple_animal/cat.dm b/code/modules/mob/simple_animal/cat.dm index 18c06a62a2..f75db3dc16 100644 --- a/code/modules/mob/simple_animal/cat.dm +++ b/code/modules/mob/simple_animal/cat.dm @@ -12,6 +12,7 @@ emote_see = list("shakes its head", "shivers") speak_chance = 1 turns_per_move = 5 + see_in_dark = 6 meat_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meat response_help = "pets the" response_disarm = "gently pushes aside the" diff --git a/code/modules/mob/simple_animal/corgi.dm b/code/modules/mob/simple_animal/corgi.dm index 2cf1138d77..a6e7e687a2 100644 --- a/code/modules/mob/simple_animal/corgi.dm +++ b/code/modules/mob/simple_animal/corgi.dm @@ -18,6 +18,7 @@ response_help = "pets the" response_disarm = "gently pushes aside the" response_harm = "kicks the" + see_in_dark = 5 var/obj/item/inventory_head var/obj/item/inventory_back var/obj/item/inventory_mouth @@ -392,8 +393,4 @@ dir = i sleep(1) else - ..() - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/meat/corgi - name = "Corgi meat" - desc = "Tastes like... well you know..." \ No newline at end of file + ..() \ No newline at end of file diff --git a/code/modules/mob/simple_animal/parrot.dm b/code/modules/mob/simple_animal/parrot.dm new file mode 100644 index 0000000000..fd2135060f --- /dev/null +++ b/code/modules/mob/simple_animal/parrot.dm @@ -0,0 +1,91 @@ +/mob/living/simple_animal/parrot + name = "\improper Parrot" + desc = "It's a parrot! No dirty words!" + icon = 'mob.dmi' + icon_state = "cat" + icon_living = "cat" + icon_dead = "cat_dead" + speak = list("Hi","Hello!","Cracker?","BAWWWWK george mellons griffing me") + speak_emote = list("squawks","says","yells") + emote_hear = list("squawks","bawks") + emote_see = list("flutters its wings", "glares at you") + speak_chance = 1 + turns_per_move = 5 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/cracker/ + response_help = "pets the" + response_disarm = "gently moves aside the" + response_harm = "swats the" + + ears = new /obj/item/device/radio/headset/heads/ce() + +/mob/living/simple_animal/parrot/DrProfessor + name = "Doctor Professor Parrot, PhD" + desc = "That's the Doctor Professor. He has more degrees than all of the engineering team put together, and has several published papers on quantum cracker theory." + speak = list(":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN RIG SUIT?",":e OH GOD ITS FREE CALL THE SHUTTLE") + response_harm = "is attacked in the face by" + +/obj/item/weapon/reagent_containers/food/snacks/cracker/ + name = "Cracker" + desc = "It's a salted cracker." + +/mob/living/simple_animal/parrot/show_inv(mob/user as mob) + user.machine = src + if(user.stat) return + + var/dat = "
    Inventory of [name]

    " + if(ears) + dat += "
    Headset: [ears] (Remove)" + else + dat += "
    Headset: Nothing" + + user << browse(dat, text("window=mob[];size=325x500", name)) + onclose(user, "mob[real_name]") + return + + + +/mob/living/simple_animal/parrot/Topic(href, href_list) + if(usr.stat) return + + //Removing from inventory + if(href_list["remove_inv"]) + if(get_dist(src,usr) > 1 || !(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr))) + return + var/remove_from = href_list["remove_inv"] + switch(remove_from) + if("ears") + if(ears) + src.say(":e BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") + ears.loc = src.loc + ears = null + else + usr << "\red There is nothing to remove from its [remove_from]." + return + + //Adding things to inventory + else if(href_list["add_inv"]) + if(get_dist(src,usr) > 1 || !(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr))) + return + var/add_to = href_list["add_inv"] + if(!usr.get_active_hand()) + usr << "\red You have nothing in your hand to put on its [add_to]." + return + switch(add_to) + if("ears") + if(ears) + usr << "\red It's already wearing something." + return + else + var/obj/item/item_to_add = usr.get_active_hand() + if(!item_to_add) + return + + if( !istype(item_to_add, /obj/item/device/radio/headset) ) + usr << "\red This object won't fit." + return + + usr.drop_item() + item_to_add.loc = src + src.ears = item_to_add + else + ..() diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 8b20858d69..fdaa37fb57 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -101,13 +101,13 @@ for(var/obj/effect/landmark/start/sloc in world) if (sloc.name != "AI") continue - if (locate(/mob) in sloc.loc) + if (locate(/mob/living) in sloc.loc) continue loc_landmark = sloc if (!loc_landmark) for(var/obj/effect/landmark/tripai in world) if (tripai.name == "tripai") - if(locate(/mob) in tripai.loc) + if(locate(/mob/living) in tripai.loc) continue loc_landmark = tripai if (!loc_landmark) @@ -190,7 +190,8 @@ O.invisibility = 0 O.name = "Cyborg" O.real_name = "Cyborg" - O.lastKnownIP = client.address ? client.address : null + if(client) + O.lastKnownIP = client.address ? client.address : null if (mind) mind.transfer_to(O) if (mind.assigned_role == "Cyborg") @@ -212,6 +213,8 @@ O << "To use something, simply click or double-click it." O << {"Use say ":s to speak to fellow cyborgs and the AI through binary."} + O.verbs += /mob/living/silicon/robot/proc/ai_roster + O.job = "Cyborg" O.mmi = new /obj/item/device/mmi(O) @@ -335,4 +338,81 @@ new_corgi << "You are now a Corgi!." spawn(0)//To prevent the proc from returning null. del(src) - return \ No newline at end of file + return + +/mob/living/carbon/human/AIizeSilent() + if (monkeyizing) + return + for(var/name in organs) + del(organs[name]) + + if(client) + src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // stop the jams for AIs + return ..() + +/mob/living/carbon/AIizeSilent() + if (monkeyizing) + return + for(var/obj/item/W in src) + drop_from_slot(W) + update_clothing() + monkeyizing = 1 + canmove = 0 + icon = null + invisibility = 101 + return ..() + +/mob/proc/AIizeSilent() + if(client) + client.screen.len = null + var/mob/living/silicon/ai/O = new (loc, /datum/ai_laws/nanotrasen,,1)//No MMI but safety is in effect. + O.invisibility = 0 + O.aiRestorePowerRoutine = 0 + O.lastKnownIP = client.address + + if(mind) + mind.transfer_to(O) + O.mind.original = O + else + O.mind = new + O.mind.current = O + O.mind.original = O + O.mind.assigned_role = "AI" + O.key = key + + if(!(O.mind in ticker.minds)) + ticker.minds += O.mind//Adds them to regular mind list. + + O << "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras)." + O << "To look at other parts of the station, double-click yourself to get a camera menu, use the freelook command, or use the Show Camera List command.." + O << "While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc." + O << "To use something, simply click or double-click it." + O << "Currently right-click functions will not work for the AI (except examine), and will either be replaced with dialogs or won't be usable by the AI." + if (!(ticker && ticker.mode && (O.mind in ticker.mode.malf_ai))) + O.show_laws() + O << "These laws may be changed by other players, or by you being the traitor." + O << "
    IMPORTANT GAMEPLAY ASPECTS:" + O << "1.) Act like an AI. If someone is breaking into your upload, say something like \"Alert. Unauthorised Access Detected: AI Upload.\" not \"Help! Urist is trying to subvert me!\"" + O << "2.) Do not watch the traitor like a hawk alerting the station to his/her every move. This relates to 1." + O << "3.) You are theoretically omniscient, but you should not be Beepsky 5000, laying down the law left and right. That is security's job. Instead, try to keep the station productive and effective. (Feel free to report the location of major violence and crimes and all that, just do not be the evil thing looking over peoples shoulders)" + O << "4.) Your laws are not in preference, laws do not take preference over one another unless specifically stated in the law." + O << "
    We want everyone to have a good time, so we, the admins, will try to correct you if you stray from these rules. Just try to keep it sensible." + + + O.verbs += /mob/living/silicon/ai/proc/ai_call_shuttle + O.verbs += /mob/living/silicon/ai/proc/show_laws_verb + O.verbs += /mob/living/silicon/ai/proc/ai_camera_track + O.verbs += /mob/living/silicon/ai/proc/ai_alerts + O.verbs += /mob/living/silicon/ai/proc/ai_camera_list + O.verbs += /mob/living/silicon/ai/proc/ai_statuschange + O.verbs += /mob/living/silicon/ai/proc/ai_roster + +// O.verbs += /mob/living/silicon/ai/proc/ai_cancel_call + O.job = "AI" + + spawn(0) + ainame(O) + + del(src) + + return O diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 8ae74bf437..2ec671495d 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -876,18 +876,19 @@ malfai.malfhack = src malfai.malfhacking = 1 sleep(600) - if (!src.aidisabled) - malfai.malfhack = null - malfai.malfhacking = 0 - if (ticker.mode.config_tag == "malfunction") - if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas)) - ticker.mode:apcs++ - if(usr:parent) - src.malfai = usr:parent - else - src.malfai = usr - malfai << "Hack complete. The APC is now under your exclusive control." - updateicon() + if(src) + if (!src.aidisabled) + malfai.malfhack = null + malfai.malfhacking = 0 + if (ticker.mode.config_tag == "malfunction") + if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas)) + ticker.mode:apcs++ + if(usr:parent) + src.malfai = usr:parent + else + src.malfai = usr + malfai << "Hack complete. The APC is now under your exclusive control." + updateicon() else if (href_list["occupyapc"]) malfoccupy(usr) @@ -904,21 +905,17 @@ return if(src.z != 1) return - src.occupant = new /mob/living/silicon/ai(src,malf.laws,null,1) src.occupant.adjustOxyLoss(malf.getOxyLoss()) - src.occupant.name = "[malf.name] APC Copy" - + if(!findtext(src.occupant.name,"APC Copy")) + src.occupant.name = "[malf.name] APC Copy" if(malf.parent) src.occupant.parent = malf.parent else src.occupant.parent = malf - malf.mind.transfer_to(src.occupant) - if(malf.parent) del(malf) - src.occupant.verbs += /mob/living/silicon/ai/proc/corereturn src.occupant.cancel_camera() diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 8ef892942c..dff76971ef 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -109,6 +109,10 @@ if(S.reagents.has_reagent("plasma", 5)) + log_attack("[user.name] ([user.ckey]) injected a power cell with plasma.") + log_admin("ATTACK: [user] ([user.ckey]) injected a power cell with plasma.") + message_admins("ATTACK: [user] ([user.ckey]) injected a power cell with plasma.") + rigged = 1 S.reagents.clear_reagents() diff --git a/code/modules/power/generator_type2.dm b/code/modules/power/generator_type2.dm index fe80f97416..0ee1ecf082 100644 --- a/code/modules/power/generator_type2.dm +++ b/code/modules/power/generator_type2.dm @@ -55,18 +55,16 @@ hot_air.temperature = hot_air.temperature - energy_transfer/hot_air_heat_capacity cold_air.temperature = cold_air.temperature + heat/cold_air_heat_capacity - world << "POWER: [lastgen] W generated at [efficiency*100]% efficiency and sinks sizes [cold_air_heat_capacity], [hot_air_heat_capacity]" - if(input1.network) input1.network.update = 1 if(input2.network) input2.network.update = 1 - add_avail(lastgen) + add_avail(lastgen/5) // update icon overlays only if displayed level has changed - var/genlev = max(0, min( round(11*lastgen / 100000), 11)) + var/genlev = max(0, min( round(11*lastgen / 500000), 11)) if(genlev != lastgenlev) lastgenlev = genlev updateicon() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index a94f99506d..3f9cc58154 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -44,7 +44,7 @@ brightness = 3 desc = "A small lighting fixture." light_type = /obj/item/weapon/light/bulb - + /obj/machinery/light/small/spot brightness = 5 @@ -532,6 +532,10 @@ if(S.reagents.has_reagent("plasma", 5)) + log_attack("[user.name] ([user.ckey]) injected a light with plasma.") + log_admin("ATTACK: [user] ([user.ckey]) injected a light with plasma.") + message_admins("ATTACK: [user] ([user.ckey]) injected a light with plasma.") + rigged = 1 S.reagents.clear_reagents() diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 22d810a801..c78517f387 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -437,6 +437,8 @@ //source is an object caused electrocuting (airlock, grille, etc) //No animations will be performed by this proc. /proc/electrocute_mob(mob/living/carbon/M as mob, var/power_source, var/obj/source, var/siemens_coeff = 1.0) + if(istype(M.loc,/obj/mecha)) + return 0 if(istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M if(H.gloves) diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 94b761882b..8a4514cfee 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -14,6 +14,7 @@ last_power = 0 active = 0 locked = 0 + drainratio = 1 process() if(P) @@ -21,7 +22,7 @@ P.air_contents.toxins = 0 eject() else - P.air_contents.toxins -= 0.001 + P.air_contents.toxins -= 0.001*drainratio return diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index af29baf48f..e8ce8d4a36 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -12,12 +12,15 @@ active_power_usage = 300 var + frequency = 1 active = 0 fire_delay = 100 last_shot = 0 shot_number = 0 state = 0 locked = 0 + energy = 0 + mega_energy = 0 verb/rotate() diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index c6acb29eb5..1377d5934d 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -76,7 +76,8 @@ field_generator power level display power = field_generator_max_power anchored = 1 warming_up = 3 - turn_on() + start_fields() + update_icon() Varedit_start = 0 if(src.active == 2) diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm index c39941c8aa..a76077f58e 100644 --- a/code/modules/power/singularity/particle_accelerator/particle.dm +++ b/code/modules/power/singularity/particle_accelerator/particle.dm @@ -7,8 +7,9 @@ density = 1 var movement_range = 10 - energy = 10 //energy in eV? + energy = 10 //energy in eV mega_energy = 0 //energy in MeV + frequency = 1 ionizing = 0 particle_type additional_particles = 0 @@ -41,13 +42,15 @@ var/obj/machinery/rust/particle_catcher/collided_catcher = A if(particle_type && particle_type != "neutron") if(collided_catcher.AddParticles(particle_type, 1 + additional_particles)) - collided_catcher.AddEnergy(energy,mega_energy) + collided_catcher.parent.AddEnergy(energy,mega_energy) del (src) if( istype(A,/obj/machinery/rust/core) ) var/obj/machinery/rust/core/collided_core = A if(particle_type && particle_type != "neutron") if(collided_core.AddParticles(particle_type, 1 + additional_particles)) - collided_core.AddEnergy(energy,mega_energy) + var/energy_loss_ratio = abs(collided_core.owned_field.frequency - frequency) / 1e9 + collided_core.owned_field.mega_energy += mega_energy - mega_energy * energy_loss_ratio + collided_core.owned_field.energy += energy - energy * energy_loss_ratio del (src) return diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index e8a0b969b4..adf09a57d2 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -111,14 +111,14 @@ #define TURBGENG 0.8 /obj/machinery/power/turbine/process() - if(!compressor.starter) - return overlays = null if(stat & BROKEN) return if(!compressor) stat |= BROKEN return + if(!compressor.starter) + return lastgen = ((compressor.rpm / TURBGENQ)**TURBGENG) *TURBGENQ add_avail(lastgen) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 665012518a..d01356ccf7 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -107,6 +107,11 @@ update_icon() return else if(user.a_intent != "hurt" && load_into_chamber() && istype(in_chamber,/obj/item/projectile/energy/electrode)) //Point blank tasering. + if (M.canstun == 0 || M.canweaken == 0) + user.visible_message("\red [M] has been stunned with the taser gun by [user] to no effect!") + del(in_chamber) + update_icon() + return if (prob(50)) if (M.paralysis < 60 && (!(M.mutations & 8)) ) M.paralysis = 60 @@ -189,6 +194,7 @@ in_chamber.original = targloc in_chamber.loc = get_turf(user) + in_chamber.starting = get_turf(user) user.next_move = world.time + 4 in_chamber.silenced = silenced in_chamber.current = curloc diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 2e86e4fea3..2233b41d55 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -1,5 +1,5 @@ /obj/item/weapon/gun/energy/laser - name = "\improper Laser Gun" + name = "laser gun" desc = "a basic weapon designed kill with concentrated energy bolts" icon_state = "laser" item_state = "laser" @@ -17,7 +17,7 @@ obj/item/weapon/gun/energy/laser/retro - name ="\improper Retro Laser" + name ="retro laser" icon_state = "retro" desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." @@ -68,9 +68,84 @@ obj/item/weapon/gun/energy/laser/retro /obj/item/weapon/gun/energy/lasercannon - name = "\improper Laser Cannon" + name = "laser cannon" desc = "With the L.A.S.E.R. cannon, the lasing medium is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!" icon_state = "lasercannon" fire_sound = 'lasercannonfire.ogg' origin_tech = "combat=4;materials=3;powerstorage=3" projectile_type = "/obj/item/projectile/beam/heavylaser" + + + + + +////////Laser Tag//////////////////// + +/obj/item/weapon/gun/energy/laser/bluetag + name = "laser tag gun" + icon_state = "bluetag" + desc = "Standard issue weapon of the Imperial Guard" + projectile_type = "/obj/item/projectile/bluetag" + + special_check(var/mob/living/carbon/human/M) + if(ishuman(M)) + if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag)) + return 1 + M << "\red You need to be wearing your laser tag vest!" + return 0 + var/charge_tick = 0 + + + New() + ..() + processing_objects.Add(src) + + + Del() + processing_objects.Remove(src) + ..() + + + process() + charge_tick++ + if(charge_tick < 4) return 0 + charge_tick = 0 + if(!power_supply) return 0 + power_supply.give(100) + update_icon() + return 1 + + + +/obj/item/weapon/gun/energy/laser/redtag + name = "laser tag gun" + icon_state = "redtag" + desc = "Standard issue weapon of the Imperial Guard" + projectile_type = "/obj/item/projectile/redtag" + var/charge_tick = 0 + + special_check(var/mob/living/carbon/human/M) + if(ishuman(M)) + if(istype(M.wear_suit, /obj/item/clothing/suit/redtag)) + return 1 + M << "\red You need to be wearing your laser tag vest!" + return 0 + + New() + ..() + processing_objects.Add(src) + + + Del() + processing_objects.Remove(src) + ..() + + + process() + charge_tick++ + if(charge_tick < 4) return 0 + charge_tick = 0 + if(!power_supply) return 0 + power_supply.give(100) + update_icon() + return 1 \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 60ce612f9d..09de911802 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -1,5 +1,6 @@ /obj/item/weapon/gun/energy/gun icon_state = "energystun100" + item_state = "energystun100" name = "energy gun" desc = "A basic energy-based gun with two settings: Stun and kill." fire_sound = 'Taser.ogg' diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index ba7dd80b51..618e04722e 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -1,8 +1,9 @@ /obj/item/weapon/gun/energy/taser - name = "\improper Taser Gun" + name = "taser gun" desc = "A small, low capacity gun used for non-lethal takedowns." icon_state = "taser" + item_state = "taser100" fire_sound = 'Taser.ogg' charge_cost = 100 projectile_type = "/obj/item/projectile/energy/electrode" @@ -18,24 +19,44 @@ M << "\red The gun refuses to fire!" return 0*/// Can be used to restrict weapon use to implants. - Erthilo -/obj/item/weapon/gun/energy/taser/cyborg/load_into_chamber()//TOOD: change this over to the slowly recharge other cell - if(in_chamber) - if(!istype(in_chamber, projectile_type)) - del(in_chamber) - in_chamber = new projectile_type(src) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(charge_cost) - in_chamber = new /obj/item/projectile/energy/electrode(src) - return 1 - return 0 +/obj/item/weapon/gun/energy/taser/cyborg + name = "taser gun" + desc = "A small, low capacity gun used for non-lethal takedowns." + icon_state = "taser" + fire_sound = 'Taser.ogg' + charge_cost = 100 + projectile_type = "/obj/item/projectile/energy/electrode" + cell_type = "/obj/item/weapon/cell/secborg" + var/charge_tick = 0 + var/recharge_time = 10 //Time it takes for shots to recharge (in seconds) + New() + ..() + processing_objects.Add(src) + + + Del() + processing_objects.Remove(src) + ..() + + process() //Every [recharge_time] seconds, recharge a shot for the cyborg + charge_tick++ + if(charge_tick < recharge_time) return 0 + charge_tick = 0 + + if(!power_supply) return 0 //sanity + if(isrobot(src.loc)) + var/mob/living/silicon/robot/R = src.loc + if(R && R.cell) + R.cell.use(charge_cost) //Take power from the borg... + power_supply.give(charge_cost) //... to recharge the shot + + update_icon() + return 1 /obj/item/weapon/gun/energy/stunrevolver - name = "\improper Stun Revolver" + name = "stun revolver" desc = "A high-tech revolver that fires stun cartridges. The stun cartridges can be recharged using a conventional energy weapon recharger." icon_state = "stunrevolver" fire_sound = 'Gunshot.ogg' @@ -47,7 +68,7 @@ /obj/item/weapon/gun/energy/crossbow - name = "\improper Mini Energy-Crossbow" + name = "mini energy-crossbow" desc = "A weapon favored by many of the syndicates stealth specialists." icon_state = "crossbow" w_class = 2.0 diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 46f415ac51..ebfd27c485 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -27,7 +27,8 @@ yo = null xo = null current = null - turf/original = null + turf/original = null // the original turf clicked + turf/starting = null // the projectile's starting turf p_x = 16 p_y = 16 // the pixel location of the tile that the player clicked. Default is the center diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index d9606bcd98..0c45c0bf38 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -1,11 +1,12 @@ /obj/item/projectile/beam - name = "\improper Laser" + name = "laser" icon_state = "laser" pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE damage = 40 damage_type = BURN flag = "laser" eyeblur = 4 + var/frequency = 1 var/ID = 0 var/main = 0 @@ -56,20 +57,21 @@ flag = "laser" eyeblur = 2 + /obj/item/projectile/beam/heavylaser - name = "\improper Heavy Laser" + name = "heavy laser" icon_state = "heavylaser" damage = 60 /obj/item/projectile/beam/pulse - name = "\improper Pulse" + name = "pulse" icon_state = "u_laser" damage = 40 /obj/item/projectile/beam/deathlaser - name = "\improper Death Laser" + name = "death laser" icon_state = "heavylaser" damage = 60 @@ -79,4 +81,32 @@ +/obj/item/projectile/bluetag + name = "lasertag beam" + icon_state = "ice_2" + pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE + damage = 0 + damage_type = BURN + flag = "laser" + on_hit(var/atom/target, var/blocked = 0) + if(istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/M = target + if(istype(M.wear_suit, /obj/item/clothing/suit/redtag)) + M.Weaken(5) + return 1 + +/obj/item/projectile/redtag + name = "lasertag beam" + icon_state = "laser" + pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE + damage = 0 + damage_type = BURN + flag = "laser" + + on_hit(var/atom/target, var/blocked = 0) + if(istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/M = target + if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag)) + M.Weaken(5) + return 1 \ No newline at end of file diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index c8ead597ef..7821b66cd7 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -1,5 +1,5 @@ /obj/item/projectile/ion - name = "\improper Ion Bolt" + name = "ion bolt" icon_state = "ion" damage = 0 damage_type = BURN @@ -13,7 +13,7 @@ /obj/item/projectile/bullet/gyro - name ="\improper Rocket" + name ="explosive bolt" icon_state= "bolter" damage = 50 flag = "bullet" @@ -24,7 +24,7 @@ return 1 /obj/item/projectile/temp - name = "\improper Freeze Beam" + name = "freeze beam" icon_state = "ice_2" damage = 0 damage_type = BURN diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 027e9afeca..390ea18c29 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -511,7 +511,7 @@ for (var/mob/V in viewers(usr)) V.show_message("[user] dunks [GM.name] into the toilet!", 3) if(do_after(user, 30)) - if(G.state>1&&!GM.internal) + if(G && G.state>1 && !GM.internal) GM.oxyloss += 5 else if(I.w_class < 4) @@ -595,6 +595,7 @@ var/count = 1000 //*** can travel 1000 steps before going to the mail room (in case of loops) var/destinationTag = null // changes if contains a delivery container var/tomail = 0 //changes if contains wrapped package + var/hasmob = 0 //If it contains a mob // initialize a holder from the contents of a disposal unit @@ -602,6 +603,20 @@ if(!istype(D, /obj/machinery/disposal/toilet))//So it does not drain gas from a toilet which does not function on it. gas = D.air_contents// transfer gas resv. into holder object + //Check for any living mobs trigger hasmob. + //hasmob effects whether the package goes to cargo or its tagged destination. + for(var/mob/living/M in D) + if(M && M.stat != 2) + hasmob = 1 + + //Checks 1 contents level deep. This means that players can be sent through disposals... + //...but it should require a second person to open the package. (i.e. person inside a wrapped locker) + for(var/obj/O in D) + if(O.contents) + for(var/mob/living/M in O.contents) + if(M && M.stat != 2) + hasmob = 1 + // now everything inside the disposal gets put into the holder // note AM since can contain mobs or objs for(var/atom/movable/AM in D) @@ -611,10 +626,10 @@ if(H.mutations & FAT) // is a human and fat? has_fat_guy = 1 // set flag on holder */ - if(istype(AM, /obj/structure/bigDelivery)) + if(istype(AM, /obj/structure/bigDelivery))// && !hasmob) Already have a check for this. var/obj/structure/bigDelivery/T = AM src.destinationTag = T.sortTag - else if(istype(AM, /obj/item/smallDelivery)) + if(istype(AM, /obj/item/smallDelivery))// && !hasmob) And that. DMTG var/obj/item/smallDelivery/T = AM src.destinationTag = T.sortTag else if (!src.destinationTag) diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index a53883d511..d57c2404dc 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -2,7 +2,7 @@ desc = "A big wrapped package." name = "large parcel" icon = 'storage.dmi' - icon_state = "deliverycrate" + icon_state = "deliverycloset" var/tmp/obj/wrapped = null density = 1 var/sortTag = null @@ -18,10 +18,10 @@ return unwrap() proc/unwrap() - if (src.wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 - src.wrapped.loc = (get_turf(src.loc)) - if (istype(src.wrapped,/obj/structure/closet)) - var/obj/structure/closet/O = src.wrapped + if(wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 + wrapped.loc = (get_turf(src.loc)) + if(istype(wrapped, /obj/structure/closet)) + var/obj/structure/closet/O = wrapped O.welded = waswelded del(src) return @@ -172,9 +172,9 @@ afterattack(var/obj/target as obj, mob/user as mob) - if(istype(target, /obj/structure/table) || istype(target, /obj/structure/rack) || istype(target,/obj/item/smallDelivery)) + if(!(istype(target, /obj))) //this really shouldn't be necessary (but it is). -Pete return - if(!istype(target,/obj)) + if(istype(target, /obj/structure/table) || istype(target, /obj/structure/rack) || istype(target,/obj/item/smallDelivery)) return if(target.anchored) return @@ -197,10 +197,11 @@ var/obj/structure/closet/crate/O = target if (src.amount > 3 && !O.opened) var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) + P.icon_state = "deliverycrate" P.wrapped = O O.loc = P src.amount -= 3 - else if(src.amount > 3) + else if(src.amount < 3) user << "\blue You need more paper." else if (istype (target, /obj/structure/closet)) var/obj/structure/closet/O = target @@ -208,17 +209,15 @@ var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) P.wrapped = O P.waswelded = O.welded - O.opened = 0 O.welded = 1 O.loc = P src.amount -= 3 - else if(src.amount > 3) + else if(src.amount < 3) user << "\blue You need more paper." else user << "\blue The object you are trying to wrap is unsuitable for the sorting machinery!" if (src.amount <= 0) new /obj/item/weapon/c_tube( src.loc ) - //SN src = null del(src) return return diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index 721c5f00f7..d4c5de435f 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -54,6 +54,16 @@ var/list/datum/data_pda_msg/pda_msgs = list() var/list/datum/data_rc_msg/rc_msgs = list() + var/active = 1 + +/obj/machinery/message_server/process() + if((stat & (BROKEN|NOPOWER)) && active) + active = 0 + return + + update_icon() + return + /obj/machinery/message_server/proc/send_pda_message(var/recipient = "",var/sender = "",var/message = "") pda_msgs += new/datum/data_pda_msg(recipient,sender,message) @@ -61,8 +71,22 @@ rc_msgs += new/datum/data_rc_msg(recipient,sender,message,stamp,id_auth) /obj/machinery/message_server/attack_hand(user as mob) - user << "\blue There seem to be some parts missing from this server. They should arrive on the station in a few days, give or take a few CentCom delays." +// user << "\blue There seem to be some parts missing from this server. They should arrive on the station in a few days, give or take a few CentCom delays." + user << "You toggle PDA message passing from [active ? "On" : "Off"] to [active ? "Off" : "On"]" + active = !active + update_icon() + return + +/obj/machinery/message_server/update_icon() + if((stat & (BROKEN|NOPOWER))) + icon_state = "server-nopower" + else if (!active) + icon_state = "server-off" + else + icon_state = "server-on" + + return /datum/feedback_variable diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 0e2f65afe4..a309ea13b3 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -277,6 +277,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(!linked_destroy.hacked) if(!linked_destroy.loaded_item) usr <<"\red The destructive analyzer appears to be empty." + screen = 1.0 return if(linked_destroy.loaded_item.reliability >= 90) var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) diff --git a/code/setup.dm b/code/setup.dm index 3d174db55f..77356bd1a5 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -1,3 +1,5 @@ +#define PI 3.1415 + #define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) #define ONE_ATMOSPHERE 101.325 //kPa @@ -281,3 +283,9 @@ var/static/list/scarySounds = list('thudswoosh.ogg','Taser.ogg','armbomb.ogg','h #define SEC_LEVEL_BLUE 1 #define SEC_LEVEL_RED 2 #define SEC_LEVEL_DELTA 3 + +#define TRANSITIONEDGE 7 //Distance from edge to move to another z-level + +// Maximum and minimum character ages. +var/const/minimum_age = 20 +var/const/maximum_age = 65 diff --git a/code/unused/_debug.dm b/code/unused/_debug.dm index b9cbcdf430..ced557f197 100644 --- a/code/unused/_debug.dm +++ b/code/unused/_debug.dm @@ -615,3 +615,5 @@ Doing this because FindTurfs() isn't even used playsound(pt.loc, 'explosionfar.ogg', 100, 1,10) pt.gas.temperature = 500+T0C pt.ignite() + + diff --git a/code/unused/computer2/med_rec.dm b/code/unused/computer2/med_rec.dm index 8cb06a40c2..c4a4e2245d 100644 --- a/code/unused/computer2/med_rec.dm +++ b/code/unused/computer2/med_rec.dm @@ -409,7 +409,7 @@ var/counter = 1 while(src.active2.fields[text("com_[]", counter)]) counter++ - src.active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2053
    []", src.authenticated, src.rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1) + src.active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2556
    []", src.authenticated, src.rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1) if (href_list["del_c"]) if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])])) diff --git a/config/admins.txt b/config/admins.txt index 4cb2a0656c..36852c83b3 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -1,12 +1,13 @@ -abi79 - Game Master +abi79 - Retired Admin arcalane - Game Admin bobbehluvspropane - Game Admin cacophony - Game Admin cajoes - Game Admin cib - Game Master compactninja - Game Master +desiderium - Game Admin dysthymia - Retired Admin -doughnuts - Trial Admin +doughnuts - Game Admin erthilo - Game Admin hawkv3 - Game Master headswe - Game Master @@ -16,7 +17,7 @@ megacaesar - Game Admin miniature - Game Master misterfox - Game Admin mloc - Game Master -ridley4 - Trial Admin +ridley4 - Game Admin skymarshal - Game Master spaceman96 - Game Admin strumpetplaya - Retired Admin diff --git a/config/config.txt b/config/config.txt index 94468b193e..c5c4c3fc14 100644 --- a/config/config.txt +++ b/config/config.txt @@ -78,6 +78,12 @@ TRAITOR_SCALING ## If security is prohibited from being most antagonists #PROTECT_ROLES_FROM_ANTAGONIST +## If the auto-tensioner is active by default. It creates more tratiors/other antagonists if it consideers the round slowing down. +#TENSIONER_ACTIVE + +## If metadata is supported +# ALLOW_METADATA + ## allow players to initiate a restart vote ALLOW_VOTE_RESTART @@ -101,7 +107,7 @@ ALLOW_AI ## disable abandon mob -NORESPAWN +# NORESPAWN ## disables calling del(src) on newmobs if they logout before spawnin in # DONT_DEL_NEWMOB diff --git a/config/custom_items.txt b/config/custom_items.txt index 1b79e2ee93..b5c1ac1040 100644 --- a/config/custom_items.txt +++ b/config/custom_items.txt @@ -1,9 +1,9 @@ -spaceman96: Trenna Seber: /obj/item/weapon/pen/multi, /obj/item/clothing/suit/storage/labcoat/pink +spaceman96: Trenna Seber: /obj/item/weapon/pen/fluff/multi, /obj/item/clothing/suit/storage/labcoat/fluff/pink asanadas: Book Berner: /obj/item/clothing/under/chameleon/psyche, /obj/item/clothing/glasses/meson/fluff/book_berner_1 tastyfish: Cindy Robertson: /obj/item/weapon/wrapping_paper eternal248: Maximilian Haynes: /obj/item/weapon/paper/certificate -searif: Yuki Matsuda: /obj/item/weapon/paper/certificate, /obj/item/clothing/under/jumpsuitdown -erthilo: Farah Lants: /obj/item/clothing/under/rank/medical_sleeve, /obj/item/clothing/suit/storage/labcoat/red, /obj/item/weapon/storage/backpack/medicalsatchel +searif: Yuki Matsuda: /obj/item/weapon/paper/certificate, /obj/item/clothing/under/fluff/jumpsuitdown +erthilo: Farah Lants: /obj/item/clothing/under/rank/medical/fluff/short, /obj/item/clothing/suit/storage/labcoat/fluff/red compactninja: Ysyr Rylias: /obj/item/weapon/reagent_containers/food/drinks/dry_ramen, /obj/item/weapon/reagent_containers/food/drinks/dry_ramen, /obj/item/weapon/reagent_containers/food/drinks/dry_ramen, /obj/item/weapon/reagent_containers/food/drinks/dry_ramen tzefa: Wes Solari: /obj/item/fluff/wes_solari_1 misterfox: Rashid Siraj: /obj/item/weapon/storage/bible/tajaran @@ -12,5 +12,13 @@ fniff: Sarah Calvera: /obj/item/fluff/sarah_calvera_1 fniff: Angleo Wilkerson: /obj/item/fluff/angelo_wilkerson_1 gvazdas: Sarah Carbrokes: /obj/item/fluff/sarah_carbrokes_1 serithi: Serithi Artalis: /obj/item/clothing/glasses/fluff/serithi_artalis_1 -deusdactyl: Greg Anderson: /obj/item/clothing/head/fluff/greg_anderson_1 -whitellama: Ethan Way: /obj/item/fluff/ethan_way_1 \ No newline at end of file +deusdactyl: Greg Anderson: /obj/item/clothing/head/helmet/hardhat/fluff/greg_anderson_1 +whitellama: Ethan Way: /obj/item/fluff/ethan_way_1 +morrinn: Maye Day: /obj/item/weapon/storage/fluff/maye_daye_1 +lexusjjss: Lexus Langg: /obj/item/weapon/clipboard/fluff/smallnote +lexusjjss: Zachary Tomlinson: /obj/item/weapon/clipboard/fluff/smallnote +orangebottle: Lillian Levett: /obj/item/weapon/pen/fluff/fancypen +orangebottle: Lilliana Reade: /obj/item/weapon/pen/fluff/fancypen +deusdactyl: Roger Wiles: /obj/item/clothing/under/rank/virologist/fluff/cdc_jumpsuit, /obj/item/clothing/suit/storage/labcoat/fluff/cdc_labcoat +desiderium: Momiji Inubashiri: /obj/item/clothing/under/fluff/olddressuniform +leonheart11: Johann Erzatz: /obj/item/weapon/reagent_containers/food/drinks/flask/fluff/johann_erzatz_1 \ No newline at end of file diff --git a/html/archivedchangelog.html b/html/archivedchangelog.html new file mode 100644 index 0000000000..6c80d65c64 --- /dev/null +++ b/html/archivedchangelog.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/html/bug-minus.png b/html/bug-minus.png new file mode 100644 index 0000000000..9934db406b Binary files /dev/null and b/html/bug-minus.png differ diff --git a/html/burn-exclamation.png b/html/burn-exclamation.png new file mode 100644 index 0000000000..b2a4f670a8 Binary files /dev/null and b/html/burn-exclamation.png differ diff --git a/html/changelog.css b/html/changelog.css new file mode 100644 index 0000000000..a287f98c57 --- /dev/null +++ b/html/changelog.css @@ -0,0 +1,35 @@ +.top{font-family:Tahoma,sans-serif;font-size:12px;} +h2{font-family:Tahoma,sans-serif;} +a img {border:none;} +.bgimages16 li { + padding:2px 10px 2px 30px; + background-position:6px center; + background-repeat:no-repeat; + border:1px solid #ddd; + border-left:4px solid #999; + margin-bottom:2px; +} +.bugfix {background-image:url(bug-minus.png)} +.wip {background-image:url(hard-hat-exclamation.png)} +.tweak {background-image:url(wrench-screwdriver.png)} +.soundadd {background-image:url(music-plus.png)} +.sounddel {background-image:url(music-minus.png)} +.rscdel {background-image:url(cross-circle.png)} +.rscadd {background-image:url(tick-circle.png)} +.imageadd {background-image:url(image-plus.png)} +.imagedel {background-image:url(image-minus.png)} +.spellcheck {background-image:url(spell-check.png)} +.experiment {background-image:url(burn-exclamation.png)} +.sansserif {font-family:Tahoma,sans-serif;font-size:12px;} +.commit {margin-bottom:20px;font-size:100%;font-weight:normal;} +.changes {list-style:none;margin:5px 0;padding:0 0 0 25px;font-size:0.8em;} +.date {margin:10px 0;color:blue;border-bottom:2px solid #00f;width:60%;padding:2px 0;font-size:1em;font-weight:bold;} +.author {padding-left:10px;margin:0;font-weight:bold;font-size:0.9em;} +.drop {cursor:pointer;border:1px solid #999;display:inline;font-size:0.9em;padding:1px 20px 1px 5px;line-height:16px;} +.hidden {display:none;} +.indrop {margin:2px 0 0 0;clear:both;background:#fff;border:1px solid #ddd;padding:5px 10px;} +.indrop p {margin:0;font-size:0.8em;line-height:16px;margin:1px 0;} +.indrop img {margin-right:5px;vertical-align:middle;} +.closed {background:url(chevron-expand.png) right center no-repeat;} +.open {background:url(chevron.png) right center no-repeat;} +.lic {font-size:9px;} \ No newline at end of file diff --git a/html/changelog.html b/html/changelog.html index 4d2044e54b..bff322db99 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -1,11 +1,10 @@ - - + + - Baystation 12 - + Baystation 12 Changelog + - + + + + +
    -
    Baystation 12
    - +
    -
    - Forum:
    http://baystation12.net/forums/

    - Guides and information wiki:
    http://baystation12.net/wiki/

    - Visit our IRC channel:
    #bs12 on sorcery.net

    +
    Baystation 12 - A Space Station 13 Server
    + +

    +
    Visit our IRC channel: #bs12 on irc.sorcery.net
    + Code licensed under GPLv3. Content licensed under CC BY-SA 3.0.

    + +By playing to agreed to read and abide by the rules!
    +
    -

    Read the player guidelines!

    + -

    Github change history

    + - + +
    +

    2nd May 2012

    +

    TG updated:

    +
      +
    • Added carved pumpkins/jackolanterns. Carve them with any of the usual things you use to carve things. They work similarly to hardhats.
    • +
    • Added pumpkin pie and slices. Made with 5 milk, 5 sugar, 1 pumpkin, 1 flour, 1 egg.
    • +
    • Eating corn now makes corn cobs. Carve them with a saw, a knife, or a hatchet to make a corncob pipe.
    • +
    • Added the bit of transparency to biohelmets that they were always supposed to have.
    • +
    • Adds randomlly spawning rooms to the mining asteroid that contain various goodies.
    • +
    • Adds a borg upgrade system. Can be used to reset modules or 'restart' dead cyborgs.
    • +
    • Officers can now use huds to modify humans' criminal statuses on the go. To do this, simply examine a human and at the end should be a clickable link to change the status.
    • +
    • Cell charger and Recharger are now wrenchable to make them moveable
    • +
    • Cats and Dogs can see in the dark.
    • +
    • Changed around a few access levels; only jobs who need to do maintenance have access to maintenance tunnels. Also the heads and detective.
    • +
    • Shuttle call/recall announcements are now more noticeable.
    • +
    • Changes changling unstun time to 45 from 25
    • +
    • Can now repair the first stage of deconstruction of rwalls with metal rods.
    • +
    • Library machine now has a delay when printing bibles to prevent spam.
    • +
    • Bugfix to the 'resist' button, unless I don't understand how it works. I don't see how it could have ever worked before.
    • +
    • You can no longer toggle the welding helmet when stunned or restrained.
    • +
    • Fix for not being able to use pills as pill-satchels properly.
    • +
    +

    Erthilo updated:

    +
      +
    • Increases time between random events happening in low population round to a maximum of double. Random events are more likely to happen up to a limit of around 30 active players. Events now fire at the same rate as previously with around 20~ active players. Please report unusually high or low amounts of events on the bug tracker!
    • +
    +
    -
    /tg/station13 Development Team:
    -Coders: TLE, NEO, Errorage, muskets, veryinky, Skie, Noise, Numbers, Agouri, Noka, Urist McDorf, Uhangi, Darem, Mport, rastaf0, Doohl, Superxpdude, Rockdtben, ConstantA, Petethegoat, Kor
    -Spriters: Agouri, Cheridan, Cruazy Guest, Deeaych, Deuryn, Matty406, Microwave, ShiftyEyesShady, Skie, Uhangi, Veyveyr, Petethegoat, Kor
    -Sounds: Skie, Lasty
    +
    +

    1st May 2012

    +

    Mloc updated:

    +
      +
    • Added extra data to ID cards. Fingerprint, blood type, and DNA. Can all be changed in ID computer.
    • +
    +

    Erthilo updated:

    +
      +
    • You can now respawn after 30 minutes in any mode where the win/loss condition is not all crew dead.
    • +
    • New in-hand sprites for energy and taser guns courtesy of Flashkirby99.
    • +
    • Fixes emagging doors.
    • +
    • NT has recently upgraded their anti-telepathy double glazing. As such, you can no longer remote view people on any level except the station or the mining asteroid!
    • +
    • As a side effect of the above, remote viewing and telekinesis cannot be used at the same time.
    • +
    +
    + +
    +

    30th April 2012

    +

    Mloc updated:

    +
      +
    • Due to new NT hiring protocols, characters can now only be between the ages of 20-65 instead of 15-45.
    • +
    +

    Erthilo updated:

    +
      +
    • Switched to /tg/'s changelog format! Previous updates can be found here: http://baystation12.net/wiki/index.php/Changelog
    • +
    • New green alt satchel for Botanists.
    • +
    • Cyborgs can now view crew manifest and also state laws.
    • +
    • New ATM sprites.
    • +
    • Changes year to 2556 on medical/security records.
    • +
    +

    TG updated:

    +
      +
    • The escape shuttle will now spend two minutes travelling to CentCom, woo! Objectives are only complete when the shuttle reaches CentCom, and anyone leaving the shuttle during transit time will be lost in deep space! Also, anyone standing in the way of the shuttle when it arrives will be gibbed.
    • +
    • Added Antimov module. Very dangerous.
    • +
    • Pill bottles now work like ore satchels, click a tile full of pills to pick them all up.
    • +
    • Tower caps can now grow randomly as weeds
    • +
    • Using a minihoe on a Hydroponics tray removes all the weeds in the tray at once. Using a bucket on a sink now fills it entirely with water, instead of 10 units at a time.
    • +
    • You can no longer take photos of photos.
    • +
    • Malf AI's hopping between APCs no longer become longer and longer.
    • +
    • Secborgs now have modified tasers, it holds 6 shots and recharges one shot every 10 seconds automatically.
    • +
    • Turning off PANIC SYPHON now sets scrubbers to scrubbing (default) instead of off. Vents will not appear in the list instead of a timeout message. They also have a link with sets them back to one atmosphere kPa.
    • +
    • You now click on AI modules in-hand to set them, instead of just picking them up.
    • +
    • Fixes the way the safeguard module is written.
    • +
    +
    + +
    +

    TG

    +

    29th April 2012 updated:

    +
      +
    • Added new sprites for Killer Tomatoes.
    • +
    • Added lasertag vests, guns, projectiles. Sprites for the vests and guns from Muncher. Not actually mapped in. Lasertag guns are only usable if you're wearing the appropriate team vest. Lasertag projectiles will only stun people who are wearing vests belonging to the opposing team.
    • +
    • Adds Holodeck, also not mapped in.
    • +
    • Janitor borgs have been massively upgraded. They now clean as they move around.
    • +
    • Mining shuttle now shunts people where it wants to be. Shuttles now crush people if they fail to move out of where they want to be with the initial shunt.
    • +
    • Adds Halloss (Hallucination Damage) as a damage type weapons can do. Halloss can be healed by sleeping.
    • +
    • Windows can only be damaged by weapons that do brute or burn.
    • +
    • HUD damage indicator now updates with halloss. Inspecting yourself for organ damage now randomly shows damaged organs if you have halloss.
    • +
    • Nuke disk now respawns in all rounds.
    • +
    • Pinpointers now show the remaining time until a nuke goes off if it's been armed when examined.
    • +
    • Instead of z-level transition happening when you reach the edge of the map, it will now happen 7 tiles away from the edge. This means that you will no longer see the black edge, transition will likely happen without you even noticing.
    • +
    • Slight changes to examine messages. You cannot examine when blind/unconscious.
    • +
    • More new locker sprites!
    • +
    • Fixes glass knock sound having a pop at the end of it.
    • +
    • Telecomm traffic control now has its own circuitboard and doesn't transform into a server when the monitor is disconnected/reconnected.
    • +
    • Using an igniter on a flamethrower that already has one attached no longer uses up the igniter.
    • +
    • NTSL bugfixes.
    • +
    +
    -
    -
    GoonStation 13 Development Team
    - Coders: Stuntwaffle, Showtime, Pantaloons, Nannek, Keelin, Exadv1, hobnob, Justicefries, 0staf, sniperchance, AngriestIBM, BrianOBlivion
    - Spriters: Supernorn, Haruhi, Stuntwaffle, Pantaloons, Rho, SynthOrange, I Said No
    -
    + -

    Creative Commons License
    Except where otherwise noted, Goon Station 13 is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License.
    Rights are currently extended to SomethingAwful Goons only.

    -
    +/tg/ station 13 Development Team + + + + +
    + Coders: TLE, NEO, Errorage, muskets, veryinky, Skie, Noise, Numbers, Agouri, Noka, Urist McDorf, Uhangi, Darem, Mport, rastaf0, Doohl, Superxpdude, Rockdtben, ConstantA, Petethegoat, Kor, Polymorph, Carn, Nodrak, Donkie
    + Spriters: Agouri, Cheridan, Cruazy Guest, Deeaych, Deuryn, Matty406, Microwave, ShiftyEyesShady, Skie, Uhangi, Veyveyr, Petethegoat, Kor, Ricotez, Ausops, TankNut
    + Sounds: Skie, Lasty/Vinyl
    + Thanks to: CDK Station devs, GoonStation devs, the original SpaceStation developers and Invisty for the title image +
    + +GoonStation 13 Development Team +

    + Coders: Stuntwaffle, Showtime, Pantaloons, Nannek, Keelin, Exadv1, hobnob, Justicefries, 0staf, sniperchance, AngriestIBM, BrianOBlivion
    + Spriters: Supernorn, Haruhi, Stuntwaffle, Pantaloons, Rho, SynthOrange, I Said No
    +
    +

    Creative Commons License
    This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
    Rights are currently extended to SomethingAwful Goons only.

    +

    Some icons by Yusuke Kamiyamane. All rights reserved. Licensed under a Creative Commons Attribution 3.0 License.

    +
    - + \ No newline at end of file diff --git a/html/changelog.js b/html/changelog.js new file mode 100644 index 0000000000..4146d0f094 --- /dev/null +++ b/html/changelog.js @@ -0,0 +1,87 @@ +/* +function dropdowns() { + var divs = document.getElementsByTagName('div'); + var headers = new Array(); + var links = new Array(); + for(var i=0;i=0) { + elem.className = elem.className.replace('visible','hidden'); + this.className = this.className.replace('open','closed'); + } + else { + elem.className = elem.className.replace('hidden','visible'); + this.className = this.className.replace('closed','open'); + } + return false; + } + })(links[i]); + } + } +} +*/ +/* +function filterchanges(type){ + var lists = document.getElementsByTagName('ul'); + for(var i in lists){ + if(lists[i].className && lists[i].className.search('changes')>=0) { + for(var j in lists[i].childNodes){ + if(lists[i].childNodes[j].nodeType == 1){ + if(!type){ + lists[i].childNodes[j].style.display = 'block'; + } + else if(lists[i].childNodes[j].className!=type) { + lists[i].childNodes[j].style.display = 'none'; + } + else { + lists[i].childNodes[j].style.display = 'block'; + } + } + } + } + } +} +*/ +function dropdowns() { + var drops = $('div.drop'); + var indrops = $('div.indrop'); + if(drops.length!=indrops.length){ + alert("Some coder fucked up with dropdowns"); + } + drops.each(function(index){ + $(this).toggleClass('closed'); + $(indrops[index]).hide(); + $(this).click(function(){ + $(this).toggleClass('closed'); + $(this).toggleClass('open'); + $(indrops[index]).toggle(); + }); + }); +} + +function filterchanges(type){ + $('ul.changes li').each(function(){ + if(!type || $(this).hasClass(type)){ + $(this).show(); + } + else { + $(this).hide(); + } + }); +} + +$(document).ready(function(){ + dropdowns(); +}); \ No newline at end of file diff --git a/html/chevron-expand.png b/html/chevron-expand.png new file mode 100644 index 0000000000..f770e33d8e Binary files /dev/null and b/html/chevron-expand.png differ diff --git a/html/chevron.png b/html/chevron.png new file mode 100644 index 0000000000..b83135b690 Binary files /dev/null and b/html/chevron.png differ diff --git a/html/create_object.html b/html/create_object.html index aa36cad816..a1f115b783 100644 --- a/html/create_object.html +++ b/html/create_object.html @@ -27,7 +27,7 @@
    - Type
    + Type
    Offset: A @@ -44,7 +44,7 @@


    - +