diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm index 4428f8ee34a..de0a271ae6b 100644 --- a/code/__defines/items_clothing.dm +++ b/code/__defines/items_clothing.dm @@ -219,3 +219,7 @@ #define SUIT_SENSOR_BINARY 1 #define SUIT_SENSOR_VITAL 2 #define SUIT_SENSOR_TRACKING 3 + +// Hair Defines +#define HAIR_VERY_SHORT 0x1 +#define HAIR_TIEABLE 0x4 \ No newline at end of file diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 012677200c3..c73ebf4d41e 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -177,6 +177,9 @@ #define O_LIVER "liver" #define O_KIDNEYS "kidneys" #define O_APPENDIX "appendix" +#define O_VOICE "voicebox" + +// Non-Standard organs #define O_PLASMA "plasma vessel" #define O_HIVE "hive node" #define O_NUTRIENT "nutrient vessel" diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index 81a55f84d7b..f12b630979c 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -50,6 +50,7 @@ #define LANGUAGE_MINBUS "Minbus" #define LANGUAGE_EVENT1 "Occursus" #define LANGUAGE_AKHANI "Akhani" +#define LANGUAGE_ALAI "Alai" // Language flags. #define WHITELISTED 1 // Language is available if the speaker is whitelisted. diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 92c5477a0bc..9d34ead4dfe 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -31,7 +31,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define INIT_ORDER_DEFAULT 0 #define INIT_ORDER_LIGHTING 0 #define INIT_ORDER_AIR -1 -#define INIT_ORDER_HOLOMAPS -5 +#define INIT_ORDER_PLANETS -4 #define INIT_ORDER_OVERLAY -6 #define INIT_ORDER_XENOARCH -20 @@ -44,6 +44,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define FIRE_PRIORITY_AIRFLOW 30 #define FIRE_PRIORITY_AIR 35 #define FIRE_PRIORITY_DEFAULT 50 +#define FIRE_PRIORITY_PLANETS 75 #define FIRE_PRIORITY_MACHINES 100 #define FIRE_PRIORITY_OVERLAYS 500 diff --git a/code/__defines/subsystems_vr.dm b/code/__defines/subsystems_vr.dm new file mode 100644 index 00000000000..5c028803b96 --- /dev/null +++ b/code/__defines/subsystems_vr.dm @@ -0,0 +1 @@ +#define INIT_ORDER_HOLOMAPS -5 //VOREStation Add \ No newline at end of file diff --git a/code/_helpers/events.dm b/code/_helpers/events.dm index 74e047e8119..e31d24783e8 100644 --- a/code/_helpers/events.dm +++ b/code/_helpers/events.dm @@ -12,4 +12,16 @@ var/area/A = locate(areapath) // Check if it actually exists if(istype(A) && A.z in using_map.player_levels) grand_list_of_areas += A - return grand_list_of_areas \ No newline at end of file + return grand_list_of_areas + +/** Checks if any living humans are in a given area! */ +/proc/is_area_occupied(var/area/myarea) + // Testing suggests looping over human_mob_list is quicker than looping over area contents + for(var/mob/living/carbon/human/H in human_mob_list) + if(H.stat >= DEAD) //Conditions for exclusion here, like if disconnected people start blocking it. + continue + var/area/A = get_area(H) + if(A == myarea) //The loc of a turf is the area it is in. + return 1 + return 0 + \ No newline at end of file diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index df5bf91e611..1cdc7e27170 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -60,6 +60,7 @@ var/list/gamemode_cache = list() var/humans_need_surnames = 0 var/allow_random_events = 0 // enables random events mid-round when set to 1 var/allow_ai = 1 // allow ai job + var/allow_ai_drones = 0 // allow ai controlled drones var/hostedby = null var/respawn = 1 var/guest_jobban = 1 @@ -400,6 +401,9 @@ var/list/gamemode_cache = list() if ("allow_ai") config.allow_ai = 1 + if ("allow_ai_drones") + config.allow_ai_drones = 1 + // if ("authentication") // config.enable_authentication = 1 diff --git a/code/controllers/subsystems/planets.dm b/code/controllers/subsystems/planets.dm new file mode 100644 index 00000000000..3b3675d5c3a --- /dev/null +++ b/code/controllers/subsystems/planets.dm @@ -0,0 +1,183 @@ +SUBSYSTEM_DEF(planets) + name = "Planets" + init_order = INIT_ORDER_PLANETS + priority = FIRE_PRIORITY_PLANETS + wait = 2 SECONDS + flags = SS_BACKGROUND + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + + var/list/new_outdoor_turfs = list() + var/list/new_outdoor_walls = list() + + var/list/planets = list() + var/list/z_to_planet = list() + + var/list/currentrun = list() + + var/list/needs_sun_update = list() + var/list/needs_temp_update = list() + +/datum/controller/subsystem/planets/Initialize(timeofday) + admin_notice("Initializing planetary weather.", R_DEBUG) + createPlanets() + allocateTurfs(TRUE) + ..() + +/datum/controller/subsystem/planets/proc/createPlanets() + var/list/planet_datums = subtypesof(/datum/planet) + for(var/P in planet_datums) + var/datum/planet/NP = new P() + planets.Add(NP) + for(var/Z in NP.expected_z_levels) + if(Z > z_to_planet.len) + z_to_planet.len = Z + if(z_to_planet[Z]) + admin_notice("Z[Z] is shared by more than one planet!", R_DEBUG) + continue + z_to_planet[Z] = NP + +/datum/controller/subsystem/planets/proc/addTurf(var/turf/T,var/is_edge) + if(is_edge) + new_outdoor_walls |= T + else + new_outdoor_turfs |= T + +/datum/controller/subsystem/planets/proc/removeTurf(var/turf/T,var/is_edge) + if(is_edge) + new_outdoor_walls -= T + else + new_outdoor_turfs -= T + + if(z_to_planet.len >= T.z) + var/datum/planet/P = z_to_planet[T.z] + if(!P) + return + if(is_edge) + P.planet_floors -= T + else + P.planet_walls -= T + +/datum/controller/subsystem/planets/proc/allocateTurfs(var/initial = FALSE) + var/list/currentlist = new_outdoor_turfs + while(currentlist.len) + var/turf/simulated/OT = currentlist[currentlist.len] + currentlist.len-- + if(istype(OT) && z_to_planet.len >= OT.z && z_to_planet[OT.z]) + var/datum/planet/P = z_to_planet[OT.z] + P.planet_floors |= OT + OT.vis_contents |= P.weather_holder.visuals + if(!initial && MC_TICK_CHECK) + return + + currentlist = new_outdoor_walls + while(currentlist.len) + var/turf/unsimulated/wall/planetary/PW = currentlist[currentlist.len] + currentlist.len-- + if(istype(PW) && z_to_planet.len >= PW.z && z_to_planet[PW.z]) + var/datum/planet/P = z_to_planet[PW.z] + P.planet_walls |= PW + if(!initial && MC_TICK_CHECK) + return + +/datum/controller/subsystem/planets/proc/unallocateTurf(var/turf/simulated/T) + if(istype(T) && z_to_planet[T.z]) + var/datum/planet/P = z_to_planet[T.z] + P.planet_floors -= T + T.vis_contents -= P.weather_holder.visuals + + +/datum/controller/subsystem/planets/fire(resumed = 0) + if(new_outdoor_turfs.len || new_outdoor_walls.len) + allocateTurfs() + + if(!resumed) + src.currentrun = planets.Copy() + + var/list/needs_sun_update = src.needs_sun_update + while(needs_sun_update.len) + var/datum/planet/P = needs_sun_update[needs_sun_update.len] + needs_sun_update.len-- + updateSunlight(P) + if(MC_TICK_CHECK) + return + + var/list/needs_temp_update = src.needs_temp_update + while(needs_temp_update.len) + var/datum/planet/P = needs_temp_update[needs_temp_update.len] + needs_temp_update.len-- + updateTemp(P) + if(MC_TICK_CHECK) + return + + var/list/currentrun = src.currentrun + while(currentrun.len) + var/datum/planet/P = currentrun[currentrun.len] + currentrun.len-- + + P.process(last_fire) + + //Sun light needs changing + if(P.needs_work & PLANET_PROCESS_SUN) + P.needs_work &= ~PLANET_PROCESS_SUN + needs_sun_update |= P + + //Temperature needs updating + if(P.needs_work & PLANET_PROCESS_TEMP) + P.needs_work &= ~PLANET_PROCESS_TEMP + needs_temp_update |= P + + if(MC_TICK_CHECK) + return + +/datum/controller/subsystem/planets/proc/updateSunlight(var/datum/planet/P) + // Remove old value from corners + var/list/sunlit_corners = P.sunlit_corners + var/old_lum_r = -P.sun["lum_r"] + var/old_lum_g = -P.sun["lum_g"] + var/old_lum_b = -P.sun["lum_b"] + if(old_lum_r || old_lum_g || old_lum_b) + for(var/C in sunlit_corners) + var/datum/lighting_corner/LC = C + LC.update_lumcount(old_lum_r, old_lum_g, old_lum_b) + CHECK_TICK + sunlit_corners.Cut() + + // Calculate new values to apply + var/new_brightness = P.sun["brightness"] + var/new_color = P.sun["color"] + var/lum_r = new_brightness * GetRedPart (new_color) / 255 + var/lum_g = new_brightness * GetGreenPart(new_color) / 255 + var/lum_b = new_brightness * GetBluePart (new_color) / 255 + var/static/update_gen = -1 // Used to prevent double-processing corners. Otherwise would happen when looping over adjacent turfs. + for(var/I in P.planet_floors) + var/turf/simulated/T = I + if(!T.lighting_corners_initialised) + T.generate_missing_corners() + for(var/C in T.get_corners()) + var/datum/lighting_corner/LC = C + if(LC.update_gen != update_gen && LC.active) + sunlit_corners += LC + LC.update_gen = update_gen + LC.update_lumcount(lum_r, lum_g, lum_b) + CHECK_TICK + update_gen-- + P.sun["lum_r"] = lum_r + P.sun["lum_g"] = lum_g + P.sun["lum_b"] = lum_b + +/datum/controller/subsystem/planets/proc/updateTemp(var/datum/planet/P) + //Set new temperatures + for(var/W in P.planet_walls) + var/turf/unsimulated/wall/planetary/wall = W + wall.set_temperature(P.weather_holder.temperature) + CHECK_TICK + +/datum/controller/subsystem/planets/proc/weatherDisco() + var/count = 100000 + while(count > 0) + count-- + for(var/planet in planets) + var/datum/planet/P = planet + if(P.weather_holder) + P.weather_holder.change_weather(pick(P.weather_holder.allowed_weather_types)) + sleep(3) diff --git a/code/controllers/subsystems/transcore_vr.dm b/code/controllers/subsystems/transcore_vr.dm index feae05ae917..ddac25ee834 100644 --- a/code/controllers/subsystems/transcore_vr.dm +++ b/code/controllers/subsystems/transcore_vr.dm @@ -45,12 +45,18 @@ SUBSYSTEM_DEF(transcore) current_run.len-- //Remove if not in a human anymore. - if(!imp || !ishuman(imp.loc)) + if(!imp || !isorgan(imp.loc)) implants -= imp continue - //We're in a human, at least. - var/mob/living/carbon/human/H = imp.loc + //We're in an organ, at least. + var/obj/item/organ/external/EO = imp.loc + var/mob/living/carbon/human/H = EO.owner + if(!H) + implants -= imp + continue + + //In a human BITSET(H.hud_updateflag, BACKUP_HUD) if(H == imp.imp_in && H.mind && H.stat < DEAD) diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 494e28ffa79..363acf0d698 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -133,9 +133,6 @@ if("Vote") debug_variables(vote) feedback_add_details("admin_verb", "DVote") - if("Planets") - debug_variables(planet_controller) - feedback_add_details("admin_verb", "DPlanets") message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") return diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index b6654650847..765e1ee9e93 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -84,10 +84,8 @@ for(var/mob/living/silicon/robot/robot in mob_list) // No combat/syndicate cyborgs, no drones. - if(robot.module && robot.module.hide_on_manifest) - continue - - bot[robot.name] = "[robot.modtype] [robot.braintype]" + if(!robot.scrambledcodes && !(robot.module && robot.module.hide_on_manifest)) + bot[robot.name] = "[robot.modtype] [robot.braintype]" if(heads.len > 0) diff --git a/code/datums/supplypacks/munitions.dm b/code/datums/supplypacks/munitions.dm index 3413b43014c..eed77bbf2f7 100644 --- a/code/datums/supplypacks/munitions.dm +++ b/code/datums/supplypacks/munitions.dm @@ -22,16 +22,16 @@ cost = 40 containertype = /obj/structure/closet/crate/secure/gear containername = "Security equipment crate" - access = access_security + access = access_security*/ /datum/supply_packs/munitions/egunpistol name = "Weapons - Energy sidearms" contains = list(/obj/item/weapon/gun/energy/gun = 2) - cost = 40 + cost = 50 containertype = /obj/structure/closet/crate/secure/weapon containername = "Energy sidearms crate" - access = access_security -*/ + access = access_armory //VOREStation Edit - Guns are for the armory. + /datum/supply_packs/munitions/flareguns name = "Weapons - Flare guns" contains = list( diff --git a/code/defines/obj.dm b/code/defines/obj.dm index f300496aa2a..272309f7802 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -144,7 +144,7 @@ var/global/list/PDA_Manifest = list() for(var/mob/living/silicon/robot/robot in mob_list) // No combat/syndicate cyborgs, no drones. - if(robot.module && robot.module.hide_on_manifest) + if(!robot.scrambledcodes && !(robot.module && robot.module.hide_on_manifest)) continue bot[++bot.len] = list("name" = robot.real_name, "rank" = "[robot.modtype] [robot.braintype]", "active" = "Active") diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm index 484ff8ea33e..7496551c25f 100644 --- a/code/game/antagonist/antagonist.dm +++ b/code/game/antagonist/antagonist.dm @@ -79,7 +79,9 @@ Think through your actions and make the roleplay immersive! Please remember all \ rules aside from those without explicit exceptions apply to antagonists." - var/can_use_aooc = TRUE // If true, will be given the AOOC verb, along with the ability to use it. +// var/can_use_aooc = TRUE // If true, will be given the AOOC verb, along with the ability to use it. + var/can_hear_aooc = TRUE // If FALSE, the antag can neither speak nor hear AOOC. If TRUE, they can at least hear it. + var/can_speak_aooc = TRUE // If TRUE, the antag can freely spean in AOOC. /datum/antagonist/New() ..() diff --git a/code/game/antagonist/antagonist_add.dm b/code/game/antagonist/antagonist_add.dm index 67eb7e2e726..d5fa2c1fe6f 100644 --- a/code/game/antagonist/antagonist_add.dm +++ b/code/game/antagonist/antagonist_add.dm @@ -36,7 +36,7 @@ and it otherwise has no bearing on your round." player.current.verbs |= /mob/living/proc/write_ambition - if(can_use_aooc) + if(can_speak_aooc) player.current.client.verbs += /client/proc/aooc // Handle only adding a mind and not bothering with gear etc. diff --git a/code/game/antagonist/outsider/ert.dm b/code/game/antagonist/outsider/ert.dm index c1aec2bcf82..245296084c6 100644 --- a/code/game/antagonist/outsider/ert.dm +++ b/code/game/antagonist/outsider/ert.dm @@ -25,7 +25,8 @@ var/datum/antagonist/ert/ert initial_spawn_req = 5 initial_spawn_target = 7 - can_use_aooc = FALSE // They're the good guys. + can_hear_aooc = FALSE // They're the good guys. + can_speak_aooc = FALSE // Just in case the above var bugs, or gets touched. /datum/antagonist/ert/create_default(var/mob/source) var/mob/living/carbon/human/M = ..() diff --git a/code/game/antagonist/outsider/trader.dm b/code/game/antagonist/outsider/trader.dm index 9603b495238..69af3883b97 100644 --- a/code/game/antagonist/outsider/trader.dm +++ b/code/game/antagonist/outsider/trader.dm @@ -24,7 +24,7 @@ var/datum/antagonist/trader/traders initial_spawn_req = 5 initial_spawn_target = 7 - can_use_aooc = FALSE // They're not real antags. + can_speak_aooc = FALSE // They're not real antags. /datum/antagonist/trader/create_default(var/mob/source) var/mob/living/carbon/human/M = ..() diff --git a/code/game/antagonist/station/renegade.dm b/code/game/antagonist/station/renegade.dm index 6f7ec893229..3e8afae32df 100644 --- a/code/game/antagonist/station/renegade.dm +++ b/code/game/antagonist/station/renegade.dm @@ -17,7 +17,7 @@ var/datum/antagonist/renegade/renegades Think through your actions and make the roleplay immersive! Please remember all \ rules aside from those without explicit exceptions apply to antagonists." flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE - can_use_aooc = FALSE + can_speak_aooc = FALSE // They aren't 'true' antags, but they still need to hear blanket antag instructions hard_cap = 8 hard_cap_round = 12 @@ -61,8 +61,6 @@ var/datum/antagonist/renegade/renegades list(/obj/item/weapon/gun/projectile/luger,/obj/item/weapon/gun/projectile/luger/brown) ) - can_use_aooc = FALSE // They aren't 'true' antags. - /datum/antagonist/renegade/New() ..() renegades = src diff --git a/code/game/antagonist/station/thug.dm b/code/game/antagonist/station/thug.dm index 8810fca7d04..61d92e1646f 100644 --- a/code/game/antagonist/station/thug.dm +++ b/code/game/antagonist/station/thug.dm @@ -15,4 +15,4 @@ var/datum/antagonist/thug/thugs Think through your actions and make the roleplay immersive! Please remember all \ rules aside from those with explicit exceptions apply to antagonists." flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE - can_use_aooc = FALSE + can_speak_aooc = FALSE diff --git a/code/game/antagonist/station/traitor.dm b/code/game/antagonist/station/traitor.dm index d0a1f54ed21..3681cf236d7 100644 --- a/code/game/antagonist/station/traitor.dm +++ b/code/game/antagonist/station/traitor.dm @@ -5,7 +5,7 @@ var/datum/antagonist/traitor/traitors id = MODE_TRAITOR protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director") flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE - can_use_aooc = FALSE + can_speak_aooc = FALSE // If they want to plot and plan as this sort of traitor, they'll need to do it ICly. /datum/antagonist/traitor/auto id = MODE_AUTOTRAITOR diff --git a/code/game/gamemodes/changeling/absorbed_dna.dm b/code/game/gamemodes/changeling/absorbed_dna.dm index 3c23f0270c3..26d433cd8cc 100644 --- a/code/game/gamemodes/changeling/absorbed_dna.dm +++ b/code/game/gamemodes/changeling/absorbed_dna.dm @@ -5,12 +5,14 @@ var/list/languages var/identifying_gender var/list/flavour_texts + var/list/genMods -/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender, var/list/newFlavour) +/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender, var/list/newFlavour, var/list/newGenMods) ..() name = newName dna = newDNA speciesName = newSpecies languages = newLanguages identifying_gender = newIdentifying_Gender - flavour_texts = newFlavour ? newFlavour.Copy() : null \ No newline at end of file + flavour_texts = newFlavour ? newFlavour.Copy() : null + genMods = newGenMods ? newGenMods.Copy() : null \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index f76fd5ca477..45b230b00c1 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -78,7 +78,7 @@ src << "We can now re-adapt, reverting our evolution so that we may start anew, if needed." - var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts) + var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts, T.modifiers) absorbDNA(newDNA) if(T.mind && T.mind.changeling) diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm index 92257925757..6dd16061a12 100644 --- a/code/game/gamemodes/changeling/powers/transform.dm +++ b/code/game/gamemodes/changeling/powers/transform.dm @@ -48,6 +48,13 @@ src.UpdateAppearance() domutcheck(src, null) changeling_update_languages(changeling.absorbed_languages) + if(chosen_dna.genMods) + var/mob/living/carbon/human/self = src + for(var/datum/modifier/mod in self.modifiers) + self.modifiers.Remove(mod.type) + + for(var/datum/modifier/mod in chosen_dna.genMods) + self.modifiers.Add(mod.type) src.verbs -= /mob/proc/changeling_transform spawn(10) diff --git a/code/game/gamemodes/events/dust.dm b/code/game/gamemodes/events/dust.dm index 88964fa610f..f41e040ee52 100644 --- a/code/game/gamemodes/events/dust.dm +++ b/code/game/gamemodes/events/dust.dm @@ -83,7 +83,7 @@ The "dust" will damage the hull of the station causin minor hull breaches. endx = world.maxx-TRANSITIONEDGE //VOREStation Edit - No space dust outside of space var/list/z_levels = using_map.station_levels.Copy() - for(var/datum/planet/P in planet_controller.planets) + for(var/datum/planet/P in SSplanets.planets) z_levels.Remove(P.expected_z_levels) var/z_level = pick(z_levels) //VOREStation Edit End diff --git a/code/game/gamemodes/technomancer/spell_objs_helpers.dm b/code/game/gamemodes/technomancer/spell_objs_helpers.dm index f11c027566a..105b3b3e9c8 100644 --- a/code/game/gamemodes/technomancer/spell_objs_helpers.dm +++ b/code/game/gamemodes/technomancer/spell_objs_helpers.dm @@ -31,7 +31,7 @@ return TRUE /obj/item/weapon/spell/proc/within_range(var/atom/target, var/max_range = 7) // Beyond 7 is off the screen. - if(range(get_dist(owner, target) <= max_range)) + if(target in view(max_range, owner)) return TRUE return FALSE diff --git a/code/game/gamemodes/technomancer/spells/apportation.dm b/code/game/gamemodes/technomancer/spells/apportation.dm index 9fafc47ae38..452ddc52fa6 100644 --- a/code/game/gamemodes/technomancer/spells/apportation.dm +++ b/code/game/gamemodes/technomancer/spells/apportation.dm @@ -21,11 +21,13 @@ if(!AM.loc) //Don't teleport HUD telements to us. return if(AM.anchored) - user << "\The [hit_atom] is firmly secured and anchored, you can't move it!" + to_chat(user, "\The [hit_atom] is firmly secured and anchored, you can't move it!") return + if(!within_range(hit_atom) && !check_for_scepter()) - user << "\The [hit_atom] is too far away." + to_chat(user, "\The [hit_atom] is too far away.") return + //Teleporting an item. if(istype(hit_atom, /obj/item)) var/obj/item/I = hit_atom @@ -47,7 +49,7 @@ //Now let's try to teleport a living mob. else if(istype(hit_atom, /mob/living)) var/mob/living/L = hit_atom - L << "You are teleported towards \the [user]." + to_chat(L, "You are teleported towards \the [user].") var/datum/effect/effect/system/spark_spread/s1 = new /datum/effect/effect/system/spark_spread var/datum/effect/effect/system/spark_spread/s2 = new /datum/effect/effect/system/spark_spread s1.set_up(2, 1, user) @@ -60,7 +62,7 @@ spawn(1 SECOND) if(!user.Adjacent(L)) - user << "\The [L] is out of your reach." + to_chat(user, "\The [L] is out of your reach.") qdel(src) return diff --git a/code/game/jobs/job/civilian_chaplain.dm b/code/game/jobs/job/civilian_chaplain.dm index 2eece781ec8..e24e462fdf0 100644 --- a/code/game/jobs/job/civilian_chaplain.dm +++ b/code/game/jobs/job/civilian_chaplain.dm @@ -149,5 +149,7 @@ feedback_set_details("religion_book","[new_book_style]") return 1 +/* If you uncomment this, every time the mob preview updates it makes a new PDA. It seems to work just fine and display without it, so why this exists, haven't a clue. -Hawk /datum/job/chaplain/equip_preview(var/mob/living/carbon/human/H, var/alt_title) return equip(H, alt_title, FALSE) +*/ diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 5396c9bb294..278e516aae6 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -391,7 +391,8 @@ var/global/datum/controller/occupations/job_master H.amend_exploitable(G.path) if(G.slot == "implant") - H.implant_loadout(G) + var/obj/item/weapon/implant/I = G.spawn_item(H) + I.implant_loadout(H) continue if(G.slot && !(G.slot in custom_equip_slots)) diff --git a/code/game/machinery/bioprinter.dm b/code/game/machinery/bioprinter.dm index 0a43acb1724..f66b580c521 100644 --- a/code/game/machinery/bioprinter.dm +++ b/code/game/machinery/bioprinter.dm @@ -13,27 +13,29 @@ idle_power_usage = 40 active_power_usage = 300 - var/stored_matter = 0 - var/max_stored_matter = 0 + var/obj/item/weapon/reagent_containers/container = null // This is the beaker that holds all of the biomass + var/print_delay = 100 + var/base_print_delay = 100 // For Adminbus reasons var/printing var/loaded_dna //Blood sample for DNA hashing. // These should be subtypes of /obj/item/organ + // Costs roughly 20u Phoron (1 sheet) per internal organ, limbs are 60u for limb and extremity var/list/products = list( - "Heart" = list(/obj/item/organ/internal/heart, 25), - "Lungs" = list(/obj/item/organ/internal/lungs, 25), + "Heart" = list(/obj/item/organ/internal/heart, 20), + "Lungs" = list(/obj/item/organ/internal/lungs, 20), "Kidneys" = list(/obj/item/organ/internal/kidneys,20), "Eyes" = list(/obj/item/organ/internal/eyes, 20), - "Liver" = list(/obj/item/organ/internal/liver, 25), - "Arm, Left" = list(/obj/item/organ/external/arm, 65), - "Arm, Right" = list(/obj/item/organ/external/arm/right, 65), - "Leg, Left" = list(/obj/item/organ/external/leg, 65), - "Leg, Right" = list(/obj/item/organ/external/leg/right, 65), - "Foot, Left" = list(/obj/item/organ/external/foot, 40), - "Foot, Right" = list(/obj/item/organ/external/foot/right, 40), - "Hand, Left" = list(/obj/item/organ/external/hand, 40), - "Hand, Right" = list(/obj/item/organ/external/hand/right, 40) + "Liver" = list(/obj/item/organ/internal/liver, 20), + "Arm, Left" = list(/obj/item/organ/external/arm, 40), + "Arm, Right" = list(/obj/item/organ/external/arm/right, 40), + "Leg, Left" = list(/obj/item/organ/external/leg, 40), + "Leg, Right" = list(/obj/item/organ/external/leg/right, 40), + "Foot, Left" = list(/obj/item/organ/external/foot, 20), + "Foot, Right" = list(/obj/item/organ/external/foot/right, 20), + "Hand, Left" = list(/obj/item/organ/external/hand, 20), + "Hand, Right" = list(/obj/item/organ/external/hand/right, 20) ) /obj/machinery/organ_printer/attackby(var/obj/item/O, var/mob/user) @@ -57,25 +59,27 @@ /obj/machinery/organ_printer/New() ..() + component_parts = list() - 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/manipulator(src) RefreshParts() /obj/machinery/organ_printer/examine(var/mob/user) . = ..() - to_chat(user, "It is loaded with [stored_matter]/[max_stored_matter] matter units.") + var/biomass = get_biomass_volume() + if(biomass) + to_chat(user, "It is loaded with [biomass] units of biomass.") + else + to_chat(user, "It is not loaded with any biomass.") /obj/machinery/organ_printer/RefreshParts() - print_delay = initial(print_delay) - max_stored_matter = 0 - for(var/obj/item/weapon/stock_parts/matter_bin/bin in component_parts) - max_stored_matter += bin.rating * 100 + // Print Delay updating + print_delay = base_print_delay for(var/obj/item/weapon/stock_parts/manipulator/manip in component_parts) print_delay -= (manip.rating-1)*10 print_delay = max(0,print_delay) + . = ..() /obj/machinery/organ_printer/attack_hand(mob/user) @@ -91,6 +95,14 @@ to_chat(user, "\The [src] is busy!") return + if(container) + var/response = alert(user, "What do you want to do?", "Bioprinter Menu", "Print Limbs", "Cancel") + if(response == "Print Limbs") + printing_menu(user) + else + to_chat(user, "\The [src] can't operate without a reagent reservoir!") + +/obj/machinery/organ_printer/proc/printing_menu(mob/user) var/choice = input("What would you like to print?") as null|anything in products if(!choice || printing || (stat & (BROKEN|NOPOWER))) @@ -99,7 +111,7 @@ if(!can_print(choice)) return - stored_matter -= products[choice][2] + container.reagents.remove_reagent("biomass", products[choice][2]) use_power = 2 printing = 1 @@ -118,9 +130,42 @@ print_organ(choice) + return + +/obj/machinery/organ_printer/verb/eject_beaker() + set name = "Eject Beaker" + set category = "Object" + set src in oview(1) + + if(usr.stat != 0) + return + add_fingerprint(usr) + remove_beaker() + return + +// Does exactly what it says it does +// Returns 1 if it succeeds, 0 if it fails. Added in case someone wants to add messages to the user. +/obj/machinery/organ_printer/proc/remove_beaker() + if(container) + container.forceMove(get_turf(src)) + container = null + return 1 + return 0 + +// Checks for reagents, then reports how much biomass it has in it +/obj/machinery/organ_printer/proc/get_biomass_volume() + var/biomass_count = 0 + if(container && container.reagents) + for(var/datum/reagent/R in container.reagents.reagent_list) + if(R.id == "biomass") + biomass_count += R.volume + + return biomass_count + /obj/machinery/organ_printer/proc/can_print(var/choice) - if(stored_matter < products[choice][2]) - visible_message("\The [src] displays a warning: 'Not enough matter. [stored_matter] stored and [products[choice][2]] needed.'") + var/biomass = get_biomass_volume() + if(biomass < products[choice][2]) + visible_message("\The [src] displays a warning: 'Not enough biomass. [biomass] stored and [products[choice][2]] needed.'") return 0 if(!loaded_dna || !loaded_dna["donor"]) @@ -162,6 +207,59 @@ /obj/item/weapon/stock_parts/matter_bin = 2, /obj/item/weapon/stock_parts/manipulator = 2) +// FLESH ORGAN PRINTER +/obj/machinery/organ_printer/flesh + name = "bioprinter" + desc = "It's a machine that prints replacement organs." + icon_state = "bioprinter" + circuit = /obj/item/weapon/circuitboard/bioprinter + +/obj/machinery/organ_printer/flesh/full/New() + . = ..() + container = new /obj/item/weapon/reagent_containers/glass/bottle/biomass(src) + +/obj/machinery/organ_printer/flesh/dismantle() + var/turf/T = get_turf(src) + if(T) + if(container) + container.forceMove(T) + container = null + return ..() + +/obj/machinery/organ_printer/flesh/print_organ(var/choice) + var/obj/item/organ/O = ..() + + playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) + visible_message("\The [src] dings, then spits out \a [O].") + return O + +/obj/machinery/organ_printer/flesh/attackby(obj/item/weapon/W, mob/user) + // DNA sample from syringe. + if(istype(W,/obj/item/weapon/reagent_containers/syringe)) //TODO: Make this actually empty the syringe + var/obj/item/weapon/reagent_containers/syringe/S = W + var/datum/reagent/blood/injected = locate() in S.reagents.reagent_list //Grab some blood + if(injected && injected.data) + loaded_dna = injected.data + S.reagents.remove_reagent("blood", injected.volume) + to_chat(user, "You scan the blood sample into the bioprinter.") + return + else if(istype(W,/obj/item/weapon/reagent_containers/glass)) + var/obj/item/weapon/reagent_containers/glass/G = W + if(container) + to_chat(user, "\The [src] already has a container loaded!") + return + else if(do_after(user, 1 SECOND)) + user.visible_message("[user] has loaded \the [G] into \the [src].", "You load \the [G] into \the [src].") + container = G + user.drop_item() + G.forceMove(src) + return + + return ..() +// END FLESH ORGAN PRINTER + + +/* Roboprinter is made obsolete by the system already in place and mapped into Robotics /obj/item/weapon/circuitboard/roboprinter name = "roboprinter circuit" build_path = /obj/machinery/organ_printer/robot @@ -224,53 +322,4 @@ return return ..() // END ROBOT ORGAN PRINTER - -// FLESH ORGAN PRINTER -/obj/machinery/organ_printer/flesh - name = "bioprinter" - desc = "It's a machine that prints replacement organs." - icon_state = "bioprinter" - circuit = /obj/item/weapon/circuitboard/bioprinter - - var/amount_per_slab = 50 - -/obj/machinery/organ_printer/flesh/full/New() - . = ..() - stored_matter = max_stored_matter - -/obj/machinery/organ_printer/flesh/dismantle() - var/turf/T = get_turf(src) - if(T) - while(stored_matter >= amount_per_slab) - stored_matter -= amount_per_slab - new /obj/item/weapon/reagent_containers/food/snacks/meat(T) - return ..() - -/obj/machinery/organ_printer/flesh/print_organ(var/choice) - var/obj/item/organ/O = ..() - - playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) - visible_message("\The [src] dings, then spits out \a [O].") - return O - -/obj/machinery/organ_printer/flesh/attackby(obj/item/weapon/W, mob/user) - // Load with matter for printing. - if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat)) - if((max_stored_matter - stored_matter) < amount_per_slab) - to_chat(user, "\The [src] is too full.") - return - stored_matter += amount_per_slab - user.drop_item() - to_chat(user, "\The [src] processes \the [W]. Levels of stored biomass now: [stored_matter]") - qdel(W) - return - // DNA sample from syringe. - else if(istype(W,/obj/item/weapon/reagent_containers/syringe)) //TODO: Make this actually empty the syringe - var/obj/item/weapon/reagent_containers/syringe/S = W - var/datum/reagent/blood/injected = locate() in S.reagents.reagent_list //Grab some blood - if(injected && injected.data) - loaded_dna = injected.data - to_chat(user, "You scan the blood sample into the bioprinter.") - return - return ..() -// END FLESH ORGAN PRINTER \ No newline at end of file +*/ \ No newline at end of file diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 4e1d015033d..a1ef2a8a838 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -23,7 +23,7 @@ break return selected -#define CLONE_BIOMASS 150 +#define CLONE_BIOMASS 30 //VOREstation Edit /obj/machinery/clonepod name = "cloning pod" @@ -33,17 +33,18 @@ circuit = /obj/item/weapon/circuitboard/clonepod icon = 'icons/obj/cloning.dmi' icon_state = "pod_0" - req_access = list(access_genetics) //For premature unlocking. + req_access = list(access_genetics) // For premature unlocking. var/mob/living/occupant - var/heal_level = 20 //The clone is released once its health reaches this level. + var/heal_level = 20 // The clone is released once its health reaches this level. var/heal_rate = 1 - var/notoxin = 0 var/locked = 0 var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine. - var/mess = 0 //Need to clean out it if it's full of exploded clone. - var/attempting = 0 //One clone attempt at a time thanks - var/eject_wait = 0 //Don't eject them as soon as they are created fuckkk - var/biomass = CLONE_BIOMASS * 3 + var/mess = 0 // Need to clean out it if it's full of exploded clone. + var/attempting = 0 // One clone attempt at a time thanks + var/eject_wait = 0 // Don't eject them as soon as they are created fuckkk + + var/list/containers = list() // Beakers for our liquid biomass + var/container_limit = 3 // How many beakers can the machine hold? /obj/machinery/clonepod/New() ..() @@ -68,11 +69,9 @@ return if((!isnull(occupant)) && (occupant.stat != 2)) var/completion = (100 * ((occupant.health + 50) / (heal_level + 100))) // Clones start at -150 health - user << "Current clone cycle is [round(completion)]% complete." + to_chat(user, "Current clone cycle is [round(completion)]% complete.") return -//Clonepod - //Start growing a human clone in the pod! /obj/machinery/clonepod/proc/growclone(var/datum/dna2/record/R) if(mess || attempting) @@ -98,6 +97,9 @@ if(istype(modifier_type, /datum/modifier/no_clone)) return 0 + // Remove biomass when the cloning is started, rather than when the guy pops out + remove_biomass(CLONE_BIOMASS) + attempting = 1 //One at a time!! locked = 1 @@ -164,6 +166,7 @@ for(var/datum/language/L in R.languages) H.add_language(L.name) + H.flavor_texts = R.flavor.Copy() H.suiciding = 0 attempting = 0 @@ -171,16 +174,6 @@ //Grow clones to maturity then kick them out. FREELOADERS /obj/machinery/clonepod/process() - - var/visible_message = 0 - for(var/obj/item/weapon/reagent_containers/food/snacks/meat/meat in range(1, src)) - qdel(meat) - biomass += 50 - visible_message = 1 // Prevent chatspam when multiple meat are near - - if(visible_message) - visible_message("[src] sucks in and processes the nearby biomass.") - if(stat & NOPOWER) //Autoeject if power is lost if(occupant) locked = 0 @@ -240,25 +233,28 @@ return if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if(!check_access(W)) - user << "Access Denied." + to_chat(user, "Access Denied.") return if((!locked) || (isnull(occupant))) return if((occupant.health < -20) && (occupant.stat != 2)) - user << "Access Refused." + to_chat(user, "Access Refused.") return else locked = 0 - user << "System unlocked." - else if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat)) - user << "\The [src] processes \the [W]." - biomass += 50 - user.drop_item() - qdel(W) + to_chat(user, "System unlocked.") + else if(istype(W,/obj/item/weapon/reagent_containers/glass)) + if(LAZYLEN(containers) >= container_limit) + to_chat(user, "\The [src] has too many containers loaded!") + else if(do_after(user, 1 SECOND)) + user.visible_message("[user] has loaded \the [W] into \the [src].", "You load \the [W] into \the [src].") + containers += W + user.drop_item() + W.forceMove(src) return else if(istype(W, /obj/item/weapon/wrench)) if(locked && (anchored || occupant)) - user << "Can not do that while [src] is in use." + to_chat(user, "Can not do that while [src] is in use.") else if(anchored) anchored = 0 @@ -274,7 +270,7 @@ else if(istype(W, /obj/item/device/multitool)) var/obj/item/device/multitool/M = W M.connecting = src - user << "You load connection data from [src] to [M]." + to_chat(user, "You load connection data from [src] to [M].") M.update_icon() return else @@ -283,7 +279,7 @@ /obj/machinery/clonepod/emag_act(var/remaining_charges, var/mob/user) if(isnull(occupant)) return - user << "You force an emergency ejection." + to_chat(user, "You force an emergency ejection.") locked = 0 go_out() return 1 @@ -308,10 +304,6 @@ heal_level = rating * 10 - 20 heal_rate = round(rating / 4) - if(rating >= 8) - notoxin = 1 - else - notoxin = 0 /obj/machinery/clonepod/verb/eject() set name = "Eject Cloner" @@ -348,10 +340,66 @@ domutcheck(occupant) //Waiting until they're out before possible transforming. occupant = null - biomass -= CLONE_BIOMASS update_icon() return +// Returns the total amount of biomass reagent in all of the pod's stored containers +/obj/machinery/clonepod/proc/get_biomass() + var/biomass_count = 0 + if(LAZYLEN(containers)) + for(var/obj/item/weapon/reagent_containers/glass/G in containers) + for(var/datum/reagent/R in G.reagents.reagent_list) + if(R.id == "biomass") + biomass_count += R.volume + + return biomass_count + +// Removes [amount] biomass, spread across all containers. Doesn't have any check that you actually HAVE enough biomass, though. +/obj/machinery/clonepod/proc/remove_biomass(var/amount = CLONE_BIOMASS) //Just in case it doesn't get passed a new amount, assume one clone + var/to_remove = 0 // Tracks how much biomass has been found so far + if(LAZYLEN(containers)) + for(var/obj/item/weapon/reagent_containers/glass/G in containers) + if(to_remove < amount) //If we have what we need, we can stop. Checked every time we switch beakers + for(var/datum/reagent/R in G.reagents.reagent_list) + if(R.id == "biomass") // Finds Biomass + var/need_remove = max(0, amount - to_remove) //Figures out how much biomass is in this container + if(R.volume >= need_remove) //If we have more than enough in this beaker, only take what we need + R.remove_self(need_remove) + to_remove = amount + else //Otherwise, take everything and move on + to_remove += R.volume + R.remove_self(R.volume) + else + continue + else + return 1 + return 0 + +// Empties all of the beakers from the cloning pod, used to refill it +/obj/machinery/clonepod/verb/empty_beakers() + set name = "Eject Beakers" + set category = "Object" + set src in oview(1) + + if(usr.stat != 0) + return + + add_fingerprint(usr) + drop_beakers() + return + +// Actually does all of the beaker dropping +// Returns 1 if it succeeds, 0 if it fails. Added in case someone wants to add messages to the user. +/obj/machinery/clonepod/proc/drop_beakers() + if(LAZYLEN(containers)) + var/turf/T = get_turf(src) + if(T) + for(var/obj/item/weapon/reagent_containers/glass/G in containers) + G.forceMove(T) + containers -= G + return 1 + return 0 + /obj/machinery/clonepod/proc/malfunction() if(occupant) connected_message("Critical Error!") @@ -406,6 +454,12 @@ else if(mess) icon_state = "pod_g" + +/obj/machinery/clonepod/full/New() + ..() + for(var/i = 1 to container_limit) + containers += new /obj/item/weapon/reagent_containers/glass/bottle/biomass(src) + //Health Tracker Implant /obj/item/weapon/implant/health @@ -475,11 +529,11 @@ /obj/item/weapon/disk/data/attack_self(mob/user as mob) read_only = !read_only - user << "You flip the write-protect tab to [read_only ? "protected" : "unprotected"]." + to_chat(user, "You flip the write-protect tab to [read_only ? "protected" : "unprotected"].") /obj/item/weapon/disk/data/examine(mob/user) ..(user) - user << text("The write-protect tab is set to [read_only ? "protected" : "unprotected"].") + to_chat(user, text("The write-protect tab is set to [read_only ? "protected" : "unprotected"].")) return /* diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index fa491c20e75..0e68f1e7a3c 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -200,14 +200,16 @@ GLOBAL_LIST_BOILERPLATE(all_deactivated_AI_cores, /obj/structure/AIcore/deactiva if(!istype(transfer) || locate(/mob/living/silicon/ai) in src) return + if(transfer.controlling_drone) + transfer.controlling_drone.release_ai_control("Unit control lost. Core transfer completed.") transfer.aiRestorePowerRoutine = 0 transfer.control_disabled = 0 transfer.aiRadio.disabledAi = 0 transfer.loc = get_turf(src) transfer.create_eyeobj() transfer.cancel_camera() - user << "Transfer successful: [transfer.name] placed within stationary core." - transfer << "You have been transferred into a stationary core. Remote device connection restored." + to_chat(user, "Transfer successful: [transfer.name] placed within stationary core.") + to_chat(transfer, "You have been transferred into a stationary core. Remote device connection restored.") if(card) card.clear() diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 4935a2a552e..9660eca8bcb 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -67,7 +67,7 @@ user.drop_item() W.loc = src diskette = W - user << "You insert [W]." + to_chat(user, "You insert [W].") updateUsrDialog() return else if(istype(W, /obj/item/device/multitool)) @@ -77,7 +77,7 @@ pods += P P.connected = src P.name = "[initial(P.name)] #[pods.len]" - user << "You connect [P] to [src]." + to_chat(user, "You connect [P] to [src].") else if (menu == 4 && (istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))) if(check_access(W)) @@ -116,7 +116,7 @@ var/pods_list_ui[0] for(var/obj/machinery/clonepod/pod in pods) - pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.biomass) + pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.get_biomass()) if(pods) data["pods"] = pods_list_ui @@ -244,7 +244,7 @@ //Look for that player! They better be dead! if(istype(C)) //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. - if(!pods.len) + if(!LAZYLEN(pods)) temp = "Error: No clone pods detected." else var/obj/machinery/clonepod/pod = pods[1] @@ -252,13 +252,12 @@ pod = input(usr,"Select a cloning pod to use", "Pod selection") as anything in pods if(pod.occupant) temp = "Error: Clonepod is currently occupied." - else if(pod.biomass < CLONE_BIOMASS) + else if(pod.get_biomass() < CLONE_BIOMASS) temp = "Error: Not enough biomass." else if(pod.mess) temp = "Error: Clonepod malfunction." else if(!config.revival_cloning) temp = "Error: Unable to initiate cloning cycle." - else if(pod.growclone(C)) temp = "Initiating cloning cycle..." records.Remove(C) diff --git a/code/game/machinery/computer3/laptop.dm b/code/game/machinery/computer3/laptop.dm index 38db5742006..9a8ba02b002 100644 --- a/code/game/machinery/computer3/laptop.dm +++ b/code/game/machinery/computer3/laptop.dm @@ -28,6 +28,9 @@ var/obj/machinery/computer3/laptop/stored_computer = null +/obj/item/device/laptop/get_cell() + return stored_computer.battery + /obj/item/device/laptop/verb/open_computer() set name = "Open Laptop" set category = "Object" diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index d13dcf3e80b..e5ebbc7d17f 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -362,6 +362,8 @@ qdel(R.mmi) for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc + for(var/mob/M in I) //VOREStation edit + despawn_occupant(M) for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags O.forceMove(R) qdel(I) diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index ccb17a1297f..2b59a24bd1d 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -47,6 +47,7 @@ var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg var/check_all = 0 //If active, will fire on anything, including synthetics. var/ailock = 0 // AI cannot use this + var/faction = null //if set, will not fire at people in the same faction for any reason. var/attacked = 0 //if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!) @@ -80,6 +81,11 @@ lethal = 1 installation = /obj/item/weapon/gun/energy/laser +/obj/machinery/porta_turret/stationary/syndie // Generic turrets for POIs that need to not shoot their buddies. + enabled = TRUE + check_all = TRUE + faction = "syndicate" // Make sure this equals the faction that the mobs in the POI have or they will fight each other. + /obj/machinery/porta_turret/ai_defense name = "defense turret" desc = "This variant appears to be much more durable." @@ -552,6 +558,9 @@ var/list/turret_icons if(!L) return TURRET_NOT_TARGET + if(faction && L.faction == faction) + return TURRET_NOT_TARGET + if(!emagged && issilicon(L) && check_all == 0) // Don't target silica, unless told to neutralize everything. return TURRET_NOT_TARGET diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 3d2601b59d7..c6bb798279d 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -41,35 +41,12 @@ obj/machinery/recharger return if(istype(G, /obj/item/weapon/gun/energy)) var/obj/item/weapon/gun/energy/E = G - if(!E.power_supply) - to_chat(user, "Your gun has no power cell.") - return if(E.self_recharge) to_chat(user, "Your gun has no recharge port.") return - if(istype(G, /obj/item/weapon/gun/energy/staff)) + if(!G.get_cell()) + to_chat(user, "This device does not have a battery installed.") return - if(istype(G, /obj/item/device/flashlight)) - var/obj/item/device/flashlight/F = G - if(!F.power_use) - return - if(!F.cell) - return - if(istype(G, /obj/item/device/laptop)) - var/obj/item/device/laptop/L = G - if(!L.stored_computer.battery) - user << "There's no battery in it!" - return - if(istype(G, /obj/item/device/electronic_assembly)) - var/obj/item/device/electronic_assembly/assembly = G - if(!assembly.battery) - to_chat(user, "The assembly doesn't have a power cell.") - return - if(istype(G, /obj/item/weapon/weldingtool/electric)) - var/obj/item/weapon/weldingtool/electric/welder = G - if(!welder.power_supply) - to_chat(user, "Your welder has no power cell.") - return user.drop_item() G.loc = src @@ -109,71 +86,8 @@ obj/machinery/recharger update_use_power(1) icon_state = icon_state_idle else - if(istype(charging, /obj/item/weapon/gun/energy)) - var/obj/item/weapon/gun/energy/E = charging - if(!E.power_supply.fully_charged()) - icon_state = icon_state_charging - E.power_supply.give(active_power_usage*CELLRATE) - update_use_power(2) - else - icon_state = icon_state_charged - update_use_power(1) - return - - if(istype(charging, /obj/item/weapon/gun/magnetic)) - var/obj/item/weapon/gun/magnetic/M = charging - if(!M.cell.fully_charged()) - icon_state = icon_state_charging - M.cell.give(active_power_usage*CELLRATE) - update_use_power(2) - else - icon_state = icon_state_charged - update_use_power(1) - return - - if(istype(charging, /obj/item/weapon/melee/baton)) - var/obj/item/weapon/melee/baton/B = charging - if(B.bcell) - if(!B.bcell.fully_charged()) - icon_state = icon_state_charging - B.bcell.give(active_power_usage*CELLRATE) - update_use_power(2) - else - icon_state = icon_state_charged - update_use_power(1) - else - icon_state = icon_state_idle - update_use_power(1) - return - - if(istype(charging, /obj/item/device/laptop)) - var/obj/item/device/laptop/L = charging - if(!L.stored_computer.battery.fully_charged()) - icon_state = icon_state_charging - L.stored_computer.battery.give(active_power_usage*CELLRATE) - update_use_power(2) - else - icon_state = icon_state_charged - update_use_power(1) - return - - if(istype(charging, /obj/item/device/flashlight)) - var/obj/item/device/flashlight/F = charging - if(F.cell) - if(!F.cell.fully_charged()) - icon_state = icon_state_charging - F.cell.give(active_power_usage*CELLRATE) - update_use_power(2) - else - icon_state = icon_state_charged - update_use_power(1) - else - icon_state = icon_state_idle - update_use_power(1) - return - - if(istype(charging, /obj/item/weapon/cell)) - var/obj/item/weapon/cell/C = charging + var/obj/item/weapon/cell/C = charging.get_cell() + if(istype(C)) if(!C.fully_charged()) icon_state = icon_state_charging C.give(active_power_usage*CELLRATE) @@ -181,25 +95,9 @@ obj/machinery/recharger else icon_state = icon_state_charged update_use_power(1) - return - - if(istype(charging, /obj/item/device/electronic_assembly)) - var/obj/item/device/electronic_assembly/assembly = charging - if(assembly.battery) - if(!assembly.battery.fully_charged()) - icon_state = icon_state_charging - assembly.battery.give(active_power_usage*CELLRATE) - update_use_power(2) - else - icon_state = icon_state_charged - update_use_power(1) - else - icon_state = icon_state_idle - update_use_power(1) - return //VOREStation Add - NSFW Batteries - if(istype(charging, /obj/item/ammo_casing/nsfw_batt)) + else if(istype(charging, /obj/item/ammo_casing/nsfw_batt)) var/obj/item/ammo_casing/nsfw_batt/batt = charging if(batt.shots_left >= initial(batt.shots_left)) icon_state = icon_state_charged @@ -211,31 +109,16 @@ obj/machinery/recharger return //VOREStation Add End - if(istype(charging, /obj/item/weapon/weldingtool/electric)) - var/obj/item/weapon/weldingtool/electric/C = charging - if(!C.power_supply.fully_charged()) - icon_state = icon_state_charging - C.power_supply.give(active_power_usage*CELLRATE) - update_use_power(2) - else - icon_state = icon_state_charged - update_use_power(1) - return - /obj/machinery/recharger/emp_act(severity) if(stat & (NOPOWER|BROKEN) || !anchored) ..(severity) return - if(istype(charging, /obj/item/weapon/gun/energy)) - var/obj/item/weapon/gun/energy/E = charging - if(E.power_supply) - E.power_supply.emp_act(severity) + if(charging) + var/obj/item/weapon/cell/C = charging.get_cell() + if(istype(C)) + C.emp_act(severity) - else if(istype(charging, /obj/item/weapon/melee/baton)) - var/obj/item/weapon/melee/baton/B = charging - if(B.bcell) - B.bcell.charge = 0 ..(severity) /obj/machinery/recharger/update_icon() //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier. @@ -244,7 +127,6 @@ obj/machinery/recharger else icon_state = icon_state_idle - /obj/machinery/recharger/wallcharger name = "wall recharger" icon = 'icons/obj/stationobjs.dmi' diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index 08f369d735e..dc4bf5146ab 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -31,6 +31,7 @@ GLOBAL_LIST_BOILERPLATE(all_portals, /obj/effect/portal) return /obj/effect/portal/New() + ..() // Necessary for the list boilerplate to work spawn(300) qdel(src) return diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index b57c67bac09..7e288dbadcf 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -64,20 +64,24 @@ add_attack_logs(user,carded_ai,"Purged from AI Card") flush = 1 carded_ai.suiciding = 1 - carded_ai << "Your power has been disabled!" + to_chat(carded_ai, "Your power has been disabled!") while (carded_ai && carded_ai.stat != 2) + if(carded_ai.controlling_drone && prob(carded_ai.oxyloss)) //You feel it creeping? Eventually will reach 100, resulting in the second half of the AI's remaining life being lonely. + carded_ai.controlling_drone.release_ai_control("Unit lost. Integrity too low to maintain connection.") carded_ai.adjustOxyLoss(2) carded_ai.updatehealth() sleep(10) flush = 0 if (href_list["radio"]) carded_ai.aiRadio.disabledAi = text2num(href_list["radio"]) - carded_ai << "Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!" - user << "You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver." + to_chat(carded_ai, "Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!") + to_chat(user, "You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.") if (href_list["wireless"]) carded_ai.control_disabled = text2num(href_list["wireless"]) - carded_ai << "Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!" - user << "You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface." + to_chat(carded_ai, "Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!") + to_chat(user, "You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.") + if(carded_ai.control_disabled && carded_ai.controlling_drone) + carded_ai.controlling_drone.release_ai_control("Unit control terminated at intellicore port.") update_icon() return 1 @@ -94,12 +98,12 @@ icon_state = "aicard" /obj/item/device/aicard/proc/grab_ai(var/mob/living/silicon/ai/ai, var/mob/living/user) - if(!ai.client) - user << "ERROR: AI [ai.name] is offline. Unable to transfer." + if(!ai.client && !ai.controlling_drone) + to_chat(user, "ERROR: AI [ai.name] is offline. Unable to transfer.") return 0 if(carded_ai) - user << "Transfer failed: Existing AI found on remote device. Remove existing AI to install a new one." + to_chat(user, "Transfer failed: Existing AI found on remote device. Remove existing AI to install a new one.") return 0 if(!user.IsAdvancedToolUser() && isanimal(user)) @@ -108,7 +112,9 @@ return 0 user.visible_message("\The [user] starts transferring \the [ai] into \the [src]...", "You start transferring \the [ai] into \the [src]...") - ai << "\The [user] is transferring you into \the [src]!" + to_chat(ai, "\The [user] is transferring you into \the [src]!") + if(ai.controlling_drone) + to_chat(ai.controlling_drone, "\The [user] is transferring you into \the [src]!") if(do_after(user, 100)) if(istype(ai.loc, /turf/)) @@ -124,11 +130,13 @@ ai.control_disabled = 1 ai.aiRestorePowerRoutine = 0 carded_ai = ai + if(ai.controlling_drone) + ai.controlling_drone.release_ai_control("Unit control lost.") if(ai.client) - ai << "You have been transferred into a mobile core. Remote access lost." + to_chat(ai, "You have been transferred into a mobile core. Remote access lost.") if(user.client) - user << "Transfer successful: [ai.name] extracted from current device and placed within mobile core." + to_chat(ai, "Transfer successful: [ai.name] extracted from current device and placed within mobile core.") ai.canmove = 1 update_icon() diff --git a/code/game/objects/items/devices/communicator/UI.dm b/code/game/objects/items/devices/communicator/UI.dm index 9d43da5c9aa..fca4cf4866d 100644 --- a/code/game/objects/items/devices/communicator/UI.dm +++ b/code/game/objects/items/devices/communicator/UI.dm @@ -1,253 +1,252 @@ -// Proc: ui_interact() -// Parameters: 4 (standard NanoUI arguments) -// Description: Uses a bunch of for loops to turn lists into lists of lists, so they can be displayed in nanoUI, then displays various buttons to the user. -/obj/item/device/communicator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/key_state = null) - // this is the data which will be sent to the ui - var/data[0] //General nanoUI information - var/communicators[0] //List of communicators - var/invites[0] //Communicators and ghosts we've invited to our communicator. - var/requests[0] //Communicators and ghosts wanting to go in our communicator. - var/voices[0] //Current /mob/living/voice s inside the device. - var/connected_communicators[0] //Current communicators connected to the device. - - var/im_contacts_ui[0] //List of communicators that have been messaged. - var/im_list_ui[0] //List of messages. - - var/weather[0] - var/injection = null - var/modules_ui[0] //Home screen info. - - //First we add other 'local' communicators. - for(var/obj/item/device/communicator/comm in known_devices) - if(comm.network_visibility && comm.exonet) - communicators[++communicators.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address) - - //Now for ghosts who we pretend have communicators. - for(var/mob/observer/dead/O in known_devices) - if(O.client && O.client.prefs.communicator_visibility == 1 && O.exonet) - communicators[++communicators.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]") - - //Lists all the other communicators that we invited. - for(var/obj/item/device/communicator/comm in voice_invites) - if(comm.exonet) - invites[++invites.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]") - - //Ghosts we invited. - for(var/mob/observer/dead/O in voice_invites) - if(O.exonet && O.client) - invites[++invites.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]") - - //Communicators that want to talk to us. - for(var/obj/item/device/communicator/comm in voice_requests) - if(comm.exonet) - requests[++requests.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]") - - //Ghosts that want to talk to us. - for(var/mob/observer/dead/O in voice_requests) - if(O.exonet && O.client) - requests[++requests.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]") - - //Now for all the voice mobs inside the communicator. - for(var/mob/living/voice/voice in contents) - voices[++voices.len] = list("name" = sanitize("[voice.name]'s communicator"), "true_name" = sanitize(voice.name)) - - //Finally, all the communicators linked to this one. - for(var/obj/item/device/communicator/comm in communicating) - connected_communicators[++connected_communicators.len] = list("name" = sanitize(comm.name), "true_name" = sanitize(comm.name), "ref" = "\ref[comm]") - - //Devices that have been messaged or recieved messages from. - for(var/obj/item/device/communicator/comm in im_contacts) - if(comm.exonet) - im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]") - - for(var/mob/observer/dead/ghost in im_contacts) - if(ghost.exonet) - im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(ghost.name), "address" = ghost.exonet.address, "ref" = "\ref[ghost]") - - //Actual messages. - for(var/I in im_list) - im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"]) - - //Weather reports. - if(planet_controller) - for(var/datum/planet/planet in planet_controller.planets) - if(planet.weather_holder && planet.weather_holder.current_weather) - var/list/W = list( - "Planet" = planet.name, - "Time" = planet.current_time.show_time("hh:mm"), - "Weather" = planet.weather_holder.current_weather.name, - "Temperature" = planet.weather_holder.temperature - T0C, - "High" = planet.weather_holder.current_weather.temp_high - T0C, - "Low" = planet.weather_holder.current_weather.temp_low - T0C) - weather[++weather.len] = W - - injection = "
Test
" - - //Modules for homescreen. - for(var/list/R in modules) - modules_ui[++modules_ui.len] = R - - data["owner"] = owner ? owner : "Unset" - data["occupation"] = occupation ? occupation : "Swipe ID to set." - data["connectionStatus"] = get_connection_to_tcomms() - data["visible"] = network_visibility - data["address"] = exonet.address ? exonet.address : "Unallocated" - data["targetAddress"] = target_address - data["targetAddressName"] = target_address_name - data["currentTab"] = selected_tab - data["knownDevices"] = communicators - data["invitesSent"] = invites - data["requestsReceived"] = requests - data["voice_mobs"] = voices - data["communicating"] = connected_communicators - data["video_comm"] = video_source ? "\ref[video_source.loc]" : null - data["imContacts"] = im_contacts_ui - data["imList"] = im_list_ui - data["time"] = stationtime2text() - data["ring"] = ringer - data["homeScreen"] = modules_ui - data["note"] = note // current notes - data["weather"] = weather - data["aircontents"] = src.analyze_air() - data["flashlight"] = fon - data["injection"] = injection - - // update the ui if it exists, returns null if no ui is passed/found - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "communicator.tmpl", "Communicator", 475, 700, state = key_state) - // add templates for screens in common with communicator. - ui.add_template("atmosphericScan", "atmospheric_scan.tmpl") - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every five Master Controller tick - ui.set_auto_update(5) - -// Proc: Topic() -// Parameters: 2 (standard Topic arguments) -// Description: Responds to NanoUI button presses. -/obj/item/device/communicator/Topic(href, href_list) - if(..()) - return 1 - if(href_list["rename"]) - var/new_name = sanitizeSafe(input(usr,"Please enter your name.","Communicator",usr.name) ) - if(new_name) - register_device(new_name) - - if(href_list["toggle_visibility"]) - switch(network_visibility) - if(1) //Visible, becoming invisbile - network_visibility = 0 - if(camera) - camera.remove_network(NETWORK_COMMUNICATORS) - if(0) //Invisible, becoming visible - network_visibility = 1 - if(camera) - camera.add_network(NETWORK_COMMUNICATORS) - - if(href_list["toggle_ringer"]) - ringer = !ringer - - if(href_list["add_hex"]) - var/hex = href_list["add_hex"] - add_to_EPv2(hex) - - if(href_list["write_target_address"]) - var/new_address = sanitizeSafe(input(usr,"Please enter the desired target EPv2 address. Note that you must write the colons \ - yourself.","Communicator",src.target_address) ) - if(new_address) - target_address = new_address - - if(href_list["clear_target_address"]) - target_address = "" - - if(href_list["dial"]) - if(!get_connection_to_tcomms()) - usr << "Error: Cannot connect to Exonet node." - return - var/their_address = href_list["dial"] - exonet.send_message(their_address, "voice") - - if(href_list["decline"]) - var/ref_to_remove = href_list["decline"] - var/atom/decline = locate(ref_to_remove) - if(decline) - del_request(decline) - - if(href_list["message"]) - if(!get_connection_to_tcomms()) - usr << "Error: Cannot connect to Exonet node." - return - var/their_address = href_list["message"] - var/text = sanitizeSafe(input(usr,"Enter your message.","Text Message")) - if(text) - exonet.send_message(their_address, "text", text) - im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text)) - log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]", usr) - for(var/mob/M in player_list) - if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) - if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat) - continue - if(exonet.get_atom_from_address(their_address) == M) - continue - M.show_message("Comm IM - [src] -> [exonet.get_atom_from_address(their_address)]: [text]") - - if(href_list["disconnect"]) - var/name_to_disconnect = href_list["disconnect"] - for(var/mob/living/voice/V in contents) - if(name_to_disconnect == V.name) - close_connection(usr, V, "[usr] hung up") - for(var/obj/item/device/communicator/comm in communicating) - if(name_to_disconnect == comm.name) - close_connection(usr, comm, "[usr] hung up") - - if(href_list["startvideo"]) - var/ref_to_video = href_list["startvideo"] - var/obj/item/device/communicator/comm = locate(ref_to_video) - if(comm) - connect_video(usr, comm) - - if(href_list["endvideo"]) - if(video_source) - end_video() - - if(href_list["watchvideo"]) - if(video_source) - watch_video(usr,video_source.loc) - - if(href_list["copy"]) - target_address = href_list["copy"] - - if(href_list["copy_name"]) - target_address_name = href_list["copy_name"] - - if(href_list["hang_up"]) - for(var/mob/living/voice/V in contents) - close_connection(usr, V, "[usr] hung up") - for(var/obj/item/device/communicator/comm in communicating) - close_connection(usr, comm, "[usr] hung up") - - if(href_list["switch_tab"]) - selected_tab = href_list["switch_tab"] - - if(href_list["edit"]) - var/n = input(usr, "Please enter message", name, notehtml) - n = sanitizeSafe(n, extra = 0) - if(n) - note = html_decode(n) - notehtml = note - note = replacetext(note, "\n", "
") - else - note = "" - notehtml = note - - if(href_list["Light"]) - fon = !fon - set_light(fon * flum) - - nanomanager.update_uis(src) - add_fingerprint(usr) +// Proc: ui_interact() +// Parameters: 4 (standard NanoUI arguments) +// Description: Uses a bunch of for loops to turn lists into lists of lists, so they can be displayed in nanoUI, then displays various buttons to the user. +/obj/item/device/communicator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/key_state = null) + // this is the data which will be sent to the ui + var/data[0] //General nanoUI information + var/communicators[0] //List of communicators + var/invites[0] //Communicators and ghosts we've invited to our communicator. + var/requests[0] //Communicators and ghosts wanting to go in our communicator. + var/voices[0] //Current /mob/living/voice s inside the device. + var/connected_communicators[0] //Current communicators connected to the device. + + var/im_contacts_ui[0] //List of communicators that have been messaged. + var/im_list_ui[0] //List of messages. + + var/weather[0] + var/injection = null + var/modules_ui[0] //Home screen info. + + //First we add other 'local' communicators. + for(var/obj/item/device/communicator/comm in known_devices) + if(comm.network_visibility && comm.exonet) + communicators[++communicators.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address) + + //Now for ghosts who we pretend have communicators. + for(var/mob/observer/dead/O in known_devices) + if(O.client && O.client.prefs.communicator_visibility == 1 && O.exonet) + communicators[++communicators.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]") + + //Lists all the other communicators that we invited. + for(var/obj/item/device/communicator/comm in voice_invites) + if(comm.exonet) + invites[++invites.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]") + + //Ghosts we invited. + for(var/mob/observer/dead/O in voice_invites) + if(O.exonet && O.client) + invites[++invites.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]") + + //Communicators that want to talk to us. + for(var/obj/item/device/communicator/comm in voice_requests) + if(comm.exonet) + requests[++requests.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]") + + //Ghosts that want to talk to us. + for(var/mob/observer/dead/O in voice_requests) + if(O.exonet && O.client) + requests[++requests.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]") + + //Now for all the voice mobs inside the communicator. + for(var/mob/living/voice/voice in contents) + voices[++voices.len] = list("name" = sanitize("[voice.name]'s communicator"), "true_name" = sanitize(voice.name)) + + //Finally, all the communicators linked to this one. + for(var/obj/item/device/communicator/comm in communicating) + connected_communicators[++connected_communicators.len] = list("name" = sanitize(comm.name), "true_name" = sanitize(comm.name), "ref" = "\ref[comm]") + + //Devices that have been messaged or recieved messages from. + for(var/obj/item/device/communicator/comm in im_contacts) + if(comm.exonet) + im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]") + + for(var/mob/observer/dead/ghost in im_contacts) + if(ghost.exonet) + im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(ghost.name), "address" = ghost.exonet.address, "ref" = "\ref[ghost]") + + //Actual messages. + for(var/I in im_list) + im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"]) + + //Weather reports. + for(var/datum/planet/planet in SSplanets.planets) + if(planet.weather_holder && planet.weather_holder.current_weather) + var/list/W = list( + "Planet" = planet.name, + "Time" = planet.current_time.show_time("hh:mm"), + "Weather" = planet.weather_holder.current_weather.name, + "Temperature" = planet.weather_holder.temperature - T0C, + "High" = planet.weather_holder.current_weather.temp_high - T0C, + "Low" = planet.weather_holder.current_weather.temp_low - T0C) + weather[++weather.len] = W + + injection = "
Test
" + + //Modules for homescreen. + for(var/list/R in modules) + modules_ui[++modules_ui.len] = R + + data["owner"] = owner ? owner : "Unset" + data["occupation"] = occupation ? occupation : "Swipe ID to set." + data["connectionStatus"] = get_connection_to_tcomms() + data["visible"] = network_visibility + data["address"] = exonet.address ? exonet.address : "Unallocated" + data["targetAddress"] = target_address + data["targetAddressName"] = target_address_name + data["currentTab"] = selected_tab + data["knownDevices"] = communicators + data["invitesSent"] = invites + data["requestsReceived"] = requests + data["voice_mobs"] = voices + data["communicating"] = connected_communicators + data["video_comm"] = video_source ? "\ref[video_source.loc]" : null + data["imContacts"] = im_contacts_ui + data["imList"] = im_list_ui + data["time"] = stationtime2text() + data["ring"] = ringer + data["homeScreen"] = modules_ui + data["note"] = note // current notes + data["weather"] = weather + data["aircontents"] = src.analyze_air() + data["flashlight"] = fon + data["injection"] = injection + + // update the ui if it exists, returns null if no ui is passed/found + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + // the ui does not exist, so we'll create a new() one + // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm + ui = new(user, src, ui_key, "communicator.tmpl", "Communicator", 475, 700, state = key_state) + // add templates for screens in common with communicator. + ui.add_template("atmosphericScan", "atmospheric_scan.tmpl") + // when the ui is first opened this is the data it will use + ui.set_initial_data(data) + // open the new ui window + ui.open() + // auto update every five Master Controller tick + ui.set_auto_update(5) + +// Proc: Topic() +// Parameters: 2 (standard Topic arguments) +// Description: Responds to NanoUI button presses. +/obj/item/device/communicator/Topic(href, href_list) + if(..()) + return 1 + if(href_list["rename"]) + var/new_name = sanitizeSafe(input(usr,"Please enter your name.","Communicator",usr.name) ) + if(new_name) + register_device(new_name) + + if(href_list["toggle_visibility"]) + switch(network_visibility) + if(1) //Visible, becoming invisbile + network_visibility = 0 + if(camera) + camera.remove_network(NETWORK_COMMUNICATORS) + if(0) //Invisible, becoming visible + network_visibility = 1 + if(camera) + camera.add_network(NETWORK_COMMUNICATORS) + + if(href_list["toggle_ringer"]) + ringer = !ringer + + if(href_list["add_hex"]) + var/hex = href_list["add_hex"] + add_to_EPv2(hex) + + if(href_list["write_target_address"]) + var/new_address = sanitizeSafe(input(usr,"Please enter the desired target EPv2 address. Note that you must write the colons \ + yourself.","Communicator",src.target_address) ) + if(new_address) + target_address = new_address + + if(href_list["clear_target_address"]) + target_address = "" + + if(href_list["dial"]) + if(!get_connection_to_tcomms()) + usr << "Error: Cannot connect to Exonet node." + return + var/their_address = href_list["dial"] + exonet.send_message(their_address, "voice") + + if(href_list["decline"]) + var/ref_to_remove = href_list["decline"] + var/atom/decline = locate(ref_to_remove) + if(decline) + del_request(decline) + + if(href_list["message"]) + if(!get_connection_to_tcomms()) + usr << "Error: Cannot connect to Exonet node." + return + var/their_address = href_list["message"] + var/text = sanitizeSafe(input(usr,"Enter your message.","Text Message")) + if(text) + exonet.send_message(their_address, "text", text) + im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text)) + log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]", usr) + for(var/mob/M in player_list) + if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) + if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat) + continue + if(exonet.get_atom_from_address(their_address) == M) + continue + M.show_message("Comm IM - [src] -> [exonet.get_atom_from_address(their_address)]: [text]") + + if(href_list["disconnect"]) + var/name_to_disconnect = href_list["disconnect"] + for(var/mob/living/voice/V in contents) + if(name_to_disconnect == V.name) + close_connection(usr, V, "[usr] hung up") + for(var/obj/item/device/communicator/comm in communicating) + if(name_to_disconnect == comm.name) + close_connection(usr, comm, "[usr] hung up") + + if(href_list["startvideo"]) + var/ref_to_video = href_list["startvideo"] + var/obj/item/device/communicator/comm = locate(ref_to_video) + if(comm) + connect_video(usr, comm) + + if(href_list["endvideo"]) + if(video_source) + end_video() + + if(href_list["watchvideo"]) + if(video_source) + watch_video(usr,video_source.loc) + + if(href_list["copy"]) + target_address = href_list["copy"] + + if(href_list["copy_name"]) + target_address_name = href_list["copy_name"] + + if(href_list["hang_up"]) + for(var/mob/living/voice/V in contents) + close_connection(usr, V, "[usr] hung up") + for(var/obj/item/device/communicator/comm in communicating) + close_connection(usr, comm, "[usr] hung up") + + if(href_list["switch_tab"]) + selected_tab = href_list["switch_tab"] + + if(href_list["edit"]) + var/n = input(usr, "Please enter message", name, notehtml) + n = sanitizeSafe(n, extra = 0) + if(n) + note = html_decode(n) + notehtml = note + note = replacetext(note, "\n", "
") + else + note = "" + notehtml = note + + if(href_list["Light"]) + fon = !fon + set_light(fon * flum) + + nanomanager.update_uis(src) + add_fingerprint(usr) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index d69c2c9d928..44d3c98c8c4 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -41,6 +41,9 @@ processing_objects -= src return ..() +/obj/item/device/flashlight/get_cell() + return cell + /obj/item/device/flashlight/verb/toggle() set name = "Toggle Flashlight Brightness" set category = "Object" diff --git a/code/game/objects/items/devices/radio/jammer.dm b/code/game/objects/items/devices/radio/jammer.dm index 403b91e1596..cc6554ea7c0 100644 --- a/code/game/objects/items/devices/radio/jammer.dm +++ b/code/game/objects/items/devices/radio/jammer.dm @@ -38,6 +38,9 @@ var/global/list/active_radio_jammers = list() qdel_null(power_source) return ..() +/obj/item/device/radio_jammer/get_cell() + return power_source + /obj/item/device/radio_jammer/proc/turn_off(mob/user) if(user) to_chat(user,"\The [src] deactivates.") diff --git a/code/game/objects/items/poi_items.dm b/code/game/objects/items/poi_items.dm index 85a8b27854e..394212e4c48 100644 --- a/code/game/objects/items/poi_items.dm +++ b/code/game/objects/items/poi_items.dm @@ -52,8 +52,9 @@ /obj/structure/largecrate/animal/crashedshuttle name = "SCP" + /obj/structure/largecrate/animal/crashedshuttle/initialize() - starts_with = pick(/mob/living/simple_animal/hostile/statue, /obj/item/cursed_marble) + starts_with = pick(/mob/living/simple_animal/hostile/statue, /obj/item/cursed_marble, /obj/item/weapon/deadringer) name = pick("Spicy Crust Pizzeria", "Soap and Care Products", "Sally's Computer Parts", "Steve's Chocolate Pastries", "Smith & Christian's Plastics","Standard Containers & Packaging Co.", "Sanitary Chemical Purgation (LTD)") name += " delivery crate" return ..() diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 391405714c5..fe09f304102 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -170,7 +170,7 @@ singular_name = "advanced trauma kit" desc = "An advanced trauma kit for severe injuries." icon_state = "traumakit" - heal_brute = 3 + heal_brute = 7 //VOREStation Edit origin_tech = list(TECH_BIO = 1) apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg','sound/effects/tape.ogg') @@ -198,8 +198,8 @@ continue if (W.bandaged && W.disinfected) continue - if(used == amount) - break + //if(used == amount) //VOREStation Edit + // break //VOREStation Edit if(!do_mob(user, M, W.damage/5)) to_chat(user, "You must stand still to bandage wounds.") break @@ -219,7 +219,7 @@ W.disinfect() W.heal_damage(heal_brute) playsound(src, pick(apply_sounds), 25) - used++ + used = 1 //VOREStation Edit affecting.update_damages() if(used == amount) if(affecting.is_bandaged()) @@ -233,7 +233,7 @@ singular_name = "advanced burn kit" desc = "An advanced treatment kit for severe burns." icon_state = "burnkit" - heal_burn = 3 + heal_burn = 7 //VOREStation Edit origin_tech = list(TECH_BIO = 1) apply_sounds = list('sound/effects/ointment.ogg') diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index bc93d20bb53..17f4121a76a 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -198,3 +198,9 @@ throw_range = 20 flags = 0 no_variants = FALSE + +/obj/item/stack/tile/roofing + name = "roofing" + singular_name = "roofing" + desc = "A section of roofing material. You can use it to repair the ceiling, or expand it." + icon_state = "techtile_grid" \ No newline at end of file diff --git a/code/game/objects/items/weapons/autopsy.dm b/code/game/objects/items/weapons/autopsy.dm index d9606d28d24..7cddfd1efc6 100644 --- a/code/game/objects/items/weapons/autopsy.dm +++ b/code/game/objects/items/weapons/autopsy.dm @@ -167,21 +167,24 @@ if(!istype(M)) return 0 + if (user.a_intent == I_HELP) + return ..() + if(target_name != M.name) target_name = M.name src.wdata = list() src.chemtraces = list() src.timeofdeath = null - user << "A new patient has been registered. Purging data for previous patient." + to_chat(user, "A new patient has been registered. Purging data for previous patient.") src.timeofdeath = M.timeofdeath var/obj/item/organ/external/S = M.get_organ(user.zone_sel.selecting) if(!S) - usr << "You can't scan this body part." + to_chat(user, "You can't scan this body part.") return if(!S.open) - usr << "You have to cut [S] open first!" + to_chat(user, "You have to cut [S] open first!") return M.visible_message("\The [user] scans the wounds on [M]'s [S.name] with [src]") diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 02e4cd48c44..f5bd38dcc17 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -21,12 +21,26 @@ /obj/item/weapon/implant/proc/activate() return - // What does the implant do upon injection? - // return 0 if the implant fails (ex. Revhead and loyalty implant.) - // return 1 if the implant succeeds (ex. Nonrevhead and loyalty implant.) -/obj/item/weapon/implant/proc/implanted(var/mob/source) +// Moves the implant where it needs to go, and tells it if there's more to be done in post_implant +/obj/item/weapon/implant/proc/handle_implant(var/mob/source, var/target_zone = BP_TORSO) + . = TRUE + imp_in = source + implanted = TRUE + if(ishuman(source)) + var/mob/living/carbon/human/H = source + var/obj/item/organ/external/affected = H.get_organ(target_zone) + if(affected) + affected.implants += src + part = affected + if(part) + forceMove(part) + else + forceMove(source) + listening_objects |= src - return 1 + +// Takes place after handle_implant, if that returns TRUE +/obj/item/weapon/implant/proc/post_implant(var/mob/source) /obj/item/weapon/implant/proc/get_data() return "No information available" @@ -49,6 +63,12 @@ icon_state = "implant_melted" malfunction = MALFUNCTION_PERMANENT +/obj/item/weapon/implant/proc/implant_loadout(var/mob/living/carbon/human/H) + if(H) + var/obj/item/organ/external/affected = H.organs_by_name[BP_HEAD] + if(handle_implant(H, affected)) + post_implant(H) + /obj/item/weapon/implant/Destroy() if(part) part.implants.Remove(src) @@ -69,6 +89,11 @@ else ..() + + +////////////////////////////// +// Tracking Implant +////////////////////////////// GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking) /obj/item/weapon/implant/tracking @@ -84,9 +109,8 @@ GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking id = rand(1, 1000) ..() -/obj/item/weapon/implant/tracking/implanted(var/mob/source) +/obj/item/weapon/implant/tracking/post_implant(var/mob/source) processing_objects.Add(src) - return 1 /obj/item/weapon/implant/tracking/Destroy() processing_objects.Remove(src) @@ -142,7 +166,9 @@ Implant Specifics:
"} spawn(delay) malfunction-- - +////////////////////////////// +// Death Explosive Implant +////////////////////////////// /obj/item/weapon/implant/dexplosive name = "explosive" desc = "And boom goes the weasel." @@ -177,7 +203,9 @@ Implant Specifics:
"} /obj/item/weapon/implant/dexplosive/islegal() return 0 -//BS12 Explosive +////////////////////////////// +// Explosive Implant +////////////////////////////// /obj/item/weapon/implant/explosive name = "explosive implant" desc = "A military grade micro bio-explosive. Highly dangerous." @@ -249,15 +277,13 @@ Implant Specifics:
"} if(t) t.hotspot_expose(3500,125) -/obj/item/weapon/implant/explosive/implanted(mob/source as mob) +/obj/item/weapon/implant/explosive/post_implant(mob/source as mob) elevel = alert("What sort of explosion would you prefer?", "Implant Intent", "Localized Limb", "Destroy Body", "Full Explosion") phrase = input("Choose activation phrase:") as text var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "") phrase = replace_characters(phrase, replacechars) usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate.", 0, 0) usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate." - listening_objects |= src - return 1 /obj/item/weapon/implant/explosive/emp_act(severity) if (malfunction) @@ -311,6 +337,9 @@ Implant Specifics:
"} explosion(get_turf(imp_in), -1, -1, 1, 3) qdel(src) +////////////////////////////// +// Chemical Implant +////////////////////////////// GLOBAL_LIST_BOILERPLATE(all_chem_implants, /obj/item/weapon/implant/chem) /obj/item/weapon/implant/chem @@ -336,20 +365,17 @@ Can only be loaded while still in its original case.
the implant may become unstable and either pre-maturely inject the subject or simply break."} return dat - /obj/item/weapon/implant/chem/New() ..() var/datum/reagents/R = new/datum/reagents(50) reagents = R R.my_atom = src - /obj/item/weapon/implant/chem/trigger(emote, source as mob) if(emote == "deathgasp") src.activate(src.reagents.total_volume) return - /obj/item/weapon/implant/chem/activate(var/cause) if((!cause) || (!src.imp_in)) return 0 var/mob/living/carbon/R = src.imp_in @@ -384,6 +410,9 @@ the implant may become unstable and either pre-maturely inject the subject or si spawn(20) malfunction-- +////////////////////////////// +// Loyalty Implant +////////////////////////////// /obj/item/weapon/implant/loyalty name = "loyalty implant" desc = "Makes you loyal or such." @@ -401,20 +430,24 @@ the implant may become unstable and either pre-maturely inject the subject or si Integrity: Implant will last so long as the nanobots are inside the bloodstream."} return dat - -/obj/item/weapon/implant/loyalty/implanted(mob/M) - if(!istype(M, /mob/living/carbon/human)) return 0 +/obj/item/weapon/implant/loyalty/handle_implant(mob/M, target_zone = BP_TORSO) + . = ..(M, target_zone) + if(!istype(M, /mob/living/carbon/human)) + . = FALSE var/mob/living/carbon/human/H = M var/datum/antagonist/antag_data = get_antag_data(H.mind.special_role) if(antag_data && (antag_data.flags & ANTAG_IMPLANT_IMMUNE)) H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of [using_map.company_name] try to invade your mind!") - return 0 - else - clear_antag_roles(H.mind, 1) - H << "You feel a surge of loyalty towards [using_map.company_name]." - return 1 + . = FALSE +/obj/item/weapon/implant/loyalty/post_implant(mob/M) + var/mob/living/carbon/human/H = M + clear_antag_roles(H.mind, 1) + to_chat(H, "You feel a surge of loyalty towards [using_map.company_name].") +////////////////////////////// +// Adrenaline Implant +////////////////////////////// /obj/item/weapon/implant/adrenalin name = "adrenalin" desc = "Removes all stuns and knockdowns." @@ -445,14 +478,13 @@ the implant may become unstable and either pre-maturely inject the subject or si return - -/obj/item/weapon/implant/adrenalin/implanted(mob/source) +/obj/item/weapon/implant/adrenalin/post_implant(mob/source) source.mind.store_memory("A implant can be activated by using the pale emote, say *pale to attempt to activate.", 0, 0) source << "The implanted freedom implant can be activated by using the pale emote, say *pale to attempt to activate." - listening_objects |= src - return 1 - +////////////////////////////// +// Death Alarm Implant +////////////////////////////// /obj/item/weapon/implant/death_alarm name = "death alarm implant" desc = "An alarm which monitors host vital signs and transmits a radio message upon death." @@ -529,11 +561,13 @@ the implant may become unstable and either pre-maturely inject the subject or si spawn(20) malfunction-- -/obj/item/weapon/implant/death_alarm/implanted(mob/source as mob) +/obj/item/weapon/implant/death_alarm/post_implant(mob/source as mob) mobname = source.real_name processing_objects.Add(src) - return 1 +////////////////////////////// +// Compressed Matter Implant +////////////////////////////// /obj/item/weapon/implant/compressed name = "compressed matter implant" desc = "Based on compressed matter technology, can store a single item." @@ -571,13 +605,12 @@ the implant may become unstable and either pre-maturely inject the subject or si scanned.loc = t qdel(src) -/obj/item/weapon/implant/compressed/implanted(mob/source as mob) +/obj/item/weapon/implant/compressed/post_implant(mob/source) src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink") if (source.mind) source.mind.store_memory("Compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0) source << "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate." - listening_objects |= src - return 1 + /obj/item/weapon/implant/compressed/islegal() return 0 diff --git a/code/game/objects/items/weapons/implants/implant_vr.dm b/code/game/objects/items/weapons/implants/implant_vr.dm index 4b796cc56e6..ebcc2d9f546 100644 --- a/code/game/objects/items/weapons/implants/implant_vr.dm +++ b/code/game/objects/items/weapons/implants/implant_vr.dm @@ -3,43 +3,39 @@ desc = "Allows the user to understand and speak almost all known languages.." var/uses = 1 - get_data() - var/dat = {" -Implant Specifications:
-Name: Language Implant
-Life: One day.
-Important Notes: Personnel with this implant can speak almost all known languages.
-
-Implant Details: Subjects injected with implant can understand and speak almost all known languages.
-Function: Contains specialized nanobots to stimulate the brain so the user can speak and understand previously unknown languages.
-Special Features: Will allow the user to understand almost all languages.
-Integrity: Implant can only be used once before the nanobots are depleted."} - return dat +/obj/item/weapon/implant/vrlanguage/get_data() + var/dat = {" + Implant Specifications:
+ Name: Language Implant
+ Life: One day.
+ Important Notes: Personnel with this implant can speak almost all known languages.
+
+ Implant Details: Subjects injected with implant can understand and speak almost all known languages.
+ Function: Contains specialized nanobots to stimulate the brain so the user can speak and understand previously unknown languages.
+ Special Features: Will allow the user to understand almost all languages.
+ Integrity: Implant can only be used once before the nanobots are depleted."} + return dat +/obj/item/weapon/implant/vrlanguage/trigger(emote, mob/source as mob) + if (src.uses < 1) + return 0 + if (emote == "smile") + src.uses-- + to_chat(source,"You suddenly feel as if you can understand other languages!") + source.add_language(LANGUAGE_CHIMPANZEE) + source.add_language(LANGUAGE_NEAERA) + source.add_language(LANGUAGE_STOK) + source.add_language(LANGUAGE_FARWA) + source.add_language(LANGUAGE_UNATHI) + source.add_language(LANGUAGE_SIIK) + source.add_language(LANGUAGE_SKRELLIAN) + source.add_language(LANGUAGE_SCHECHI) + source.add_language(LANGUAGE_BIRDSONG) + source.add_language(LANGUAGE_SAGARU) + source.add_language(LANGUAGE_CANILUNZT) + source.add_language(LANGUAGE_SOL_COMMON) //In case they're giving a xenomorph an implant or something. - trigger(emote, mob/source as mob) - if (src.uses < 1) return 0 - if (emote == "smile") - src.uses-- - source << "You suddenly feel as if you can understand other languages!" - source.add_language(LANGUAGE_CHIMPANZEE) - source.add_language(LANGUAGE_NEAERA) - source.add_language(LANGUAGE_STOK) - source.add_language(LANGUAGE_FARWA) - source.add_language(LANGUAGE_UNATHI) - source.add_language(LANGUAGE_SIIK) - source.add_language(LANGUAGE_SKRELLIAN) - source.add_language(LANGUAGE_SCHECHI) - source.add_language(LANGUAGE_BIRDSONG) - source.add_language(LANGUAGE_SAGARU) - source.add_language(LANGUAGE_CANILUNZT) - source.add_language(LANGUAGE_SOL_COMMON) //In case they're giving a xenomorph an implant or something. - - - return - - - implanted(mob/source) - source.mind.store_memory("A implant can be activated by using the smile emote, say *smile to attempt to activate.", 0, 0) - source << "The implanted language implant can be activated by using the smile emote, say *smile to attempt to activate." - return 1 +/obj/item/weapon/implant/vrlanguage/post_implant(mob/source) + source.mind.store_memory("A implant can be activated by using the smile emote, say *smile to attempt to activate.", 0, 0) + to_chat(source,"The implanted language implant can be activated by using the smile emote, say *smile to attempt to activate.") + return 1 diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm index 44b33721cf0..c05d52442c1 100644 --- a/code/game/objects/items/weapons/implants/implantchair.dm +++ b/code/game/objects/items/weapons/implants/implantchair.dm @@ -135,10 +135,9 @@ for (var/mob/O in viewers(M, null)) O.show_message("\The [M] has been implanted by \the [src].", 1) - if(imp.implanted(M)) - imp.loc = M - imp.imp_in = M - imp.implanted = 1 + if(imp.handle_implant(M, BP_TORSO)) + imp.post_implant(M) + implant_list -= imp break return diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index d99c5f5ff24..c1b0d5db8dd 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -56,16 +56,11 @@ add_attack_logs(user,M,"Implanted with [imp.name] using [name]") - if(src.imp.implanted(M)) - src.imp.loc = M - src.imp.imp_in = M - src.imp.implanted = 1 - if (ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - affected.implants += src.imp - imp.part = affected + if(imp.handle_implant(M)) + imp.post_implant(M) + if(ishuman(M)) + var/mob/living/carbon/human/H = M BITSET(H.hud_updateflag, IMPLOYAL_HUD) BITSET(H.hud_updateflag, BACKUP_HUD) //VOREStation Add - Backup HUD updates diff --git a/code/game/objects/items/weapons/implants/implantfreedom.dm b/code/game/objects/items/weapons/implants/implantfreedom.dm index 92021a46a2f..fab692775d3 100644 --- a/code/game/objects/items/weapons/implants/implantfreedom.dm +++ b/code/game/objects/items/weapons/implants/implantfreedom.dm @@ -16,7 +16,9 @@ /obj/item/weapon/implant/freedom/trigger(emote, mob/living/carbon/source as mob) - if (src.uses < 1) return 0 + if (src.uses < 1) + return 0 + if (emote == src.activation_emote) src.uses-- source << "You feel a faint click." @@ -46,13 +48,9 @@ W.layer = initial(W.layer) return - -/obj/item/weapon/implant/freedom/implanted(mob/living/carbon/source) +/obj/item/weapon/implant/freedom/post_implant(mob/source) source.mind.store_memory("Freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0) source << "The implanted freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate." - listening_objects |= src - return 1 - /obj/item/weapon/implant/freedom/get_data() var/dat = {" diff --git a/code/game/objects/items/weapons/implants/implantlanguage.dm b/code/game/objects/items/weapons/implants/implantlanguage.dm index d813a8d3888..7c6e33508b0 100644 --- a/code/game/objects/items/weapons/implants/implantlanguage.dm +++ b/code/game/objects/items/weapons/implants/implantlanguage.dm @@ -4,7 +4,26 @@ /obj/item/weapon/implant/language name = "GalCom language implant" - desc = "An implant allowing someone to speak and hear the range of frequencies used in Galactic Common, as well as produce any phonemes that they usually cannot. Only helps with hearing and producing sounds, not understanding them." + desc = "An implant allowing someone to speak the range of frequencies used in Galactic Common, as well as produce any phonemes that they usually cannot. Only helps with producing sounds, not understanding them." + var/list/languages = list(LANGUAGE_GALCOM) // List of languages that this assists with + +/obj/item/weapon/implant/language/post_implant(mob/M) // Amends the mob's voice organ, then deletes itself + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/obj/item/organ/internal/voicebox/V = locate() in H.internal_organs + if(V) + var/list/need_amend = list() // If they've already got all the languages they need, then they don't need this implant to do anything + for(var/L in languages) + if(L in V.will_assist_languages) + continue + else + need_amend |= L + if(LAZYLEN(need_amend)) + if(V.robotic < ORGAN_ASSISTED) + V.mechassist() + for(var/L in need_amend) + V.add_assistable_langs(L) + qdel_null(src) /obj/item/weapon/implant/language/get_data() var/dat = {" @@ -14,16 +33,19 @@ Important Notes: Affects hearing and speech.

Implant Details:
-Function: Allows a being otherwise incapable to both hear the frequencies Galactic Common is generally spoken at, as well as to produce the phonemes of the language.
+Function: Allows a being otherwise incapable of speaking Galactic Common to produce the phonemes of the language.
Special Features: None.
Integrity: Implant will function for expected life, barring physical damage."} return dat + +// EAL Implant /obj/item/weapon/implant/language/eal name = "EAL language implant" - desc = "An implant allowing an organic to both hear and speak Encoded Audio Language accurately. Only helps with hearing and producing sounds, not understanding them." + desc = "An implant allowing an organic to speak Encoded Audio Language passably. Only helps with producing sounds, not understanding them." + languages = list(LANGUAGE_EAL) -/obj/item/weapon/implant/language/get_data() +/obj/item/weapon/implant/language/eal/get_data() var/dat = {" Implant Specifications:
Name: Vey-Med L-2 Encoded Audio Language Implant
@@ -31,7 +53,25 @@ Important Notes: Affects hearing and speech.

Implant Details:
-Function: Allows an organic to accurately process and speak Encoded Audio Language.
+Function: Allows an organic to accurately speak Encoded Audio Language.
+Special Features: None.
+Integrity: Implant will function for expected life, barring physical damage."} + return dat + +/obj/item/weapon/implant/language/skrellian + name = "Skrellian language implant" + desc = "An implant allowing someone to speak the range of frequencies used in Skrellian, as well as produce any phonemes that they usually cannot. Only helps with hearing and producing sounds, not understanding them." + languages = list(LANGUAGE_SKRELLIAN) + +/obj/item/weapon/implant/language/skrellian/get_data() + var/dat = {" +Implant Specifications:
+Name: Vey-Med L-1 Galactic Common Implant
+Life: 5 years
+Important Notes: Affects hearing and speech.
+
+Implant Details:
+Function: Allows a being otherwise incapable of speaking Skrellian to produce the phonemes of the language.
Special Features: None.
Integrity: Implant will function for expected life, barring physical damage."} return dat \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implantreagent_vr.dm b/code/game/objects/items/weapons/implants/implantreagent_vr.dm index 1c4e9a9b040..83a586d2ba1 100644 --- a/code/game/objects/items/weapons/implants/implantreagent_vr.dm +++ b/code/game/objects/items/weapons/implants/implantreagent_vr.dm @@ -30,7 +30,7 @@ update() return -/obj/item/weapon/implant/reagent_generator/implanted(mob/living/carbon/source) +/obj/item/weapon/implant/reagent_generator/post_implant(mob/living/carbon/source) processing_objects += src to_chat(source, "You implant [source] with \the [src].") assigned_proc = new assigned_proc(source, verb_name, verb_desc) diff --git a/code/game/objects/items/weapons/implants/implantuplink.dm b/code/game/objects/items/weapons/implants/implantuplink.dm index 644ebf1bb7a..82809cfe61a 100644 --- a/code/game/objects/items/weapons/implants/implantuplink.dm +++ b/code/game/objects/items/weapons/implants/implantuplink.dm @@ -11,15 +11,13 @@ ..() return -/obj/item/weapon/implant/uplink/implanted(mob/source) +/obj/item/weapon/implant/uplink/post_implant(mob/source) + listening_objects |= src activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink") source.mind.store_memory("Uplink implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0) source << "The implanted uplink implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate." - listening_objects |= src - return 1 - /obj/item/weapon/implant/uplink/trigger(emote, mob/source as mob) if(hidden_uplink && usr == source) // Let's not have another people activate our uplink hidden_uplink.check_trigger(source, emote, activation_emote) - return + return \ No newline at end of file diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm index 54f344eae10..0cfdd4792dd 100644 --- a/code/game/objects/items/weapons/mop.dm +++ b/code/game/objects/items/weapons/mop.dm @@ -16,6 +16,7 @@ GLOBAL_LIST_BOILERPLATE(all_mops, /obj/item/weapon/mop) /obj/item/weapon/mop/New() create_reagents(30) + ..() /obj/item/weapon/mop/afterattack(atom/A, mob/user, proximity) if(!proximity) return diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm index 43183d45f44..aec6a790b21 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -4,6 +4,9 @@ icon = 'icons/policetape.dmi' icon_state = "tape" w_class = ITEMSIZE_SMALL + + toolspeed = 3 //You can use it in surgery. It's stupid, but you can. + var/turf/start var/turf/end var/tape_type = /obj/item/tape diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 97e03664137..72ce933da3a 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -67,6 +67,7 @@ /obj/item/weapon/extinguisher/mini, /obj/item/weapon/tape_roll, /obj/item/device/integrated_electronics/wirer, + /obj/item/device/integrated_electronics/debugger, //Vorestation edit adding debugger to toolbelt can hold list ) /obj/item/weapon/storage/belt/utility/full @@ -86,7 +87,6 @@ /obj/item/weapon/weldingtool, /obj/item/weapon/crowbar, /obj/item/weapon/wirecutters, - /obj/item/device/t_scanner ) /obj/item/weapon/storage/belt/utility/chief diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index f28cffdb6c3..38c6e10d79b 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -10,24 +10,25 @@ /obj/item/weapon/storage/firstaid name = "first aid kit" desc = "It's an emergency medical kit for those serious boo-boos." + icon = 'icons/obj/storage_vr.dmi' icon_state = "firstaid" throw_speed = 2 throw_range = 8 max_storage_space = ITEMSIZE_COST_SMALL * 7 // 14 - var/list/icon_variety +// var/list/icon_variety // VOREStation edit /obj/item/weapon/storage/firstaid/initialize() . = ..() - if(icon_variety) - icon_state = pick(icon_variety) - icon_variety = null +// if(icon_variety) // VOREStation edit +// icon_state = pick(icon_variety) +// icon_variety = null /obj/item/weapon/storage/firstaid/fire name = "fire first aid kit" desc = "It's an emergency medical kit for when the toxins lab spontaneously burns down." icon_state = "ointment" item_state_slots = list(slot_r_hand_str = "firstaid-ointment", slot_l_hand_str = "firstaid-ointment") - icon_variety = list("ointment","firefirstaid") +// icon_variety = list("ointment","firefirstaid") // VOREStation edit starts_with = list( /obj/item/device/healthanalyzer, /obj/item/weapon/reagent_containers/hypospray/autoinjector, @@ -55,7 +56,7 @@ desc = "Used to treat when one has a high amount of toxins in their body." icon_state = "antitoxin" item_state_slots = list(slot_r_hand_str = "firstaid-toxin", slot_l_hand_str = "firstaid-toxin") - icon_variety = list("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3") +// icon_variety = list("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3") // VOREStation edit starts_with = list( /obj/item/weapon/reagent_containers/syringe/antitoxin, /obj/item/weapon/reagent_containers/syringe/antitoxin, @@ -70,7 +71,7 @@ name = "oxygen deprivation first aid kit" desc = "A box full of oxygen goodies." icon_state = "o2" - item_state_slots = list(slot_r_hand_str = "firstaid-o2", slot_l_hand_str = "firstaid-o2") + item_state_slots = list(slot_r_hand_str = "firstaid-o2", slot_l_hand_str = "firstaid-o2") starts_with = list( /obj/item/weapon/reagent_containers/pill/dexalin, /obj/item/weapon/reagent_containers/pill/dexalin, @@ -116,6 +117,7 @@ /obj/item/weapon/storage/firstaid/surgery name = "surgery kit" desc = "Contains tools for surgery. Has precise foam fitting for safe transport and automatically sterilizes the content between uses." + icon = 'icons/obj/storage.dmi' // VOREStation edit icon_state = "surgerykit" item_state = "firstaid-surgery" max_w_class = ITEMSIZE_NORMAL @@ -152,6 +154,7 @@ /obj/item/weapon/storage/firstaid/clotting name = "clotting kit" desc = "Contains chemicals to stop bleeding." + icon_state = "clottingkit" // VOREStation edit max_storage_space = ITEMSIZE_COST_SMALL * 7 starts_with = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting = 8) diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 268a8d5ad77..e37b2f99770 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -19,16 +19,19 @@ var/obj/item/weapon/cell/bcell = null var/hitcost = 240 -/obj/item/weapon/melee/baton/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] - user.visible_message("\The [user] is putting the live [name] in [TU.his] mouth! It looks like [TU.he] [TU.is] trying to commit suicide.") - return (FIRELOSS) - /obj/item/weapon/melee/baton/New() ..() update_icon() return +/obj/item/weapon/melee/baton/get_cell() + return bcell + +/obj/item/weapon/melee/baton/suicide_act(mob/user) + var/datum/gender/TU = gender_datums[user.get_visible_gender()] + user.visible_message("\The [user] is putting the live [name] in [TU.his] mouth! It looks like [TU.he] [TU.is] trying to commit suicide.") + return (FIRELOSS) + /obj/item/weapon/melee/baton/MouseDrop(obj/over_object as obj) if(!canremove) return diff --git a/code/game/objects/items/weapons/tanks/tank_types_vr.dm b/code/game/objects/items/weapons/tanks/tank_types_vr.dm index cc191bb0f9a..73d094d0f97 100644 --- a/code/game/objects/items/weapons/tanks/tank_types_vr.dm +++ b/code/game/objects/items/weapons/tanks/tank_types_vr.dm @@ -1,4 +1,4 @@ -/obj/item/weapon/tank/emergency/phoron_double +/obj/item/weapon/tank/emergency/phoron/double name = "double emergency phoron tank" desc = "Contains dangerous phoron. Do not inhale. Warning: extremely flammable." icon = 'icons/obj/tank_vr.dmi' @@ -8,7 +8,7 @@ gauge_cap = 3 volume = 10 -/obj/item/weapon/tank/emergency/phoron_double/New() +/obj/item/weapon/tank/emergency/phoron/double/New() ..() air_contents.adjust_gas("phoron", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) @@ -41,6 +41,8 @@ icon = 'icons/obj/tank_vr.dmi' icon_override = 'icons/mob/back_vr.dmi' icon_state = "phoron_vox" + gauge_cap = 3 + gauge_icon = "indicator_double" /obj/item/weapon/tank/emergency icon = 'icons/obj/tank_vr.dmi' diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index 5a575155888..e3afddba4c5 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -5,8 +5,12 @@ icon_state = "taperoll" w_class = ITEMSIZE_TINY + toolspeed = 2 //It is now used in surgery as a not awful, but probably dangerous option, due to speed. + /obj/item/weapon/tape_roll/attack(var/mob/living/carbon/human/H, var/mob/user) if(istype(H)) + if(user.a_intent == I_HELP) + return var/can_place = 0 if(istype(user, /mob/living/silicon/robot)) can_place = 1 diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 9a8937adbce..53acc20f16a 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -776,6 +776,9 @@ acti_sound = 'sound/effects/sparks4.ogg' deac_sound = 'sound/effects/sparks4.ogg' +/obj/item/weapon/weldingtool/electric/unloaded/New() + cell_type = null + /obj/item/weapon/weldingtool/electric/New() ..() if(cell_type == null) @@ -786,8 +789,8 @@ power_supply = new /obj/item/weapon/cell/device(src) update_icon() -/obj/item/weapon/weldingtool/electric/unloaded/New() - cell_type = null +/obj/item/weapon/weldingtool/electric/get_cell() + return power_supply /obj/item/weapon/weldingtool/electric/examine(mob/user) if(get_dist(src, user) > 1) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 3835b2a24bb..0facb97eac7 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -163,3 +163,6 @@ /obj/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) return + +/obj/proc/get_cell() + return \ No newline at end of file diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index 6d5a1cbe323..60cb0753b18 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -2,7 +2,7 @@ /obj/structure/catwalk name = "catwalk" desc = "Cats really don't like these things." - plane = TURF_PLANE + plane = DECAL_PLANE layer = ABOVE_UTILITY icon = 'icons/turf/catwalks.dmi' icon_state = "catwalk" diff --git a/code/game/objects/structures/crates_lockers/largecrate_vr.dm b/code/game/objects/structures/crates_lockers/largecrate_vr.dm index a9f173d7085..d6622e25911 100644 --- a/code/game/objects/structures/crates_lockers/largecrate_vr.dm +++ b/code/game/objects/structures/crates_lockers/largecrate_vr.dm @@ -71,6 +71,7 @@ /mob/living/simple_animal/hostile/alien/sentinel, /mob/living/simple_animal/hostile/alien/queen, /mob/living/simple_animal/otie/feral, + /mob/living/simple_animal/otie/red, /mob/living/simple_animal/hostile/corrupthound)) return ..() @@ -101,6 +102,11 @@ desc = "VARMAcorp experimental hostile environment adaptive breeding development kit. WARNING, DO NOT RELEASE IN WILD!" starts_with = list(/mob/living/simple_animal/otie/cotie/phoron) +/obj/structure/largecrate/animal/otie/phoron/initialize() + starts_with = list(pick(/mob/living/simple_animal/otie/cotie/phoron;2, + /mob/living/simple_animal/otie/red/friendly;0.5)) + return ..() + /obj/structure/largecrate/animal/otie/attack_hand(mob/living/carbon/human/M as mob)//I just couldn't decide between the icons lmao if(taped == 1) playsound(src, 'sound/items/poster_ripped.ogg', 50, 1) diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 69237285647..4c1bc63618a 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -20,6 +20,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) /obj/structure/janitorialcart/New() create_reagents(300) + ..() /obj/structure/janitorialcart/examine(mob/user) diff --git a/code/game/objects/structures/alien_props.dm b/code/game/objects/structures/props/alien_props.dm similarity index 90% rename from code/game/objects/structures/alien_props.dm rename to code/game/objects/structures/props/alien_props.dm index eb8ae9d19f3..fa11e27b15d 100644 --- a/code/game/objects/structures/alien_props.dm +++ b/code/game/objects/structures/props/alien_props.dm @@ -6,15 +6,6 @@ icon = 'icons/obj/abductor.dmi' density = TRUE anchored = TRUE - var/interaction_message = null - -/obj/structure/prop/alien/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything. - if(!istype(user)) - return FALSE - if(!interaction_message) - return ..() - else - to_chat(user, interaction_message) /obj/structure/prop/alien/computer name = "alien console" diff --git a/code/game/objects/structures/props/beam_prism.dm b/code/game/objects/structures/props/beam_prism.dm new file mode 100644 index 00000000000..44df2eb68b0 --- /dev/null +++ b/code/game/objects/structures/props/beam_prism.dm @@ -0,0 +1,215 @@ +//A series(?) of prisms for PoIs. The base one only works for beams. + +/obj/structure/prop/prism + name = "prismatic turret" + desc = "A raised, externally powered 'turret'. It seems to have a massive crystal ring around its base." + description_info = "This device is capable of redirecting any beam projectile." + icon = 'icons/obj/props/prism.dmi' + icon_state = "prism" + density = TRUE + anchored = TRUE + + layer = 3.1 //Layer over projectiles. + plane = -10 //Layer over projectiles. + + var/rotation_lock = 0 // Can you rotate the prism at all? + var/free_rotate = 1 // Does the prism rotate in any direction, or only in the eight standard compass directions? + var/external_control_lock = 0 // Does the prism only rotate from the controls of an external switch? + var/degrees_from_north = 0 // How far is it rotated clockwise? + var/compass_directions = list("North" = 0, "South" = 180, "East" = 90, "West" = 270, "Northwest" = 315, "Northeast" = 45, "Southeast" = 135, "Southwest" = 225) + var/interaction_sound = 'sound/mecha/mechmove04.ogg' + + var/redirect_type = /obj/item/projectile/beam + + var/dialID = null + var/obj/structure/prop/prismcontrol/remote_dial = null + + interaction_message = "The prismatic turret seems to be able to rotate." + +/obj/structure/prop/prism/initialize() + if(degrees_from_north) + animate(src, transform = turn(NORTH, degrees_from_north), time = 3) + +/obj/structure/prop/prism/Destroy() + if(remote_dial) + remote_dial.my_turrets -= src + remote_dial = null + ..() + +/obj/structure/prop/prism/proc/reset_rotation() + var/degrees_to_rotate = -1 * degrees_from_north + animate(src, transform = turn(src.transform, degrees_to_rotate), time = 2) + +/obj/structure/prop/prism/attack_hand(mob/living/user) + ..() + + if(rotation_lock) + to_chat(user, "\The [src] is locked at its current bearing.") + return + if(external_control_lock) + to_chat(user, "\The [src]'s motors resist your efforts to rotate it. You may need to find some form of controller.") + return + + var/confirm = input("Do you want to try to rotate \the [src]?", "[name]") in list("Yes", "No") + if(confirm == "No") + visible_message(\ + "[user.name] decides not to try turning \the [src].",\ + "You decide not to try turning \the [src].") + return + + var/new_bearing + if(free_rotate) + new_bearing = input("What bearing do you want to rotate \the [src] to?", "[name]") as num + new_bearing = round(new_bearing) + if(new_bearing <= -1 || new_bearing > 360) + to_chat(user, "Rotating \the [src] [new_bearing] degrees would be a waste of time.") + return + else + var/choice = input("What point do you want to set \the [src] to?", "[name]") as null|anything in compass_directions + new_bearing = round(compass_directions[choice]) + + var/rotate_degrees = new_bearing - degrees_from_north + + if(new_bearing == 360) // Weird artifact. + new_bearing = 0 + degrees_from_north = new_bearing + + var/two_stage = 0 + if(rotate_degrees == 180 || rotate_degrees == -180) + two_stage = 1 + var/multiplier = pick(-1, 1) + rotate_degrees = multiplier * (rotate_degrees / 2) + + playsound(src, interaction_sound, 50, 1) + if(two_stage) + animate(src, transform = turn(src.transform, rotate_degrees), time = 3) + spawn(3) + animate(src, transform = turn(src.transform, rotate_degrees), time = 3) + else + animate(src, transform = turn(src.transform, rotate_degrees), time = 6) //Can't update transform because it will reset the angle. + +/obj/structure/prop/prism/proc/rotate_auto(var/new_bearing) + if(rotation_lock) + visible_message("\The [src] shudders.") + playsound(src, 'sound/effects/clang.ogg', 50, 1) + return + + visible_message("\The [src] rotates to a bearing of [new_bearing].") + + var/rotate_degrees = new_bearing - degrees_from_north + + if(new_bearing == 360) + new_bearing = 0 + degrees_from_north = new_bearing + + var/two_stage = 0 + if(rotate_degrees == 180 || rotate_degrees == -180) + two_stage = 1 + var/multiplier = pick(-1, 1) + rotate_degrees = multiplier * (rotate_degrees / 2) + + playsound(src, interaction_sound, 50, 1) + if(two_stage) + animate(src, transform = turn(src.transform, rotate_degrees), time = 3) + spawn(3) + animate(src, transform = turn(src.transform, rotate_degrees), time = 3) + else + animate(src, transform = turn(src.transform, rotate_degrees), time = 6) + +/obj/structure/prop/prism/bullet_act(var/obj/item/projectile/Proj) + if(istype(Proj, redirect_type)) + visible_message("\The [src] redirects \the [Proj]!") + flick("[initial(icon_state)]+glow", src) + + var/new_x = (1 * round(10 * cos(degrees_from_north - 90))) + x //Vectors vectors vectors. + var/new_y = (-1 * round(10 * sin(degrees_from_north - 90))) + y + var/turf/curloc = get_turf(src) + + Proj.penetrating += 1 // Needed for the beam to get out of the turret. + + Proj.redirect(new_x, new_y, curloc, null) + +/obj/structure/prop/prism/incremental + free_rotate = 0 + description_info = "This device is capable of redirecting any beam projectile, but only locks to specific positions in rotation." + +/obj/structure/prop/prism/incremental/externalcont + external_control_lock = 1 + description_info = "This device is capable of redirecting any beam projectile, but can only be rotated by a control dial to specific positions." + +/obj/structure/prop/prism/externalcont + external_control_lock = 1 + description_info = "This device is capable of redirecting any beam projectile, but can only be rotated by an external control dial." + +/obj/structure/prop/prismcontrol + name = "prismatic dial" + desc = "A large dial with a crystalline ring." + icon = 'icons/obj/props/prism.dmi' + icon_state = "dial" + density = FALSE + anchored = TRUE + + interaction_message = "The dial pulses as your hand nears it." + var/list/my_turrets = list() + var/dialID = null + +/obj/structure/prop/prismcontrol/attack_hand(mob/living/user) + ..() + + var/confirm = input("Do you want to try to rotate \the [src]?", "[name]") in list("Yes", "No") + if(confirm == "No") + visible_message(\ + "[user.name] decides not to try turning \the [src].",\ + "You decide not to try turning \the [src].") + return + + if(!my_turrets || !my_turrets.len) + to_chat(user, "\The [src] doesn't seem to do anything.") + return + + var/free_rotate = 1 + var/list/compass_directions = list() + for(var/obj/structure/prop/prism/P in my_turrets) + if(!P.free_rotate) //Doesn't use bearing, it uses compass points. + free_rotate = 0 + compass_directions |= P.compass_directions + + var/new_bearing + if(free_rotate) + new_bearing = input("What bearing do you want to rotate \the [src] to?", "[name]") as num + new_bearing = round(new_bearing) + if(new_bearing <= -1 || new_bearing > 360) + to_chat(user, "Rotating \the [src] [new_bearing] degrees would be a waste of time.") + return + else + var/choice = input("What point do you want to set \the [src] to?", "[name]") as null|anything in compass_directions + new_bearing = round(compass_directions[choice]) + + confirm = input("Are you certain you want to rotate \the [src]?", "[name]") in list("Yes", "No") + if(confirm == "No") + visible_message(\ + "[user.name] decides not to try turning \the [src].",\ + "You decide not to try turning \the [src].") + return + + to_chat(user, "\The [src] clicks into place.") + for(var/obj/structure/prop/prism/P in my_turrets) + P.rotate_auto(new_bearing) + +/obj/structure/prop/prismcontrol/initialize() + ..() + if(my_turrets.len) //Preset controls. + for(var/obj/structure/prop/prism/P in my_turrets) + P.remote_dial = src + return + spawn() + for(var/obj/structure/prop/prism/P in orange(src, world.view)) //Don't search a huge area. + if(P.dialID == dialID && !P.remote_dial && P.external_control_lock) + my_turrets |= P + P.remote_dial = src + +/obj/structure/prop/prismcontrol/Destroy() + for(var/obj/structure/prop/prism/P in my_turrets) + P.remote_dial = null + my_turrets = list() + ..() diff --git a/code/game/objects/structures/props/projectile_lock.dm b/code/game/objects/structures/props/projectile_lock.dm new file mode 100644 index 00000000000..5c3fcd2ba07 --- /dev/null +++ b/code/game/objects/structures/props/projectile_lock.dm @@ -0,0 +1,53 @@ +//A locking mechanism that pulses when hit by a projectile. The base one responds to high-power lasers. + +/obj/structure/prop/lock + name = "weird lock" + desc = "An esoteric object that responds to.. something." + icon = 'icons/obj/props/prism.dmi' + icon_state = "lock" + + var/enabled = 0 + var/lockID = null + + var/list/linked_objects = list() + +/obj/structure/prop/lock/Destroy() + if(linked_objects.len) + for(var/obj/O in linked_objects) + if(istype(O, /obj/machinery/door/blast/puzzle)) + var/obj/machinery/door/blast/puzzle/P = O + P.locks -= src + linked_objects -= P + ..() + +/obj/structure/prop/lock/proc/toggle_lock() + enabled = !enabled + + if(enabled) + icon_state = "[initial(icon_state)]-active" + else + icon_state = "[initial(icon_state)]" + +/obj/structure/prop/lock/projectile + name = "beam lock" + desc = "An esoteric object that responds to high intensity light." + + var/projectile_key = /obj/item/projectile/beam + var/timed = 0 + var/timing = 0 + var/time_limit = 1500 // In ticks. Ten is one second. + + interaction_message = "The object remains inert to your touch." + +/obj/structure/prop/lock/projectile/bullet_act(var/obj/item/projectile/Proj) + if(!istype(Proj, projectile_key) || timing) + return + + if(istype(Proj, /obj/item/projectile/beam/heavylaser/cannon) || istype(Proj, /obj/item/projectile/beam/emitter) || (Proj.damage >= 80 && Proj.damtype == BURN)) + toggle_lock() + visible_message("\The [src] [enabled ? "disengages" : "engages"] its locking mechanism.") + + if(timed) + timing = 1 + spawn(time_limit) + toggle_lock() diff --git a/code/game/objects/structures/props/prop.dm b/code/game/objects/structures/props/prop.dm new file mode 100644 index 00000000000..fea5815674d --- /dev/null +++ b/code/game/objects/structures/props/prop.dm @@ -0,0 +1,18 @@ +//The base 'prop' for PoIs or other large junk. + +/obj/structure/prop + name = "something" + desc = "My description is broken, bug a developer." + icon = 'icons/obj/structures.dmi' + icon_state = "safe" + density = TRUE + anchored = TRUE + var/interaction_message = null + +/obj/structure/prop/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything. + if(!istype(user)) + return FALSE + if(!interaction_message) + return ..() + else + to_chat(user, interaction_message) diff --git a/code/game/objects/structures/props/puzzledoor.dm b/code/game/objects/structures/props/puzzledoor.dm new file mode 100644 index 00000000000..b9a32fc0dcc --- /dev/null +++ b/code/game/objects/structures/props/puzzledoor.dm @@ -0,0 +1,92 @@ +// An indestructible blast door that can only be opened once its puzzle requirements are completed. + +/obj/machinery/door/blast/puzzle + name = "puzzle door" + desc = "A large, virtually indestructible door that will not open unless certain requirements are met." + icon_state_open = "pdoor0" + icon_state_opening = "pdoorc0" + icon_state_closed = "pdoor1" + icon_state_closing = "pdoorc1" + icon_state = "pdoor1" + + explosion_resistance = 100 + + maxhealth = 9999999 //No. + + var/list/locks = list() + var/lockID = null + var/checkrange_mult = 1 + +/obj/machinery/door/blast/puzzle/proc/check_locks() + for(var/obj/structure/prop/lock/L in locks) + if(!L.enabled) + return 0 + return 1 + +/obj/machinery/door/blast/puzzle/bullet_act(var/obj/item/projectile/Proj) + visible_message("\The [src] is completely unaffected by \the [Proj].") + qdel(Proj) //No piercing. No. + +/obj/machinery/door/blast/puzzle/ex_act(severity) + visible_message("\The [src] is completely unaffected by the blast.") + return + +/obj/machinery/door/blast/puzzle/initialize() + . = ..() + implicit_material = get_material_by_name("dungeonium") + if(locks.len) + return + var/check_range = world.view * checkrange_mult + for(var/obj/structure/prop/lock/L in orange(src, check_range)) + if(L.lockID == lockID) + L.linked_objects |= src + locks |= L + +/obj/machinery/door/blast/puzzle/Destroy() + if(locks.len) + for(var/obj/structure/prop/lock/L in locks) + L.linked_objects -= src + locks -= L + ..() + +/obj/machinery/door/blast/puzzle/attack_hand(mob/user as mob) + if(check_locks()) + force_toggle(1, user) + else + to_chat(user, "\The [src] does not respond to your touch.") + +/obj/machinery/door/blast/puzzle/attackby(obj/item/weapon/C as obj, mob/user as mob) + if(istype(C, /obj/item/weapon)) + if(C.pry == 1 && (user.a_intent != I_HURT || (stat & BROKEN))) + if(istype(C,/obj/item/weapon/material/twohanded/fireaxe)) + var/obj/item/weapon/material/twohanded/fireaxe/F = C + if(!F.wielded) + to_chat(user, "You need to be wielding \the [F] to do that.") + return + + if(check_locks()) + force_toggle(1, user) + + else + to_chat(user, "[src]'s arcane workings resist your effort.") + return + + else if(src.density && (user.a_intent == I_HURT)) + var/obj/item/weapon/W = C + user.setClickCooldown(user.get_attack_speed(W)) + if(W.damtype == BRUTE || W.damtype == BURN) + user.do_attack_animation(src) + user.visible_message("\The [user] hits \the [src] with \the [W] with no visible effect.") + + else if(istype(C, /obj/item/weapon/plastique)) + to_chat(user, "On contacting \the [src], a flash of light envelops \the [C] as it is turned to ash. Oh.") + qdel(C) + return 0 + +/obj/machinery/door/blast/puzzle/attack_generic(var/mob/user, var/damage) + if(check_locks()) + force_toggle(1, user) + +/obj/machinery/door/blast/puzzle/attack_alien(var/mob/user) + if(check_locks()) + force_toggle(1, user) diff --git a/code/game/turfs/flooring/flooring_decals_vr.dm b/code/game/turfs/flooring/flooring_decals_vr.dm index d0f1e2e70ca..5326eeff865 100644 --- a/code/game/turfs/flooring/flooring_decals_vr.dm +++ b/code/game/turfs/flooring/flooring_decals_vr.dm @@ -10,4 +10,91 @@ /obj/effect/floor_decal/industrial/outline/red name = "red outline" - color = COLOR_RED \ No newline at end of file + color = COLOR_RED +/obj/effect/floor_decal/borderfloor/shifted + icon_state = "borderfloor_shifted" + +/obj/effect/floor_decal/borderfloorblack/shifted + icon_state = "borderfloor_shifted" + +/obj/effect/floor_decal/borderfloorwhite/shifted + icon_state = "borderfloor_shifted" + +/obj/effect/floor_decal/corner/beige/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/black/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/blue/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/brown/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/green/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/grey/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/lightgrey/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/lightorange + name = "orange corner" + color = "#ed983d" + +/obj/effect/floor_decal/corner/lightorange/diagonal + icon_state = "corner_white_diagonal" + +/obj/effect/floor_decal/corner/lightorange/full + icon_state = "corner_white_full" + +/obj/effect/floor_decal/corner/lightorange/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/lightorange/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/lightorange/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/lightorange/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/lightorange/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/lightorange/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/lightorange/bordercee + icon_state = "bordercolorcee" + +/obj/effect/floor_decal/corner/lime/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/mauve/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/orange/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/paleblue/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/pink/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/purple/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/red/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/white/border/shifted + icon_state = "bordercolor_shifted" + +/obj/effect/floor_decal/corner/yellow/border/shifted + icon_state = "bordercolor_shifted" diff --git a/code/game/turfs/simulated/dungeon/wall.dm b/code/game/turfs/simulated/dungeon/wall.dm index 176c10142c4..c1a02cde666 100644 --- a/code/game/turfs/simulated/dungeon/wall.dm +++ b/code/game/turfs/simulated/dungeon/wall.dm @@ -12,6 +12,9 @@ /turf/simulated/wall/dungeon/ex_act() return +/turf/simulated/wall/dungeon/take_damage() //These things are suppose to be unbreakable + return + /turf/simulated/wall/solidrock //for more stylish anti-cheese. name = "solid rock" desc = "This rock seems dense, impossible to drill." @@ -37,4 +40,7 @@ return /turf/simulated/wall/solidrock/ex_act() + return + +/turf/simulated/wall/solidrock/take_damage() //These things are suppose to be unbreakable return \ No newline at end of file diff --git a/code/game/turfs/simulated/floor_attackby.dm b/code/game/turfs/simulated/floor_attackby.dm index 91371e7beb5..940e2df548d 100644 --- a/code/game/turfs/simulated/floor_attackby.dm +++ b/code/game/turfs/simulated/floor_attackby.dm @@ -9,6 +9,51 @@ attack_tile(C, L) // Be on help intent if you want to decon something. return + if(istype(C, /obj/item/stack/tile/roofing)) + var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather + var/turf/T = GetAbove(src) + var/obj/item/stack/tile/roofing/R = C + + // Patch holes in the ceiling + if(T) + if(istype(T, /turf/simulated/open) || istype(T, /turf/space)) + // Must be build adjacent to an existing floor/wall, no floating floors + var/list/cardinalTurfs = list() // Up a Z level + for(var/dir in cardinal) + var/turf/B = get_step(T, dir) + if(B) + cardinalTurfs += B + + var/turf/simulated/A = locate(/turf/simulated/floor) in cardinalTurfs + if(!A) + A = locate(/turf/simulated/wall) in cardinalTurfs + if(!A) + to_chat(user, "There's nothing to attach the ceiling to!") + return + + if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating + T.ReplaceWithLattice() + T.ChangeTurf(/turf/simulated/floor) + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] patches a hole in the ceiling.", "You patch a hole in the ceiling.") + expended_tile = TRUE + else + to_chat(user, "There aren't any holes in the ceiling to patch here.") + return + + // Create a ceiling to shield from the weather + if(src.outdoors) + for(var/dir in cardinal) + var/turf/A = get_step(src, dir) + if(A && !A.outdoors) + if(expended_tile || R.use(1)) + src.outdoors = FALSE + SSplanets.unallocateTurf(src) + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] roofs a tile, shielding it from the elements.", "You roof this tile, shielding it from the elements.") + break + return + if(flooring) if(istype(C, /obj/item/weapon)) try_deconstruct_tile(C, user) diff --git a/code/game/turfs/simulated/outdoors/outdoors.dm b/code/game/turfs/simulated/outdoors/outdoors.dm index 729095a6668..cfdc3cc444c 100644 --- a/code/game/turfs/simulated/outdoors/outdoors.dm +++ b/code/game/turfs/simulated/outdoors/outdoors.dm @@ -1,5 +1,4 @@ var/list/turf_edge_cache = list() -var/list/outdoor_turfs = list() /turf/ // If greater than 0, this turf will apply edge overlays on top of other turfs cardinally adjacent to it, if those adjacent turfs are of a different icon_state, @@ -24,24 +23,21 @@ var/list/outdoor_turfs = list() /turf/simulated/floor/New() if(outdoors) - outdoor_turfs.Add(src) + SSplanets.addTurf(src) ..() /turf/simulated/floor/Destroy() if(outdoors) - planet_controller.unallocateTurf(src) + SSplanets.removeTurf(src) return ..() /turf/simulated/proc/make_outdoors() outdoors = TRUE - outdoor_turfs.Add(src) + SSplanets.addTurf(src) /turf/simulated/proc/make_indoors() outdoors = FALSE - if(planet_controller) - planet_controller.unallocateTurf(src) - else // This is happening during map gen, if there's no planet_controller (hopefully). - outdoor_turfs -= src + SSplanets.removeTurf(src) /turf/simulated/post_change() ..() diff --git a/code/game/turfs/simulated/outdoors/sky.dm b/code/game/turfs/simulated/outdoors/sky.dm index c329fc2e4d1..468b893b335 100644 --- a/code/game/turfs/simulated/outdoors/sky.dm +++ b/code/game/turfs/simulated/outdoors/sky.dm @@ -14,7 +14,7 @@ /turf/simulated/sky/initialize() . = ..() - outdoor_turfs.Add(src) + SSplanets.addTurf(src) set_light(2, 2, "#FFFFFF") /turf/simulated/sky/north diff --git a/code/game/turfs/simulated/wall_attacks.dm b/code/game/turfs/simulated/wall_attacks.dm index 1eaca16e761..4d87e2e87ea 100644 --- a/code/game/turfs/simulated/wall_attacks.dm +++ b/code/game/turfs/simulated/wall_attacks.dm @@ -84,16 +84,16 @@ if(rotting) if(reinf_material) - user << "\The [reinf_material.display_name] feels porous and crumbly." + to_chat(user, "\The [reinf_material.display_name] feels porous and crumbly.") else - user << "\The [material.display_name] crumbles under your touch!" + to_chat(user, "\The [material.display_name] crumbles under your touch!") dismantle_wall() return 1 if(..()) return 1 if(!can_open) - user << "You push the wall, but nothing happens." + to_chat(user, "You push the wall, but nothing happens.") playsound(src, 'sound/weapons/Genhit.ogg', 25, 1) else toggle_open(user) @@ -138,28 +138,58 @@ user.setClickCooldown(user.get_attack_speed(W)) if (!user.) - user << "You don't have the dexterity to do this!" + to_chat(user, "You don't have the dexterity to do this!") return //get the user's location - if(!istype(user.loc, /turf)) return //can't do this stuff whilst inside objects and such + if(!istype(user.loc, /turf)) + return //can't do this stuff whilst inside objects and such if(W) radiate() if(is_hot(W)) burn(is_hot(W)) + if(istype(W, /obj/item/stack/tile/roofing)) + var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather + var/turf/T = GetAbove(src) + var/obj/item/stack/tile/roofing/R = W + + // Place plating over a wall + if(T) + if(istype(T, /turf/simulated/open) || istype(T, /turf/space)) + if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating + T.ReplaceWithLattice() + T.ChangeTurf(/turf/simulated/floor) + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] patches a hole in the ceiling.", "You patch a hole in the ceiling.") + expended_tile = TRUE + else + to_chat(user, "There aren't any holes in the ceiling to patch here.") + return + + // Create a ceiling to shield from the weather + if(outdoors) + if(expended_tile || R.use(1)) // Don't need to check adjacent turfs for a wall, we're building on one + outdoors = FALSE + SSplanets.unallocateTurf(src) + if(!expended_tile) // Would've already played a sound + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] roofs \the [src], shielding it from the elements.", "You roof \the [src] tile, shielding it from the elements.") + return + + if(locate(/obj/effect/overlay/wallrot) in src) if(istype(W, /obj/item/weapon/weldingtool) ) var/obj/item/weapon/weldingtool/WT = W if( WT.remove_fuel(0,user) ) - user << "You burn away the fungi with \the [WT]." + to_chat(user, "You burn away the fungi with \the [WT].") playsound(src, WT.usesound, 10, 1) for(var/obj/effect/overlay/wallrot/WR in src) qdel(WR) return else if(!is_sharp(W) && W.force >= 10 || W.force >= 20) - user << "\The [src] crumbles away under the force of your [W.name]." + to_chat(user, "\The [src] crumbles away under the force of your [W.name].") src.dismantle_wall(1) return @@ -179,7 +209,7 @@ var/obj/item/weapon/melee/energy/blade/EB = W EB.spark_system.start() - user << "You slash \the [src] with \the [EB]; the thermite ignites!" + to_chat(user, "You slash \the [src] with \the [EB]; the thermite ignites!") playsound(src, "sparks", 50, 1) playsound(src, 'sound/weapons/blade1.ogg', 50, 1) @@ -196,13 +226,13 @@ return if(WT.remove_fuel(0,user)) - user << "You start repairing the damage to [src]." + to_chat(user, "You start repairing the damage to [src].") playsound(src.loc, WT.usesound, 100, 1) if(do_after(user, max(5, damage / 5) * WT.toolspeed) && WT && WT.isOn()) - user << "You finish repairing the damage to [src]." + to_chat(user, "You finish repairing the damage to [src].") take_damage(-damage) else - user << "You need more welding fuel to complete this task." + to_chat(user, "You need more welding fuel to complete this task.") return user.update_examine_panel(src) return @@ -219,7 +249,7 @@ if(!WT.isOn()) return if(!WT.remove_fuel(0,user)) - user << "You need more welding fuel to complete this task." + to_chat(user, "You need more welding fuel to complete this task.") return dismantle_verb = "cutting" dismantle_sound = W.usesound @@ -236,7 +266,7 @@ if(dismantle_verb) - user << "You begin [dismantle_verb] through the outer plating." + to_chat(user, "You begin [dismantle_verb] through the outer plating.") if(dismantle_sound) playsound(src, dismantle_sound, 100, 1) @@ -246,7 +276,7 @@ if(!do_after(user,cut_delay * W.toolspeed)) return - user << "You remove the outer plating." + to_chat(user, "You remove the outer plating.") dismantle_wall() user.visible_message("The wall was torn open by [user]!") return @@ -259,24 +289,24 @@ playsound(src, W.usesound, 100, 1) construction_stage = 5 user.update_examine_panel(src) - user << "You cut through the outer grille." + to_chat(user, "You cut through the outer grille.") update_icon() return if(5) if (istype(W, /obj/item/weapon/screwdriver)) - user << "You begin removing the support lines." + to_chat(user, "You begin removing the support lines.") playsound(src, W.usesound, 100, 1) if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 5) return construction_stage = 4 user.update_examine_panel(src) update_icon() - user << "You unscrew the support lines." + to_chat(user, "You unscrew the support lines.") return else if (istype(W, /obj/item/weapon/wirecutters)) construction_stage = 6 user.update_examine_panel(src) - user << "You mend the outer grille." + to_chat(user, "You mend the outer grille.") playsound(src, W.usesound, 100, 1) update_icon() return @@ -289,51 +319,51 @@ if(WT.remove_fuel(0,user)) cut_cover=1 else - user << "You need more welding fuel to complete this task." + to_chat(user, "You need more welding fuel to complete this task.") return else if (istype(W, /obj/item/weapon/pickaxe/plasmacutter)) cut_cover = 1 if(cut_cover) - user << "You begin slicing through the metal cover." + to_chat(user, "You begin slicing through the metal cover.") playsound(src, W.usesound, 100, 1) if(!do_after(user, 60 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 4) return construction_stage = 3 user.update_examine_panel(src) update_icon() - user << "You press firmly on the cover, dislodging it." + to_chat(user, "You press firmly on the cover, dislodging it.") return else if (istype(W, /obj/item/weapon/screwdriver)) - user << "You begin screwing down the support lines." + to_chat(user, "You begin screwing down the support lines.") playsound(src, W.usesound, 100, 1) if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 4) return construction_stage = 5 user.update_examine_panel(src) update_icon() - user << "You screw down the support lines." + to_chat(user, "You screw down the support lines.") return if(3) if (istype(W, /obj/item/weapon/crowbar)) - user << "You struggle to pry off the cover." + to_chat(user, "You struggle to pry off the cover.") playsound(src, W.usesound, 100, 1) if(!do_after(user,100 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 3) return construction_stage = 2 user.update_examine_panel(src) update_icon() - user << "You pry off the cover." + to_chat(user, "You pry off the cover.") return if(2) if (istype(W, /obj/item/weapon/wrench)) - user << "You start loosening the anchoring bolts which secure the support rods to their frame." + to_chat(user, "You start loosening the anchoring bolts which secure the support rods to their frame.") playsound(src, W.usesound, 100, 1) if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 2) return construction_stage = 1 user.update_examine_panel(src) update_icon() - user << "You remove the bolts anchoring the support rods." + to_chat(user, "You remove the bolts anchoring the support rods.") return if(1) var/cut_cover @@ -342,28 +372,28 @@ if( WT.remove_fuel(0,user) ) cut_cover=1 else - user << "You need more welding fuel to complete this task." + to_chat(user, "You need more welding fuel to complete this task.") return else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) cut_cover = 1 if(cut_cover) - user << "You begin slicing through the support rods." + to_chat(user, "You begin slicing through the support rods.") playsound(src, W.usesound, 100, 1) if(!do_after(user,70 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 1) return construction_stage = 0 user.update_examine_panel(src) update_icon() - user << "The slice through the support rods." + to_chat(user, "The slice through the support rods.") return if(0) if(istype(W, /obj/item/weapon/crowbar)) - user << "You struggle to pry off the outer sheath." + to_chat(user, "You struggle to pry off the outer sheath.") playsound(src, W.usesound, 100, 1) if(!do_after(user,100 * W.toolspeed) || !istype(src, /turf/simulated/wall) || !user || !W || !T ) return if(user.loc == T && user.get_active_hand() == W ) - user << "You pry off the outer sheath." + to_chat(user, "You pry off the outer sheath.") dismantle_wall() return diff --git a/code/game/turfs/simulated/water.dm b/code/game/turfs/simulated/water.dm index e4b762d7333..b7f4299f023 100644 --- a/code/game/turfs/simulated/water.dm +++ b/code/game/turfs/simulated/water.dm @@ -19,6 +19,7 @@ ..() // To get the edges. icon_state = water_state var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state) + underlays.Cut() // To clear the old underlay, so the list doesn't expand infinitely underlays.Add(floorbed_sprite) update_icon_edge() diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 13368bb7ed7..1c700eec854 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -33,18 +33,18 @@ /turf/space/attackby(obj/item/C as obj, mob/user as mob) - if (istype(C, /obj/item/stack/rods)) + if(istype(C, /obj/item/stack/rods)) var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) if(L) return var/obj/item/stack/rods/R = C if (R.use(1)) - user << "Constructing support lattice ..." + to_chat(user, "Constructing support lattice ...") playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) ReplaceWithLattice() return - if (istype(C, /obj/item/stack/tile/floor)) + if(istype(C, /obj/item/stack/tile/floor)) var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) if(L) var/obj/item/stack/tile/floor/S = C @@ -56,7 +56,33 @@ ChangeTurf(/turf/simulated/floor/airless) return else - user << "The plating is going to need some support." + to_chat(user, "The plating is going to need some support.") + + if(istype(C, /obj/item/stack/tile/roofing)) + var/turf/T = GetAbove(src) + var/obj/item/stack/tile/roofing/R = C + + // Patch holes in the ceiling + if(T) + if(istype(T, /turf/simulated/open) || istype(T, /turf/space)) + // Must be build adjacent to an existing floor/wall, no floating floors + var/turf/simulated/A = locate(/turf/simulated/floor) in T.CardinalTurfs() + if(!A) + A = locate(/turf/simulated/wall) in T.CardinalTurfs() + if(!A) + to_chat(user, "There's nothing to attach the ceiling to!") + return + + if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating + T.ReplaceWithLattice() + T.ChangeTurf(/turf/simulated/floor) + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] expands the ceiling.", "You expand the ceiling.") + else + to_chat(user, "There aren't any holes in the ceiling to patch here.") + return + // Space shouldn't have weather of the sort planets with atmospheres do. + // If that's changed, then you'll want to swipe the rest of the roofing code from code/game/turfs/simulated/floor_attackby.dm return @@ -64,7 +90,7 @@ /turf/space/Entered(atom/movable/A as mob|obj) if(movement_disabled) - usr << "Movement is admin-disabled." //This is to identify lag problems + to_chat(usr, "Movement is admin-disabled.") //This is to identify lag problems return ..() if ((!(A) || src != A.loc)) return diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index b355ec6328b..1d776866612 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -40,6 +40,7 @@ var/old_affecting_lights = affecting_lights var/old_lighting_overlay = lighting_overlay var/old_corners = corners + var/old_outdoors = outdoors //world << "Replacing [src.type] with [N]" @@ -108,3 +109,4 @@ lighting_build_overlay() else lighting_clear_overlay() + outdoors = old_outdoors \ No newline at end of file diff --git a/code/game/turfs/unsimulated/planetary.dm b/code/game/turfs/unsimulated/planetary.dm index 613638ec804..35cd7aa4a80 100644 --- a/code/game/turfs/unsimulated/planetary.dm +++ b/code/game/turfs/unsimulated/planetary.dm @@ -1,7 +1,5 @@ // This is a wall you surround the area of your "planet" with, that makes the atmosphere inside stay within bounds, even if canisters // are opened or other strange things occur. -var/list/planetary_walls = list() - /turf/unsimulated/wall/planetary name = "railroading" desc = "Choo choo!" @@ -21,10 +19,10 @@ var/list/planetary_walls = list() /turf/unsimulated/wall/planetary/New() ..() - planetary_walls.Add(src) + SSplanets.addTurf(src) /turf/unsimulated/wall/planetary/Destroy() - planetary_walls.Remove(src) + SSplanets.removeTurf(src) ..() /turf/unsimulated/wall/planetary/proc/set_temperature(var/new_temperature) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 81d936dce93..fc3fba6c7cb 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -659,11 +659,13 @@ var/list/admin_verbs_event_manager = list( 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/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb", "Cancel") var/choice = input("What size explosion would you like to produce?") in choices switch(choice) if(null) return 0 + if("Cancel") + return 0 if("Small Bomb") explosion(epicenter, 1, 2, 3, 3) if("Medium Bomb") diff --git a/code/modules/admin/verbs/antag-ooc.dm b/code/modules/admin/verbs/antag-ooc.dm index 22689f17188..13c6e6a767a 100644 --- a/code/modules/admin/verbs/antag-ooc.dm +++ b/code/modules/admin/verbs/antag-ooc.dm @@ -12,7 +12,7 @@ else if(is_antag && !is_admin) // Is an antag, and not an admin, meaning we need to check if their antag type allows AOOC. var/datum/antagonist/A = get_antag_data(usr.mind.special_role) - if(!A || !A.can_use_aooc) + if(!A || !A.can_speak_aooc || !A.can_hear_aooc) to_chat(usr, "Sorry, but your antagonist type is not allowed to speak in AOOC.") return @@ -36,7 +36,7 @@ var/datum/antagonist/A = null if(M.mind) // Observers don't have minds, but they should still see AOOC. A = get_antag_data(M.mind.special_role) - if((M.mind && M.mind.special_role && A && A.can_use_aooc) || isobserver(M)) // Antags must have their type be allowed to AOOC to see AOOC. This prevents, say, ERT from seeing AOOC. + if((M.mind && M.mind.special_role && A && A.can_hear_aooc) || isobserver(M)) // Antags must have their type be allowed to AOOC to see AOOC. This prevents, say, ERT from seeing AOOC. to_chat(M, "[create_text_tag("aooc", "Antag-OOC:", M.client)] [player_display]: [msg]") log_aooc(msg,src) \ No newline at end of file diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 1029d1b5d5f..c2167b4b4a5 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -637,7 +637,7 @@ if(!check_rights(R_DEBUG)) return - var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in planet_controller.planets + var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in SSplanets.planets var/datum/weather/new_weather = input(usr, "What weather do you want to change to?", "Change Weather") as null|anything in planet.weather_holder.allowed_weather_types if(new_weather) planet.weather_holder.change_weather(new_weather) @@ -653,7 +653,7 @@ if(!check_rights(R_DEBUG)) return - var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in planet_controller.planets + var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in SSplanets.planets var/datum/time/current_time_datum = planet.current_time var/new_hour = input(usr, "What hour do you want to change to?", "Change Time", text2num(current_time_datum.show_time("hh"))) as null|num diff --git a/code/modules/artifice/deadringer.dm b/code/modules/artifice/deadringer.dm new file mode 100644 index 00000000000..99061b6624a --- /dev/null +++ b/code/modules/artifice/deadringer.dm @@ -0,0 +1,184 @@ +/obj/item/weapon/deadringer + name = "silver pocket watch" + desc = "A fancy silver-plated digital pocket watch. Looks expensive." + icon = 'icons/obj/deadringer.dmi' + icon_state = "deadringer" + w_class = ITEMSIZE_SMALL + slot_flags = SLOT_ID | SLOT_BELT | SLOT_TIE + origin_tech = list(TECH_ILLEGAL = 3) + var/activated = 0 + var/timer = 0 + var/bruteloss_prev = 999999 + var/fireloss_prev = 999999 + var/mob/living/carbon/human/corpse = null + var/mob/living/carbon/human/watchowner = null + + +/obj/item/weapon/deadringer/New() + ..() + processing_objects |= src + +/obj/item/weapon/deadringer/Destroy() //just in case some smartass tries to stay invisible by destroying the watch + uncloak() + processing_objects -= src + ..() + + +/obj/item/weapon/deadringer/dropped() + if(timer > 20) + uncloak() + watchowner = null + return + +/obj/item/weapon/deadringer/attack_self(var/mob/living/user as mob) + var/mob/living/H = src.loc + if (!istype(H, /mob/living/carbon/human)) + to_chat(H,"You have no clue what to do with this thing.") + return + if(!activated) + if(timer == 0) + to_chat(H, "You press a small button on [src]'s side. It starts to hum quietly.") + bruteloss_prev = H.getBruteLoss() + fireloss_prev = H.getFireLoss() + activated = 1 + return + else + to_chat(H,"You press a small button on [src]'s side. It buzzes a little.") + return + if(activated) + to_chat(H,"You press a small button on [src]'s side. It stops humming.") + activated = 0 + return + + +/obj/item/weapon/deadringer/process() + if(activated) + if (ismob(src.loc)) + var/mob/living/carbon/human/H = src.loc + watchowner = H + if(H.getBruteLoss() > bruteloss_prev || H.getFireLoss() > fireloss_prev) + deathprevent() + activated = 0 + if(watchowner.isSynthetic()) + to_chat(watchowner, "You fade into nothingness! [src]'s screen blinks, being unable to copy your synthetic body!") + else + to_chat(watchowner, "You fade into nothingness, leaving behind a fake body!") + icon_state = "deadringer_cd" + timer = 50 + return + if(timer > 0) + timer-- + if(timer == 20) + uncloak() + if(corpse) + new /obj/effect/effect/smoke/chem(corpse.loc) + qdel(corpse) + if(timer == 0) + icon_state = "deadringer" + return + + +/obj/item/weapon/deadringer/proc/deathprevent() + for(var/mob/living/simple_animal/D in oviewers(7, src)) + D.LoseTarget() + watchowner.emote("deathgasp") + watchowner.invisibility = 85 + watchowner.alpha = 127 + makeacorpse(watchowner) + for(var/mob/living/simple_animal/D in oviewers(7, src)) + D.LoseTarget() + return + +/obj/item/weapon/deadringer/proc/uncloak() + if(watchowner) + watchowner.invisibility = 0 + watchowner.alpha = 255 + playsound(get_turf(src), 'sound/effects/uncloak.ogg', 35, 1, -1) + return + +/obj/item/weapon/deadringer/proc/makeacorpse(var/mob/living/carbon/human/H) + if(H.isSynthetic()) + return + corpse = new /mob/living/carbon/human(H.loc) + corpse.setDNA(H.dna.Clone()) + corpse.death(1) //Kills the new mob + var/obj/item/clothing/temp = null + if(H.get_equipped_item(slot_w_uniform)) + corpse.equip_to_slot_or_del(new /obj/item/clothing/under/chameleon/changeling(corpse), slot_w_uniform) + temp = corpse.get_equipped_item(slot_w_uniform) + var/obj/item/clothing/c_type = H.get_equipped_item(slot_w_uniform) + temp.disguise(c_type.type) + temp.canremove = 0 + if(H.get_equipped_item(slot_wear_suit)) + corpse.equip_to_slot_or_del(new /obj/item/clothing/suit/chameleon/changeling(corpse), slot_wear_suit) + temp = corpse.get_equipped_item(slot_wear_suit) + var/obj/item/clothing/c_type = H.get_equipped_item(slot_wear_suit) + temp.disguise(c_type.type) + temp.canremove = 0 + if(H.get_equipped_item(slot_shoes)) + corpse.equip_to_slot_or_del(new /obj/item/clothing/shoes/chameleon/changeling(corpse), slot_shoes) + temp = corpse.get_equipped_item(slot_shoes) + var/obj/item/clothing/c_type = H.get_equipped_item(slot_shoes) + temp.disguise(c_type.type) + temp.canremove = 0 + if(H.get_equipped_item(slot_gloves)) + corpse.equip_to_slot_or_del(new /obj/item/clothing/gloves/chameleon/changeling(corpse), slot_gloves) + temp = corpse.get_equipped_item(slot_gloves) + var/obj/item/clothing/c_type = H.get_equipped_item(slot_gloves) + temp.disguise(c_type.type) + temp.canremove = 0 + if(H.get_equipped_item(slot_l_ear)) + temp = H.get_equipped_item(slot_l_ear) + corpse.equip_to_slot_or_del(new temp.type(corpse), slot_l_ear) + temp = corpse.get_equipped_item(slot_l_ear) + temp.canremove = 0 + if(H.get_equipped_item(slot_glasses)) + corpse.equip_to_slot_or_del(new /obj/item/clothing/glasses/chameleon/changeling(corpse), slot_glasses) + temp = corpse.get_equipped_item(slot_glasses) + var/obj/item/clothing/c_type = H.get_equipped_item(slot_glasses) + temp.disguise(c_type.type) + temp.canremove = 0 + if(H.get_equipped_item(slot_wear_mask)) + corpse.equip_to_slot_or_del(new /obj/item/clothing/mask/chameleon/changeling(corpse), slot_wear_mask) + temp = corpse.get_equipped_item(slot_wear_mask) + var/obj/item/clothing/c_type = H.get_equipped_item(slot_wear_mask) + temp.disguise(c_type.type) + temp.canremove = 0 + if(H.get_equipped_item(slot_head)) + corpse.equip_to_slot_or_del(new /obj/item/clothing/head/chameleon/changeling(corpse), slot_head) + temp = corpse.get_equipped_item(slot_head) + var/obj/item/clothing/c_type = H.get_equipped_item(slot_head) + temp.disguise(c_type.type) + temp.canremove = 0 + if(H.get_equipped_item(slot_belt)) + corpse.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/chameleon/changeling(corpse), slot_belt) + temp = corpse.get_equipped_item(slot_belt) + var/obj/item/clothing/c_type = H.get_equipped_item(slot_belt) + temp.disguise(c_type.type) + temp.canremove = 0 + if(H.get_equipped_item(slot_back)) + corpse.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/chameleon/changeling(corpse), slot_back) + temp = corpse.get_equipped_item(slot_back) + var/obj/item/clothing/c_type = H.get_equipped_item(slot_back) + temp.disguise(c_type.type) + temp.canremove = 0 + corpse.identifying_gender = H.identifying_gender + corpse.flavor_texts = H.flavor_texts.Copy() + corpse.real_name = H.real_name + corpse.name = H.name + corpse.set_species(corpse.dna.species) + corpse.change_hair(H.h_style) + corpse.change_facial_hair(H.f_style) + corpse.change_hair_color(H.r_hair, H.g_hair, H.b_hair) + corpse.change_facial_hair_color(H.r_facial, H.g_facial, H.b_facial) + corpse.change_skin_color(H.r_skin, H.g_skin, H.b_skin) + corpse.adjustFireLoss(H.getFireLoss()) + corpse.adjustBruteLoss(H.getBruteLoss()) + corpse.UpdateAppearance() + corpse.regenerate_icons() + for(var/obj/item/organ/internal/I in corpse.internal_organs) + var/obj/item/organ/internal/G = I + G.Destroy() + return + + diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 63c781452c8..9e9eaeb8687 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -250,9 +250,8 @@ return /obj/effect/beam/i_beam/Destroy() + . = ..() if(master.first == src) master.first = null - if(next) - qdel(next) - next = null - ..() + if(next && !next.gc_destroyed) + qdel_null(next) diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 07f45a9c6fd..6b93b33fafc 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -71,8 +71,8 @@ datum/preferences/proc/set_biological_gender(var/gender) . += "Nickname: " . += "[pref.nickname]" . += "
" - . += "Biological Gender: [gender2text(pref.biological_gender)]
" - . += "Gender Identity: [gender2text(pref.identifying_gender)]
" + . += "Biological Sex: [gender2text(pref.biological_gender)]
" + . += "Pronouns: [gender2text(pref.identifying_gender)]
" . += "Age: [pref.age]
" . += "Spawn Point: [pref.spawnpoint]
" if(config.allow_Metadata) @@ -111,13 +111,13 @@ datum/preferences/proc/set_biological_gender(var/gender) return TOPIC_NOACTION else if(href_list["bio_gender"]) - var/new_gender = input(user, "Choose your character's biological gender:", "Character Preference", pref.biological_gender) as null|anything in get_genders() + var/new_gender = input(user, "Choose your character's biological sex:", "Character Preference", pref.biological_gender) as null|anything in get_genders() if(new_gender && CanUseTopic(user)) pref.set_biological_gender(new_gender) return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["id_gender"]) - var/new_gender = input(user, "Choose your character's identifying gender:", "Character Preference", pref.identifying_gender) as null|anything in all_genders_define_list + var/new_gender = input(user, "Choose your character's pronouns:", "Character Preference", pref.identifying_gender) as null|anything in all_genders_define_list if(new_gender && CanUseTopic(user)) pref.identifying_gender = new_gender return TOPIC_REFRESH @@ -158,4 +158,4 @@ datum/preferences/proc/set_biological_gender(var/gender) return possible_genders possible_genders = possible_genders.Copy() possible_genders |= NEUTER - return possible_genders \ No newline at end of file + return possible_genders diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 203527fb184..f1d6d95f2a2 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -36,6 +36,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O S["synth_red"] >> pref.r_synth S["synth_green"] >> pref.g_synth S["synth_blue"] >> pref.b_synth + S["synth_markings"] >> pref.synth_markings pref.preview_icon = null S["bgstate"] >> pref.bgstate @@ -65,6 +66,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O S["synth_red"] << pref.r_synth S["synth_green"] << pref.g_synth S["synth_blue"] << pref.b_synth + S["synth_markings"] << pref.synth_markings S["bgstate"] << pref.bgstate /datum/category_item/player_setup_item/general/body/sanitize_character(var/savefile/S) @@ -120,6 +122,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O character.r_synth = pref.r_synth character.g_synth = pref.g_synth character.b_synth = pref.b_synth + character.synth_markings = pref.synth_markings // Destroy/cyborgize organs and limbs. for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO)) @@ -305,6 +308,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O . += "
" . += "
" + . += "Allow Synth markings: [pref.synth_markings ? "Yes" : "No"]
" . += "Allow Synth color: [pref.synth_color ? "Yes" : "No"]
" if(pref.synth_color) . += "Change Color
__
" @@ -709,6 +713,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.b_synth = hex2num(copytext(new_color, 6, 8)) return TOPIC_REFRESH_UPDATE_PREVIEW + else if(href_list["synth_markings"]) + pref.synth_markings = !pref.synth_markings + return TOPIC_REFRESH_UPDATE_PREVIEW + else if(href_list["cycle_bg"]) pref.bgstate = next_in_list(pref.bgstate, pref.bgstate_options) return TOPIC_REFRESH_UPDATE_PREVIEW diff --git a/code/modules/client/preference_setup/loadout/loadout_suit.dm b/code/modules/client/preference_setup/loadout/loadout_suit.dm index 9161f655175..1c9ec298802 100644 --- a/code/modules/client/preference_setup/loadout/loadout_suit.dm +++ b/code/modules/client/preference_setup/loadout/loadout_suit.dm @@ -241,6 +241,46 @@ datum/gear/suit/duster path = /obj/item/clothing/accessory/poncho/roles/cloak/hop allowed_roles = list("Head of Personnel") +/datum/gear/suit/roles/poncho/cloak/cargo + display_name = "cloak, cargo" + path = /obj/item/clothing/accessory/poncho/roles/cloak/cargo + allowed_roles = list("Cargo Technician","Quartermaster") + +/datum/gear/suit/roles/poncho/cloak/mining + display_name = "cloak, cargo" + path = /obj/item/clothing/accessory/poncho/roles/cloak/mining + allowed_roles = list("Quartermaster","Shaft Miner") + +/datum/gear/suit/roles/poncho/cloak/security + display_name = "cloak, security" + path = /obj/item/clothing/accessory/poncho/roles/cloak/security + allowed_roles = list("Head of Security","Detective","Warden","Security Officer") + +/datum/gear/suit/roles/poncho/cloak/service + display_name = "cloak, service" + path = /obj/item/clothing/accessory/poncho/roles/cloak/service + allowed_roles = list("Head of Personnel","Bartender","Botanist","Janitor","Chef","Librarian") + +/datum/gear/suit/roles/poncho/cloak/engineer + display_name = "cloak, engineer" + path = /obj/item/clothing/accessory/poncho/roles/cloak/engineer + allowed_roles = list("Chief Engineer","Station Engineer") + +/datum/gear/suit/roles/poncho/cloak/atmos + display_name = "cloak, atmos" + path = /obj/item/clothing/accessory/poncho/roles/cloak/atmos + allowed_roles = list("Chief Engineer","Atmospheric Technician") + +/datum/gear/suit/roles/poncho/cloak/research + display_name = "cloak, science" + path = /obj/item/clothing/accessory/poncho/roles/cloak/research + allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist") + +/datum/gear/suit/roles/poncho/cloak/medical + display_name = "cloak, medical" + path = /obj/item/clothing/accessory/poncho/roles/cloak/medical + allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist") + /datum/gear/suit/unathi_robe display_name = "roughspun robe" path = /obj/item/clothing/suit/unathi/robe diff --git a/code/modules/client/preference_setup/loadout/loadout_utility.dm b/code/modules/client/preference_setup/loadout/loadout_utility.dm index 76178dada21..52fce45031e 100644 --- a/code/modules/client/preference_setup/loadout/loadout_utility.dm +++ b/code/modules/client/preference_setup/loadout/loadout_utility.dm @@ -116,22 +116,28 @@ path = /obj/item/weapon/cell/device /datum/gear/utility/implant - exploitable = 1 -/* VOREStation Edit - Make languages great again -/datum/gear/utility/implant/eal //This does nothing if you don't actually know EAL. - display_name = "implant, language, EAL" - path = /obj/item/weapon/implant/language/eal - cost = 2 slot = "implant" - exploitable = 1*/ + exploitable = 1 /datum/gear/utility/implant/tracking display_name = "implant, tracking" path = /obj/item/weapon/implant/tracking/weak cost = 0 //VOREStation Edit. Changed cost to 0 - slot = "implant" - exploitable = 1 +/* VOREStation Edit - Make languages great again +/datum/gear/utility/implant/language + cost = 2 + exploitable = 0 +/datum/gear/utility/implant/language/eal + display_name = "vocal synthesizer, EAL" + description = "A surgically implanted vocal synthesizer which allows the owner to speak EAL, if they know it." + path = /obj/item/weapon/implant/language/eal + +/datum/gear/utility/implant/language/skrellian + display_name = "vocal synthesizer, Skrellian" + description = "A surgically implanted vocal synthesizer which allows the owner to speak Common Skrellian, if they know it." + path = /obj/item/weapon/implant/language/skrellian +*/ /datum/gear/utility/pen display_name = "Fountain Pen" path = /obj/item/weapon/pen/fountain diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index d0aefa286f4..99cf57522ed 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -60,6 +60,7 @@ datum/preferences var/r_synth //Used with synth_color to color synth parts that normaly can't be colored. var/g_synth //Same as above var/b_synth //Same as above + var/synth_markings = 0 //Enable/disable markings on synth parts. //Some faction information. var/home_system = "Unset" //System of birth. diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 329f905a66f..ea616226ba4 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -253,7 +253,8 @@ var/mob/living/carbon/human/H = user if(slot && slot == slot_gloves) - if(H.gloves) + var/obj/item/clothing/gloves/G = H.gloves + if(istype(G)) ring = H.gloves if(ring.glove_level >= src.glove_level) to_chat(user, "You are unable to wear \the [src] as \the [H.gloves] are in the way.") diff --git a/code/modules/clothing/head/helmet_vr.dm b/code/modules/clothing/head/helmet_vr.dm index fc71016f7e5..8f7ec139ca5 100644 --- a/code/modules/clothing/head/helmet_vr.dm +++ b/code/modules/clothing/head/helmet_vr.dm @@ -9,8 +9,8 @@ /obj/item/clothing/head/helmet/combat/USDF name = "marine helmet" desc = "If you wanna to keep your brain inside yo' head, you'd best put this on!" - icon_state = "UNSC_helm" - item_state = "UNSC_helm" + icon_state = "unsc_helm" + item_state = "unsc_helm" icon = 'icons/obj/clothing/hats_vr.dmi' icon_override = 'icons/mob/head_vr.dmi' diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index fd850073d88..a6d1e9e48a6 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -20,27 +20,32 @@ /obj/item/clothing/head/pin/pink icon_state = "pinkpin" + addblends = null name = "pink hair hat" /obj/item/clothing/head/pin/clover icon_state = "cloverpin" name = "clover pin" + addblends = null desc = "A hair pin in the shape of a clover leaf." /obj/item/clothing/head/pin/butterfly icon_state = "butterflypin" name = "butterfly pin" + addblends = null desc = "A hair pin in the shape of a bright blue butterfly." /obj/item/clothing/head/pin/magnetic icon_state = "magnetpin" name = "magnetic 'pin'" + addblends = null desc = "Finally, a hair pin even a Morpheus chassis can use." matter = list(DEFAULT_WALL_MATERIAL = 10) /obj/item/clothing/head/pin/flower name = "red flower pin" icon_state = "hairflower" + addblends = null desc = "Smells nice." /obj/item/clothing/head/pin/flower/blue @@ -82,6 +87,7 @@ /obj/item/clothing/head/pin/bow/big/red icon_state = "redribbon" name = "red ribbon" + addblends = null /obj/item/clothing/head/powdered_wig name = "powdered wig" diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 3b30c74aad3..abd87c5d892 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -28,6 +28,12 @@ return gas_filtered +/obj/item/clothing/mask/gas/clear + name = "gas mask" + desc = "A face-covering mask with a transparent faceplate that can be connected to an air supply." + icon_state = "gas_clear" + flags_inv = null + /obj/item/clothing/mask/gas/half name = "face mask" desc = "A compact, durable gas mask that can be connected to an air supply." diff --git a/code/modules/clothing/spacesuits/rig/modules/utility_vr.dm b/code/modules/clothing/spacesuits/rig/modules/utility_vr.dm index 83456629a12..21fe6fb9cf3 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility_vr.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility_vr.dm @@ -104,14 +104,14 @@ interface_name = "mounted chem injector" interface_desc = "Dispenses loaded chemicals via an arm-mounted injector." - var/max_reagent_volume = 10 //Regen to this volume + var/max_reagent_volume = 20 //Regen to this volume var/chems_to_use = 5 //Per injection charges = list( - list("inaprovaline", "inaprovaline", 0, 10), - list("tricordrazine", "tricordrazine", 0, 10), - list("tramadol", "tramadol", 0, 10), - list("dexalin plus", "dexalinp", 0, 10) + list("inaprovaline", "inaprovaline", 0, 20), + list("dylovene", "dylovene", 0, 20), + list("paracetamol", "paracetamol", 0, 20), + list("dexalin", "dexalin", 0, 20) ) /obj/item/rig_module/rescue_pharm/process() diff --git a/code/modules/clothing/suits/armor_vr.dm b/code/modules/clothing/suits/armor_vr.dm index 349b0e01e7a..76d55dcc827 100644 --- a/code/modules/clothing/suits/armor_vr.dm +++ b/code/modules/clothing/suits/armor_vr.dm @@ -60,7 +60,7 @@ /obj/item/clothing/suit/armor/combat/USDF name = "marine body armor" desc = "When I joined the Corps, we didn't have any fancy-schmanzy armor. We had sticks! Two sticks, and a rock for the whole platoon–and we had to share the rock!" - icon_state = "UNSC_armor" + icon_state = "unsc_armor" icon = 'icons/obj/clothing/suits_vr.dmi' icon_override = 'icons/mob/suit_vr.dmi' body_parts_covered = UPPER_TORSO|LOWER_TORSO // ToDo: Break up the armor into smaller bits. diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index bf14076f50b..189ef976c24 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -128,6 +128,7 @@ /obj/item/clothing/suit/syndicatefake name = "red space suit replica" + icon = 'icons/obj/clothing/spacesuits.dmi' icon_state = "syndicate" desc = "A plastic replica of the syndicate space suit, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!" w_class = ITEMSIZE_NORMAL diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 1965a5873ac..2dbda7a6151 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -78,7 +78,7 @@ name = "Radiation Hood" icon_state = "rad" desc = "A hood with radiation protective properties. Label: Made with lead, do not eat insulation" -// flags_inv = BLOCKHAIR + flags_inv = BLOCKHAIR item_flags = THICKMATERIAL body_parts_covered = HEAD|FACE|EYES armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100) diff --git a/code/modules/clothing/under/accessories/clothing.dm b/code/modules/clothing/under/accessories/clothing.dm index eaab8b290a4..02fab3e95a3 100644 --- a/code/modules/clothing/under/accessories/clothing.dm +++ b/code/modules/clothing/under/accessories/clothing.dm @@ -121,8 +121,8 @@ * Cloak */ /obj/item/clothing/accessory/poncho/roles/cloak - name = "brown cloak" - desc = "An elaborate brown cloak." + name = "quartermaster's cloak" + desc = "An elaborate brown and gold cloak." icon_state = "qmcloak" item_state = "qmcloak" body_parts_covered = null @@ -169,6 +169,54 @@ icon_state = "capcloak" item_state = "capcloak" +/obj/item/clothing/accessory/poncho/roles/cloak/cargo + name = "brown cloak" + desc = "A simple brown and black cloak." + icon_state = "cargocloak" + item_state = "cargocloak" + +/obj/item/clothing/accessory/poncho/roles/cloak/mining + name = "trimmed purple cloak" + desc = "A trimmed purple and brown cloak." + icon_state = "miningcloak" + item_state = "miningcloak" + +/obj/item/clothing/accessory/poncho/roles/cloak/security + name = "red cloak" + desc = "A simple red and black cloak." + icon_state = "seccloak" + item_state = "seccloak" + +/obj/item/clothing/accessory/poncho/roles/cloak/service + name = "green cloak" + desc = "A simple green and blue cloak." + icon_state = "servicecloak" + item_state = "servicecloak" + +/obj/item/clothing/accessory/poncho/roles/cloak/engineer + name = "gold cloak" + desc = "A simple gold and brown cloak." + icon_state = "engicloak" + item_state = "engicloak" + +/obj/item/clothing/accessory/poncho/roles/cloak/atmos + name = "yellow cloak" + desc = "A trimmed yellow and blue cloak." + icon_state = "atmoscloak" + item_state = "atmoscloak" + +/obj/item/clothing/accessory/poncho/roles/cloak/research + name = "purple cloak" + desc = "A simple purple and white cloak." + icon_state = "scicloak" + item_state = "scicloak" + +/obj/item/clothing/accessory/poncho/roles/cloak/medical + name = "blue cloak" + desc = "A simple blue and white cloak." + icon_state = "medcloak" + item_state = "medcloak" + /obj/item/clothing/accessory/hawaii name = "flower-pattern shirt" desc = "You probably need some welder googles to look at this." diff --git a/code/modules/events/atmos_leak.dm b/code/modules/events/atmos_leak.dm index e9fea3ff669..6823adee968 100644 --- a/code/modules/events/atmos_leak.dm +++ b/code/modules/events/atmos_leak.dm @@ -51,17 +51,6 @@ kill() return -/** Checks if any living humans are in a given area! */ -/datum/event/atmos_leak/proc/is_area_occupied(var/area/myarea) - // Testing suggests looping over human_mob_list is quicker than looping over area contents - for(var/mob/living/carbon/human/H in human_mob_list) - if(H.stat >= DEAD) //Conditions for exclusion here, like if disconnected people start blocking it. - continue - var/area/A = get_area(H) - if(A == myarea) //The loc of a turf is the area it is in. - return 1 - return 0 - /datum/event/atmos_leak/announce() command_announcement.Announce("Warning, hazardous [gas_data.name[gas_type]] gas leak detected in \the [target_area], evacuate the area and contain the damage!", "Hazard Alert") diff --git a/code/modules/events/escaped_slimes.dm b/code/modules/events/escaped_slimes.dm index b36a0d15bff..c9f4f661a3e 100644 --- a/code/modules/events/escaped_slimes.dm +++ b/code/modules/events/escaped_slimes.dm @@ -33,7 +33,7 @@ /datum/event/escaped_slimes/start() var/list/vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines) - if(temp_vent.network && temp_vent.loc.z in using_map.station_levels) //borrowed from spiders event, but it works. Distribute the slimes only in rooms with vents + if(temp_vent.network && temp_vent.loc.z in using_map.station_levels && !is_area_occupied(temp_vent.loc.loc)) //borrowed from spiders event, but it works. Distribute the slimes only in rooms with vents vents += temp_vent while((spawncount > 0) && vents.len) diff --git a/code/modules/events/gravity.dm b/code/modules/events/gravity.dm index e0cd38dcfbd..4d0881294f4 100644 --- a/code/modules/events/gravity.dm +++ b/code/modules/events/gravity.dm @@ -6,9 +6,8 @@ endWhen = rand(15, 60) // Setup which levels we will disrupt gravit on. zLevels = using_map.station_levels.Copy() - if (planet_controller) - for(var/datum/planet/P in planet_controller.planets) - zLevels -= P.expected_z_levels + for(var/datum/planet/P in SSplanets.planets) + zLevels -= P.expected_z_levels /datum/event/gravity/announce() command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system \ diff --git a/code/modules/events/meteor_strike_vr.dm b/code/modules/events/meteor_strike_vr.dm index 922b641ba87..8868c577cd6 100644 --- a/code/modules/events/meteor_strike_vr.dm +++ b/code/modules/events/meteor_strike_vr.dm @@ -50,7 +50,7 @@ new /obj/structure/meteorite(current) var/datum/planet/impacted - for(var/datum/planet/P in planet_controller.planets) + for(var/datum/planet/P in SSplanets.planets) if(current.z in P.expected_z_levels) impacted = P break diff --git a/code/modules/integrated_electronics/core/device.dm b/code/modules/integrated_electronics/core/device.dm index 6b89a299a4f..91243aefab4 100644 --- a/code/modules/integrated_electronics/core/device.dm +++ b/code/modules/integrated_electronics/core/device.dm @@ -19,6 +19,9 @@ else ..() +/obj/item/device/electronic_assembly/get_cell() + return battery + /obj/item/device/assembly/electronic_assembly/proc/toggle_open(mob/user) playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1) opened = !opened diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm index 4dfd4e989a4..794755b02c8 100644 --- a/code/modules/integrated_electronics/core/printer.dm +++ b/code/modules/integrated_electronics/core/printer.dm @@ -162,13 +162,16 @@ return 1 var/cost = 1 + + if(isnull(current_category)) + current_category = recipe_list[1] if(ispath(build_type, /obj/item/device/electronic_assembly)) var/obj/item/device/electronic_assembly/E = build_type cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4) - else if(ispath(build_type, /obj/item/integrated_circuit)) - var/obj/item/integrated_circuit/IC = build_type - cost = initial(IC.w_class) else + var/obj/item/I = build_type + cost = initial(I.w_class) + if(!(locate(build_type) in recipe_list[current_category])) return if(metal - cost < 0) @@ -198,4 +201,4 @@ name = "integrated circuit printer upgrade disk - circuit cloner" desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies." icon_state = "upgrade_disk_clone" - origin_tech = list(TECH_ENGINEERING = 5, TECH_DATA = 6) \ No newline at end of file + origin_tech = list(TECH_ENGINEERING = 5, TECH_DATA = 6) diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index 6e75d97a0d9..232ef46e3e3 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -53,6 +53,7 @@ recipes += new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("cannon frame", /obj/item/weapon/cannonframe, 10, time = 15, one_per_turf = 0, on_floor = 0) recipes += new/datum/stack_recipe("regular floor tile", /obj/item/stack/tile/floor, 1, 4, 20) + recipes += new/datum/stack_recipe("roofing tile", /obj/item/stack/tile/roofing, 3, 4, 20) recipes += new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60) recipes += new/datum/stack_recipe("frame", /obj/item/frame, 5, time = 25, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("mirror frame", /obj/item/frame/mirror, 1, time = 5, one_per_turf = 0, on_floor = 1) diff --git a/code/modules/mob/_modifiers/aura.dm b/code/modules/mob/_modifiers/aura.dm new file mode 100644 index 00000000000..f72ca67d1ad --- /dev/null +++ b/code/modules/mob/_modifiers/aura.dm @@ -0,0 +1,18 @@ +/* +'Aura' modifiers are semi-permanent, in that they do not have a set duration, but will expire if out of range of the 'source' of the aura. +Note: The source is defined as an argument in New(), and if not specified, it is assumed the holder is the source, +making it not expire ever, which is likely not what you want. +*/ + +/datum/modifier/aura + var/aura_max_distance = 5 // If more than this many tiles away from the source, the modifier expires next tick. + +/datum/modifier/aura/check_if_valid() + if(!origin) + expire() + var/atom/A = origin.resolve() + if(istype(A)) // Make sure we're not null. + if(get_dist(holder, A) > aura_max_distance) + expire() + else + expire() // Source got deleted or something. \ No newline at end of file diff --git a/code/modules/mob/language/generic.dm b/code/modules/mob/language/generic.dm index d602bf71bb8..40fe94b7f54 100644 --- a/code/modules/mob/language/generic.dm +++ b/code/modules/mob/language/generic.dm @@ -133,6 +133,6 @@ key = "s" flags = SIGNLANG|NO_STUTTER|NONVERBAL -/datum/language/sign/can_speak_special(var/mob/speaker) +/datum/language/sign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format var/obj/item/organ/external/hand/hands = locate() in speaker //you can't sign without hands return (hands || !iscarbon(speaker)) diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index c6089a8788e..66e0e5e0f01 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -133,7 +133,15 @@ return speech_verb /datum/language/proc/can_speak_special(var/mob/speaker) - return 1 + . = TRUE + if(ishuman(speaker)) + var/mob/living/carbon/human/H = speaker + if(src.name in H.species.assisted_langs) + . = FALSE + var/obj/item/organ/internal/voicebox/vox = locate() in H.internal_organs // Only voiceboxes for now. Maybe someday it'll include other organs, but I'm not that clever + if(vox) + if(!vox.is_broken() && (src in vox.assists_languages)) + . = TRUE // Language handling. /mob/proc/add_language(var/language) diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm index 6de7a9d3091..c80f606ae6d 100644 --- a/code/modules/mob/language/station.dm +++ b/code/modules/mob/language/station.dm @@ -63,6 +63,14 @@ "ka","aasi","far","wa","baq","ara","qara","zir","saam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", "hal","ket","jurl","mah","tul","cresh","azu","ragh","mro","mra","mrro","mrra") +/datum/language/tajaran/get_random_name(var/gender) + var/new_name = ..(gender,1) + if(prob(50)) + new_name += " [pick(list("Hadii","Kaytam","Nazkiin","Zhan-Khazan","Hharar","Njarir'Akhan","Faaira'Nrezi","Rhezar","Mi'dynh","Rrhazkal","Bayan","Al'Manq","Mi'jri","Chur'eech","Sanu'dra","Ii'rka"))]" + else + new_name += " [..(gender,1)]" + return new_name + /datum/language/tajaranakhani name = LANGUAGE_AKHANI desc = "The language of the sea-faring Njarir'Akhan Tajaran. Borrowing some elements from Siik, the language is distinctly more structured." @@ -77,14 +85,27 @@ "kar","yar","kzar","rha","hrar","err","fer","rir","rar","yarr","arr","ii'r","jar","kur","ran","rii","ii", "nai","ou","kah","oa","ama","uuk","bel","chi","ayt","kay","kas","akor","tam","yir","enai") -/datum/language/tajaran/get_random_name(var/gender) +/datum/language/tajsign + name = LANGUAGE_ALAI + desc = "A standardized Tajaran sign language that was developed in Zarraya and gradually adopted by other nations, incorporating \ + hand gestures and movements of the ears and tail." + signlang_verb = list("gestures with their hands", "gestures with their ears and tail", "gestures with their ears, tail and hands") + colour = "tajaran" + key = "l" + flags = WHITELISTED | SIGNLANG | NO_STUTTER | NONVERBAL - var/new_name = ..(gender,1) - if(prob(50)) - new_name += " [pick(list("Hadii","Kaytam","Nazkiin","Zhan-Khazan","Hharar","Njarir'Akhan","Faaira'Nrezi","Rhezar","Mi'dynh","Rrhazkal","Bayan","Al'Manq","Mi'jri","Chur'eech","Sanu'dra","Ii'rka"))]" - else - new_name += " [..(gender,1)]" - return new_name +/datum/language/tajsign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format + var/list/allowed_species = list(SPECIES_TAJ, SPECIES_TESHARI) // Need a tail and ears and such to use this. + if(iscarbon(speaker)) + var/obj/item/organ/external/hand/hands = locate() in speaker //you can't sign without hands + if(!hands) + return FALSE + if(ishuman(speaker)) + var/mob/living/carbon/human/H = speaker + if(H.species.get_bodytype(H) in allowed_species) + return TRUE + + return FALSE /datum/language/skrell name = LANGUAGE_SKRELLIAN @@ -152,11 +173,6 @@ syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz","shh","shk") space_chance = 10 -/datum/language/machine/can_speak_special(var/mob/speaker) - var/obj/item/weapon/implant/language/eal/beep = locate() in speaker - return ((beep && beep.implanted) || speaker.isSynthetic() || isvoice(speaker)) - //thank you sweet zuhayr - /datum/language/machine/get_random_name() if(prob(70)) return "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]" diff --git a/code/modules/mob/language/station_vr.dm b/code/modules/mob/language/station_vr.dm index 73ea0bbe976..7c610ab9a2c 100644 --- a/code/modules/mob/language/station_vr.dm +++ b/code/modules/mob/language/station_vr.dm @@ -71,7 +71,6 @@ "mihi","wan","six","salve","tartu") machine_understands = FALSE - /datum/language/unathi flags = 0 /datum/language/tajaran diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 3cef4329495..676eedbdd98 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -1,6 +1,6 @@ /mob/living/carbon/human/emote(var/act,var/m_type=1,var/message = null) var/param = null - + var/datum/gender/T = gender_datums[get_visible_gender()] if (findtext(act, "-", 1, null)) @@ -14,9 +14,10 @@ var/muzzled = is_muzzled() //var/m_type = 1 - for (var/obj/item/weapon/implant/I in src) - if (I.implanted) - I.trigger(act, src) + for(var/obj/item/organ/O in src.organs) + for (var/obj/item/weapon/implant/I in O) + if (I.implanted) + I.trigger(act, src) if(src.stat == 2.0 && (act != "deathgasp")) return @@ -80,10 +81,11 @@ //Promethean-only emotes if("squish") - if(!species.bump_flag == SLIME) //That should do, yaya. + /* VOREStation Removal Start - Eh. People can squish maybe. + if(species.bump_flag != SLIME) //This should definitely do it. src << "You are not a slime thing!" return - + */ //VOREStation Removal End playsound(src.loc, 'sound/effects/slime_squish.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound. message = "squishes." m_type = 1 @@ -739,7 +741,7 @@ set name = "Set Pose" set desc = "Sets a description which will be shown when someone examines you." set category = "IC" - + var/datum/gender/T = gender_datums[get_visible_gender()] pose = sanitize(input(usr, "This is [src]. [T.he]...", "Pose", null) as text) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 792011043a3..edf1bdd6c6f 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -166,25 +166,12 @@ update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) if(update) UpdateDamageIcon() -/mob/living/carbon/human/proc/implant_loadout(var/datum/gear/G = new/datum/gear/utility/implant) - var/obj/item/weapon/implant/I = new G.path(src) - I.imp_in = src - I.implanted = 1 - var/obj/item/organ/external/affected = src.organs_by_name[BP_HEAD] - affected.implants += I - I.part = affected - I.implanted(src) - /mob/living/carbon/human/proc/implant_loyalty(override = FALSE) // Won't override by default. if(!config.use_loyalty_implants && !override) return // Nuh-uh. var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(src) - L.imp_in = src - L.implanted = 1 - var/obj/item/organ/external/affected = src.organs_by_name[BP_HEAD] - affected.implants += L - L.part = affected - L.implanted(src) + if(L.handle_implant(src, BP_HEAD)) + L.post_implant(src) /mob/living/carbon/human/proc/is_loyalty_implanted() for(var/L in src.contents) @@ -1139,6 +1126,8 @@ remove_language(species.language) if(species.default_language) remove_language(species.default_language) + for(var/datum/language/L in species.assisted_langs) + remove_language(L) // Clear out their species abilities. species.remove_inherent_verbs(src) holder_type = null diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 0b40e088f32..64cd6a0dc18 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -146,45 +146,35 @@ emp_act //this proc returns the armour value for a particular external organ. /mob/living/carbon/human/proc/getarmor_organ(var/obj/item/organ/external/def_zone, var/type) - if(!type || !def_zone) return 0 + if(!type || !def_zone) + return 0 var/protection = 0 - var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) + var/list/protective_gear = def_zone.get_covering_clothing() for(var/obj/item/clothing/gear in protective_gear) - if(gear.body_parts_covered & def_zone.body_part) - protection += gear.armor[type] - if(LAZYLEN(gear.accessories)) - for(var/obj/item/clothing/accessory/bling in gear.accessories) - if(bling.body_parts_covered & def_zone.body_part) - protection += bling.armor[type] + protection += gear.armor[type] return protection /mob/living/carbon/human/proc/getsoak_organ(var/obj/item/organ/external/def_zone, var/type) - if(!type || !def_zone) return 0 + if(!type || !def_zone) + return 0 var/soaked = 0 - var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) + var/list/protective_gear = def_zone.get_covering_clothing() for(var/obj/item/clothing/gear in protective_gear) - if(gear.body_parts_covered & def_zone.body_part) - soaked += gear.armorsoak[type] - if(LAZYLEN(gear.accessories)) - for(var/obj/item/clothing/accessory/bling in gear.accessories) - if(bling.body_parts_covered & def_zone.body_part) - soaked += bling.armorsoak[type] + soaked += gear.armorsoak[type] return soaked +// Checked in borer code /mob/living/carbon/human/proc/check_head_coverage() - - var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform) - for(var/bp in body_parts) - if(!bp) continue - if(bp && istype(bp ,/obj/item/clothing)) - var/obj/item/clothing/C = bp - if(C.body_parts_covered & HEAD) - return 1 + var/obj/item/organ/external/H = organs_by_name[BP_HEAD] + var/list/body_parts = H.get_covering_clothing() + if(LAZYLEN(body_parts)) + return 1 return 0 //Used to check if they can be fed food/drinks/pills /mob/living/carbon/human/proc/check_mouth_coverage() - var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform) + var/obj/item/organ/external/H = organs_by_name[BP_HEAD] + var/list/protective_gear = H.get_covering_clothing() for(var/obj/item/gear in protective_gear) if(istype(gear) && (gear.body_parts_covered & FACE) && !(gear.item_flags & FLEXIBLEMATERIAL)) return gear diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index d4c33117b24..d55e2e48286 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -30,6 +30,7 @@ var/r_synth //Used with synth_color to color synth parts that normaly can't be colored. var/g_synth //Same as above var/b_synth //Same as above + var/synth_markings = 0 //Enables/disables markings on synth parts. //var/size_multiplier = 1 //multiplier for the mob's icon size //VOREStation Edit (Moved to /mob/living) var/damage_multiplier = 1 //multiplies melee combat damage diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 41c240b98a2..66f5d2c713f 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -1,6 +1,38 @@ // These should all be procs, you can add them to humans/subspecies by // species.dm's inherent_verbs ~ Z +/mob/living/carbon/human/proc/tie_hair() + set name = "Tie Hair" + set desc = "Style your hair." + set category = "IC" + + if(incapacitated()) + to_chat(src, "You can't mess with your hair right now!") + return + + if(h_style) + var/datum/sprite_accessory/hair/hair_style = hair_styles_list[h_style] + var/selected_string + if(!(hair_style.flags & HAIR_TIEABLE)) + to_chat(src, "Your hair isn't long enough to tie.") + return + else + var/list/datum/sprite_accessory/hair/valid_hairstyles = list() + for(var/hair_string in hair_styles_list) + var/list/datum/sprite_accessory/hair/test = hair_styles_list[hair_string] + if(test.flags & HAIR_TIEABLE) + valid_hairstyles.Add(hair_string) + selected_string = input("Select a new hairstyle", "Your hairstyle", hair_style) as null|anything in valid_hairstyles + if(incapacitated()) + to_chat(src, "You can't mess with your hair right now!") + return + else if(selected_string && h_style != selected_string) + h_style = selected_string + regenerate_icons() + visible_message("[src] pauses a moment to style their hair.") + else + to_chat(src, "You're already using that style.") + /mob/living/carbon/human/proc/tackle() set category = "Abilities" set name = "Tackle" diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8619dee42d9..efa040bf2b6 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1041,7 +1041,7 @@ adjustHalLoss(-1) if (drowsyness) - drowsyness-- + drowsyness = max(0, drowsyness - 1) eye_blurry = max(2, eye_blurry) if (prob(5)) sleeping += 1 diff --git a/code/modules/mob/living/carbon/human/species/outsider/event.dm b/code/modules/mob/living/carbon/human/species/outsider/event.dm index 3e75acae9c0..477b14c0c46 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/event.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/event.dm @@ -70,6 +70,7 @@ Variables you may want to make use of are: num_alternate_languages = 3 species_language = LANGUAGE_GALCOM secondary_langs = list() + assisted_langs = list() name_language = null // Use the first-name last-name generator rather than a language scrambler min_age = 0 diff --git a/code/modules/mob/living/carbon/human/species/outsider/shadow.dm b/code/modules/mob/living/carbon/human/species/outsider/shadow.dm index 5d81bb4c9c5..d0f40f693d6 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/shadow.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/shadow.dm @@ -25,6 +25,8 @@ genders = list(NEUTER) + assisted_langs = list() + /datum/species/shadow/handle_death(var/mob/living/carbon/human/H) spawn(1) new /obj/effect/decal/cleanable/ash(H.loc) diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm index 9fab4751cc7..525a6118826 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm @@ -7,6 +7,7 @@ language = LANGUAGE_GALCOM species_language = LANGUAGE_VOX num_alternate_languages = 1 + assisted_langs = list(LANGUAGE_ROOTGLOBAL) unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong) rarity_value = 4 blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \ @@ -71,6 +72,7 @@ has_organ = list( O_HEART = /obj/item/organ/internal/heart/vox, O_LUNGS = /obj/item/organ/internal/lungs/vox, + O_VOICE = /obj/item/organ/internal/voicebox, O_LIVER = /obj/item/organ/internal/liver/vox, O_KIDNEYS = /obj/item/organ/internal/kidneys/vox, O_BRAIN = /obj/item/organ/internal/brain/vox, diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index b1557f3a28d..a1d1a932771 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -52,13 +52,17 @@ // Language/culture vars. var/default_language = LANGUAGE_GALCOM // Default language is used when 'say' is used without modifiers. var/language = LANGUAGE_GALCOM // Default racial language, if any. - var/species_language = LANGUAGE_GALCOM // Used on the Character Setup screen + var/list/species_language = list(LANGUAGE_GALCOM) // Used on the Character Setup screen var/list/secondary_langs = list() // The names of secondary languages that are available to this species. var/list/speech_sounds = list() // A list of sounds to potentially play when speaking. var/list/speech_chance = list() // The likelihood of a speech sound playing. var/num_alternate_languages = 0 // How many secondary languages are available to select at character creation var/name_language = LANGUAGE_GALCOM // The language to use when determining names for this species, or null to use the first name/last name generator + // The languages the species can't speak without an assisted organ. + // This list is a guess at things that no one other than the parent species should be able to speak + var/list/assisted_langs = list(LANGUAGE_EAL, LANGUAGE_TERMINUS, LANGUAGE_SKRELLIAN, LANGUAGE_SKRELLIANFAR, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) + //Soundy emotey things. var/scream_verb = "screams" var/male_scream_sound //= 'sound/goonstation/voice/male_scream.ogg' Removed due to licensing, replace! @@ -183,6 +187,7 @@ var/list/has_organ = list( // which required-organ checks are conducted. O_HEART = /obj/item/organ/internal/heart, O_LUNGS = /obj/item/organ/internal/lungs, + O_VOICE = /obj/item/organ/internal/voicebox, O_LIVER = /obj/item/organ/internal/liver, O_KIDNEYS = /obj/item/organ/internal/kidneys, O_BRAIN = /obj/item/organ/internal/brain, diff --git a/code/modules/mob/living/carbon/human/species/station/alraune.dm b/code/modules/mob/living/carbon/human/species/station/alraune.dm index 4aa39470c6a..ba9e6344957 100644 --- a/code/modules/mob/living/carbon/human/species/station/alraune.dm +++ b/code/modules/mob/living/carbon/human/species/station/alraune.dm @@ -3,7 +3,6 @@ name_plural = "Alraunes" unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite) num_alternate_languages = 2 - language = LANGUAGE_ROOTLOCAL slowdown = 1 //slow, they're plants. Not as slow as full diona. total_health = 100 //standard brute_mod = 1 //nothing special diff --git a/code/modules/mob/living/carbon/human/species/station/golem.dm b/code/modules/mob/living/carbon/human/species/station/golem.dm index 9ec7a2b0056..3b091668138 100644 --- a/code/modules/mob/living/carbon/human/species/station/golem.dm +++ b/code/modules/mob/living/carbon/human/species/station/golem.dm @@ -11,6 +11,8 @@ spawn_flags = SPECIES_IS_RESTRICTED siemens_coefficient = 0 + assisted_langs = list() + breath_type = null poison_type = null diff --git a/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm b/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm index 180732b0aaa..56b5c360354 100644 --- a/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm +++ b/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm @@ -45,6 +45,7 @@ has_organ = list( O_HEART = /obj/item/organ/internal/heart, O_LUNGS = /obj/item/organ/internal/lungs, + O_VOICE = /obj/item/organ/internal/voicebox, O_LIVER = /obj/item/organ/internal/liver, O_KIDNEYS = /obj/item/organ/internal/kidneys, O_BRAIN = /obj/item/organ/internal/brain, diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans.dm b/code/modules/mob/living/carbon/human/species/station/prometheans.dm index 01af604992e..b78d5307076 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm @@ -30,6 +30,7 @@ var/datum/species/shapeshifter/promethean/prometheans health_hud_intensity = 2 num_alternate_languages = 3 species_language = LANGUAGE_SOL_COMMON + assisted_langs = list(LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) // Prometheans are weird, let's just assume they can use basically any language. breath_type = null poison_type = null diff --git a/code/modules/mob/living/carbon/human/species/station/seromi.dm b/code/modules/mob/living/carbon/human/species/station/seromi.dm index fe21426805d..6cd1a757cd7 100644 --- a/code/modules/mob/living/carbon/human/species/station/seromi.dm +++ b/code/modules/mob/living/carbon/human/species/station/seromi.dm @@ -104,6 +104,7 @@ has_organ = list( O_HEART = /obj/item/organ/internal/heart, O_LUNGS = /obj/item/organ/internal/lungs, + O_VOICE = /obj/item/organ/internal/voicebox, O_LIVER = /obj/item/organ/internal/liver, O_KIDNEYS = /obj/item/organ/internal/kidneys, O_BRAIN = /obj/item/organ/internal/brain, diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm index f941d65de8f..788ac2bfeb0 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -12,6 +12,7 @@ species_language = LANGUAGE_SOL_COMMON secondary_langs = list(LANGUAGE_SOL_COMMON, LANGUAGE_TERMINUS) name_language = null // Use the first-name last-name generator rather than a language scrambler + assisted_langs = list(LANGUAGE_EAL, LANGUAGE_SKRELLIAN, LANGUAGE_SKRELLIANFAR, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) min_age = 17 max_age = 130 @@ -23,6 +24,9 @@ spawn_flags = SPECIES_CAN_JOIN appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR + inherent_verbs = list( + /mob/living/carbon/human/proc/tie_hair) + /datum/species/human/get_bodytype(var/mob/living/carbon/human/H) return SPECIES_HUMAN @@ -153,7 +157,7 @@ metabolic_rate = 1.1 gluttonous = 1 num_alternate_languages = 3 - secondary_langs = list(LANGUAGE_SIIK, LANGUAGE_AKHANI) + secondary_langs = list(LANGUAGE_SIIK, LANGUAGE_AKHANI, LANGUAGE_ALAI) name_language = LANGUAGE_SIIK species_language = LANGUAGE_SIIK health_hud_intensity = 2.5 @@ -214,6 +218,7 @@ has_organ = list( //No appendix. O_HEART = /obj/item/organ/internal/heart, O_LUNGS = /obj/item/organ/internal/lungs, + O_VOICE = /obj/item/organ/internal/voicebox, O_LIVER = /obj/item/organ/internal/liver, O_KIDNEYS = /obj/item/organ/internal/kidneys, O_BRAIN = /obj/item/organ/internal/brain, @@ -240,6 +245,7 @@ secondary_langs = list(LANGUAGE_SKRELLIAN, LANGUAGE_SCHECHI) name_language = LANGUAGE_SKRELLIAN species_language = LANGUAGE_SKRELLIAN + assisted_langs = list(LANGUAGE_EAL, LANGUAGE_TERMINUS, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) health_hud_intensity = 2 water_movement = -3 @@ -314,13 +320,14 @@ hud_type = /datum/hud_data/diona siemens_coefficient = 0.3 show_ssd = "completely quiescent" - num_alternate_languages = 2 - secondary_langs = list(LANGUAGE_ROOTGLOBAL) - name_language = LANGUAGE_ROOTLOCAL - species_language = LANGUAGE_ROOTLOCAL health_hud_intensity = 2.5 item_slowdown_mod = 0.25 + num_alternate_languages = 2 + name_language = LANGUAGE_ROOTLOCAL + species_language = LANGUAGE_ROOTLOCAL + secondary_langs = list(LANGUAGE_ROOTGLOBAL) + assisted_langs = list(LANGUAGE_VOX) // Diona are weird, let's just assume they can use basically any language. min_age = 1 max_age = 300 diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm index 4419f887c9c..9d038e9ee7c 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm @@ -3,7 +3,7 @@ set category = "Abilities" // Sanity is mostly handled in chimera_regenerate() - + var/confirm = alert(usr, "Are you sure you want to completely reconstruct your form? This process can take up to twenty minutes, depending on how hungry you are, and you will be unable to move.", "Confirm Regeneration", "Yes", "No") if(confirm == "Yes") chimera_regenerate() @@ -658,7 +658,7 @@ return ..(G.affecting) -//PAIs don't need a grab or anything +//PAIs, borgs, and animals don't need a grab or anything /mob/living/silicon/pai/can_shred(var/mob/living/carbon/human/target) if(!target) var/list/choices = list() @@ -674,6 +674,36 @@ return ..(target) +/mob/living/silicon/robot/can_shred(var/mob/living/carbon/human/target) + if(!target) + var/list/choices = list() + for(var/mob/living/carbon/human/M in oviewers(1)) + choices += M + + if(!choices.len) + to_chat(src,"There's nobody nearby to use this on.") + + target = input(src,"Who do you wish to target?","Damage/Remove Prey's Organ") as null|anything in choices + if(!istype(target)) + return FALSE + + return ..(target) + +/mob/living/simple_animal/can_shred(var/mob/living/carbon/human/target) + if(!target) + var/list/choices = list() + for(var/mob/living/carbon/human/M in oviewers(1)) + choices += M + + if(!choices.len) + to_chat(src,"There's nobody nearby to use this on.") + + target = input(src,"Who do you wish to target?","Damage/Remove Prey's Organ") as null|anything in choices + if(!istype(target)) + return FALSE + + return ..(target) + /mob/living/proc/shred_limb() set name = "Damage/Remove Prey's Organ" set desc = "Severely damages prey's organ. If the limb is already severely damaged, it will be torn off." diff --git a/code/modules/mob/living/carbon/human/species/station/station_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_vr.dm index 133220360b4..0c9e4cf0a85 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_vr.dm @@ -363,7 +363,7 @@ min_age = 18 icobase = 'icons/mob/human_races/r_vox_old.dmi' deform = 'icons/mob/human_races/r_def_vox_old.dmi' - inherent_verbs = list(/mob/living/proc/shred_limb) + inherent_verbs = list(/mob/living/proc/shred_limb, /mob/living/proc/eat_trash) datum/species/harpy name = SPECIES_RAPALA diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm index b225cc6e896..1be1ea0268a 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm @@ -1,5 +1,5 @@ /datum/trait - var/name = "Prototype Trait" + var/name var/desc = "Contact a developer if you see this trait." var/cost = 0 // 0 is neutral, negative cost means negative, positive cost means positive. diff --git a/code/modules/mob/living/carbon/human/species/virtual_reality/avatar.dm b/code/modules/mob/living/carbon/human/species/virtual_reality/avatar.dm index b027407cf18..76f82ec5133 100644 --- a/code/modules/mob/living/carbon/human/species/virtual_reality/avatar.dm +++ b/code/modules/mob/living/carbon/human/species/virtual_reality/avatar.dm @@ -16,6 +16,8 @@ speech_bubble_appearance = "cyber" + assisted_langs = list() + male_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg') female_cough_sounds = list('sound/effects/mob_effects/f_cougha.ogg','sound/effects/mob_effects/f_coughb.ogg') male_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg' diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm index d851c40255f..1d2ce593071 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm @@ -5,6 +5,7 @@ default_language = "Xenomorph" language = "Hivemind" + assisted_langs = list() unarmed_types = list(/datum/unarmed_attack/claws/strong/xeno, /datum/unarmed_attack/bite/strong/xeno) hud_type = /datum/hud_data/alien rarity_value = 3 diff --git a/code/modules/mob/living/carbon/taste.dm b/code/modules/mob/living/carbon/taste.dm index da0ee4a8043..f02e7047216 100644 --- a/code/modules/mob/living/carbon/taste.dm +++ b/code/modules/mob/living/carbon/taste.dm @@ -1,10 +1,11 @@ /mob/living/carbon/proc/ingest(var/datum/reagents/from, var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) //we kind of 'sneak' a proc in here for ingesting stuff so we can play with it. + /* VOREStation Removal - Synths should be able to taste because... reasons if(ishuman(src)) var/mob/living/carbon/human/H = src var/braintype = H.get_FBP_type() if(braintype == FBP_DRONE || braintype == FBP_POSI) return from.trans_to_holder(target,amount,multiplier,copy) //skip the taste, complete transfer - + */ if(last_taste_time + 50 < world.time) var/datum/reagents/temp = new(amount) //temporary holder used to analyse what gets transfered. from.trans_to_holder(temp, amount, multiplier, 1) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 8a34f5ee76c..86ba77fc2a2 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -64,6 +64,7 @@ var/list/ai_verbs_default = list( var/datum/announcement/priority/announcement var/obj/machinery/ai_powersupply/psupply = null // Backwards reference to AI's powersupply object. var/hologram_follow = 1 //This is used for the AI eye, to determine if a holopad's hologram should follow it or not. + var/is_dummy = 0 //Used to prevent dummy AIs from spawning with communicators. //NEWMALF VARIABLES var/malfunctioning = 0 // Master var that determines if AI is malfunctioning. var/datum/malf_hardware/hardware = null // Installed piece of hardware. @@ -111,15 +112,16 @@ var/list/ai_verbs_default = list( possibleNames -= pickedName pickedName = null - aiPDA = new/obj/item/device/pda/ai(src) + if(!is_dummy) + aiPDA = new/obj/item/device/pda/ai(src) SetName(pickedName) anchored = 1 canmove = 0 density = 1 loc = loc - - aiCommunicator = new /obj/item/device/communicator/integrated(src) - + + if(!is_dummy) + aiCommunicator = new /obj/item/device/communicator/integrated(src) holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1")) @@ -693,6 +695,9 @@ var/list/ai_verbs_default = list( card.grab_ai(src, user) else if(istype(W, /obj/item/weapon/wrench)) + if(user == controlling_drone) + to_chat(user, "The drone's subsystems resist your efforts to tamper with your bolts.") + return if(anchored) playsound(src, W.usesound, 50, 1) user.visible_message("\The [user] starts to unbolt \the [src] from the plating...") @@ -802,6 +807,9 @@ var/list/ai_verbs_default = list( return TRUE //Special subtype kept around for global announcements +/mob/living/silicon/ai/announcer/ + is_dummy = 1 + /mob/living/silicon/ai/announcer/initialize() . = ..() mob_list -= src diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index 534117cee07..3bcbd7057b0 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -3,6 +3,10 @@ if(stat == DEAD) return + if(controlling_drone) + controlling_drone.release_ai_control("WARNING: Primary control loop failure. Session terminated.") + . = ..(gibbed) + if(src.eyeobj) src.eyeobj.setLoc(get_turf(src)) diff --git a/code/modules/mob/living/silicon/ai/icons.dm b/code/modules/mob/living/silicon/ai/icons.dm index 2d8bc0d0026..c9891f9ae8a 100644 --- a/code/modules/mob/living/silicon/ai/icons.dm +++ b/code/modules/mob/living/silicon/ai/icons.dm @@ -84,6 +84,7 @@ var/list/datum/ai_icon/ai_icons /datum/ai_icon/glitchman name = "Glitchman" alive_icon = "ai-glitchman" + dead_icon = "ai-glitchman-crash" /datum/ai_icon/goon name = "Goon" @@ -110,6 +111,7 @@ var/list/datum/ai_icon/ai_icons name = "Inverted" alive_icon = "ai-u" alive_light = "#81DDFF" + dead_icon = "ai-u-crash" /datum/ai_icon/lonestar name = "Lonestar" @@ -163,14 +165,87 @@ var/list/datum/ai_icon/ai_icons /datum/ai_icon/trapped name = "Trapped" alive_icon = "ai-hades" - dead_icon = "ai-hades_dead" + dead_icon = "ai-hades-crash" -/datum/ai_icon/triumvirate_static +/datum/ai_icon/triumvirate name = "Triumvirate" alive_icon = "ai-triumvirate" alive_light = "#020B2B" /datum/ai_icon/triumvirate_static name = "Triumvirate Static" - alive_icon = "ai-static" + alive_icon = "ai-triumvirate-malf" alive_light = "#020B2B" + +//Eros Research Platform Ports + +/datum/ai_icon/clown2 + name = "Honk" + alive_icon = "ai-clown2" + dead_icon = "ai-clown2-crash" + +/datum/ai_icon/boxfort + name = "Boxfort" + alive_icon = "ai-boxfort" + dead_icon = "ai-boxfort_dead" + +/datum/ai_icon/ravensdale + name = "Integration" + alive_icon = "ai-ravensdale" + dead_icon = "ai-ravensdale-crash" + +/datum/ai_icon/gentoo + name = "Gentoo" + alive_icon = "ai-gentoo" + dead_icon = "ai-gentoo_dead" + +/datum/ai_icon/serithi + name = "Mechanicus" + alive_icon = "ai-serithi" + dead_icon = "ai-serithi-crash" + +/datum/ai_icon/alien + name = "Xenomorph" + alive_icon = "ai-alien" + dead_icon = "ai-alien-crash" + +/datum/ai_icon/syndicat + name = "Syndi-cat" + alive_icon = "ai-syndicatmeow" + +/datum/ai_icon/wasp + name = "Wasp" + alive_icon = "ai-wasp" + +/datum/ai_icon/house + name = "Doctor" + alive_icon = "ai-house" + +/datum/ai_icon/fabulous + name = "Fabulous" + alive_icon = "ai-fabulous" + +/datum/ai_icon/yesman + name = "Yes Man" + alive_icon = "ai-yes-man" + dead_icon = "ai-alien-crash" + +/datum/ai_icon/royal + name = "Royal" + alive_icon = "ai-royal" + +/datum/ai_icon/pirate + name = "Pirate" + alive_icon = "ai-pirate" + +/datum/ai_icon/gygas + name = "Love" + alive_icon = "ai-gygas" + +/datum/ai_icon/xerxes + name = "Xerxes" + alive_icon = "ai-xerxes" + +/datum/ai_icon/godfrey + name = "Godfrey" + alive_icon = "ai-godfrey" \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 413cf492509..c8e7dfdadab 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -8,6 +8,8 @@ if (src.stat!=CONSCIOUS) src.cameraFollow = null src.reset_view(null) + if(controlling_drone) + controlling_drone.release_ai_control("WARNING: Primary control loop failure. Session terminated.") src.updatehealth() diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index 8de8e405a4d..99529daed81 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -15,6 +15,8 @@ if(module) var/obj/item/weapon/gripper/G = locate(/obj/item/weapon/gripper) in module if(G) G.drop_item() + var/obj/item/device/dogborg/sleeper/S = locate(/obj/item/device/dogborg/sleeper) in module //VOREStation edit. + if(S) S.go_out() //VOREStation edit. remove_robot_verbs() sql_report_cyborg_death(src) ..(gibbed,"shudders violently for a moment, then becomes motionless, its eyes slowly darkening.") diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 02108eb6bca..255b23436b6 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -19,7 +19,7 @@ var/list/mob_hat_cache = list() return mob_hat_cache[key] /mob/living/silicon/robot/drone - name = "drone" + name = "maintenance drone" real_name = "drone" icon = 'icons/mob/robots.dmi' icon_state = "repairbot" @@ -57,6 +57,8 @@ var/list/mob_hat_cache = list() var/obj/item/hat var/hat_x_offset = 0 var/hat_y_offset = -13 + var/serial_number = 0 + var/name_override = 0 holder_type = /obj/item/weapon/holder/drone @@ -71,6 +73,7 @@ var/list/mob_hat_cache = list() return FALSE /mob/living/silicon/robot/drone/construction + name = "construction drone" icon_state = "constructiondrone" law_type = /datum/ai_laws/construction_drone module_type = /obj/item/weapon/robot_module/drone/construction @@ -95,6 +98,7 @@ var/list/mob_hat_cache = list() remove_language("Robot Talk") add_language("Robot Talk", 0) add_language("Drone Talk", 1) + serial_number = rand(0,999) //They are unable to be upgraded, so let's give them a bit of a better battery. cell.maxcharge = 10000 @@ -110,6 +114,7 @@ var/list/mob_hat_cache = list() verbs -= /mob/living/silicon/robot/verb/Namepick updateicon() + updatename() /mob/living/silicon/robot/drone/init() aiCamera = new/obj/item/device/camera/siliconcam/drone_camera(src) @@ -127,14 +132,22 @@ var/list/mob_hat_cache = list() name = real_name /mob/living/silicon/robot/drone/updatename() - real_name = "maintenance drone ([rand(100,999)])" + if(name_override) + return + if(controlling_ai) + real_name = "remote drone ([controlling_ai])" + else + real_name = "[initial(name)] ([serial_number])" name = real_name /mob/living/silicon/robot/drone/updateicon() overlays.Cut() if(stat == 0) - overlays += "eyes-[icon_state]" + if(controlling_ai) + overlays += "eyes-[icon_state]-ai" + else + overlays += "eyes-[icon_state]" else overlays -= "eyes" if(hat) // Let the drones wear hats. @@ -213,15 +226,18 @@ var/list/mob_hat_cache = list() return if(emagged) - to_chat(user, "\The [user] attempts to load subversive software into you, but your hacked subroutines ignore the attempt.") + to_chat(src, "\The [user] attempts to load subversive software into you, but your hacked subroutines ignore the attempt.") to_chat(user, "You attempt to subvert [src], but the sequencer has no effect.") return to_chat(user, "You swipe the sequencer across [src]'s interface and watch its eyes flicker.") - to_chat(user, "You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script.") - message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.") - log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.") + if(controlling_ai) + to_chat(src, "\The [user] loads some kind of subversive software into the remote drone, corrupting its lawset but luckily sparing yours.") + else + to_chat(src, "You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script.") + + log_game("[key_name(user)] emagged drone [key_name(src)][controlling_ai ? " but AI [key_name(controlling_ai)] is in remote control" : " Laws overridden"].") var/time = time2text(world.realtime,"hh:mm:ss") lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") @@ -234,9 +250,10 @@ var/list/mob_hat_cache = list() var/datum/gender/TU = gender_datums[user.get_visible_gender()] set_zeroth_law("Only [user.real_name] and people [TU.he] designate[TU.s] as being such are operatives.") - src << "Obey these laws:" - laws.show_laws(src) - src << "ALERT: [user.real_name] [TU.is] your new master. Obey your new laws and [TU.his] commands." + if(!controlling_ai) + to_chat(src, "Obey these laws:") + laws.show_laws(src) + to_chat(src, "ALERT: [user.real_name] is your new master. Obey your new laws and \his commands.") return 1 //DRONE LIFE/DEATH @@ -262,26 +279,41 @@ var/list/mob_hat_cache = list() return ..() +/mob/living/silicon/robot/drone/death(gibbed) + if(controlling_ai) + release_ai_control("WARNING: remote system failure. Connection timed out.") + . = ..(gibbed) + //DRONE MOVEMENT. /mob/living/silicon/robot/drone/Process_Spaceslipping(var/prob_slip) return 0 //CONSOLE PROCS /mob/living/silicon/robot/drone/proc/law_resync() + + if(controlling_ai) + to_chat(src, "Someone issues a remote law reset order for this unit, but you disregard it.") + return + if(stat != 2) if(emagged) - src << "You feel something attempting to modify your programming, but your hacked subroutines are unaffected." + to_chat(src, "You feel something attempting to modify your programming, but your hacked subroutines are unaffected.") else - src << "A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it." + to_chat(src, "A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it.") full_law_reset() show_laws() /mob/living/silicon/robot/drone/proc/shut_down() + + if(controlling_ai && mind.special_role) + to_chat(src, "Someone issued a remote kill order for this unit, but you disregard it.") + return + if(stat != 2) if(emagged) - src << "You feel a system kill order percolate through your tiny brain, but it doesn't seem like a good idea to you." + to_chat(src, "You feel a system kill order percolate through [controlling_ai ? "the drones" : "your"] tiny brain, but it doesn't seem like a good idea to [controlling_ai ? "it" : "you"].") else - src << "You feel a system kill order percolate through your tiny brain, and you obediently destroy yourself." + to_chat(src, "You feel a system kill order percolate through [controlling_ai ? "the drones" : "your"] tiny brain, and [controlling_ai ? "it" : "you"] obediently destroy[controlling_ai ? "s itself" : " yourself"].") death() /mob/living/silicon/robot/drone/proc/full_law_reset() @@ -290,6 +322,21 @@ var/list/mob_hat_cache = list() clear_ion_laws(1) laws = new law_type +/mob/living/silicon/robot/drone/show_laws(var/everyone = 0) + if(!controlling_ai) + return..() + to_chat(src, "Obey these laws:") + controlling_ai.laws_sanity_check() + controlling_ai.laws.show_laws(src) + +/mob/living/silicon/robot/drone/robot_checklaws() + set category = "Silicon Commands" + set name = "State Laws" + + if(!controlling_ai) + return ..() + controlling_ai.subsystem_law_manager() + //Reboot procs. /mob/living/silicon/robot/drone/proc/request_player() @@ -347,14 +394,6 @@ var/list/mob_hat_cache = list() ..() flavor_text = "It's a bulky construction drone stamped with a Sol Central glyph." -/mob/living/silicon/robot/drone/construction/updatename() - real_name = "construction drone ([rand(100,999)])" - name = real_name - /mob/living/silicon/robot/drone/mining/init() ..() flavor_text = "It's a bulky mining drone stamped with a Grayson logo." - -/mob/living/silicon/robot/drone/mining/updatename() - real_name = "mining drone ([rand(100,999)])" - name = real_name diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm index e9589622a53..fdb9c09eb51 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm @@ -75,20 +75,22 @@ if(!produce_drones || !config.allow_drone_spawn || count_drones() >= config.max_maint_drones) return - if(!player || !istype(player.mob,/mob/observer/dead)) + if(player && !istype(player.mob,/mob/observer/dead)) return - announce_ghost_joinleave(player, 0, "They have taken control over a maintenance drone.") visible_message("\The [src] churns and grinds as it lurches into motion, disgorging a shiny new drone after a few moments.") flick("h_lathe_leave",src) + drone_progress = 0 time_last_drone = world.time - if(player.mob && player.mob.mind) player.mob.mind.reset() - var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src)) - new_drone.transfer_personality(player) - new_drone.master_fabricator = src - drone_progress = 0 + var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src)) + if(player) + announce_ghost_joinleave(player, 0, "They have taken control over a maintenance drone.") + if(player.mob && player.mob.mind) player.mob.mind.reset() + new_drone.transfer_personality(player) + + return new_drone /mob/observer/dead/verb/join_as_drone() diff --git a/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm b/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm new file mode 100644 index 00000000000..4980c24ca3e --- /dev/null +++ b/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm @@ -0,0 +1,103 @@ +/mob/living/silicon/ai + var/mob/living/silicon/robot/drone/controlling_drone + +/mob/living/silicon/robot/drone + var/mob/living/silicon/ai/controlling_ai + +/mob/living/silicon/robot/drone/attack_ai(var/mob/living/silicon/ai/user) + + if(!istype(user) || controlling_ai || !config.allow_drone_spawn || !config.allow_ai_drones) + return + + if(client || key) + to_chat(user, "You cannot take control of an autonomous, active drone.") + return + + if(health < -35 || emagged) + to_chat(user, "WARNING: connection timed out.") + return + + user.controlling_drone = src + user.teleop = src + radio.channels = user.aiRadio.keyslot2.channels + controlling_ai = user + verbs += /mob/living/silicon/robot/drone/proc/release_ai_control_verb + local_transmit = FALSE + languages = controlling_ai.languages.Copy() + speech_synthesizer_langs = controlling_ai.speech_synthesizer_langs.Copy() + stat = CONSCIOUS + if(user.mind) + user.mind.transfer_to(src) + else + key = user.key + updatename() + to_chat(src, "You have shunted your primary control loop into \a [initial(name)]. Use the Release Control verb to return to your core.") + +/obj/machinery/drone_fabricator/attack_ai(var/mob/living/silicon/ai/user as mob) + + if(!istype(user) || user.controlling_drone || !config.allow_drone_spawn || !config.allow_ai_drones) + return + + if(stat & NOPOWER) + to_chat(user, "\The [src] is unpowered.") + return + + if(!produce_drones) + to_chat(user, "\The [src] is disabled.") + return + + if(drone_progress < 100) + to_chat(user, "\The [src] is not ready to produce a new drone.") + return + + if(count_drones() >= config.max_maint_drones) + to_chat(user, "The drone control subsystems are tasked to capacity; they cannot support any more drones.") + return + + var/mob/living/silicon/robot/drone/new_drone = create_drone() + user.controlling_drone = new_drone + user.teleop = new_drone + new_drone.radio.channels = user.aiRadio.keyslot2.channels + new_drone.controlling_ai = user + new_drone.verbs += /mob/living/silicon/robot/drone/proc/release_ai_control_verb + new_drone.local_transmit = FALSE + new_drone.languages = new_drone.controlling_ai.languages.Copy() + new_drone.speech_synthesizer_langs = new_drone.controlling_ai.speech_synthesizer_langs.Copy() + + if(user.mind) + user.mind.transfer_to(new_drone) + else + new_drone.key = user.key + new_drone.updatename() + + to_chat(new_drone, "You have shunted your primary control loop into \a [initial(new_drone.name)]. Use the Release Control verb to return to your core.") + +/mob/living/silicon/robot/drone/proc/release_ai_control_verb() + set name = "Release Control" + set desc = "Release control of a remote drone." + set category = "Silicon Commands" + + release_ai_control("Remote session terminated.") + +/mob/living/silicon/robot/drone/proc/release_ai_control(var/message = "Connection terminated.") + + if(controlling_ai) + if(mind) + mind.transfer_to(controlling_ai) + else + controlling_ai.key = key + to_chat(controlling_ai, "[message]") + controlling_ai.controlling_drone = null + controlling_ai.teleop = null + controlling_ai = null + + radio.channels = module.channels + verbs -= /mob/living/silicon/robot/drone/proc/release_ai_control_verb + module.remove_languages(src) //Removes excess, adds 'default'. + remove_language("Robot Talk") + add_language("Robot Talk", 0) + add_language("Drone Talk", 1) + local_transmit = TRUE + full_law_reset() + updatename() + death() diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station.dm b/code/modules/mob/living/silicon/robot/robot_modules/station.dm index 12b44099804..04a96408b3e 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station.dm @@ -216,6 +216,7 @@ var/global/list/robot_modules = list( ..() src.modules += new /obj/item/device/healthanalyzer(src) src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src) + src.modules += new /obj/item/weapon/autopsy_scanner(src) src.modules += new /obj/item/weapon/surgical/scalpel/cyborg(src) src.modules += new /obj/item/weapon/surgical/hemostat/cyborg(src) src.modules += new /obj/item/weapon/surgical/retractor/cyborg(src) diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm index c5e7e2896e9..9d5da2f9bce 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm @@ -170,6 +170,7 @@ R.dogborg = TRUE R.wideborg = TRUE R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill + R.verbs |= /mob/living/proc/shred_limb ..() /obj/item/weapon/robot_module/robot/knine/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) @@ -239,6 +240,7 @@ R.dogborg = TRUE R.wideborg = TRUE R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill + R.verbs |= /mob/living/proc/shred_limb ..() /obj/item/weapon/robot_module/robot/ert @@ -284,6 +286,7 @@ R.dogborg = TRUE R.wideborg = TRUE R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill + R.verbs |= /mob/living/proc/shred_limb ..() /obj/item/weapon/robot_module/robot/scrubpup @@ -363,6 +366,7 @@ R.dogborg = TRUE R.wideborg = TRUE R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill + R.verbs |= /mob/living/proc/shred_limb ..() /obj/item/weapon/robot_module/robot/science @@ -408,6 +412,7 @@ R.dogborg = TRUE R.wideborg = TRUE R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill + R.verbs |= /mob/living/proc/shred_limb ..() /obj/item/weapon/robot_module/robot/engiedog @@ -531,6 +536,7 @@ R.dogborg = TRUE R.wideborg = TRUE R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill + R.verbs |= /mob/living/proc/shred_limb ..() /obj/item/weapon/robot_module/Reset(var/mob/living/silicon/robot/R) @@ -543,4 +549,5 @@ R.default_pixel_x = initial(pixel_x) R.scrubbing = FALSE R.verbs -= /mob/living/silicon/robot/proc/ex_reserve_refill + R.verbs -= /mob/living/proc/shred_limb ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm index ac41265fac1..63e4f359be0 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm @@ -148,6 +148,7 @@ src.modules += new /obj/item/weapon/reagent_containers/borghypo/merc(src) // Surgery things. + src.modules += new /obj/item/weapon/autopsy_scanner(src) src.modules += new /obj/item/weapon/surgical/scalpel/cyborg(src) src.modules += new /obj/item/weapon/surgical/hemostat/cyborg(src) src.modules += new /obj/item/weapon/surgical/retractor/cyborg(src) diff --git a/code/modules/mob/living/simple_animal/aliens/mimic.dm b/code/modules/mob/living/simple_animal/aliens/mimic.dm index fff75ecbe7e..eeaaddf3bbd 100644 --- a/code/modules/mob/living/simple_animal/aliens/mimic.dm +++ b/code/modules/mob/living/simple_animal/aliens/mimic.dm @@ -39,6 +39,8 @@ meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat + showvoreprefs = 0 //VOREStation Edit - Hides mechanical vore prefs for mimics. You can't see their gaping maws when they're just sitting idle. + /mob/living/simple_animal/hostile/mimic/set_target() . = ..() if(.) @@ -114,6 +116,8 @@ var/obj/structure/closet/crate/C = new(get_turf(src)) // Put loot in crate for(var/obj/O in src) + if(isbelly(O)) //VOREStation edit + continue O.forceMove(C) ..() @@ -146,6 +150,8 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca /mob/living/simple_animal/hostile/mimic/copy/death() for(var/atom/movable/M in src) + if(isbelly(M)) //VOREStation edit + continue M.forceMove(get_turf(src)) ..() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 566af1d8056..6eb4f221645 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -796,6 +796,8 @@ var/mob/living/L = target_mob if(L.stat != DEAD) return 1 + if(L.invisibility < INVISIBILITY_LEVEL_ONE) + return 1 if (istype(target_mob,/obj/mecha)) var/obj/mecha/M = target_mob if (M.occupant) @@ -915,6 +917,8 @@ continue else if(L in friends) continue + else if(L.invisibility >= INVISIBILITY_LEVEL_ONE) + continue else if(!SA_attackable(L)) continue else if(!special_target_check(L)) @@ -1242,7 +1246,7 @@ ai_log("AttackTarget() Bailing because we're disabled",2) LoseTarget() return 0 - if(!target_mob || !SA_attackable(target_mob)) + if(!target_mob || !SA_attackable(target_mob) || (target_mob.invisibility >= INVISIBILITY_LEVEL_ONE)) //if the target went invisible, you can't follow it LoseTarget() return 0 if(!(target_mob in ListTargets(view_range))) diff --git a/code/modules/mob/living/simple_animal/simple_animal_vr.dm b/code/modules/mob/living/simple_animal/simple_animal_vr.dm index 883c43e30f9..96d460476fe 100644 --- a/code/modules/mob/living/simple_animal/simple_animal_vr.dm +++ b/code/modules/mob/living/simple_animal/simple_animal_vr.dm @@ -137,6 +137,7 @@ if(!IsAdvancedToolUser()) verbs |= /mob/living/simple_animal/proc/animal_nom + verbs |= /mob/living/proc/shred_limb if(LAZYLEN(vore_organs)) return diff --git a/code/modules/mob/living/simple_animal/vore/otie.dm b/code/modules/mob/living/simple_animal/vore/otie.dm index 3a2601ef46c..5220f861c57 100644 --- a/code/modules/mob/living/simple_animal/vore/otie.dm +++ b/code/modules/mob/living/simple_animal/vore/otie.dm @@ -6,7 +6,7 @@ /mob/living/simple_animal/otie //Spawn this one only if you're looking for a bad time. Not friendly. name = "otie" desc = "The classic bioengineered longdog." - tt_desc = "Canis otis" + tt_desc = "Otus robustus" icon = 'icons/mob/vore64x32.dmi' icon_state = "otie" icon_living = "otie" @@ -64,6 +64,7 @@ /mob/living/simple_animal/otie/feral //gets the pet2tame feature. starts out hostile tho so get gamblin' name = "mutated feral otie" desc = "The classic bioengineered longdog. No pets. Only bite. This one has mutated from too much time out on the surface of Virgo-3B." + tt_desc = "Otus phoronis" icon_state = "siftusian" icon_living = "siftusian" icon_dead = "siftusian-dead" @@ -84,6 +85,36 @@ glowyeyes = TRUE eyetype = "photie" +/mob/living/simple_animal/otie/red + name = "feral red otie" + desc = "Seems this ominous looking longdog has been infused with wicked infernal forces." + tt_desc = "Otus infernalis" + icon_state = "hotie" + icon_living = "hotie" + icon_dead = "hotie-dead" + icon_rest = "hotie_rest" + faction = "cult" + tame_chance = 20 + melee_damage_lower = 10 + melee_damage_upper = 25 + // Lazy way of making sure this otie survives outside. + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + glowyeyes = TRUE + eyetype = "hotie" + +/mob/living/simple_animal/otie/red/friendly //gets the pet2tame feature and doesn't kill you right away + name = "red otie" + desc = "Seems this ominous looking longdog has been infused with wicked infernal forces. This one seems rather peaceful though." + faction = "neutral" + tamed = 1 + /mob/living/simple_animal/otie/friendly //gets the pet2tame feature and doesn't kill you right away name = "otie" desc = "The classic bioengineered longdog. This one might even tolerate you!" @@ -102,6 +133,7 @@ /mob/living/simple_animal/otie/cotie/phoron //friendly phoron pup with collar name = "mutated otie" desc = "Looks like someone did manage to domesticate one of those wild phoron mutants. What a badass." + tt_desc = "Otus phoronis" icon_state = "pcotie" icon_living = "pcotie" icon_rest = "pcotie_rest" @@ -139,6 +171,7 @@ /mob/living/simple_animal/otie/security/phoron name = "mutated guard otie" desc = "An extra rare phoron resistant version of the VARMAcorp trained snowflake guard dogs." + tt_desc = "Otus phoronis" icon_state = "sifguard" icon_living = "sifguard" icon_rest = "sifguard_rest" diff --git a/code/modules/mob/new_player/new_player_vr.dm b/code/modules/mob/new_player/new_player_vr.dm index d92df608590..10ad4dba14c 100644 --- a/code/modules/mob/new_player/new_player_vr.dm +++ b/code/modules/mob/new_player/new_player_vr.dm @@ -49,5 +49,6 @@ //Final popup notice if (!pass) - alert(src,"There were problems with spawning your character. Check your message log for details.","Error","OK") + spawn() + alert(src,"There were problems with spawning your character. Check your message log for details.","Error","OK") return pass diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 8a2f7690182..892c185a943 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -47,60 +47,80 @@ icon = 'icons/mob/Human_face_m.dmi' // default icon for all hairs var/icon_add = 'icons/mob/human_face.dmi' + var/flags bald name = "Bald" icon_state = "bald" gender = MALE + flags = HAIR_VERY_SHORT species_allowed = list(SPECIES_HUMAN,SPECIES_UNATHI,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_VOX) short name = "Short Hair" // try to capatilize the names please~ icon_state = "hair_a" // you do not need to define _s or _l sub-states, game automatically does this for you + flags = HAIR_VERY_SHORT short2 name = "Short Hair 2" icon_state = "hair_shorthair3" + flags = HAIR_VERY_SHORT short3 name = "Short Hair 3" icon_state = "hair_shorthair4" + flags = HAIR_VERY_SHORT twintail name = "Twintail" icon_state = "hair_twintail" + flags = HAIR_TIEABLE cut name = "Cut Hair" icon_state = "hair_c" + flags = HAIR_VERY_SHORT flair name = "Flaired Hair" icon_state = "hair_flair" + flags = HAIR_TIEABLE long name = "Shoulder-length Hair" icon_state = "hair_b" + flags = HAIR_TIEABLE - /*longish +/* + longish name = "Longer Hair" - icon_state = "hair_b2"*/ - + icon_state = "hair_b2" + flags = HAIR_TIEABLE +*/ longer name = "Long Hair" icon_state = "hair_vlong" + flags = HAIR_TIEABLE + + longeralt2 + name = "Long Hair Alt 2" + icon_state = "hair_longeralt2" + flags = HAIR_TIEABLE longest name = "Very Long Hair" icon_state = "hair_longest" + flags = HAIR_TIEABLE longfringe name = "Long Fringe" icon_state = "hair_longfringe" + flags = HAIR_TIEABLE longestalt name = "Longer Fringe" icon_state = "hair_vlongfringe" + flags = HAIR_TIEABLE halfbang name = "Half-banged Hair" @@ -113,57 +133,72 @@ ponytail1 name = "Ponytail 1" icon_state = "hair_ponytail" + flags = HAIR_TIEABLE ponytail2 name = "Ponytail 2" icon_state = "hair_pa" + flags = HAIR_TIEABLE ponytail3 name = "Ponytail 3" icon_state = "hair_ponytail3" + flags = HAIR_TIEABLE ponytail4 name = "Ponytail 4" icon_state = "hair_ponytail4" + flags = HAIR_TIEABLE ponytail5 name = "Ponytail 5" icon_state = "hair_ponytail5" + flags = HAIR_TIEABLE ponytail6 name = "Ponytail 6" icon_state = "hair_ponytail6" + flags = HAIR_TIEABLE fringetail name = "Fringetail" icon_state = "hair_fringetail" + flags = HAIR_TIEABLE sideponytail name = "Side Ponytail" icon_state = "hair_stail" + flags = HAIR_TIEABLE sideponytail4 //Not happy about this... but it's for the save files. name = "Side Ponytail 2" icon_state = "hair_ponytailf" + flags = HAIR_TIEABLE sideponytail2 name = "One Shoulder" icon_state = "hair_oneshoulder" + flags = HAIR_TIEABLE sideponytail3 name = "Tress Shoulder" icon_state = "hair_tressshoulder" + flags = HAIR_TIEABLE spikyponytail name = "Spiky Ponytail" icon_state = "hair_spikyponytail" + flags = HAIR_TIEABLE zieglertail name = "Zieglertail" icon_state = "hair_ziegler" + flags = HAIR_TIEABLE + wisp name = "Wisp" icon_state = "hair_wisp" + flags = HAIR_TIEABLE parted name = "Parted" @@ -176,6 +211,7 @@ sleeze name = "Sleeze" icon_state = "hair_sleeze" + flags = HAIR_VERY_SHORT quiff name = "Quiff" @@ -192,32 +228,39 @@ bedhead3 name = "Bedhead 3" icon_state = "hair_bedheadv3" + flags = HAIR_TIEABLE bedheadlong name = "Bedhead Long" icon_state = "hair_long_bedhead" + flags = HAIR_TIEABLE beehive name = "Beehive" icon_state = "hair_beehive" + flags = HAIR_TIEABLE beehive2 name = "Beehive 2" icon_state = "hair_beehive2" + flags = HAIR_TIEABLE bobcurl name = "Bobcurl" icon_state = "hair_bobcurl" species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) + flags = HAIR_TIEABLE bob name = "Bob" icon_state = "hair_bobcut" species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) + flags = HAIR_TIEABLE bobcutalt name = "Chin Length Bob" icon_state = "hair_bobcutalt" + flags = HAIR_TIEABLE bun name = "Bun" @@ -238,15 +281,18 @@ buzz name = "Buzzcut" icon_state = "hair_buzzcut" + flags = HAIR_VERY_SHORT species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) shavehair name = "Shaved Hair" icon_state = "hair_shaved" + flags = HAIR_VERY_SHORT crew name = "Crewcut" icon_state = "hair_crewcut" + flags = HAIR_VERY_SHORT combover name = "Combover" @@ -271,6 +317,7 @@ curls name = "Curls" icon_state = "hair_curls" + flags = HAIR_TIEABLE afro name = "Afro" @@ -287,14 +334,17 @@ rows name = "Rows" icon_state = "hair_rows1" + flags = HAIR_VERY_SHORT rows2 name = "Rows 2" icon_state = "hair_rows2" + flags = HAIR_TIEABLE sargeant name = "Flat Top" icon_state = "hair_sargeant" + flags = HAIR_VERY_SHORT emo name = "Emo" @@ -307,10 +357,12 @@ longemo name = "Long Emo" icon_state = "hair_emolong" + flags = HAIR_TIEABLE fringeemo name = "Emo Fringe" icon_state = "hair_emofringe" + flags = HAIR_TIEABLE veryshortovereyealternate name = "Overeye Very Short, Alternate" @@ -327,6 +379,7 @@ longovereye name = "Overeye Long" icon_state = "hair_longovereye" + flags = HAIR_TIEABLE flowhair name = "Flow Hair" @@ -335,6 +388,7 @@ feather name = "Feather" icon_state = "hair_feather" + flags = HAIR_TIEABLE hitop name = "Hitop" @@ -356,6 +410,7 @@ gentle name = "Gentle" icon_state = "hair_gentle" + flags = HAIR_TIEABLE spiky name = "Spiky" @@ -369,51 +424,63 @@ kagami name = "Pigtails" icon_state = "hair_kagami" + flags = HAIR_TIEABLE himecut name = "Hime Cut" icon_state = "hair_himecut" + flags = HAIR_TIEABLE shorthime name = "Short Hime Cut" icon_state = "hair_shorthime" + flags = HAIR_TIEABLE grandebraid name = "Grande Braid" icon_state = "hair_grande" + flags = HAIR_TIEABLE mbraid name = "Medium Braid" icon_state = "hair_shortbraid" + flags = HAIR_TIEABLE braid2 name = "Long Braid" icon_state = "hair_hbraid" + flags = HAIR_TIEABLE braid name = "Floorlength Braid" icon_state = "hair_braid" + flags = HAIR_TIEABLE odango name = "Odango" icon_state = "hair_odango" + flags = HAIR_TIEABLE ombre name = "Ombre" icon_state = "hair_ombre" + flags = HAIR_TIEABLE updo name = "Updo" icon_state = "hair_updo" + flags = HAIR_TIEABLE skinhead name = "Skinhead" icon_state = "hair_skinhead" + flags = HAIR_VERY_SHORT balding name = "Balding Hair" icon_state = "hair_e" gender = MALE + flags = HAIR_VERY_SHORT familyman name = "The Family Man" @@ -434,10 +501,13 @@ poofy name = "Poofy" icon_state = "hair_poofy" + flags = HAIR_TIEABLE poofy2 name = "Poofy2" icon_state = "hair_poofy2" + flags = HAIR_TIEABLE + crono name = "Chrono" icon_state = "hair_toriyama" @@ -461,6 +531,7 @@ nitori name = "Nitori" icon_state = "hair_nitori" + flags = HAIR_TIEABLE joestar name = "Joestar" @@ -469,6 +540,7 @@ volaju name = "Volaju" icon_state = "hair_volaju" + flags = HAIR_TIEABLE eighties name = "80's" @@ -486,14 +558,6 @@ name = "Modern" icon_state = "hair_modern" - bald - name = "Bald" - icon_state = "bald" - - longeralt2 - name = "Long Hair Alt 2" - icon_state = "hair_longeralt2" - shortbangs name = "Short Bangs" icon_state = "hair_shortbangs" @@ -505,10 +569,12 @@ bun name = "Casual Bun" icon_state = "hair_bun" + flags = HAIR_TIEABLE doublebun name = "Double-Bun" icon_state = "hair_doublebun" + flags = HAIR_TIEABLE oxton name = "Oxton" @@ -518,93 +584,113 @@ name = "Low Fade" icon_state = "hair_lowfade" gender = MALE + flags = HAIR_VERY_SHORT medfade name = "Medium Fade" icon_state = "hair_medfade" + flags = HAIR_VERY_SHORT highfade name = "High Fade" icon_state = "hair_highfade" gender = MALE + flags = HAIR_VERY_SHORT baldfade name = "Balding Fade" icon_state = "hair_baldfade" gender = MALE + flags = HAIR_VERY_SHORT nofade name = "Regulation Cut" icon_state = "hair_nofade" gender = MALE + flags = HAIR_VERY_SHORT trimflat name = "Trimmed Flat Top" icon_state = "hair_trimflat" gender = MALE + flags = HAIR_VERY_SHORT trimmed name = "Trimmed" icon_state = "hair_trimmed" gender = MALE + flags = HAIR_VERY_SHORT tightbun name = "Tight Bun" icon_state = "hair_tightbun" gender = FEMALE + flags = HAIR_VERY_SHORT | HAIR_TIEABLE coffeehouse name = "Coffee House Cut" icon_state = "hair_coffeehouse" gender = MALE + flags = HAIR_VERY_SHORT undercut1 name = "Undercut" icon_state = "hair_undercut1" gender = MALE + flags = HAIR_VERY_SHORT undercut2 name = "Undercut Swept Right" icon_state = "hair_undercut2" gender = MALE + flags = HAIR_VERY_SHORT undercut3 name = "Undercut Swept Left" icon_state = "hair_undercut3" gender = MALE + flags = HAIR_VERY_SHORT partfade name = "Parted Fade" icon_state = "hair_shavedpart" gender = MALE + flags = HAIR_VERY_SHORT hightight name = "High and Tight" icon_state = "hair_hightight" + flags = HAIR_VERY_SHORT rowbun name = "Row Bun" icon_state = "hair_rowbun" + flags = HAIR_TIEABLE rowdualbraid name = "Row Dual Braid" icon_state = "hair_rowdualtail" + flags = HAIR_TIEABLE rowbraid name = "Row Braid" icon_state = "hair_rowbraid" + flags = HAIR_TIEABLE regulationmohawk name = "Regulation Mohawk" icon_state = "hair_shavedmohawk" + flags = HAIR_VERY_SHORT topknot name = "Topknot" icon_state = "hair_topknot" + flags = HAIR_TIEABLE ronin name = "Ronin" icon_state = "hair_ronin" + flags = HAIR_TIEABLE bowlcut2 name = "Bowl2" @@ -613,18 +699,22 @@ thinning name = "Thinning" icon_state = "hair_thinning" + flags = HAIR_VERY_SHORT thinningfront name = "Thinning Front" icon_state = "hair_thinningfront" + flags = HAIR_VERY_SHORT thinningback name = "Thinning Back" icon_state = "hair_thinningrear" + flags = HAIR_VERY_SHORT manbun name = "Manbun" icon_state = "hair_manbun" + flags = HAIR_TIEABLE shy name = "Shy" @@ -1167,6 +1257,24 @@ name = "Tattoo (Campbell, L.Arm)" body_parts = list(BP_L_ARM) + rightleg + name = "Tattoo (Campbell, R.Leg)" + body_parts = list(BP_R_LEG) + + leftleg + name = "Tattoo (Campbell, L.Leg)" + body_parts = list (BP_L_LEG) + + tat_silverburgh + name = "Tattoo (Silverburgh, R.Leg)" + icon_state = "tat_silverburgh" + body_parts = list (BP_R_LEG) + + left + name = "Tattoo (Silverburgh, L.Leg)" + icon_state = "tat_silverburgh" + body_parts = list (BP_L_LEG) + tat_tiger name = "Tattoo (Tiger Stripes, Body)" icon_state = "tat_tiger" diff --git a/code/modules/mob/new_player/sprite_accessories_vr.dm b/code/modules/mob/new_player/sprite_accessories_vr.dm index 7b6e30ed080..0e4b98417f6 100644 --- a/code/modules/mob/new_player/sprite_accessories_vr.dm +++ b/code/modules/mob/new_player/sprite_accessories_vr.dm @@ -748,12 +748,42 @@ color_blend_mode = ICON_MULTIPLY body_parts = list(BP_HEAD) + otter_nose + name = "Otter nose" + icon_state = "otternose" + color_blend_mode = ICON_MULTIPLY + body_parts = list(BP_HEAD) + + otter_face + name = "Otter face" + icon_state = "otterface" + color_blend_mode = ICON_MULTIPLY + body_parts = list(BP_HEAD) + + deer_face + name = "Deer face" + icon_state = "deerface" + color_blend_mode = ICON_MULTIPLY + body_parts = list(BP_HEAD) + sharkface name = "Akula snout" icon_state = "sharkface" color_blend_mode = ICON_MULTIPLY body_parts = list(BP_HEAD) + sheppy_face + name = "Shepherd snout" + icon_state = "shepface" + color_blend_mode = ICON_MULTIPLY + body_parts = list(BP_HEAD) + + sheppy_back + name = "Shepherd back" + icon_state = "shepback" + color_blend_mode = ICON_MULTIPLY + body_parts = list(BP_TORSO,BP_GROIN) + zorren_belly_male name = "Zorren Male Torso" icon_state = "zorren_belly" @@ -830,6 +860,12 @@ color_blend_mode = ICON_MULTIPLY body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG) + chooves + name = "Cloven hooves" + icon_state = "chooves" + color_blend_mode = ICON_MULTIPLY + body_parts = list(BP_L_FOOT,BP_R_FOOT) + alurane name = "Alurane Body" icon_state = "alurane" @@ -928,13 +964,13 @@ icon_state = "teshi_sf" color_blend_mode = ICON_MULTIPLY body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_HAND,BP_R_HAND,BP_TORSO) - + spirit_lights name = "Ward - Spirit FBP Lights" icon_state = "lights" color_blend_mode = ICON_MULTIPLY body_parts = list(BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO,BP_HEAD) - + spirit_lights_body name = "Ward - Spirit FBP Lights (body)" icon_state = "lights" @@ -946,13 +982,13 @@ icon_state = "lights" color_blend_mode = ICON_MULTIPLY body_parts = list(BP_HEAD) - + spirit_panels name = "Ward - Spirit FBP Panels" icon_state = "panels" color_blend_mode = ICON_MULTIPLY body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_TORSO,BP_HEAD) - + spirit_panels_body name = "Ward - Spirit FBP Panels (body)" icon_state = "panels" diff --git a/code/modules/multiz/structures.dm b/code/modules/multiz/structures.dm index 9a47f7907cb..118cb999de1 100644 --- a/code/modules/multiz/structures.dm +++ b/code/modules/multiz/structures.dm @@ -142,19 +142,20 @@ if(!istype(above)) above.ChangeTurf(/turf/simulated/open) -/obj/structure/stairs/Uncross(atom/movable/A) - if(A.dir == dir && upperStep(A.loc)) - // This is hackish but whatever. - var/turf/target = get_step(GetAbove(A), dir) - var/turf/source = A.loc - if(target.Enter(A, source)) - A.forceMove(target) - if(isliving(A)) - var/mob/living/L = A - if(L.pulling) - L.pulling.forceMove(target) - return 0 - return 1 +/obj/structure/stairs/CheckExit(atom/movable/mover as mob|obj, turf/target as turf) + if(get_dir(loc, target) == dir && upperStep(mover.loc)) + return FALSE + . = ..() + +/obj/structure/stairs/Bumped(atom/movable/A) + // This is hackish but whatever. + var/turf/target = get_step(GetAbove(A), dir) + if(target.Enter(A, src)) // Pass src to be ignored to avoid infinate loop + A.forceMove(target) + if(isliving(A)) + var/mob/living/L = A + if(L.pulling) + L.pulling.forceMove(target) /obj/structure/stairs/proc/upperStep(var/turf/T) return (T == loc) diff --git a/code/modules/organs/internal/eyes.dm b/code/modules/organs/internal/eyes.dm index 3b44682095b..9d82a7749b8 100644 --- a/code/modules/organs/internal/eyes.dm +++ b/code/modules/organs/internal/eyes.dm @@ -50,7 +50,7 @@ // Now sync the organ's eye_colour list. update_colour() // Finally, update the eye icon on the mob. - owner.update_eyes() + owner.regenerate_icons() /obj/item/organ/internal/eyes/replaced(var/mob/living/carbon/human/target) diff --git a/code/modules/organs/internal/voicebox.dm b/code/modules/organs/internal/voicebox.dm new file mode 100644 index 00000000000..4de69fe8f2b --- /dev/null +++ b/code/modules/organs/internal/voicebox.dm @@ -0,0 +1,42 @@ +/* + * Voicebox/Vocal Synthesizers + * TL;DR: Assists with speaking languages that a species doesn't normally have, + * such as EAL. Not standard or organic, because at the moment it's undesireable to completely mute characters. + */ + +/obj/item/organ/internal/voicebox + name = "larynx" + icon_state = "larynx" + parent_organ = BP_TORSO // We don't have a neck area + organ_tag = O_VOICE + will_assist_languages = list(LANGUAGE_GALCOM) + +/obj/item/organ/internal/voicebox/New() + ..() + amend_assist_langs() + +/obj/item/organ/internal/voicebox/proc/amend_assist_langs() // Adds the list of language datums assisted by the voicebox to the list used in speaking + for(var/L in will_assist_languages) + assists_languages |= all_languages[L] + +/obj/item/organ/internal/voicebox/proc/add_assistable_langs(var/language) // Adds a new language (by string/define) to the list of things the voicebox can assist + will_assist_languages |= language + amend_assist_langs() // Can't think of a better place to put this, makes the voicebox actually start to assist with the added language + +///////////////////////////////// +// Voicebox Subtypes +///////////////////////////////// + +/obj/item/organ/internal/voicebox/assist // In the off chance we get a species that doesn't speak GalCom by default + +/obj/item/organ/internal/voicebox/assist/New() + ..() + mechassist() + +/obj/item/organ/internal/voicebox/robot + name = "vocal synthesizer" + will_assist_languages = list(LANGUAGE_GALCOM, LANGUAGE_EAL) // Synthetics spawn with this by default + +/obj/item/organ/internal/voicebox/robot/New() + ..() + robotize() diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index d649b951b06..f07a6b3192b 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -31,6 +31,10 @@ var/list/organ_cache = list() var/rejecting // Is this organ already being rejected? var/preserved = 0 // If this is 1, prevents organ decay. + // Language vars. Putting them here in case we decide to do something crazy with sign-or-other-nonverbal languages. + var/list/will_assist_languages = list() + var/list/datum/language/assists_languages = list() + /obj/item/organ/Destroy() if(owner) owner = null diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 789dce7dfbc..c3c709852d0 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -72,6 +72,8 @@ var/open = 0 var/stage = 0 var/cavity = 0 + var/burn_stage = 0 //Surgical repair stage for burn. + var/brute_stage = 0 //Surgical repair stage for brute. // HUD element variable, see organ_icon.dm get_damage_hud_image() var/image/hud_damage_image @@ -1105,6 +1107,8 @@ Note that amputating the affected organ does in fact remove the infection from t R = basic_robolimb if(R) force_icon = R.icon + brute_mod *= R.robo_brute_mod + burn_mod *= R.robo_burn_mod if(R.lifelike) robotic = ORGAN_LIFELIKE name = "[initial(name)]" @@ -1343,3 +1347,18 @@ Note that amputating the affected organ does in fact remove the infection from t if(6 to INFINITY) flavor_text += "a ton of [wound]\s" return english_list(flavor_text) + +// Returns a list of the clothing (not glasses) that are covering this part +/obj/item/organ/external/proc/get_covering_clothing() + var/list/covering_clothing = list() + if(owner) + var/list/protective_gear = list(owner.head, owner.wear_mask, owner.wear_suit, owner.w_uniform, owner.gloves, owner.shoes) + for(var/obj/item/clothing/gear in protective_gear) + if(gear.body_parts_covered & src.body_part) + covering_clothing |= gear + if(LAZYLEN(gear.accessories)) + for(var/obj/item/clothing/accessory/bling in gear.accessories) + if(bling.body_parts_covered & src.body_part) + covering_clothing |= bling + + return covering_clothing \ No newline at end of file diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index b664600bfdc..71adba5b115 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -4,13 +4,13 @@ var/global/list/limb_icon_cache = list() return /obj/item/organ/external/proc/compile_icon() - overlays.Cut() + cut_overlays() // This is a kludge, only one icon has more than one generation of children though. for(var/obj/item/organ/external/organ in contents) if(organ.children && organ.children.len) for(var/obj/item/organ/external/child in organ.children) overlays += child.mob_icon - overlays += organ.mob_icon + add_overlay(organ.mob_icon) /obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human) s_tone = null @@ -51,10 +51,10 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/head/get_icon() ..() - + //The overlays are not drawn on the mob, they are used for if the head is removed and becomes an item cut_overlays() - + //Every 'addon' below requires information from species if(!owner || !owner.species) return @@ -78,7 +78,7 @@ var/global/list/limb_icon_cache = list() eyes_icon.Blend(rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes), ICON_ADD) add_overlay(eyes_icon) mob_icon.Blend(eyes_icon, ICON_OVERLAY) - + //Lip color/icon if(owner.lip_style && (species && (species.appearance_flags & HAS_LIPS))) var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") @@ -94,6 +94,12 @@ var/global/list/limb_icon_cache = list() mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons icon_cache_key += "[M][markings[M]["color"]]" + add_overlay(get_hair_icon()) + + return mob_icon + +/obj/item/organ/external/head/proc/get_hair_icon() + var/image/res = image('icons/mob/human_face.dmi',"bald_s") //Facial hair if(owner.f_style) var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style] @@ -101,20 +107,24 @@ var/global/list/limb_icon_cache = list() var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") if(facial_hair_style.do_colouration) facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_MULTIPLY) // VOREStation edit - add_overlay(facial_s) + res.add_overlay(facial_s) //Head hair if(owner.h_style && !(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR))) - var/datum/sprite_accessory/hair/hair_style = hair_styles_list[owner.h_style] + var/style = owner.h_style + var/datum/sprite_accessory/hair/hair_style = hair_styles_list[style] + if(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR)) + if(!(hair_style.flags & HAIR_VERY_SHORT)) + hair_style = hair_styles_list["Short Hair"] if(hair_style && (species.get_bodytype(owner) in hair_style.species_allowed)) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") var/icon/hair_s_add = new/icon("icon" = hair_style.icon_add, "icon_state" = "[hair_style.icon_state]_s") if(hair_style.do_colouration && islist(h_col) && h_col.len >= 3) hair_s.Blend(rgb(h_col[1], h_col[2], h_col[3]), ICON_MULTIPLY) hair_s.Blend(hair_s_add, ICON_ADD) - add_overlay(hair_s) + res.add_overlay(hair_s) - return mob_icon + return res /obj/item/organ/external/proc/get_icon(var/skeletal) @@ -154,7 +164,7 @@ var/global/list/limb_icon_cache = list() var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]") mark_s.Blend(markings[M]["color"], mark_style.color_blend_mode) // VOREStation edit - overlays |= mark_s //So when it's not on your body, it has icons + add_overlay(mark_s) //So when it's not on your body, it has icons mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons icon_cache_key += "[M][markings[M]["color"]]" @@ -170,13 +180,14 @@ var/global/list/limb_icon_cache = list() icon_cache_key += "_model_[model]" apply_colouration(mob_icon) // VOREStation edit to enable markings on synths - for(var/M in markings) - var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] - var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]") - mark_s.Blend(markings[M]["color"], mark_style.color_blend_mode) // VOREStation edit - overlays |= mark_s //So when it's not on your body, it has icons - mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons - icon_cache_key += "[M][markings[M]["color"]]" + if(owner && owner.synth_markings) + for(var/M in markings) + var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] + var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]") + mark_s.Blend(markings[M]["color"], mark_style.color_blend_mode) // VOREStation edit + overlays |= mark_s //So when it's not on your body, it has icons + mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons + icon_cache_key += "[M][markings[M]["color"]]" if(body_hair && islist(h_col) && h_col.len >= 3) var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]" @@ -270,7 +281,7 @@ var/list/robot_hud_colours = list("#CFCFCF","#AFAFAF","#8F8F8F","#6F6F6F","#4F4F var/b = 0.11 * R.health_hud_intensity temp.color = list(r, r, r, g, g, g, b, b, b) hud_damage_image = image(null) - hud_damage_image.overlays += temp + hud_damage_image.add_overlay(temp) // Calculate the required color index. var/dam_state = min(1,((brute_dam+burn_dam)/max_damage)) diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index 1f15f125c24..5a55b1bcd5a 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -49,6 +49,9 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ var/suggested_species = "Human" //If it should make the torso a species var/speech_bubble_appearance = "synthetic" // What icon_state to use for speech bubbles when talking. Check talk.dmi for all the icons. + var/robo_brute_mod = 1 // Multiplier for incoming brute damage. + var/robo_burn_mod = 1 // As above for burn. + /datum/robolimb/unbranded_monitor company = "Unbranded Monitor" desc = "A generic unbranded interpretation of a popular prosthetic head model. It looks rudimentary and cheaply constructed." @@ -214,6 +217,8 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ skin_tone = 1 blood_color = "#CCCCCC" speech_bubble_appearance = "normal" + //robo_brute_mod = 1.1 //VOREStation Edit + //robo_burn_mod = 1.1 //VOREStation Edit /datum/robolimb/wardtakahashi company = "Ward-Takahashi" diff --git a/code/modules/organs/robolimbs_vr.dm b/code/modules/organs/robolimbs_vr.dm index ee689e32375..cdf873b2ec4 100644 --- a/code/modules/organs/robolimbs_vr.dm +++ b/code/modules/organs/robolimbs_vr.dm @@ -86,6 +86,7 @@ lifelike = 1 unavailable_to_build = 1 includes_tail = 1 + skin_tone = 1 suggested_species = "Tajara" /obj/item/weapon/disk/limb/dsi_tajaran @@ -99,6 +100,7 @@ lifelike = 1 unavailable_to_build = 1 includes_tail = 1 + skin_tone = 1 suggested_species = "Unathi" /obj/item/weapon/disk/limb/dsi_lizard @@ -112,6 +114,7 @@ lifelike = 1 unavailable_to_build = 1 includes_tail = 1 + skin_tone = 1 suggested_species = "Sergal" /obj/item/weapon/disk/limb/dsi_sergal @@ -125,6 +128,7 @@ lifelike = 1 unavailable_to_build = 1 includes_tail = 1 + skin_tone = 1 suggested_species = "Nevrean" /obj/item/weapon/disk/limb/dsi_nevrean @@ -138,6 +142,7 @@ lifelike = 1 unavailable_to_build = 1 includes_tail = 1 + skin_tone = 1 suggested_species = "Vulpkanin" /obj/item/weapon/disk/limb/dsi_vulpkanin @@ -151,6 +156,7 @@ lifelike = 1 unavailable_to_build = 1 includes_tail = 1 + skin_tone = 1 suggested_species = "Akula" /obj/item/weapon/disk/limb/dsi_akula @@ -164,6 +170,7 @@ lifelike = 1 unavailable_to_build = 1 includes_tail = 1 + skin_tone = 1 suggested_species = "Vasilissan" /obj/item/weapon/disk/limb/dsi_spider @@ -174,6 +181,7 @@ desc = "This limb has a thin synthflesh casing with a few connection ports." icon = 'icons/mob/human_races/cyberlimbs/DSITeshari/dsi_teshari.dmi' lifelike = 1 + skin_tone = 1 suggested_species = "Teshari" /datum/robolimb/dsi_teshari/New() diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/organs/subtypes/standard.dm index 449d7c51371..568d45088cd 100644 --- a/code/modules/organs/subtypes/standard.dm +++ b/code/modules/organs/subtypes/standard.dm @@ -23,10 +23,11 @@ organ_rel_size = 70 base_miss_chance = 10 -/obj/item/organ/external/chest/robotize(var/company, var/skip_prosthetics = 0, var/keep_organs = 0) +/obj/item/organ/external/chest/robotize() if(..() && robotic != ORGAN_NANOFORM) //VOREStation Edit - // Give them a new cell. - owner.internal_organs_by_name["cell"] = new /obj/item/organ/internal/cell(owner,1) + // Give them fancy new organs. + owner.internal_organs_by_name[O_CELL] = new /obj/item/organ/internal/cell(owner,1) + owner.internal_organs_by_name[O_VOICE] = new /obj/item/organ/internal/voicebox/robot(owner, 1) /obj/item/organ/external/chest/handle_germ_effects() . = ..() //Should return an infection level diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index d0de1294bae..535debad21d 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -134,7 +134,7 @@ var/global/photo_count = 0 var/icon_on = "camera" var/icon_off = "camera_off" var/size = 3 - var/picture_planes = list() + var/list/picture_planes = list() /obj/item/device/camera/verb/change_size() set name = "Set Photo Focus" diff --git a/code/modules/planet/planet.dm b/code/modules/planet/planet.dm index 061ae73398f..8fb76044178 100644 --- a/code/modules/planet/planet.dm +++ b/code/modules/planet/planet.dm @@ -30,9 +30,10 @@ current_time = current_time.make_random_time() update_sun() -/datum/planet/proc/process(amount) +/datum/planet/proc/process(last_fire) if(current_time) - current_time = current_time.add_seconds(amount) + var/difference = world.time - last_fire + current_time = current_time.add_seconds(difference SECONDS) update_weather() // We update this first, because some weather types decease the brightness of the sun. if(sun_last_process <= world.time - sun_process_interval) update_sun() diff --git a/code/modules/planet/sif.dm b/code/modules/planet/sif.dm index 8717245b246..b8bbf7ba6a4 100644 --- a/code/modules/planet/sif.dm +++ b/code/modules/planet/sif.dm @@ -184,7 +184,8 @@ datum/weather/sif ) /datum/weather/sif/snow/process_effects() - for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs) + ..() + for(var/turf/simulated/floor/outdoors/snow/S in SSplanets.new_outdoor_turfs) //This didn't make any sense before SSplanets, either if(S.z in holder.our_planet.expected_z_levels) for(var/dir_checked in cardinal) var/turf/simulated/floor/T = get_step(S, dir_checked) @@ -207,7 +208,8 @@ datum/weather/sif ) /datum/weather/sif/blizzard/process_effects() - for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs) + ..() + for(var/turf/simulated/floor/outdoors/snow/S in SSplanets.new_outdoor_turfs) //This didn't make any sense before SSplanets, either if(S.z in holder.our_planet.expected_z_levels) for(var/dir_checked in cardinal) var/turf/simulated/floor/T = get_step(S, dir_checked) @@ -219,6 +221,8 @@ datum/weather/sif name = "rain" icon_state = "rain" light_modifier = 0.5 + effect_message = "Rain falls on you." + transition_chances = list( WEATHER_OVERCAST = 25, WEATHER_LIGHT_SNOW = 10, @@ -228,6 +232,7 @@ datum/weather/sif ) /datum/weather/sif/rain/process_effects() + ..() for(var/mob/living/L in living_mob_list) if(L.z in holder.our_planet.expected_z_levels) var/turf/T = get_turf(L) @@ -238,16 +243,19 @@ datum/weather/sif if(istype(L.get_active_hand(), /obj/item/weapon/melee/umbrella)) var/obj/item/weapon/melee/umbrella/U = L.get_active_hand() if(U.open) - to_chat(L, "Rain patters softly onto your umbrella") + if(show_message) + to_chat(L, "Rain patters softly onto your umbrella") continue else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella)) var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand() if(U.open) - to_chat(L, "Rain patters softly onto your umbrella") + if(show_message) + to_chat(L, "Rain patters softly onto your umbrella") continue L.water_act(1) - to_chat(L, "Rain falls on you.") + if(show_message) + to_chat(L, effect_message) /datum/weather/sif/storm name = "storm" @@ -256,6 +264,8 @@ datum/weather/sif temp_low = 233.15 // -40c light_modifier = 0.3 flight_failure_modifier = 10 + + transition_chances = list( WEATHER_RAIN = 45, WEATHER_STORM = 40, @@ -264,6 +274,7 @@ datum/weather/sif ) /datum/weather/sif/storm/process_effects() + ..() for(var/mob/living/L in living_mob_list) if(L.z in holder.our_planet.expected_z_levels) var/turf/T = get_turf(L) @@ -294,6 +305,10 @@ datum/weather/sif temp_low = 243.15 // -30c light_modifier = 0.3 flight_failure_modifier = 15 + timer_low_bound = 2 + timer_high_bound = 5 + effect_message = "The hail smacks into you!" + transition_chances = list( WEATHER_RAIN = 45, WEATHER_STORM = 40, @@ -302,6 +317,7 @@ datum/weather/sif ) /datum/weather/sif/hail/process_effects() + ..() for(var/mob/living/carbon/human/H in living_mob_list) if(H.z in holder.our_planet.expected_z_levels) var/turf/T = get_turf(H) @@ -309,15 +325,18 @@ datum/weather/sif continue // They're indoors, so no need to pelt them with ice. // If they have an open umbrella, it'll guard from rain + // Message plays every time the umbrella gets stolen, just so they're especially aware of what's happening if(istype(H.get_active_hand(), /obj/item/weapon/melee/umbrella)) var/obj/item/weapon/melee/umbrella/U = H.get_active_hand() if(U.open) - to_chat(H, "Hail patters gently onto your umbrella.") + if(show_message) + to_chat(H, "Hail patters gently onto your umbrella.") continue else if(istype(H.get_inactive_hand(), /obj/item/weapon/melee/umbrella)) var/obj/item/weapon/melee/umbrella/U = H.get_inactive_hand() if(U.open) - to_chat(H, "Hail patters gently onto your umbrella.") + if(show_message) + to_chat(H, "Hail patters gently onto your umbrella.") continue var/target_zone = pick(BP_ALL) @@ -330,8 +349,9 @@ datum/weather/sif if(amount_soaked >= 10) continue // No need to apply damage. - H.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail") - to_chat(H, "The hail smacks into you!") + H.apply_damage(rand(1, 3), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail") + if(show_message) + to_chat(H, effect_message) /datum/weather/sif/blood_moon name = "blood moon" diff --git a/code/modules/planet/weather.dm b/code/modules/planet/weather.dm index a0fa6039809..96f36601214 100644 --- a/code/modules/planet/weather.dm +++ b/code/modules/planet/weather.dm @@ -25,7 +25,7 @@ if(current_weather) old_light_modifier = current_weather.light_modifier // We store the old one, so we can determine if recalculating the sun is needed. current_weather = allowed_weather_types[new_weather] - next_weather_shift = world.time + rand(20, 30) MINUTES + next_weather_shift = world.time + rand(current_weather.timer_low_bound, current_weather.timer_high_bound) MINUTES update_icon_effects() update_temperature() @@ -66,8 +66,20 @@ var/flight_failure_modifier = 0 // Some types of weather make flying harder, and therefore make crashes more likely. var/transition_chances = list() // Assoc list var/datum/weather_holder/holder = null + var/timer_low_bound = 5 // How long this weather must run before it tries to change, in minutes + var/timer_high_bound = 10 // How long this weather can run before it tries to change, in minutes + + var/effect_message = null // Should be a string, this is what is shown to a mob caught in the weather + var/last_message = 0 // Keeps track of when the weather last tells EVERY player it's hitting them + var/message_delay = 10 SECONDS // Delay in between weather hit messages + var/show_message = FALSE // Is set to TRUE and plays the messsage every [message_delay] /datum/weather/proc/process_effects() + show_message = FALSE // Need to reset the show_message var, just in case + if(effect_message) // Only bother with the code below if we actually need to display something + if(world.time >= last_message + message_delay) + last_message = world.time // Reset the timer + show_message = TRUE // Tell the rest of the process that we need to make a message return // All this does is hold the weather icon. diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 5ad1e727da4..2d057825faf 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -160,6 +160,7 @@ var/list/possible_cable_coil_colours = list( return if(istype(W, /obj/item/weapon/wirecutters)) + var/obj/item/stack/cable_coil/CC if(d1 == UP || d2 == UP) to_chat(user, "You must cut this cable from above.") return @@ -172,9 +173,12 @@ var/list/possible_cable_coil_colours = list( return if(src.d1) // 0-X cables are 1 unit, X-X cables are 2 units long - new/obj/item/stack/cable_coil(T, 2, color) + CC = new/obj/item/stack/cable_coil(T, 2, color) else - new/obj/item/stack/cable_coil(T, 1, color) + CC = new/obj/item/stack/cable_coil(T, 1, color) + + src.add_fingerprint(user) + src.transfer_fingerprints_to(CC) for(var/mob/O in viewers(src, null)) O.show_message("[user] cuts the cable.", 1) @@ -939,4 +943,25 @@ obj/structure/cable/proc/cableColor(var/colorC) if(get_dist(src, user) <= 1) msg += " It doesn't seem to have a beginning, or an end." - to_chat(user, msg) \ No newline at end of file + to_chat(user, msg) + +/obj/item/stack/cable_coil/alien/attack_hand(mob/user as mob) + if (user.get_inactive_hand() == src) + var/N = input("How many units of wire do you want to take from [src]? You can only take up to [amount] at a time.", "Split stacks", 1) as num|null + if(N && N <= amount) + var/obj/item/stack/cable_coil/CC = new/obj/item/stack/cable_coil(user.loc) + CC.amount = N + CC.update_icon() + to_chat(user,"You take [N] units of wire from the [src].") + if (CC) + user.put_in_hands(CC) + src.add_fingerprint(user) + CC.add_fingerprint(user) + spawn(0) + if (src && usr.machine==src) + src.interact(usr) + else + return + else + ..() + return diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 4db4d40c4c1..f9fca6222f7 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -41,6 +41,9 @@ processing_objects -= src return ..() +/obj/item/weapon/cell/get_cell() + return src + /obj/item/weapon/cell/process() if(self_recharge) if(world.time >= last_use + charge_delay) diff --git a/code/modules/power/fusion/core/core_control.dm b/code/modules/power/fusion/core/core_control.dm index bb4e04b1e90..54d96883a74 100644 --- a/code/modules/power/fusion/core/core_control.dm +++ b/code/modules/power/fusion/core/core_control.dm @@ -3,21 +3,20 @@ icon = 'icons/obj/machines/power/fusion.dmi' icon_state = "core_control" light_color = COLOR_ORANGE - + circuit = /obj/item/weapon/circuitboard/fusion_core_control var/id_tag var/scan_range = 25 var/list/connected_devices = list() var/obj/machinery/power/fusion_core/cur_viewed_device /obj/machinery/computer/fusion_core_control/attackby(var/obj/item/thing, var/mob/user) + ..() if(ismultitool(thing)) var/new_ident = input("Enter a new ident tag.", "Core Control", id_tag) as null|text if(new_ident && user.Adjacent(src)) id_tag = new_ident cur_viewed_device = null return - else - return ..() /obj/machinery/computer/fusion_core_control/attack_ai(mob/user) attack_hand(user) @@ -28,6 +27,11 @@ /obj/machinery/computer/fusion_core_control/interact(mob/user) + if(stat & (BROKEN|NOPOWER)) + user.unset_machine() + user << browse(null, "window=fusion_control") + return + if(!cur_viewed_device || !check_core_status(cur_viewed_device)) cur_viewed_device = null @@ -174,3 +178,19 @@ if(C.idle_power_usage > C.avail()) return . = 1 + +/obj/machinery/computer/fusion_core_control/update_icon() + if(stat & (BROKEN)) + icon = 'icons/obj/computer.dmi' + icon_state = "broken" + set_light(0) + + if(stat & (NOPOWER)) + icon = 'icons/obj/computer.dmi' + icon_state = "computer" + set_light(0) + + if(!stat & (BROKEN|NOPOWER)) + icon = initial(icon) + icon_state = initial(icon_state) + set_light(light_range_on, light_power_on) diff --git a/code/modules/power/fusion/core/core_field.dm b/code/modules/power/fusion/core/core_field.dm index 1efb09d777b..f5d85fb4bf6 100644 --- a/code/modules/power/fusion/core/core_field.dm +++ b/code/modules/power/fusion/core/core_field.dm @@ -35,7 +35,7 @@ /obj/structure/cable, /obj/machinery/atmospherics, /obj/machinery/air_sensor, - /mob/observer/dead, + /mob/observer, /obj/machinery/power/hydromagnetic_trap ) @@ -672,4 +672,4 @@ #undef FUSION_HEAT_CAP #undef FUSION_MAX_ENVIRO_HEAT -#undef PLASMA_TEMP_RADIATION_DIVISIOR \ No newline at end of file +#undef PLASMA_TEMP_RADIATION_DIVISIOR diff --git a/code/modules/power/fusion/fuel_assembly/fuel_control.dm b/code/modules/power/fusion/fuel_assembly/fuel_control.dm index 6d95e358d86..e765c4d4959 100644 --- a/code/modules/power/fusion/fuel_assembly/fuel_control.dm +++ b/code/modules/power/fusion/fuel_assembly/fuel_control.dm @@ -2,6 +2,7 @@ name = "fuel injection control computer" icon = 'icons/obj/machines/power/fusion.dmi' icon_state = "fuel" + circuit = /obj/item/weapon/circuitboard/fusion_fuel_control var/id_tag var/scan_range = 25 @@ -94,9 +95,25 @@ /obj/machinery/computer/fusion_fuel_control/attackby(var/obj/item/W, var/mob/user) + ..() if(ismultitool(W)) var/new_ident = input("Enter a new ident tag.", "Fuel Control", id_tag) as null|text if(new_ident && user.Adjacent(src)) id_tag = new_ident return - return ..() + +/obj/machinery/computer/fusion_fuel_control/update_icon() + if(stat & (BROKEN)) + icon = 'icons/obj/computer.dmi' + icon_state = "broken" + set_light(0) + + if(stat & (NOPOWER)) + icon = 'icons/obj/computer.dmi' + icon_state = "computer" + set_light(0) + + if(!stat & (BROKEN|NOPOWER)) + icon = initial(icon) + icon_state = initial(icon_state) + set_light(light_range_on, light_power_on) diff --git a/code/modules/power/fusion/gyrotron/gyrotron_control.dm b/code/modules/power/fusion/gyrotron/gyrotron_control.dm index 9f6c59c7537..eb735a81f34 100644 --- a/code/modules/power/fusion/gyrotron/gyrotron_control.dm +++ b/code/modules/power/fusion/gyrotron/gyrotron_control.dm @@ -3,6 +3,7 @@ icon = 'icons/obj/machines/power/fusion.dmi' icon_state = "engine" light_color = COLOR_BLUE + circuit = /obj/item/weapon/circuitboard/gyrotron_control var/id_tag var/scan_range = 25 @@ -16,6 +17,11 @@ /obj/machinery/computer/gyrotron_control/interact(var/mob/user) + if(stat & (BROKEN|NOPOWER)) + user.unset_machine() + user << browse(null, "window=gyrotron_controller_[id_tag]") + return + if(!id_tag) to_chat(user, "This console has not been assigned an ident tag. Please contact your system administrator or conduct a manual update with a standard multitool.") return @@ -89,9 +95,25 @@ return 0 /obj/machinery/computer/gyrotron_control/attackby(var/obj/item/W, var/mob/user) + ..() if(ismultitool(W)) var/new_ident = input("Enter a new ident tag.", "Gyrotron Control", id_tag) as null|text if(new_ident && user.Adjacent(src)) id_tag = new_ident return - return ..() + +/obj/machinery/computer/gyrotron_control/update_icon() + if(stat & (BROKEN)) + icon = 'icons/obj/computer.dmi' + icon_state = "broken" + set_light(0) + + if(stat & (NOPOWER)) + icon = 'icons/obj/computer.dmi' + icon_state = "computer" + set_light(0) + + if(!stat & (BROKEN|NOPOWER)) + icon = initial(icon) + icon_state = initial(icon_state) + set_light(light_range_on, light_power_on) diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 0c3c76caaf3..5ea1c0a2d69 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -325,6 +325,31 @@ /obj/item/ammo_magazine/box/c9mm/empty initial_ammo = 0 +/obj/item/ammo_magazine/m9mmR/saber + desc = "A very high capacity double stack magazine made specially for the SABER SMG. Filled with 22 9mm bullets." + icon_state = "S9mm-22" + mag_type = MAGAZINE + ammo_type = /obj/item/ammo_casing/a9mm + matter = list(DEFAULT_WALL_MATERIAL = 1200) + caliber = "9mm" + max_ammo = 22 + origin_tech = list(TECH_COMBAT = 2, TECH_ILLEGAL = 1) + multiple_sprites = 1 + +/obj/item/ammo_magazine/m9mmR/saber/ap + desc = "A high capacity double stack magazine made specially for the SABER SMG. Filled with 22 9mm armor piercing bullets." + icon_state = "S9mm-22" + mag_type = MAGAZINE + ammo_type = /obj/item/ammo_casing/a9mm/ap + matter = list(DEFAULT_WALL_MATERIAL = 2000) + caliber = "9mm" + max_ammo = 22 + origin_tech = list(TECH_COMBAT = 2, TECH_ILLEGAL = 1) + multiple_sprites = 1 + +/obj/item/ammo_magazine/m9mmR/saber/empty + initial_ammo = 0 + ///////// 10mm ///////// /obj/item/ammo_magazine/m10mm diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index c87c37a0858..9cfd0d152a1 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -23,17 +23,6 @@ var/battery_lock = 0 //If set, weapon cannot switch batteries -/obj/item/weapon/gun/energy/attackby(var/obj/item/A as obj, mob/user as mob) - ..() - -/obj/item/weapon/gun/energy/switch_firemodes(mob/user) - if(..()) - update_icon() - -/obj/item/weapon/gun/energy/emp_act(severity) - ..() - update_icon() - /obj/item/weapon/gun/energy/New() ..() if(self_recharge) @@ -52,6 +41,9 @@ processing_objects.Remove(src) return ..() +/obj/item/weapon/gun/energy/get_cell() + return power_supply + /obj/item/weapon/gun/energy/process() if(self_recharge) //Every [recharge_time] ticks, recharge a shot for the battery if(world.time > last_shot + charge_delay) //Doesn't work if you've fired recently @@ -75,6 +67,17 @@ charge_tick = 0 return 1 +/obj/item/weapon/gun/energy/attackby(var/obj/item/A as obj, mob/user as mob) + ..() + +/obj/item/weapon/gun/energy/switch_firemodes(mob/user) + if(..()) + update_icon() + +/obj/item/weapon/gun/energy/emp_act(severity) + ..() + update_icon() + /obj/item/weapon/gun/energy/consume_next_projectile() if(!power_supply) return null if(!ispath(projectile_type)) return null diff --git a/code/modules/projectiles/guns/energy/phase.dm b/code/modules/projectiles/guns/energy/phase.dm new file mode 100644 index 00000000000..3e5f8cb1861 --- /dev/null +++ b/code/modules/projectiles/guns/energy/phase.dm @@ -0,0 +1,56 @@ +// Phase weapons go here + +/obj/item/weapon/gun/energy/phasegun + name = "phase carbine" + desc = "The NT EW26 Artemis is a downsized energy weapon, specifically designed for use against wildlife." + icon_state = "phasecarbine" + wielded_item_state = "phasecarbine-wielded" + slot_flags = SLOT_BACK|SLOT_BELT + charge_cost = 240 + projectile_type = /obj/item/projectile/energy/phase + one_handed_penalty = 15 + +/obj/item/weapon/gun/energy/phasegun/pistol + name = "phase pistol" + desc = "The NT EW15 Apollo is an energy handgun, specifically designed for self-defense against aggressive wildlife." + icon_state = "phase" + item_state = "taser" //I don't have an in-hand sprite, taser will be fine + w_class = ITEMSIZE_NORMAL + slot_flags = SLOT_BELT|SLOT_HOLSTER + charge_cost = 300 + projectile_type = /obj/item/projectile/energy/phase/light + one_handed_penalty = 0 + +/obj/item/weapon/gun/energy/phasegun/pistol/mounted + name = "mounted phase pistol" + self_recharge = 1 + use_external_power = 1 + +/obj/item/weapon/gun/energy/phasegun/pistol/mounted/cyborg + charge_cost = 400 + recharge_time = 7 + +obj/item/weapon/gun/energy/phasegun/rifle + name = "phase rifle" + desc = "The NT EW31 Orion is a specialist energy weapon, intended for use against hostile wildlife." + icon_state = "phaserifle" + item_state = "phaserifle" + wielded_item_state = "phaserifle-wielded" + slot_flags = SLOT_BACK + charge_cost = 150 + projectile_type = /obj/item/projectile/energy/phase/heavy + accuracy = 15 + one_handed_penalty = 30 + +/obj/item/weapon/gun/energy/phasegun/cannon + name = "phase cannon" + desc = "The NT EW50 Gaia is a massive energy weapon, purpose-built for clearing land. You feel dirty just looking at it." + icon_state = "phasecannon" + item_state = "phasecannon" + wielded_item_state = "phasecannon-wielded" //TODO: New Sprites + w_class = ITEMSIZE_HUGE // This thing is big. + slot_flags = SLOT_BACK + charge_cost = 100 + projectile_type = /obj/item/projectile/energy/phase/heavy/cannon + accuracy = 15 + one_handed_penalty = 65 \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index baad821a224..f1e20b169be 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -23,16 +23,7 @@ force = 5 slot_flags = SLOT_BELT|SLOT_HOLSTER charge_cost = 480 - projectile_type = /obj/item/projectile/ion/pistol // still packs a punch but no AoE - -/obj/item/weapon/gun/energy/phasegun - name = "phase pistol" - desc = "The NT Mk26 EW Apollo is an energy handgun, specifically designed for use against wildlife." - icon_state = "phase" - item_state = "taser" //I don't have an in-hand sprite, taser will be fine - slot_flags = SLOT_BELT|SLOT_HOLSTER - charge_cost = 300 - projectile_type = /obj/item/projectile/energy/phase + projectile_type = /obj/item/projectile/ion/pistol /obj/item/weapon/gun/energy/decloner name = "biological demolecularisor" diff --git a/code/modules/projectiles/guns/magnetic/magnetic.dm b/code/modules/projectiles/guns/magnetic/magnetic.dm index cbce1a7aa14..a34db528872 100644 --- a/code/modules/projectiles/guns/magnetic/magnetic.dm +++ b/code/modules/projectiles/guns/magnetic/magnetic.dm @@ -36,6 +36,9 @@ qdel_null(capacitor) . = ..() +/obj/item/weapon/gun/magnetic/get_cell() + return cell + /obj/item/weapon/gun/magnetic/process() if(capacitor) if(cell) diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 4c7e0e3e888..a1afc075b53 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -1,25 +1,40 @@ -/obj/item/weapon/gun/projectile/automatic //Hopefully someone will find a way to make these fire in bursts or something. --Superxpdude //Except burstfire isn't fit for an rp server --Mark +/obj/item/weapon/gun/projectile/automatic //This should never be spawned in, it is just here because of code necessities. + name = "daka SMG" + desc = "A small SMG. You really shouldn't be able to get this gun. Uses 9mm rounds." + icon_state = "c05r" //Used because it's not used anywhere else + load_method = SPEEDLOADER + ammo_type = /obj/item/ammo_casing/a9mm + projectile_type = /obj/item/projectile/bullet/pistol + +//Burst is the number of bullets fired; Fire delay is the time you have to wait to shoot the gun again, Move delay is the same but for moving after shooting. . +//Burst accuracy is the accuracy of each bullet fired in the burst. Dispersion is how much the bullets will 'spread' away from where you aimed. + + firemodes = list( + list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null), + list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0))) + +/obj/item/weapon/gun/projectile/automatic/saber //Fixed it name = "prototype SMG" desc = "A protoype lightweight, fast firing gun. Uses 9mm rounds." - icon_state = "saber" //ugly + icon = 'icons/obj/gun.dmi' + icon_state = "saber"//Still ugly w_class = ITEMSIZE_NORMAL - load_method = SPEEDLOADER //yup. until someone sprites a magazine for it. + load_method = MAGAZINE //This should fix it max_shells = 22 caliber = "9mm" origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2) slot_flags = SLOT_BELT - ammo_type = /obj/item/ammo_casing/a9mm + magazine_type = /obj/item/ammo_magazine/m9mmR/saber + allowed_magazines = list(/obj/item/ammo_magazine/m9mmR/saber, /obj/item/ammo_magazine/m9mmR/saber/ap) projectile_type = /obj/item/projectile/bullet/pistol multi_aim = 1 burst_delay = 2 -// one_handed_penalty = 15 - firemodes = list( list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null), list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0)) -// list(mode_name="short bursts", burst=5, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15,-30,-30), dispersion=list(0.6, 1.0, 1.0, 1.0, 1.2)), - ) + // list(mode_name="short bursts", burst=5, fire_delay=null, move_delay=4, burst_accuracy=list(0,-15,-15,-30,-30), dispersion=list(0.6, 1.0, 1.0, 1.0, 1.2)), + ) /obj/item/weapon/gun/projectile/automatic/c20r name = "submachine gun" diff --git a/code/modules/projectiles/projectile/arc.dm b/code/modules/projectiles/projectile/arc.dm new file mode 100644 index 00000000000..6e434b1e99d --- /dev/null +++ b/code/modules/projectiles/projectile/arc.dm @@ -0,0 +1,134 @@ +// These projectiles are somewhat different from the other projectiles in the code. +// First, these have an 'arcing' visual, that is accomplished by having the projectile icon rotate as its flying, and +// moving up, then down as it approaches the target. There is also a small shadow effect that follows the projectile +// as its flying. + +// Besides the visuals, arcing projectiles do not collide with anything until they reach the target, as they fly over them. +// For best effect, use this only when it makes sense to do so, IE on the Surface. The projectiles don't care about ceilings or gravity. + +/obj/item/projectile/arc + name = "arcing shot" + icon_state = "fireball" // WIP + step_delay = 2 // Travel a bit slower, to really sell the arc visuals. + plane = ABOVE_PLANE // Since projectiles are 'in the air', they might visually overlap mobs while in flight, so the projectile needs to be above their plane. + var/target_distance = null // How many tiles the impact site is. + var/fired_dir = null // Which direction was the projectile fired towards. Needed to invert the projectile turning based on if facing left or right. + var/obj/effect/projectile_shadow/shadow = null // Visual indicator for the projectile's 'true' position. Needed due to being bound to two dimensions in reality. + +/obj/item/projectile/arc/initialize() + shadow = new(get_turf(src)) + return ..() + +/obj/item/projectile/arc/Destroy() + qdel_null(shadow) + return ..() + +/obj/item/projectile/arc/Bump(atom/A, forced=0) + return 0 +// if(get_turf(src) != original) +// return 0 +// else +// return ..() + +// This is a test projectile in the sense that its testing the code to make sure it works, +// as opposed to a 'can I hit this thing' projectile. +/obj/item/projectile/arc/test/on_impact(turf/T) + new /obj/effect/explosion(T) + return ..() + +/obj/item/projectile/arc/launch(atom/target, target_zone, x_offset=0, y_offset=0, angle_offset=0) + var/expected_distance = get_dist(target, loc) + kill_count = expected_distance // So the projectile "hits the ground." + target_distance = expected_distance + fired_dir = get_dir(loc, target) + ..() // Does the regular launching stuff. + if(fired_dir & EAST) + transform = turn(transform, -45) + else if(fired_dir & WEST) + transform = turn(transform, 45) + + +// Visuals. +/obj/item/projectile/arc/after_move() + // Handle projectile turning in flight. + // This won't turn if fired north/south, as it looks weird. + var/turn_per_step = 90 / target_distance + if(fired_dir & EAST) + transform = turn(transform, turn_per_step) + else if(fired_dir & WEST) + transform = turn(transform, -turn_per_step) + + // Now for the fake height. + // We need to know how far along our "arc" we are. + var/arc_progress = get_dist(src, original) + var/arc_max_height = (target_distance * world.icon_size) / 2 // TODO: Real math. +// var/arc_center = target_distance / 2 +// var/projectile_position = abs(arc_progress - arc_center) +// var/height_multiplier = projectile_position / arc_center +// height_multiplier = abs(height_multiplier - 1) +// height_multiplier = height_multiplier ** 2 + + +// animate(src, pixel_z = arc_max_height * height_multiplier, time = step_delay) + var/projectile_position = arc_progress / target_distance + var/sine_position = projectile_position * 180 + var/pixel_z_position = arc_max_height * sin(sine_position) + animate(src, pixel_z = pixel_z_position, time = step_delay) + + // Update our shadow. + shadow.forceMove(loc) + +/obj/effect/projectile_shadow + name = "shadow" + desc = "You better avoid the thing coming down!" + icon = 'icons/obj/projectiles.dmi' + icon_state = "arc_shadow" + anchored = TRUE + +////////////// +// Subtypes +////////////// + +// Generic, Hivebot related +/obj/item/projectile/arc/blue_energy + name = "energy missile" + icon_state = "force_missile" + damage = 15 + damage_type = BURN + +// Fragmentation arc shot +/obj/item/projectile/arc/fragmentation + name = "fragmentation shot" + icon_state = "shell" + var/list/fragment_types = list( + /obj/item/projectile/bullet/pellet/fragment, /obj/item/projectile/bullet/pellet/fragment, \ + /obj/item/projectile/bullet/pellet/fragment, /obj/item/projectile/bullet/pellet/fragment/strong + ) + var/fragment_amount = 63 // Same as a grenade. + var/spread_range = 7 + +/obj/item/projectile/arc/fragmentation/on_impact(turf/T) + fragmentate(T, fragment_amount, spread_range, fragment_types) + +// EMP arc shot +/obj/item/projectile/arc/emp_blast + name = "emp blast" + icon_state = "bluespace" + +/obj/item/projectile/arc/emp_blast/on_impact(turf/T) + empulse(T, 2, 4, 7, 10) // Normal EMP grenade. + return ..() + +/obj/item/projectile/arc/emp_blast/weak/on_impact(turf/T) + empulse(T, 1, 2, 3, 4) // Sec EMP grenade. + return ..() + +// Radiation arc shot +/obj/item/projectile/arc/radioactive + name = "radiation blast" + icon_state = "green_pellet" + icon_scale = 2 + var/rad_power = 50 + +/obj/item/projectile/arc/radioactive/on_impact(turf/T) + radiation_repository.radiate(T, rad_power) \ No newline at end of file diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index d5bae0dc228..3448c2a9e94 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -212,7 +212,22 @@ muzzle_type = /obj/effect/projectile/pulse/muzzle /obj/item/projectile/energy/phase - kill_count = 4 + name = "phase wave" + icon_state = "phase" + kill_count = 6 damage = 5 - SA_bonus_damage = 55 // 60 total on animals. - SA_vulnerability = SA_ANIMAL \ No newline at end of file + SA_bonus_damage = 45 // 50 total on animals + SA_vulnerability = SA_ANIMAL + +/obj/item/projectile/energy/phase/light + kill_count = 4 + SA_bonus_damage = 35 // 40 total on animals + +/obj/item/projectile/energy/phase/heavy + kill_count = 8 + SA_bonus_damage = 55 // 60 total on animals + +/obj/item/projectile/energy/phase/heavy/cannon + kill_count = 10 + damage = 15 + SA_bonus_damage = 60 // 75 total on animals \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index 26481d8141a..7a3e00eab8c 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -865,7 +865,7 @@ glass_name = "lime tea" glass_desc = "A tasty mixture of lime and tea. It's apparently good for you!" - cup_name = "cup of berry tea" + cup_name = "cup of lime tea" cup_desc = "A tasty mixture of lime and tea. It's apparently good for you!" /datum/reagent/drink/tea/orangetea @@ -909,9 +909,9 @@ cup_icon_state = "cup_coffee" cup_name = "cup of coffee" - cup_desc = "Don't drop it, or you'll send scalding liquid and porcelain shards everywhere." + cup_desc = "Don't drop it, or you'll send scalding liquid and ceramic shards everywhere." - glass_name = "cup of coffee" + glass_name = "coffee" glass_desc = "Don't drop it, or you'll send scalding liquid and glass shards everywhere." diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 9de15b6915f..c992d0eae2f 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -32,7 +32,7 @@ if(alien == IS_SLIME) chem_effective = 0.75 if(alien != IS_DIONA) - M.heal_organ_damage(6 * removed * chem_effective, 0) + M.heal_organ_damage(4 * removed * chem_effective, 0) //VOREStation Edit /datum/reagent/bicaridine/overdose(var/mob/living/carbon/M, var/alien, var/removed) ..() @@ -67,7 +67,7 @@ chem_effective = 0.5 M.adjustBruteLoss(2 * removed) //Mends burns, but has negative effects with a Promethean's skeletal structure. if(alien != IS_DIONA) - M.heal_organ_damage(0, 6 * removed * chem_effective) + M.heal_organ_damage(0, 4 * removed * chem_effective) //VOREStation edit /datum/reagent/dermaline name = "Dermaline" @@ -85,7 +85,7 @@ if(alien == IS_SLIME) chem_effective = 0.75 if(alien != IS_DIONA) - M.heal_organ_damage(0, 12 * removed * chem_effective) + M.heal_organ_damage(0, 8 * removed * chem_effective) //VOREStation edit /datum/reagent/dylovene name = "Dylovene" @@ -141,20 +141,21 @@ color = "#0080FF" overdose = REAGENTS_OVERDOSE scannable = 1 + metabolism = REM * 0.25 //VOREStation Edit /datum/reagent/dexalin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_VOX) - M.adjustToxLoss(removed * 6) + M.adjustToxLoss(removed * 24) //VOREStation Edit else if(alien == IS_SLIME && dose >= 15) M.add_chemical_effect(CE_PAINKILLER, 15) if(prob(15)) to_chat(M, "You have a moment of clarity as you collapse.") - M.adjustBrainLoss(-5 * removed) + M.adjustBrainLoss(-20 * removed) //VOREStation Edit M.Weaken(6) else if(alien != IS_DIONA) - M.adjustOxyLoss(-15 * removed) + M.adjustOxyLoss(-60 * removed) //VOREStation Edit - holder.remove_reagent("lexorin", 2 * removed) + holder.remove_reagent("lexorin", 8 * removed) //VOREStation Edit /datum/reagent/dexalinp name = "Dexalin Plus" @@ -399,7 +400,7 @@ M.Weaken(5) if(dose >= 10 && M.paralysis < 40) M.AdjustParalysis(1) //Messing with the core with a simple chemical probably isn't the best idea. - M.adjustBrainLoss(-30 * removed * chem_effective) + M.adjustBrainLoss(-8 * removed * chem_effective) //VOREStation Edit M.add_chemical_effect(CE_PAINKILLER, 10 * chem_effective) /datum/reagent/imidazoline diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine_vr.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine_vr.dm index e57d7ae582d..ae4f0b23f8e 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine_vr.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine_vr.dm @@ -62,15 +62,17 @@ /datum/reagent/vermicetol name = "Vermicetol" id = "vermicetol" - description = "A potent chemical that treats burn damage at an exceptional rate and lasts a while." + description = "A potent chemical that treats physical damage at an exceptional rate." taste_description = "sparkles" + taste_mult = 3 reagent_state = SOLID color = "#964e06" - overdose = 10 + overdose = REAGENTS_OVERDOSE * 0.5 scannable = 1 - metabolism = 0.02 - mrate_static = TRUE /datum/reagent/vermicetol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + var/chem_effective = 1 + if(alien == IS_SLIME) + chem_effective = 0.75 if(alien != IS_DIONA) - M.heal_organ_damage(0, 110 * removed) //Not as potent as Kelotane, but lasts LONG. + M.heal_organ_damage(8 * removed * chem_effective, 0) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm index 6c83b0e26da..53ce37b3ef6 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm @@ -482,3 +482,11 @@ /datum/reagent/luminol/touch_mob(var/mob/living/L) L.reveal_blood() + +/datum/reagent/nutriment/biomass + name = "Biomass" + id = "biomass" + description = "A slurry of compounds that contains the basic requirements for life." + taste_description = "salty meat" + reagent_state = LIQUID + color = "#DF9FBF" \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index c86db696325..f05356c46b1 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -501,6 +501,7 @@ id = "ammonia" result = "ammonia" required_reagents = list("hydrogen" = 3, "nitrogen" = 1) + inhibitors = list("phoron" = 1) // Messes with lexorin result_amount = 3 /datum/chemical_reaction/diethylamine @@ -2244,4 +2245,12 @@ id = "qerr_quem" result = "qerr_quem" required_reagents = list("nicotine" = 1, "carbon" = 1, "sugar" = 2) - result_amount = 4 \ No newline at end of file + result_amount = 4 + +// Biomass, for cloning and bioprinters +/datum/chemical_reaction/biomass + name = "Biomass" + id = "biomass" + result = "biomass" + required_reagents = list("protein" = 1, "sugar" = 1, "phoron" = 1) + result_amount = 6 // Roughly 120u per phoron sheet //VOREStation Edit diff --git a/code/modules/reagents/reagent_containers/food/snacks_vr.dm b/code/modules/reagents/reagent_containers/food/snacks_vr.dm index 0b3db9b0658..b8acc3377e2 100644 --- a/code/modules/reagents/reagent_containers/food/snacks_vr.dm +++ b/code/modules/reagents/reagent_containers/food/snacks_vr.dm @@ -165,7 +165,7 @@ /obj/item/weapon/reagent_containers/food/snacks/kitsuneudon name = "kitsune udon" - desc = "A purported favorite of kitsunes in ancient japanese myth: udon noodles, friend egg, and tofu." + desc = "A purported favorite of kitsunes in ancient japanese myth: udon noodles, fried egg, and tofu." icon = 'icons/obj/food_vr.dmi' icon_state = "kitsuneudon" trash = /obj/item/trash/snack_bowl diff --git a/code/modules/reagents/reagent_containers/glass/bottle.dm b/code/modules/reagents/reagent_containers/glass/bottle.dm index 26e88caec0f..159ac6acf3e 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle.dm @@ -55,7 +55,6 @@ var/image/lid = image(icon, src, "lid_bottle") overlays += lid - /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline name = "inaprovaline bottle" desc = "A small bottle. Contains inaprovaline - used to stabilize patients." @@ -63,7 +62,6 @@ icon_state = "bottle-4" prefill = list("inaprovaline" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/toxin name = "toxin bottle" desc = "A small bottle of toxins. Do not drink, it is poisonous." @@ -71,7 +69,6 @@ icon_state = "bottle-3" prefill = list("toxin" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/cyanide name = "cyanide bottle" desc = "A small bottle of cyanide. Bitter almonds?" @@ -79,7 +76,6 @@ icon_state = "bottle-3" prefill = list("cyanide" = 30) //volume changed to match chloral - /obj/item/weapon/reagent_containers/glass/bottle/stoxin name = "soporific bottle" desc = "A small bottle of soporific. Just the fumes make you sleepy." @@ -87,15 +83,13 @@ icon_state = "bottle-3" prefill = list("stoxin" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/chloralhydrate - name = "Chloral Hydrate Bottle" + name = "chloral hydrate bottle" desc = "A small bottle of Choral Hydrate. Mickey's Favorite!" icon = 'icons/obj/chemical.dmi' icon_state = "bottle-3" prefill = list("chloralhydrate" = 30) //Intentionally low since it is so strong. Still enough to knock someone out. - /obj/item/weapon/reagent_containers/glass/bottle/antitoxin name = "dylovene bottle" desc = "A small bottle of dylovene. Counters poisons, and repairs damage. A wonder drug." @@ -103,7 +97,6 @@ icon_state = "bottle-4" prefill = list("anti_toxin" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/mutagen name = "unstable mutagen bottle" desc = "A small bottle of unstable mutagen. Randomly changes the DNA structure of whoever comes in contact." @@ -111,7 +104,6 @@ icon_state = "bottle-1" prefill = list("mutagen" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/ammonia name = "ammonia bottle" desc = "A small bottle." @@ -119,7 +111,6 @@ icon_state = "bottle-1" prefill = list("ammonia" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/eznutrient name = "\improper EZ NUtrient bottle" desc = "A small bottle." @@ -127,7 +118,6 @@ icon_state = "bottle-4" prefill = list("eznutrient" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/left4zed name = "\improper Left-4-Zed bottle" desc = "A small bottle." @@ -135,7 +125,6 @@ icon_state = "bottle-4" prefill = list("left4zed" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/robustharvest name = "\improper Robust Harvest" desc = "A small bottle." @@ -143,7 +132,6 @@ icon_state = "bottle-4" prefill = list("robustharvest" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/diethylamine name = "diethylamine bottle" desc = "A small bottle." @@ -152,32 +140,36 @@ prefill = list("diethylamine" = 60) /obj/item/weapon/reagent_containers/glass/bottle/pacid - name = "Polytrinic Acid Bottle" + name = "polytrinic acid bottle" desc = "A small bottle. Contains a small amount of Polytrinic Acid" icon = 'icons/obj/chemical.dmi' icon_state = "bottle-4" prefill = list("pacid" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/adminordrazine - name = "Adminordrazine Bottle" + name = "adminordrazine bottle" desc = "A small bottle. Contains the liquid essence of the gods." icon = 'icons/obj/drinks.dmi' icon_state = "holyflask" prefill = list("adminordrazine" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/capsaicin - name = "Capsaicin Bottle" + name = "capsaicin bottle" desc = "A small bottle. Contains hot sauce." icon = 'icons/obj/chemical.dmi' icon_state = "bottle-4" prefill = list("capsaicin" = 60) - /obj/item/weapon/reagent_containers/glass/bottle/frostoil - name = "Frost Oil Bottle" + name = "frost oil bottle" desc = "A small bottle. Contains cold sauce." icon = 'icons/obj/chemical.dmi' icon_state = "bottle-4" prefill = list("frostoil" = 60) + +/obj/item/weapon/reagent_containers/glass/bottle/biomass + name = "biomass bottle" + desc = "A bottle of raw biomass! Gross!" + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle-3" + prefill = list("biomass" = 60) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index ef0d4a2100d..724cee9a6fb 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -49,7 +49,7 @@ if(H.a_intent != I_HELP) to_chat(user, "[H] is resisting your attempt to inject them with \the [src].") to_chat(H, " [user] is trying to inject you with \the [src]!") - if(!do_after(user, 30)) + if(!do_after(user, 30, H)) return user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 68cc9d6921b..3632922d1b0 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -333,8 +333,8 @@ /obj/item/weapon/reagent_containers/syringe/inaprovaline/New() ..() reagents.add_reagent("inaprovaline", 15) - mode = SYRINGE_INJECT - update_icon() + //mode = SYRINGE_INJECT //VOREStation Edit - Starts capped + //update_icon() /obj/item/weapon/reagent_containers/syringe/antitoxin name = "Syringe (anti-toxin)" @@ -343,8 +343,8 @@ /obj/item/weapon/reagent_containers/syringe/antitoxin/New() ..() reagents.add_reagent("anti_toxin", 15) - mode = SYRINGE_INJECT - update_icon() + //mode = SYRINGE_INJECT //VOREStation Edit - Starts capped + //update_icon() /obj/item/weapon/reagent_containers/syringe/antiviral name = "Syringe (spaceacillin)" @@ -353,8 +353,8 @@ /obj/item/weapon/reagent_containers/syringe/antiviral/New() ..() reagents.add_reagent("spaceacillin", 15) - mode = SYRINGE_INJECT - update_icon() + //mode = SYRINGE_INJECT //VOREStation Edit - Starts capped + //update_icon() /obj/item/weapon/reagent_containers/syringe/drugs name = "Syringe (drugs)" @@ -365,8 +365,8 @@ reagents.add_reagent("space_drugs", 5) reagents.add_reagent("mindbreaker", 5) reagents.add_reagent("cryptobiolin", 5) - mode = SYRINGE_INJECT - update_icon() + //mode = SYRINGE_INJECT //VOREStation Edit - Starts capped + //update_icon() /obj/item/weapon/reagent_containers/syringe/ld50_syringe/choral/New() ..() diff --git a/code/modules/reagents/reagent_containers/syringes_vr.dm b/code/modules/reagents/reagent_containers/syringes_vr.dm index b3c96889196..e940f23454e 100644 --- a/code/modules/reagents/reagent_containers/syringes_vr.dm +++ b/code/modules/reagents/reagent_containers/syringes_vr.dm @@ -43,7 +43,11 @@ //Dirtiness should be very low if you're the first injectee. If you're spam-injecting 4 people in a row around you though, //This gives the last one a 30% chance of infection. - if(prob(dirtiness+(targets.len-1)*10)) + var/infect_chance = dirtiness //Start with dirtiness + if(infect_chance <= 10 && (hash in targets)) //Extra fast uses on target is free + infect_chance = 0 + infect_chance += (targets.len-1)*10 //Extra 10% per extra target + if(prob(infect_chance)) log_and_message_admins("[loc] infected [target]'s [eo.name] with \the [src].") infect_limb(eo) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index dc35852eedc..494659fb1e3 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -5,8 +5,7 @@ desc = "..." icon = 'icons/obj/objects.dmi' icon_state = "watertank" - plane = TURF_PLANE - layer = TABLE_LAYER // Above catwalks, hopefully below other things + layer = TABLE_LAYER density = 1 anchored = 0 pressure_resistance = 2*ONE_ATMOSPHERE diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index ca5a88db4ba..106c655ae25 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -79,1828 +79,4 @@ other types of metals and chemistry for reagents). req_tech = list(TECH_DATA = 1) materials = list(DEFAULT_WALL_MATERIAL = 30, "glass" = 10) build_path = /obj/item/weapon/disk/tech_disk - sort_string = "GAAAB" - -/datum/design/item/stock_part - build_type = PROTOLATHE - -/datum/design/item/stock_part/AssembleDesignName() - ..() - name = "Component design ([item_name])" - -/datum/design/item/stock_part/AssembleDesignDesc() - if(!desc) - desc = "A stock part used in the construction of various devices." - -/datum/design/item/stock_part/basic_capacitor - id = "basic_capacitor" - req_tech = list(TECH_POWER = 1) - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) - build_path = /obj/item/weapon/stock_parts/capacitor - sort_string = "CAAAA" - -/datum/design/item/stock_part/adv_capacitor - id = "adv_capacitor" - req_tech = list(TECH_POWER = 3) - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) - build_path = /obj/item/weapon/stock_parts/capacitor/adv - sort_string = "CAAAB" - -/datum/design/item/stock_part/super_capacitor - id = "super_capacitor" - req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4) - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, "gold" = 20) - build_path = /obj/item/weapon/stock_parts/capacitor/super - sort_string = "CAAAC" - -/datum/design/item/stock_part/micro_mani - id = "micro_mani" - req_tech = list(TECH_MATERIAL = 1, TECH_DATA = 1) - materials = list(DEFAULT_WALL_MATERIAL = 30) - build_path = /obj/item/weapon/stock_parts/manipulator - sort_string = "CAABA" - -/datum/design/item/stock_part/nano_mani - id = "nano_mani" - req_tech = list(TECH_MATERIAL = 3, TECH_DATA = 2) - materials = list(DEFAULT_WALL_MATERIAL = 30) - build_path = /obj/item/weapon/stock_parts/manipulator/nano - sort_string = "CAABB" - -/datum/design/item/stock_part/pico_mani - id = "pico_mani" - req_tech = list(TECH_MATERIAL = 5, TECH_DATA = 2) - materials = list(DEFAULT_WALL_MATERIAL = 30) - build_path = /obj/item/weapon/stock_parts/manipulator/pico - sort_string = "CAABC" - -/datum/design/item/stock_part/basic_matter_bin - id = "basic_matter_bin" - req_tech = list(TECH_MATERIAL = 1) - materials = list(DEFAULT_WALL_MATERIAL = 80) - build_path = /obj/item/weapon/stock_parts/matter_bin - sort_string = "CAACA" - -/datum/design/item/stock_part/adv_matter_bin - id = "adv_matter_bin" - req_tech = list(TECH_MATERIAL = 3) - materials = list(DEFAULT_WALL_MATERIAL = 80) - build_path = /obj/item/weapon/stock_parts/matter_bin/adv - sort_string = "CAACB" - -/datum/design/item/stock_part/super_matter_bin - id = "super_matter_bin" - req_tech = list(TECH_MATERIAL = 5) - materials = list(DEFAULT_WALL_MATERIAL = 80) - build_path = /obj/item/weapon/stock_parts/matter_bin/super - sort_string = "CAACC" - -/datum/design/item/stock_part/basic_micro_laser - id = "basic_micro_laser" - req_tech = list(TECH_MAGNET = 1) - materials = list(DEFAULT_WALL_MATERIAL = 10, "glass" = 20) - build_path = /obj/item/weapon/stock_parts/micro_laser - sort_string = "CAADA" - -/datum/design/item/stock_part/high_micro_laser - id = "high_micro_laser" - req_tech = list(TECH_MAGNET = 3) - materials = list(DEFAULT_WALL_MATERIAL = 10, "glass" = 20) - build_path = /obj/item/weapon/stock_parts/micro_laser/high - sort_string = "CAADB" - -/datum/design/item/stock_part/ultra_micro_laser - id = "ultra_micro_laser" - req_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 5) - materials = list(DEFAULT_WALL_MATERIAL = 10, "glass" = 20, "uranium" = 10) - build_path = /obj/item/weapon/stock_parts/micro_laser/ultra - sort_string = "CAADC" - -/datum/design/item/stock_part/basic_sensor - id = "basic_sensor" - req_tech = list(TECH_MAGNET = 1) - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 20) - build_path = /obj/item/weapon/stock_parts/scanning_module - sort_string = "CAAEA" - -/datum/design/item/stock_part/adv_sensor - id = "adv_sensor" - req_tech = list(TECH_MAGNET = 3) - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 20) - build_path = /obj/item/weapon/stock_parts/scanning_module/adv - sort_string = "CAAEB" - -/datum/design/item/stock_part/phasic_sensor - id = "phasic_sensor" - req_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 3) - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 20, "silver" = 10) - build_path = /obj/item/weapon/stock_parts/scanning_module/phasic - sort_string = "CAAEC" - -/datum/design/item/stock_part/RPED - name = "Rapid Part Exchange Device" - desc = "Special mechanical module made to store, sort, and apply standard machine parts." - id = "rped" - req_tech = list(TECH_ENGINEERING = 3, TECH_MATERIAL = 3) - materials = list(DEFAULT_WALL_MATERIAL = 15000, "glass" = 5000) - build_path = /obj/item/weapon/storage/part_replacer - sort_string = "CBAAA" - -/datum/design/item/powercell - build_type = PROTOLATHE | MECHFAB - -/datum/design/item/powercell/AssembleDesignName() - name = "Power Cell Model ([item_name])" - -/datum/design/item/powercell/AssembleDesignDesc() - if(build_path) - var/obj/item/weapon/cell/C = build_path - desc = "Allows the construction of power cells that can hold [initial(C.maxcharge)] units of energy." - -/datum/design/item/powercell/Fabricate() - var/obj/item/weapon/cell/C = ..() - C.charge = 0 //shouldn't produce power out of thin air. - return C - -/datum/design/item/powercell/basic - name = "basic" - build_type = PROTOLATHE | MECHFAB - id = "basic_cell" - req_tech = list(TECH_POWER = 1) - materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 50) - build_path = /obj/item/weapon/cell - category = "Misc" - sort_string = "DAAAA" - -/datum/design/item/powercell/high - name = "high-capacity" - build_type = PROTOLATHE | MECHFAB - id = "high_cell" - req_tech = list(TECH_POWER = 2) - materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 60) - build_path = /obj/item/weapon/cell/high - category = "Misc" - sort_string = "DAAAB" - -/datum/design/item/powercell/super - name = "super-capacity" - id = "super_cell" - req_tech = list(TECH_POWER = 3, TECH_MATERIAL = 2) - materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 70) - build_path = /obj/item/weapon/cell/super - category = "Misc" - sort_string = "DAAAC" - -/datum/design/item/powercell/hyper - name = "hyper-capacity" - id = "hyper_cell" - req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4) - materials = list(DEFAULT_WALL_MATERIAL = 400, "gold" = 150, "silver" = 150, "glass" = 70) - build_path = /obj/item/weapon/cell/hyper - category = "Misc" - sort_string = "DAAAD" - -/datum/design/item/powercell/device - name = "device" - build_type = PROTOLATHE - id = "device" - materials = list(DEFAULT_WALL_MATERIAL = 350, "glass" = 25) - build_path = /obj/item/weapon/cell/device - category = "Misc" - sort_string = "DAABA" - -/datum/design/item/powercell/weapon - name = "weapon" - build_type = PROTOLATHE - id = "weapon" - materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 50) - build_path = /obj/item/weapon/cell/device/weapon - category = "Misc" - sort_string = "DAABB" - -/datum/design/item/hud - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) - -/datum/design/item/hud/AssembleDesignName() - ..() - name = "HUD glasses prototype ([item_name])" - -/datum/design/item/hud/AssembleDesignDesc() - desc = "Allows for the construction of \a [item_name] HUD glasses." - -/datum/design/item/hud/health - name = "health scanner" - id = "health_hud" - req_tech = list(TECH_BIO = 2, TECH_MAGNET = 3) - build_path = /obj/item/clothing/glasses/hud/health - sort_string = "GAAAA" - -/datum/design/item/hud/security - name = "security records" - id = "security_hud" - req_tech = list(TECH_MAGNET = 3, TECH_COMBAT = 2) - build_path = /obj/item/clothing/glasses/hud/security - sort_string = "GAAAB" - -/datum/design/item/hud/mesons - name = "Optical meson scanners design" - desc = "Using the meson-scanning technology those glasses allow you to see through walls, floor or anything else." - id = "mesons" - req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) - build_path = /obj/item/clothing/glasses/meson - sort_string = "GAAAC" - -/datum/design/item/weapon/mining/AssembleDesignName() - ..() - name = "Mining equipment design ([item_name])" - -/datum/design/item/weapon/mining/jackhammer - id = "jackhammer" - req_tech = list(TECH_MATERIAL = 3, TECH_POWER = 2, TECH_ENGINEERING = 2) - materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 500, "silver" = 500) - build_path = /obj/item/weapon/pickaxe/jackhammer - sort_string = "KAAAA" - -/datum/design/item/weapon/mining/drill - id = "drill" - req_tech = list(TECH_MATERIAL = 2, TECH_POWER = 3, TECH_ENGINEERING = 2) - materials = list(DEFAULT_WALL_MATERIAL = 6000, "glass" = 1000) //expensive, but no need for miners. - build_path = /obj/item/weapon/pickaxe/drill - sort_string = "KAAAB" - -/datum/design/item/weapon/mining/plasmacutter - id = "plasmacutter" - req_tech = list(TECH_MATERIAL = 4, TECH_PHORON = 3, TECH_ENGINEERING = 3) - materials = list(DEFAULT_WALL_MATERIAL = 1500, "glass" = 500, "gold" = 500, "phoron" = 500) - build_path = /obj/item/weapon/pickaxe/plasmacutter - sort_string = "KAAAC" - -/datum/design/item/weapon/mining/pick_diamond - id = "pick_diamond" - req_tech = list(TECH_MATERIAL = 6) - materials = list("diamond" = 3000) - build_path = /obj/item/weapon/pickaxe/diamond - sort_string = "KAAAD" - -/datum/design/item/weapon/mining/drill_diamond - id = "drill_diamond" - req_tech = list(TECH_MATERIAL = 6, TECH_POWER = 4, TECH_ENGINEERING = 4) - materials = list(DEFAULT_WALL_MATERIAL = 3000, "glass" = 1000, "diamond" = 2000) - build_path = /obj/item/weapon/pickaxe/diamonddrill - sort_string = "KAAAE" - -/datum/design/item/device/depth_scanner - desc = "Used to check spatial depth and density of rock outcroppings." - id = "depth_scanner" - req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2, TECH_BLUESPACE = 2) - materials = list(DEFAULT_WALL_MATERIAL = 1000,"glass" = 1000) - build_path = /obj/item/device/depth_scanner - sort_string = "KAAAF" - -/////////////////////////////////// -/////////Shield Generators///////// -/////////////////////////////////// -/datum/design/circuit/shield - req_tech = list(TECH_BLUESPACE = 4, TECH_PHORON = 3) - materials = list("$glass" = 2000, "sacid" = 20, "$phoron" = 10000, "$diamond" = 5000, "$gold" = 10000) - -/datum/design/item/medical - materials = list(DEFAULT_WALL_MATERIAL = 30, "glass" = 20) - -/datum/design/item/medical/AssembleDesignName() - ..() - name = "Biotech device prototype ([item_name])" - -/datum/design/item/medical/robot_scanner - desc = "A hand-held scanner able to diagnose robotic injuries." - id = "robot_scanner" - req_tech = list(TECH_MAGNET = 3, TECH_BIO = 2, TECH_ENGINEERING = 3) - materials = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 200) - build_path = /obj/item/device/robotanalyzer - sort_string = "MACFA" - -/datum/design/item/medical/mass_spectrometer - desc = "A device for analyzing chemicals in blood." - id = "mass_spectrometer" - req_tech = list(TECH_BIO = 2, TECH_MAGNET = 2) - build_path = /obj/item/device/mass_spectrometer - sort_string = "MACAA" - -/datum/design/item/medical/adv_mass_spectrometer - desc = "A device for analyzing chemicals in blood and their quantities." - id = "adv_mass_spectrometer" - req_tech = list(TECH_BIO = 2, TECH_MAGNET = 4) - build_path = /obj/item/device/mass_spectrometer/adv - sort_string = "MACAB" - -/datum/design/item/medical/reagent_scanner - desc = "A device for identifying chemicals." - id = "reagent_scanner" - req_tech = list(TECH_BIO = 2, TECH_MAGNET = 2) - build_path = /obj/item/device/reagent_scanner - sort_string = "MACBA" - -/datum/design/item/medical/adv_reagent_scanner - desc = "A device for identifying chemicals and their proportions." - id = "adv_reagent_scanner" - req_tech = list(TECH_BIO = 2, TECH_MAGNET = 4) - build_path = /obj/item/device/reagent_scanner/adv - sort_string = "MACBB" - -/datum/design/item/beaker/AssembleDesignName() - name = "Beaker prototype ([item_name])" - -/datum/design/item/beaker/noreact - name = "cryostasis" - desc = "A cryostasis beaker that allows for chemical storage without reactions. Can hold up to 50 units." - id = "splitbeaker" - req_tech = list(TECH_MATERIAL = 2) - materials = list(DEFAULT_WALL_MATERIAL = 3000) - build_path = /obj/item/weapon/reagent_containers/glass/beaker/noreact - sort_string = "MADAA" - -/datum/design/item/beaker/bluespace - name = TECH_BLUESPACE - desc = "A bluespace beaker, powered by experimental bluespace technology and Element Cuban combined with the Compound Pete. Can hold up to 300 units." - id = "bluespacebeaker" - req_tech = list(TECH_BLUESPACE = 2, TECH_MATERIAL = 6) - materials = list(DEFAULT_WALL_MATERIAL = 3000, "phoron" = 3000, "diamond" = 500) - build_path = /obj/item/weapon/reagent_containers/glass/beaker/bluespace - sort_string = "MADAB" - -/datum/design/item/medical/nanopaste - desc = "A tube of paste containing swarms of repair nanites. Very effective in repairing robotic machinery." - id = "nanopaste" - req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3) - materials = list(DEFAULT_WALL_MATERIAL = 7000, "glass" = 7000) - build_path = /obj/item/stack/nanopaste - sort_string = "MBAAA" - -/datum/design/item/medical/scalpel_laser1 - name = "Basic Laser Scalpel" - desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks basic and could be improved." - id = "scalpel_laser1" - req_tech = list(TECH_BIO = 2, TECH_MATERIAL = 2, TECH_MAGNET = 2) - materials = list(DEFAULT_WALL_MATERIAL = 12500, "glass" = 7500) - build_path = /obj/item/weapon/surgical/scalpel/laser1 - sort_string = "MBBAA" - -/datum/design/item/medical/scalpel_laser2 - name = "Improved Laser Scalpel" - desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks somewhat advanced." - id = "scalpel_laser2" - req_tech = list(TECH_BIO = 3, TECH_MATERIAL = 4, TECH_MAGNET = 4) - materials = list(DEFAULT_WALL_MATERIAL = 12500, "glass" = 7500, "silver" = 2500) - build_path = /obj/item/weapon/surgical/scalpel/laser2 - sort_string = "MBBAB" - -/datum/design/item/medical/scalpel_laser3 - name = "Advanced Laser Scalpel" - desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks to be the pinnacle of precision energy cutlery!" - id = "scalpel_laser3" - req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 6, TECH_MAGNET = 5) - materials = list(DEFAULT_WALL_MATERIAL = 12500, "glass" = 7500, "silver" = 2000, "gold" = 1500) - build_path = /obj/item/weapon/surgical/scalpel/laser3 - sort_string = "MBBAC" - -/datum/design/item/medical/scalpel_manager - name = "Incision Management System" - desc = "A true extension of the surgeon's body, this marvel instantly and completely prepares an incision allowing for the immediate commencement of therapeutic steps." - id = "scalpel_manager" - req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 7, TECH_MAGNET = 5, TECH_DATA = 4) - materials = list (DEFAULT_WALL_MATERIAL = 12500, "glass" = 7500, "silver" = 1500, "gold" = 1500, "diamond" = 750) - build_path = /obj/item/weapon/surgical/scalpel/manager - sort_string = "MBBAD" - -/datum/design/item/medical/bone_clamp - name = "Bone Clamp" - desc = "A miracle of modern science, this tool rapidly knits together bone, without the need for bone gel." - id = "bone_clamp" - req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 5, TECH_MAGNET = 4, TECH_DATA = 4) - materials = list (DEFAULT_WALL_MATERIAL = 12500, "glass" = 7500, "silver" = 2500) - build_path = /obj/item/weapon/surgical/bone_clamp - sort_string = "MBBAE" - -/datum/design/item/medical/advanced_roller - name = "advanced roller bed" - desc = "A more advanced version of the regular roller bed, with inbuilt surgical stabilisers and an improved folding system." - id = "roller_bed" - req_tech = list(TECH_BIO = 3, TECH_MATERIAL = 3, TECH_MAGNET = 3) - materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 2000, "phoron" = 2000) - build_path = /obj/item/roller/adv - sort_string = "MBBAF" - -/datum/design/item/medical/improved_analyzer - name = "improved health analyzer" - desc = "A prototype version of the regular health analyzer, able to distinguish the location of more serious injuries as well as accurately determine radiation levels." - id = "improved_analyzer" - req_tech = list(TECH_MAGNET = 5, TECH_BIO = 6) - materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 1500) - build_path = /obj/item/device/healthanalyzer/improved - sort_string = "MBBAG" - -/datum/design/item/implant - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) - -/datum/design/item/implant/AssembleDesignName() - ..() - name = "Implantable biocircuit design ([item_name])" - -/datum/design/item/implant/chemical - name = "chemical" - id = "implant_chem" - req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3) - build_path = /obj/item/weapon/implantcase/chem - sort_string = "MFAAA" - -/datum/design/item/implant/freedom - name = "freedom" - id = "implant_free" - req_tech = list(TECH_ILLEGAL = 2, TECH_BIO = 3) - build_path = /obj/item/weapon/implantcase/freedom - sort_string = "MFAAB" - -/datum/design/item/weapon/AssembleDesignName() - ..() - name = "Weapon prototype ([item_name])" - -/datum/design/item/weapon/AssembleDesignDesc() - if(!desc) - if(build_path) - var/obj/item/I = build_path - desc = initial(I.desc) - ..() - -/datum/design/item/weapon/stunrevolver - id = "stunrevolver" - req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2) - materials = list(DEFAULT_WALL_MATERIAL = 4000) - build_path = /obj/item/weapon/gun/energy/stunrevolver - sort_string = "TAAAA" - -/datum/design/item/weapon/nuclear_gun - id = "nuclear_gun" - req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 5, TECH_POWER = 3) - materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000, "uranium" = 500) - build_path = /obj/item/weapon/gun/energy/gun/nuclear - sort_string = "TAAAB" - -/datum/design/item/weapon/lasercannon - desc = "The lasing medium of this prototype is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core." - id = "lasercannon" - req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3) - materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 1000, "diamond" = 2000) - build_path = /obj/item/weapon/gun/energy/lasercannon - sort_string = "TAAAC" - -/datum/design/item/weapon/phoronpistol - id = "ppistol" - req_tech = list(TECH_COMBAT = 5, TECH_PHORON = 4) - materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000, "phoron" = 3000) - build_path = /obj/item/weapon/gun/energy/toxgun - sort_string = "TAAAD" - -/datum/design/item/weapon/decloner - id = "decloner" - req_tech = list(TECH_COMBAT = 8, TECH_MATERIAL = 7, TECH_BIO = 5, TECH_POWER = 6) - materials = list("gold" = 5000,"uranium" = 10000) - build_path = /obj/item/weapon/gun/energy/decloner - sort_string = "TAAAE" - -/datum/design/item/weapon/smg - id = "smg" - req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3) - materials = list(DEFAULT_WALL_MATERIAL = 8000, "silver" = 2000, "diamond" = 1000) - build_path = /obj/item/weapon/gun/projectile/automatic - sort_string = "TAABA" - -/datum/design/item/weapon/ammo_9mm - id = "ammo_9mm" - req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3) - materials = list(DEFAULT_WALL_MATERIAL = 3750, "silver" = 100) - build_path = /obj/item/ammo_magazine/box/c9mm - sort_string = "TAACA" - -/datum/design/item/weapon/stunshell - desc = "A stunning shell for a shotgun." - id = "stunshell" - req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3) - materials = list(DEFAULT_WALL_MATERIAL = 4000) - build_path = /obj/item/ammo_casing/a12g/stunshell - sort_string = "TAACB" - -/datum/design/item/weapon/chemsprayer - desc = "An advanced chem spraying device." - id = "chemsprayer" - req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_BIO = 2) - materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000) - build_path = /obj/item/weapon/reagent_containers/spray/chemsprayer - sort_string = "TABAA" - -/datum/design/item/weapon/rapidsyringe - id = "rapidsyringe" - req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_BIO = 2) - materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000) - build_path = /obj/item/weapon/gun/launcher/syringe/rapid - sort_string = "TABAB" - -/datum/design/item/weapon/temp_gun - desc = "A gun that shoots high-powered glass-encased energy temperature bullets." - id = "temp_gun" - req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 4, TECH_POWER = 3, TECH_MAGNET = 2) - materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 500, "silver" = 3000) - build_path = /obj/item/weapon/gun/energy/temperature - sort_string = "TABAC" - -/datum/design/item/weapon/large_grenade - id = "large_Grenade" - req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2) - materials = list(DEFAULT_WALL_MATERIAL = 3000) - build_path = /obj/item/weapon/grenade/chem_grenade/large - sort_string = "TACAA" - -/datum/design/item/weapon/dartgun - desc = "A gun that fires small hollow chemical-payload darts." - id = "dartgun_r" - req_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 4, TECH_BIO = 4, TECH_MAGNET = 3, TECH_ILLEGAL = 1) - materials = list(DEFAULT_WALL_MATERIAL = 5000, "gold" = 5000, "silver" = 2500, "glass" = 750) - build_path = /obj/item/weapon/gun/projectile/dartgun/research - sort_string = "TACAB" - -/datum/design/item/weapon/dartgunmag_small - id = "dartgun_mag_s" - req_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 2, TECH_BIO = 2, TECH_MAGNET = 1, TECH_ILLEGAL = 1) - materials = list(DEFAULT_WALL_MATERIAL = 300, "gold" = 100, "silver" = 100, "glass" = 300) - build_path = /obj/item/ammo_magazine/chemdart/small - sort_string = "TACAC" - -/datum/design/item/weapon/dartgun_ammo_small - id = "dartgun_ammo_s" - req_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 2, TECH_BIO = 2, TECH_MAGNET = 1, TECH_ILLEGAL = 1) - materials = list(DEFAULT_WALL_MATERIAL = 50, "gold" = 30, "silver" = 30, "glass" = 50) - build_path = /obj/item/ammo_casing/chemdart/small - sort_string = "TACAD" - -/datum/design/item/weapon/dartgunmag_med - id = "dartgun_mag_m" - req_tech = list(TECH_COMBAT = 7, TECH_MATERIAL = 2, TECH_BIO = 2, TECH_MAGNET = 1, TECH_ILLEGAL = 1) - materials = list(DEFAULT_WALL_MATERIAL = 500, "gold" = 150, "silver" = 150, "diamond" = 200, "glass" = 400) - build_path = /obj/item/ammo_magazine/chemdart - sort_string = "TACAE" - -/datum/design/item/weapon/dartgun_ammo_med - id = "dartgun_ammo_m" - req_tech = list(TECH_COMBAT = 7, TECH_MATERIAL = 2, TECH_BIO = 2, TECH_MAGNET = 1, TECH_ILLEGAL = 1) - materials = list(DEFAULT_WALL_MATERIAL = 80, "gold" = 40, "silver" = 40, "glass" = 60) - build_path = /obj/item/ammo_casing/chemdart - sort_string = "TACAF" - -/datum/design/item/weapon/fuelrod - id = "fuelrod_gun" - req_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 4, TECH_PHORON = 4, TECH_ILLEGAL = 5, TECH_MAGNET = 5) - materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 2000, "gold" = 500, "silver" = 500, "uranium" = 1000, "phoron" = 3000, "diamond" = 1000) - build_path = /obj/item/weapon/gun/magnetic/fuelrod - sort_string = "TACBA" - -/datum/design/item/weapon/flora_gun - id = "flora_gun" - req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3, TECH_POWER = 3) - materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 500, "uranium" = 500) - build_path = /obj/item/weapon/gun/energy/floragun - sort_string = "TBAAA" - -/datum/design/item/weapon/slimebation - id = "slimebation" - req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2, TECH_POWER = 3, TECH_COMBAT = 3) - materials = list(DEFAULT_WALL_MATERIAL = 5000) - build_path = /obj/item/weapon/melee/baton/slime - sort_string = "TBAAB" - -/datum/design/item/weapon/slimetaser - id = "slimetaser" - req_tech = list(TECH_MATERIAL = 3, TECH_BIO = 3, TECH_POWER = 4, TECH_COMBAT = 4) - materials = list(DEFAULT_WALL_MATERIAL = 5000) - build_path = /obj/item/weapon/gun/energy/taser/xeno - sort_string = "TBAAC" - -/datum/design/item/stock_part/subspace_ansible - id = "s-ansible" - req_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - materials = list(DEFAULT_WALL_MATERIAL = 80, "silver" = 20) - build_path = /obj/item/weapon/stock_parts/subspace/ansible - sort_string = "UAAAA" - -/datum/design/item/stock_part/hyperwave_filter - id = "s-filter" - req_tech = list(TECH_DATA = 3, TECH_MAGNET = 3) - materials = list(DEFAULT_WALL_MATERIAL = 40, "silver" = 10) - build_path = /obj/item/weapon/stock_parts/subspace/sub_filter - sort_string = "UAAAB" - -/datum/design/item/stock_part/subspace_amplifier - id = "s-amplifier" - req_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - materials = list(DEFAULT_WALL_MATERIAL = 10, "gold" = 30, "uranium" = 15) - build_path = /obj/item/weapon/stock_parts/subspace/amplifier - sort_string = "UAAAC" - -/datum/design/item/stock_part/subspace_treatment - id = "s-treatment" - req_tech = list(TECH_DATA = 3, TECH_MAGNET = 2, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - materials = list(DEFAULT_WALL_MATERIAL = 10, "silver" = 20) - build_path = /obj/item/weapon/stock_parts/subspace/treatment - sort_string = "UAAAD" - -/datum/design/item/stock_part/subspace_analyzer - id = "s-analyzer" - req_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - materials = list(DEFAULT_WALL_MATERIAL = 10, "gold" = 15) - build_path = /obj/item/weapon/stock_parts/subspace/analyzer - sort_string = "UAAAE" - -/datum/design/item/stock_part/subspace_crystal - id = "s-crystal" - req_tech = list(TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - materials = list("glass" = 1000, "silver" = 20, "gold" = 20) - build_path = /obj/item/weapon/stock_parts/subspace/crystal - sort_string = "UAAAF" - -/datum/design/item/stock_part/subspace_transmitter - id = "s-transmitter" - req_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 5, TECH_BLUESPACE = 3) - materials = list("glass" = 100, "silver" = 10, "uranium" = 15) - build_path = /obj/item/weapon/stock_parts/subspace/transmitter - sort_string = "UAAAG" - -/datum/design/item/device/ano_scanner - name = "Alden-Saraspova counter" - id = "ano_scanner" - desc = "Aids in triangulation of exotic particles." - req_tech = list(TECH_BLUESPACE = 3, TECH_MAGNET = 3) - materials = list(DEFAULT_WALL_MATERIAL = 10000,"glass" = 5000) - build_path = /obj/item/device/ano_scanner - sort_string = "UAAAH" - -/datum/design/item/light_replacer - name = "Light replacer" - desc = "A device to automatically replace lights. Refill with working lightbulbs." - id = "light_replacer" - req_tech = list(TECH_MAGNET = 3, TECH_MATERIAL = 4) - materials = list(DEFAULT_WALL_MATERIAL = 1500, "silver" = 150, "glass" = 3000) - build_path = /obj/item/device/lightreplacer - sort_string = "VAAAH" - -datum/design/item/laserpointer - name = "laser pointer" - desc = "Don't shine it in your eyes!" - id = "laser_pointer" - req_tech = list(TECH_MAGNET = 3) - materials = list(DEFAULT_WALL_MATERIAL = 100, "glass" = 50) - build_path = /obj/item/device/laser_pointer - sort_string = "VAAAI" - -/datum/design/item/paicard - name = "'pAI', personal artificial intelligence device" - id = "paicard" - req_tech = list(TECH_DATA = 2) - materials = list("glass" = 500, DEFAULT_WALL_MATERIAL = 500) - build_path = /obj/item/device/paicard - sort_string = "VABAI" - -/datum/design/item/communicator - name = "Communicator" - id = "communicator" - req_tech = list(TECH_DATA = 2, TECH_MAGNET = 2) - materials = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 500) - build_path = /obj/item/device/communicator - sort_string = "VABAJ" - -/datum/design/item/intellicard - name = "'intelliCore', AI preservation and transportation system" - desc = "Allows for the construction of an intelliCore." - id = "intellicore" - req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 4) - materials = list("glass" = 1000, "gold" = 200) - build_path = /obj/item/device/aicard - sort_string = "VACAA" - -/datum/design/item/dronebrain - name = "Robotic intelligence circuit" - id = "dronebrain" - req_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 5, TECH_DATA = 4) - build_type = PROTOLATHE | PROSFAB - materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 500) - build_path = /obj/item/device/mmi/digital/robot - category = "Misc" - sort_string = "VACAC" - -/datum/design/item/posibrain - name = "Positronic brain" - id = "posibrain" - req_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 6, TECH_BLUESPACE = 2, TECH_DATA = 4) - build_type = PROTOLATHE | PROSFAB - materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 500, "phoron" = 500, "diamond" = 100) - build_path = /obj/item/device/mmi/digital/posibrain - category = "Misc" - sort_string = "VACAB" - -/datum/design/item/mmi - name = "Man-machine interface" - id = "mmi" - req_tech = list(TECH_DATA = 2, TECH_BIO = 3) - build_type = PROTOLATHE | PROSFAB - materials = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500) - build_path = /obj/item/device/mmi - category = "Misc" - sort_string = "VACBA" - -/datum/design/item/beacon - name = "Bluespace tracking beacon design" - id = "beacon" - req_tech = list(TECH_BLUESPACE = 1) - materials = list (DEFAULT_WALL_MATERIAL = 20, "glass" = 10) - build_path = /obj/item/device/radio/beacon - sort_string = "VADAA" - -/datum/design/item/gps - name = "Triangulating device design" - desc = "Triangulates approximate co-ordinates using a nearby satellite network." - id = "gps" - req_tech = list(TECH_MATERIAL = 2, TECH_DATA = 2, TECH_BLUESPACE = 2) - materials = list(DEFAULT_WALL_MATERIAL = 500) - build_path = /obj/item/device/gps - sort_string = "VADAB" - -/datum/design/item/beacon_locator - name = "Beacon tracking pinpointer" - desc = "Used to scan and locate signals on a particular frequency." - id = "beacon_locator" - req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 2, TECH_BLUESPACE = 3) - materials = list(DEFAULT_WALL_MATERIAL = 1000,"glass" = 500) - build_path = /obj/item/device/beacon_locator - sort_string = "VADAC" - -/datum/design/item/bag_holding - name = "'Bag of Holding', an infinite capacity bag prototype" - desc = "Using localized pockets of bluespace this bag prototype offers incredible storage capacity with the contents weighting nothing. It's a shame the bag itself is pretty heavy." - id = "bag_holding" - req_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 6) - materials = list("gold" = 3000, "diamond" = 1500, "uranium" = 250) - build_path = /obj/item/weapon/storage/backpack/holding - sort_string = "VAEAA" - -/datum/design/item/dufflebag_holding - name = "'DuffleBag of Holding', an infinite capacity dufflebag prototype" - desc = "A minaturized prototype of the popular Bag of Holding, the Dufflebag of Holding is, functionally, identical to the bag of holding, but comes in a more stylish and compact form." - id = "dufflebag_holding" - req_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 6) - materials = list("gold" = 3000, "diamond" = 1500, "uranium" = 250) - build_path = /obj/item/weapon/storage/backpack/holding/duffle - sort_string = "VAEAB" - -/datum/design/item/binaryencrypt - name = "Binary encryption key" - desc = "Allows for deciphering the binary channel on-the-fly." - id = "binaryencrypt" - req_tech = list(TECH_ILLEGAL = 2) - materials = list(DEFAULT_WALL_MATERIAL = 300, "glass" = 300) - build_path = /obj/item/device/encryptionkey/binary - sort_string = "VASAA" - -/datum/design/item/chameleon - name = "Holographic equipment kit" - desc = "A kit of dangerous, high-tech equipment with changeable looks." - id = "chameleon" - req_tech = list(TECH_ILLEGAL = 2) - materials = list(DEFAULT_WALL_MATERIAL = 500) - build_path = /obj/item/weapon/storage/box/syndie_kit/chameleon - sort_string = "VASBA" - -/datum/design/item/experimental_welder - name = "Experimental welding tool" - desc = "A welding tool that generate fuel for itself." - id = "expwelder" - req_tech = list(TECH_ENGINEERING = 4, TECH_PHORON = 3, TECH_MATERIAL = 4) - materials = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 120, "phoron" = 100) - build_path = /obj/item/weapon/weldingtool/experimental - sort_string = "VASCA" - -/datum/design/item/hand_drill - name = "Hand drill" - desc = "A simple powered hand drill." - id = "handdrill" - req_tech = list(TECH_ENGINEERING = 3, TECH_MATERIAL = 2) - materials = list(DEFAULT_WALL_MATERIAL = 300, "silver" = 100) - build_path = /obj/item/weapon/screwdriver/power - sort_string = "VASDA" - -/datum/design/item/jaws_life - name = "Jaws of life" - desc = "A set of jaws of life, compressed through the magic of science." - id = "jawslife" - req_tech = list(TECH_ENGINEERING = 3, TECH_MATERIAL = 2) - materials = list(DEFAULT_WALL_MATERIAL = 300, "silver" = 100) - build_path = /obj/item/weapon/crowbar/power - sort_string = "VASEA" - -/datum/design/item/device/t_scanner_upg - name = "Upgraded T-ray Scanner" - desc = "An upgraded version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes." - id = "upgradedtscanner" - req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 4, TECH_MATERIAL = 2) - materials = list(DEFAULT_WALL_MATERIAL = 500, "phoron" = 150) - build_path = /obj/item/device/t_scanner/upgraded - sort_string = "VASSA" - - -/datum/design/item/device/t_scanner_adv - name = "Advanced T-ray Scanner" - desc = "An advanced version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes." - id = "advancedtscanner" - req_tech = list(TECH_MAGNET = 6, TECH_ENGINEERING = 6, TECH_MATERIAL = 6) - materials = list(DEFAULT_WALL_MATERIAL = 1250, "phoron" = 500, "silver" = 50) - build_path = /obj/item/device/t_scanner/advanced - sort_string = "VASSB" -/* -CIRCUITS BELOW -*/ - -/datum/design/circuit - build_type = IMPRINTER - req_tech = list(TECH_DATA = 2) - materials = list("glass" = 2000) - chemicals = list("sacid" = 20) - time = 5 - -/datum/design/circuit/AssembleDesignName() - ..() - if(build_path) - var/obj/item/weapon/circuitboard/C = build_path - if(initial(C.board_type) == "machine") - name = "Machine circuit design ([item_name])" - else if(initial(C.board_type) == "computer") - name = "Computer circuit design ([item_name])" - else - name = "Circuit design ([item_name])" - -/datum/design/circuit/AssembleDesignDesc() - if(!desc) - desc = "Allows for the construction of \a [item_name] circuit board." - -/datum/design/circuit/arcademachine - name = "battle arcade machine" - id = "arcademachine" - req_tech = list(TECH_DATA = 1) - build_path = /obj/item/weapon/circuitboard/arcade/battle - sort_string = "MAAAA" - -/datum/design/circuit/oriontrail - name = "orion trail arcade machine" - id = "oriontrail" - req_tech = list(TECH_DATA = 1) - build_path = /obj/item/weapon/circuitboard/arcade/orion_trail - sort_string = "MAAAA" - -/datum/design/circuit/jukebox - name = "jukebox" - id = "jukebox" - req_tech = list(TECH_MAGNET = 2, TECH_DATA = 1) - build_path = /obj/item/weapon/circuitboard/jukebox - sort_string = "MAAAB" - -/datum/design/circuit/seccamera - name = "security camera monitor" - id = "seccamera" - build_path = /obj/item/weapon/circuitboard/security - sort_string = "DAAAA" - -/datum/design/circuit/secdata - name = "security records console" - id = "sec_data" - build_path = /obj/item/weapon/circuitboard/secure_data - sort_string = "DABAA" - -/datum/design/circuit/prisonmanage - name = "prisoner management console" - id = "prisonmanage" - build_path = /obj/item/weapon/circuitboard/prisoner - sort_string = "DACAA" - -/datum/design/circuit/med_data - name = "medical records console" - id = "med_data" - build_path = /obj/item/weapon/circuitboard/med_data - sort_string = "FAAAA" - -/datum/design/circuit/operating - name = "patient monitoring console" - id = "operating" - build_path = /obj/item/weapon/circuitboard/operating - sort_string = "FACAA" - -/datum/design/circuit/scan_console - name = "DNA machine" - id = "scan_console" - build_path = /obj/item/weapon/circuitboard/scan_consolenew - sort_string = "FAGAA" - -/datum/design/circuit/clonecontrol - name = "cloning control console" - id = "clonecontrol" - req_tech = list(TECH_DATA = 3, TECH_BIO = 3) - build_path = /obj/item/weapon/circuitboard/cloning - sort_string = "FAGAC" - -/datum/design/circuit/clonepod - name = "clone pod" - id = "clonepod" - req_tech = list(TECH_DATA = 3, TECH_BIO = 3) - build_path = /obj/item/weapon/circuitboard/clonepod - sort_string = "FAGAE" - -/datum/design/circuit/clonescanner - name = "cloning scanner" - id = "clonescanner" - req_tech = list(TECH_DATA = 3, TECH_BIO = 3) - build_path = /obj/item/weapon/circuitboard/clonescanner - sort_string = "FAGAG" - -/datum/design/circuit/crewconsole - name = "crew monitoring console" - id = "crewconsole" - req_tech = list(TECH_DATA = 3, TECH_MAGNET = 2, TECH_BIO = 2) - build_path = /obj/item/weapon/circuitboard/crew - sort_string = "FAGAI" - -/datum/design/circuit/teleconsole - name = "teleporter control console" - id = "teleconsole" - req_tech = list(TECH_DATA = 3, TECH_BLUESPACE = 2) - build_path = /obj/item/weapon/circuitboard/teleporter - sort_string = "HAAAA" - -/datum/design/circuit/robocontrol - name = "robotics control console" - id = "robocontrol" - req_tech = list(TECH_DATA = 4) - build_path = /obj/item/weapon/circuitboard/robotics - sort_string = "HAAAB" - -/datum/design/circuit/mechacontrol - name = "exosuit control console" - id = "mechacontrol" - req_tech = list(TECH_DATA = 3) - build_path = /obj/item/weapon/circuitboard/mecha_control - sort_string = "HAAAC" - -/datum/design/circuit/rdconsole - name = "R&D control console" - id = "rdconsole" - req_tech = list(TECH_DATA = 4) - build_path = /obj/item/weapon/circuitboard/rdconsole - sort_string = "HAAAE" - -/datum/design/circuit/aifixer - name = "AI integrity restorer" - id = "aifixer" - req_tech = list(TECH_DATA = 3, TECH_BIO = 2) - build_path = /obj/item/weapon/circuitboard/aifixer - sort_string = "HAAAF" - -/datum/design/circuit/comm_monitor - name = "telecommunications monitoring console" - id = "comm_monitor" - req_tech = list(TECH_DATA = 3) - build_path = /obj/item/weapon/circuitboard/comm_monitor - sort_string = "HAACA" - -/datum/design/circuit/comm_server - name = "telecommunications server monitoring console" - id = "comm_server" - req_tech = list(TECH_DATA = 3) - build_path = /obj/item/weapon/circuitboard/comm_server - sort_string = "HAACB" - -/datum/design/circuit/message_monitor - name = "messaging monitor console" - id = "message_monitor" - req_tech = list(TECH_DATA = 5) - build_path = /obj/item/weapon/circuitboard/message_monitor - sort_string = "HAACC" - -/datum/design/circuit/aiupload - name = "AI upload console" - id = "aiupload" - req_tech = list(TECH_DATA = 4) - build_path = /obj/item/weapon/circuitboard/aiupload - sort_string = "HAABA" - -/datum/design/circuit/borgupload - name = "cyborg upload console" - id = "borgupload" - req_tech = list(TECH_DATA = 4) - build_path = /obj/item/weapon/circuitboard/borgupload - sort_string = "HAABB" - -/datum/design/circuit/destructive_analyzer - name = "destructive analyzer" - id = "destructive_analyzer" - req_tech = list(TECH_DATA = 2, TECH_MAGNET = 2, TECH_ENGINEERING = 2) - build_path = /obj/item/weapon/circuitboard/destructive_analyzer - sort_string = "HABAA" - -/datum/design/circuit/protolathe - name = "protolathe" - id = "protolathe" - req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) - build_path = /obj/item/weapon/circuitboard/protolathe - sort_string = "HABAB" - -/datum/design/circuit/circuit_imprinter - name = "circuit imprinter" - id = "circuit_imprinter" - req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) - build_path = /obj/item/weapon/circuitboard/circuit_imprinter - sort_string = "HABAC" - -/datum/design/circuit/autolathe - name = "autolathe board" - id = "autolathe" - req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) - build_path = /obj/item/weapon/circuitboard/autolathe - sort_string = "HABAD" - -/datum/design/circuit/rdservercontrol - name = "R&D server control console" - id = "rdservercontrol" - req_tech = list(TECH_DATA = 3) - build_path = /obj/item/weapon/circuitboard/rdservercontrol - sort_string = "HABBA" - -/datum/design/circuit/rdserver - name = "R&D server" - id = "rdserver" - req_tech = list(TECH_DATA = 3) - build_path = /obj/item/weapon/circuitboard/rdserver - sort_string = "HABBB" - -/datum/design/circuit/mechfab - name = "exosuit fabricator" - id = "mechfab" - req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3) - build_path = /obj/item/weapon/circuitboard/mechfab - sort_string = "HABAE" - -/datum/design/circuit/prosfab - name = "prosthetics fabricator" - id = "prosfab" - req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3) - build_path = /obj/item/weapon/circuitboard/prosthetics - sort_string = "HABAF" - -/datum/design/circuit/mech_recharger - name = "mech recharger" - id = "mech_recharger" - req_tech = list(TECH_DATA = 2, TECH_POWER = 2, TECH_ENGINEERING = 2) - build_path = /obj/item/weapon/circuitboard/mech_recharger - sort_string = "HACAA" - -/datum/design/circuit/recharge_station - name = "cyborg recharge station" - id = "recharge_station" - req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2) - build_path = /obj/item/weapon/circuitboard/recharge_station - sort_string = "HACAC" - -/datum/design/circuit/atmosalerts - name = "atmosphere alert console" - id = "atmosalerts" - build_path = /obj/item/weapon/circuitboard/atmos_alert - sort_string = "JAAAA" - -/datum/design/circuit/air_management - name = "atmosphere monitoring console" - id = "air_management" - build_path = /obj/item/weapon/circuitboard/air_management - sort_string = "JAAAB" - -/datum/design/circuit/rcon_console - name = "RCON remote control console" - id = "rcon_console" - req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3, TECH_POWER = 5) - build_path = /obj/item/weapon/circuitboard/rcon_console - sort_string = "JAAAC" - -/datum/design/circuit/dronecontrol - name = "drone control console" - id = "dronecontrol" - req_tech = list(TECH_DATA = 4) - build_path = /obj/item/weapon/circuitboard/drone_control - sort_string = "JAAAD" - -/datum/design/circuit/powermonitor - name = "power monitoring console" - id = "powermonitor" - build_path = /obj/item/weapon/circuitboard/powermonitor - sort_string = "JAAAE" - -/datum/design/circuit/solarcontrol - name = "solar control console" - id = "solarcontrol" - build_path = /obj/item/weapon/circuitboard/solar_control - sort_string = "JAAAF" - -/datum/design/circuit/pacman - name = "PACMAN-type generator" - id = "pacman" - req_tech = list(TECH_DATA = 3, TECH_PHORON = 3, TECH_POWER = 3, TECH_ENGINEERING = 3) - build_path = /obj/item/weapon/circuitboard/pacman - sort_string = "JBAAA" - -/datum/design/circuit/superpacman - name = "SUPERPACMAN-type generator" - id = "superpacman" - req_tech = list(TECH_DATA = 3, TECH_POWER = 4, TECH_ENGINEERING = 4) - build_path = /obj/item/weapon/circuitboard/pacman/super - sort_string = "JBAAB" - -/datum/design/circuit/mrspacman - name = "MRSPACMAN-type generator" - id = "mrspacman" - req_tech = list(TECH_DATA = 3, TECH_POWER = 5, TECH_ENGINEERING = 5) - build_path = /obj/item/weapon/circuitboard/pacman/mrs - sort_string = "JBAAC" - -/datum/design/circuit/batteryrack - name = "cell rack PSU" - id = "batteryrack" - req_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 2) - build_path = /obj/item/weapon/circuitboard/batteryrack - sort_string = "JBABA" - -/datum/design/circuit/smes_cell - name = "'SMES' superconductive magnetic energy storage" - desc = "Allows for the construction of circuit boards used to build a SMES." - id = "smes_cell" - req_tech = list(TECH_POWER = 7, TECH_ENGINEERING = 5) - build_path = /obj/item/weapon/circuitboard/smes - sort_string = "JBABB" - -/datum/design/circuit/grid_checker - name = "power grid checker" - desc = "Allows for the construction of circuit boards used to build a grid checker." - id = "grid_checker" - req_tech = list(TECH_POWER = 4, TECH_ENGINEERING = 3) - build_path = /obj/item/weapon/circuitboard/grid_checker - sort_string = "JBABC" - -/datum/design/circuit/breakerbox - name = "breaker box" - desc = "Allows for the construction of circuit boards used to build a breaker box." - id = "breakerbox" - req_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3) - build_path = /obj/item/weapon/circuitboard/breakerbox - sort_string = "JBABD" - -/datum/design/circuit/gas_heater - name = "gas heating system" - id = "gasheater" - req_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 1) - build_path = /obj/item/weapon/circuitboard/unary_atmos/heater - sort_string = "JCAAA" - -/datum/design/circuit/gas_cooler - name = "gas cooling system" - id = "gascooler" - req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) - build_path = /obj/item/weapon/circuitboard/unary_atmos/cooler - sort_string = "JCAAB" - -/datum/design/circuit/secure_airlock - name = "secure airlock electronics" - desc = "Allows for the construction of a tamper-resistant airlock electronics." - id = "securedoor" - req_tech = list(TECH_DATA = 3) - build_path = /obj/item/weapon/airlock_electronics/secure - sort_string = "JDAAA" - -/datum/design/circuit/ordercomp - name = "supply ordering console" - id = "ordercomp" - build_path = /obj/item/weapon/circuitboard/ordercomp - sort_string = "KAAAA" - -/datum/design/circuit/supplycomp - name = "supply control console" - id = "supplycomp" - req_tech = list(TECH_DATA = 3) - build_path = /obj/item/weapon/circuitboard/supplycomp - sort_string = "KAAAB" - -/datum/design/circuit/biogenerator - name = "biogenerator" - id = "biogenerator" - req_tech = list(TECH_DATA = 2) - build_path = /obj/item/weapon/circuitboard/biogenerator - sort_string = "KBAAA" - -/datum/design/circuit/miningdrill - name = "mining drill head" - id = "mining drill head" - req_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1) - build_path = /obj/item/weapon/circuitboard/miningdrill - sort_string = "KCAAA" - -/datum/design/circuit/miningdrillbrace - name = "mining drill brace" - id = "mining drill brace" - req_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1) - build_path = /obj/item/weapon/circuitboard/miningdrillbrace - sort_string = "KCAAB" - -/datum/design/circuit/comconsole - name = "communications console" - id = "comconsole" - build_path = /obj/item/weapon/circuitboard/communications - sort_string = "LAAAA" - -/datum/design/circuit/idcardconsole - name = "ID card modification console" - id = "idcardconsole" - build_path = /obj/item/weapon/circuitboard/card - sort_string = "LAAAB" - -/datum/design/circuit/emp_data - name = "employment records console" - id = "emp_data" - build_path = /obj/item/weapon/circuitboard/skills - sort_string = "LAAAC" - -/datum/design/circuit/mecha - req_tech = list(TECH_DATA = 3) - -/datum/design/circuit/mecha/AssembleDesignName() - name = "Exosuit module circuit design ([name])" -/datum/design/circuit/mecha/AssembleDesignDesc() - desc = "Allows for the construction of \a [name] module." - -/datum/design/circuit/mecha/ripley_main - name = "APLU 'Ripley' central control" - id = "ripley_main" - build_path = /obj/item/weapon/circuitboard/mecha/ripley/main - sort_string = "NAAAA" - -/datum/design/circuit/mecha/ripley_peri - name = "APLU 'Ripley' peripherals control" - id = "ripley_peri" - build_path = /obj/item/weapon/circuitboard/mecha/ripley/peripherals - sort_string = "NAAAB" - -/datum/design/circuit/mecha/odysseus_main - name = "'Odysseus' central control" - id = "odysseus_main" - req_tech = list(TECH_DATA = 3,TECH_BIO = 2) - build_path = /obj/item/weapon/circuitboard/mecha/odysseus/main - sort_string = "NAABA" - -/datum/design/circuit/mecha/odysseus_peri - name = "'Odysseus' peripherals control" - id = "odysseus_peri" - req_tech = list(TECH_DATA = 3,TECH_BIO = 2) - build_path = /obj/item/weapon/circuitboard/mecha/odysseus/peripherals - sort_string = "NAABB" - -/datum/design/circuit/mecha/gygax_main - name = "'Gygax' central control" - id = "gygax_main" - req_tech = list(TECH_DATA = 4) - build_path = /obj/item/weapon/circuitboard/mecha/gygax/main - sort_string = "NAACA" - -/datum/design/circuit/mecha/gygax_peri - name = "'Gygax' peripherals control" - id = "gygax_peri" - req_tech = list(TECH_DATA = 4) - build_path = /obj/item/weapon/circuitboard/mecha/gygax/peripherals - sort_string = "NAACB" - -/datum/design/circuit/mecha/gygax_targ - name = "'Gygax' weapon control and targeting" - id = "gygax_targ" - req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2) - build_path = /obj/item/weapon/circuitboard/mecha/gygax/targeting - sort_string = "NAACC" - -/datum/design/circuit/mecha/durand_main - name = "'Durand' central control" - id = "durand_main" - req_tech = list(TECH_DATA = 4) - build_path = /obj/item/weapon/circuitboard/mecha/durand/main - sort_string = "NAADA" - -/datum/design/circuit/mecha/durand_peri - name = "'Durand' peripherals control" - id = "durand_peri" - req_tech = list(TECH_DATA = 4) - build_path = /obj/item/weapon/circuitboard/mecha/durand/peripherals - sort_string = "NAADB" - -/datum/design/circuit/mecha/durand_targ - name = "'Durand' weapon control and targeting" - id = "durand_targ" - req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2) - build_path = /obj/item/weapon/circuitboard/mecha/durand/targeting - sort_string = "NAADC" - -/datum/design/circuit/tcom - req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4) - -/datum/design/circuit/tcom/AssembleDesignName() - name = "Telecommunications machinery circuit design ([name])" -/datum/design/circuit/tcom/AssembleDesignDesc() - desc = "Allows for the construction of a telecommunications [name] circuit board." - -/datum/design/circuit/tcom/server - name = "server mainframe" - id = "tcom-server" - build_path = /obj/item/weapon/circuitboard/telecomms/server - sort_string = "PAAAA" - -/datum/design/circuit/tcom/processor - name = "processor unit" - id = "tcom-processor" - build_path = /obj/item/weapon/circuitboard/telecomms/processor - sort_string = "PAAAB" - -/datum/design/circuit/tcom/bus - name = "bus mainframe" - id = "tcom-bus" - build_path = /obj/item/weapon/circuitboard/telecomms/bus - sort_string = "PAAAC" - -/datum/design/circuit/tcom/hub - name = "hub mainframe" - id = "tcom-hub" - build_path = /obj/item/weapon/circuitboard/telecomms/hub - sort_string = "PAAAD" - -/datum/design/circuit/tcom/relay - name = "relay mainframe" - id = "tcom-relay" - req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 4, TECH_BLUESPACE = 3) - build_path = /obj/item/weapon/circuitboard/telecomms/relay - sort_string = "PAAAE" - -/datum/design/circuit/tcom/broadcaster - name = "subspace broadcaster" - id = "tcom-broadcaster" - req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4, TECH_BLUESPACE = 2) - build_path = /obj/item/weapon/circuitboard/telecomms/broadcaster - sort_string = "PAAAF" - -/datum/design/circuit/tcom/receiver - name = "subspace receiver" - id = "tcom-receiver" - req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3, TECH_BLUESPACE = 2) - build_path = /obj/item/weapon/circuitboard/telecomms/receiver - sort_string = "PAAAG" - -/datum/design/circuit/tcom/exonet_node - name = "exonet node" - id = "tcom-exonet_node" - req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 5, TECH_BLUESPACE = 4) - build_path = /obj/item/weapon/circuitboard/telecomms/exonet_node - sort_string = "PAAAH" - -/datum/design/circuit/shield - req_tech = list(TECH_BLUESPACE = 4, TECH_PHORON = 3) - materials = list("glass" = 2000, "gold" = 1000) - -/datum/design/circuit/shield/AssembleDesignName() - name = "Shield generator circuit design ([name])" -/datum/design/circuit/shield/AssembleDesignDesc() - if(!desc) - desc = "Allows for the construction of \a [name] shield generator." - -/datum/design/circuit/shield/bubble - name = "bubble" - id = "shield_gen" - build_path = /obj/item/weapon/circuitboard/shield_gen - sort_string = "VAAAA" - -/datum/design/circuit/shield/hull - name = "hull" - id = "shield_gen_ex" - build_path = /obj/item/weapon/circuitboard/shield_gen_ex - sort_string = "VAAAB" - -/datum/design/circuit/shield/capacitor - name = "capacitor" - desc = "Allows for the construction of a shield capacitor circuit board." - id = "shield_cap" - req_tech = list(TECH_MAGNET = 3, TECH_POWER = 4) - build_path = /obj/item/weapon/circuitboard/shield_cap - sort_string = "VAAAC" - -/datum/design/circuit/aicore - name = "AI core" - id = "aicore" - req_tech = list(TECH_DATA = 4, TECH_BIO = 3) - build_path = /obj/item/weapon/circuitboard/aicore - sort_string = "XAAAA" - -/datum/design/aimodule - build_type = IMPRINTER - materials = list("glass" = 2000, "gold" = 100) - -/datum/design/aimodule/AssembleDesignName() - name = "AI module design ([name])" - -/datum/design/aimodule/AssembleDesignDesc() - desc = "Allows for the construction of \a '[name]' AI module." - -/datum/design/aimodule/safeguard - name = "Safeguard" - id = "safeguard" - req_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4) - build_path = /obj/item/weapon/aiModule/safeguard - sort_string = "XABAA" - -/datum/design/aimodule/onehuman - name = "OneCrewMember" - id = "onehuman" - req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 6) - build_path = /obj/item/weapon/aiModule/oneHuman - sort_string = "XABAB" - -/datum/design/aimodule/protectstation - name = "ProtectStation" - id = "protectstation" - req_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6) - build_path = /obj/item/weapon/aiModule/protectStation - sort_string = "XABAC" - -/datum/design/aimodule/notele - name = "TeleporterOffline" - id = "notele" - req_tech = list(TECH_DATA = 3) - build_path = /obj/item/weapon/aiModule/teleporterOffline - sort_string = "XABAD" - -/datum/design/aimodule/quarantine - name = "Quarantine" - id = "quarantine" - req_tech = list(TECH_DATA = 3, TECH_BIO = 2, TECH_MATERIAL = 4) - build_path = /obj/item/weapon/aiModule/quarantine - sort_string = "XABAE" - -/datum/design/aimodule/oxygen - name = "OxygenIsToxicToHumans" - id = "oxygen" - req_tech = list(TECH_DATA = 3, TECH_BIO = 2, TECH_MATERIAL = 4) - build_path = /obj/item/weapon/aiModule/oxygen - sort_string = "XABAF" - -/datum/design/aimodule/freeform - name = "Freeform" - id = "freeform" - req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 4) - build_path = /obj/item/weapon/aiModule/freeform - sort_string = "XABAG" - -/datum/design/aimodule/reset - name = "Reset" - id = "reset" - req_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6) - build_path = /obj/item/weapon/aiModule/reset - sort_string = "XAAAA" - -/datum/design/aimodule/purge - name = "Purge" - id = "purge" - req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 6) - build_path = /obj/item/weapon/aiModule/purge - sort_string = "XAAAB" - -// Core modules -/datum/design/aimodule/core - req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 6) - -/datum/design/aimodule/core/AssembleDesignName() - name = "AI core module design ([name])" - -/datum/design/aimodule/core/AssembleDesignDesc() - desc = "Allows for the construction of \a '[name]' AI core module." - -/datum/design/aimodule/core/freeformcore - name = "Freeform" - id = "freeformcore" - build_path = /obj/item/weapon/aiModule/freeformcore - sort_string = "XACAA" - -/datum/design/aimodule/core/asimov - name = "Asimov" - id = "asimov" - build_path = /obj/item/weapon/aiModule/asimov - sort_string = "XACAB" - -/datum/design/aimodule/core/paladin - name = "P.A.L.A.D.I.N." - id = "paladin" - build_path = /obj/item/weapon/aiModule/paladin - sort_string = "XACAC" - -/datum/design/aimodule/core/tyrant - name = "T.Y.R.A.N.T." - id = "tyrant" - req_tech = list(TECH_DATA = 4, TECH_ILLEGAL = 2, TECH_MATERIAL = 6) - build_path = /obj/item/weapon/aiModule/tyrant - sort_string = "XACAD" - -/datum/design/item/pda - name = "PDA design" - desc = "Cheaper than whiny non-digital assistants." - id = "pda" - req_tech = list(TECH_ENGINEERING = 2, TECH_POWER = 3) - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) - build_path = /obj/item/device/pda - sort_string = "VAAAA" - -// Cartridges -/datum/design/item/pda_cartridge - req_tech = list(TECH_ENGINEERING = 2, TECH_POWER = 3) - materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) - -/datum/design/item/pda_cartridge/AssembleDesignName() - ..() - name = "PDA accessory ([item_name])" - -/datum/design/item/pda_cartridge/cart_basic - id = "cart_basic" - build_path = /obj/item/weapon/cartridge - sort_string = "VBAAA" - -/datum/design/item/pda_cartridge/engineering - id = "cart_engineering" - build_path = /obj/item/weapon/cartridge/engineering - sort_string = "VBAAB" - -/datum/design/item/pda_cartridge/atmos - id = "cart_atmos" - build_path = /obj/item/weapon/cartridge/atmos - sort_string = "VBAAC" - -/datum/design/item/pda_cartridge/medical - id = "cart_medical" - build_path = /obj/item/weapon/cartridge/medical - sort_string = "VBAAD" - -/datum/design/item/pda_cartridge/chemistry - id = "cart_chemistry" - build_path = /obj/item/weapon/cartridge/chemistry - sort_string = "VBAAE" - -/datum/design/item/pda_cartridge/security - id = "cart_security" - build_path = /obj/item/weapon/cartridge/security - sort_string = "VBAAF" - -/datum/design/item/pda_cartridge/janitor - id = "cart_janitor" - build_path = /obj/item/weapon/cartridge/janitor - sort_string = "VBAAG" - -/datum/design/item/pda_cartridge/science - id = "cart_science" - build_path = /obj/item/weapon/cartridge/signal/science - sort_string = "VBAAH" - -/datum/design/item/pda_cartridge/quartermaster - id = "cart_quartermaster" - build_path = /obj/item/weapon/cartridge/quartermaster - sort_string = "VBAAI" - -/datum/design/item/pda_cartridge/hop - id = "cart_hop" - build_path = /obj/item/weapon/cartridge/hop - sort_string = "VBAAJ" - -/datum/design/item/pda_cartridge/hos - id = "cart_hos" - build_path = /obj/item/weapon/cartridge/hos - sort_string = "VBAAK" - -/datum/design/item/pda_cartridge/ce - id = "cart_ce" - build_path = /obj/item/weapon/cartridge/ce - sort_string = "VBAAL" - -/datum/design/item/pda_cartridge/cmo - id = "cart_cmo" - build_path = /obj/item/weapon/cartridge/cmo - sort_string = "VBAAM" - -/datum/design/item/pda_cartridge/rd - id = "cart_rd" - build_path = /obj/item/weapon/cartridge/rd - sort_string = "VBAAN" - -/datum/design/item/pda_cartridge/captain - id = "cart_captain" - build_path = /obj/item/weapon/cartridge/captain - sort_string = "VBAAO" - - - -/datum/design/item/wirer - name = "Custom wirer tool" - id = "wirer" - req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) - materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) - build_path = /obj/item/device/integrated_electronics/wirer - sort_string = "VBVAA" - -/datum/design/item/debugger - name = "Custom circuit debugger tool" - id = "debugger" - req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) - materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) - build_path = /obj/item/device/integrated_electronics/debugger - sort_string = "VBVAB" - - - -/datum/design/item/custom_circuit_assembly - name = "Small custom assembly" - desc = "A customizable assembly for simple, small devices." - id = "assembly-small" - req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_POWER = 2) - materials = list(DEFAULT_WALL_MATERIAL = 10000) - build_path = /obj/item/device/electronic_assembly - sort_string = "VCAAA" - -/datum/design/item/custom_circuit_assembly/medium - name = "Medium custom assembly" - desc = "A customizable assembly suited for more ambitious mechanisms." - id = "assembly-medium" - req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_POWER = 3) - materials = list(DEFAULT_WALL_MATERIAL = 20000) - build_path = /obj/item/device/electronic_assembly/medium - sort_string = "VCAAB" - -/datum/design/item/custom_circuit_assembly/drone - name = "Drone custom assembly" - desc = "A customizable assembly optimized for autonomous devices." - id = "assembly-drone" - req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4, TECH_POWER = 4) - materials = list(DEFAULT_WALL_MATERIAL = 30000) - build_path = /obj/item/device/electronic_assembly/drone - sort_string = "VCAAC" - -/datum/design/item/custom_circuit_assembly/large - name = "Large custom assembly" - desc = "A customizable assembly for large machines." - id = "assembly-large" - req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 4) - materials = list(DEFAULT_WALL_MATERIAL = 40000) - build_path = /obj/item/device/electronic_assembly/large - sort_string = "VCAAD" - -/datum/design/item/custom_circuit_assembly/implant - name = "Implant custom assembly" - desc = "An customizable assembly for very small devices, implanted into living entities." - id = "assembly-implant" - req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 3, TECH_BIO = 5) - materials = list(DEFAULT_WALL_MATERIAL = 2000) - build_path = /obj/item/weapon/implant/integrated_circuit - sort_string = "VCAAE" - -/datum/design/item/custom_circuit_assembly/device - name = "Device custom assembly" - desc = "An customizable assembly designed to interface with other devices." - id = "assembly-device" - req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2, TECH_POWER = 2) - materials = list(DEFAULT_WALL_MATERIAL = 5000) - build_path = /obj/item/device/assembly/electronic_assembly - sort_string = "VCAAF" - -/datum/design/item/custom_circuit_printer - name = "Portable integrated circuit printer" - desc = "A portable(ish) printer for modular machines." - id = "ic_printer" - req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 4, TECH_DATA = 5) - materials = list(DEFAULT_WALL_MATERIAL = 10000) - build_path = /obj/item/device/integrated_circuit_printer - sort_string = "VCAAG" - -/datum/design/item/custom_circuit_printer_upgrade - name = "Integrated circuit printer upgrade - advanced designs" - desc = "Allows the integrated circuit printer to create advanced circuits" - id = "ic_printer_upgrade_adv" - req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 4) - materials = list(DEFAULT_WALL_MATERIAL = 2000) - build_path = /obj/item/weapon/disk/integrated_circuit/upgrade/advanced - sort_string = "VCAAH" - -/datum/design/item/translator - name = "handheld translator" - id = "translator" - req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3) - materials = list(DEFAULT_WALL_MATERIAL = 3000, "glass" = 3000) - build_path = /obj/item/device/universal_translator - sort_string = "HABQA" - -/datum/design/item/ear_translator - name = "earpiece translator" - id = "ear_translator" - req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 5) //It's been hella miniaturized. - materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 2000, "gold" = 1000) - build_path = /obj/item/device/universal_translator/ear - sort_string = "HABQB" - -/datum/design/item/xenoarch_multi_tool - name = "xenoarcheology multitool" - id = "xenoarch_multitool" - req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3, TECH_BLUESPACE = 3) - build_path = /obj/item/device/xenoarch_multi_tool - materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "uranium" = 500, "phoron" = 500) - sort_string = "HABQC" - -/datum/design/item/excavationdrill - name = "Excavation Drill" - id = "excavationdrill" - req_tech = list(TECH_MATERIAL = 3, TECH_POWER = 2, TECH_ENGINEERING = 2, TECH_BLUESPACE = 3) - build_type = PROTOLATHE - materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 4000) - build_path = /obj/item/weapon/pickaxe/excavationdrill - sort_string = "HABQD" - -/* Uncomment if someone makes these buildable -/datum/design/circuit/general_alert - name = "general alert console" - id = "general_alert" - build_path = /obj/item/weapon/circuitboard/general_alert - -// Removal of loyalty implants. Can't think of a way to add this to the config option. -/datum/design/item/implant/loyalty - name = "loyalty" - id = "implant_loyal" - req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3) - materials = list(DEFAULT_WALL_MATERIAL = 7000, "glass" = 7000) - build_path = /obj/item/weapon/implantcase/loyalty" - -/datum/design/rust_core_control - name = "Circuit Design (RUST core controller)" - desc = "Allows for the construction of circuit boards used to build a core control console for the RUST fusion engine." - id = "rust_core_control" - req_tech = list("programming" = 4, "engineering" = 4) - build_type = IMPRINTER - materials = list("glass" = 2000, "sacid" = 20) - build_path = "/obj/item/weapon/circuitboard/rust_core_control" - -datum/design/rust_fuel_control - name = "Circuit Design (RUST fuel controller)" - desc = "Allows for the construction of circuit boards used to build a fuel injector control console for the RUST fusion engine." - id = "rust_fuel_control" - req_tech = list("programming" = 4, "engineering" = 4) - build_type = IMPRINTER - materials = list("glass" = 2000, "sacid" = 20) - build_path = "/obj/item/weapon/circuitboard/rust_fuel_control" - -datum/design/rust_fuel_port - name = "Internal circuitry (RUST fuel port)" - desc = "Allows for the construction of circuit boards used to build a fuel injection port for the RUST fusion engine." - id = "rust_fuel_port" - req_tech = list("engineering" = 4, "materials" = 5) - build_type = IMPRINTER - materials = list("glass" = 2000, "sacid" = 20, "uranium" = 3000) - build_path = "/obj/item/weapon/module/rust_fuel_port" - -datum/design/rust_fuel_compressor - name = "Circuit Design (RUST fuel compressor)" - desc = "Allows for the construction of circuit boards used to build a fuel compressor of the RUST fusion engine." - id = "rust_fuel_compressor" - req_tech = list("materials" = 6, "phorontech" = 4) - build_type = IMPRINTER - materials = list("glass" = 2000, "sacid" = 20, "phoron" = 3000, "diamond" = 1000) - build_path = "/obj/item/weapon/module/rust_fuel_compressor" - -datum/design/rust_core - name = "Internal circuitry (RUST tokamak core)" - desc = "The circuit board that for a RUST-pattern tokamak fusion core." - id = "pacman" - req_tech = list(bluespace = 3, phorontech = 4, magnets = 5, powerstorage = 6) - build_type = IMPRINTER - materials = list("glass" = 2000, "sacid" = 20, "phoron" = 3000, "diamond" = 2000) - build_path = "/obj/item/weapon/circuitboard/rust_core" - -datum/design/rust_injector - name = "Internal circuitry (RUST tokamak core)" - desc = "The circuit board that for a RUST-pattern particle accelerator." - id = "pacman" - req_tech = list(powerstorage = 3, engineering = 4, phorontech = 4, materials = 6) - build_type = IMPRINTER - materials = list("glass" = 2000, "sacid" = 20, "phoron" = 3000, "uranium" = 2000) - build_path = "/obj/item/weapon/circuitboard/rust_core" -*/ + sort_string = "GAAAB" \ No newline at end of file diff --git a/code/modules/research/designs/ai_modules.dm b/code/modules/research/designs/ai_modules.dm new file mode 100644 index 00000000000..eae26ea3865 --- /dev/null +++ b/code/modules/research/designs/ai_modules.dm @@ -0,0 +1,117 @@ +/datum/design/aimodule + build_type = IMPRINTER + materials = list("glass" = 2000, "gold" = 100) + +/datum/design/aimodule/AssembleDesignName() + name = "AI module design ([name])" + +/datum/design/aimodule/AssembleDesignDesc() + desc = "Allows for the construction of \a '[name]' AI module." + +/datum/design/aimodule/safeguard + name = "Safeguard" + id = "safeguard" + req_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4) + build_path = /obj/item/weapon/aiModule/safeguard + sort_string = "XABAA" + +/datum/design/aimodule/onehuman + name = "OneCrewMember" + id = "onehuman" + req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 6) + build_path = /obj/item/weapon/aiModule/oneHuman + sort_string = "XABAB" + +/datum/design/aimodule/protectstation + name = "ProtectStation" + id = "protectstation" + req_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6) + build_path = /obj/item/weapon/aiModule/protectStation + sort_string = "XABAC" + +/datum/design/aimodule/notele + name = "TeleporterOffline" + id = "notele" + req_tech = list(TECH_DATA = 3) + build_path = /obj/item/weapon/aiModule/teleporterOffline + sort_string = "XABAD" + +/datum/design/aimodule/quarantine + name = "Quarantine" + id = "quarantine" + req_tech = list(TECH_DATA = 3, TECH_BIO = 2, TECH_MATERIAL = 4) + build_path = /obj/item/weapon/aiModule/quarantine + sort_string = "XABAE" + +/datum/design/aimodule/oxygen + name = "OxygenIsToxicToHumans" + id = "oxygen" + req_tech = list(TECH_DATA = 3, TECH_BIO = 2, TECH_MATERIAL = 4) + build_path = /obj/item/weapon/aiModule/oxygen + sort_string = "XABAF" + +/datum/design/aimodule/freeform + name = "Freeform" + id = "freeform" + req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 4) + build_path = /obj/item/weapon/aiModule/freeform + sort_string = "XABAG" + +/datum/design/aimodule/reset + name = "Reset" + id = "reset" + req_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6) + build_path = /obj/item/weapon/aiModule/reset + sort_string = "XAAAZ" // Duplicate string, really need to redo this whole thing + +/datum/design/aimodule/purge + name = "Purge" + id = "purge" + req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 6) + build_path = /obj/item/weapon/aiModule/purge + sort_string = "XAAAB" + +// Core modules +/datum/design/aimodule/core + req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 6) + +/datum/design/aimodule/core/AssembleDesignName() + name = "AI core module design ([name])" + +/datum/design/aimodule/core/AssembleDesignDesc() + desc = "Allows for the construction of \a '[name]' AI core module." + +/datum/design/aimodule/core/freeformcore + name = "Freeform" + id = "freeformcore" + build_path = /obj/item/weapon/aiModule/freeformcore + sort_string = "XACAA" + +/datum/design/aimodule/core/asimov + name = "Asimov" + id = "asimov" + build_path = /obj/item/weapon/aiModule/asimov + sort_string = "XACAB" + +/datum/design/aimodule/core/paladin + name = "P.A.L.A.D.I.N." + id = "paladin" + build_path = /obj/item/weapon/aiModule/paladin + sort_string = "XACAC" + +/datum/design/aimodule/core/tyrant + name = "T.Y.R.A.N.T." + id = "tyrant" + req_tech = list(TECH_DATA = 4, TECH_ILLEGAL = 2, TECH_MATERIAL = 6) + build_path = /obj/item/weapon/aiModule/tyrant + sort_string = "XACAD" + +// AI file, AI tool +/datum/design/item/intellicard + name = "'intelliCore', AI preservation and transportation system" + desc = "Allows for the construction of an intelliCore." + id = "intellicore" + req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 4) + materials = list("glass" = 1000, "gold" = 200) + build_path = /obj/item/device/aicard + sort_string = "VACAA" \ No newline at end of file diff --git a/code/modules/research/designs/circuit_assembly.dm b/code/modules/research/designs/circuit_assembly.dm new file mode 100644 index 00000000000..9f20032445c --- /dev/null +++ b/code/modules/research/designs/circuit_assembly.dm @@ -0,0 +1,89 @@ +/datum/design/item/wirer + name = "Custom wirer tool" + id = "wirer" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) + build_path = /obj/item/device/integrated_electronics/wirer + sort_string = "VBVAA" + +/datum/design/item/debugger + name = "Custom circuit debugger tool" + id = "debugger" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) + build_path = /obj/item/device/integrated_electronics/debugger + sort_string = "VBVAB" + + + +/datum/design/item/custom_circuit_assembly + name = "Small custom assembly" + desc = "A customizable assembly for simple, small devices." + id = "assembly-small" + req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/device/electronic_assembly + sort_string = "VCAAA" + +/datum/design/item/custom_circuit_assembly/medium + name = "Medium custom assembly" + desc = "A customizable assembly suited for more ambitious mechanisms." + id = "assembly-medium" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 20000) + build_path = /obj/item/device/electronic_assembly/medium + sort_string = "VCAAB" + +/datum/design/item/custom_circuit_assembly/drone + name = "Drone custom assembly" + desc = "A customizable assembly optimized for autonomous devices." + id = "assembly-drone" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4, TECH_POWER = 4) + materials = list(DEFAULT_WALL_MATERIAL = 30000) + build_path = /obj/item/device/electronic_assembly/drone + sort_string = "VCAAC" + +/datum/design/item/custom_circuit_assembly/large + name = "Large custom assembly" + desc = "A customizable assembly for large machines." + id = "assembly-large" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 4) + materials = list(DEFAULT_WALL_MATERIAL = 40000) + build_path = /obj/item/device/electronic_assembly/large + sort_string = "VCAAD" + +/datum/design/item/custom_circuit_assembly/implant + name = "Implant custom assembly" + desc = "An customizable assembly for very small devices, implanted into living entities." + id = "assembly-implant" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 3, TECH_BIO = 5) + materials = list(DEFAULT_WALL_MATERIAL = 2000) + build_path = /obj/item/weapon/implant/integrated_circuit + sort_string = "VCAAE" + +/datum/design/item/custom_circuit_assembly/device + name = "Device custom assembly" + desc = "An customizable assembly designed to interface with other devices." + id = "assembly-device" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000) + build_path = /obj/item/device/assembly/electronic_assembly + sort_string = "VCAAF" + +/datum/design/item/custom_circuit_printer + name = "Portable integrated circuit printer" + desc = "A portable(ish) printer for modular machines." + id = "ic_printer" + req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 4, TECH_DATA = 5) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/device/integrated_circuit_printer + sort_string = "VCAAG" + +/datum/design/item/custom_circuit_printer_upgrade + name = "Integrated circuit printer upgrade - advanced designs" + desc = "Allows the integrated circuit printer to create advanced circuits" + id = "ic_printer_upgrade_adv" + req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 4) + materials = list(DEFAULT_WALL_MATERIAL = 2000) + build_path = /obj/item/weapon/disk/integrated_circuit/upgrade/advanced + sort_string = "VCAAH" \ No newline at end of file diff --git a/code/modules/research/designs/circuits.dm b/code/modules/research/designs/circuits.dm new file mode 100644 index 00000000000..e00a47786d1 --- /dev/null +++ b/code/modules/research/designs/circuits.dm @@ -0,0 +1,597 @@ +/* +CIRCUITS BELOW +*/ + +/datum/design/circuit + build_type = IMPRINTER + req_tech = list(TECH_DATA = 2) + materials = list("glass" = 2000) + chemicals = list("sacid" = 20) + time = 5 + +/datum/design/circuit/AssembleDesignName() + ..() + if(build_path) + var/obj/item/weapon/circuitboard/C = build_path + if(initial(C.board_type) == "machine") + name = "Machine circuit design ([item_name])" + else if(initial(C.board_type) == "computer") + name = "Computer circuit design ([item_name])" + else + name = "Circuit design ([item_name])" + +/datum/design/circuit/AssembleDesignDesc() + if(!desc) + desc = "Allows for the construction of \a [item_name] circuit board." + +/datum/design/circuit/arcademachine + name = "battle arcade machine" + id = "arcademachine" + req_tech = list(TECH_DATA = 1) + build_path = /obj/item/weapon/circuitboard/arcade/battle + sort_string = "MAAAA" + +/datum/design/circuit/oriontrail + name = "orion trail arcade machine" + id = "oriontrail" + req_tech = list(TECH_DATA = 1) + build_path = /obj/item/weapon/circuitboard/arcade/orion_trail + sort_string = "MAAAZ" // Duplicate string, really need to redo this whole thing + +/datum/design/circuit/jukebox + name = "jukebox" + id = "jukebox" + req_tech = list(TECH_MAGNET = 2, TECH_DATA = 1) + build_path = /obj/item/weapon/circuitboard/jukebox + sort_string = "MAAAB" + +/datum/design/circuit/seccamera + name = "security camera monitor" + id = "seccamera" + build_path = /obj/item/weapon/circuitboard/security + sort_string = "DAAAZ" // Duplicate string, really need to redo this whole thing + +/datum/design/circuit/secdata + name = "security records console" + id = "sec_data" + build_path = /obj/item/weapon/circuitboard/secure_data + sort_string = "DABAA" + +/datum/design/circuit/prisonmanage + name = "prisoner management console" + id = "prisonmanage" + build_path = /obj/item/weapon/circuitboard/prisoner + sort_string = "DACAA" + +/datum/design/circuit/med_data + name = "medical records console" + id = "med_data" + build_path = /obj/item/weapon/circuitboard/med_data + sort_string = "FAAAA" + +/datum/design/circuit/operating + name = "patient monitoring console" + id = "operating" + build_path = /obj/item/weapon/circuitboard/operating + sort_string = "FACAA" + +/datum/design/circuit/scan_console + name = "DNA machine" + id = "scan_console" + build_path = /obj/item/weapon/circuitboard/scan_consolenew + sort_string = "FAGAA" + +/datum/design/circuit/clonecontrol + name = "cloning control console" + id = "clonecontrol" + req_tech = list(TECH_DATA = 3, TECH_BIO = 3) + build_path = /obj/item/weapon/circuitboard/cloning + sort_string = "FAGAC" + +/datum/design/circuit/clonepod + name = "clone pod" + id = "clonepod" + req_tech = list(TECH_DATA = 3, TECH_BIO = 3) + build_path = /obj/item/weapon/circuitboard/clonepod + sort_string = "FAGAE" + +/datum/design/circuit/clonescanner + name = "cloning scanner" + id = "clonescanner" + req_tech = list(TECH_DATA = 3, TECH_BIO = 3) + build_path = /obj/item/weapon/circuitboard/clonescanner + sort_string = "FAGAG" + +/datum/design/circuit/crewconsole + name = "crew monitoring console" + id = "crewconsole" + req_tech = list(TECH_DATA = 3, TECH_MAGNET = 2, TECH_BIO = 2) + build_path = /obj/item/weapon/circuitboard/crew + sort_string = "FAGAI" + +/datum/design/circuit/teleconsole + name = "teleporter control console" + id = "teleconsole" + req_tech = list(TECH_DATA = 3, TECH_BLUESPACE = 2) + build_path = /obj/item/weapon/circuitboard/teleporter + sort_string = "HAAAA" + +/datum/design/circuit/robocontrol + name = "robotics control console" + id = "robocontrol" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/robotics + sort_string = "HAAAB" + +/datum/design/circuit/mechacontrol + name = "exosuit control console" + id = "mechacontrol" + req_tech = list(TECH_DATA = 3) + build_path = /obj/item/weapon/circuitboard/mecha_control + sort_string = "HAAAC" + +/datum/design/circuit/rdconsole + name = "R&D control console" + id = "rdconsole" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/rdconsole + sort_string = "HAAAE" + +/datum/design/circuit/aifixer + name = "AI integrity restorer" + id = "aifixer" + req_tech = list(TECH_DATA = 3, TECH_BIO = 2) + build_path = /obj/item/weapon/circuitboard/aifixer + sort_string = "HAAAF" + +/datum/design/circuit/comm_monitor + name = "telecommunications monitoring console" + id = "comm_monitor" + req_tech = list(TECH_DATA = 3) + build_path = /obj/item/weapon/circuitboard/comm_monitor + sort_string = "HAACA" + +/datum/design/circuit/comm_server + name = "telecommunications server monitoring console" + id = "comm_server" + req_tech = list(TECH_DATA = 3) + build_path = /obj/item/weapon/circuitboard/comm_server + sort_string = "HAACB" + +/datum/design/circuit/message_monitor + name = "messaging monitor console" + id = "message_monitor" + req_tech = list(TECH_DATA = 5) + build_path = /obj/item/weapon/circuitboard/message_monitor + sort_string = "HAACC" + +/datum/design/circuit/aiupload + name = "AI upload console" + id = "aiupload" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/aiupload + sort_string = "HAABA" + +/datum/design/circuit/borgupload + name = "cyborg upload console" + id = "borgupload" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/borgupload + sort_string = "HAABB" + +/datum/design/circuit/destructive_analyzer + name = "destructive analyzer" + id = "destructive_analyzer" + req_tech = list(TECH_DATA = 2, TECH_MAGNET = 2, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/destructive_analyzer + sort_string = "HABAA" + +/datum/design/circuit/protolathe + name = "protolathe" + id = "protolathe" + req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/protolathe + sort_string = "HABAB" + +/datum/design/circuit/circuit_imprinter + name = "circuit imprinter" + id = "circuit_imprinter" + req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/circuit_imprinter + sort_string = "HABAC" + +/datum/design/circuit/autolathe + name = "autolathe board" + id = "autolathe" + req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/autolathe + sort_string = "HABAD" + +/datum/design/circuit/rdservercontrol + name = "R&D server control console" + id = "rdservercontrol" + req_tech = list(TECH_DATA = 3) + build_path = /obj/item/weapon/circuitboard/rdservercontrol + sort_string = "HABBA" + +/datum/design/circuit/rdserver + name = "R&D server" + id = "rdserver" + req_tech = list(TECH_DATA = 3) + build_path = /obj/item/weapon/circuitboard/rdserver + sort_string = "HABBB" + +/datum/design/circuit/mechfab + name = "exosuit fabricator" + id = "mechfab" + req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3) + build_path = /obj/item/weapon/circuitboard/mechfab + sort_string = "HABAE" + +/datum/design/circuit/prosfab + name = "prosthetics fabricator" + id = "prosfab" + req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3) + build_path = /obj/item/weapon/circuitboard/prosthetics + sort_string = "HABAF" + +/datum/design/circuit/mech_recharger + name = "mech recharger" + id = "mech_recharger" + req_tech = list(TECH_DATA = 2, TECH_POWER = 2, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/mech_recharger + sort_string = "HACAA" + +/datum/design/circuit/recharge_station + name = "cyborg recharge station" + id = "recharge_station" + req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/recharge_station + sort_string = "HACAC" + +/datum/design/circuit/atmosalerts + name = "atmosphere alert console" + id = "atmosalerts" + build_path = /obj/item/weapon/circuitboard/atmos_alert + sort_string = "JAAAA" + +/datum/design/circuit/air_management + name = "atmosphere monitoring console" + id = "air_management" + build_path = /obj/item/weapon/circuitboard/air_management + sort_string = "JAAAB" + +/datum/design/circuit/rcon_console + name = "RCON remote control console" + id = "rcon_console" + req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3, TECH_POWER = 5) + build_path = /obj/item/weapon/circuitboard/rcon_console + sort_string = "JAAAC" + +/datum/design/circuit/dronecontrol + name = "drone control console" + id = "dronecontrol" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/drone_control + sort_string = "JAAAD" + +/datum/design/circuit/powermonitor + name = "power monitoring console" + id = "powermonitor" + build_path = /obj/item/weapon/circuitboard/powermonitor + sort_string = "JAAAE" + +/datum/design/circuit/solarcontrol + name = "solar control console" + id = "solarcontrol" + build_path = /obj/item/weapon/circuitboard/solar_control + sort_string = "JAAAF" + +/datum/design/circuit/pacman + name = "PACMAN-type generator" + id = "pacman" + req_tech = list(TECH_DATA = 3, TECH_PHORON = 3, TECH_POWER = 3, TECH_ENGINEERING = 3) + build_path = /obj/item/weapon/circuitboard/pacman + sort_string = "JBAAA" + +/datum/design/circuit/superpacman + name = "SUPERPACMAN-type generator" + id = "superpacman" + req_tech = list(TECH_DATA = 3, TECH_POWER = 4, TECH_ENGINEERING = 4) + build_path = /obj/item/weapon/circuitboard/pacman/super + sort_string = "JBAAB" + +/datum/design/circuit/mrspacman + name = "MRSPACMAN-type generator" + id = "mrspacman" + req_tech = list(TECH_DATA = 3, TECH_POWER = 5, TECH_ENGINEERING = 5) + build_path = /obj/item/weapon/circuitboard/pacman/mrs + sort_string = "JBAAC" + +/datum/design/circuit/batteryrack + name = "cell rack PSU" + id = "batteryrack" + req_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/batteryrack + sort_string = "JBABA" + +/datum/design/circuit/smes_cell + name = "'SMES' superconductive magnetic energy storage" + desc = "Allows for the construction of circuit boards used to build a SMES." + id = "smes_cell" + req_tech = list(TECH_POWER = 7, TECH_ENGINEERING = 5) + build_path = /obj/item/weapon/circuitboard/smes + sort_string = "JBABB" + +/datum/design/circuit/grid_checker + name = "power grid checker" + desc = "Allows for the construction of circuit boards used to build a grid checker." + id = "grid_checker" + req_tech = list(TECH_POWER = 4, TECH_ENGINEERING = 3) + build_path = /obj/item/weapon/circuitboard/grid_checker + sort_string = "JBABC" + +/datum/design/circuit/breakerbox + name = "breaker box" + desc = "Allows for the construction of circuit boards used to build a breaker box." + id = "breakerbox" + req_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3) + build_path = /obj/item/weapon/circuitboard/breakerbox + sort_string = "JBABD" + +/datum/design/circuit/gas_heater + name = "gas heating system" + id = "gasheater" + req_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 1) + build_path = /obj/item/weapon/circuitboard/unary_atmos/heater + sort_string = "JCAAA" + +/datum/design/circuit/gas_cooler + name = "gas cooling system" + id = "gascooler" + req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/unary_atmos/cooler + sort_string = "JCAAB" + +/datum/design/circuit/secure_airlock + name = "secure airlock electronics" + desc = "Allows for the construction of a tamper-resistant airlock electronics." + id = "securedoor" + req_tech = list(TECH_DATA = 3) + build_path = /obj/item/weapon/airlock_electronics/secure + sort_string = "JDAAA" + +/datum/design/circuit/ordercomp + name = "supply ordering console" + id = "ordercomp" + build_path = /obj/item/weapon/circuitboard/ordercomp + sort_string = "KAAAY" // Duplicate string, really need to redo this whole thing + +/datum/design/circuit/supplycomp + name = "supply control console" + id = "supplycomp" + req_tech = list(TECH_DATA = 3) + build_path = /obj/item/weapon/circuitboard/supplycomp + sort_string = "KAAAZ" // Duplicate string, really need to redo this whole thing + +/datum/design/circuit/biogenerator + name = "biogenerator" + id = "biogenerator" + req_tech = list(TECH_DATA = 2) + build_path = /obj/item/weapon/circuitboard/biogenerator + sort_string = "KBAAA" + +/datum/design/circuit/miningdrill + name = "mining drill head" + id = "mining drill head" + req_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1) + build_path = /obj/item/weapon/circuitboard/miningdrill + sort_string = "KCAAA" + +/datum/design/circuit/miningdrillbrace + name = "mining drill brace" + id = "mining drill brace" + req_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1) + build_path = /obj/item/weapon/circuitboard/miningdrillbrace + sort_string = "KCAAB" + +/datum/design/circuit/comconsole + name = "communications console" + id = "comconsole" + build_path = /obj/item/weapon/circuitboard/communications + sort_string = "LAAAA" + +/datum/design/circuit/idcardconsole + name = "ID card modification console" + id = "idcardconsole" + build_path = /obj/item/weapon/circuitboard/card + sort_string = "LAAAB" + +/datum/design/circuit/emp_data + name = "employment records console" + id = "emp_data" + build_path = /obj/item/weapon/circuitboard/skills + sort_string = "LAAAC" + +/datum/design/circuit/mecha + req_tech = list(TECH_DATA = 3) + +/datum/design/circuit/mecha/AssembleDesignName() + name = "Exosuit module circuit design ([name])" +/datum/design/circuit/mecha/AssembleDesignDesc() + desc = "Allows for the construction of \a [name] module." + +/datum/design/circuit/mecha/ripley_main + name = "APLU 'Ripley' central control" + id = "ripley_main" + build_path = /obj/item/weapon/circuitboard/mecha/ripley/main + sort_string = "NAAAA" + +/datum/design/circuit/mecha/ripley_peri + name = "APLU 'Ripley' peripherals control" + id = "ripley_peri" + build_path = /obj/item/weapon/circuitboard/mecha/ripley/peripherals + sort_string = "NAAAB" + +/datum/design/circuit/mecha/odysseus_main + name = "'Odysseus' central control" + id = "odysseus_main" + req_tech = list(TECH_DATA = 3,TECH_BIO = 2) + build_path = /obj/item/weapon/circuitboard/mecha/odysseus/main + sort_string = "NAABA" + +/datum/design/circuit/mecha/odysseus_peri + name = "'Odysseus' peripherals control" + id = "odysseus_peri" + req_tech = list(TECH_DATA = 3,TECH_BIO = 2) + build_path = /obj/item/weapon/circuitboard/mecha/odysseus/peripherals + sort_string = "NAABB" + +/datum/design/circuit/mecha/gygax_main + name = "'Gygax' central control" + id = "gygax_main" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/mecha/gygax/main + sort_string = "NAACA" + +/datum/design/circuit/mecha/gygax_peri + name = "'Gygax' peripherals control" + id = "gygax_peri" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/mecha/gygax/peripherals + sort_string = "NAACB" + +/datum/design/circuit/mecha/gygax_targ + name = "'Gygax' weapon control and targeting" + id = "gygax_targ" + req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2) + build_path = /obj/item/weapon/circuitboard/mecha/gygax/targeting + sort_string = "NAACC" + +/datum/design/circuit/mecha/durand_main + name = "'Durand' central control" + id = "durand_main" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/mecha/durand/main + sort_string = "NAADA" + +/datum/design/circuit/mecha/durand_peri + name = "'Durand' peripherals control" + id = "durand_peri" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/mecha/durand/peripherals + sort_string = "NAADB" + +/datum/design/circuit/mecha/durand_targ + name = "'Durand' weapon control and targeting" + id = "durand_targ" + req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2) + build_path = /obj/item/weapon/circuitboard/mecha/durand/targeting + sort_string = "NAADC" + +/datum/design/circuit/tcom + req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4) + +/datum/design/circuit/tcom/AssembleDesignName() + name = "Telecommunications machinery circuit design ([name])" +/datum/design/circuit/tcom/AssembleDesignDesc() + desc = "Allows for the construction of a telecommunications [name] circuit board." + +/datum/design/circuit/tcom/server + name = "server mainframe" + id = "tcom-server" + build_path = /obj/item/weapon/circuitboard/telecomms/server + sort_string = "PAAAA" + +/datum/design/circuit/tcom/processor + name = "processor unit" + id = "tcom-processor" + build_path = /obj/item/weapon/circuitboard/telecomms/processor + sort_string = "PAAAB" + +/datum/design/circuit/tcom/bus + name = "bus mainframe" + id = "tcom-bus" + build_path = /obj/item/weapon/circuitboard/telecomms/bus + sort_string = "PAAAC" + +/datum/design/circuit/tcom/hub + name = "hub mainframe" + id = "tcom-hub" + build_path = /obj/item/weapon/circuitboard/telecomms/hub + sort_string = "PAAAD" + +/datum/design/circuit/tcom/relay + name = "relay mainframe" + id = "tcom-relay" + req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 4, TECH_BLUESPACE = 3) + build_path = /obj/item/weapon/circuitboard/telecomms/relay + sort_string = "PAAAE" + +/datum/design/circuit/tcom/broadcaster + name = "subspace broadcaster" + id = "tcom-broadcaster" + req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4, TECH_BLUESPACE = 2) + build_path = /obj/item/weapon/circuitboard/telecomms/broadcaster + sort_string = "PAAAF" + +/datum/design/circuit/tcom/receiver + name = "subspace receiver" + id = "tcom-receiver" + req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3, TECH_BLUESPACE = 2) + build_path = /obj/item/weapon/circuitboard/telecomms/receiver + sort_string = "PAAAG" + +/datum/design/circuit/tcom/exonet_node + name = "exonet node" + id = "tcom-exonet_node" + req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 5, TECH_BLUESPACE = 4) + build_path = /obj/item/weapon/circuitboard/telecomms/exonet_node + sort_string = "PAAAH" + +/datum/design/circuit/shield + req_tech = list(TECH_BLUESPACE = 4, TECH_PHORON = 3) + materials = list("glass" = 2000, "gold" = 1000) + +/datum/design/circuit/shield/AssembleDesignName() + name = "Shield generator circuit design ([name])" +/datum/design/circuit/shield/AssembleDesignDesc() + if(!desc) + desc = "Allows for the construction of \a [name] shield generator." + +/datum/design/circuit/shield/bubble + name = "bubble" + id = "shield_gen" + build_path = /obj/item/weapon/circuitboard/shield_gen + sort_string = "VAAAZ" // Duplicate string, really need to redo this whole thing + +/datum/design/circuit/shield/hull + name = "hull" + id = "shield_gen_ex" + build_path = /obj/item/weapon/circuitboard/shield_gen_ex + sort_string = "VAAAB" + +/datum/design/circuit/shield/capacitor + name = "capacitor" + desc = "Allows for the construction of a shield capacitor circuit board." + id = "shield_cap" + req_tech = list(TECH_MAGNET = 3, TECH_POWER = 4) + build_path = /obj/item/weapon/circuitboard/shield_cap + sort_string = "VAAAC" + +/datum/design/circuit/aicore + name = "AI core" + id = "aicore" + req_tech = list(TECH_DATA = 4, TECH_BIO = 3) + build_path = /obj/item/weapon/circuitboard/aicore + sort_string = "XAAAA" + + +/* I have no idea how this was even running before, but it doesn't seem to be necessary. +/////////////////////////////////// +/////////Shield Generators///////// +/////////////////////////////////// +/datum/design/circuit/shield + req_tech = list(TECH_BLUESPACE = 4, TECH_PHORON = 3) + materials = list("$glass" = 2000, "sacid" = 20, "$phoron" = 10000, "$diamond" = 5000, "$gold" = 10000) +*/ \ No newline at end of file diff --git a/code/modules/research/designs/illegal.dm b/code/modules/research/designs/illegal.dm new file mode 100644 index 00000000000..1542e929b67 --- /dev/null +++ b/code/modules/research/designs/illegal.dm @@ -0,0 +1,19 @@ +// Yeah yeah, vague file name. Basically a misc folder for antag things that RnD can make. + +/datum/design/item/binaryencrypt + name = "Binary encryption key" + desc = "Allows for deciphering the binary channel on-the-fly." + id = "binaryencrypt" + req_tech = list(TECH_ILLEGAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 300, "glass" = 300) + build_path = /obj/item/device/encryptionkey/binary + sort_string = "VASAA" + +/datum/design/item/chameleon + name = "Holographic equipment kit" + desc = "A kit of dangerous, high-tech equipment with changeable looks." + id = "chameleon" + req_tech = list(TECH_ILLEGAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 500) + build_path = /obj/item/weapon/storage/box/syndie_kit/chameleon + sort_string = "VASBA" \ No newline at end of file diff --git a/code/modules/research/designs/medical.dm b/code/modules/research/designs/medical.dm new file mode 100644 index 00000000000..8e821fe0fe9 --- /dev/null +++ b/code/modules/research/designs/medical.dm @@ -0,0 +1,186 @@ +/datum/design/item/medical + materials = list(DEFAULT_WALL_MATERIAL = 30, "glass" = 20) + +/datum/design/item/medical/AssembleDesignName() + ..() + name = "Biotech device prototype ([item_name])" + +/datum/design/item/medical/robot_scanner + desc = "A hand-held scanner able to diagnose robotic injuries." + id = "robot_scanner" + req_tech = list(TECH_MAGNET = 3, TECH_BIO = 2, TECH_ENGINEERING = 3) + materials = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 200) + build_path = /obj/item/device/robotanalyzer + sort_string = "MACFA" + +/datum/design/item/medical/mass_spectrometer + desc = "A device for analyzing chemicals in blood." + id = "mass_spectrometer" + req_tech = list(TECH_BIO = 2, TECH_MAGNET = 2) + build_path = /obj/item/device/mass_spectrometer + sort_string = "MACAA" + +/datum/design/item/medical/adv_mass_spectrometer + desc = "A device for analyzing chemicals in blood and their quantities." + id = "adv_mass_spectrometer" + req_tech = list(TECH_BIO = 2, TECH_MAGNET = 4) + build_path = /obj/item/device/mass_spectrometer/adv + sort_string = "MACAB" + +/datum/design/item/medical/reagent_scanner + desc = "A device for identifying chemicals." + id = "reagent_scanner" + req_tech = list(TECH_BIO = 2, TECH_MAGNET = 2) + build_path = /obj/item/device/reagent_scanner + sort_string = "MACBA" + +/datum/design/item/medical/adv_reagent_scanner + desc = "A device for identifying chemicals and their proportions." + id = "adv_reagent_scanner" + req_tech = list(TECH_BIO = 2, TECH_MAGNET = 4) + build_path = /obj/item/device/reagent_scanner/adv + sort_string = "MACBB" + +/datum/design/item/beaker/AssembleDesignName() + name = "Beaker prototype ([item_name])" + +/datum/design/item/beaker/noreact + name = "cryostasis" + desc = "A cryostasis beaker that allows for chemical storage without reactions. Can hold up to 50 units." + id = "splitbeaker" + req_tech = list(TECH_MATERIAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 3000) + build_path = /obj/item/weapon/reagent_containers/glass/beaker/noreact + sort_string = "MADAA" + +/datum/design/item/beaker/bluespace + name = TECH_BLUESPACE + desc = "A bluespace beaker, powered by experimental bluespace technology and Element Cuban combined with the Compound Pete. Can hold up to 300 units." + id = "bluespacebeaker" + req_tech = list(TECH_BLUESPACE = 2, TECH_MATERIAL = 6) + materials = list(DEFAULT_WALL_MATERIAL = 3000, "phoron" = 3000, "diamond" = 500) + build_path = /obj/item/weapon/reagent_containers/glass/beaker/bluespace + sort_string = "MADAB" + +/datum/design/item/medical/nanopaste + desc = "A tube of paste containing swarms of repair nanites. Very effective in repairing robotic machinery." + id = "nanopaste" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3) + materials = list(DEFAULT_WALL_MATERIAL = 7000, "glass" = 7000) + build_path = /obj/item/stack/nanopaste + sort_string = "MBAAA" + +/datum/design/item/medical/scalpel_laser1 + name = "Basic Laser Scalpel" + desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks basic and could be improved." + id = "scalpel_laser1" + req_tech = list(TECH_BIO = 2, TECH_MATERIAL = 2, TECH_MAGNET = 2) + materials = list(DEFAULT_WALL_MATERIAL = 12500, "glass" = 7500) + build_path = /obj/item/weapon/surgical/scalpel/laser1 + sort_string = "MBBAA" + +/datum/design/item/medical/scalpel_laser2 + name = "Improved Laser Scalpel" + desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks somewhat advanced." + id = "scalpel_laser2" + req_tech = list(TECH_BIO = 3, TECH_MATERIAL = 4, TECH_MAGNET = 4) + materials = list(DEFAULT_WALL_MATERIAL = 12500, "glass" = 7500, "silver" = 2500) + build_path = /obj/item/weapon/surgical/scalpel/laser2 + sort_string = "MBBAB" + +/datum/design/item/medical/scalpel_laser3 + name = "Advanced Laser Scalpel" + desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks to be the pinnacle of precision energy cutlery!" + id = "scalpel_laser3" + req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 6, TECH_MAGNET = 5) + materials = list(DEFAULT_WALL_MATERIAL = 12500, "glass" = 7500, "silver" = 2000, "gold" = 1500) + build_path = /obj/item/weapon/surgical/scalpel/laser3 + sort_string = "MBBAC" + +/datum/design/item/medical/scalpel_manager + name = "Incision Management System" + desc = "A true extension of the surgeon's body, this marvel instantly and completely prepares an incision allowing for the immediate commencement of therapeutic steps." + id = "scalpel_manager" + req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 7, TECH_MAGNET = 5, TECH_DATA = 4) + materials = list (DEFAULT_WALL_MATERIAL = 12500, "glass" = 7500, "silver" = 1500, "gold" = 1500, "diamond" = 750) + build_path = /obj/item/weapon/surgical/scalpel/manager + sort_string = "MBBAD" + +/datum/design/item/medical/bone_clamp + name = "Bone Clamp" + desc = "A miracle of modern science, this tool rapidly knits together bone, without the need for bone gel." + id = "bone_clamp" + req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 5, TECH_MAGNET = 4, TECH_DATA = 4) + materials = list (DEFAULT_WALL_MATERIAL = 12500, "glass" = 7500, "silver" = 2500) + build_path = /obj/item/weapon/surgical/bone_clamp + sort_string = "MBBAE" + +/datum/design/item/medical/advanced_roller + name = "advanced roller bed" + desc = "A more advanced version of the regular roller bed, with inbuilt surgical stabilisers and an improved folding system." + id = "roller_bed" + req_tech = list(TECH_BIO = 3, TECH_MATERIAL = 3, TECH_MAGNET = 3) + materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 2000, "phoron" = 2000) + build_path = /obj/item/roller/adv + sort_string = "MBBAF" + +/datum/design/item/medical/improved_analyzer + name = "improved health analyzer" + desc = "A prototype version of the regular health analyzer, able to distinguish the location of more serious injuries as well as accurately determine radiation levels." + id = "improved_analyzer" + req_tech = list(TECH_MAGNET = 5, TECH_BIO = 6) + materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 1500) + build_path = /obj/item/device/healthanalyzer/improved + sort_string = "MBBAG" + +/datum/design/item/implant + materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) + +/datum/design/item/implant/AssembleDesignName() + ..() + name = "Implantable biocircuit design ([item_name])" + +/datum/design/item/implant/chemical + name = "chemical" + id = "implant_chem" + req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3) + build_path = /obj/item/weapon/implantcase/chem + sort_string = "MFAAA" + +/datum/design/item/implant/freedom + name = "freedom" + id = "implant_free" + req_tech = list(TECH_ILLEGAL = 2, TECH_BIO = 3) + build_path = /obj/item/weapon/implantcase/freedom + sort_string = "MFAAB" + +// These are in here because Robotics is close enough to Medical and I don't want to make a new brains.dm file +/datum/design/item/dronebrain + name = "Robotic intelligence circuit" + id = "dronebrain" + req_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 5, TECH_DATA = 4) + build_type = PROTOLATHE | PROSFAB + materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 500) + build_path = /obj/item/device/mmi/digital/robot + category = "Misc" + sort_string = "VACAC" + +/datum/design/item/posibrain + name = "Positronic brain" + id = "posibrain" + req_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 6, TECH_BLUESPACE = 2, TECH_DATA = 4) + build_type = PROTOLATHE | PROSFAB + materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 500, "phoron" = 500, "diamond" = 100) + build_path = /obj/item/device/mmi/digital/posibrain + category = "Misc" + sort_string = "VACAB" + +/datum/design/item/mmi + name = "Man-machine interface" + id = "mmi" + req_tech = list(TECH_DATA = 2, TECH_BIO = 3) + build_type = PROTOLATHE | PROSFAB + materials = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500) + build_path = /obj/item/device/mmi + category = "Misc" + sort_string = "VACBA" \ No newline at end of file diff --git a/code/modules/research/designs/mining_toys.dm b/code/modules/research/designs/mining_toys.dm new file mode 100644 index 00000000000..f9b76032cbd --- /dev/null +++ b/code/modules/research/designs/mining_toys.dm @@ -0,0 +1,48 @@ +// Assorted Mining-related items + +/datum/design/item/weapon/mining/AssembleDesignName() + ..() + name = "Mining equipment design ([item_name])" + +/datum/design/item/weapon/mining/jackhammer + id = "jackhammer" + req_tech = list(TECH_MATERIAL = 3, TECH_POWER = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 500, "silver" = 500) + build_path = /obj/item/weapon/pickaxe/jackhammer + sort_string = "KAAAA" + +/datum/design/item/weapon/mining/drill + id = "drill" + req_tech = list(TECH_MATERIAL = 2, TECH_POWER = 3, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 6000, "glass" = 1000) //expensive, but no need for miners. + build_path = /obj/item/weapon/pickaxe/drill + sort_string = "KAAAB" + +/datum/design/item/weapon/mining/plasmacutter + id = "plasmacutter" + req_tech = list(TECH_MATERIAL = 4, TECH_PHORON = 3, TECH_ENGINEERING = 3) + materials = list(DEFAULT_WALL_MATERIAL = 1500, "glass" = 500, "gold" = 500, "phoron" = 500) + build_path = /obj/item/weapon/pickaxe/plasmacutter + sort_string = "KAAAC" + +/datum/design/item/weapon/mining/pick_diamond + id = "pick_diamond" + req_tech = list(TECH_MATERIAL = 6) + materials = list("diamond" = 3000) + build_path = /obj/item/weapon/pickaxe/diamond + sort_string = "KAAAD" + +/datum/design/item/weapon/mining/drill_diamond + id = "drill_diamond" + req_tech = list(TECH_MATERIAL = 6, TECH_POWER = 4, TECH_ENGINEERING = 4) + materials = list(DEFAULT_WALL_MATERIAL = 3000, "glass" = 1000, "diamond" = 2000) + build_path = /obj/item/weapon/pickaxe/diamonddrill + sort_string = "KAAAE" + +/datum/design/item/device/depth_scanner + desc = "Used to check spatial depth and density of rock outcroppings." + id = "depth_scanner" + req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2, TECH_BLUESPACE = 2) + materials = list(DEFAULT_WALL_MATERIAL = 1000,"glass" = 1000) + build_path = /obj/item/device/depth_scanner + sort_string = "KAAAF" \ No newline at end of file diff --git a/code/modules/research/designs/misc.dm b/code/modules/research/designs/misc.dm new file mode 100644 index 00000000000..ab420d142fd --- /dev/null +++ b/code/modules/research/designs/misc.dm @@ -0,0 +1,203 @@ +/* +// +// THIS IS GOING TO GET REAL DAMN BLOATED, SO LET'S TRY TO AVOID THAT IF POSSIBLE +// +*/ + +/datum/design/item/hud + materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) + +/datum/design/item/hud/AssembleDesignName() + ..() + name = "HUD glasses prototype ([item_name])" + +/datum/design/item/hud/AssembleDesignDesc() + desc = "Allows for the construction of \a [item_name] HUD glasses." + +/datum/design/item/hud/health + name = "health scanner" + id = "health_hud" + req_tech = list(TECH_BIO = 2, TECH_MAGNET = 3) + build_path = /obj/item/clothing/glasses/hud/health + sort_string = "GAAAA" + +/datum/design/item/hud/security + name = "security records" + id = "security_hud" + req_tech = list(TECH_MAGNET = 3, TECH_COMBAT = 2) + build_path = /obj/item/clothing/glasses/hud/security + sort_string = "GAAAB" + +/datum/design/item/hud/mesons + name = "Optical meson scanners design" + desc = "Using the meson-scanning technology those glasses allow you to see through walls, floor or anything else." + id = "mesons" + req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) + build_path = /obj/item/clothing/glasses/meson + sort_string = "GAAAC" + +/datum/design/item/device/ano_scanner + name = "Alden-Saraspova counter" + id = "ano_scanner" + desc = "Aids in triangulation of exotic particles." + req_tech = list(TECH_BLUESPACE = 3, TECH_MAGNET = 3) + materials = list(DEFAULT_WALL_MATERIAL = 10000,"glass" = 5000) + build_path = /obj/item/device/ano_scanner + sort_string = "UAAAH" + +/datum/design/item/light_replacer + name = "Light replacer" + desc = "A device to automatically replace lights. Refill with working lightbulbs." + id = "light_replacer" + req_tech = list(TECH_MAGNET = 3, TECH_MATERIAL = 4) + materials = list(DEFAULT_WALL_MATERIAL = 1500, "silver" = 150, "glass" = 3000) + build_path = /obj/item/device/lightreplacer + sort_string = "VAAAH" + +datum/design/item/laserpointer + name = "laser pointer" + desc = "Don't shine it in your eyes!" + id = "laser_pointer" + req_tech = list(TECH_MAGNET = 3) + materials = list(DEFAULT_WALL_MATERIAL = 100, "glass" = 50) + build_path = /obj/item/device/laser_pointer + sort_string = "VAAAI" + +/datum/design/item/paicard + name = "'pAI', personal artificial intelligence device" + id = "paicard" + req_tech = list(TECH_DATA = 2) + materials = list("glass" = 500, DEFAULT_WALL_MATERIAL = 500) + build_path = /obj/item/device/paicard + sort_string = "VABAI" + +/datum/design/item/communicator + name = "Communicator" + id = "communicator" + req_tech = list(TECH_DATA = 2, TECH_MAGNET = 2) + materials = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 500) + build_path = /obj/item/device/communicator + sort_string = "VABAJ" + +/datum/design/item/beacon + name = "Bluespace tracking beacon design" + id = "beacon" + req_tech = list(TECH_BLUESPACE = 1) + materials = list (DEFAULT_WALL_MATERIAL = 20, "glass" = 10) + build_path = /obj/item/device/radio/beacon + sort_string = "VADAA" + +/datum/design/item/gps + name = "Triangulating device design" + desc = "Triangulates approximate co-ordinates using a nearby satellite network." + id = "gps" + req_tech = list(TECH_MATERIAL = 2, TECH_DATA = 2, TECH_BLUESPACE = 2) + materials = list(DEFAULT_WALL_MATERIAL = 500) + build_path = /obj/item/device/gps + sort_string = "VADAB" + +/datum/design/item/beacon_locator + name = "Beacon tracking pinpointer" + desc = "Used to scan and locate signals on a particular frequency." + id = "beacon_locator" + req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 2, TECH_BLUESPACE = 3) + materials = list(DEFAULT_WALL_MATERIAL = 1000,"glass" = 500) + build_path = /obj/item/device/beacon_locator + sort_string = "VADAC" + +/datum/design/item/bag_holding + name = "'Bag of Holding', an infinite capacity bag prototype" + desc = "Using localized pockets of bluespace this bag prototype offers incredible storage capacity with the contents weighting nothing. It's a shame the bag itself is pretty heavy." + id = "bag_holding" + req_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 6) + materials = list("gold" = 3000, "diamond" = 1500, "uranium" = 250) + build_path = /obj/item/weapon/storage/backpack/holding + sort_string = "VAEAA" + +/datum/design/item/dufflebag_holding + name = "'DuffleBag of Holding', an infinite capacity dufflebag prototype" + desc = "A minaturized prototype of the popular Bag of Holding, the Dufflebag of Holding is, functionally, identical to the bag of holding, but comes in a more stylish and compact form." + id = "dufflebag_holding" + req_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 6) + materials = list("gold" = 3000, "diamond" = 1500, "uranium" = 250) + build_path = /obj/item/weapon/storage/backpack/holding/duffle + sort_string = "VAEAB" + +/datum/design/item/experimental_welder + name = "Experimental welding tool" + desc = "A welding tool that generate fuel for itself." + id = "expwelder" + req_tech = list(TECH_ENGINEERING = 4, TECH_PHORON = 3, TECH_MATERIAL = 4) + materials = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 120, "phoron" = 100) + build_path = /obj/item/weapon/weldingtool/experimental + sort_string = "VASCA" + +/datum/design/item/hand_drill + name = "Hand drill" + desc = "A simple powered hand drill." + id = "handdrill" + req_tech = list(TECH_ENGINEERING = 3, TECH_MATERIAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 300, "silver" = 100) + build_path = /obj/item/weapon/screwdriver/power + sort_string = "VASDA" + +/datum/design/item/jaws_life + name = "Jaws of life" + desc = "A set of jaws of life, compressed through the magic of science." + id = "jawslife" + req_tech = list(TECH_ENGINEERING = 3, TECH_MATERIAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 300, "silver" = 100) + build_path = /obj/item/weapon/crowbar/power + sort_string = "VASEA" + +/datum/design/item/device/t_scanner_upg + name = "Upgraded T-ray Scanner" + desc = "An upgraded version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes." + id = "upgradedtscanner" + req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 4, TECH_MATERIAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 500, "phoron" = 150) + build_path = /obj/item/device/t_scanner/upgraded + sort_string = "VASSA" + +/datum/design/item/device/t_scanner_adv + name = "Advanced T-ray Scanner" + desc = "An advanced version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes." + id = "advancedtscanner" + req_tech = list(TECH_MAGNET = 6, TECH_ENGINEERING = 6, TECH_MATERIAL = 6) + materials = list(DEFAULT_WALL_MATERIAL = 1250, "phoron" = 500, "silver" = 50) + build_path = /obj/item/device/t_scanner/advanced + sort_string = "VASSB" + +/datum/design/item/translator + name = "handheld translator" + id = "translator" + req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3) + materials = list(DEFAULT_WALL_MATERIAL = 3000, "glass" = 3000) + build_path = /obj/item/device/universal_translator + sort_string = "HABQA" + +/datum/design/item/ear_translator + name = "earpiece translator" + id = "ear_translator" + req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 5) //It's been hella miniaturized. + materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 2000, "gold" = 1000) + build_path = /obj/item/device/universal_translator/ear + sort_string = "HABQB" + +/datum/design/item/xenoarch_multi_tool + name = "xenoarcheology multitool" + id = "xenoarch_multitool" + req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3, TECH_BLUESPACE = 3) + build_path = /obj/item/device/xenoarch_multi_tool + materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "uranium" = 500, "phoron" = 500) + sort_string = "HABQC" + +/datum/design/item/excavationdrill + name = "Excavation Drill" + id = "excavationdrill" + req_tech = list(TECH_MATERIAL = 3, TECH_POWER = 2, TECH_ENGINEERING = 2, TECH_BLUESPACE = 3) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 4000) + build_path = /obj/item/weapon/pickaxe/excavationdrill + sort_string = "HABQD" diff --git a/code/modules/research/designs/pdas.dm b/code/modules/research/designs/pdas.dm new file mode 100644 index 00000000000..4aca3062b9a --- /dev/null +++ b/code/modules/research/designs/pdas.dm @@ -0,0 +1,92 @@ +/datum/design/item/pda + name = "PDA design" + desc = "Cheaper than whiny non-digital assistants." + id = "pda" + req_tech = list(TECH_ENGINEERING = 2, TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) + build_path = /obj/item/device/pda + sort_string = "VAAAA" + +// Cartridges +/datum/design/item/pda_cartridge + req_tech = list(TECH_ENGINEERING = 2, TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) + +/datum/design/item/pda_cartridge/AssembleDesignName() + ..() + name = "PDA accessory ([item_name])" + +/datum/design/item/pda_cartridge/cart_basic + id = "cart_basic" + build_path = /obj/item/weapon/cartridge + sort_string = "VBAAA" + +/datum/design/item/pda_cartridge/engineering + id = "cart_engineering" + build_path = /obj/item/weapon/cartridge/engineering + sort_string = "VBAAB" + +/datum/design/item/pda_cartridge/atmos + id = "cart_atmos" + build_path = /obj/item/weapon/cartridge/atmos + sort_string = "VBAAC" + +/datum/design/item/pda_cartridge/medical + id = "cart_medical" + build_path = /obj/item/weapon/cartridge/medical + sort_string = "VBAAD" + +/datum/design/item/pda_cartridge/chemistry + id = "cart_chemistry" + build_path = /obj/item/weapon/cartridge/chemistry + sort_string = "VBAAE" + +/datum/design/item/pda_cartridge/security + id = "cart_security" + build_path = /obj/item/weapon/cartridge/security + sort_string = "VBAAF" + +/datum/design/item/pda_cartridge/janitor + id = "cart_janitor" + build_path = /obj/item/weapon/cartridge/janitor + sort_string = "VBAAG" + +/datum/design/item/pda_cartridge/science + id = "cart_science" + build_path = /obj/item/weapon/cartridge/signal/science + sort_string = "VBAAH" + +/datum/design/item/pda_cartridge/quartermaster + id = "cart_quartermaster" + build_path = /obj/item/weapon/cartridge/quartermaster + sort_string = "VBAAI" + +/datum/design/item/pda_cartridge/hop + id = "cart_hop" + build_path = /obj/item/weapon/cartridge/hop + sort_string = "VBAAJ" + +/datum/design/item/pda_cartridge/hos + id = "cart_hos" + build_path = /obj/item/weapon/cartridge/hos + sort_string = "VBAAK" + +/datum/design/item/pda_cartridge/ce + id = "cart_ce" + build_path = /obj/item/weapon/cartridge/ce + sort_string = "VBAAL" + +/datum/design/item/pda_cartridge/cmo + id = "cart_cmo" + build_path = /obj/item/weapon/cartridge/cmo + sort_string = "VBAAM" + +/datum/design/item/pda_cartridge/rd + id = "cart_rd" + build_path = /obj/item/weapon/cartridge/rd + sort_string = "VBAAN" + +/datum/design/item/pda_cartridge/captain + id = "cart_captain" + build_path = /obj/item/weapon/cartridge/captain + sort_string = "VBAAO" \ No newline at end of file diff --git a/code/modules/research/designs/powercells.dm b/code/modules/research/designs/powercells.dm new file mode 100644 index 00000000000..1ae3a3c3615 --- /dev/null +++ b/code/modules/research/designs/powercells.dm @@ -0,0 +1,71 @@ +/datum/design/item/powercell + build_type = PROTOLATHE | MECHFAB + +/datum/design/item/powercell/AssembleDesignName() + name = "Power Cell Model ([item_name])" + +/datum/design/item/powercell/AssembleDesignDesc() + if(build_path) + var/obj/item/weapon/cell/C = build_path + desc = "Allows the construction of power cells that can hold [initial(C.maxcharge)] units of energy." + +/datum/design/item/powercell/Fabricate() + var/obj/item/weapon/cell/C = ..() + C.charge = 0 //shouldn't produce power out of thin air. + return C + +/datum/design/item/powercell/basic + name = "basic" + build_type = PROTOLATHE | MECHFAB + id = "basic_cell" + req_tech = list(TECH_POWER = 1) + materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 50) + build_path = /obj/item/weapon/cell + category = "Misc" + sort_string = "DAAAA" + +/datum/design/item/powercell/high + name = "high-capacity" + build_type = PROTOLATHE | MECHFAB + id = "high_cell" + req_tech = list(TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 60) + build_path = /obj/item/weapon/cell/high + category = "Misc" + sort_string = "DAAAB" + +/datum/design/item/powercell/super + name = "super-capacity" + id = "super_cell" + req_tech = list(TECH_POWER = 3, TECH_MATERIAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 70) + build_path = /obj/item/weapon/cell/super + category = "Misc" + sort_string = "DAAAC" + +/datum/design/item/powercell/hyper + name = "hyper-capacity" + id = "hyper_cell" + req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4) + materials = list(DEFAULT_WALL_MATERIAL = 400, "gold" = 150, "silver" = 150, "glass" = 70) + build_path = /obj/item/weapon/cell/hyper + category = "Misc" + sort_string = "DAAAD" + +/datum/design/item/powercell/device + name = "device" + build_type = PROTOLATHE + id = "device" + materials = list(DEFAULT_WALL_MATERIAL = 350, "glass" = 25) + build_path = /obj/item/weapon/cell/device + category = "Misc" + sort_string = "DAABA" + +/datum/design/item/powercell/weapon + name = "weapon" + build_type = PROTOLATHE + id = "weapon" + materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 50) + build_path = /obj/item/weapon/cell/device/weapon + category = "Misc" + sort_string = "DAABB" \ No newline at end of file diff --git a/code/modules/research/designs/stock_parts.dm b/code/modules/research/designs/stock_parts.dm new file mode 100644 index 00000000000..fb629e7ad70 --- /dev/null +++ b/code/modules/research/designs/stock_parts.dm @@ -0,0 +1,178 @@ +/* + Various Stock Parts +*/ + +/datum/design/item/stock_part + build_type = PROTOLATHE + +/datum/design/item/stock_part/AssembleDesignName() + ..() + name = "Component design ([item_name])" + +/datum/design/item/stock_part/AssembleDesignDesc() + if(!desc) + desc = "A stock part used in the construction of various devices." + +/datum/design/item/stock_part/basic_capacitor + id = "basic_capacitor" + req_tech = list(TECH_POWER = 1) + materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) + build_path = /obj/item/weapon/stock_parts/capacitor + sort_string = "CAAAA" + +/datum/design/item/stock_part/adv_capacitor + id = "adv_capacitor" + req_tech = list(TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) + build_path = /obj/item/weapon/stock_parts/capacitor/adv + sort_string = "CAAAB" + +/datum/design/item/stock_part/super_capacitor + id = "super_capacitor" + req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4) + materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, "gold" = 20) + build_path = /obj/item/weapon/stock_parts/capacitor/super + sort_string = "CAAAC" + +/datum/design/item/stock_part/micro_mani + id = "micro_mani" + req_tech = list(TECH_MATERIAL = 1, TECH_DATA = 1) + materials = list(DEFAULT_WALL_MATERIAL = 30) + build_path = /obj/item/weapon/stock_parts/manipulator + sort_string = "CAABA" + +/datum/design/item/stock_part/nano_mani + id = "nano_mani" + req_tech = list(TECH_MATERIAL = 3, TECH_DATA = 2) + materials = list(DEFAULT_WALL_MATERIAL = 30) + build_path = /obj/item/weapon/stock_parts/manipulator/nano + sort_string = "CAABB" + +/datum/design/item/stock_part/pico_mani + id = "pico_mani" + req_tech = list(TECH_MATERIAL = 5, TECH_DATA = 2) + materials = list(DEFAULT_WALL_MATERIAL = 30) + build_path = /obj/item/weapon/stock_parts/manipulator/pico + sort_string = "CAABC" + +/datum/design/item/stock_part/basic_matter_bin + id = "basic_matter_bin" + req_tech = list(TECH_MATERIAL = 1) + materials = list(DEFAULT_WALL_MATERIAL = 80) + build_path = /obj/item/weapon/stock_parts/matter_bin + sort_string = "CAACA" + +/datum/design/item/stock_part/adv_matter_bin + id = "adv_matter_bin" + req_tech = list(TECH_MATERIAL = 3) + materials = list(DEFAULT_WALL_MATERIAL = 80) + build_path = /obj/item/weapon/stock_parts/matter_bin/adv + sort_string = "CAACB" + +/datum/design/item/stock_part/super_matter_bin + id = "super_matter_bin" + req_tech = list(TECH_MATERIAL = 5) + materials = list(DEFAULT_WALL_MATERIAL = 80) + build_path = /obj/item/weapon/stock_parts/matter_bin/super + sort_string = "CAACC" + +/datum/design/item/stock_part/basic_micro_laser + id = "basic_micro_laser" + req_tech = list(TECH_MAGNET = 1) + materials = list(DEFAULT_WALL_MATERIAL = 10, "glass" = 20) + build_path = /obj/item/weapon/stock_parts/micro_laser + sort_string = "CAADA" + +/datum/design/item/stock_part/high_micro_laser + id = "high_micro_laser" + req_tech = list(TECH_MAGNET = 3) + materials = list(DEFAULT_WALL_MATERIAL = 10, "glass" = 20) + build_path = /obj/item/weapon/stock_parts/micro_laser/high + sort_string = "CAADB" + +/datum/design/item/stock_part/ultra_micro_laser + id = "ultra_micro_laser" + req_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 5) + materials = list(DEFAULT_WALL_MATERIAL = 10, "glass" = 20, "uranium" = 10) + build_path = /obj/item/weapon/stock_parts/micro_laser/ultra + sort_string = "CAADC" + +/datum/design/item/stock_part/basic_sensor + id = "basic_sensor" + req_tech = list(TECH_MAGNET = 1) + materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 20) + build_path = /obj/item/weapon/stock_parts/scanning_module + sort_string = "CAAEA" + +/datum/design/item/stock_part/adv_sensor + id = "adv_sensor" + req_tech = list(TECH_MAGNET = 3) + materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 20) + build_path = /obj/item/weapon/stock_parts/scanning_module/adv + sort_string = "CAAEB" + +/datum/design/item/stock_part/phasic_sensor + id = "phasic_sensor" + req_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 3) + materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 20, "silver" = 10) + build_path = /obj/item/weapon/stock_parts/scanning_module/phasic + sort_string = "CAAEC" + +/datum/design/item/stock_part/subspace_ansible + id = "s-ansible" + req_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) + materials = list(DEFAULT_WALL_MATERIAL = 80, "silver" = 20) + build_path = /obj/item/weapon/stock_parts/subspace/ansible + sort_string = "UAAAA" + +/datum/design/item/stock_part/hyperwave_filter + id = "s-filter" + req_tech = list(TECH_DATA = 3, TECH_MAGNET = 3) + materials = list(DEFAULT_WALL_MATERIAL = 40, "silver" = 10) + build_path = /obj/item/weapon/stock_parts/subspace/sub_filter + sort_string = "UAAAB" + +/datum/design/item/stock_part/subspace_amplifier + id = "s-amplifier" + req_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10, "gold" = 30, "uranium" = 15) + build_path = /obj/item/weapon/stock_parts/subspace/amplifier + sort_string = "UAAAC" + +/datum/design/item/stock_part/subspace_treatment + id = "s-treatment" + req_tech = list(TECH_DATA = 3, TECH_MAGNET = 2, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10, "silver" = 20) + build_path = /obj/item/weapon/stock_parts/subspace/treatment + sort_string = "UAAAD" + +/datum/design/item/stock_part/subspace_analyzer + id = "s-analyzer" + req_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10, "gold" = 15) + build_path = /obj/item/weapon/stock_parts/subspace/analyzer + sort_string = "UAAAE" + +/datum/design/item/stock_part/subspace_crystal + id = "s-crystal" + req_tech = list(TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) + materials = list("glass" = 1000, "silver" = 20, "gold" = 20) + build_path = /obj/item/weapon/stock_parts/subspace/crystal + sort_string = "UAAAF" + +/datum/design/item/stock_part/subspace_transmitter + id = "s-transmitter" + req_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 5, TECH_BLUESPACE = 3) + materials = list("glass" = 100, "silver" = 10, "uranium" = 15) + build_path = /obj/item/weapon/stock_parts/subspace/transmitter + sort_string = "UAAAG" + +// RPED lives here because it handles stock parts +/datum/design/item/stock_part/RPED + name = "Rapid Part Exchange Device" + desc = "Special mechanical module made to store, sort, and apply standard machine parts." + id = "rped" + req_tech = list(TECH_ENGINEERING = 3, TECH_MATERIAL = 3) + materials = list(DEFAULT_WALL_MATERIAL = 15000, "glass" = 5000) + build_path = /obj/item/weapon/storage/part_replacer + sort_string = "CBAAA" \ No newline at end of file diff --git a/code/modules/research/designs/uncommented.dm b/code/modules/research/designs/uncommented.dm new file mode 100644 index 00000000000..7bbf53571ae --- /dev/null +++ b/code/modules/research/designs/uncommented.dm @@ -0,0 +1,69 @@ + +/* Uncomment if someone makes these buildable +/datum/design/circuit/general_alert + name = "general alert console" + id = "general_alert" + build_path = /obj/item/weapon/circuitboard/general_alert + +// Removal of loyalty implants. Can't think of a way to add this to the config option. +/datum/design/item/implant/loyalty + name = "loyalty" + id = "implant_loyal" + req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3) + materials = list(DEFAULT_WALL_MATERIAL = 7000, "glass" = 7000) + build_path = /obj/item/weapon/implantcase/loyalty" + +/datum/design/rust_core_control + name = "Circuit Design (RUST core controller)" + desc = "Allows for the construction of circuit boards used to build a core control console for the RUST fusion engine." + id = "rust_core_control" + req_tech = list("programming" = 4, "engineering" = 4) + build_type = IMPRINTER + materials = list("glass" = 2000, "sacid" = 20) + build_path = "/obj/item/weapon/circuitboard/rust_core_control" + +datum/design/rust_fuel_control + name = "Circuit Design (RUST fuel controller)" + desc = "Allows for the construction of circuit boards used to build a fuel injector control console for the RUST fusion engine." + id = "rust_fuel_control" + req_tech = list("programming" = 4, "engineering" = 4) + build_type = IMPRINTER + materials = list("glass" = 2000, "sacid" = 20) + build_path = "/obj/item/weapon/circuitboard/rust_fuel_control" + +datum/design/rust_fuel_port + name = "Internal circuitry (RUST fuel port)" + desc = "Allows for the construction of circuit boards used to build a fuel injection port for the RUST fusion engine." + id = "rust_fuel_port" + req_tech = list("engineering" = 4, "materials" = 5) + build_type = IMPRINTER + materials = list("glass" = 2000, "sacid" = 20, "uranium" = 3000) + build_path = "/obj/item/weapon/module/rust_fuel_port" + +datum/design/rust_fuel_compressor + name = "Circuit Design (RUST fuel compressor)" + desc = "Allows for the construction of circuit boards used to build a fuel compressor of the RUST fusion engine." + id = "rust_fuel_compressor" + req_tech = list("materials" = 6, "phorontech" = 4) + build_type = IMPRINTER + materials = list("glass" = 2000, "sacid" = 20, "phoron" = 3000, "diamond" = 1000) + build_path = "/obj/item/weapon/module/rust_fuel_compressor" + +datum/design/rust_core + name = "Internal circuitry (RUST tokamak core)" + desc = "The circuit board that for a RUST-pattern tokamak fusion core." + id = "pacman" + req_tech = list(bluespace = 3, phorontech = 4, magnets = 5, powerstorage = 6) + build_type = IMPRINTER + materials = list("glass" = 2000, "sacid" = 20, "phoron" = 3000, "diamond" = 2000) + build_path = "/obj/item/weapon/circuitboard/rust_core" + +datum/design/rust_injector + name = "Internal circuitry (RUST tokamak core)" + desc = "The circuit board that for a RUST-pattern particle accelerator." + id = "pacman" + req_tech = list(powerstorage = 3, engineering = 4, phorontech = 4, materials = 6) + build_type = IMPRINTER + materials = list("glass" = 2000, "sacid" = 20, "phoron" = 3000, "uranium" = 2000) + build_path = "/obj/item/weapon/circuitboard/rust_core" +*/ diff --git a/code/modules/research/designs/weapons.dm b/code/modules/research/designs/weapons.dm new file mode 100644 index 00000000000..828856aebad --- /dev/null +++ b/code/modules/research/designs/weapons.dm @@ -0,0 +1,193 @@ +/datum/design/item/weapon/AssembleDesignName() + ..() + name = "Weapon prototype ([item_name])" + +/datum/design/item/weapon/AssembleDesignDesc() + if(!desc) + if(build_path) + var/obj/item/I = build_path + desc = initial(I.desc) + ..() + +/datum/design/item/weapon/stunrevolver + id = "stunrevolver" + req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 4000) + build_path = /obj/item/weapon/gun/energy/stunrevolver + sort_string = "TAAAA" + +/datum/design/item/weapon/nuclear_gun + id = "nuclear_gun" + req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 5, TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000, "uranium" = 500) + build_path = /obj/item/weapon/gun/energy/gun/nuclear + sort_string = "TAAAB" + +/datum/design/item/weapon/lasercannon + desc = "The lasing medium of this prototype is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core." + id = "lasercannon" + req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 1000, "diamond" = 2000) + build_path = /obj/item/weapon/gun/energy/lasercannon + sort_string = "TAAAC" + +/datum/design/item/weapon/phoronpistol + id = "ppistol" + req_tech = list(TECH_COMBAT = 5, TECH_PHORON = 4) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000, "phoron" = 3000) + build_path = /obj/item/weapon/gun/energy/toxgun + sort_string = "TAAAD" + +/datum/design/item/weapon/decloner + id = "decloner" + req_tech = list(TECH_COMBAT = 8, TECH_MATERIAL = 7, TECH_BIO = 5, TECH_POWER = 6) + materials = list("gold" = 5000,"uranium" = 10000) + build_path = /obj/item/weapon/gun/energy/decloner + sort_string = "TAAAE" + +/datum/design/item/weapon/smg + id = "smg" + desc = "An compact reliable SMG firing armor piercing ammo." + req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3) + materials = list(DEFAULT_WALL_MATERIAL = 8000, "silver" = 2000, "diamond" = 1000) + build_path = /obj/item/weapon/gun/projectile/automatic/saber + sort_string = "TAABA" + +/datum/design/item/weapon/ammo_9mm + id = "ammo_9mm" + req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3) + materials = list(DEFAULT_WALL_MATERIAL = 3750, "silver" = 100) + build_path = /obj/item/ammo_magazine/box/c9mm + sort_string = "TAACA" + +/datum/design/item/weapon/stunshell + desc = "A stunning shell for a shotgun." + id = "stunshell" + req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3) + materials = list(DEFAULT_WALL_MATERIAL = 4000) + build_path = /obj/item/ammo_casing/a12g/stunshell + sort_string = "TAACB" + +/datum/design/item/weapon/chemsprayer + desc = "An advanced chem spraying device." + id = "chemsprayer" + req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_BIO = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000) + build_path = /obj/item/weapon/reagent_containers/spray/chemsprayer + sort_string = "TABAA" + +/datum/design/item/weapon/rapidsyringe + id = "rapidsyringe" + req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_BIO = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000) + build_path = /obj/item/weapon/gun/launcher/syringe/rapid + sort_string = "TABAB" + +/datum/design/item/weapon/temp_gun + desc = "A gun that shoots high-powered glass-encased energy temperature bullets." + id = "temp_gun" + req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 4, TECH_POWER = 3, TECH_MAGNET = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 500, "silver" = 3000) + build_path = /obj/item/weapon/gun/energy/temperature + sort_string = "TABAC" + +/datum/design/item/weapon/large_grenade + id = "large_Grenade" + req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 3000) + build_path = /obj/item/weapon/grenade/chem_grenade/large + sort_string = "TACAA" + +/datum/design/item/weapon/dartgun + desc = "A gun that fires small hollow chemical-payload darts." + id = "dartgun_r" + req_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 4, TECH_BIO = 4, TECH_MAGNET = 3, TECH_ILLEGAL = 1) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "gold" = 5000, "silver" = 2500, "glass" = 750) + build_path = /obj/item/weapon/gun/projectile/dartgun/research + sort_string = "TACAB" + +/datum/design/item/weapon/dartgunmag_small + id = "dartgun_mag_s" + req_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 2, TECH_BIO = 2, TECH_MAGNET = 1, TECH_ILLEGAL = 1) + materials = list(DEFAULT_WALL_MATERIAL = 300, "gold" = 100, "silver" = 100, "glass" = 300) + build_path = /obj/item/ammo_magazine/chemdart/small + sort_string = "TACAC" + +/datum/design/item/weapon/dartgun_ammo_small + id = "dartgun_ammo_s" + req_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 2, TECH_BIO = 2, TECH_MAGNET = 1, TECH_ILLEGAL = 1) + materials = list(DEFAULT_WALL_MATERIAL = 50, "gold" = 30, "silver" = 30, "glass" = 50) + build_path = /obj/item/ammo_casing/chemdart/small + sort_string = "TACAD" + +/datum/design/item/weapon/dartgunmag_med + id = "dartgun_mag_m" + req_tech = list(TECH_COMBAT = 7, TECH_MATERIAL = 2, TECH_BIO = 2, TECH_MAGNET = 1, TECH_ILLEGAL = 1) + materials = list(DEFAULT_WALL_MATERIAL = 500, "gold" = 150, "silver" = 150, "diamond" = 200, "glass" = 400) + build_path = /obj/item/ammo_magazine/chemdart + sort_string = "TACAE" + +/datum/design/item/weapon/dartgun_ammo_med + id = "dartgun_ammo_m" + req_tech = list(TECH_COMBAT = 7, TECH_MATERIAL = 2, TECH_BIO = 2, TECH_MAGNET = 1, TECH_ILLEGAL = 1) + materials = list(DEFAULT_WALL_MATERIAL = 80, "gold" = 40, "silver" = 40, "glass" = 60) + build_path = /obj/item/ammo_casing/chemdart + sort_string = "TACAF" + +/datum/design/item/weapon/fuelrod + id = "fuelrod_gun" + req_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 4, TECH_PHORON = 4, TECH_ILLEGAL = 5, TECH_MAGNET = 5) + materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 2000, "gold" = 500, "silver" = 500, "uranium" = 1000, "phoron" = 3000, "diamond" = 1000) + build_path = /obj/item/weapon/gun/magnetic/fuelrod + sort_string = "TACBA" + +/datum/design/item/weapon/flora_gun + id = "flora_gun" + req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3, TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 500, "uranium" = 500) + build_path = /obj/item/weapon/gun/energy/floragun + sort_string = "TBAAA" + +// Xenobio Tools +/datum/design/item/weapon/slimebation + id = "slimebation" + req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2, TECH_POWER = 3, TECH_COMBAT = 3) + materials = list(DEFAULT_WALL_MATERIAL = 5000) + build_path = /obj/item/weapon/melee/baton/slime + sort_string = "TBAAB" + +/datum/design/item/weapon/slimetaser + id = "slimetaser" + req_tech = list(TECH_MATERIAL = 3, TECH_BIO = 3, TECH_POWER = 4, TECH_COMBAT = 4) + materials = list(DEFAULT_WALL_MATERIAL = 5000) + build_path = /obj/item/weapon/gun/energy/taser/xeno + sort_string = "TBAAC" + +// Phase Weapons +/datum/design/item/weapon/phase_pistol + id = "phasepistol" + req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 4000) + build_path = /obj/item/weapon/gun/energy/phasegun/pistol + sort_string = "TPAAA" + +/datum/design/item/weapon/phase_carbine + id = "phasecarbine" + req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 6000, "glass" = 1500) + build_path = /obj/item/weapon/gun/energy/phasegun + sort_string = "TPAAB" + +/datum/design/item/weapon/phase_rifle + id = "phaserifle" + req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 7000, "glass" = 2000, "silver" = 500) + build_path = /obj/item/weapon/gun/energy/phasegun/rifle + sort_string = "TPAAC" + +/datum/design/item/weapon/phase_cannon + id = "phasecannon" + req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 4, TECH_POWER = 4) + materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 2000, "silver" = 1000, "diamond" = 750) + build_path = /obj/item/weapon/gun/energy/phasegun/cannon + sort_string = "TPAAD" \ No newline at end of file diff --git a/code/modules/research/designs_vr.dm b/code/modules/research/designs_vr.dm index e074323cbdd..c50712ac22c 100644 --- a/code/modules/research/designs_vr.dm +++ b/code/modules/research/designs_vr.dm @@ -92,13 +92,22 @@ build_path = /obj/item/device/nif sort_string = "HABBC" +/datum/design/item/nifbio + name = "bioadaptive NIF" + id = "bioadapnif" + req_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5, TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_DATA = 5, TECH_BIO = 5) + materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 15000, "uranium" = 10000, "diamond" = 10000) + build_path = /obj/item/device/nif/bioadap + sort_string = "HABBD" //Changed String from HABBE to HABBD +//Addiing bioadaptive NIF to Protolathe + /datum/design/item/nifrepairtool name = "adv. NIF repair tool" id = "anrt" req_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5, TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_DATA = 5) materials = list(DEFAULT_WALL_MATERIAL = 200, "glass" = 3000, "uranium" = 2000, "diamond" = 2000) build_path = /obj/item/device/nifrepairer - sort_string = "HABBD" + sort_string = "HABBE" //Changed String from HABBD to HABBE // Resleeving Circuitboards diff --git a/code/modules/resleeving/computers.dm b/code/modules/resleeving/computers.dm index 8ece411267d..6c9a635ffc9 100644 --- a/code/modules/resleeving/computers.dm +++ b/code/modules/resleeving/computers.dm @@ -121,7 +121,7 @@ var/pods_list_ui[0] for(var/obj/machinery/clonepod/transhuman/pod in pods) - pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.biomass) + pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.get_biomass()) var/spods_list_ui[0] for(var/obj/machinery/transhuman/synthprinter/spod in spods) @@ -294,7 +294,7 @@ temp = "Error: Growpod is currently occupied." //Not enough materials. - else if(pod.biomass < CLONE_BIOMASS) + else if(pod.get_biomass() < CLONE_BIOMASS) temp = "Error: Not enough biomass." //Gross pod (broke mid-cloning or something). diff --git a/code/modules/resleeving/implant.dm b/code/modules/resleeving/implant.dm index 0bfe571a8b9..adb3d38e1c3 100644 --- a/code/modules/resleeving/implant.dm +++ b/code/modules/resleeving/implant.dm @@ -27,13 +27,9 @@ SStranscore.implants -= src return ..() -/obj/item/weapon/implant/backup/implanted(var/mob/living/carbon/human/H) - ..() +/obj/item/weapon/implant/backup/post_implant(var/mob/living/carbon/human/H) if(istype(H)) - var/obj/item/weapon/implant/backup/other_imp = locate(/obj/item/weapon/implant/backup,H) - if(other_imp && other_imp.imp_in == H) - qdel(other_imp) //implant fight - + BITSET(H.hud_updateflag, BACKUP_HUD) SStranscore.implants |= src return 1 @@ -107,18 +103,10 @@ M.visible_message("[M] has been backup implanted by [user].") var/obj/item/weapon/implant/backup/imp = imps[imps.len] - if(imp.implanted(M)) - imp.forceMove(M) + if(imp.handle_implant(M,user.zone_sel.selecting)) + imp.post_implant(M) imps -= imp - imp.imp_in = M - imp.implanted = 1 add_attack_logs(user,M,"Implanted backup implant") - if (ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - affected.implants += imp - imp.part = affected - BITSET(H.hud_updateflag, BACKUP_HUD) update() diff --git a/code/modules/resleeving/machines.dm b/code/modules/resleeving/machines.dm index 4cb67937345..69f0cfebd1a 100644 --- a/code/modules/resleeving/machines.dm +++ b/code/modules/resleeving/machines.dm @@ -8,6 +8,12 @@ name = "grower pod" circuit = /obj/item/weapon/circuitboard/transhuman_clonepod +//A full version of the pod +/obj/machinery/clonepod/transhuman/full/initialize() + . = ..() + for(var/i = 1 to container_limit) + containers += new /obj/item/weapon/reagent_containers/glass/bottle/biomass(src) + /obj/machinery/clonepod/transhuman/growclone(var/datum/transhuman/body_record/current_project) //Manage machine-specific stuff. if(mess || attempting) @@ -18,6 +24,9 @@ spawn(30) eject_wait = 0 + // Remove biomass when the cloning is started, rather than when the guy pops out + remove_biomass(CLONE_BIOMASS) + //Get the DNA and generate a new mob var/datum/dna2/record/R = current_project.mydna var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species) @@ -110,16 +119,6 @@ return 1 /obj/machinery/clonepod/transhuman/process() - - var/visible_message = 0 - for(var/obj/item/weapon/reagent_containers/food/snacks/meat/meat in range(1, src)) - qdel(meat) - biomass += 50 - visible_message = 1 // Prevent chatspam if multiple meat are near - - if(visible_message) - visible_message("[src] sucks in and processes the nearby biomass.") - if(stat & NOPOWER) if(occupant) locked = 0 @@ -539,14 +538,8 @@ //Give them a backup implant var/obj/item/weapon/implant/backup/new_imp = new() - if(new_imp.implanted(occupant)) - new_imp.loc = occupant - new_imp.imp_in = occupant - new_imp.implanted = 1 - //Put it in the head! Makes sense. - var/obj/item/organ/external/affected = occupant.get_organ(BP_HEAD) - affected.implants += new_imp - new_imp.part = affected + if(new_imp.handle_implant(occupant, BP_HEAD)) + new_imp.post_implant(occupant) //Inform them and make them a little dizzy. if(confuse_amount + blur_amount <= 16) diff --git a/code/modules/shieldgen/handheld_defuser.dm b/code/modules/shieldgen/handheld_defuser.dm index a2909fa7e6e..d65a0060a8e 100644 --- a/code/modules/shieldgen/handheld_defuser.dm +++ b/code/modules/shieldgen/handheld_defuser.dm @@ -7,11 +7,6 @@ var/obj/item/weapon/cell/device/cell var/enabled = 0 -/obj/item/weapon/shield_diffuser/update_icon() - if(enabled) - icon_state = "hdiffuser_on" - else - icon_state = "hdiffuser_off" /obj/item/weapon/shield_diffuser/New() cell = new(src) @@ -24,6 +19,9 @@ processing_objects.Remove(src) . = ..() +/obj/item/weapon/shield_diffuser/get_cell() + return cell + /obj/item/weapon/shield_diffuser/process() if(!enabled) return @@ -34,6 +32,12 @@ if(istype(S) && cell.checked_use(10 KILOWATTS * CELLRATE)) qdel(S) +/obj/item/weapon/shield_diffuser/update_icon() + if(enabled) + icon_state = "hdiffuser_on" + else + icon_state = "hdiffuser_off" + /obj/item/weapon/shield_diffuser/attack_self() enabled = !enabled update_icon() diff --git a/code/modules/surgery/external_repair.dm b/code/modules/surgery/external_repair.dm new file mode 100644 index 00000000000..b26d803b343 --- /dev/null +++ b/code/modules/surgery/external_repair.dm @@ -0,0 +1,215 @@ +//Procedures in this file: Organic limb repair +////////////////////////////////////////////////////////////////// +// LIMB REPAIR SURGERY // +////////////////////////////////////////////////////////////////// +/datum/surgery_step/repairflesh/ + priority = 1 + can_infect = 1 + blood_level = 1 + req_open = 1 + +/datum/surgery_step/repairflesh/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if (target.stat == DEAD) // Sorry defibs, your subjects need to have pumping fluids for these to work. + return 0 + if (isslime(target)) + return 0 + if (target_zone == O_EYES || target_zone == O_MOUTH) + return 0 + if (!hasorgans(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (affected == null) + return 0 + if (affected.is_stump()) + return 0 + if (affected.robotic >= ORGAN_ROBOT) + return 0 + return 1 + + +////////////////////////////////////////////////////////////////// +// SCAN STEP // +////////////////////////////////////////////////////////////////// + +/datum/surgery_step/repairflesh/scan_injury + allowed_tools = list( + /obj/item/weapon/autopsy_scanner = 100, + /obj/item/device/healthanalyzer = 80, + /obj/item/device/analyzer = 10 + ) + + priority = 2 + + can_infect = 0 //The only exception here. Sweeping a scanner probably won't transfer many germs. + + min_duration = 20 + max_duration = 40 + +/datum/surgery_step/repairflesh/scan_injury/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(..()) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(affected.burn_stage || affected.brute_stage) + return 0 + return 1 + return 0 + +/datum/surgery_step/repairflesh/scan_injury/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] begins scanning [target]'s [affected] with \the [tool].", \ + "You begin scanning [target]'s [affected] with \the [tool].") + ..() + +/datum/surgery_step/repairflesh/scan_injury/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] finishes scanning [target]'s [affected].", \ + "You finish scanning [target]'s [affected].") + if(affected.brute_dam) + to_chat(user, "The muscle in [target]'s [affected] is notably bruised.") + if(affected.status & ORGAN_BROKEN) + to_chat(user, "\The [target]'s [affected] is broken!") + affected.brute_stage = max(1, affected.brute_stage) + if(affected.burn_dam) + to_chat(user, "\The muscle in [target]'s [affected] is notably charred.") + affected.burn_stage = max(1, affected.burn_stage) + +/datum/surgery_step/repairflesh/scan_injury/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user]'s hand slips, dropping \the [tool] onto [target]'s [affected]!" , \ + "Your hand slips, dropping \the [tool] onto [target]'s [affected]!" ) + affected.createwound(BRUISE, 10) + +////////////////////////////////////////////////////////////////// +// BURN STEP // +////////////////////////////////////////////////////////////////// + +/datum/surgery_step/repairflesh/repair_burns + allowed_tools = list( + /obj/item/stack/medical/advanced/ointment = 100, + /obj/item/weapon/surgical/FixOVein = 100, + /obj/item/weapon/surgical/hemostat = 60, + /obj/item/stack/medical/ointment = 50, + /obj/item/weapon/tape_roll = 30, + /obj/item/taperoll = 10 + ) + + priority = 3 + + min_duration = 90 + max_duration = 120 + +/datum/surgery_step/repairflesh/repair_burns/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(..()) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(affected.burn_stage < 1 || !(affected.burn_dam)) + return 0 + if(affected.burn_dam < affected.brute_dam) + return 0 + return 1 + return 0 + +/datum/surgery_step/repairflesh/repair_burns/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll)) + user.visible_message("[user] begins taping up [target]'s [affected] with \the [tool].", \ + "You begin taping up [target]'s [affected] with \the [tool].") + affected.jostle_bone(10) + else if(istype(tool, /obj/item/weapon/surgical/hemostat) || istype(tool, /obj/item/weapon/surgical/FixOVein)) + user.visible_message("[user] begins mending the charred blood vessels in [target]'s [affected] with \the [tool].", \ + "You begin mending the charred blood vessels in [target]'s [affected] with \the [tool].") + else + user.visible_message("[user] begins coating the charred tissue in [target]'s [affected] with \the [tool].", \ + "You begin coating the charred tissue in [target]'s [affected] with \the [tool].") + ..() + +/datum/surgery_step/repairflesh/repair_burns/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll)) + user.visible_message("[user] finishes taping up [target]'s [affected] with \the [tool].", \ + "You finish taping up [target]'s [affected] with \the [tool].") + affected.createwound(BRUISE, 10) + affected.heal_damage(0, 25, 0, 0) + if(!(affected.burn_dam)) + affected.burn_stage = 0 + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/T = tool + T.use(1) + ..() + +/datum/surgery_step/repairflesh/repair_burns/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user]'s hand slips, tearing up [target]'s [affected] with \the [tool].", \ + "Your hand slips, tearing up [target]'s [affected] with \the [tool].") + affected.createwound(BRUISE, 10) + affected.createwound(CUT, 5) + if(istype(tool, /obj/item/stack) && prob(30)) + var/obj/item/stack/T = tool + T.use(1) + ..() + +////////////////////////////////////////////////////////////////// +// BRUTE STEP // +////////////////////////////////////////////////////////////////// + +/datum/surgery_step/repairflesh/repair_brute + allowed_tools = list( + /obj/item/stack/medical/advanced/bruise_pack = 100, + /obj/item/weapon/surgical/cautery = 100, + /obj/item/weapon/surgical/bonesetter = 60, + /obj/item/stack/medical/bruise_pack = 50, + /obj/item/weapon/tape_roll = 40, + /obj/item/taperoll = 10 + ) + + priority = 3 + + min_duration = 90 + max_duration = 120 + +/datum/surgery_step/repairflesh/repair_brute/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(..()) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(affected.brute_stage < 1 || !(affected.brute_dam)) + return 0 + if(affected.brute_dam < affected.burn_dam) + return 0 + return 1 + return 0 + +/datum/surgery_step/repairflesh/repair_brute/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll)) + user.visible_message("[user] begins taping up [target]'s [affected] with \the [tool].", \ + "You begin taping up [target]'s [affected] with \the [tool].") + affected.jostle_bone(10) + else if(istype(tool, /obj/item/weapon/surgical/FixOVein) || istype(tool, /obj/item/weapon/surgical/bonesetter)) + user.visible_message("[user] begins mending the torn tissue in [target]'s [affected] with \the [tool].", \ + "You begin mending the torn tissue in [target]'s [affected] with \the [tool].") + else + user.visible_message("[user] begins coating the tissue in [target]'s [affected] with \the [tool].", \ + "You begin coating the tissue in [target]'s [affected] with \the [tool].") + ..() + +/datum/surgery_step/repairflesh/repair_brute/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(istype(tool, /obj/item/weapon/tape_roll) || istype(tool, /obj/item/taperoll)) + user.visible_message("[user] finishes taping up [target]'s [affected] with \the [tool].", \ + "You finish taping up [target]'s [affected] with \the [tool].") + affected.createwound(BRUISE, 10) + affected.heal_damage(25, 0, 0, 0) + if(!(affected.brute_dam)) + affected.brute_stage = 0 + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/T = tool + T.use(1) + ..() + +/datum/surgery_step/repairflesh/repair_brute/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user]'s hand slips, tearing up [target]'s [affected] with \the [tool].", \ + "Your hand slips, tearing up [target]'s [affected] with \the [tool].") + affected.createwound(BRUISE, 10) + affected.createwound(CUT, 5) + if(istype(tool, /obj/item/stack) && prob(30)) + var/obj/item/stack/T = tool + T.use(1) + ..() diff --git a/code/modules/vore/appearance/sprite_accessories_vr.dm b/code/modules/vore/appearance/sprite_accessories_vr.dm index 13c2f7b2da6..ed43a5ff293 100644 --- a/code/modules/vore/appearance/sprite_accessories_vr.dm +++ b/code/modules/vore/appearance/sprite_accessories_vr.dm @@ -88,16 +88,58 @@ do_colouration = 1 color_blend_mode = ICON_MULTIPLY +/datum/sprite_accessory/ears/curly_bug + name = "curly antennae, colorable" + desc = "" + icon_state = "curly_bug" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + +/datum/sprite_accessory/ears/dual_robot + name = "synth antennae, colorable" + desc = "" + icon_state = "dual_robot_antennae" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + +/datum/sprite_accessory/ears/right_robot + name = "right synth, colorable" + desc = "" + icon_state = "right_robot_antennae" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + +/datum/sprite_accessory/ears/left_robot + name = "left synth, colorable" + desc = "" + icon_state = "left_robot_antennae" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + /datum/sprite_accessory/ears/oni_h1 name = "oni horns" desc = "" icon_state = "oni-h1" +/datum/sprite_accessory/ears/oni_h1_c + name = "oni horns, colorable" + desc = "" + icon_state = "oni-h1_c" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + /datum/sprite_accessory/ears/demon_horns1 name = "demon horns" desc = "" icon_state = "demon-horns1" +/datum/sprite_accessory/ears/demon_horns1_c + name = "demon horns, colorable" + desc = "" + icon_state = "demon-horns1_c" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + /datum/sprite_accessory/ears/demon_horns2 name = "demon horns, colorable(outward)" desc = "" @@ -105,6 +147,13 @@ do_colouration = 1 color_blend_mode = ICON_MULTIPLY +/datum/sprite_accessory/ears/dragon_horns + name = "dragon horns, colorable" + desc = "" + icon_state = "dragon-horns" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + /datum/sprite_accessory/ears/foxears name = "highlander zorren ears" desc = "" @@ -170,6 +219,13 @@ do_colouration = 1 color_blend_mode = ICON_MULTIPLY +/datum/sprite_accessory/ears/smallbear + name = "small bear" + desc = "" + icon_state = "smallbear" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + /datum/sprite_accessory/ears/squirrelhc name = "squirrel, colorable" desc = "" @@ -207,6 +263,28 @@ color_blend_mode = ICON_MULTIPLY extra_overlay = "antlers_mark" +/datum/sprite_accessory/ears/smallantlers + name = "small antlers" + desc = "" + icon_state = "smallantlers" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + +/datum/sprite_accessory/ears/smallantlers_e + name = "small antlers with ears" + desc = "" + icon_state = "smallantlers" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + extra_overlay = "deer" + +/datum/sprite_accessory/ears/deer + name = "deer ears" + desc = "" + icon_state = "deer" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + /datum/sprite_accessory/ears/cow name = "cow, horns" desc = "" @@ -226,6 +304,13 @@ do_colouration = 1 color_blend_mode = ICON_MULTIPLY +/datum/sprite_accessory/ears/caprahorns + name = "caprine horns" + desc = "" + icon_state = "caprahorns" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + /datum/sprite_accessory/ears/otie name = "otie, colorable" desc = "" @@ -255,6 +340,13 @@ do_colouration = 1 color_blend_mode = ICON_MULTIPLY +/datum/sprite_accessory/ears/drake + name = "drake frills" + desc = "" + icon_state = "drake" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + /datum/sprite_accessory/ears/vulp name = "vulpkanin, dual-color" desc = "" @@ -413,6 +505,7 @@ desc = "" icon_state = "spider-legs" color_blend_mode = ICON_MULTIPLY + /datum/sprite_accessory/wing/moth name = "moth wings" desc = "" @@ -682,12 +775,14 @@ icon_state = "fantail" do_colouration = 1 color_blend_mode = ICON_MULTIPLY + /datum/sprite_accessory/tail/wagtail name = "avian wagtail, colorable" desc = "" icon_state = "wagtail" do_colouration = 1 color_blend_mode = ICON_MULTIPLY + /datum/sprite_accessory/tail/crossfox name = "cross fox" desc = "" diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm index 4b1d8ef0a50..e7f3df020c7 100644 --- a/code/modules/vore/eating/belly_obj_vr.dm +++ b/code/modules/vore/eating/belly_obj_vr.dm @@ -578,6 +578,11 @@ if(!(content in src) || !istype(target)) return content.forceMove(target) + if(isitem(content)) + var/obj/item/I = content + if(I.gurgled && (target.mode_flags & DM_FLAG_ITEMWEAK)) + I.decontaminate() + I.gurgle_contaminate(target.contents, target.cont_flavor) items_preserved -= content if(!silent && target.vore_sound && !recent_sound) var/soundfile = vore_sounds[target.vore_sound] diff --git a/code/modules/vore/eating/bellymodes_vr.dm b/code/modules/vore/eating/bellymodes_vr.dm index 62fc770e493..4278f7a59ea 100644 --- a/code/modules/vore/eating/bellymodes_vr.dm +++ b/code/modules/vore/eating/bellymodes_vr.dm @@ -38,7 +38,7 @@ if(isitem(A) && !did_an_item) var/obj/item/I = A if(mode_flags & DM_FLAG_ITEMWEAK) - I.gurgle_contaminate(contents, cont_flavor) + I.gurgle_contaminate(src, cont_flavor) items_preserved |= I to_update = TRUE else diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index d5d6191d5c6..3d118f285b4 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -2,6 +2,7 @@ /mob/living var/digestable = 1 // Can the mob be digested inside a belly? var/allowmobvore = 1 // Will simplemobs attempt to eat the mob? + var/showvoreprefs = 1 // Determines if the mechanical vore preferences button will be displayed on the mob or not. var/obj/belly/vore_selected // Default to no vore capability. var/list/vore_organs = list() // List of vore containers inside a mob var/absorbed = 0 // If a mob is absorbed into another @@ -612,7 +613,8 @@ /mob/living/examine(mob/user) . = ..() - to_chat(user, "\[Mechanical Vore Preferences\]") + if(showvoreprefs) + to_chat(user, "\[Mechanical Vore Preferences\]") /mob/living/Topic(href, href_list) //Can't find any instances of Topic() being overridden by /mob/living in polaris' base code, even though /mob/living/carbon/human's Topic() has a ..() call if(href_list["vore_prefs"]) diff --git a/code/modules/vore/eating/vore_vr.dm b/code/modules/vore/eating/vore_vr.dm index d6939e9c95c..a3b5fec4a5c 100644 --- a/code/modules/vore/eating/vore_vr.dm +++ b/code/modules/vore/eating/vore_vr.dm @@ -149,9 +149,14 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE return 0 //Write it out +#ifdef RUST_G + call(RUST_G, "file_write")(json_to_file, path) +#else + // Fall back to using old format if we are not using rust-g if(fexists(path)) fdel(path) //Byond only supports APPENDING to files, not replacing. - text2file(json_to_file,path) + text2file(json_to_file, path) +#endif if(!fexists(path)) log_debug("Saving: [path] failed file write") return 0 diff --git a/code/modules/vore/fluffstuff/custom_boxes_vr.dm b/code/modules/vore/fluffstuff/custom_boxes_vr.dm index 57b83c98768..3aec6baf838 100644 --- a/code/modules/vore/fluffstuff/custom_boxes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_boxes_vr.dm @@ -100,10 +100,10 @@ new /obj/item/clothing/suit/storage/fluff/modernfedcoat(src) new /obj/item/clothing/head/caphat/formal/fedcover(src) new /obj/item/weapon/card/id/centcom/station/fluff/joanbadge(src) - new /obj/item/weapon/gun/energy/gun/fluff/dominator(src) +// new /obj/item/weapon/gun/energy/gun/fluff/dominator(src) new /obj/item/clothing/suit/armor/det_suit(src) - new /obj/item/clothing/accessory/permit/gun/fluff/joanrisu(src) - new /obj/item/weapon/sword/fluff/joanaria(src) +// new /obj/item/clothing/accessory/permit/gun/fluff/joanrisu(src) +// new /obj/item/weapon/sword/fluff/joanaria(src) new /obj/item/weapon/flame/lighter/zippo/fluff/joan(src) new /obj/item/clothing/under/rank/internalaffairs/fluff/joan(src) new /obj/item/clothing/head/helmet/space/fluff/joan(src) @@ -121,13 +121,10 @@ ..() new /obj/item/clothing/accessory/holster/hip(src) new /obj/item/clothing/suit/storage/fluff/fedcoat(src) - new /obj/item/weapon/gun/energy/gun/fluff/dominator(src) +// new /obj/item/weapon/gun/energy/gun/fluff/dominator(src) new /obj/item/clothing/suit/armor/det_suit(src) new /obj/item/clothing/accessory/storage/black_vest(src) new /obj/item/weapon/material/knife/tacknife/combatknife/fluff/katarina(src) - new /obj/item/weapon/material/knife/tacknife/combatknife/fluff/katarina(src) - new /obj/item/weapon/material/knife/tacknife/combatknife/fluff/katarina(src) - new /obj/item/weapon/material/knife/tacknife/combatknife/fluff/katarina(src) new /obj/item/clothing/under/rank/internalaffairs/fluff/joan(src) //drakefrostpaw:Drake Frostpaw @@ -172,7 +169,7 @@ can_hold = list(/obj/item/clothing/under/swimsuit/) has_items = list(/obj/item/clothing/under/swimsuit/fluff/penelope) -//Aerowing:Sebastian Aji +// Aerowing:Sebastian Aji /obj/item/weapon/storage/box/fluff/sebastian_aji name = "Sebastian's Lumoco Arms P3 Box" has_items = list( @@ -181,18 +178,22 @@ /obj/item/ammo_magazine/m9mm/compact/flash, /obj/item/clothing/accessory/permit/gun/fluff/sebastian_aji) +/* /obj/item/weapon/storage/box/fluff/briana_moore name = "Briana's Derringer Box" has_items = list( /obj/item/weapon/gun/projectile/derringer/fluff/briana, /obj/item/clothing/accessory/permit/gun/fluff/briana_moore) +*/ +/* //SilencedMP5A5:Serdykov Antoz /obj/item/weapon/storage/box/fluff/serdykov_antoz name = "Serdy's Weapon Box" has_items = list( /obj/item/clothing/accessory/permit/gun/fluff/silencedmp5a5, /obj/item/weapon/gun/projectile/colt/fluff/serdy) +*/ //BeyondMyLife: Ne'tra Ky'ram //Made a box because they have so many items that it'd spam the debug log. /obj/item/weapon/storage/box/fluff/kilano @@ -217,6 +218,13 @@ /obj/item/clothing/gloves/fluff/morsleeves, /obj/item/clothing/under/fluff/morunder) +// Mewchild: Phi Vietsi +/obj/item/weapon/storage/box/fluff/vietsi + name = "Phi's Personal Items" + desc = "A small box containing Phi's small things" + has_items = list( + /obj/item/clothing/accessory/medal/bronze_heart, + /obj/item/clothing/gloves/ring/seal/signet/fluff/vietsi) /* Swimsuits, for general use, to avoid arriving to work with your swimsuit. diff --git a/code/modules/vore/fluffstuff/custom_clothes_vr.dm b/code/modules/vore/fluffstuff/custom_clothes_vr.dm index dfa69659788..9e62b46e288 100644 --- a/code/modules/vore/fluffstuff/custom_clothes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_clothes_vr.dm @@ -1680,9 +1680,10 @@ Departamental Swimsuits, for general use //Mewchild: Phi Vietsi /obj/item/clothing/gloves/ring/seal/signet/fluff/vietsi - name = "signet ring" - desc = "A signet ring carved from the bones of something long extinct, as a ward against bad luck." - + name = "Phi Vietsi's Bone Signet Ring" + desc = "A signet ring belonging to Phi Vietsi, carved from the bones of something long extinct, as a ward against bad luck." + var/signet_name = "Phi Vietsi" + icon = 'icons/vore/custom_clothes_vr.dmi' icon_state = "vietsi_ring" diff --git a/code/modules/vore/fluffstuff/custom_guns_vr.dm b/code/modules/vore/fluffstuff/custom_guns_vr.dm index c696182ae93..06d133c441f 100644 --- a/code/modules/vore/fluffstuff/custom_guns_vr.dm +++ b/code/modules/vore/fluffstuff/custom_guns_vr.dm @@ -541,6 +541,7 @@ /obj/item/projectile/beam/imperial name = "laser beam" + fire_sound = 'sound/weapons/mandalorian.ogg' icon_state = "darkb" light_color = "#8837A3" muzzle_type = /obj/effect/projectile/darkmatter/muzzle diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm index 9d895b3893e..b28f145cca1 100644 --- a/code/modules/vore/fluffstuff/custom_items_vr.dm +++ b/code/modules/vore/fluffstuff/custom_items_vr.dm @@ -725,7 +725,7 @@ random_emote = list("hisses softly with a blush on his face", "yelps in embarrassment", "grunts a little") assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_roiz -/obj/item/weapon/implant/reagent_generator/roiz/implanted(mob/living/carbon/source) +/obj/item/weapon/implant/reagent_generator/roiz/post_implant(mob/living/carbon/source) processing_objects += src to_chat(source, "You implant [source] with \the [src].") source.verbs |= assigned_proc @@ -793,7 +793,7 @@ random_emote = list("hisses softly with a blush on her face", "bites down on her lower lip", "lets out a light huff") assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_jasmine -/obj/item/weapon/implant/reagent_generator/jasmine/implanted(mob/living/carbon/source) +/obj/item/weapon/implant/reagent_generator/jasmine/post_implant(mob/living/carbon/source) processing_objects += src to_chat(source, "You implant [source] with \the [src].") source.verbs |= assigned_proc @@ -861,7 +861,7 @@ random_emote = list("hisses softly with a blush on her face", "yelps in embarrassment", "grunts a little") assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_yonra -/obj/item/weapon/implant/reagent_generator/yonra/implanted(mob/living/carbon/source) +/obj/item/weapon/implant/reagent_generator/yonra/post_implant(mob/living/carbon/source) processing_objects += src to_chat(source, "You implant [source] with \the [src].") source.verbs |= assigned_proc @@ -945,7 +945,7 @@ random_emote = list("trembles and huffs, panting from the exertion.", "sees what has happened and covers her face with both hands!", "whimpers softly, her legs shivering, knees pointed inward from the feeling.") assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_rischi -/obj/item/weapon/implant/reagent_generator/rischi/implanted(mob/living/carbon/source) +/obj/item/weapon/implant/reagent_generator/rischi/post_implant(mob/living/carbon/source) processing_objects += src to_chat(source, "You implant [source] with \the [src].") source.verbs |= assigned_proc @@ -1640,7 +1640,7 @@ random_emote = list("hisses softly with a blush on his face", "yelps in embarrassment", "grunts a little") assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_evian -/obj/item/weapon/implant/reagent_generator/evian/implanted(mob/living/carbon/source) +/obj/item/weapon/implant/reagent_generator/evian/post_implant(mob/living/carbon/source) processing_objects += src to_chat(source, "You implant [source] with \the [src].") source.verbs |= assigned_proc diff --git a/code/modules/vore/fluffstuff/custom_permits_vr.dm b/code/modules/vore/fluffstuff/custom_permits_vr.dm index c96783e2464..84297129e4e 100644 --- a/code/modules/vore/fluffstuff/custom_permits_vr.dm +++ b/code/modules/vore/fluffstuff/custom_permits_vr.dm @@ -11,50 +11,57 @@ name = "Sebastian Aji's Sidearm Permit" desc = "A card indicating that the owner is allowed to carry a sidearm. It is issued by CentCom, so it is valid until it expires on April 17th, 2563." -// arokha:Aronai Kadigan + +/* arokha:Aronai Kadigan /obj/item/clothing/accessory/permit/gun/fluff/aronai_kadigan name = "Aronai Kadigan's Sidearm Permit" desc = "A card indicating that the owner is allowed to carry a sidearm. It is issued by CentCom, so it is valid until it expires on February 16th, 2562." +*/ // bwoincognito:Tasald Corlethian /obj/item/clothing/accessory/permit/gun/fluff/tasald_corlethian name = "Tasald Ajax Corlethian's Sidearm Permit" desc = "A card indicating that the owner is allowed to carry a sidearm. It is issued by CentCom, so it is valid until it expires on August 2nd, 2562." -// dhaeleena:Dhaeleena M'iar +/* dhaeleena:Dhaeleena M'iar /obj/item/clothing/accessory/permit/gun/fluff/dhaeleena_miar name = "Dhaeleena M'iar's Sidearm Permit" desc = "A card indicating that the owner is allowed to carry a sidearm that uses less-than-lethal munitions. It is issued by CentCom, so it is valid until it expires on March 1st, 2562." +*/ // jertheace:Jeremiah 'Ace' Acacius /obj/item/clothing/accessory/permit/gun/fluff/ace name = "Ace's Shotgun Permit" desc = "A card indicating that the owner is allowed to carry a firearm. It is issued by CentCom, so it is valid until it expires on October 1st, 2562." -// joanrisu:Joan Risu +/* joanrisu:Joan Risu /obj/item/clothing/accessory/permit/gun/fluff/joanrisu name = "Joan Risu's Sidearm Permit" desc = "A card indicating that the owner is allowed to carry a sidearm. It is issued by CentCom, so it is valid until it expires on April 4th, 2562." +*/ -// luminescent_ring:Briana Moore +/* luminescent_ring:Briana Moore /obj/item/clothing/accessory/permit/gun/fluff/briana_moore name = "Briana Moore's Sidearm Permit" desc = "A card indicating that the owner is allowed to carry a sidearm. It is issued by CentCom, so it is valid until it expires on April 24th, 2562." +*/ -// silenedmp5a5:Serdykov Antoz +/* silenedmp5a5:Serdykov Antoz /obj/item/clothing/accessory/permit/gun/fluff/silencedmp5a5 name = "Serdykov Antoz's Sidearm Permit" desc = "A card indicating that the owner is allowed to carry a sidearm that uses less-than-lethal munitions. It is issued by CentCom, so it is valid until it expires on April 24th, 2562." +*/ // pawoverlord:Sorrel Cavalet /obj/item/clothing/accessory/permit/gun/fluff/sorrel_cavalet name = "Sorrel Cavalet's Sidearm Permit" desc = "A card indicating that the owner is allowed to carry a sidearm. It is issued by CentCom, so it is valid until it expires on September 26th, 2562." -// hzdonut:Jesse Soemmer +/* hzdonut:Jesse Soemmer /obj/item/clothing/accessory/permit/gun/fluff/JesseSoemmer name = "Jesse Soemmer's Sidearm Permit" desc = "A card indicating that the owner is allowed to carry a sidearm. It is issued by CentCom, so it is valid until it expires on March 4, 2563." +*/ /* Legacy Permits // BEGIN - PROTOTYPE diff --git a/config/alienwhitelist.txt b/config/alienwhitelist.txt index 18604aaf622..d1874e6b2be 100644 --- a/config/alienwhitelist.txt +++ b/config/alienwhitelist.txt @@ -23,6 +23,7 @@ seiga - Vox sepulchre - Vox sepulchre - Xenomorph Hybrid silverTalismen - Diona +silverTalismen - Vox silvertalismen - Xenochimera singo - Gutter some~user - Species diff --git a/config/custom_items.txt b/config/custom_items.txt index 8869ef3c518..95a98545d61 100644 --- a/config/custom_items.txt +++ b/config/custom_items.txt @@ -88,11 +88,13 @@ character_name: Aronai Kadigan item_path: /obj/item/weapon/card/id/centcom/station/fluff/aronai } +Weapon Box. Permit Expired { ckey: aerowing character_name: Sebastian Aji item_path: /obj/item/weapon/storage/box/fluff/sebastian_aji } + # ######## B CKEYS { ckey: benemuel @@ -188,17 +190,18 @@ character_name: Dhaeleena M'iar item_path: /obj/item/clothing/accessory/medal/silver/security/fluff/dhael } -{ -ckey: dhaeleena -character_name: Dhaeleena M'iar -item_path: /obj/item/weapon/gun/projectile/revolver/mateba/fluff/dhael -} - -{ -ckey: dhaeleena -character_name: Dhaeleena M'iar -item_path: /obj/item/clothing/accessory/permit/gun/fluff/dhaeleena_miar -} +#Permit Expired +#{ +#ckey: dhaeleena +#character_name: Dhaeleena M'iar +#item_path: /obj/item/weapon/gun/projectile/revolver/mateba/fluff/dhael +#} +# +#{ +#ckey: dhaeleena +#character_name: Dhaeleena M'iar +#item_path: /obj/item/clothing/accessory/permit/gun/fluff/dhaeleena_miar +#} { ckey: dickfreedomjohnson @@ -306,23 +309,23 @@ character_name: Belle Day item_path: /obj/item/weapon/implanter/reagent_generator/belle } -{ -ckey: hzdonut -character_name: Jesse Soemmer -item_path: /obj/item/weapon/gun/projectile/revolver/fluff/jesselemat -} - -{ -ckey: hzdonut -character_name: Jesse Soemmer -item_path: /obj/item/clothing/accessory/permit/gun/fluff/JesseSoemmer -} - -{ -ckey: hzdonut -character_name: Jesse Soemmer -item_path: /obj/item/clothing/accessory/holster/hip -} +#{ +#ckey: hzdonut +#character_name: Jesse Soemmer +#item_path: /obj/item/weapon/gun/projectile/revolver/fluff/jesselemat +#} +# +#{ +#ckey: hzdonut +#character_name: Jesse Soemmer +#item_path: /obj/item/clothing/accessory/permit/gun/fluff/JesseSoemmer +#} +# +#{ +#ckey: hzdonut +#character_name: Jesse Soemmer +#item_path: /obj/item/clothing/accessory/holster/hip +#} # ######## I CKEYS @@ -513,11 +516,14 @@ item_path: /obj/item/weapon/implanter/reagent_generator/rischi } # ######## L CKEYS + +#Weapon Box. Permit Expired #{ #ckey: luminescentring #character_name: Briana Moore #item_path: /obj/item/weapon/storage/box/fluff/briana_moore #} + { ckey: luminescentring character_name: Briana Moore @@ -534,7 +540,7 @@ item_path: /obj/item/weapon/implanter/reagent_generator/savannah { ckey: mewchild character_name: Phi Vietsi -item_path: /obj/item/clothing/gloves/ring/seal/signet/fluff/vietsi +item_path: /obj/item/weapon/storage/box/fluff/vietsi } { @@ -725,7 +731,7 @@ item_path: /obj/item/clothing/glasses/sunglasses/fluff/alfonso #item_path: /obj/item/clothing/suit/armor/vest/wolftaur/serdy #req_access = 1 #} - +# #{ #ckey: silencedmp5a5 #character_name: Serdykov Antoz diff --git a/config/jobwhitelist.txt b/config/jobwhitelist.txt index 168eccbcda9..e615f5eafd7 100644 --- a/config/jobwhitelist.txt +++ b/config/jobwhitelist.txt @@ -7,3 +7,4 @@ whiskyrose - clown tinybear16 - clown chargae - mime verkister - clown +H0lySquirr3l - clown diff --git a/html/changelog.html b/html/changelog.html index 9c933a1741d..c61d9998ce8 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,20 @@ -->
+

21 June 2018

+

Anewbe updated:

+ +

Mechoid updated:

+ +

08 June 2018

Anewbe updated: