diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index 92dd6f5d51..4a4c29dcfb 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -132,7 +132,7 @@ obj/var/phoronproof = 0 eye_blurry = min(eye_blurry+1.5,50) if (prob(max(0,E.damage - 15) + 1) &&!eye_blind) src << "You are blinded!" - eye_blind += 20 + Blind(20) /mob/living/carbon/human/proc/pl_head_protected() //Checks if the head is adequately sealed. diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index c4d0511b99..b93a32aa67 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -69,6 +69,11 @@ #define COLOR_PALE_RED_GRAY "#CC9090" #define COLOR_PALE_PURPLE_GRAY "#BDA2BA" #define COLOR_PURPLE_GRAY "#A2819E" +#define COLOR_RED_LIGHT "#FF3333" +#define COLOR_DEEP_SKY_BLUE "#00e1ff" + + + // Shuttles. diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 1dc6436355..ef00eed334 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -148,6 +148,12 @@ #define INCAPACITATION_DISABLED (INCAPACITATION_KNOCKDOWN|INCAPACITATION_STUNNED) #define INCAPACITATION_ALL (~INCAPACITATION_NONE) +#define MODIFIER_STACK_FORBID 1 // Disallows stacking entirely. +#define MODIFIER_STACK_EXTEND 2 // Disallows a second instance, but will extend the first instance if possible. +#define MODIFIER_STACK_ALLOWED 3 // Multiple instances are allowed. + +#define MODIFIER_GENETIC 0 // Modifiers with this flag will be copied to mobs who get cloned. + // Bodyparts and organs. #define O_MOUTH "mouth" #define O_EYES "eyes" @@ -200,4 +206,10 @@ #define TASTE_SENSITIVE 2 //anything below 7% #define TASTE_NORMAL 1 //anything below 15% #define TASTE_DULL 0.5 //anything below 30% -#define TASTE_NUMB 0.1 //anything below 150% \ No newline at end of file +#define TASTE_NUMB 0.1 //anything below 150% + +// If they're in an FBP, what braintype. +#define FBP_NONE "" +#define FBP_CYBORG "Cyborg" +#define FBP_POSI "Positronic" +#define FBP_DRONE "Drone" \ No newline at end of file diff --git a/code/__defines/planets.dm b/code/__defines/planets.dm new file mode 100644 index 0000000000..e8f526382e --- /dev/null +++ b/code/__defines/planets.dm @@ -0,0 +1,15 @@ +#define WEATHER_CLEAR "clear" +#define WEATHER_OVERCAST "overcast" +#define WEATHER_LIGHT_SNOW "light snow" +#define WEATHER_SNOW "snow" +#define WEATHER_BLIZZARD "blizzard" +#define WEATHER_RAIN "rain" +#define WEATHER_STORM "storm" +#define WEATHER_HAIL "hail" +#define WEATHER_WINDY "windy" +#define WEATHER_HOT "hot" +#define WEATHER_BLOOD_MOON "blood moon" // For admin fun or cult later on. + +#define PLANET_PROCESS_WEATHER 0x1 +#define PLANET_PROCESS_SUN 0x2 +#define PLANET_PROCESS_TEMP 0x4 \ No newline at end of file diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 2413cb57ae..7b8fe1bc86 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -82,6 +82,9 @@ avoid code duplication. This includes items that may sometimes act as a standard playsound(loc, hitsound, 50, 1, -1) var/power = force + for(var/datum/modifier/M in user.modifiers) + if(!isnull(M.outgoing_melee_damage_percent)) + power *= M.outgoing_melee_damage_percent if(HULK in user.mutations) power *= 2 return target.hit_with_weapon(src, user, power, hit_zone) diff --git a/code/controllers/Processes/planet.dm b/code/controllers/Processes/planet.dm index b3b556d7bd..7b446b4d2d 100644 --- a/code/controllers/Processes/planet.dm +++ b/code/controllers/Processes/planet.dm @@ -2,16 +2,77 @@ var/datum/controller/process/planet/planet_controller = null /datum/controller/process/planet var/list/planets = list() + var/list/z_to_planet = list() /datum/controller/process/planet/setup() - name = "planet" + name = "planet controller" planet_controller = src - schedule_interval = 600 // every minute + schedule_interval = 1 MINUTE + var/list/planet_datums = typesof(/datum/planet) - /datum/planet for(var/P in planet_datums) var/datum/planet/NP = new P() planets.Add(NP) + allocateTurfs() + +/datum/controller/process/planet/proc/allocateTurfs() + for(var/turf/simulated/OT in outdoor_turfs) + for(var/datum/planet/P in planets) + if(OT.z in P.expected_z_levels) + P.planet_floors += OT + break + outdoor_turfs.Cut() //Why were you in there INCORRECTLY? + + for(var/turf/unsimulated/wall/planetary/PW in planetary_walls) + for(var/datum/planet/P in planets) + if(PW.type == P.planetary_wall_type) + P.planet_walls += PW + break + planetary_walls.Cut() + +/datum/controller/process/planet/proc/unallocateTurf(var/turf/T) + for(var/planet in planets) + var/datum/planet/P = planet + if(T.z in P.expected_z_levels) + P.planet_floors -= T + /datum/controller/process/planet/doWork() + if(outdoor_turfs.len || planetary_walls.len) + allocateTurfs() + for(var/datum/planet/P in planets) - P.process(schedule_interval / 10) \ No newline at end of file + P.process(schedule_interval / 10) + SCHECK //Your process() really shouldn't take this long... + //Weather style needs redrawing + if(P.needs_work & PLANET_PROCESS_WEATHER) + P.needs_work &= ~PLANET_PROCESS_WEATHER + var/image/new_overlay = image(icon = P.weather_holder.current_weather.icon, icon_state = P.weather_holder.current_weather.icon_state, layer = LIGHTING_LAYER - 1) + //Redraw weather icons + for(var/T in P.planet_floors) + var/turf/simulated/turf = T + turf.overlays -= turf.weather_overlay + turf.weather_overlay = new_overlay + turf.overlays += turf.weather_overlay + SCHECK + + //Sun light needs changing + if(P.needs_work & PLANET_PROCESS_SUN) + P.needs_work &= ~PLANET_PROCESS_SUN + //Redraw sun overlay + var/new_range = P.sun["range"] + var/new_brightness = P.sun["brightness"] + var/new_color = P.sun["color"] + for(var/T in P.planet_floors) + var/turf/simulated/turf = T + turf.set_light(new_range, new_brightness, new_color) + SCHECK + + //Temperature needs updating + if(P.needs_work & PLANET_PROCESS_TEMP) + P.needs_work &= ~PLANET_PROCESS_TEMP + //Set new temperatures + for(var/W in P.planet_walls) + var/turf/unsimulated/wall/planetary/wall = W + wall.set_temperature(P.weather_holder.temperature) + SCHECK diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 22b7b77477..96ddec2b06 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -157,6 +157,8 @@ var/list/gamemode_cache = list() var/slime_delay = 0 var/animal_delay = 0 + var/footstep_volume = 0 + var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database @@ -772,6 +774,8 @@ var/list/gamemode_cache = list() if("animal_delay") config.animal_delay = value + if("footstep_volume") + config.footstep_volume = text2num(value) if("use_loyalty_implants") config.use_loyalty_implants = 1 diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 4a861c65dd..7acc6b28ce 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -25,7 +25,7 @@ usr.client.debug_variables(antag) message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.") -/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano","Chemistry","Vote","Xenobio")) +/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano","Chemistry","Vote","Xenobio","Planets")) set category = "Debug" set name = "Debug Controller" set desc = "Debug the various periodic loop controllers for the game (be careful!)" @@ -98,6 +98,9 @@ if("Xenobio") debug_variables(xenobio_controller) feedback_add_details("admin_verb", "DXenobio") + 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 d40fd4fa5a..274c0c0903 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -184,6 +184,10 @@ G.fields["real_rank"] = H.mind.assigned_role G.fields["rank"] = assignment G.fields["age"] = H.age + if(H.get_FBP_type()) + G.fields["brain_type"] = H.get_FBP_type() + else + G.fields["brain_type"] = "Organic" G.fields["fingerprint"] = md5(H.dna.uni_identity) G.fields["p_stat"] = "Active" G.fields["m_stat"] = "Stable" @@ -201,11 +205,19 @@ M.fields["b_type"] = H.b_type M.fields["b_dna"] = H.dna.unique_enzymes M.fields["id_gender"] = gender2text(H.identifying_gender) + if(H.get_FBP_type()) + M.fields["brain_type"] = H.get_FBP_type() + else + M.fields["brain_type"] = "Organic" if(H.med_record && !jobban_isbanned(H, "Records")) M.fields["notes"] = H.med_record //Security Record var/datum/data/record/S = CreateSecurityRecord(H.real_name, id) + if(H.get_FBP_type()) + S.fields["brain_type"] = H.get_FBP_type() + else + S.fields["brain_type"] = "Organic" if(H.sec_record && !jobban_isbanned(H, "Records")) S.fields["notes"] = H.sec_record @@ -218,6 +230,10 @@ L.fields["fingerprint"] = md5(H.dna.uni_identity) L.fields["sex"] = gender2text(H.gender) L.fields["id_gender"] = gender2text(H.identifying_gender) + if(H.get_FBP_type()) + L.fields["brain_type"] = H.get_FBP_type() + else + L.fields["brain_type"] = "Organic" L.fields["b_type"] = H.b_type L.fields["b_dna"] = H.dna.unique_enzymes L.fields["enzymes"] = H.dna.SE // Used in respawning @@ -426,6 +442,7 @@ G.fields["real_rank"] = "Unassigned" G.fields["sex"] = "Unknown" G.fields["age"] = "Unknown" + G.fields["brain_type"] = "Unknown" G.fields["fingerprint"] = "Unknown" G.fields["p_stat"] = "Active" G.fields["m_stat"] = "Stable" @@ -447,6 +464,7 @@ R.name = "Security Record #[id]" R.fields["name"] = name R.fields["id"] = id + R.fields["brain_type"] = "Unknown" R.fields["criminal"] = "None" R.fields["mi_crim"] = "None" R.fields["mi_crim_d"] = "No minor crime convictions." @@ -467,6 +485,7 @@ M.fields["b_type"] = "AB+" M.fields["b_dna"] = md5(name) M.fields["id_gender"] = "Unknown" + M.fields["brain_type"] = "Unknown" M.fields["mi_dis"] = "None" M.fields["mi_dis_d"] = "No minor disabilities have been declared." M.fields["ma_dis"] = "None" diff --git a/code/datums/uplink/visible_weapons.dm b/code/datums/uplink/visible_weapons.dm index 41a1779322..34b20a9f48 100644 --- a/code/datums/uplink/visible_weapons.dm +++ b/code/datums/uplink/visible_weapons.dm @@ -100,6 +100,11 @@ item_cost = 40 path = /obj/item/weapon/gun/energy/ionrifle +/datum/uplink_item/item/visible_weapons/ionpistol + name = "Ion Pistol" + item_cost = 25 + path = /obj/item/weapon/gun/energy/ionrifle/pistol + /datum/uplink_item/item/visible_weapons/xray name = "Xray Gun" item_cost = 85 diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 87971dd033..3bba74296e 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -216,7 +216,6 @@ /obj/machinery/computer/scan_consolenew name = "DNA Modifier Access Console" desc = "Scan DNA." - icon = 'icons/obj/computer.dmi' icon_keyboard = "med_key" icon_screen = "dna" density = 1 diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index a60faeb830..2234e0a540 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -13,6 +13,8 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E var/isabsorbing = 0 var/geneticpoints = 5 var/max_geneticpoints = 5 + var/readapts = 1 + var/max_readapts = 2 var/list/purchased_powers = list() var/mimicing = "" var/cloaked = 0 @@ -60,6 +62,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E if(!mind.changeling) mind.changeling = new /datum/changeling(gender) verbs += /datum/changeling/proc/EvolutionMenu + verbs += /mob/proc/changeling_respec add_language("Changeling") var/lesser_form = !ishuman(src) diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 10cb5f9fbb..396e6faf34 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -72,7 +72,12 @@ if(src.nutrition < 400) src.nutrition = min((src.nutrition + T.nutrition), 400) changeling.chem_charges += 10 - src.verbs += /mob/proc/changeling_respec + if(changeling.readapts <= 0) + changeling.readapts = 0 //SANITYYYYYY + changeling.readapts++ + if(changeling.readapts > changeling.max_readapts) + changeling.readapts = changeling.max_readapts + 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) diff --git a/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm b/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm index 3068f1eee5..c173ba55ac 100644 --- a/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm +++ b/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm @@ -24,7 +24,7 @@ if(held_item == null) if(src.mind.changeling.recursive_enhancement) - if(changeling_generic_weapon(/obj/item/weapon/electric_hand/efficent)) + if(changeling_generic_weapon(/obj/item/weapon/electric_hand/efficent,0)) src << "We will shock others more efficently." return 1 else diff --git a/code/game/gamemodes/changeling/powers/blind_sting.dm b/code/game/gamemodes/changeling/powers/blind_sting.dm index e098c98f03..41b14478b3 100644 --- a/code/game/gamemodes/changeling/powers/blind_sting.dm +++ b/code/game/gamemodes/changeling/powers/blind_sting.dm @@ -26,7 +26,7 @@ src << "They will be deprived of sight for longer." spawn(duration) T.disabilities &= ~NEARSIGHTED - T.eye_blind = 10 + T.Blind(10) T.eye_blurry = 20 feedback_add_details("changeling_powers","BS") return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm b/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm index fd72524e5a..a9b323465c 100644 --- a/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm +++ b/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm @@ -2,12 +2,24 @@ name = "Delayed Toxic Sting" desc = "We silently sting a biological, causing a significant amount of toxins after a few minutes, allowing us to not \ implicate ourselves." - helptext = "The toxin takes effect in about two minutes. The sting has a three minute cooldown between uses." + helptext = "The toxin takes effect in about two minutes. Multiple applications within the two minutes will not cause increased toxicity." enhancedtext = "The toxic damage is doubled." ability_icon_state = "ling_sting_del_toxin" genomecost = 1 verbpath = /mob/proc/changeling_delayed_toxic_sting +/datum/modifier/delayed_toxin_sting + name = "delayed toxin injection" + hidden = TRUE + stacks = MODIFIER_STACK_FORBID + on_expired_text = "You feel a burning sensation flowing through your veins!" + +/datum/modifier/delayed_toxin_sting/on_expire() + holder.adjustToxLoss(rand(20, 30)) + +/datum/modifier/delayed_toxin_sting/strong/on_expire() + holder.adjustToxLoss(rand(40, 60)) + /mob/proc/changeling_delayed_toxic_sting() set category = "Changeling" set name = "Delayed Toxic Sting (20)" @@ -19,21 +31,13 @@ T.attack_log += text("\[[time_stamp()]\] Was delayed toxic stung by [key_name(src)]") src.attack_log += text("\[[time_stamp()]\] Used delayed toxic sting on [key_name(T)]") msg_admin_attack("[key_name(T)] was delayed toxic stung by [key_name(src)]") - var/i = rand(20,30) + + var/type_to_give = /datum/modifier/delayed_toxin_sting if(src.mind.changeling.recursive_enhancement) - i = i * 2 + type_to_give = /datum/modifier/delayed_toxin_sting/strong src << "Our toxin will be extra potent, when it strikes." - spawn(2 MINUTES) - if(T) //We might not exist in two minutes, for whatever reason. - T << "You feel a burning sensation flowing through your veins!" - while(i) - T.adjustToxLoss(1) - i-- - sleep(2 SECONDS) - src.verbs -= /mob/proc/changeling_delayed_toxic_sting - spawn(3 MINUTES) - src << "We are ready to use our delayed toxic string once more." - src.verbs |= /mob/proc/changeling_delayed_toxic_sting + + T.add_modifier(type_to_give, 2 MINUTES) feedback_add_details("changeling_powers","DTS") diff --git a/code/game/gamemodes/changeling/powers/endoarmor.dm b/code/game/gamemodes/changeling/powers/endoarmor.dm index 4052568a50..536aef26ce 100644 --- a/code/game/gamemodes/changeling/powers/endoarmor.dm +++ b/code/game/gamemodes/changeling/powers/endoarmor.dm @@ -6,9 +6,18 @@ isVerb = 0 verbpath = /mob/proc/changeling_endoarmor +/datum/modifier/endoarmor + name = "endoarmor" + desc = "We have hard plating underneath our skin, making us more durable." + + on_created_text = "We feel protective plating form underneath our skin." + on_expired_text = "Our protective armor underneath our skin fades as we absorb it." + max_health_flat = 50 + //Increases macimum chemical storage /mob/proc/changeling_endoarmor() if(ishuman(src)) var/mob/living/carbon/human/H = src - H.maxHealth += 50 + H.add_modifier(/datum/modifier/endoarmor) + // H.maxHealth += 50 return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/enfeebling_string.dm b/code/game/gamemodes/changeling/powers/enfeebling_string.dm index 5370a68200..b7a6c56957 100644 --- a/code/game/gamemodes/changeling/powers/enfeebling_string.dm +++ b/code/game/gamemodes/changeling/powers/enfeebling_string.dm @@ -1,13 +1,29 @@ /datum/power/changeling/enfeebling_string name = "Enfeebling String" desc = "We sting a biological with a potent toxin that will greatly weaken them for a short period of time." - helptext = "Lowers the maximum health of the victim for a few minutes. This sting will also warn them of this. Has a \ - five minute coodown between uses." - enhancedtext = "Maximum health is lowered further." + helptext = "Lowers the maximum health of the victim for a few minutes, as well as making them more frail and weak. This sting will also warn them of this." + enhancedtext = "Maximum health and outgoing melee damage is lowered further. Incoming damage is increased." ability_icon_state = "ling_sting_enfeeble" genomecost = 1 verbpath = /mob/proc/changeling_enfeebling_string +/datum/modifier/enfeeble + name = "enfeebled" + desc = "You feel really weak and frail for some reason." + + stacks = MODIFIER_STACK_EXTEND + max_health_percent = 0.7 + outgoing_melee_damage_percent = 0.75 + incoming_damage_percent = 1.1 + on_created_text = "You feel a small prick and you feel extremly weak!" + on_expired_text = "You no longer feel extremly weak." + +// Now YOU'RE the Teshari! +/datum/modifier/enfeeble/strong + max_health_percent = 0.5 + outgoing_melee_damage_percent = 0.5 + incoming_damage_percent = 1.35 + /mob/proc/changeling_enfeebling_string() set category = "Changeling" set name = "Enfeebling Sting (30)" @@ -23,22 +39,10 @@ src.attack_log += text("\[[time_stamp()]\] Used enfeebling sting on [key_name(T)]") msg_admin_attack("[key_name(T)] was enfeebling stung by [key_name(src)]") - - var/effect = 30 //percent + var/type_to_give = /datum/modifier/enfeeble if(src.mind.changeling.recursive_enhancement) - effect = effect + 20 + type_to_give = /datum/modifier/enfeeble/strong src << "We make them extremely weak." - var/health_to_take_away = H.maxHealth * (effect / 100) - - H.maxHealth -= health_to_take_away - H << "You feel a small prick and you feel extremly weak!" - src.verbs -= /mob/proc/changeling_enfeebling_string - spawn(5 MINUTES) - src.verbs |= /mob/proc/changeling_enfeebling_string - src << "Our enfeebling string is ready to be used once more." - if(H) //Just incase we stop existing in five minutes for whatever reason. - H.maxHealth += health_to_take_away - if(!H.stat) //It'd be weird to no longer feel weak when you're dead. - H << "You no longer feel extremly weak." + H.add_modifier(type_to_give, 2 MINUTES) feedback_add_details("changeling_powers","ES") return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/epinephrine_overdose.dm b/code/game/gamemodes/changeling/powers/epinephrine_overdose.dm index 3875a4b4fa..38d200cad5 100644 --- a/code/game/gamemodes/changeling/powers/epinephrine_overdose.dm +++ b/code/game/gamemodes/changeling/powers/epinephrine_overdose.dm @@ -2,11 +2,20 @@ name = "Epinephrine Overdose" desc = "We evolve additional sacs of adrenaline throughout our body." helptext = "We can instantly recover from stuns and reduce the effect of future stuns, but we will suffer toxicity in the long term. Can be used while unconscious." - enhancedtext = "Constant recovery from stuns for thirty seconds." + enhancedtext = "Immunity from most disabling effects for 30 seconds." ability_icon_state = "ling_epinepherine_overdose" genomecost = 2 verbpath = /mob/proc/changeling_epinephrine_overdose +/datum/modifier/unstoppable + name = "unstoppable" + desc = "We feel limitless amounts of energy surge in our veins. Nothing can stop us!" + + stacks = MODIFIER_STACK_EXTEND + on_created_text = "We feel unstoppable!" + on_expired_text = "We feel our newfound energy fade..." + disable_duration_percent = 0 + //Recover from stuns. /mob/proc/changeling_epinephrine_overdose() set category = "Changeling" @@ -30,18 +39,7 @@ C.reagents.add_reagent("epinephrine", 20) if(src.mind.changeling.recursive_enhancement) - src << "We feel unstoppable." - spawn(1) - var/i = 30 - while(i) - C.SetParalysis(0) - C.SetStunned(0) - C.SetWeakened(0) - C.lying = 0 - C.update_canmove() - i-- - sleep(10) - src << "We feel our newfound energy fade." + C.add_modifier(/datum/modifier/unstoppable, 30 SECONDS) feedback_add_details("changeling_powers","UNS") return 1 diff --git a/code/game/gamemodes/changeling/powers/rapid_regen.dm b/code/game/gamemodes/changeling/powers/rapid_regen.dm index eddf83292e..2eb628b8f6 100644 --- a/code/game/gamemodes/changeling/powers/rapid_regen.dm +++ b/code/game/gamemodes/changeling/powers/rapid_regen.dm @@ -35,7 +35,7 @@ C.species.create_organs(C) C.restore_all_organs() C.blinded = 0 - C.eye_blind = 0 + C.SetBlinded(0) C.eye_blurry = 0 C.ear_deaf = 0 C.ear_damage = 0 diff --git a/code/game/gamemodes/changeling/powers/respec.dm b/code/game/gamemodes/changeling/powers/respec.dm index 7910ceaf7c..d984083aba 100644 --- a/code/game/gamemodes/changeling/powers/respec.dm +++ b/code/game/gamemodes/changeling/powers/respec.dm @@ -6,9 +6,14 @@ var/datum/changeling/changeling = changeling_power(0,0,100) if(!changeling) return + if(src.mind.changeling.readapts <= 0) + to_chat(src, "We must first absorb another compatable creature!") + src.mind.changeling.readapts = 0 + return src.remove_changeling_powers() //First, remove the verbs. var/datum/changeling/ling_datum = src.mind.changeling + ling_datum.readapts-- ling_datum.purchased_powers = list() //Then wipe all the powers we bought. ling_datum.geneticpoints = ling_datum.max_geneticpoints //Now refund our points to the maximum. ling_datum.chem_recharge_rate = 0.5 //If glands were bought, revert that upgrade. @@ -17,8 +22,8 @@ ling_datum.chem_storage = 50 if(ishuman(src)) var/mob/living/carbon/human/H = src - H.does_not_breathe = 0 //If self respiration was bought, revert that too. - H.maxHealth = initial(H.maxHealth) //Revert endoarmor too. + // H.does_not_breathe = 0 //If self respiration was bought, revert that too. + H.remove_modifiers_of_type(/datum/modifier/endoarmor) //Revert endoarmor too. src.make_changeling() //And give back our freebies. src << "We have removed our evolutions from this form, and are now ready to readapt." @@ -26,4 +31,4 @@ ling_datum.purchased_powers_history.Add("Re-adapt (Reset to [ling_datum.max_geneticpoints])") //Now to lose the verb, so no unlimited resets. - src.verbs -= /mob/proc/changeling_respec \ No newline at end of file + diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm index 2b8af49eb6..ded66148fa 100644 --- a/code/game/gamemodes/changeling/powers/shriek.dm +++ b/code/game/gamemodes/changeling/powers/shriek.dm @@ -55,7 +55,7 @@ M << "You hear an extremely loud screeching sound! It \ [pick("confuses","confounds","perturbs","befuddles","dazes","unsettles","disorients")] you." M.adjustEarDamage(0,30) - M.confused += 20 + M.Confuse(20) M << sound('sound/effects/screech.ogg') M.attack_log += text("\[[time_stamp()]\] Was affected by [key_name(src)]'s Resonant Shriek.") else diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 5868bf4b59..cecb7b87c7 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -49,7 +49,7 @@ desc = "A hood worn by the followers of Nar-Sie." flags_inv = HIDEFACE body_parts_covered = HEAD - armor = list(melee = 50, bullet = 30, laser = 50, energy = 20, bomb = 25, bio = 10, rad = 0) + armor = list(melee = 50, bullet = 30, laser = 50, energy = 80, bomb = 25, bio = 10, rad = 0) cold_protection = HEAD min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE siemens_coefficient = 0 @@ -73,7 +73,7 @@ icon_state = "cultrobes" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS allowed = list(/obj/item/weapon/book/tome,/obj/item/weapon/melee/cultblade) - armor = list(melee = 50, bullet = 30, laser = 50, energy = 20, bomb = 25, bio = 10, rad = 0) + armor = list(melee = 50, bullet = 30, laser = 50, energy = 80, bomb = 25, bio = 10, rad = 0) flags_inv = HIDEJUMPSUIT siemens_coefficient = 0 @@ -95,7 +95,7 @@ name = "cult helmet" desc = "A space worthy helmet used by the followers of Nar-Sie." icon_state = "cult_helmet" - armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30) + armor = list(melee = 60, bullet = 50, laser = 30, energy = 80, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0 /obj/item/clothing/head/helmet/space/cult/cultify() @@ -108,7 +108,7 @@ w_class = ITEMSIZE_NORMAL allowed = list(/obj/item/weapon/book/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/emergency/oxygen,/obj/item/device/suit_cooling_unit) slowdown = 1 - armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30) + armor = list(melee = 60, bullet = 50, laser = 30, energy = 80, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0 flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 61f177eae5..027b61333e 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -958,7 +958,7 @@ var/list/sacrificed = list() if(N) continue C.eye_blurry += 50 - C.eye_blind += 20 + C.Blind(20) if(prob(5)) C.disabilities |= NEARSIGHTED if(prob(10)) @@ -981,7 +981,7 @@ var/list/sacrificed = list() if(N) continue C.eye_blurry += 30 - C.eye_blind += 10 + C.Blind(10) //talismans is weaker. affected += C C.show_message("You feel a sharp pain in your eyes, and the world disappears into darkness..", 3) diff --git a/code/game/gamemodes/technomancer/spells/aura/unstable_aura.dm b/code/game/gamemodes/technomancer/spells/aura/unstable_aura.dm index 431e72a32f..3c65a9503f 100644 --- a/code/game/gamemodes/technomancer/spells/aura/unstable_aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/unstable_aura.dm @@ -25,7 +25,7 @@ if(is_ally(L)) continue - var/damage_to_inflict = max(L.health / L.maxHealth, 0) // Otherwise, those in crit would actually be healed. + var/damage_to_inflict = max(L.health / L.getMaxHealth(), 0) // Otherwise, those in crit would actually be healed. var/armor_factor = abs(L.getarmor(null, "energy") - 100) armor_factor = armor_factor / 100 diff --git a/code/game/gamemodes/technomancer/spells/insert/asphyxiation.dm b/code/game/gamemodes/technomancer/spells/insert/asphyxiation.dm index 555ff9f559..84b0b22931 100644 --- a/code/game/gamemodes/technomancer/spells/insert/asphyxiation.dm +++ b/code/game/gamemodes/technomancer/spells/insert/asphyxiation.dm @@ -32,7 +32,7 @@ warned_victim = predict_crit(pulses, H, 0) sleep(4 SECONDS) H.adjustOxyLoss(5) - var/health_lost = H.maxHealth - H.getOxyLoss() + H.getToxLoss() + H.getFireLoss() + H.getBruteLoss() + H.getCloneLoss() + var/health_lost = H.getMaxHealth() - H.getOxyLoss() + H.getToxLoss() + H.getFireLoss() + H.getBruteLoss() + H.getCloneLoss() H.adjustOxyLoss(round(abs(health_lost * 0.25))) //world << "Inflicted [round(abs(health_lost * 0.25))] damage!" pulses-- @@ -62,7 +62,7 @@ pulses_remaining-- return .(pulses_remaining, victim, previous_damage) // Now check if our damage predictions are going to cause the victim to go into crit if no healing occurs. - if(previous_damage + health_lost >= victim.maxHealth) // We're probably going to hardcrit + if(previous_damage + health_lost >= victim.getMaxHealth()) // We're probably going to hardcrit victim << "A feeling of immense dread starts to overcome you as everything starts \ to fade to black..." //world << "Predicted hardcrit." diff --git a/code/game/gamemodes/technomancer/spells/resurrect.dm b/code/game/gamemodes/technomancer/spells/resurrect.dm index c56df4f26e..90a352c95f 100644 --- a/code/game/gamemodes/technomancer/spells/resurrect.dm +++ b/code/game/gamemodes/technomancer/spells/resurrect.dm @@ -32,7 +32,7 @@ user << "You stab \the [L] with a hidden integrated hypo, attempting to bring them back..." if(istype(L, /mob/living/simple_animal)) var/mob/living/simple_animal/SM = L - SM.health = SM.maxHealth / 3 + SM.health = SM.getMaxHealth() / 3 SM.stat = CONSCIOUS dead_mob_list -= SM living_mob_list += SM diff --git a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm index d7f5669775..9a004d3ea3 100644 --- a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm +++ b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm @@ -62,4 +62,4 @@ // Now we hurt their new pal, because being forcefully abducted by teleportation can't be healthy. - summoned.health = round(summoned.maxHealth * 0.7) \ No newline at end of file + summoned.health = round(summoned.getMaxHealth() * 0.7) \ No newline at end of file diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index 1e4398546c..e7bb56347e 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -27,11 +27,13 @@ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/bartender(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/device/pda/bar(H), slot_belt) if(has_alt_title(H, alt_title,"Bartender")) + var/obj/item/weapon/permit/gun/bar/permit = new(H) if(H.backbag == 1) - H.equip_to_slot_or_del(new /obj/item/weapon/permit/gun/bar(H), slot_l_hand) + H.equip_to_slot_or_del(permit, slot_l_hand) else - H.equip_to_slot_or_del(new /obj/item/weapon/permit/gun/bar(H.back), slot_in_backpack) - return 1 + H.equip_to_slot_or_del(permit, slot_in_backpack) + permit.set_name(H.real_name) + return 1 diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 6495a56828..d45c0d4c3b 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -388,6 +388,7 @@ var/global/datum/controller/occupations/job_master job.equip_backpack(H) job.equip_survival(H) job.apply_fingerprints(H) + H.equip_post_job() //If some custom items could not be equipped before, try again now. for(var/thing in custom_equip_leftovers) diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index 83c6f81e30..546e6acd88 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -72,7 +72,6 @@ obj/machinery/air_sensor/Destroy() ..() /obj/machinery/computer/general_air_control - icon = 'icons/obj/computer.dmi' icon_keyboard = "atmos_key" icon_screen = "tank" name = "Computer" diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index de81fbb0fa..cf657e1c10 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -1,6 +1,5 @@ /obj/machinery/computer/aifixer name = "\improper AI system integrity restorer" - icon = 'icons/obj/computer.dmi' icon_keyboard = "rd_key" icon_screen = "ai-fixer" light_color = "#a97faa" @@ -102,7 +101,7 @@ return 1 if (href_list["fix"]) src.active = 1 - src.overlays += image('icons/obj/computer.dmi', "ai-fixer-on") + src.overlays += image(icon, "ai-fixer-on") while (src.occupant.health < 100) src.occupant.adjustOxyLoss(-1) src.occupant.adjustFireLoss(-1) @@ -114,13 +113,13 @@ src.occupant.lying = 0 dead_mob_list -= src.occupant living_mob_list += src.occupant - src.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404") - src.overlays += image('icons/obj/computer.dmi', "ai-fixer-full") + src.overlays -= image(icon, "ai-fixer-404") + src.overlays += image(icon, "ai-fixer-full") src.occupant.add_ai_verbs() src.updateUsrDialog() sleep(10) src.active = 0 - src.overlays -= image('icons/obj/computer.dmi', "ai-fixer-on") + src.overlays -= image(icon, "ai-fixer-on") src.add_fingerprint(usr) @@ -135,8 +134,8 @@ if(occupant) if(occupant.stat) - overlays += image('icons/obj/computer.dmi', "ai-fixer-404", overlay_layer) + overlays += image(icon, "ai-fixer-404", overlay_layer) else - overlays += image('icons/obj/computer.dmi', "ai-fixer-full", overlay_layer) + overlays += image(icon, "ai-fixer-full", overlay_layer) else - overlays += image('icons/obj/computer.dmi', "ai-fixer-empty", overlay_layer) + overlays += image(icon, "ai-fixer-empty", overlay_layer) diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index 9f1b7afb38..3826eb3c94 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -4,7 +4,6 @@ /obj/machinery/computer/atmoscontrol name = "\improper Central Atmospherics Computer" - icon = 'icons/obj/computer.dmi' icon_keyboard = "generic_key" icon_screen = "comm_logs" light_color = "#00b000" diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 75ba732950..db932f8cd0 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -1,6 +1,5 @@ /obj/machinery/computer/cloning name = "cloning control console" - icon = 'icons/obj/computer.dmi' icon_keyboard = "med_key" icon_screen = "dna" light_color = "#315ab4" diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 6eae870cfd..b51fa788ab 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -85,6 +85,7 @@ if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) dat += "
Name: [active1.fields["name"]] \ ID: [active1.fields["id"]]
\n \ + Entity Classification: [active1.fields["brain_type"]]
\n \ Sex: [active1.fields["sex"]]
\n" if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) dat += "Gender identity: [active2.fields["id_gender"]]
" diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index e8fe96ae6c..3d0235fab9 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -2,7 +2,6 @@ /obj/machinery/computer/prisoner name = "prisoner management console" - icon = 'icons/obj/computer.dmi' icon_keyboard = "security_key" icon_screen = "explosive" light_color = "#a91515" diff --git a/code/game/machinery/computer/prisonshuttle.dm b/code/game/machinery/computer/prisonshuttle.dm index 1c54fb0f4c..8c435f5845 100644 --- a/code/game/machinery/computer/prisonshuttle.dm +++ b/code/game/machinery/computer/prisonshuttle.dm @@ -12,7 +12,6 @@ var/prison_shuttle_timeleft = 0 /obj/machinery/computer/prison_shuttle name = "prison shuttle control console" - icon = 'icons/obj/computer.dmi' icon_keyboard = "security_key" icon_screen = "syndishuttle" light_color = "#00ffff" diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index ca56ce168d..4d29a56b89 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -1,7 +1,6 @@ /obj/machinery/computer/robotics name = "robotics control console" desc = "Used to remotely lockdown or detonate linked cyborgs." - icon = 'icons/obj/computer.dmi' icon_keyboard = "tech_key" icon_screen = "robot" light_color = "#a97faa" diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 54c94d8684..465884b2ca 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -127,6 +127,7 @@ dat += text("
\ Name: [active1.fields["name"]]
\ ID: [active1.fields["id"]]
\n \ + Entity Classification: [active1.fields["brain_type"]]
\n \ Sex: [active1.fields["sex"]]
\n \ Age: [active1.fields["age"]]
\n \ Rank: [active1.fields["rank"]]
\n \ @@ -612,5 +613,4 @@ What a mess.*/ ..(severity) /obj/machinery/computer/secure_data/detective_computer - icon = 'icons/obj/computer.dmi' icon_state = "messyfiles" diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index 1a67778fdf..bd9c66dbae 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -93,6 +93,7 @@ dat += text("
\ Name: [active1.fields["name"]]
\ ID: [active1.fields["id"]]
\n \ + Entity Classification: [active1.fields["brain_type"]]
\n \ Sex: [active1.fields["sex"]]
\n \ Age: [active1.fields["age"]]
\n \ Rank: [active1.fields["rank"]]
\n \ diff --git a/code/game/machinery/computer/specops_shuttle.dm b/code/game/machinery/computer/specops_shuttle.dm index cb0f8a5552..0a337f4df8 100644 --- a/code/game/machinery/computer/specops_shuttle.dm +++ b/code/game/machinery/computer/specops_shuttle.dm @@ -13,7 +13,6 @@ var/specops_shuttle_timeleft = 0 /obj/machinery/computer/specops_shuttle name = "special operations shuttle control console" - icon = 'icons/obj/computer.dmi' icon_keyboard = "security_key" icon_screen = "syndishuttle" light_color = "#00ffff" diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm index d390a7f163..4bcc43bbec 100644 --- a/code/game/machinery/computer/supply.dm +++ b/code/game/machinery/computer/supply.dm @@ -1,6 +1,5 @@ /obj/machinery/computer/supplycomp name = "supply control console" - icon = 'icons/obj/computer.dmi' icon_keyboard = "tech_key" icon_screen = "supply" light_color = "#b88b2e" @@ -13,7 +12,6 @@ /obj/machinery/computer/ordercomp name = "supply ordering console" - icon = 'icons/obj/computer.dmi' icon_screen = "request" circuit = /obj/item/weapon/circuitboard/ordercomp var/temp = null diff --git a/code/game/machinery/computer/syndicate_specops_shuttle.dm b/code/game/machinery/computer/syndicate_specops_shuttle.dm index d36f03b525..ba7193b69b 100644 --- a/code/game/machinery/computer/syndicate_specops_shuttle.dm +++ b/code/game/machinery/computer/syndicate_specops_shuttle.dm @@ -12,7 +12,6 @@ var/syndicate_elite_shuttle_timeleft = 0 /obj/machinery/computer/syndicate_elite_shuttle name = "elite syndicate squad shuttle control console" - icon = 'icons/obj/computer.dmi' icon_keyboard = "syndie_key" icon_screen = "syndishuttle" light_color = "#00ffff" diff --git a/code/game/machinery/computer3/computers/medical.dm b/code/game/machinery/computer3/computers/medical.dm index 57a662db46..bb4228397d 100644 --- a/code/game/machinery/computer3/computers/medical.dm +++ b/code/game/machinery/computer3/computers/medical.dm @@ -95,6 +95,7 @@ dat += "
Name: [active1.fields["name"]] \ ID: [active1.fields["id"]]
\n \ + Entity Classification: [active1.fields["brain_type"]]
\n \ Sex: [active1.fields["sex"]]
\n \ Age: [active1.fields["age"]]
\n \ Fingerprint: [active1.fields["fingerprint"]]
\n \ diff --git a/code/game/machinery/computer3/computers/security.dm b/code/game/machinery/computer3/computers/security.dm index a314bed273..6b77a274bf 100644 --- a/code/game/machinery/computer3/computers/security.dm +++ b/code/game/machinery/computer3/computers/security.dm @@ -134,6 +134,7 @@ dat += text("
\ Name: [active1.fields["name"]]
\ ID: [active1.fields["id"]]
\n \ + Entity Classification: [active1.fields["brain_type"]]
\n \ Sex: [active1.fields["sex"]]
\n \ Age: [active1.fields["age"]]
\n \ Rank: [active1.fields["rank"]]
\n \ diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index d1ab11e706..5d0f707ae8 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -96,7 +96,7 @@ occupantData["name"] = occupant.name occupantData["stat"] = occupant.stat occupantData["health"] = occupant.health - occupantData["maxHealth"] = occupant.maxHealth + occupantData["maxHealth"] = occupant.getMaxHealth() occupantData["minHealth"] = config.health_threshold_dead occupantData["bruteLoss"] = occupant.getBruteLoss() occupantData["oxyLoss"] = occupant.getOxyLoss() diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm index 209e3bb228..3d899377cc 100644 --- a/code/game/machinery/doors/blast_door.dm +++ b/code/game/machinery/doors/blast_door.dm @@ -12,6 +12,7 @@ desc = "That looks like it doesn't open easily." icon = 'icons/obj/doors/rapid_pdoor.dmi' icon_state = null + min_force = 20 //minimum amount of force needed to damage the door with a melee weapon // Icon states for different shutter types. Simply change this instead of rewriting the update_icon proc. var/icon_state_open = null @@ -78,7 +79,10 @@ // Proc: force_toggle() // Parameters: None // Description: Opens or closes the door, depending on current state. No checks are done inside this proc. -/obj/machinery/door/blast/proc/force_toggle() +/obj/machinery/door/blast/proc/force_toggle(var/forced = 0, mob/user as mob) + if (forced) + playsound(src.loc, 'sound/machines/airlock_creaking.ogg', 100, 1) + if(src.density) src.force_open() else @@ -91,7 +95,7 @@ /obj/machinery/door/blast/attackby(obj/item/weapon/C as obj, mob/user as mob) src.add_fingerprint(user) if(istype(C, /obj/item/weapon)) // For reasons unknown, sometimes C is actually not what it is advertised as, like a mob. - if(C.pry == 1) // Can we pry it open with something, like a crowbar/fireaxe/lingblade? + if(C.pry == 1 && (user.a_intent != I_HURT || (stat & BROKEN))) // Can we pry it open with something, like a crowbar/fireaxe/lingblade? if(istype(C,/obj/item/weapon/material/twohanded/fireaxe)) // Fireaxes need to be in both hands to pry. var/obj/item/weapon/material/twohanded/fireaxe/F = C if(!F.wielded) @@ -100,7 +104,8 @@ // If we're at this point, it's a fireaxe in both hands or something else that doesn't care for twohanding. if(((stat & NOPOWER) || (stat & BROKEN)) && !( src.operating )) - force_toggle() + force_toggle(1, user) + else usr << "[src]'s motors resist your effort." return @@ -123,15 +128,33 @@ usr << "You don't have enough sheets to repair this! You need at least [amt] sheets." + else if(src.density) + var/obj/item/weapon/W = C + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + if(W.damtype == BRUTE || W.damtype == BURN) + user.do_attack_animation(src) + if(W.force < min_force) + user.visible_message("\The [user] hits \the [src] with \the [W] with no visible effect.") + else + user.visible_message("\The [user] forcefully strikes \the [src] with \the [W]!") + playsound(src.loc, hitsound, 100, 1) + take_damage(W.force*0.35) //it's a blast door, it should take a while. -Luke + return + // Proc: open() // Parameters: None // Description: Opens the door. Does necessary checks. Automatically closes if autoclose is true -/obj/machinery/door/blast/open() - if (src.operating || (stat & BROKEN || stat & NOPOWER)) - return - force_open() - if(autoclose) +/obj/machinery/door/blast/open(var/forced = 0) + if(forced) + force_open() + return 1 + else + if (src.operating || (stat & BROKEN || stat & NOPOWER)) + return 1 + force_open() + + if(autoclose && src.operating && !(stat & BROKEN || stat & NOPOWER)) spawn(150) close() return 1 diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index dd8e868d8a..0f4d541b6d 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -314,6 +314,8 @@ /obj/machinery/door/examine(mob/user) . = ..() + if(src.health <= 0) + user << "\The [src] is broken!" if(src.health < src.maxhealth / 4) user << "\The [src] looks like it's about to break!" else if(src.health < src.maxhealth / 2) diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index ae48142b4d..a18edbc5fa 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -78,7 +78,7 @@ C.traits = new() C.nameVar = "grey" I.add_product(C) - + /obj/machinery/smartfridge/secure/medbay name = "\improper Refrigerated Medicine Storage" @@ -139,6 +139,7 @@ icon_state = "drying_rack" icon_on = "drying_rack_on" icon_off = "drying_rack" + icon_panel = "drying_rack-panel" /obj/machinery/smartfridge/drying_rack/accept_check(var/obj/item/O as obj) if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/)) @@ -260,7 +261,7 @@ locked = -1 user << "You short out the product lock on [src]." return 1 - + /obj/machinery/smartfridge/proc/stock(obj/item/O) var/hasRecord = FALSE //Check to see if this passes or not. for(var/datum/stored_item/I in item_records) @@ -273,7 +274,7 @@ item.add_product(O) item_records.Add(item) nanomanager.update_uis(src) - + /obj/machinery/smartfridge/proc/vend(datum/stored_item/I) I.get_product(get_turf(src)) nanomanager.update_uis(src) @@ -357,7 +358,7 @@ if (!throw_item) continue break - + if(!throw_item) return 0 spawn(0) diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index a6da9bfa00..00a0654cc1 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -1,6 +1,5 @@ /obj/machinery/computer/mecha name = "Exosuit Control" - icon = 'icons/obj/computer.dmi' icon_keyboard = "rd_key" icon_screen = "mecha" light_color = "#a97faa" diff --git a/code/game/mecha/medical/odysseus.dm b/code/game/mecha/medical/odysseus.dm index 967c03252f..6aec830c89 100644 --- a/code/game/mecha/medical/odysseus.dm +++ b/code/game/mecha/medical/odysseus.dm @@ -95,7 +95,7 @@ holder.icon_state = "hudhealth-100" C.images += holder else - holder.icon_state = RoundHealth((patient.health-config.health_threshold_crit)/(patient.maxHealth-config.health_threshold_crit)*100) + holder.icon_state = RoundHealth((patient.health-config.health_threshold_crit)/(patient.getMaxHealth()-config.health_threshold_crit)*100) C.images += holder holder = patient.hud_list[STATUS_HUD] diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 7950200137..f456a95d73 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -74,7 +74,12 @@ add_fingerprint(user) unbuckle_mob() - if(buckle_mob(M)) + //can't buckle unless you share locs so try to move M to the obj. + if(M.loc != src.loc) + step_towards(M, src) + + . = buckle_mob(M) + if(.) if(M == user) M.visible_message(\ "[M.name] buckles themselves to [src].",\ diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 1450fa94ce..b4ba67e4c2 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -86,6 +86,12 @@ qdel(src) return +/obj/structure/closet/body_bag/relaymove(mob/user,direction) + if(src.loc != get_turf(src)) + src.loc.relaymove(user,direction) + else + ..() + /obj/structure/closet/body_bag/proc/get_occupants() var/list/occupants = list() for(var/mob/living/carbon/human/H in contents) diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index d1a5b63e82..632f9afdfd 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -92,8 +92,8 @@ flash_strength *= H.species.flash_mod if(flash_strength > 0) - H.confused = max(H.confused, flash_strength + 5) - H.eye_blind = max(H.eye_blind, flash_strength) + H.Confuse(flash_strength + 5) + H.Blind(flash_strength) H.eye_blurry = max(H.eye_blurry, flash_strength + 5) H.flash_eyes() H.adjustHalLoss(halloss_per_flash * (flash_strength / 5)) // Should take four flashes to stun. diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 1bd7f9349a..74d9a4b8ed 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -65,10 +65,12 @@ var/global/list/default_medbay_channels = list( ..() wires = new(src) internal_channels = default_internal_channels.Copy() + listening_objects += src /obj/item/device/radio/Destroy() qdel(wires) wires = null + listening_objects -= src if(radio_controller) radio_controller.remove_object(src, frequency) for (var/ch_name in channels) @@ -474,7 +476,6 @@ var/global/list/default_medbay_channels = list( /obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null) - if (broadcasting) if(get_dist(src, M) <= canhear_range) talk_into(M, msg,null,verb,speaking) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 243d301289..5d883784aa 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -69,7 +69,7 @@ REAGENT SCANNER user.show_message("Analyzing Results for [M]:") user.show_message("Overall Status: dead") else - user.show_message("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[round((M.health/M.maxHealth)*100) ]% healthy"]") + user.show_message("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[round((M.health/M.getMaxHealth())*100) ]% healthy"]") user.show_message(" Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message(" Damage Specifics: [OX] - [TX] - [BU] - [BR]") user.show_message("Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm index 10a847b469..d404b5cd44 100644 --- a/code/game/objects/items/weapons/RSF.dm +++ b/code/game/objects/items/weapons/RSF.dm @@ -39,7 +39,7 @@ RSF playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) if (mode == 1) mode = 2 - user << "Changed dispensing mode to 'Drinking Glass'" + user << "Changed dispensing mode to 'Drinking Glass:Pint'" return if (mode == 2) mode = 3 @@ -82,7 +82,7 @@ RSF product = new /obj/item/clothing/mask/smokable/cigarette() used_energy = 10 if(2) - product = new /obj/item/weapon/reagent_containers/food/drinks/glass2() + product = new /obj/item/weapon/reagent_containers/food/drinks/glass2/pint() used_energy = 50 if(3) product = new /obj/item/weapon/paper() diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 76c4f9e768..ee2d2f2c57 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -399,21 +399,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM ..() name = "empty [initial(name)]" -/obj/item/clothing/mask/smokable/pipe/light(var/flavor_text = "[usr] lights the [name].") - if(!src.lit && src.smoketime) - src.lit = 1 - damtype = "fire" - icon_state = icon_on - item_state = icon_on - var/turf/T = get_turf(src) - T.visible_message(flavor_text) - processing_objects.Add(src) - if(ismob(loc)) - var/mob/living/M = loc - M.update_inv_wear_mask(0) - M.update_inv_l_hand(0) - M.update_inv_r_hand(1) - /obj/item/clothing/mask/smokable/pipe/attack_self(mob/user as mob) if(lit == 1) if(user.a_intent == I_HURT) diff --git a/code/game/objects/items/weapons/implants/implantcircuits.dm b/code/game/objects/items/weapons/implants/implantcircuits.dm index cf55cbd706..db24be3c0a 100644 --- a/code/game/objects/items/weapons/implants/implantcircuits.dm +++ b/code/game/objects/items/weapons/implants/implantcircuits.dm @@ -38,7 +38,10 @@ IC.examine(user) /obj/item/weapon/implant/integrated_circuit/attackby(var/obj/item/O, var/mob/user) - if(istype(O, /obj/item/weapon/crowbar) || istype(O, /obj/item/device/integrated_electronics) || istype(O, /obj/item/integrated_circuit) || istype(O, /obj/item/weapon/screwdriver) ) + if(istype(O, /obj/item/weapon/crowbar) || istype(O, /obj/item/device/integrated_electronics) || istype(O, /obj/item/integrated_circuit) || istype(O, /obj/item/weapon/screwdriver) || istype(O, /obj/item/weapon/cell/device) ) IC.attackby(O, user) else - ..() \ No newline at end of file + ..() + +/obj/item/weapon/implant/integrated_circuit/attack_self(mob/user) + IC.attack_self(user) \ No newline at end of file diff --git a/code/game/objects/items/weapons/material/material_armor.dm b/code/game/objects/items/weapons/material/material_armor.dm new file mode 100644 index 0000000000..1041fb5d1f --- /dev/null +++ b/code/game/objects/items/weapons/material/material_armor.dm @@ -0,0 +1,263 @@ +#define MATERIAL_ARMOR_COEFFICENT 0.05 +/* +SEE code/modules/materials/materials.dm FOR DETAILS ON INHERITED DATUM. +This class of armor takes armor and appearance data from a material "datum". +They are also fragile based on material data and many can break/smash apart when hit. + +Materials has a var called protectiveness which plays a major factor in how good it is for armor. +With the coefficent being 0.05, this is how strong different levels of protectiveness are (for melee) +For bullets and lasers, material hardness and reflectivity also play a major role, respectively. + + +Protectiveness | Armor % + 0 = 0% + 5 = 20% + 10 = 33% + 15 = 42% + 20 = 50% + 25 = 55% + 30 = 60% + 40 = 66% + 50 = 71% + 60 = 75% + 70 = 77% + 80 = 80% +*/ + + +// Putting these at /clothing/ level saves a lot of code duplication in armor/helmets/gauntlets/etc +/obj/item/clothing + var/material/material = null // Why isn't this a datum? + var/applies_material_color = TRUE + var/unbreakable = FALSE + var/default_material = null // Set this to something else if you want material attributes on init. + var/material_armor_modifer = 1 // Adjust if you want seperate types of armor made from the same material to have different protectiveness (e.g. makeshift vs real armor) + +/obj/item/clothing/New(var/newloc, var/material_key) + ..(newloc) + if(!material_key) + material_key = default_material + if(material_key) // May still be null if a material was not specified as a default. + set_material(material_key) + +/obj/item/clothing/Destroy() + processing_objects -= src + ..() + +/obj/item/clothing/get_material() + return material + +// Debating if this should be made an /obj/item/ proc. +/obj/item/clothing/proc/set_material(var/new_material) + material = get_material_by_name(new_material) + if(!material) + qdel(src) + else + name = "[material.display_name] [initial(name)]" + health = round(material.integrity/10) + if(applies_material_color) + color = material.icon_colour + if(material.products_need_process()) + processing_objects |= src + update_armor() + +// This is called when someone wearing the object gets hit in some form (melee, bullet_act(), etc). +// Note that this cannot change if someone gets hurt, as it merely reacts to being hit. +/obj/item/clothing/proc/clothing_impact(var/obj/source, var/damage) + if(material && damage) + material_impact(source, damage) + +/obj/item/clothing/proc/material_impact(var/obj/source, var/damage) + if(!material || unbreakable) + return + + if(istype(source, /obj/item/projectile)) + var/obj/item/projectile/P = source + if(P.pass_flags & PASSGLASS) + if(material.opacity - 0.3 <= 0) + return // Lasers ignore 'fully' transparent material. + + if(material.is_brittle()) + health = 0 + else if(!prob(material.hardness)) + health-- + + if(health <= 0) + shatter() + +/obj/item/clothing/proc/shatter() + if(!material) + return + var/turf/T = get_turf(src) + T.visible_message("\The [src] [material.destruction_desc]!") + if(istype(loc, /mob/living)) + var/mob/living/M = loc + M.drop_from_inventory(src) + if(material.shard_type == SHARD_SHARD) // Wearing glass armor is a bad idea. + var/obj/item/weapon/material/shard/S = material.place_shard(T) + M.embed(S) + + playsound(src, "shatter", 70, 1) + qdel(src) + +// Might be best to make ablative vests a material armor using a new material to cut down on this copypaste. +/obj/item/clothing/suit/armor/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + if(!material) // No point checking for reflection. + return ..() + + if(material.reflectivity) + if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam)) + var/obj/item/projectile/P = damage_source + + if(P.reflected) // Can't reflect twice + return ..() + + var/reflectchance = (40 * material.reflectivity) - round(damage/3) + reflectchance *= material_armor_modifer + if(!(def_zone in list(BP_TORSO, BP_GROIN))) + reflectchance /= 2 + if(P.starting && prob(reflectchance)) + visible_message("\The [user]'s [src.name] reflects [attack_text]!") + + // Find a turf near or on the original location to bounce to + var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/turf/curloc = get_turf(user) + + // redirect the projectile + P.redirect(new_x, new_y, curloc, user) + P.reflected = 1 + + return PROJECTILE_CONTINUE // complete projectile permutation + +/proc/calculate_material_armor(amount) + var/result = 1 - MATERIAL_ARMOR_COEFFICENT * amount / (1 + MATERIAL_ARMOR_COEFFICENT * abs(amount)) + result = result * 100 + result = abs(result - 100) + return round(result) + + +/obj/item/clothing/proc/update_armor() + if(material) + var/melee_armor = 0, bullet_armor = 0, laser_armor = 0, energy_armor = 0, bomb_armor = 0 + + melee_armor = calculate_material_armor(material.protectiveness * material_armor_modifer) + + bullet_armor = calculate_material_armor((material.protectiveness * (material.hardness / 100) * material_armor_modifer) * 0.7) + + laser_armor = calculate_material_armor((material.protectiveness * (material.reflectivity + 1) * material_armor_modifer) * 0.7) + if(material.opacity != 1) + laser_armor *= max(material.opacity - 0.3, 0) // Glass and such has an opacity of 0.3, but lasers should go through glass armor entirely. + + energy_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.4) + + bomb_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.5) + + // Makes sure the numbers stay capped. + for(var/number in list(melee_armor, bullet_armor, laser_armor, energy_armor, bomb_armor)) + number = between(0, number, 100) + + armor["melee"] = melee_armor + armor["bullet"] = bullet_armor + armor["laser"] = laser_armor + armor["energy"] = energy_armor + armor["bomb"] = bomb_armor + + if(!isnull(material.conductivity)) + siemens_coefficient = between(0, material.conductivity / 10, 10) + slowdown = between(0, round(material.weight / 10, 0.1), 6) + +/obj/item/clothing/suit/armor/material + name = "armor" + default_material = DEFAULT_WALL_MATERIAL + +/obj/item/clothing/suit/armor/material/makeshift + name = "sheet armor" + desc = "This appears to be two 'sheets' of a material held together by cable. If the sheets are strong, this could be rather protective." + icon_state = "material_armor_makeshift" + +/obj/item/clothing/suit/armor/material/makeshift/durasteel + default_material = "durasteel" + +/obj/item/clothing/suit/armor/material/makeshift/glass + default_material = "glass" + +// Used to craft sheet armor, and possibly other things in the Future(tm). +/obj/item/weapon/material/armor_plating + name = "armor plating" + desc = "A sheet designed to protect something." + icon = 'icons/obj/items.dmi' + icon_state = "armor_plate" + unbreakable = TRUE + force_divisor = 0.05 // Really bad as a weapon. + thrown_force_divisor = 0.2 + var/wired = FALSE + +/obj/item/weapon/material/armor_plating/attackby(var/obj/O, mob/user) + if(istype(O, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/S = O + if(wired) + to_chat(user, "This already has enough wires on it.") + return + if(S.use(20)) + to_chat(user, "You attach several wires to \the [src]. Now it needs another plate.") + wired = TRUE + icon_state = "[initial(icon_state)]_wired" + return + else + to_chat(user, "You need more wire for that.") + return + if(istype(O, /obj/item/weapon/material/armor_plating)) + var/obj/item/weapon/material/armor_plating/second_plate = O + if(!wired && !second_plate.wired) + to_chat(user, "You need something to hold the two pieces of plating together.") + return + if(second_plate.material != src.material) + to_chat(user, "Both plates need to be the same type of material.") + return + user.drop_from_inventory(src) + user.drop_from_inventory(second_plate) + var/obj/item/clothing/suit/armor/material/makeshift/new_armor = new(null, src.material.name) + user.put_in_hands(new_armor) + qdel(second_plate) + qdel(src) + else + ..() + + +// Used to craft the makeshift helmet +/obj/item/clothing/head/helmet/bucket + name = "bucket" + desc = "It's a bucket with a large hole cut into it. You could wear it on your head and look really stupid." + flags_inv = HIDEEARS|HIDEEYES|BLOCKHAIR + icon_state = "bucket" + armor = list(melee = 5, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) + +/obj/item/clothing/head/helmet/bucket/attackby(var/obj/O, mob/user) + if(istype(O, /obj/item/stack/material)) + var/obj/item/stack/material/S = O + if(S.use(2)) + to_chat(user, "You apply some [S.material.use_name] to \the [src]. Hopefully it'll make the makeshift helmet stronger.") + var/obj/item/clothing/head/helmet/material/makeshift/helmet = new(null, S.material.name) + user.put_in_hands(helmet) + user.drop_from_inventory(src) + qdel(src) + return + else + to_chat(user, "You don't have enough material to build a helmet!") + else + ..() + +/obj/item/clothing/head/helmet/material + name = "helmet" + flags_inv = HIDEEARS|HIDEEYES|BLOCKHAIR + default_material = DEFAULT_WALL_MATERIAL + +/obj/item/clothing/head/helmet/material/makeshift + name = "bucket" + desc = "A bucket with plating applied to the outside. Very crude, but could potentially be rather protective, if \ + it was plated with something strong." + icon_state = "material_armor_makeshift" + +/obj/item/clothing/head/helmet/material/makeshift/durasteel + default_material = "durasteel" \ No newline at end of file diff --git a/code/game/objects/items/weapons/permits.dm b/code/game/objects/items/weapons/permits.dm index bb0ebfdd0c..8008959460 100644 --- a/code/game/objects/items/weapons/permits.dm +++ b/code/game/objects/items/weapons/permits.dm @@ -32,4 +32,9 @@ /obj/item/weapon/permit/gun/bar name = "bar shotgun permit" - desc = "A card indicating that the owner is allowed to carry a shotgun in the bar." \ No newline at end of file + desc = "A card indicating that the owner is allowed to carry a shotgun in the bar." + +/obj/item/weapon/permit/drone + name = "drone identification card" + desc = "A card issued by the EIO, indicating that the owner is a Drone Intelligence. Drones are mandated to carry this card within SolGov space, by law." + icon_state = "drone" \ No newline at end of file diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm index a9f2a15dea..9b4cb3ca9b 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -2,12 +2,12 @@ /obj/item/taperoll name = "tape roll" icon = 'icons/policetape.dmi' - icon_state = "rollstart" + icon_state = "tape" w_class = ITEMSIZE_SMALL var/turf/start var/turf/end var/tape_type = /obj/item/tape - var/icon_base + var/icon_base = "tape" var/apply_tape = FALSE @@ -33,7 +33,7 @@ var/list/tape_roll_applications = list() var/lifted = 0 var/crumpled = 0 var/tape_dir = 0 - var/icon_base + var/icon_base = "tape" /obj/item/tape/update_icon() //Possible directional bitflags: 0 (AIRLOCK), 1 (NORTH), 2 (SOUTH), 4 (EAST), 8 (WEST), 3 (VERTICAL), 12 (HORIZONTAL) @@ -60,22 +60,20 @@ var/list/tape_roll_applications = list() /obj/item/taperoll/police name = "police tape" desc = "A roll of police tape used to block off crime scenes from the public." - icon_state = "police" tape_type = /obj/item/tape/police - icon_base = "police" + color = COLOR_RED_LIGHT /obj/item/tape/police name = "police tape" desc = "A length of police tape. Do not cross." req_access = list(access_security) - icon_base = "police" + color = COLOR_RED_LIGHT /obj/item/taperoll/engineering name = "engineering tape" desc = "A roll of engineering tape used to block off working areas from the public." - icon_state = "engineering" tape_type = /obj/item/tape/engineering - icon_base = "engineering" + color = COLOR_YELLOW /obj/item/taperoll/engineering/applied apply_tape = TRUE @@ -84,28 +82,31 @@ var/list/tape_roll_applications = list() name = "engineering tape" desc = "A length of engineering tape. Better not cross it." req_one_access = list(access_engine,access_atmospherics) - icon_base = "engineering" + color = COLOR_YELLOW /obj/item/taperoll/atmos name = "atmospherics tape" desc = "A roll of atmospherics tape used to block off working areas from the public." - icon_state = "atmos" tape_type = /obj/item/tape/atmos - icon_base = "atmos" + color = COLOR_DEEP_SKY_BLUE /obj/item/tape/atmos name = "atmospherics tape" desc = "A length of atmospherics tape. Better not cross it." req_one_access = list(access_engine,access_atmospherics) - icon_base = "atmos" + color = COLOR_DEEP_SKY_BLUE /obj/item/taperoll/update_icon() overlays.Cut() + var/image/overlay = image(icon = src.icon) + overlay.appearance_flags = RESET_COLOR if(ismob(loc)) if(!start) - overlays += "start" + overlay.icon_state = "start" else - overlays += "stop" + overlay.icon_state = "stop" + overlays += overlay + /obj/item/taperoll/dropped(mob/user) update_icon() diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index b6fc2f4251..04e5aa909b 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -163,6 +163,15 @@ overlays = null qdel(src) +/obj/item/weapon/ducttape/attackby(var/obj/item/I, var/mob/user) + if(!(istype(src, /obj/item/weapon/handcuffs/cable/tape) || istype(src, /obj/item/clothing/mask/muzzle/tape))) + return ..() + else + user.drop_from_inventory(I) + I.loc = src + qdel(I) + to_chat(user, "You place \the [I] back into \the [src].") + /obj/item/weapon/ducttape/afterattack(var/A, mob/user, flag, params) if(!in_range(user, A) || istype(A, /obj/machinery/door) || !stuck) diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 1080e1b8fb..8c4067187f 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -401,7 +401,7 @@ user.sdisabilities |= BLIND else if (E.damage >= E.min_bruised_damage) user << "You go blind!" - user.eye_blind = 5 + user.Blind(5) user.eye_blurry = 5 user.disabilities |= NEARSIGHTED spawn(100) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index eb6e2c2a77..34fb77f9f0 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -77,34 +77,44 @@ return return + /obj/structure/morgue/attack_hand(mob/user as mob) if (src.connected) - for(var/atom/movable/A as mob|obj in src.connected.loc) - if (!( A.anchored )) - A.forceMove(src) - playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - qdel(src.connected) - src.connected = null + close() else - playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - src.connected = new /obj/structure/m_tray( src.loc ) - step(src.connected, src.dir) - src.connected.layer = OBJ_LAYER - var/turf/T = get_step(src, src.dir) - if (T.contents.Find(src.connected)) - src.connected.connected = src - src.icon_state = "morgue0" - for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.connected.loc) - src.connected.icon_state = "morguet" - src.connected.set_dir(src.dir) - else - qdel(src.connected) - src.connected = null + open() src.add_fingerprint(user) update() return + +/obj/structure/morgue/proc/close() + for(var/atom/movable/A as mob|obj in src.connected.loc) + if (!( A.anchored )) + A.forceMove(src) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + qdel(src.connected) + src.connected = null + + +/obj/structure/morgue/proc/open() + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + src.connected = new /obj/structure/m_tray( src.loc ) + step(src.connected, src.dir) + src.connected.layer = OBJ_LAYER + var/turf/T = get_step(src, src.dir) + if (T.contents.Find(src.connected)) + src.connected.connected = src + src.icon_state = "morgue0" + for(var/atom/movable/A as mob|obj in src) + A.forceMove(src.connected.loc) + src.connected.icon_state = "morguet" + src.connected.set_dir(src.dir) + else + qdel(src.connected) + src.connected = null + + /obj/structure/morgue/attackby(P as obj, mob/user as mob) if (istype(P, /obj/item/weapon/pen)) var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text @@ -123,21 +133,8 @@ /obj/structure/morgue/relaymove(mob/user as mob) if (user.stat) return - src.connected = new /obj/structure/m_tray( src.loc ) - step(src.connected, EAST) - src.connected.layer = OBJ_LAYER - var/turf/T = get_step(src, EAST) - if (T.contents.Find(src.connected)) - src.connected.connected = src - src.icon_state = "morgue0" - for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.connected.loc) - src.connected.icon_state = "morguet" - else - qdel(src.connected) - src.connected = null - return - + if (user in src.occupants) + open() /* * Morgue tray diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm index 779f76fc93..2170ea3019 100644 --- a/code/game/turfs/flooring/flooring.dm +++ b/code/game/turfs/flooring/flooring.dm @@ -37,6 +37,7 @@ var/list/flooring_types var/descriptor = "tiles" var/flags var/can_paint + var/list/footstep_sounds = list() // key=species name, value = list of soundss /decl/flooring/grass name = "grass" @@ -90,6 +91,12 @@ var/list/flooring_types build_type = /obj/item/stack/tile/carpet damage_temperature = T0C+200 flags = TURF_HAS_EDGES | TURF_HAS_CORNERS | TURF_REMOVE_CROWBAR | TURF_CAN_BURN + footstep_sounds = list("human" = list( + 'sound/effects/footstep/carpet1.ogg', + 'sound/effects/footstep/carpet2.ogg', + 'sound/effects/footstep/carpet3.ogg', + 'sound/effects/footstep/carpet4.ogg', + 'sound/effects/footstep/carpet5.ogg')) /decl/flooring/carpet/blue name = "carpet" @@ -107,6 +114,12 @@ var/list/flooring_types flags = TURF_REMOVE_CROWBAR | TURF_CAN_BREAK | TURF_CAN_BURN build_type = /obj/item/stack/tile/floor can_paint = 1 + footstep_sounds = list("human" = list( + 'sound/effects/footstep/floor1.ogg', + 'sound/effects/footstep/floor2.ogg', + 'sound/effects/footstep/floor3.ogg', + 'sound/effects/footstep/floor4.ogg', + 'sound/effects/footstep/floor5.ogg')) /decl/flooring/linoleum name = "linoleum" @@ -193,6 +206,12 @@ var/list/flooring_types descriptor = "planks" build_type = /obj/item/stack/tile/wood flags = TURF_CAN_BREAK | TURF_IS_FRAGILE | TURF_REMOVE_SCREWDRIVER + footstep_sounds = list("human" = list( + 'sound/effects/footstep/wood1.ogg', + 'sound/effects/footstep/wood2.ogg', + 'sound/effects/footstep/wood3.ogg', + 'sound/effects/footstep/wood4.ogg', + 'sound/effects/footstep/wood5.ogg')) /decl/flooring/reinforced name = "reinforced floor" diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 3a7c1afdf0..336a34b2fe 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -13,6 +13,12 @@ var/base_desc = "The naked hull." var/base_icon = 'icons/turf/flooring/plating.dmi' var/base_icon_state = "plating" + var/static/list/base_footstep_sounds = list("human" = list( + 'sound/effects/footstep/plating1.ogg', + 'sound/effects/footstep/plating2.ogg', + 'sound/effects/footstep/plating3.ogg', + 'sound/effects/footstep/plating4.ogg', + 'sound/effects/footstep/plating5.ogg')) // Flooring data. var/flooring_override @@ -33,10 +39,13 @@ floortype = initial_flooring if(floortype) set_flooring(get_flooring_data(floortype)) + else + footstep_sounds = base_footstep_sounds /turf/simulated/floor/proc/set_flooring(var/decl/flooring/newflooring) make_plating(defer_icon_update = 1) flooring = newflooring + footstep_sounds = newflooring.footstep_sounds update_icon(1) levelupdate() @@ -53,6 +62,7 @@ desc = base_desc icon = base_icon icon_state = base_icon_state + footstep_sounds = base_footstep_sounds if(flooring) if(flooring.build_type && place_product) diff --git a/code/game/turfs/simulated/outdoors/outdoors.dm b/code/game/turfs/simulated/outdoors/outdoors.dm index da69406157..75c7e68083 100644 --- a/code/game/turfs/simulated/outdoors/outdoors.dm +++ b/code/game/turfs/simulated/outdoors/outdoors.dm @@ -31,17 +31,19 @@ var/list/outdoor_turfs = list() /turf/simulated/floor/Destroy() if(outdoors) - outdoor_turfs.Remove(src) + planet_controller.unallocateTurf(src) ..() -/turf/simulated/floor/proc/update_icon_edge() +/turf/simulated/proc/update_icon_edge() if(edge_blending_priority) for(var/checkdir in cardinal) var/turf/simulated/T = get_step(src, checkdir) if(istype(T) && T.edge_blending_priority && edge_blending_priority < T.edge_blending_priority && icon_state != T.icon_state) var/cache_key = "[T.get_edge_icon_state()]-[checkdir]" if(!turf_edge_cache[cache_key]) - turf_edge_cache[cache_key] = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir) + var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir) + I.plane = 0 + turf_edge_cache[cache_key] = I overlays += turf_edge_cache[cache_key] /turf/simulated/proc/get_edge_icon_state() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 028223ef26..3f2e0064f2 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -26,6 +26,8 @@ var/movement_cost = 0 // How much the turf slows down movement, if any. + var/list/footstep_sounds = null + /turf/New() ..() for(var/atom/movable/AM as mob|obj in src) @@ -145,6 +147,9 @@ var/const/enterloopsanity = 100 else if(!is_space()) M.inertia_dir = 0 M.make_floating(0) + if(isliving(M)) + var/mob/living/L = M + L.handle_footstep(src) ..() var/objects = 0 if(A && (A.flags & PROXMOVE)) diff --git a/code/game/turfs/unsimulated/planetary.dm b/code/game/turfs/unsimulated/planetary.dm index ce4ffa44c0..7d9159d04a 100644 --- a/code/game/turfs/unsimulated/planetary.dm +++ b/code/game/turfs/unsimulated/planetary.dm @@ -27,6 +27,15 @@ var/list/planetary_walls = list() planetary_walls.Remove(src) ..() +/turf/unsimulated/wall/planetary/proc/set_temperature(var/new_temperature) + if(new_temperature == temperature) + return + temperature = new_temperature + // Force ZAS to reconsider our connections because our temperature has changed + if(connections) + connections.erase_all() + air_master.mark_for_update(src) + // Normal station/earth air. /turf/unsimulated/wall/planetary/normal oxygen = MOLES_O2STANDARD @@ -55,3 +64,4 @@ var/list/planetary_walls = list() oxygen = MOLES_O2STANDARD nitrogen = MOLES_N2STANDARD temperature = 310.92 // About 37.7C / 100F + diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm index ec84ee4232..6e23d74bbb 100644 --- a/code/game/verbs/suicide.dm +++ b/code/game/verbs/suicide.dm @@ -127,7 +127,7 @@ suiciding = 1 viewers(src) << "[src] is powering down. It looks like \he's trying to commit suicide." //put em at -175 - adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0)) + adjustOxyLoss(max(getMaxHealth() * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0)) updatehealth() /mob/living/silicon/robot/verb/suicide() @@ -147,7 +147,7 @@ suiciding = 1 viewers(src) << "[src] is powering down. It looks like \he's trying to commit suicide." //put em at -175 - adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0)) + adjustOxyLoss(max(getMaxHealth() * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0)) updatehealth() /mob/living/silicon/pai/verb/suicide() diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index ffea7b7fab..099aa43978 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -408,6 +408,7 @@ projectile_type = /obj/item/projectile/chameleon charge_meter = 0 charge_cost = 48 //uses next to no power, since it's just holograms + battery_lock = 1 var/obj/item/projectile/copy_projectile var/global/list/gun_choices diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 16501464c6..f3f4cc855a 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -347,7 +347,9 @@ body_parts_covered = FACE|EYES sprite_sheets = list( "Teshari" = 'icons/mob/species/seromi/masks.dmi', - "Vox" = 'icons/mob/species/vox/masks.dmi' + "Vox" = 'icons/mob/species/vox/masks.dmi', + "Tajara" = 'icons/mob/species/tajaran/mask.dmi', + "Unathi" = 'icons/mob/species/unathi/mask.dmi' ) var/voicechange = 0 diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 137cab1a01..9e27f5c73d 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -402,7 +402,7 @@ BLIND // can't see anything var/mob/living/carbon/human/M = src.loc M << "\red The Optical Thermal Scanner overloads and blinds you!" if(M.glasses == src) - M.eye_blind = 3 + M.Blind(3) M.eye_blurry = 5 // Don't cure being nearsighted if(!(M.disabilities & NEARSIGHTED)) diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm index 978a5c13e6..5a311c5172 100644 --- a/code/modules/clothing/masks/boxing.dm +++ b/code/modules/clothing/masks/boxing.dm @@ -6,10 +6,6 @@ flags_inv = HIDEFACE|BLOCKHAIR body_parts_covered = FACE|HEAD w_class = ITEMSIZE_SMALL - sprite_sheets = list( - "Tajara" = 'icons/mob/species/tajaran/mask.dmi', - "Unathi" = 'icons/mob/species/unathi/mask.dmi', - ) /obj/item/clothing/mask/balaclava/tactical name = "green balaclava" @@ -18,10 +14,6 @@ item_state_slots = list(slot_r_hand_str = "bandgreen", slot_l_hand_str = "bandgreen") flags_inv = HIDEFACE|BLOCKHAIR w_class = ITEMSIZE_SMALL - sprite_sheets = list( - "Tajara" = 'icons/mob/species/tajaran/mask.dmi', - "Unathi" = 'icons/mob/species/unathi/mask.dmi', - ) /obj/item/clothing/mask/luchador name = "Luchador Mask" diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm index ff0f8ae077..e23c3c0c26 100644 --- a/code/modules/clothing/spacesuits/alien.dm +++ b/code/modules/clothing/spacesuits/alien.dm @@ -34,7 +34,7 @@ item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | PHORONGUARD allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) phoronproof = 1 - slowdown = 2 + slowdown = 0.5 armor = list(melee = 60, bullet = 50, laser = 40,energy = 15, bomb = 30, bio = 100, rad = 50) siemens_coefficient = 0.2 heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index d08726371a..f090312320 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -80,6 +80,9 @@ if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam)) var/obj/item/projectile/P = damage_source + if(P.reflected) // Can't reflect twice + return ..() + var/reflectchance = 40 - round(damage/3) if(!(def_zone in list(BP_TORSO, BP_GROIN))) reflectchance /= 2 diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm index d9dc2f2e54..a68605ff91 100644 --- a/code/modules/clothing/under/accessories/holster.dm +++ b/code/modules/clothing/under/accessories/holster.dm @@ -76,10 +76,12 @@ /obj/item/clothing/accessory/holster/on_attached(obj/item/clothing/under/S, mob/user as mob) ..() - has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb + if(has_suit) + has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb /obj/item/clothing/accessory/holster/on_removed(mob/user as mob) - has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb + if(has_suit) + has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb ..() //For the holster hotkey diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index e09c062ab0..d0f9a8165c 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -41,9 +41,11 @@ i++ /datum/event/carp_migration/end() - for(var/mob/living/simple_animal/hostile/carp/C in spawned_carp) - if(!C.stat) - var/turf/T = get_turf(C) - if(istype(T, /turf/space)) - if(!prob(25)) - qdel(C) \ No newline at end of file + spawn(0) + for(var/mob/living/simple_animal/hostile/C in spawned_carp) + if(!C.stat) + var/turf/T = get_turf(C) + if(istype(T, /turf/space)) + if(prob(75)) + qdel(C) + sleep(1) \ No newline at end of file diff --git a/code/modules/genetics/side_effects.dm b/code/modules/genetics/side_effects.dm index dcb5b4e499..f3a9efb6d2 100644 --- a/code/modules/genetics/side_effects.dm +++ b/code/modules/genetics/side_effects.dm @@ -72,7 +72,7 @@ finish(mob/living/carbon/human/H) if(!H.reagents.has_reagent("anti_toxin")) - H.confused += 100 + H.Confuse(100) proc/trigger_side_effect(mob/living/carbon/human/H) spawn diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm index c404f61581..7089c19d51 100644 --- a/code/modules/integrated_electronics/_defines.dm +++ b/code/modules/integrated_electronics/_defines.dm @@ -8,7 +8,7 @@ #define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box. #define IC_SPAWN_RESEARCH 2 // If the circuit design will be autogenerated for RnD. -#define IC_FORMAT_STRING "\" +#define IC_FORMAT_STRING "\" #define IC_FORMAT_NUMBER "\" #define IC_FORMAT_REF "\" #define IC_FORMAT_LIST "\" diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 88b804f80a..5c49e1817c 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -107,6 +107,7 @@ for(var/obj/item/integrated_circuit/circuit in contents) HTML += "[circuit.name] | " HTML += "\[Rename\] | " + HTML += "\[Scan with Debugger\] | " if(circuit.removable) HTML += "\[Remove\]" HTML += "
" @@ -223,9 +224,10 @@ if(proximity) var/scanned = FALSE for(var/obj/item/integrated_circuit/input/sensor/S in contents) - S.set_pin_data(IC_OUTPUT, 1, weakref(target)) - S.check_then_do_work() - scanned = TRUE +// S.set_pin_data(IC_OUTPUT, 1, weakref(target)) +// S.check_then_do_work() + if(S.scan(target)) + scanned = TRUE if(scanned) visible_message("\The [user] waves \the [src] around [target].") diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm index 87bb4cd182..1593297734 100644 --- a/code/modules/integrated_electronics/core/integrated_circuit.dm +++ b/code/modules/integrated_electronics/core/integrated_circuit.dm @@ -6,6 +6,7 @@ a creative player the means to solve many problems. Circuits are held inside an /obj/item/integrated_circuit/examine(mob/user) . = ..() external_examine(user) + interact(user) // This should be used when someone is examining while the case is opened. /obj/item/integrated_circuit/proc/internal_examine(mob/user) @@ -86,16 +87,14 @@ a creative player the means to solve many problems. Circuits are held inside an var/HTML = list() HTML += "[src.name]" HTML += "
" - HTML += "" + HTML += "
" HTML += "
\[Refresh\] | " HTML += "\[Rename\] | " + HTML += "\[Scan with Debugger\] | " HTML += "\[Remove\]
" HTML += "" - //HTML += "" - //HTML += "" - //HTML += "" HTML += "" HTML += "" HTML += "" @@ -212,6 +211,16 @@ a creative player the means to solve many problems. Circuits are held inside an if(href_list["rename"]) rename_component(usr) + if(href_list["scan"]) + if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/D = held_item + if(D.accepting_refs) + D.afterattack(src, usr, TRUE) + else + to_chat(usr, "The Debugger's 'ref scanner' needs to be on.") + else + to_chat(usr, "You need a Debugger set to 'ref' mode to do that.") + if(href_list["autopulse"]) if(autopulse != -1) autopulse = !autopulse @@ -260,10 +269,10 @@ a creative player the means to solve many problems. Circuits are held inside an return TRUE // Battery has enough. return FALSE // Not enough power. -/obj/item/integrated_circuit/proc/check_then_do_work() +/obj/item/integrated_circuit/proc/check_then_do_work(var/ignore_power = FALSE) if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam. return - if(power_draw_per_use) + if(power_draw_per_use && !ignore_power) if(!check_power()) power_fail() return diff --git a/code/modules/integrated_electronics/core/tools.dm b/code/modules/integrated_electronics/core/tools.dm index 8220162be7..a875917441 100644 --- a/code/modules/integrated_electronics/core/tools.dm +++ b/code/modules/integrated_electronics/core/tools.dm @@ -160,7 +160,7 @@ data_to_show = A.name to_chat(user, "You write '[data_to_write ? data_to_show : "NULL"]' to the '[io]' pin of \the [io.holder].") else if(io.io_type == PULSE_CHANNEL) - io.holder.check_then_do_work() + io.holder.check_then_do_work(ignore_power = TRUE) to_chat(user, "You pulse \the [io.holder]'s [io].") io.holder.interact(user) // This is to update the UI. diff --git a/code/modules/integrated_electronics/subtypes/arithmetic.dm b/code/modules/integrated_electronics/subtypes/arithmetic.dm index c6134f9bd1..059c699e50 100644 --- a/code/modules/integrated_electronics/subtypes/arithmetic.dm +++ b/code/modules/integrated_electronics/subtypes/arithmetic.dm @@ -1,9 +1,18 @@ //These circuits do simple math. /obj/item/integrated_circuit/arithmetic complexity = 1 - inputs = list("A","B","C","D","E","F","G","H") - outputs = list("result") - activators = list("compute") + inputs = list( + "\ A", + "\ B", + "\ C", + "\ D", + "\ E", + "\ F", + "\ G", + "\ H" + ) + outputs = list("\ result") + activators = list("\ compute", "\ on computed") category_text = "Arithmetic" autopulse = 1 power_draw_per_use = 5 // Math is pretty cheap. @@ -30,9 +39,9 @@ if(isnum(I.data)) result = result + I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // -Subtracting- // @@ -58,9 +67,9 @@ if(isnum(I.data)) result = result - I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // *Multiply* // @@ -86,9 +95,9 @@ if(isnum(I.data)) result = result * I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // /Division/ // @@ -114,9 +123,9 @@ if(isnum(I.data) && I.data != 0) //No runtimes here. result = result / I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) //^ Exponent ^// @@ -134,9 +143,9 @@ if(isnum(A.data) && isnum(B.data)) result = A.data ** B.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // +-Sign-+ // @@ -159,9 +168,9 @@ else result = 0 - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Round // @@ -183,9 +192,9 @@ else result = round(A.data) - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Absolute // @@ -204,9 +213,9 @@ if(isnum(I.data)) result = abs(I.data) - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Averaging // @@ -229,9 +238,9 @@ if(inputs_used) result = result / inputs_used - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Pi, because why the hell not? // /obj/item/integrated_circuit/arithmetic/pi @@ -242,9 +251,9 @@ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/pi/do_work() - var/datum/integrated_io/output/O = outputs[1] - O.data = 3.14159 - O.push_data() + set_pin_data(IC_OUTPUT, 1, 3.14159) + push_data() + activate_pin(2) // Random // /obj/item/integrated_circuit/arithmetic/random @@ -253,20 +262,20 @@ extended_desc = "'Inclusive' means that the upper bound is included in the range of numbers, e.g. L = 1 and H = 3 will allow \ for outputs of 1, 2, or 3. H being the higher number is not strictly required." icon_state = "random" - inputs = list("L","H") + inputs = list("\ L","\ H") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/random/do_work() var/result = 0 - var/datum/integrated_io/L = inputs[1] - var/datum/integrated_io/H = inputs[2] + var/L = get_pin_data(IC_INPUT, 1) + var/H = get_pin_data(IC_INPUT, 2) - if(isnum(L.data) && isnum(H.data)) - result = rand(L.data, H.data) + if(isnum(L) && isnum(H)) + result = rand(L, H) - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Square Root // @@ -274,7 +283,7 @@ name = "square root circuit" desc = "This outputs the square root of a number you put in." icon_state = "square_root" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/square_root/do_work() @@ -284,9 +293,9 @@ if(isnum(I.data)) result = sqrt(I.data) - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // % Modulo % // @@ -294,17 +303,17 @@ name = "modulo circuit" desc = "Gets the remainder of A / B." icon_state = "modulo" - inputs = list("A", "B") + inputs = list("\ A", "\ B") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/modulo/do_work() var/result = 0 - var/datum/integrated_io/input/A = inputs[1] - var/datum/integrated_io/input/B = inputs[2] - if(isnum(A.data) && isnum(B.data) && B.data != 0) - result = A.data % B.data + var/A = get_pin_data(IC_INPUT, 1) + var/B = get_pin_data(IC_INPUT, 2) + if(isnum(A) && isnum(B) && B != 0) + result = A % B - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 9e04e24db5..431faa241f 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -3,7 +3,7 @@ complexity = 2 inputs = list("input") outputs = list("output") - activators = list("convert") + activators = list("\ convert", "\ on convert") category_text = "Converter" autopulse = 1 power_draw_per_use = 10 @@ -16,89 +16,113 @@ name = "number to string" desc = "This circuit can convert a number variable into a string." icon_state = "num-string" + inputs = list("\ input") + outputs = list("\ output") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/num2text/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && isnum(incoming.data)) - result = num2text(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && isnum(incoming)) + result = num2text(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/text2num name = "string to number" desc = "This circuit can convert a string variable into a number." icon_state = "string-num" + inputs = list("\ input") + outputs = list("\ output") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/text2num/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && istext(incoming.data)) - result = text2num(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && istext(incoming)) + result = text2num(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/ref2text name = "reference to string" desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference." icon_state = "ref-string" + inputs = list("\ input") + outputs = list("\ output") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/ref2text/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - var/atom/A = incoming.data_as_type(/atom) - result = A && A.name + pull_data() + var/atom/A = get_pin_data(IC_INPUT, 1) + if(A && istype(A)) + result = A.name - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/lowercase name = "lowercase string converter" desc = "this will cause a string to come out in all lowercase." icon_state = "lowercase" + inputs = list("\ input") + outputs = list("\ output") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/lowercase/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && istext(incoming.data)) - result = lowertext(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && istext(incoming)) + result = lowertext(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/uppercase name = "uppercase string converter" desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE." icon_state = "uppercase" + inputs = list("\ input") + outputs = list("\ output") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/uppercase/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && istext(incoming.data)) - result = uppertext(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && istext(incoming)) + result = uppertext(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/concatenatior name = "concatenatior" - desc = "This joins many strings together to get one big string." + desc = "This joins many strings or numbers together to get one big string." complexity = 4 - inputs = list("A","B","C","D","E","F","G","H") - outputs = list("result") - activators = list("concatenate") + inputs = list( + "\ A", + "\ B", + "\ C", + "\ D", + "\ E", + "\ F", + "\ G", + "\ H" + ) + outputs = list("\ result") + activators = list("\ concatenate", "\ on concatenated") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/concatenatior/do_work() @@ -107,70 +131,70 @@ I.pull_data() if(istext(I.data)) result = result + I.data + else if(!isnull(I.data) && num2text(I.data)) + result = result + num2text(I.data) var/datum/integrated_io/outgoing = outputs[1] outgoing.data = result outgoing.push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/radians2degrees name = "radians to degrees converter" desc = "Converts radians to degrees." - inputs = list("radian") - outputs = list("degrees") + inputs = list("\ radian") + outputs = list("\ degrees") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/radians2degrees/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - incoming.pull_data() - if(incoming.data && isnum(incoming.data)) - result = ToDegrees(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && isnum(incoming)) + result = ToDegrees(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/degrees2radians name = "degrees to radians converter" desc = "Converts degrees to radians." - inputs = list("degrees") - outputs = list("radians") + inputs = list("\ degrees") + outputs = list("\ radians") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/degrees2radians/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - incoming.pull_data() - if(incoming.data && isnum(incoming.data)) - result = ToRadians(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && isnum(incoming)) + result = ToRadians(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/abs_to_rel_coords name = "abs to rel coordinate converter" desc = "Easily convert absolute coordinates to relative coordinates with this." complexity = 4 - inputs = list("X1 (abs)", "Y1 (abs)", "X2 (abs)", "Y2 (abs)") - outputs = list("X (rel)", "Y (rel)") - activators = list("compute rel coordinates") + inputs = list("\ X1", "\ Y1", "\ X2", "\ Y2") + outputs = list("\ X", "\ Y") + activators = list("\ compute rel coordinates", "\ on convert") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work() - var/datum/integrated_io/x1 = inputs[1] - var/datum/integrated_io/y1 = inputs[2] + var/x1 = get_pin_data(IC_INPUT, 1) + var/y1 = get_pin_data(IC_INPUT, 2) - var/datum/integrated_io/x2 = inputs[3] - var/datum/integrated_io/y2 = inputs[4] + var/x2 = get_pin_data(IC_INPUT, 3) + var/y2 = get_pin_data(IC_INPUT, 4) - var/datum/integrated_io/result_x = outputs[1] - var/datum/integrated_io/result_y = outputs[2] + if(x1 && y1 && x2 && y2) + set_pin_data(IC_OUTPUT, 1, x1 - x2) + set_pin_data(IC_OUTPUT, 2, y1 - y2) - if(x1.data && y1.data && x2.data && y2.data) - result_x.data = x1.data - x2.data - result_y.data = y1.data - y2.data - - for(var/datum/integrated_io/output/O in outputs) - O.push_data() \ No newline at end of file + push_data() + activate_pin(2) \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/input_output.dm b/code/modules/integrated_electronics/subtypes/input_output.dm index baa5738d4e..456fae889f 100644 --- a/code/modules/integrated_electronics/subtypes/input_output.dm +++ b/code/modules/integrated_electronics/subtypes/input_output.dm @@ -14,28 +14,27 @@ can_be_asked_input = 1 inputs = list() outputs = list() - activators = list("on pressed") + activators = list("\ on pressed") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use. - var/datum/integrated_io/A = activators[1] - if(A.linked.len) - for(var/datum/integrated_io/activate/target in A.linked) - target.holder.check_then_do_work() to_chat(user, "You press the button labeled '[src.name]'.") + activate_pin(1) /obj/item/integrated_circuit/input/toggle_button name = "toggle button" desc = "It toggles on, off, on, off..." icon_state = "toggle_button" complexity = 1 + can_be_asked_input = 1 inputs = list() - outputs = list("on" = 0) - activators = list("on toggle") + outputs = list("\ on" = 0) + activators = list("\ on toggle") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/input/toggle_button/ask_for_input(mob/user) // Ditto. set_pin_data(IC_OUTPUT, 1, !get_pin_data(IC_OUTPUT, 1)) + push_data() activate_pin(1) to_chat(user, "You toggle the button labeled '[src.name]' [get_pin_data(IC_OUTPUT, 1) ? "on" : "off"].") @@ -46,19 +45,17 @@ complexity = 2 can_be_asked_input = 1 inputs = list() - outputs = list("number entered") - activators = list("on entered") + outputs = list("\ number entered") + activators = list("\ on entered") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 /obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) var/new_input = input(user, "Enter a number, please.","Number pad") as null|num if(isnum(new_input) && CanInteract(user, physical_state)) - var/datum/integrated_io/O = outputs[1] - O.data = new_input - O.push_data() - var/datum/integrated_io/A = activators[1] - A.push_data() + set_pin_data(IC_OUTPUT, 1, new_input) + push_data() + activate_pin(1) /obj/item/integrated_circuit/input/textpad name = "text pad" @@ -67,49 +64,43 @@ complexity = 2 can_be_asked_input = 1 inputs = list() - outputs = list("string entered") - activators = list("on entered") + outputs = list("\ string entered") + activators = list("\ on entered") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 /obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) var/new_input = input(user, "Enter some words, please.","Number pad") as null|text if(istext(new_input) && CanInteract(user, physical_state)) - var/datum/integrated_io/O = outputs[1] - O.data = new_input - O.push_data() - var/datum/integrated_io/A = activators[1] - A.push_data() + set_pin_data(IC_OUTPUT, 1, new_input) + push_data() + activate_pin(1) /obj/item/integrated_circuit/input/med_scanner name = "integrated medical analyser" desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is." icon_state = "medscan" complexity = 4 - inputs = list("target ref") - outputs = list("total health %", "total missing health") - activators = list("scan") + inputs = list("\ target") + outputs = list("\ total health %", "\ total missing health") + activators = list("\ scan", "\ on scanned") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) power_draw_per_use = 40 /obj/item/integrated_circuit/input/med_scanner/do_work() - var/datum/integrated_io/I = inputs[1] - var/mob/living/carbon/human/H = I.data_as_type(/mob/living/carbon/human) + var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human) if(!istype(H)) //Invalid input return if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. - var/total_health = round(H.health/H.maxHealth, 0.1)*100 - var/missing_health = H.maxHealth - H.health + var/total_health = round(H.health/H.getMaxHealth(), 0.1)*100 + var/missing_health = H.getMaxHealth() - H.health - var/datum/integrated_io/total = outputs[1] - var/datum/integrated_io/missing = outputs[2] + set_pin_data(IC_OUTPUT, 1, total_health) + set_pin_data(IC_OUTPUT, 2, missing_health) - total.data = total_health - missing.data = missing_health - - for(var/datum/integrated_io/output/O in outputs) - O.push_data() + push_data() + activate_pin(2) /obj/item/integrated_circuit/input/adv_med_scanner name = "integrated advanced medical analyser" @@ -117,48 +108,39 @@ This type is much more precise, allowing the machine to know much more about the target than a normal analyzer." icon_state = "medscan_adv" complexity = 12 - inputs = list("target ref") + inputs = list("\ target") outputs = list( - "total health %", - "total missing health", - "brute damage", - "burn damage", - "tox damage", - "oxy damage", - "clone damage" + "\ total health %", + "\ total missing health", + "\ brute damage", + "\ burn damage", + "\ tox damage", + "\ oxy damage", + "\ clone damage" ) - activators = list("scan") + activators = list("\ scan", "\ on scanned") spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) power_draw_per_use = 80 /obj/item/integrated_circuit/input/adv_med_scanner/do_work() - var/datum/integrated_io/I = inputs[1] - var/mob/living/carbon/human/H = I.data_as_type(/mob/living/carbon/human) + var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human) if(!istype(H)) //Invalid input return if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. - var/total_health = round(H.health/H.maxHealth, 0.1)*100 - var/missing_health = H.maxHealth - H.health + var/total_health = round(H.health/H.getMaxHealth(), 0.1)*100 + var/missing_health = H.getMaxHealth() - H.health - var/datum/integrated_io/total = outputs[1] - var/datum/integrated_io/missing = outputs[2] - var/datum/integrated_io/brute = outputs[3] - var/datum/integrated_io/burn = outputs[4] - var/datum/integrated_io/tox = outputs[5] - var/datum/integrated_io/oxy = outputs[6] - var/datum/integrated_io/clone = outputs[7] + set_pin_data(IC_OUTPUT, 1, total_health) + set_pin_data(IC_OUTPUT, 2, missing_health) + set_pin_data(IC_OUTPUT, 3, H.getBruteLoss()) + set_pin_data(IC_OUTPUT, 4, H.getFireLoss()) + set_pin_data(IC_OUTPUT, 5, H.getToxLoss()) + set_pin_data(IC_OUTPUT, 6, H.getOxyLoss()) + set_pin_data(IC_OUTPUT, 7, H.getCloneLoss()) - total.data = total_health - missing.data = missing_health - brute.data = H.getBruteLoss() - burn.data = H.getFireLoss() - tox.data = H.getToxLoss() - oxy.data = H.getOxyLoss() - clone.data = H.getCloneLoss() - - for(var/datum/integrated_io/output/O in outputs) - O.push_data() + push_data() + activate_pin(2) /obj/item/integrated_circuit/input/local_locator name = "local locator" @@ -222,9 +204,9 @@ Meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin." icon_state = "signal" complexity = 4 - inputs = list("frequency","code") + inputs = list("\ frequency","\ code") outputs = list() - activators = list("send signal","on signal received") + activators = list("\ send signal","\ on signal sent", "\ on signal received") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2) power_draw_idle = 5 @@ -237,11 +219,9 @@ /obj/item/integrated_circuit/input/signaler/initialize() ..() set_frequency(frequency) - var/datum/integrated_io/new_freq = inputs[1] - var/datum/integrated_io/new_code = inputs[2] // Set the pins so when someone sees them, they won't show as null - new_freq.data = frequency - new_code.data = code + set_pin_data(IC_INPUT, 1, frequency) + set_pin_data(IC_INPUT, 2, code) /obj/item/integrated_circuit/input/signaler/Destroy() if(radio_controller) @@ -250,12 +230,12 @@ . = ..() /obj/item/integrated_circuit/input/signaler/on_data_written() - var/datum/integrated_io/new_freq = inputs[1] - var/datum/integrated_io/new_code = inputs[2] - if(isnum(new_freq.data) && new_freq.data > 0) - set_frequency(new_freq.data) - if(isnum(new_code.data)) - code = new_code.data + var/new_freq = get_pin_data(IC_INPUT, 1) + var/new_code = get_pin_data(IC_INPUT, 2) + if(isnum(new_freq) && new_freq > 0) + set_frequency(new_freq) + if(isnum(new_code)) + code = new_code /obj/item/integrated_circuit/input/signaler/do_work() // Sends a signal. @@ -267,6 +247,7 @@ signal.encryption = code signal.data["message"] = "ACTIVATE" radio_connection.post_signal(src, signal) + activate_pin(2) /obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency) if(!frequency) @@ -280,11 +261,11 @@ radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) /obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal) - var/datum/integrated_io/new_code = inputs[2] + var/new_code = get_pin_data(IC_INPUT, 2) var/code = 0 - if(isnum(new_code.data)) - code = new_code.data + if(isnum(new_code)) + code = new_code if(!signal) return 0 if(signal.encryption != code) @@ -292,8 +273,7 @@ if(signal.source == src) // Don't trigger ourselves. return 0 - var/datum/integrated_io/A = activators[2] - A.push_data() + activate_pin(3) for(var/mob/O in hearers(1, get_turf(src))) O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2) @@ -306,9 +286,9 @@ will pulse whatever's connected to it. Pulsing the first activation pin will send a message." icon_state = "signal" complexity = 4 - inputs = list("target EPv2 address", "data to send", "secondary text") - outputs = list("address received", "data received", "secondary text received") - activators = list("send data", "on data received") + inputs = list("\ target EPv2 address", "\ data to send", "\ secondary text") + outputs = list("\ address received", "\ data received", "\ secondary text received") + activators = list("\ send data", "\ on data received") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2) power_draw_per_use = 50 @@ -318,7 +298,7 @@ ..() exonet = new(src) exonet.make_address("EPv2_circuit-\ref[src]") - desc += "
This circuit's EPv2 address is: [exonet.address]." + desc += "
This circuit's EPv2 address is: [exonet.address]" /obj/item/integrated_circuit/input/EPv2/Destroy() if(exonet) @@ -327,64 +307,60 @@ ..() /obj/item/integrated_circuit/input/EPv2/do_work() - var/datum/integrated_io/target_address = inputs[1] - var/datum/integrated_io/message = inputs[2] - var/datum/integrated_io/text = inputs[3] - if(istext(target_address.data)) - exonet.send_message(target_address.data, message.data, text.data) + var/target_address = get_pin_data(IC_INPUT, 1) + var/message = get_pin_data(IC_INPUT, 2) + var/text = get_pin_data(IC_INPUT, 3) + + if(target_address && istext(target_address)) + exonet.send_message(target_address, message, text) /obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text) - var/datum/integrated_io/message_received = outputs[1] - var/datum/integrated_io/data_received = outputs[2] - var/datum/integrated_io/text_received = outputs[3] + set_pin_data(IC_OUTPUT, 1, origin_address) + set_pin_data(IC_OUTPUT, 2, message) + set_pin_data(IC_OUTPUT, 3, text) - var/datum/integrated_io/A = activators[2] - A.push_data() - - message_received.write_data_to_pin(origin_address) - data_received.write_data_to_pin(message) - text_received.write_data_to_pin(text) - - for(var/datum/integrated_io/output/O in outputs) - O.push_data() + push_data() + activate_pin(2) //This circuit gives information on where the machine is. /obj/item/integrated_circuit/input/gps name = "global positioning system" desc = "This allows you to easily know the position of a machine containing this device." + extended_desc = "The GPS's coordinates it gives is absolute, not relative." icon_state = "gps" complexity = 4 inputs = list() - outputs = list("X (abs)", "Y (abs)") - activators = list("get coordinates") + outputs = list("\ X", "\ Y") + activators = list("\ get coordinates", "\ on get coordinates") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 30 /obj/item/integrated_circuit/input/gps/do_work() var/turf/T = get_turf(src) - var/datum/integrated_io/result_x = outputs[1] - var/datum/integrated_io/result_y = outputs[2] - result_x.data = null - result_y.data = null + set_pin_data(IC_OUTPUT, 1, null) + set_pin_data(IC_OUTPUT, 2, null) if(!T) return - result_x.data = T.x - result_y.data = T.y + set_pin_data(IC_OUTPUT, 1, T.x) + set_pin_data(IC_OUTPUT, 2, T.y) - for(var/datum/integrated_io/output/O in outputs) - O.push_data() + push_data() + activate_pin(2) /obj/item/integrated_circuit/input/microphone name = "microphone" desc = "Useful for spying on people or for voice activated machines." + extended_desc = "This will automatically translate most languages it hears to Galactic Common. \ + The first activation pin is always pulsed when the circuit hears someone talk, while the second one \ + is only triggered if it hears someone speaking a language other than Galactic Common." icon_state = "recorder" complexity = 8 inputs = list() - outputs = list("speaker \", "message \") - activators = list("on message received") + outputs = list("\ speaker", "\ message") + activators = list("\ on message received", "\ on translation") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 15 @@ -397,42 +373,45 @@ ..() /obj/item/integrated_circuit/input/microphone/hear_talk(mob/living/M, msg, var/verb="says", datum/language/speaking=null) - var/datum/integrated_io/V = outputs[1] - var/datum/integrated_io/O = outputs[2] - var/datum/integrated_io/A = activators[1] + var/translated = FALSE if(M && msg) if(speaking) if(!speaking.machine_understands) msg = speaking.scramble(msg) - V.data = M.GetVoice() - O.data = msg - A.push_data() + if(!istype(speaking, /datum/language/common)) + translated = TRUE + set_pin_data(IC_OUTPUT, 1, M.GetVoice()) + set_pin_data(IC_OUTPUT, 2, msg) - for(var/datum/integrated_io/output/out in outputs) - out.push_data() - - A.push_data() + push_data() + activate_pin(1) + if(translated) + activate_pin(2) /obj/item/integrated_circuit/input/sensor name = "sensor" desc = "Scans and obtains a reference for any objects or persons near you. All you need to do is shove the machine in their face." + extended_desc = "If 'ignore storage' pin is set to 1, the sensor will disregard scanning various storage containers such as backpacks." icon_state = "recorder" complexity = 12 - inputs = list() - outputs = list("scanned ref \") - activators = list("on scanned") + inputs = list("\ ignore storage" = 1) + outputs = list("\ scanned") + activators = list("\ on scanned") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 120 -/obj/item/integrated_circuit/input/sensor/do_work() - // Because this gets called by attack(), all this needs to do is pulse the activator. - for(var/datum/integrated_io/output/O in outputs) - O.push_data() - var/datum/integrated_io/activate/A = activators[1] - A.push_data() +/obj/item/integrated_circuit/input/sensor/proc/scan(var/atom/A) + var/ignore_bags = get_pin_data(IC_INPUT, 1) + if(ignore_bags) + if(istype(A, /obj/item/weapon/storage)) + return FALSE + set_pin_data(IC_OUTPUT, 1, weakref(A)) + push_data() + activate_pin(1) + return TRUE /obj/item/integrated_circuit/output category_text = "Output" @@ -441,9 +420,9 @@ name = "small screen" desc = "This small screen can display a single piece of data, when the machine is examined closely." icon_state = "screen" - inputs = list("displayed data") + inputs = list("\ displayed data") outputs = list() - activators = list("load data") + activators = list("\ load data") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 10 autopulse = 1 @@ -497,7 +476,7 @@ complexity = 4 inputs = list() outputs = list() - activators = list("toggle light") + activators = list("\ toggle light") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH var/light_toggled = 0 var/light_brightness = 3 @@ -519,18 +498,18 @@ power_draw_idle = light_toggled ? light_brightness * 2 : 0 /obj/item/integrated_circuit/output/light/advanced/update_lighting() - var/datum/integrated_io/R = inputs[1] - var/datum/integrated_io/G = inputs[2] - var/datum/integrated_io/B = inputs[3] - var/datum/integrated_io/brightness = inputs[4] + var/R = get_pin_data(IC_INPUT, 1) + var/G = get_pin_data(IC_INPUT, 2) + var/B = get_pin_data(IC_INPUT, 3) + var/brightness = get_pin_data(IC_INPUT, 4) - if(isnum(R.data) && isnum(G.data) && isnum(B.data) && isnum(brightness.data)) - R.data = Clamp(R.data, 0, 255) - G.data = Clamp(G.data, 0, 255) - B.data = Clamp(B.data, 0, 255) - brightness.data = Clamp(brightness.data, 0, 6) - light_rgb = rgb(R.data, G.data, B.data) - light_brightness = brightness.data + if(isnum(R) && isnum(G) && isnum(B) && isnum(brightness)) + R = Clamp(R, 0, 255) + G = Clamp(G, 0, 255) + B = Clamp(B, 0, 255) + brightness = Clamp(brightness, 0, 6) + light_rgb = rgb(R, G, B) + light_brightness = brightness ..() @@ -544,10 +523,10 @@ icon_state = "light_adv" complexity = 8 inputs = list( - "R", - "G", - "B", - "Brightness" + "\ R", + "\ G", + "\ B", + "\ Brightness" ) outputs = list() spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -563,9 +542,9 @@ complexity = 8 cooldown_per_use = 4 SECONDS inputs = list( - "sound ID", - "volume", - "frequency" + "\ sound ID", + "\ volume", + "\ frequency" ) outputs = list() activators = list("play sound") diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm index beb44bf535..759b1586eb 100644 --- a/code/modules/integrated_electronics/subtypes/logic.dm +++ b/code/modules/integrated_electronics/subtypes/logic.dm @@ -4,7 +4,7 @@ extended_desc = "Logic circuits will treat a null, 0, and a \"\" string value as FALSE and anything else as TRUE." complexity = 3 outputs = list("result") - activators = list("compare", "on true result", "on false result") + activators = list("\ compare", "\ on true result", "\ on false result") category_text = "Logic" autopulse = 1 power_draw_per_use = 1 @@ -14,19 +14,17 @@ check_then_do_work() /obj/item/integrated_circuit/logic/do_work() - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/T = activators[2] - var/datum/integrated_io/F = activators[3] - O.push_data() - if(O.data) - T.push_data() + push_data() + if(get_pin_data(IC_INPUT, 1)) + activate_pin(1) else - F.push_data() + activate_pin(2) /obj/item/integrated_circuit/logic/binary - inputs = list("A","B") + inputs = list("\ A","\ B") /obj/item/integrated_circuit/logic/binary/do_work() + pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/O = outputs[1] @@ -37,9 +35,10 @@ return FALSE /obj/item/integrated_circuit/logic/unary - inputs = list("A") + inputs = list("\ A") /obj/item/integrated_circuit/logic/unary/do_work() + pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/O = outputs[1] O.data = do_check(A) ? TRUE : FALSE diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index 65bae751e0..4ee5145179 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -11,12 +11,12 @@ complexity = 20 w_class = ITEMSIZE_NORMAL inputs = list( - "target X rel", - "target Y rel" + "\ target X rel", + "\ target Y rel" ) outputs = list() activators = list( - "fire" + "\ fire" ) var/obj/item/weapon/gun/installed_gun = null spawn_flags = IC_SPAWN_RESEARCH diff --git a/code/modules/integrated_electronics/subtypes/power.dm b/code/modules/integrated_electronics/subtypes/power.dm index 7b3256e06b..3480a83a4a 100644 --- a/code/modules/integrated_electronics/subtypes/power.dm +++ b/code/modules/integrated_electronics/subtypes/power.dm @@ -11,9 +11,9 @@ some power is lost due to ineffiency." w_class = ITEMSIZE_SMALL complexity = 16 - inputs = list("target ref") - outputs = list("target cell charge", "target cell max charge", "target cell percentage") - activators = list("transmit") + inputs = list("\ target") + outputs = list("\ target cell charge", "\ target cell max charge", "\ target cell percentage") + activators = list("\ transmit") spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3) power_draw_per_use = 500 // Inefficency has to come from somewhere. diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index e4bd5c15a3..e3b69d31cd 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -43,39 +43,39 @@ flags = OPENCONTAINER complexity = 20 cooldown_per_use = 6 SECONDS - inputs = list("target ref", "injection amount" = 5) + inputs = list("\ target", "\ injection amount" = 5) outputs = list() - activators = list("inject") + activators = list("\ inject") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH volume = 30 power_draw_per_use = 15 /obj/item/integrated_circuit/reagent/injector/proc/inject_amount() - var/datum/integrated_io/amount = inputs[2] - if(isnum(amount.data)) - return Clamp(amount.data, 0, 30) + var/amount = get_pin_data(IC_INPUT, 2) + if(isnum(amount)) + return Clamp(amount, 0, 30) /obj/item/integrated_circuit/reagent/injector/do_work() set waitfor = 0 // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing - var/datum/integrated_io/target = inputs[1] - var/atom/movable/AM = target.data_as_type(/atom/movable) + var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) if(!istype(AM)) //Invalid input return if(!reagents.total_volume) // Empty return if(AM.can_be_injected_by(src)) if(isliving(AM)) + var/mob/living/L = AM var/turf/T = get_turf(AM) - T.visible_message("[src] is trying to inject [AM]!") + T.visible_message("[src] is trying to inject [L]!") sleep(3 SECONDS) - if(!AM.can_be_injected_by(src)) + if(!L.can_be_injected_by(src)) return var/contained = reagents.get_reagents() - var/trans = reagents.trans_to_mob(target, inject_amount(), CHEM_BLOOD) - log_debug("[src] injected \the [AM] with [trans]u of [contained].") //VOREStation Edit - I don't care THAT much. + var/trans = reagents.trans_to_mob(L, inject_amount(), CHEM_BLOOD) + message_admins("[src] injected \the [L] with [trans]u of [contained].") to_chat(AM, "You feel a tiny prick!") - visible_message("[src] injects [AM]!") + visible_message("[src] injects [L]!") else reagents.trans_to(AM, inject_amount()) @@ -88,9 +88,9 @@ outside the machine if it is next to the machine. Note that this cannot be used on entities." flags = OPENCONTAINER complexity = 8 - inputs = list("source ref", "target ref", "injection amount" = 10) + inputs = list("\ source", "\ target", "\ injection amount" = 10) outputs = list() - activators = list("transfer reagents") + activators = list("\ transfer reagents", "\ on transfer") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/transfer_amount = 10 @@ -103,10 +103,9 @@ transfer_amount = amount.data /obj/item/integrated_circuit/reagent/pump/do_work() - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/atom/movable/source = A.data_as_type(/atom/movable) - var/atom/movable/target = B.data_as_type(/atom/movable) + var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) + var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable) + if(!istype(source) || !istype(target)) //Invalid input return var/turf/T = get_turf(src) @@ -117,10 +116,11 @@ return if(!source.is_open_container() || !target.is_open_container()) return - if(!source.reagents.get_free_space() || !target.reagents.get_free_space()) + if(!target.reagents.get_free_space()) return source.reagents.trans_to(target, transfer_amount) + activate_pin(2) /obj/item/integrated_circuit/reagent/storage name = "reagent storage" diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index c159522e97..a90a3f57a3 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -8,17 +8,16 @@ cannot see the target, it will not be able to calculate the correct direction." icon_state = "numberpad" complexity = 25 - inputs = list("target ref") - outputs = list("dir") - activators = list("calculate dir") + inputs = list("\ target") + outputs = list("\ dir") + activators = list("\ calculate dir", "\ on calculated") spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5) power_draw_per_use = 40 /obj/item/integrated_circuit/smart/basic_pathfinder/do_work() var/datum/integrated_io/I = inputs[1] - var/datum/integrated_io/O = outputs[1] - O.data = null + set_pin_data(IC_OUTPUT, 1, null) if(!isweakref(I.data)) return @@ -28,6 +27,6 @@ if(!(A in view(get_turf(src)))) return // Can't see the target. var/desired_dir = get_dir(get_turf(src), A) - if(desired_dir) - O.data = desired_dir - O.push_data() \ No newline at end of file + + set_pin_data(IC_OUTPUT, 1, desired_dir) + push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/time.dm b/code/modules/integrated_electronics/subtypes/time.dm index 72766c0c48..322ee2f9e0 100644 --- a/code/modules/integrated_electronics/subtypes/time.dm +++ b/code/modules/integrated_electronics/subtypes/time.dm @@ -12,16 +12,15 @@ This circuit is set to send a pulse after a delay of two seconds." icon_state = "delay-20" var/delay = 2 SECONDS - activators = list("incoming pulse","outgoing pulse") + activators = list("\ incoming","\ outgoing") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 2 /obj/item/integrated_circuit/time/delay/do_work() set waitfor = 0 // Don't sleep in a proc that is called by a processor. It'll delay the entire thing - var/datum/integrated_io/out_pulse = activators[2] sleep(delay) - out_pulse.push_data() + activate_pin(2) /obj/item/integrated_circuit/time/delay/five_sec name = "five-sec delay circuit" @@ -60,14 +59,13 @@ desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ This circuit's delay can be customized, between 1/10th of a second to one hour. The delay is updated upon receiving a pulse." icon_state = "delay" - inputs = list("delay time") + inputs = list("\ delay time") spawn_flags = IC_SPAWN_RESEARCH /obj/item/integrated_circuit/time/delay/custom/do_work() - var/datum/integrated_io/delay_input = inputs[1] - if(delay_input.data && isnum(delay_input.data) ) - var/new_delay = min(delay_input.data, 1) - new_delay = max(new_delay, 36000) //An hour. + var/delay_input = get_pin_data(IC_INPUT, 1) + if(delay_input && isnum(delay_input) ) + var/new_delay = between(1, delay_input, 36000) //An hour. delay = new_delay ..() @@ -80,8 +78,8 @@ var/ticks_to_pulse = 4 var/ticks_completed = 0 var/is_running = FALSE - inputs = list("enable ticking") - activators = list("outgoing pulse") + inputs = list("\ enable ticking" = 0) + activators = list("\ outgoing pulse") spawn_flags = IC_SPAWN_RESEARCH power_draw_per_use = 4 @@ -91,8 +89,8 @@ . = ..() /obj/item/integrated_circuit/time/ticker/on_data_written() - var/datum/integrated_io/do_tick = inputs[1] - if(do_tick.data && !is_running) + var/do_tick = get_pin_data(IC_INPUT, 1) + if(do_tick && !is_running) is_running = TRUE processing_objects |= src else if(is_running) @@ -108,8 +106,7 @@ ticks_completed -= ticks_to_pulse else ticks_completed = 0 - var/datum/integrated_io/pulser = activators[1] - pulser.push_data() + activate_pin(1) /obj/item/integrated_circuit/time/ticker/fast name = "fast ticker" @@ -134,20 +131,16 @@ desc = "Tells you what the local time is, specific to your station or planet." icon_state = "clock" inputs = list() - outputs = list("time (string)", "hours (number)", "minutes (number)", "seconds (number)") + outputs = list("\ time", "\ hours", "\ minutes", "\ seconds") + activators = list("\ get time","\ on time got") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 /obj/item/integrated_circuit/time/clock/do_work() - var/datum/integrated_io/time = outputs[1] - var/datum/integrated_io/hour = outputs[2] - var/datum/integrated_io/min = outputs[3] - var/datum/integrated_io/sec = outputs[4] + set_pin_data(IC_OUTPUT, 1, time2text(station_time_in_ticks, "hh:mm:ss") ) + set_pin_data(IC_OUTPUT, 2, text2num(time2text(station_time_in_ticks, "hh") ) ) + set_pin_data(IC_OUTPUT, 3, text2num(time2text(station_time_in_ticks, "mm") ) ) + set_pin_data(IC_OUTPUT, 4, text2num(time2text(station_time_in_ticks, "ss") ) ) - time.data = time2text(station_time_in_ticks, "hh:mm:ss") - hour.data = text2num(time2text(station_time_in_ticks, "hh")) - min.data = text2num(time2text(station_time_in_ticks, "mm")) - sec.data = text2num(time2text(station_time_in_ticks, "ss")) - - for(var/datum/integrated_io/output/O in outputs) - O.push_data() \ No newline at end of file + push_data() + activate_pin(2) \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/trig.dm b/code/modules/integrated_electronics/subtypes/trig.dm index b1a19f4a40..72d779b621 100644 --- a/code/modules/integrated_electronics/subtypes/trig.dm +++ b/code/modules/integrated_electronics/subtypes/trig.dm @@ -1,9 +1,18 @@ //These circuits do not-so-simple math. /obj/item/integrated_circuit/trig complexity = 1 - inputs = list("A","B","C","D","E","F","G","H") - outputs = list("result") - activators = list("compute") + inputs = list( + "\ A", + "\ B", + "\ C", + "\ D", + "\ E", + "\ F", + "\ G", + "\ H" + ) + outputs = list("\ result") + activators = list("\ compute", "\ on computed") category_text = "Trig" extended_desc = "Input and output are in degrees." autopulse = 1 @@ -19,19 +28,19 @@ name = "sin circuit" desc = "Has nothing to do with evil, unless you consider trigonometry to be evil. Outputs the sine of A." icon_state = "sine" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/sine/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = sin(A.data) + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = sin(A) - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Cosine // @@ -39,19 +48,19 @@ name = "cos circuit" desc = "Outputs the cosine of A." icon_state = "cosine" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/cosine/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = cos(A.data) + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = cos(A) - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Tangent // @@ -59,19 +68,19 @@ name = "tan circuit" desc = "Outputs the tangent of A. Guaranteed to not go on a tangent about its existance." icon_state = "tangent" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/tangent/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = Tan(A.data) + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = Tan(A) - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Cosecant // @@ -79,19 +88,19 @@ name = "csc circuit" desc = "Outputs the cosecant of A." icon_state = "cosecant" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/cosecant/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = Csc(A.data) + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = Csc(A) - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Secant // @@ -100,19 +109,19 @@ name = "sec circuit" desc = "Outputs the secant of A. Has nothing to do with the security department." icon_state = "secant" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/secant/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = Sec(A.data) + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = Sec(A) - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Cotangent // @@ -121,16 +130,16 @@ name = "cot circuit" desc = "Outputs the cotangent of A." icon_state = "cotangent" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/cotangent/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = Cot(A.data) + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = Cot(A) - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() \ No newline at end of file + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) \ No newline at end of file diff --git a/code/modules/lore_codex/lore_data/species.dm b/code/modules/lore_codex/lore_data/species.dm index fa8c6d9615..54d72e0718 100644 --- a/code/modules/lore_codex/lore_data/species.dm +++ b/code/modules/lore_codex/lore_data/species.dm @@ -38,16 +38,11 @@ /datum/lore/codex/page/unathi name = "Unathi" - data = "The author wishes to apologize to the reader, as they currently lack enough knowledge of the Unathi to write about them, as they are \ - rather rare inside Vir." // Replace this when Anewbe finishes the lizard rewrite. - /* - data = "Raging in from Moghes, the Unathi are a race of tall, reptilian humanoids that possess both crocodile-like and serpent-like features. \ - They are a proud, warlike species that favors honor and strength, their home, Moghes, is a desert planet but was once believed to be full of life. \ - Of all the currently known sentient species, the Unathi are the most unequal in gender with females tending to be property of the males. Most Unathi \ - outside of Moghes tend to be exiles however, and with influence of other species the gender difference is not nearly as pronounced. Unathi were \ - humanity's second contact, and despite their aggressive nature, seem to get along well enough with humanity, though are often considered to be \ - 'second-class' citizens and are rarely seen in jobs other than where muscle is needed." // This probably needs to be updated. - */ + data = "The Unathi are a race of tall, reptilian humanoids that possess a blend of serpentine features reminiscent of crocodiles. \ + They are a proud, religious species that favors honor and strength, and originate from the desert planet of Moghes. \ + The Unathi follow a religious code known as the Unity, and they carry this with them on their travels. \ + Unathi once fought a serious war against SolGov, and as a result are often considered to be second-class citizens, \ + rarely seen in jobs that don't require a little muscle." /datum/lore/codex/page/tajaran name = "Tajaran" diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index 11f6021c75..68fb129108 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -10,6 +10,7 @@ recipes += new/datum/stack_recipe("[display_name] baseball bat", /obj/item/weapon/material/twohanded/baseballbat, 10, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]") recipes += new/datum/stack_recipe("[display_name] ashtray", /obj/item/weapon/material/ashtray, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") recipes += new/datum/stack_recipe("[display_name] spoon", /obj/item/weapon/material/kitchen/utensil/spoon/plastic, 1, on_floor = 1, supplied_material = "[name]") + recipes += new/datum/stack_recipe("[display_name] armor plate", /obj/item/weapon/material/armor_plating, 1, time = 20, on_floor = 1, supplied_material = "[name]") if(integrity>=50) recipes += new/datum/stack_recipe("[display_name] door", /obj/structure/simple_door, 10, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm index 66dde62a17..921b28d733 100644 --- a/code/modules/materials/materials.dm +++ b/code/modules/materials/materials.dm @@ -90,10 +90,12 @@ var/list/name_to_material var/ignition_point // K, point at which the material catches on fire. var/melting_point = 1800 // K, walls will take damage if they're next to a fire hotter than this var/integrity = 150 // General-use HP value for products. + var/protectiveness = 10 // How well this material works as armor. Higher numbers are better, diminishing returns applies. var/opacity = 1 // Is the material transparent? 0.5< makes transparent walls/doors. - var/reflectivity = 0 // How reflective to light is the material? Currently used for laser defense. + var/reflectivity = 0 // How reflective to light is the material? Currently used for laser reflection and defense. var/explosion_resistance = 5 // Only used by walls currently. var/conductive = 1 // Objects with this var add CONDUCTS to flags on spawn. + var/conductivity = null // How conductive the material is. Iron acts as the baseline, at 10. var/list/composite_material // If set, object matter var will be a list containing these values. // Placeholder vars for the time being, todo properly integrate windows/light tiles/rods. @@ -103,7 +105,7 @@ var/list/name_to_material var/list/window_options = list() // Damage values. - var/hardness = 60 // Prob of wall destruction by hulk, used for edge damage in weapons. + var/hardness = 60 // Prob of wall destruction by hulk, used for edge damage in weapons. Also used for bullet protection in armor. var/weight = 20 // Determines blunt damage/throwforce for weapons. // Noise when someone is faceplanted onto a table made of this material. @@ -236,6 +238,7 @@ var/list/name_to_material icon_colour = "#00FFE1" opacity = 0.4 reflectivity = 0.6 + conductivity = 1 shard_type = SHARD_SHARD tableslam_noise = 'sound/effects/Glasshit.ogg' hardness = 100 @@ -247,6 +250,7 @@ var/list/name_to_material icon_colour = "#EDD12F" weight = 24 hardness = 40 + conductivity = 41 stack_origin_tech = list(TECH_MATERIAL = 4) sheet_singular_name = "ingot" sheet_plural_name = "ingots" @@ -261,6 +265,7 @@ var/list/name_to_material icon_colour = "#D1E6E3" weight = 22 hardness = 50 + conductivity = 63 stack_origin_tech = list(TECH_MATERIAL = 3) sheet_singular_name = "ingot" sheet_plural_name = "ingots" @@ -304,6 +309,8 @@ var/list/name_to_material shard_type = SHARD_STONE_PIECE weight = 22 hardness = 55 + protectiveness = 5 // 20% + conductivity = 5 door_icon_base = "stone" sheet_singular_name = "brick" sheet_plural_name = "bricks" @@ -320,6 +327,8 @@ var/list/name_to_material name = DEFAULT_WALL_MATERIAL stack_type = /obj/item/stack/material/steel integrity = 150 + conductivity = 11 // Assuming this is carbon steel, it would actually be slightly less conductive than iron, but lets ignore that. + protectiveness = 10 // 33% icon_base = "solid" icon_reinf = "reinf_over" icon_colour = "#666666" @@ -355,6 +364,8 @@ var/list/name_to_material explosion_resistance = 25 hardness = 80 weight = 23 + protectiveness = 20 // 50% + conductivity = 13 // For the purposes of balance. stack_origin_tech = list(TECH_MATERIAL = 2) composite_material = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT, "platinum" = SHEET_MATERIAL_AMOUNT) //todo @@ -370,6 +381,7 @@ var/list/name_to_material explosion_resistance = 75 hardness = 100 weight = 28 + protectiveness = 60 // 75% reflectivity = 0.7 // Not a perfect mirror, but close. stack_origin_tech = list(TECH_MATERIAL = 8) composite_material = list("plasteel" = SHEET_MATERIAL_AMOUNT, "diamond" = SHEET_MATERIAL_AMOUNT) //shrug @@ -377,6 +389,7 @@ var/list/name_to_material /material/plasteel/titanium name = "titanium" stack_type = null + conductivity = 2.38 icon_base = "metal" door_icon_base = "metal" icon_colour = "#D1E6E3" @@ -393,6 +406,8 @@ var/list/name_to_material tableslam_noise = 'sound/effects/Glasshit.ogg' hardness = 30 weight = 15 + protectiveness = 0 // 0% + conductivity = 1 // Glass shards don't conduct. door_icon_base = "stone" destruction_desc = "shatters" window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 2) @@ -526,6 +541,8 @@ var/list/name_to_material icon_colour = "#CCCCCC" hardness = 10 weight = 12 + protectiveness = 5 // 20% + conductivity = 2 // For the sake of material armor diversity, we're gonna pretend this plastic is a good insulator. melting_point = T0C+371 //assuming heat resistant plastic stack_origin_tech = list(TECH_MATERIAL = 3) @@ -556,12 +573,14 @@ var/list/name_to_material stack_type = /obj/item/stack/material/mhydrogen icon_colour = "#E6C5DE" stack_origin_tech = list(TECH_MATERIAL = 6, TECH_POWER = 6, TECH_MAGNET = 5) + conductivity = 100 /material/platinum name = "platinum" stack_type = /obj/item/stack/material/platinum icon_colour = "#9999FF" weight = 27 + conductivity = 9.43 stack_origin_tech = list(TECH_MATERIAL = 2) sheet_singular_name = "ingot" sheet_plural_name = "ingots" @@ -571,6 +590,7 @@ var/list/name_to_material stack_type = /obj/item/stack/material/iron icon_colour = "#5C5454" weight = 22 + conductivity = 10 sheet_singular_name = "ingot" sheet_plural_name = "ingots" @@ -585,6 +605,7 @@ var/list/name_to_material explosion_resistance = 200 // Hull plating. hardness = 500 weight = 500 + protectiveness = 80 // 80% // Likewise. /material/alienalloy/elevatorium @@ -603,6 +624,8 @@ var/list/name_to_material shard_can_repair = 0 // you can't weld splinters back into planks hardness = 15 weight = 18 + protectiveness = 8 // 28% + conductivity = 1 melting_point = T0C+300 //okay, not melting in this case, but hot enough to destroy wood ignition_point = T0C+288 stack_origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 1) @@ -634,6 +657,7 @@ var/list/name_to_material icon_colour = "#AAAAAA" hardness = 1 weight = 1 + protectiveness = 0 // 0% ignition_point = T0C+232 //"the temperature at which book-paper catches fire, and burns." close enough melting_point = T0C+232 //temperature at which cardboard walls would be destroyed stack_origin_tech = list(TECH_MATERIAL = 1) @@ -650,6 +674,7 @@ var/list/name_to_material integrity = 1 hardness = 1 weight = 1 + protectiveness = 0 // 0% stack_origin_tech = list(TECH_MATERIAL = 1) melting_point = T0C+1 destruction_desc = "crumples" @@ -662,6 +687,7 @@ var/list/name_to_material door_icon_base = "wood" ignition_point = T0C+232 melting_point = T0C+300 + protectiveness = 1 // 4% flags = MATERIAL_PADDING /material/cult @@ -695,6 +721,7 @@ var/list/name_to_material flags = MATERIAL_PADDING ignition_point = T0C+300 melting_point = T0C+300 + protectiveness = 3 // 13% /material/carpet name = "carpet" @@ -706,6 +733,7 @@ var/list/name_to_material melting_point = T0C+300 sheet_singular_name = "tile" sheet_plural_name = "tiles" + protectiveness = 1 // 4% /material/cotton name = "cotton" @@ -714,7 +742,9 @@ var/list/name_to_material flags = MATERIAL_PADDING ignition_point = T0C+232 melting_point = T0C+300 + protectiveness = 1 // 4% +// This all needs to be OOP'd and use inheritence if its ever used in the future. /material/cloth_teal name = "teal" display_name ="teal" @@ -723,6 +753,7 @@ var/list/name_to_material flags = MATERIAL_PADDING ignition_point = T0C+232 melting_point = T0C+300 + protectiveness = 1 // 4% /material/cloth_black name = "black" @@ -732,6 +763,7 @@ var/list/name_to_material flags = MATERIAL_PADDING ignition_point = T0C+232 melting_point = T0C+300 + protectiveness = 1 // 4% /material/cloth_green name = "green" @@ -741,6 +773,7 @@ var/list/name_to_material flags = MATERIAL_PADDING ignition_point = T0C+232 melting_point = T0C+300 + protectiveness = 1 // 4% /material/cloth_puple name = "purple" @@ -750,6 +783,7 @@ var/list/name_to_material flags = MATERIAL_PADDING ignition_point = T0C+232 melting_point = T0C+300 + protectiveness = 1 // 4% /material/cloth_blue name = "blue" @@ -759,6 +793,7 @@ var/list/name_to_material flags = MATERIAL_PADDING ignition_point = T0C+232 melting_point = T0C+300 + protectiveness = 1 // 4% /material/cloth_beige name = "beige" @@ -768,6 +803,7 @@ var/list/name_to_material flags = MATERIAL_PADDING ignition_point = T0C+232 melting_point = T0C+300 + protectiveness = 1 // 4% /material/cloth_lime name = "lime" @@ -777,6 +813,7 @@ var/list/name_to_material flags = MATERIAL_PADDING ignition_point = T0C+232 melting_point = T0C+300 + protectiveness = 1 // 4% /material/toy_foam name = "foam" @@ -787,4 +824,5 @@ var/list/name_to_material melting_point = T0C+300 icon_colour = "#ff9900" hardness = 1 - weight = 1 \ No newline at end of file + weight = 1 + protectiveness = 0 // 0% \ No newline at end of file diff --git a/code/modules/mining/ore.dm b/code/modules/mining/ore.dm index 128dc17332..e531e5208f 100644 --- a/code/modules/mining/ore.dm +++ b/code/modules/mining/ore.dm @@ -37,7 +37,7 @@ var/mob/living/carbon/human/H = hit_atom if(istype(H) && H.has_eyes() && prob(85)) H << "Some of \the [src] gets in your eyes!" - H.eye_blind += 5 + H.Blind(5) H.eye_blurry += 10 spawn(1) if(istype(loc, /turf/)) qdel(src) diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm index 85942fcb4e..b1411f2fae 100644 --- a/code/modules/mob/language/station.dm +++ b/code/modules/mob/language/station.dm @@ -24,7 +24,7 @@ /datum/language/unathi name = LANGUAGE_UNATHI - desc = "The common language of Moghes, composed of sibilant hisses and rattles. Spoken natively by Unathi." + desc = "The common language of the Moghes Hegemony, composed of sibilant hisses and rattles. Spoken natively by Unathi." speech_verb = "hisses" ask_verb = "hisses" exclaim_verb = "roars" diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm index 8c61b68a3e..873934c0c7 100644 --- a/code/modules/mob/living/bot/bot.dm +++ b/code/modules/mob/living/bot/bot.dm @@ -70,10 +70,10 @@ /mob/living/bot/updatehealth() if(status_flags & GODMODE) - health = maxHealth + health = getMaxHealth() stat = CONSCIOUS else - health = maxHealth - getFireLoss() - getBruteLoss() + health = getMaxHealth() - getFireLoss() - getBruteLoss() oxyloss = 0 toxloss = 0 cloneloss = 0 @@ -104,9 +104,9 @@ user << "You need to unlock the controls first." return else if(istype(O, /obj/item/weapon/weldingtool)) - if(health < maxHealth) + if(health < getMaxHealth()) if(open) - health = min(maxHealth, health + 10) + health = min(getMaxHealth(), health + 10) user.visible_message("[user] repairs [src].","You repair [src].") else user << "Unable to repair with the maintenance panel closed." @@ -224,7 +224,7 @@ /mob/living/bot/proc/getPatrolTurf() var/minDist = INFINITY var/obj/machinery/navbeacon/targ = locate() in get_turf(src) - + if(!targ) for(var/obj/machinery/navbeacon/N in navbeacons) if(!N.codes["patrol"]) diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index a7764d3d1d..fd48b912a0 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -73,11 +73,11 @@ // Eyes and blindness. if(!has_eyes()) - eye_blind = 1 + SetBlinded(1) blinded = 1 eye_blurry = 1 else if(eye_blind) - eye_blind = max(eye_blind-1,0) + AdjustBlinded(-1) blinded = 1 else if(eye_blurry) eye_blurry = max(eye_blurry-1, 0) diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 3f41f21ce5..bac50b1e62 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -76,7 +76,7 @@ if(ingested) ingested.metabolize() if(bloodstr) bloodstr.metabolize() - confused = max(0, confused - 1) + AdjustConfused(-1) // decrement dizziness counter, clamped to 0 if(resting) dizziness = max(0, dizziness - 5) @@ -110,7 +110,7 @@ if(31 to INFINITY) emp_damage = 30//Let's not overdo it if(21 to 30)//High level of EMP damage, unable to see, hear, or speak - eye_blind = 1 + SetBlinded(1) blinded = 1 ear_deaf = 1 silent = 1 @@ -123,7 +123,7 @@ if(20) alert = 0 blinded = 0 - eye_blind = 0 + SetBlinded(0) ear_deaf = 0 silent = 0 emp_damage -= 1 diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm index 6370380b29..58c26a56e2 100644 --- a/code/modules/mob/living/carbon/give.dm +++ b/code/modules/mob/living/carbon/give.dm @@ -1,11 +1,11 @@ -/mob/living/carbon/human/verb/give(var/mob/living/target in view(1)-usr) +/mob/living/carbon/human/verb/give(var/mob/living/carbon/target in view(1)-usr) set category = "IC" set name = "Give" // TODO : Change to incapacitated() on merge. - if(src.stat || src.lying || src.resting || src.buckled) + if(src.stat || src.lying || src.resting || src.handcuffed) return - if(!istype(target) || target.stat || target.lying || target.resting || target.buckled || target.client == null) + if(!istype(target) || target.stat || target.lying || target.resting || target.handcuffed || target.client == null) return var/obj/item/I = src.get_active_hand() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index de58677c81..e6865ef51e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -94,6 +94,7 @@ if(mind.changeling) stat("Chemical Storage", mind.changeling.chem_charges) stat("Genetic Damage Time", mind.changeling.geneticdamage) + stat("Re-Adaptations", "[mind.changeling.readapts]/[mind.changeling.max_readapts]") /mob/living/carbon/human/ex_act(severity) if(!blinded) @@ -1518,3 +1519,11 @@ /mob/living/carbon/human/is_muzzled() return (wear_mask && (istype(wear_mask, /obj/item/clothing/mask/muzzle) || istype(src.wear_mask, /obj/item/weapon/grenade))) +// Called by job_controller. Makes drones start with a permit, might be useful for other people later too. +/mob/living/carbon/human/equip_post_job() + var/braintype = get_FBP_type() + if(braintype == FBP_DRONE) + var/turf/T = get_turf(src) + var/obj/item/weapon/permit/drone/permit = new(T) + permit.set_name(real_name) + equip_to_appropriate_slot(permit) // If for some reason it can't find room, it'll still be on the floor. \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index fa3d19ebab..02d85bbcfa 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -2,7 +2,7 @@ /mob/living/carbon/human/updatehealth() if(status_flags & GODMODE) - health = maxHealth + health = getMaxHealth() stat = CONSCIOUS return @@ -14,10 +14,10 @@ total_brute += O.brute_dam total_burn += O.burn_dam - health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute + health = getMaxHealth() - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute //TODO: fix husking - if( ((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD) + if( ((getMaxHealth() - total_burn) < config.health_threshold_dead) && stat == DEAD) ChangeToHusk() return @@ -42,7 +42,7 @@ if(should_have_organ("brain")) var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"] if(sponge) - sponge.damage = min(max(amount, 0),(maxHealth*2)) + sponge.damage = min(max(amount, 0),(getMaxHealth()*2)) brainloss = sponge.damage else brainloss = 200 @@ -56,7 +56,7 @@ if(should_have_organ("brain")) var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"] if(sponge) - brainloss = min(sponge.damage,maxHealth*2) + brainloss = min(sponge.damage,getMaxHealth()*2) else brainloss = 200 else @@ -99,16 +99,32 @@ /mob/living/carbon/human/adjustBruteLoss(var/amount) amount = amount*species.brute_mod if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + amount *= M.incoming_damage_percent + if(!isnull(M.incoming_brute_damage_percent)) + amount *= M.incoming_brute_damage_percent take_overall_damage(amount, 0) else + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_healing_percent)) + amount *= M.incoming_healing_percent heal_overall_damage(-amount, 0) BITSET(hud_updateflag, HEALTH_HUD) /mob/living/carbon/human/adjustFireLoss(var/amount) amount = amount*species.burn_mod if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + amount *= M.incoming_damage_percent + if(!isnull(M.incoming_fire_damage_percent)) + amount *= M.incoming_fire_damage_percent take_overall_damage(0, amount) else + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_healing_percent)) + amount *= M.incoming_healing_percent heal_overall_damage(0, -amount) BITSET(hud_updateflag, HEALTH_HUD) @@ -118,8 +134,16 @@ var/obj/item/organ/external/O = get_organ(organ_name) if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + amount *= M.incoming_damage_percent + if(!isnull(M.incoming_brute_damage_percent)) + amount *= M.incoming_brute_damage_percent O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source) else + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_healing_percent)) + amount *= M.incoming_healing_percent //if you don't want to heal robot organs, they you will have to check that yourself before using this proc. O.heal_damage(-amount, 0, internal=0, robo_repair=(O.robotic >= ORGAN_ROBOT)) @@ -131,8 +155,16 @@ var/obj/item/organ/external/O = get_organ(organ_name) if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + amount *= M.incoming_damage_percent + if(!isnull(M.incoming_fire_damage_percent)) + amount *= M.incoming_fire_damage_percent O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source) else + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_healing_percent)) + amount *= M.incoming_healing_percent //if you don't want to heal robot organs, they you will have to check that yourself before using this proc. O.heal_damage(0, -amount, internal=0, robo_repair=(O.robotic >= ORGAN_ROBOT)) @@ -400,11 +432,25 @@ This function restores all organs. if(BRUTE) damageoverlaytemp = 20 damage = damage*species.brute_mod + + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + damage *= M.incoming_damage_percent + if(!isnull(M.incoming_brute_damage_percent)) + damage *= M.incoming_brute_damage_percent + if(organ.take_damage(damage, 0, sharp, edge, used_weapon)) UpdateDamageIcon() if(BURN) damageoverlaytemp = 20 damage = damage*species.burn_mod + + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + damage *= M.incoming_damage_percent + if(!isnull(M.incoming_brute_damage_percent)) + damage *= M.incoming_fire_damage_percent + if(organ.take_damage(0, damage, sharp, edge, used_weapon)) UpdateDamageIcon() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 86bbdebc15..61b13316b8 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -27,6 +27,11 @@ emp_act if(!P.nodamage) organ.add_autopsy_data("[P.name]", P.damage) + // Tell clothing we're wearing that it got hit by a bullet/laser/etc + var/list/clothing = get_clothing_list_organ(organ) + for(var/obj/item/clothing/C in clothing) + C.clothing_impact(P, P.damage) + //Shrapnel if(P.can_embed()) var/armor = getarmor_organ(organ, "bullet") @@ -130,6 +135,15 @@ emp_act return siemens_coefficient +// Returns a list of clothing that is currently covering def_zone. +/mob/living/carbon/human/proc/get_clothing_list_organ(var/obj/item/organ/external/def_zone, var/type) + var/list/results = list() + var/list/clothing_items = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) + for(var/obj/item/clothing/C in clothing_items) + if(istype(C) && (C.body_parts_covered & def_zone.body_part)) + results.Add(C) + return results + //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 @@ -231,10 +245,6 @@ emp_act var/soaked = get_armor_soak(hit_zone, "melee", I.armor_penetration) - if(soaked >= effective_force) - src << "Your armor absorbs the force of [I.name]!" - return - var/blocked = run_armor_check(hit_zone, "melee", I.armor_penetration, "Your armor has protected your [affecting.name].", "Your armor has softened the blow to your [affecting.name].") standard_weapon_hit_effects(I, user, effective_force, blocked, soaked, hit_zone) @@ -246,9 +256,14 @@ emp_act if(!affecting) return 0 - if(soaked >= effective_force) - return 0 + // Allow clothing to respond to being hit. + // This is done up here so that clothing damage occurs even if fully blocked. + var/list/clothing = get_clothing_list_organ(affecting) + for(var/obj/item/clothing/C in clothing) + C.clothing_impact(I, effective_force) + if(soaked >= round(effective_force*0.8)) + effective_force -= round(effective_force*0.8) // Handle striking to cripple. if(user.a_intent == I_DISARM) effective_force *= 0.5 //reduced effective force... @@ -309,12 +324,15 @@ emp_act return 1 /mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/effective_force, var/dislocate_mult, var/blocked, var/soaked) - if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100 || soaked > effective_force) + if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100) return 0 if(W.damtype != BRUTE) return 0 + if(soaked >= round(effective_force*0.8)) + effective_force -= round(effective_force*0.8) + //want the dislocation chance to be such that the limb is expected to dislocate after dealing a fraction of the damage needed to break the limb var/dislocate_chance = effective_force/(dislocate_mult * organ.min_broken_damage * config.organ_health_multiplier)*100 if(prob(dislocate_chance * (100 - blocked)/100)) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 34f5f44015..5e35d29599 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -95,3 +95,5 @@ mob_swap_flags = ~HEAVY var/identifying_gender // In case the human identifies as another gender than it's biological + + var/step_count = 0 // Track how many footsteps have been taken to know when to play footstep sounds diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 7682f675b0..cb49001d3c 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -90,6 +90,24 @@ return 0 +// Returns a string based on what kind of brain the FBP has. +/mob/living/carbon/human/proc/get_FBP_type() + if(!isSynthetic()) + return FBP_NONE + var/obj/item/organ/internal/brain/B + B = internal_organs_by_name[O_BRAIN] + if(B) // Incase we lost our brain for some reason, like if we got decapped. + if(istype(B, /obj/item/organ/internal/mmi_holder)) + var/obj/item/organ/internal/mmi_holder/mmi_holder = B + if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi/digital/posibrain)) + return FBP_POSI + else if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi/digital/robot)) + return FBP_DRONE + else if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi)) // This needs to come last because inheritence. + return FBP_CYBORG + + return FBP_NONE + #undef HUMAN_EATING_NO_ISSUE #undef HUMAN_EATING_NO_MOUTH #undef HUMAN_EATING_BLOCKED_MOUTH diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index aa4dd28c3b..29289d34b6 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -15,7 +15,11 @@ if(force_max_speed) return -3 // Returning -1 will actually result in a slowdown for Teshari. - var/health_deficiency = (maxHealth - health) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.slowdown)) + tally += M.slowdown + + var/health_deficiency = (getMaxHealth() - health) if(health_deficiency >= 40) tally += (health_deficiency / 25) if(can_feel_pain()) @@ -146,3 +150,36 @@ prob_slip = round(prob_slip) return(prob_slip) + +// Handle footstep sounds +/mob/living/carbon/human/handle_footstep(var/turf/T) + if(!config.footstep_volume || !T.footstep_sounds || !T.footstep_sounds.len) + return + // Future Upgrades - Multi species support + var/list/footstep_sounds = T.footstep_sounds["human"] + if(!footstep_sounds) + return + + var/S = pick(footstep_sounds) + if(!S) return + + // Only play every other step while running + if(m_intent == "run" && step_count++ % 2 == 0) + return + + var/volume = config.footstep_volume + // Reduce volume while walking or barefoot + if(!shoes || m_intent != "run") + volume *= 0.5 + + if(!has_organ(BP_L_FOOT) && !has_organ(BP_R_FOOT)) + return // no feet = no footsteps + + if(buckled || lying || throwing) + return // people flying, lying down or sitting do not step + + if(!has_gravity(src) && prob(75)) + return // Far less likely to make noise in no gravity + + playsound(T, S, volume, FALSE) + return diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index a44b1e8351..3ae084dc4f 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -971,18 +971,18 @@ vision = internal_organs_by_name[species.vision_organ] if(!species.vision_organ) // Presumably if a species has no vision organs, they see via some other means. - eye_blind = 0 + SetBlinded(0) blinded = 0 eye_blurry = 0 else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind. - eye_blind = 1 + SetBlinded(1) blinded = 1 eye_blurry = 1 else //You have the requisite organs if(sdisabilities & BLIND) // Disabled-blind, doesn't get better on its own blinded = 1 else if(eye_blind) // Blindness, heals slowly over time - eye_blind = max(eye_blind-1,0) + AdjustBlinded(-1) blinded = 1 else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster eye_blurry = max(eye_blurry-3, 0) @@ -1542,7 +1542,7 @@ if(stat == DEAD) holder.icon_state = "-100" // X_X else - holder.icon_state = RoundHealth((health-config.health_threshold_crit)/(maxHealth-config.health_threshold_crit)*100) + holder.icon_state = RoundHealth((health-config.health_threshold_crit)/(getMaxHealth()-config.health_threshold_crit)*100) hud_list[HEALTH_HUD] = holder if (BITTEST(hud_updateflag, LIFE_HUD)) 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 7a0181b167..07876d1985 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -36,6 +36,8 @@ slowdown = 0.5 brute_mod = 0.9 burn_mod = 0.9 + metabolic_rate = 0.85 + item_slowdown_halved = 1 num_alternate_languages = 3 secondary_langs = list(LANGUAGE_UNATHI) name_language = LANGUAGE_UNATHI @@ -62,11 +64,36 @@ appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR flesh_color = "#34AF10" - - //reagent_tag = IS_UNATHI //VOREStation Removal + blood_color = "#b3cbc3" base_color = "#066000" - //heat_discomfort_level = 295 //VOREStation Removal + //reagent_tag = IS_UNATHI //VOREStation Edit + + has_limbs = list( + BP_TORSO = list("path" = /obj/item/organ/external/chest/unathi), + BP_GROIN = list("path" = /obj/item/organ/external/groin/unathi), + BP_HEAD = list("path" = /obj/item/organ/external/head/unathi), + BP_L_ARM = list("path" = /obj/item/organ/external/arm), + BP_R_ARM = list("path" = /obj/item/organ/external/arm/right), + BP_L_LEG = list("path" = /obj/item/organ/external/leg), + BP_R_LEG = list("path" = /obj/item/organ/external/leg/right), + BP_L_HAND = list("path" = /obj/item/organ/external/hand), + BP_R_HAND = list("path" = /obj/item/organ/external/hand/right), + BP_L_FOOT = list("path" = /obj/item/organ/external/foot), + BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right) + ) + + //No kidneys or appendix + has_organ = list( + O_HEART = /obj/item/organ/internal/heart/unathi, + O_LUNGS = /obj/item/organ/internal/lungs/unathi, + O_LIVER = /obj/item/organ/internal/liver/unathi, + O_BRAIN = /obj/item/organ/internal/brain/unathi, + O_EYES = /obj/item/organ/internal/eyes, + ) + + + //heat_discomfort_level = 295 //VOREStation Edit heat_discomfort_strings = list( "You feel soothingly warm.", "You feel the heat sink into your bones.", diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index 7bbc4110dd..0f393a9417 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -80,7 +80,7 @@ src.blinded = null - health = maxHealth - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) + health = getMaxHealth() - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) if(health < 0 && stat != DEAD) death() @@ -118,7 +118,7 @@ if (src.stuttering) src.stuttering = 0 if (src.eye_blind) - src.eye_blind = 0 + SetBlinded(0) src.blinded = 1 if (src.ear_deaf > 0) src.ear_deaf = 0 diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index 3c0bfbdbad..5fdea4a0e6 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -81,7 +81,7 @@ var/tally = 0 - var/health_deficiency = (maxHealth - health) + var/health_deficiency = (getMaxHealth() - health) if(health_deficiency >= 30) tally += (health_deficiency / 25) if (bodytemperature < 183.222) @@ -146,7 +146,7 @@ ..() statpanel("Status") - stat(null, "Health: [round((health / maxHealth) * 100)]%") + stat(null, "Health: [round((health / getMaxHealth()) * 100)]%") stat(null, "Intent: [a_intent]") if (client.statpanel == "Status") diff --git a/code/modules/mob/living/carbon/metroid/powers.dm b/code/modules/mob/living/carbon/metroid/powers.dm index 933596ef5e..9e20d49a44 100644 --- a/code/modules/mob/living/carbon/metroid/powers.dm +++ b/code/modules/mob/living/carbon/metroid/powers.dm @@ -21,7 +21,7 @@ return "I cannot feed on other slimes..." if (!Adjacent(M)) return "This subject is too far away..." - if (istype(M, /mob/living/carbon) && M.getCloneLoss() >= M.maxHealth * 1.5 || istype(M, /mob/living/simple_animal) && M.stat == DEAD) + if (istype(M, /mob/living/carbon) && M.getCloneLoss() >= M.getMaxHealth() * 1.5 || istype(M, /mob/living/simple_animal) && M.stat == DEAD) return "This subject does not have an edible life energy..." for(var/mob/living/carbon/slime/met in view()) if(met.Victim == M && met != src) diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 552319e6fe..0fa139c36f 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -11,10 +11,13 @@ /mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/soaked = 0, var/used_weapon = null, var/sharp = 0, var/edge = 0) if(Debug2) world.log << "## DEBUG: apply_damage() was called on [src], with [damage] damage, and an armor value of [blocked]." - if(!damage || (blocked >= 100) || soaked >= damage) + if(!damage || (blocked >= 100)) return 0 if(soaked) - damage -= soaked + if(soaked >= round(damage*0.8)) + damage -= round(damage*0.8) + else + damage -= soaked blocked = (100-blocked)/100 switch(damagetype) if(BRUTE) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 3e707b7c4c..c24f5b7236 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -10,6 +10,8 @@ return var/datum/gas_mixture/environment = loc.return_air() + handle_modifiers() // Do this early since it might affect other things later. + if(stat != DEAD) //Breathing, if applicable handle_breathing() @@ -150,9 +152,9 @@ /mob/living/proc/handle_disabilities() //Eyes if(sdisabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own - eye_blind = max(eye_blind, 1) + SetBlinded(1) else if(eye_blind) //blindness, heals slowly over time - eye_blind = max(eye_blind-1,0) + AdjustBlinded(-1) else if(eye_blurry) //blurry eyes heal slowly eye_blurry = max(eye_blurry-1, 0) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index a077319edc..dafeb2d37d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -163,9 +163,9 @@ default behaviour is: /mob/living/verb/succumb() set hidden = 1 - if ((src.health < 0 && src.health > (5-src.maxHealth))) // Health below Zero but above 5-away-from-death, as before, but variable - src.adjustOxyLoss(src.health + src.maxHealth * 2) // Deal 2x health in OxyLoss damage, as before but variable. - src.health = src.maxHealth - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss() + if ((src.health < 0 && src.health > (5-src.getMaxHealth()))) // Health below Zero but above 5-away-from-death, as before, but variable + src.adjustOxyLoss(src.health + src.getMaxHealth() * 2) // Deal 2x health in OxyLoss damage, as before but variable. + src.health = src.getMaxHealth() - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss() src << "\blue You have given up life and succumbed to death." @@ -174,7 +174,7 @@ default behaviour is: health = 100 stat = CONSCIOUS else - health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() - halloss + health = getMaxHealth() - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() - halloss //This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually @@ -236,14 +236,38 @@ default behaviour is: /mob/living/proc/adjustBruteLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode - bruteloss = min(max(bruteloss + amount, 0),(maxHealth*2)) + + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + amount *= M.incoming_damage_percent + if(!isnull(M.incoming_brute_damage_percent)) + amount *= M.incoming_brute_damage_percent + else if(amount < 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_healing_percent)) + amount *= M.incoming_healing_percent + + bruteloss = min(max(bruteloss + amount, 0),(getMaxHealth()*2)) /mob/living/proc/getOxyLoss() return oxyloss /mob/living/proc/adjustOxyLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode - oxyloss = min(max(oxyloss + amount, 0),(maxHealth*2)) + + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + amount *= M.incoming_damage_percent + if(!isnull(M.incoming_oxy_damage_percent)) + amount *= M.incoming_oxy_damage_percent + else if(amount < 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_healing_percent)) + amount *= M.incoming_healing_percent + + oxyloss = min(max(oxyloss + amount, 0),(getMaxHealth()*2)) /mob/living/proc/setOxyLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode @@ -254,7 +278,19 @@ default behaviour is: /mob/living/proc/adjustToxLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode - toxloss = min(max(toxloss + amount, 0),(maxHealth*2)) + + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + amount *= M.incoming_damage_percent + if(!isnull(M.incoming_tox_damage_percent)) + amount *= M.incoming_tox_damage_percent + else if(amount < 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_healing_percent)) + amount *= M.incoming_healing_percent + + toxloss = min(max(toxloss + amount, 0),(getMaxHealth()*2)) /mob/living/proc/setToxLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode @@ -268,14 +304,37 @@ default behaviour is: /mob/living/proc/adjustFireLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode - fireloss = min(max(fireloss + amount, 0),(maxHealth*2)) + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + amount *= M.incoming_damage_percent + if(!isnull(M.incoming_fire_damage_percent)) + amount *= M.incoming_fire_damage_percent + else if(amount < 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_healing_percent)) + amount *= M.incoming_healing_percent + + fireloss = min(max(fireloss + amount, 0),(getMaxHealth()*2)) /mob/living/proc/getCloneLoss() return cloneloss /mob/living/proc/adjustCloneLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode - cloneloss = min(max(cloneloss + amount, 0),(maxHealth*2)) + + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + amount *= M.incoming_damage_percent + if(!isnull(M.incoming_clone_damage_percent)) + amount *= M.incoming_clone_damage_percent + else if(amount < 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_healing_percent)) + amount *= M.incoming_healing_percent + + cloneloss = min(max(cloneloss + amount, 0),(getMaxHealth()*2)) /mob/living/proc/setCloneLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode @@ -286,7 +345,7 @@ default behaviour is: /mob/living/proc/adjustBrainLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode - brainloss = min(max(brainloss + amount, 0),(maxHealth*2)) + brainloss = min(max(brainloss + amount, 0),(getMaxHealth()*2)) /mob/living/proc/setBrainLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode @@ -297,18 +356,117 @@ default behaviour is: /mob/living/proc/adjustHalLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode - halloss = min(max(halloss + amount, 0),(maxHealth*2)) + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_damage_percent)) + amount *= M.incoming_damage_percent + if(!isnull(M.incoming_hal_damage_percent)) + amount *= M.incoming_hal_damage_percent + if(!isnull(M.disable_duration_percent)) + amount *= M.incoming_hal_damage_percent + else if(amount < 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.incoming_healing_percent)) + amount *= M.incoming_healing_percent + halloss = min(max(halloss + amount, 0),(getMaxHealth()*2)) /mob/living/proc/setHalLoss(var/amount) if(status_flags & GODMODE) return 0 //godmode halloss = amount +// Use this to get a mob's max health whenever possible. Reading maxHealth directly will give inaccurate results if any modifiers exist. /mob/living/proc/getMaxHealth() - return maxHealth + var/result = maxHealth + for(var/datum/modifier/M in modifiers) + if(!isnull(M.max_health_flat)) + result += M.max_health_flat + // Second loop is so we can get all the flat adjustments first before multiplying, otherwise the result will be different. + for(var/datum/modifier/M in modifiers) + if(!isnull(M.max_health_percent)) + result *= M.max_health_percent + return result /mob/living/proc/setMaxHealth(var/newMaxHealth) maxHealth = newMaxHealth +/mob/living/Stun(amount) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + +/mob/living/AdjustStunned(amount) + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + +/mob/living/Weaken(amount) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + +/mob/living/AdjustWeakened(amount) + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + +/mob/living/Paralyse(amount) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + +/mob/living/AdjustParalysis(amount) + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + +/mob/living/Sleeping(amount) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + +/mob/living/AdjustSleeping(amount) + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + +/mob/living/Confuse(amount) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + +/mob/living/AdjustConfused(amount) + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + +/mob/living/Blind(amount) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + +/mob/living/AdjustBlinded(amount) + if(amount > 0) + for(var/datum/modifier/M in modifiers) + if(!isnull(M.disable_duration_percent)) + amount = round(amount * M.disable_duration_percent) + ..(amount) + // ++++ROCKDTBEN++++ MOB PROCS //END /mob/proc/get_contents() @@ -446,7 +604,7 @@ default behaviour is: // fix blindness and deafness blinded = 0 - eye_blind = 0 + SetBlinded(0) eye_blurry = 0 ear_deaf = 0 ear_damage = 0 @@ -585,6 +743,9 @@ default behaviour is: for(var/mob/living/carbon/slime/M in view(1,src)) M.UpdateFeed(src) +/mob/living/proc/handle_footstep(turf/T) + return FALSE + /mob/living/verb/resist() set name = "Resist" set category = "IC" @@ -821,3 +982,7 @@ default behaviour is: if(isSynthetic()) return FALSE return TRUE + +// Called by job_controller. +/mob/living/proc/equip_post_job() + return diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 8a49ed8922..b60ff078a3 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -107,6 +107,11 @@ var/absorb = run_armor_check(def_zone, P.check_armour, P.armor_penetration) var/proj_sharp = is_sharp(P) var/proj_edge = has_edge(P) + + if ((proj_sharp || proj_edge) && (soaked >= round(P.damage*0.8))) + proj_sharp = 0 + proj_edge = 0 + if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.check_armour))) proj_sharp = 0 proj_edge = 0 @@ -167,13 +172,11 @@ var/soaked = get_armor_soak(hit_zone, "melee") var/blocked = run_armor_check(hit_zone, "melee") - //If the armor absorbs all of the damage, skip the damage calculation and the blood - if(!(soaked > effective_force)) - standard_weapon_hit_effects(I, user, effective_force, blocked, soaked, hit_zone) + standard_weapon_hit_effects(I, user, effective_force, blocked, soaked, hit_zone) - if(I.damtype == BRUTE && prob(33)) // Added blood for whacking non-humans too - var/turf/simulated/location = get_turf(src) - if(istype(location)) location.add_blood_floor(src) + if(I.damtype == BRUTE && prob(33)) // Added blood for whacking non-humans too + var/turf/simulated/location = get_turf(src) + if(istype(location)) location.add_blood_floor(src) return blocked @@ -186,13 +189,14 @@ if(HULK in user.mutations) effective_force *= 2 - //Armor soak - if(soaked >= effective_force) - return 0 - //Apply weapon damage var/weapon_sharp = is_sharp(I) var/weapon_edge = has_edge(I) + + if(getsoak(hit_zone, "melee",) - (I.armor_penetration/5) > round(effective_force*0.8)) //soaking a hit turns sharp attacks into blunt ones + weapon_sharp = 0 + weapon_edge = 0 + if(prob(max(getarmor(hit_zone, "melee") - I.armor_penetration, 0))) //melee armour provides a chance to turn sharp/edge weapon attacks into blunt ones weapon_sharp = 0 weapon_edge = 0 @@ -251,7 +255,7 @@ if(!O || !src) return if(O.sharp) //Projectile is suitable for pinning. - if(soaked >= throw_damage) //Don't embed if it didn't actually damage + if(soaked >= round(throw_damage*0.8)) return //Handles embedding for non-humans and simple_animals. diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index e6b7f2979d..d8913e7b5b 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -2,7 +2,7 @@ see_invisible = SEE_INVISIBLE_LIVING //Health and life related vars - var/maxHealth = 100 //Maximum health that should be possible. + var/maxHealth = 100 //Maximum health that should be possible. Avoid adjusting this if you can, and instead use modifiers datums. var/health = 100 //A mob's health var/hud_updateflag = 0 diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm index 349f27114b..8c12226e3d 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm @@ -1,7 +1,6 @@ /obj/machinery/computer/drone_control name = "Maintenance Drone Control" desc = "Used to monitor the station's drone population and the assembler that services them." - icon = 'icons/obj/computer.dmi' icon_keyboard = "power_key" icon_screen = "power" req_access = list(access_engine_equip) diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 9dacf9924c..a9464c595e 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -98,7 +98,7 @@ else //Not stunned. src.stat = 0 - confused = max(0, confused - 1) + AdjustConfused(-1) else //Dead. src.blinded = 1 @@ -107,7 +107,7 @@ if (src.stuttering) src.stuttering-- if (src.eye_blind) - src.eye_blind-- + src.AdjustBlinded(-1) src.blinded = 1 if (src.ear_deaf > 0) src.ear_deaf-- diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm index 1b051e029f..58a81ca7a7 100644 --- a/code/modules/mob/living/silicon/robot/robot_damage.dm +++ b/code/modules/mob/living/silicon/robot/robot_damage.dm @@ -1,9 +1,9 @@ /mob/living/silicon/robot/updatehealth() if(status_flags & GODMODE) - health = maxHealth + health = getMaxHealth() stat = CONSCIOUS return - health = maxHealth - (getBruteLoss() + getFireLoss()) + health = getMaxHealth() - (getBruteLoss() + getFireLoss()) return /mob/living/silicon/robot/getBruteLoss() diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 738e996967..40b1852528 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -63,16 +63,16 @@ switch(severity) if(1) src.take_organ_damage(0,20,emp=1) - confused = (min(confused + 5, 30)) + Confuse(5) if(2) src.take_organ_damage(0,15,emp=1) - confused = (min(confused + 4, 30)) + Confuse(4) if(3) src.take_organ_damage(0,10,emp=1) - confused = (min(confused + 3, 30)) + Confuse(3) if(4) src.take_organ_damage(0,5,emp=1) - confused = (min(confused + 2, 30)) + Confuse(2) flash_eyes(affect_silicon = 1) src << "*BZZZT*" src << "Warning: Electromagnetic pulse detected." @@ -148,7 +148,7 @@ // this function shows the health of the AI in the Status panel /mob/living/silicon/proc/show_system_integrity() if(!src.stat) - stat(null, text("System integrity: [round((health/maxHealth)*100)]%")) + stat(null, text("System integrity: [round((health/getMaxHealth())*100)]%")) else stat(null, text("Systems nonfunctional")) diff --git a/code/modules/mob/living/simple_animal/aliens/drone.dm b/code/modules/mob/living/simple_animal/aliens/drone.dm index 3d1ae1bd02..06de6b4d14 100644 --- a/code/modules/mob/living/simple_animal/aliens/drone.dm +++ b/code/modules/mob/living/simple_animal/aliens/drone.dm @@ -17,7 +17,7 @@ response_help = "pokes" response_disarm = "gently pushes aside" response_harm = "hits" - + a_intent = I_HURT ranged = 1 rapid = 1 @@ -99,16 +99,16 @@ src.visible_message("\red \icon[src] [src] suddenly lights up, and additional targetting vanes slide into place.") hostile = 1 - if(health / maxHealth > 0.9) + if(health / getMaxHealth() > 0.9) icon_state = "drone3" explode_chance = 0 - else if(health / maxHealth > 0.7) + else if(health / getMaxHealth() > 0.7) icon_state = "drone2" explode_chance = 0 - else if(health / maxHealth > 0.5) + else if(health / getMaxHealth() > 0.5) icon_state = "drone1" explode_chance = 0.5 - else if(health / maxHealth > 0.3) + else if(health / getMaxHealth() > 0.3) icon_state = "drone0" explode_chance = 5 else if(health > 0) diff --git a/code/modules/mob/living/simple_animal/animals/spiderbot.dm b/code/modules/mob/living/simple_animal/animals/spiderbot.dm index 1bb202d1a0..95b7e81a17 100644 --- a/code/modules/mob/living/simple_animal/animals/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/animals/spiderbot.dm @@ -95,10 +95,10 @@ if (istype(O, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = O if (WT.remove_fuel(0)) - if(health < maxHealth) + if(health < getMaxHealth()) health += pick(1,1,1,2,2,3) - if(health > maxHealth) - health = maxHealth + if(health > getMaxHealth()) + health = getMaxHealth() add_fingerprint(user) src.visible_message("\The [user] has spot-welded some of the damage to \the [src]!") else diff --git a/code/modules/mob/living/simple_animal/constructs/constructs.dm b/code/modules/mob/living/simple_animal/constructs/constructs.dm index c24100476c..1cc1a85108 100644 --- a/code/modules/mob/living/simple_animal/constructs/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs/constructs.dm @@ -57,7 +57,7 @@ /mob/living/simple_animal/construct/attack_generic(var/mob/user) if(istype(user, /mob/living/simple_animal/construct/builder)) - if(health < maxHealth) + if(health < getMaxHealth()) adjustBruteLoss(-5) user.visible_message("\The [user] mends some of \the [src]'s wounds.") else @@ -68,9 +68,9 @@ /mob/living/simple_animal/construct/examine(mob/user) ..(user) var/msg = "*---------*\nThis is \icon[src] \a [src]!\n" - if (src.health < src.maxHealth) + if (src.health < src.getMaxHealth()) msg += "" - if (src.health >= src.maxHealth/2) + if (src.health >= src.getMaxHealth()/2) msg += "It looks slightly dented.\n" else msg += "It looks severely dented!\n" diff --git a/code/modules/mob/living/simple_animal/constructs/soulstone.dm b/code/modules/mob/living/simple_animal/constructs/soulstone.dm index 05087c4036..7b5e77f5c3 100644 --- a/code/modules/mob/living/simple_animal/constructs/soulstone.dm +++ b/code/modules/mob/living/simple_animal/constructs/soulstone.dm @@ -170,7 +170,7 @@ T.forceMove(src) //put shade in stone T.status_flags |= GODMODE T.canmove = 0 - T.health = T.maxHealth + T.health = T.getMaxHealth() src.icon_state = "soulstone2" T << "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form" diff --git a/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm b/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm index 79f389821e..ae700d60b7 100644 --- a/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm +++ b/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm @@ -75,7 +75,7 @@ /mob/living/simple_animal/hostile/mecha/Life() . = ..() if(!.) return - if((health < maxHealth*0.3) && prob(10)) + if((health < getMaxHealth()*0.3) && prob(10)) sparks.start() /mob/living/simple_animal/hostile/mecha/bullet_act() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index af20f04201..3ad6260813 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -234,8 +234,8 @@ density = 1 //Overhealth - else if(health > maxHealth) - health = maxHealth + else if(health > getMaxHealth()) + health = getMaxHealth() /mob/living/simple_animal/update_icon() ..() @@ -534,7 +534,7 @@ if(istype(O, /obj/item/stack/medical)) if(stat != DEAD) var/obj/item/stack/medical/MED = O - if(health < maxHealth) + if(health < getMaxHealth()) if(MED.amount >= 1) adjustBruteLoss(-MED.heal_brute) MED.amount -= 1 @@ -602,7 +602,7 @@ ..() if(statpanel("Status") && show_stat_health) - stat(null, "Health: [round((health / maxHealth) * 100)]%") + stat(null, "Health: [round((health / getMaxHealth()) * 100)]%") /mob/living/simple_animal/lay_down() ..() @@ -645,10 +645,10 @@ adjustBruteLoss(30) /mob/living/simple_animal/adjustBruteLoss(damage) - health = Clamp(health - damage, 0, maxHealth) + health = Clamp(health - damage, 0, getMaxHealth()) /mob/living/simple_animal/adjustFireLoss(damage) - health = Clamp(health - damage, 0, maxHealth) + health = Clamp(health - damage, 0, getMaxHealth()) // Check target_mob if worthy of attack (i.e. check if they are dead or empty mecha) /mob/living/simple_animal/proc/SA_attackable(target_mob) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index ab53d6466c..1d8ddceedd 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -805,6 +805,30 @@ sleeping = max(sleeping + amount,0) return +/mob/proc/Confuse(amount) + confused = max(max(confused,amount),0) + return + +/mob/proc/SetConfused(amount) + confused = max(amount,0) + return + +/mob/proc/AdjustConfused(amount) + confused = max(confused + amount,0) + return + +/mob/proc/Blind(amount) + eye_blind = max(max(eye_blind,amount),0) + return + +/mob/proc/SetBlinded(amount) + eye_blind = max(amount,0) + return + +/mob/proc/AdjustBlinded(amount) + eye_blind = max(eye_blind + amount,0) + return + /mob/proc/Resting(amount) facing_dir = null resting = max(max(resting,amount),0) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index f3cd084ffa..80f68b979d 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -170,7 +170,7 @@ if(announce) assailant.visible_message("[assailant] covers [affecting]'s eyes!") if(affecting.eye_blind < 3) - affecting.eye_blind = 3 + affecting.Blind(3) /obj/item/weapon/grab/attack_self() return s_click(hud) diff --git a/code/modules/mob/modifiers.dm b/code/modules/mob/modifiers.dm new file mode 100644 index 0000000000..6ba148916e --- /dev/null +++ b/code/modules/mob/modifiers.dm @@ -0,0 +1,106 @@ +// This is a datum that tells the mob that something is affecting them. +// The advantage of using this datum verses just setting a variable on the mob directly, is that there is no risk of two different procs overwriting +// each other, or other weirdness. An excellent example is adjusting max health. + +/datum/modifier + var/name = null // Mostly used to organize, might show up on the UI in the Future(tm) + var/desc = null // Ditto. + var/icon_state = null // See above. + var/mob/living/holder = null // The mob that this datum is affecting. + var/expire_at = null // world.time when holder's Life() will remove the datum. If null, it lasts forever or until it gets deleted by something else. + var/on_created_text = null // Text to show to holder upon being created. + var/on_expired_text = null // Text to show to holder when it expires. + var/hidden = FALSE // If true, it will not show up on the HUD in the Future(tm) + var/stacks = MODIFIER_STACK_FORBID // If true, attempts to add a second instance of this type will refresh expire_at instead. + var/flags = 0 // Flags for the modifier, see mobs.dm defines for more details. + + // Now for all the different effects. + // Percentage modifiers are expressed as a multipler. (e.g. +25% damage should be written as 1.25) + var/max_health_flat // Adjusts max health by a flat (e.g. +20) amount. Note this is added to base health. + var/max_health_percent // Adjusts max health by a percentage (e.g. -30%). + var/disable_duration_percent // Adjusts duration of 'disables' (stun, weaken, paralyze, confusion, sleep, halloss, etc) Setting to 0 will grant immunity. + var/incoming_damage_percent // Adjusts all incoming damage. + var/incoming_brute_damage_percent // Only affects bruteloss. + var/incoming_fire_damage_percent // Only affects fireloss. + var/incoming_tox_damage_percent // Only affects toxloss. + var/incoming_oxy_damage_percent // Only affects oxyloss. + var/incoming_clone_damage_percent // Only affects cloneloss. + var/incoming_hal_damage_percent // Only affects halloss. + var/incoming_healing_percent // Adjusts amount of healing received. + var/outgoing_melee_damage_percent // Adjusts melee damage inflicted by holder by a percentage. Affects attacks by melee weapons and hand-to-hand. + var/slowdown // Negative numbers speed up, positive numbers slow down movement. + +/datum/modifier/New(var/new_holder) + holder = new_holder + ..() + +// Checks to see if this datum should continue existing. +/datum/modifier/proc/check_if_valid() + if(expire_at && expire_at < world.time) // Is our time up? + src.expire() + +/datum/modifier/proc/expire(var/silent = FALSE) + if(on_expired_text && !silent) + to_chat(holder, on_expired_text) + on_expire() + holder.modifiers.Remove(src) + qdel(src) + +// Override this for special effects when it gets removed. +/datum/modifier/proc/on_expire() + return + +/mob/living + var/list/modifiers = list() // A list of modifier datums, which can adjust certain mob numbers. + +/mob/living/Destroy() + remove_all_modifiers(TRUE) + ..() + +// Called by Life(). +/mob/living/proc/handle_modifiers() + if(!modifiers.len) // No work to do. + return + // Get rid of anything we shouldn't have. + for(var/datum/modifier/M in modifiers) + M.check_if_valid() + +// Call this to add a modifier to a mob. First argument is the modifier type you want, second is how long it should last, in ticks. +// The SECONDS/MINUTES macro is very helpful for this. E.g. M.add_modifier(/datum/modifier/example, 5 MINUTES) +/mob/living/proc/add_modifier(var/modifier_type, var/expire_at = null) + // First, check if the mob already has this modifier. + for(var/datum/modifier/M in modifiers) + if(ispath(modifier_type, M.type)) + switch(M.stacks) + if(MODIFIER_STACK_FORBID) + return // Stop here. + if(MODIFIER_STACK_ALLOWED) + break // No point checking anymore. + if(MODIFIER_STACK_EXTEND) + // Not allow to add a second instance, but we can try to prolong the first instance. + if(expire_at && world.time + expire_at > M.expire_at) + M.expire_at = world.time + expire_at + return + + // If we're at this point, the mob doesn't already have it, or it does but stacking is allowed. + var/datum/modifier/mod = new modifier_type(src) + if(expire_at) + mod.expire_at = world.time + expire_at + if(mod.on_created_text) + to_chat(src, mod.on_created_text) + modifiers.Add(mod) + +// Removes a specific instance of modifier +/mob/living/proc/remove_specific_modifier(var/datum/modifier/M, var/silent = FALSE) + M.expire(silent) + +// Removes all modifiers of a type +/mob/living/proc/remove_modifiers_of_type(var/modifier_type, var/silent = FALSE) + for(var/datum/modifier/M in modifiers) + if(ispath(modifier_type, M.type)) + M.expire(silent) + +// Removes all modifiers, useful if the mob's being deleted +/mob/living/proc/remove_all_modifiers(var/silent = FALSE) + for(var/datum/modifier/M in modifiers) + M.expire(silent) \ No newline at end of file diff --git a/code/modules/multiz/basic.dm b/code/modules/multiz/basic.dm index 24d24b1049..0ed4e5364a 100644 --- a/code/modules/multiz/basic.dm +++ b/code/modules/multiz/basic.dm @@ -43,3 +43,11 @@ var/z_levels = 0 // Each bit represents a connection between adjacent levels. S proc/AreConnectedZLevels(var/zA, var/zB) return zA == zB || (zB in GetConnectedZlevels(zA)) + +/proc/get_zstep(ref, dir) + if(dir == UP) + . = GetAbove(ref) + else if (dir == DOWN) + . = GetBelow(ref) + else + . = get_step(ref, dir) \ No newline at end of file diff --git a/code/modules/multiz/pipes.dm b/code/modules/multiz/pipes.dm index 6b6b24c470..7570d12b35 100644 --- a/code/modules/multiz/pipes.dm +++ b/code/modules/multiz/pipes.dm @@ -51,7 +51,7 @@ obj/machinery/atmospherics/pipe/zpipe/New() invisibility = i ? 101 : 0 update_icon() -obj/machinery/atmospherics/pipe/up/process() +obj/machinery/atmospherics/pipe/zpipe/process() if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle ..() else @@ -81,10 +81,10 @@ obj/machinery/atmospherics/pipe/zpipe/proc/burst() qdel(src) // NOT qdel. obj/machinery/atmospherics/pipe/zpipe/proc/normalize_dir() - if(dir==3) - set_dir(1) - else if(dir==12) - set_dir(4) + if(dir == (NORTH|SOUTH)) + set_dir(NORTH) + else if(dir == (EAST|WEST)) + set_dir(EAST) obj/machinery/atmospherics/pipe/zpipe/Destroy() if(node1) diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index 6514092dfc..1390c89b29 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -35,7 +35,7 @@ if (. >= 2) if(prob(1)) owner.custom_pain("Your feel very dizzy for a moment!",0) - owner.confused = max(owner.confused, 2) + owner.Confuse(2) /obj/item/organ/internal/brain/proc/replace_self_with(replace_path) var/mob/living/carbon/human/tmp_owner = owner diff --git a/code/modules/organs/internal/eyes.dm b/code/modules/organs/internal/eyes.dm index 2a2b8305d3..4febf8f479 100644 --- a/code/modules/organs/internal/eyes.dm +++ b/code/modules/organs/internal/eyes.dm @@ -72,7 +72,7 @@ if(is_bruised()) owner.eye_blurry = 20 if(is_broken()) - owner.eye_blind = 20 + owner.Blind(20) /obj/item/organ/internal/eyes/handle_germ_effects() . = ..() //Up should return an infection level as an integer diff --git a/code/modules/organs/internal/liver.dm b/code/modules/organs/internal/liver.dm index daa0a88f76..6b7459500b 100644 --- a/code/modules/organs/internal/liver.dm +++ b/code/modules/organs/internal/liver.dm @@ -53,6 +53,6 @@ if(prob(1)) owner.custom_pain("There's a sharp pain in your upper-right abdomen!",1) if (. >= 2) - if(prob(1) && owner.getToxLoss() < owner.maxHealth*0.3) + if(prob(1) && owner.getToxLoss() < owner.getMaxHealth()*0.3) //owner << "" //Toxins provide their own messages for pain owner.adjustToxLoss(5) //Not realistic to PA but there are basically no 'real' liver infections diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index aebe847fb6..7a5c42ea41 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -492,7 +492,7 @@ This function completely restores a damaged organ to perfect condition. //Burn damage can cause fluid loss due to blistering and cook-off if((damage > 5 || damage + burn_dam >= 15) && type == BURN && (robotic < ORGAN_ROBOT) && !istype(owner.loc,/mob/living) && !istype(owner.loc,/obj/item/device/dogborg/sleeper)) // VOREStation Edit - var/fluid_loss = 0.75 * (damage/(owner.maxHealth - config.health_threshold_dead)) * owner.species.blood_volume*(1 - BLOOD_VOLUME_SURVIVE/100) + var/fluid_loss = 0.75 * (damage/(owner.getMaxHealth() - config.health_threshold_dead)) * owner.species.blood_volume*(1 - BLOOD_VOLUME_SURVIVE/100) owner.remove_blood(fluid_loss) // first check whether we can widen an existing wound diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index 244c0b7971..cfc0910901 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -165,7 +165,7 @@ if(is_bruised()) owner.eye_blurry = 20 if(is_broken()) - owner.eye_blind = 20 + owner.Blind(20) /obj/item/organ/internal/liver name = "liver" diff --git a/code/modules/organs/subtypes/unathi.dm b/code/modules/organs/subtypes/unathi.dm new file mode 100644 index 0000000000..212330577c --- /dev/null +++ b/code/modules/organs/subtypes/unathi.dm @@ -0,0 +1,50 @@ +/obj/item/organ/external/chest/unathi + max_damage = 100 + min_broken_damage = 40 + encased = "upper ribplates" + +/obj/item/organ/external/groin/unathi + max_damage = 100 + min_broken_damage = 40 + encased = "lower ribplates" + +/obj/item/organ/external/head/unathi + max_damage = 75 + min_broken_damage = 35 + eye_icon = "eyes_s" + force = 5 + throwforce = 10 + + +/obj/item/organ/internal/heart/unathi + icon_state = "unathi_heart-on" + dead_icon = "unath_heart-off" + +/obj/item/organ/internal/lungs/unathi + color = "#b3cbc3" + +/obj/item/organ/internal/liver/unathi + name = "filtration organ" + icon_state = "unathi_liver" + +//Unathi liver acts as kidneys, too. +/obj/item/organ/internal/liver/unathi/process() + ..() + if(!owner) return + + var/datum/reagent/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list + if(coffee) + if(is_bruised()) + owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) + else if(is_broken()) + owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) + + var/datum/reagent/sugar = locate(/datum/reagent/sugar) in owner.reagents.reagent_list + if(sugar) + if(is_bruised()) + owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) + else if(is_broken()) + owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) + +/obj/item/organ/internal/brain/unathi + color = "#b3cbc3" \ No newline at end of file diff --git a/code/modules/planet/planet.dm b/code/modules/planet/planet.dm index 53a07f228b..4c308ca930 100644 --- a/code/modules/planet/planet.dm +++ b/code/modules/planet/planet.dm @@ -12,8 +12,17 @@ var/datum/weather_holder/weather_holder var/sun_position = 0 // 0 means midnight, 1 means noon. + var/list/sun = list("range","brightness","color") var/expected_z_levels = list() + var/turf/unsimulated/wall/planetary/planetary_wall_type = /turf/unsimulated/wall/planetary + + var/turf/simulated/floor/planet_floors = list() + var/turf/unsimulated/wall/planetary/planet_walls = list() + + + var/needs_work = 0 // Bitflags to signal to the planet controller these need (properly deferrable) work. Flags defined in controller. + /datum/planet/New() ..() weather_holder = new(src) @@ -31,17 +40,13 @@ /datum/planet/proc/update_sun() sun_last_process = world.time - /datum/planet/proc/update_weather() if(weather_holder) weather_holder.process() /datum/planet/proc/update_sun_deferred(var/new_range, var/new_brightness, var/new_color) - set background = 1 - set waitfor = 0 - var/i = 0 - for(var/turf/simulated/floor/T in outdoor_turfs) - T.set_light(new_range, new_brightness, new_color) - i++ - if(i % 30 == 0) - sleep(1) + sun["range"] = new_range + sun["brightness"] = new_brightness + sun["color"] = new_color + needs_work |= PLANET_PROCESS_SUN + diff --git a/code/modules/planet/sif.dm b/code/modules/planet/sif.dm index 303d05f509..e35646ce7f 100644 --- a/code/modules/planet/sif.dm +++ b/code/modules/planet/sif.dm @@ -10,6 +10,7 @@ var/datum/planet/sif/planet_sif = null Its center of government is the equatorial city and site of first settlement, New Reykjavik." // Ripped straight from the wiki. current_time = new /datum/time/sif() // 32 hour clocks are nice. expected_z_levels = list(1) // To be changed when real map is finished. + planetary_wall_type = /turf/unsimulated/wall/planetary/sif /datum/planet/sif/New() ..() @@ -104,3 +105,197 @@ var/datum/planet/sif/planet_sif = null /proc/get_sif_time() if(planet_sif) return planet_sif.current_time + +//Weather definitions +/datum/weather_holder/sif + temperature = T0C + allowed_weather_types = list( + WEATHER_CLEAR = new /datum/weather/sif/clear(), + WEATHER_OVERCAST = new /datum/weather/sif/overcast(), + WEATHER_LIGHT_SNOW = new /datum/weather/sif/light_snow(), + WEATHER_SNOW = new /datum/weather/sif/snow(), + WEATHER_BLIZZARD = new /datum/weather/sif/blizzard(), + WEATHER_RAIN = new /datum/weather/sif/rain(), + WEATHER_STORM = new /datum/weather/sif/storm(), + WEATHER_HAIL = new /datum/weather/sif/hail(), + WEATHER_BLOOD_MOON = new /datum/weather/sif/blood_moon() + ) + roundstart_weather_chances = list( + WEATHER_CLEAR = 30, + WEATHER_OVERCAST = 30, + WEATHER_LIGHT_SNOW = 20, + WEATHER_SNOW = 5, + WEATHER_BLIZZARD = 5, + WEATHER_RAIN = 5, + WEATHER_STORM = 2.5, + WEATHER_HAIL = 2.5 + ) + +datum/weather/sif + name = "sif base" + temp_high = 243.15 // -20c + temp_low = 233.15 // -30c + +/datum/weather/sif/clear + name = "clear" + transition_chances = list( + WEATHER_CLEAR = 60, + WEATHER_OVERCAST = 40 + ) + +/datum/weather/sif/overcast + name = "overcast" + light_modifier = 0.8 + transition_chances = list( + WEATHER_CLEAR = 25, + WEATHER_OVERCAST = 50, + WEATHER_LIGHT_SNOW = 10, + WEATHER_SNOW = 5, + WEATHER_RAIN = 5, + WEATHER_HAIL = 5 + ) + +/datum/weather/sif/light_snow + name = "light snow" + icon_state = "snowfall_light" + temp_high = 238.15 // -25c + temp_low = 228.15 // -35c + light_modifier = 0.7 + transition_chances = list( + WEATHER_OVERCAST = 20, + WEATHER_LIGHT_SNOW = 50, + WEATHER_SNOW = 25, + WEATHER_HAIL = 5 + ) + +/datum/weather/sif/snow + name = "moderate snow" + icon_state = "snowfall_med" + temp_high = 233.15 // -30c + temp_low = 223.15 // -40c + light_modifier = 0.5 + transition_chances = list( + WEATHER_LIGHT_SNOW = 20, + WEATHER_SNOW = 50, + WEATHER_BLIZZARD = 20, + WEATHER_HAIL = 5, + WEATHER_OVERCAST = 5 + ) + +/datum/weather/sif/snow/process_effects() + for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs) + 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) + if(istype(T)) + if(istype(T, /turf/simulated/floor/outdoors) && prob(33)) + T.chill() + +/datum/weather/sif/blizzard + name = "blizzard" + icon_state = "snowfall_heavy" + temp_high = 223.15 // -40c + temp_low = 203.15 // -60c + light_modifier = 0.3 + transition_chances = list( + WEATHER_SNOW = 45, + WEATHER_BLIZZARD = 40, + WEATHER_HAIL = 10, + WEATHER_OVERCAST = 5 + ) + +/datum/weather/sif/blizzard/process_effects() + for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs) + 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) + if(istype(T)) + if(istype(T, /turf/simulated/floor/outdoors) && prob(50)) + T.chill() + +/datum/weather/sif/rain + name = "rain" + icon_state = "rain" + light_modifier = 0.5 + transition_chances = list( + WEATHER_OVERCAST = 25, + WEATHER_LIGHT_SNOW = 10, + WEATHER_RAIN = 50, + WEATHER_STORM = 10, + WEATHER_HAIL = 5 + ) + +/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) + if(!T.outdoors) + return // They're indoors, so no need to rain on them. + + L.adjust_fire_stacks(-5) + to_chat(L, "Rain falls on you.") + +/datum/weather/sif/storm + name = "storm" + icon_state = "storm" + temp_high = 233.15 // -30c + temp_low = 213.15 // -50c + light_modifier = 0.3 + transition_chances = list( + WEATHER_RAIN = 45, + WEATHER_STORM = 40, + WEATHER_HAIL = 10, + WEATHER_OVERCAST = 5 + ) + +/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) + if(!T.outdoors) + return // They're indoors, so no need to rain on them. + + L.adjust_fire_stacks(-10) + to_chat(L, "Rain falls on you, drenching you in water.") + +/datum/weather/sif/hail + name = "hail" + icon_state = "hail" + temp_high = 233.15 // -30c + temp_low = 213.15 // -50c + light_modifier = 0.3 + transition_chances = list( + WEATHER_RAIN = 45, + WEATHER_STORM = 10, + WEATHER_HAIL = 40, + WEATHER_OVERCAST = 5 + ) + +/datum/weather/sif/hail/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) + if(!T.outdoors) + return // They're indoors, so no need to pelt them with ice. + + var/target_zone = pick(BP_ALL) + var/amount_blocked = L.run_armor_check(target_zone, "melee") + var/amount_soaked = L.get_armor_soak(target_zone, "melee") + + if(amount_blocked >= 100) + return // No need to apply damage. + + if(amount_soaked >= 10) + return // No need to apply damage. + + L.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail") + to_chat(L, "The hail raining down on you [L.can_feel_pain() ? "hurts" : "damages you"]!") + +/datum/weather/sif/blood_moon + name = "blood moon" + light_modifier = 0.5 + light_color = "#FF0000" + transition_chances = list( + WEATHER_BLOODMOON = 100 + ) + diff --git a/code/modules/planet/weather.dm b/code/modules/planet/weather.dm index 3c06b350df..5a58c1323e 100644 --- a/code/modules/planet/weather.dm +++ b/code/modules/planet/weather.dm @@ -1,15 +1,3 @@ -#define WEATHER_CLEAR "clear" -#define WEATHER_OVERCAST "overcast" -#define WEATHER_LIGHT_SNOW "light snow" -#define WEATHER_SNOW "snow" -#define WEATHER_BLIZZARD "blizzard" -#define WEATHER_RAIN "rain" -#define WEATHER_STORM "storm" -#define WEATHER_HAIL "hail" -#define WEATHER_WINDY "windy" -#define WEATHER_HOT "hot" -#define WEATHER_BLOOD_MOON "blood moon" // For admin fun or cult later on. - /datum/weather_holder var/datum/planet/our_planet = null var/datum/weather/current_weather = null @@ -19,7 +7,6 @@ var/list/allowed_weather_types = list() var/list/roundstart_weather_chances = list() var/next_weather_shift = null - var/planetary_wall_type = null // Which walls to look for when updating temperature. /datum/weather_holder/New(var/source) ..() @@ -54,55 +41,15 @@ current_weather.process_effects() /datum/weather_holder/proc/update_icon_effects() - set background = 1 - set waitfor = 0 - if(current_weather) - for(var/turf/simulated/floor/T in outdoor_turfs) - if(T.z in our_planet.expected_z_levels) - T.overlays -= T.weather_overlay - T.weather_overlay = image(icon = current_weather.icon, icon_state = current_weather.icon_state, layer = LIGHTING_LAYER - 1) - T.overlays += T.weather_overlay + our_planet.needs_work |= PLANET_PROCESS_WEATHER /datum/weather_holder/proc/update_temperature() temperature = Interpolate(current_weather.temp_low, current_weather.temp_high, weight = our_planet.sun_position) - - for(var/turf/unsimulated/wall/planetary/wall in planetary_walls) - if(ispath(wall.type, planetary_wall_type)) - wall.temperature = temperature - for(var/dir in cardinal) - var/turf/simulated/T = get_step(wall, dir) - if(istype(T)) - if(T.zone) - T.zone.rebuild() - + our_planet.needs_work |= PLANET_PROCESS_TEMP /datum/weather_holder/proc/get_weather_datum(desired_type) return allowed_weather_types[desired_type] -/datum/weather_holder/sif - temperature = T0C - allowed_weather_types = list( - WEATHER_CLEAR = new /datum/weather/sif/clear(), - WEATHER_OVERCAST = new /datum/weather/sif/overcast(), - WEATHER_LIGHT_SNOW = new /datum/weather/sif/light_snow(), - WEATHER_SNOW = new /datum/weather/sif/snow(), - WEATHER_BLIZZARD = new /datum/weather/sif/blizzard(), - WEATHER_RAIN = new /datum/weather/sif/rain(), - WEATHER_STORM = new /datum/weather/sif/storm(), - WEATHER_HAIL = new /datum/weather/sif/hail(), - WEATHER_BLOOD_MOON = new /datum/weather/sif/blood_moon() - ) - planetary_wall_type = /turf/unsimulated/wall/planetary/sif - roundstart_weather_chances = list( - WEATHER_CLEAR = 30, - WEATHER_OVERCAST = 30, - WEATHER_LIGHT_SNOW = 20, - WEATHER_SNOW = 5, - WEATHER_BLIZZARD = 5, - WEATHER_RAIN = 5, - WEATHER_STORM = 2.5, - WEATHER_HAIL = 2.5 - ) /datum/weather var/name = "weather base" @@ -117,169 +64,3 @@ /datum/weather/proc/process_effects() return - -/datum/weather/sif - name = "sif base" - temp_high = 243.15 // -20c - temp_low = 233.15 // -30c - -/datum/weather/sif/clear - name = "clear" - transition_chances = list( - WEATHER_CLEAR = 60, - WEATHER_OVERCAST = 40 - ) - -/datum/weather/sif/overcast - name = "overcast" - light_modifier = 0.8 - transition_chances = list( - WEATHER_CLEAR = 25, - WEATHER_OVERCAST = 50, - WEATHER_LIGHT_SNOW = 10, - WEATHER_SNOW = 5, - WEATHER_RAIN = 5, - WEATHER_HAIL = 5 - ) - -/datum/weather/sif/light_snow - name = "light snow" - icon_state = "snowfall_light" - temp_high = 238.15 // -25c - temp_low = 228.15 // -35c - light_modifier = 0.7 - transition_chances = list( - WEATHER_OVERCAST = 20, - WEATHER_LIGHT_SNOW = 50, - WEATHER_SNOW = 25, - WEATHER_HAIL = 5 - ) - -/datum/weather/sif/snow - name = "moderate snow" - icon_state = "snowfall_med" - temp_high = 233.15 // -30c - temp_low = 223.15 // -40c - light_modifier = 0.5 - transition_chances = list( - WEATHER_LIGHT_SNOW = 20, - WEATHER_SNOW = 50, - WEATHER_BLIZZARD = 20, - WEATHER_HAIL = 5, - WEATHER_OVERCAST = 5 - ) - -/datum/weather/sif/snow/process_effects() - for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs) - for(var/dir_checked in cardinal) - var/turf/simulated/floor/T = get_step(S, dir_checked) - if(istype(T)) - if(istype(T, /turf/simulated/floor/outdoors) && prob(33)) - T.chill() - -/datum/weather/sif/blizzard - name = "blizzard" - icon_state = "snowfall_heavy" - temp_high = 223.15 // -40c - temp_low = 203.15 // -60c - light_modifier = 0.3 - transition_chances = list( - WEATHER_SNOW = 45, - WEATHER_BLIZZARD = 40, - WEATHER_HAIL = 10, - WEATHER_OVERCAST = 5 - ) - -/datum/weather/sif/blizzard/process_effects() - for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs) - for(var/dir_checked in cardinal) - var/turf/simulated/floor/T = get_step(S, dir_checked) - if(istype(T)) - if(istype(T, /turf/simulated/floor/outdoors) && prob(50)) - T.chill() - -/datum/weather/sif/rain - name = "rain" - icon_state = "rain" - light_modifier = 0.5 - transition_chances = list( - WEATHER_OVERCAST = 25, - WEATHER_LIGHT_SNOW = 10, - WEATHER_RAIN = 50, - WEATHER_STORM = 10, - WEATHER_HAIL = 5 - ) - -/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) - if(!T.outdoors) - return // They're indoors, so no need to rain on them. - - L.adjust_fire_stacks(-5) - to_chat(L, "Rain falls on you.") - -/datum/weather/sif/storm - name = "storm" - icon_state = "storm" - temp_high = 233.15 // -30c - temp_low = 213.15 // -50c - light_modifier = 0.3 - transition_chances = list( - WEATHER_RAIN = 45, - WEATHER_STORM = 40, - WEATHER_HAIL = 10, - WEATHER_OVERCAST = 5 - ) - -/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) - if(!T.outdoors) - return // They're indoors, so no need to rain on them. - - L.adjust_fire_stacks(-10) - to_chat(L, "Rain falls on you, drenching you in water.") - -/datum/weather/sif/hail - name = "hail" - icon_state = "hail" - temp_high = 233.15 // -30c - temp_low = 213.15 // -50c - light_modifier = 0.3 - transition_chances = list( - WEATHER_RAIN = 45, - WEATHER_STORM = 10, - WEATHER_HAIL = 40, - WEATHER_OVERCAST = 5 - ) - -/datum/weather/sif/hail/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) - if(!T.outdoors) - return // They're indoors, so no need to pelt them with ice. - - var/target_zone = pick(BP_ALL) - var/amount_blocked = L.run_armor_check(target_zone, "melee") - var/amount_soaked = L.get_armor_soak(target_zone, "melee") - - if(amount_blocked >= 100) - return // No need to apply damage. - - if(amount_soaked >= 10) - return // No need to apply damage. - - L.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail") - to_chat(L, "The hail raining down on you [L.can_feel_pain() ? "hurts" : "damages you"]!") - -/datum/weather/sif/blood_moon - name = "blood moon" - light_modifier = 0.5 - light_color = "#FF0000" - transition_chances = list( - WEATHER_BLOODMOON = 100 - ) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 671d57e04e..27bf4c0ab7 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -48,7 +48,7 @@ var/list/possible_cable_coil_colours = list( anchored =1 var/datum/powernet/powernet name = "power cable" - desc = "A flexible superconducting cable for heavy-duty power transfer" + desc = "A flexible superconducting cable for heavy-duty power transfer." icon = 'icons/obj/power_cond_white.dmi' icon_state = "0-1" var/d1 = 0 @@ -116,9 +116,9 @@ var/list/possible_cable_coil_colours = list( user.examinate(src) // following code taken from attackby (multitool) if(powernet && (powernet.avail > 0)) - user << "[powernet.avail]W in power network." + to_chat(user, "[powernet.avail]W in power network.") else - user << "The cable is not powered." + to_chat(user, "The cable is not powered.") return /////////////////////////////////// @@ -159,12 +159,12 @@ var/list/possible_cable_coil_colours = list( return if(istype(W, /obj/item/weapon/wirecutters)) - if(d1 == 12 || d2 == 12) - user << "You must cut this cable from above." + if(d1 == UP || d2 == UP) + to_chat(user, "You must cut this cable from above.") return if(breaker_box) - user << "\red This cable is connected to nearby breaker box. Use breaker box to interact with it." + to_chat(user, "This cable is connected to nearby breaker box. Use breaker box to interact with it.") return if (shock(user, 50)) @@ -178,11 +178,11 @@ var/list/possible_cable_coil_colours = list( for(var/mob/O in viewers(src, null)) O.show_message("[user] cuts the cable.", 1) - if(d1 == 11 || d2 == 11) + if(d1 == DOWN || d2 == DOWN) var/turf/turf = GetBelow(src) if(turf) for(var/obj/structure/cable/c in turf) - if(c.d1 == 12 || c.d2 == 12) + if(c.d1 == UP || c.d2 == UP) qdel(c) investigate_log("was cut by [key_name(usr, usr.client)] in [user.loc.loc]","wires") @@ -194,17 +194,17 @@ var/list/possible_cable_coil_colours = list( else if(istype(W, /obj/item/stack/cable_coil)) var/obj/item/stack/cable_coil/coil = W if (coil.get_amount() < 1) - user << "Not enough cable" + to_chat(user, "Not enough cable") return coil.cable_join(src, user) else if(istype(W, /obj/item/device/multitool)) if(powernet && (powernet.avail > 0)) // is it powered? - user << "[powernet.avail]W in power network." + to_chat(user, "[powernet.avail]W in power network.") else - user << "The cable is not powered." + to_chat(user, "The cable is not powered.") shock(user, 5, 0.2) @@ -300,12 +300,12 @@ obj/structure/cable/proc/cableColor(var/colorC) // merge with the powernets of power objects in the given direction /obj/structure/cable/proc/mergeConnectedNetworks(var/direction) - var/fdir = (!direction)? 0 : turn(direction, 180) //flip the direction, to match with the source position on its turf + var/fdir = direction ? reverse_dir[direction] : 0 //flip the direction, to match with the source position on its turf if(!(d1 == direction || d2 == direction)) //if the cable is not pointed in this direction, do nothing return - var/turf/TB = get_step(src, direction) + var/turf/TB = get_zstep(src, direction) for(var/obj/structure/cable/C in TB) @@ -376,25 +376,15 @@ obj/structure/cable/proc/cableColor(var/colorC) . = list() // this will be a list of all connected power objects var/turf/T - // Handle up/down cables - if(d1 == 11 || d2 == 11) - T = GetBelow(src) - if(T) - . += power_list(T, src, 12, 1) - if(d1 == 12 || d1 == 12) - T = GetAbove(src) - if(T) - . += power_list(T, src, 11, 1) - // Handle standard cables in adjacent turfs for(var/cable_dir in list(d1, d2)) - if(cable_dir == 11 || cable_dir == 12 || cable_dir == 0) + if(cable_dir == 0) continue var/reverse = reverse_dir[cable_dir] - T = get_step(src, cable_dir) + T = get_zstep(src, cable_dir) if(T) for(var/obj/structure/cable/C in T) - if((C.d1 && C.d1 == reverse) || (C.d2 && C.d2 == reverse)) + if(C.d1 == reverse || C.d2 == reverse) . += C if(cable_dir & (cable_dir - 1)) // Diagonal, check for /\/\/\ style cables along cardinal directions for(var/pair in list(NORTH|SOUTH, EAST|WEST)) @@ -402,7 +392,7 @@ obj/structure/cable/proc/cableColor(var/colorC) if(T) var/req_dir = cable_dir ^ pair for(var/obj/structure/cable/C in T) - if((C.d1 && C.d1 == req_dir) || (C.d2 && C.d2 == req_dir)) + if(C.d1 == req_dir || C.d2 == req_dir) . += C // Handle cables on the same turf as us @@ -566,7 +556,7 @@ obj/structure/cable/proc/cableColor(var/colorC) final_color = possible_cable_coil_colours["Red"] selected_color = "red" color = final_color - user << "You change \the [src]'s color to [lowertext(selected_color)]." + to_chat(user, "You change \the [src]'s color to [lowertext(selected_color)].") /obj/item/stack/cable_coil/proc/update_wclass() if(amount == 1) @@ -579,11 +569,11 @@ obj/structure/cable/proc/cableColor(var/colorC) return if(get_amount() == 1) - user << "A short piece of power cable." + to_chat(user, "A short piece of power cable.") else if(get_amount() == 2) - user << "A piece of power cable." + to_chat(user, "A piece of power cable.") else - user << "A coil of power cable. There are [get_amount()] lengths of cable in the coil." + to_chat(user, "A coil of power cable. There are [get_amount()] lengths of cable in the coil.") /obj/item/stack/cable_coil/verb/make_restraint() @@ -594,14 +584,14 @@ obj/structure/cable/proc/cableColor(var/colorC) if(ishuman(M) && !M.restrained() && !M.stat && !M.paralysis && ! M.stunned) if(!istype(usr.loc,/turf)) return if(src.amount <= 14) - usr << "\red You need at least 15 lengths to make restraints!" + to_chat(usr, "You need at least 15 lengths to make restraints!") return var/obj/item/weapon/handcuffs/cable/B = new /obj/item/weapon/handcuffs/cable(usr.loc) B.color = color - usr << "You wind some cable together to make some restraints." + to_chat(usr, "You wind some cable together to make some restraints.") src.use(15) else - usr << "\blue You cannot do that." + to_chat(usr, "You cannot do that.") ..() /obj/item/stack/cable_coil/cyborg/verb/set_colour() diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index fe51b4152e..d6ae824fd1 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -3,7 +3,6 @@ /obj/machinery/computer/gravity_control_computer name = "Gravity Generator Control" desc = "A computer to control a local gravity generator. Qualified personnel only." - icon = 'icons/obj/computer.dmi' icon_state = "airtunnel0e" anchored = 1 density = 1 diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 7697fdf6a4..13213c2e7e 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -209,16 +209,8 @@ // if unmarked==1, only return those with no powernet /proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0, var/cable_only = 0) . = list() - var/fdir = (!d)? 0 : turn(d, 180) // the opposite direction to d (or 0 if d==0) -///// Z-Level Stuff - var/Zdir - if(d==11) - Zdir = 11 - else if (d==12) - Zdir = 12 - else - Zdir = 999 -///// Z-Level Stuff + + var/reverse = d ? reverse_dir[d] : 0 for(var/AM in T) if(AM == source) continue //we don't want to return source @@ -234,11 +226,7 @@ var/obj/structure/cable/C = AM if(!unmarked || !C.powernet) -///// Z-Level Stuff - if(C.d1 == fdir || C.d2 == fdir || C.d1 == Zdir || C.d2 == Zdir) -///// Z-Level Stuff - . += C - else if(C.d1 == d || C.d2 == d) + if(C.d1 == d || C.d2 == d || C.d1 == reverse || C.d2 == reverse ) . += C return . diff --git a/code/modules/power/sensors/sensor_monitoring.dm b/code/modules/power/sensors/sensor_monitoring.dm index 597ced19db..21aecc59ea 100644 --- a/code/modules/power/sensors/sensor_monitoring.dm +++ b/code/modules/power/sensors/sensor_monitoring.dm @@ -6,7 +6,6 @@ /obj/machinery/computer/power_monitor name = "Power Monitoring Console" desc = "Computer designed to remotely monitor power levels around the station" - icon = 'icons/obj/computer.dmi' icon_keyboard = "power_key" icon_screen = "power:0" light_color = "#ffcc33" diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index 8786930e2f..88c4ca34ac 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -28,7 +28,6 @@ /obj/machinery/computer/turbine_computer name = "Gas turbine control computer" desc = "A computer to remotely control a gas turbine" - icon = 'icons/obj/computer.dmi' icon_keyboard = "tech_key" icon_screen = "turbinecomp" circuit = /obj/item/weapon/circuitboard/turbine_control diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 75d574ed63..f7d963523c 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -425,21 +425,21 @@ /obj/item/weapon/gun/proc/handle_post_fire(mob/user, atom/target, var/pointblank=0, var/reflex=0) if(silenced) playsound(user, fire_sound, 10, 1) + to_chat(user, "You fire \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]") + for(var/mob/living/L in oview(2,user)) + if(L.stat) + continue + if(L.blinded) + to_chat(L, "You hear a [fire_sound_text]!") + continue + to_chat(L, "[user] fires \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]") else playsound(user, fire_sound, 50, 1) - - if(reflex) - user.visible_message( - "\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""] by reflex!", - "You fire \the [src] by reflex!", - "You hear a [fire_sound_text]!" - ) - else - user.visible_message( - "\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""]!", - "You fire \the [src]!", - "You hear a [fire_sound_text]!" - ) + user.visible_message( + "[user] fires \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]", + "You fire \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]", + "You hear a [fire_sound_text]!" + ) if(muzzle_flash) set_light(muzzle_flash) diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index faafd2e8c9..8fbfc0e657 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -21,7 +21,7 @@ item_state = null w_class = ITEMSIZE_NORMAL force = 5 - slot_flags = SLOT_BELT + slot_flags = SLOT_BELT|SLOT_HOLSTER charge_cost = 480 projectile_type = /obj/item/projectile/ion diff --git a/code/modules/projectiles/guns/projectile/boltaction.dm b/code/modules/projectiles/guns/projectile/boltaction.dm index f96dfd22ea..e07c45294c 100644 --- a/code/modules/projectiles/guns/projectile/boltaction.dm +++ b/code/modules/projectiles/guns/projectile/boltaction.dm @@ -49,4 +49,19 @@ desc = "The firepower of a Mosin, now the size of a pistol, with an effective combat range of about three feet. Uses 7.62mm rounds." user << "You shorten the barrel and stock of \the [src]!" else - ..() \ No newline at end of file + ..() + + +//Lever actions are the same thing, but bigger. +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever + name = "lever-action rifle" + desc = "A reproduction of an almost ancient weapon design from the 19th century. This one uses a lever-action to move new rounds into the chamber. Uses 5.56mm rounds." + item_state = "leveraction" + icon_state = "leveraction" + fire_sound = 'sound/weapons/rifleshot.ogg' + max_shells = 5 + caliber = "a556" + origin_tech = list(TECH_COMBAT = 1)// Old as shit rifle doesn't have very good tech. + ammo_type = /obj/item/ammo_casing/a556 + load_method = SINGLE_CASING|SPEEDLOADER + action_sound = 'sound/weapons/riflebolt.ogg' \ No newline at end of file diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 54a2d301c7..033b406510 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -29,8 +29,8 @@ flash_strength *= H.species.flash_mod if(flash_strength > 0) - H.confused = max(H.confused, flash_strength + 5) - H.eye_blind = max(H.eye_blind, flash_strength) + H.Confuse(flash_strength + 5) + H.Blind(flash_strength) H.eye_blurry = max(H.eye_blurry, flash_strength + 5) H.adjustHalLoss(22 * (flash_strength / 5)) // Five flashes to stun. Bit weaker than melee flashes due to being ranged. @@ -146,9 +146,9 @@ var/ear_safety = 0 ear_safety = M.get_ear_protection() if(ear_safety == 1) - M.confused += 150 + M.Confuse(150) else if (ear_safety > 1) - M.confused += 30 + M.Confuse(30) else if (!ear_safety) M.Stun(10) M.Weaken(2) diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index b507afc316..dd81d713fe 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -150,7 +150,7 @@ on_hit(var/atom/target, var/blocked = 0) if(ishuman(target)) var/mob/living/carbon/human/M = target - M.confused += rand(5,8) + M.Confuse(rand(5,8)) /obj/item/projectile/chameleon name = "bullet" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm index 091842663d..5909ed906f 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm @@ -96,6 +96,8 @@ strength_mod *= 5 if(alien == IS_TAJARA) strength_mod *= 1.75 + if(alien == IS_UNATHI) + strength_mod *= 0.75 if(alien == IS_DIONA) strength_mod = 0 @@ -106,7 +108,7 @@ if(dose * strength_mod >= strength * 2) // Slurring M.slurring = max(M.slurring, 30) if(dose * strength_mod >= strength * 3) // Confusion - walking in random directions - M.confused = max(M.confused, 20) + M.Confuse(20) if(dose * strength_mod >= strength * 4) // Blurry vision M.eye_blurry = max(M.eye_blurry, 10) if(dose * strength_mod >= strength * 5) // Drowsyness - periodically falling asleep 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 f7da207e15..566f3e20f9 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -376,7 +376,7 @@ else if(eyes_covered) M << "Your [safe_thing] protect you from most of the pepperspray!" M.eye_blurry = max(M.eye_blurry, effective_strength * 3) - M.eye_blind = max(M.eye_blind, effective_strength) + M.Blind(effective_strength) M.Stun(5) M.Weaken(5) return @@ -387,7 +387,7 @@ else // Oh dear :D M << "You're sprayed directly in the eyes with pepperspray!" M.eye_blurry = max(M.eye_blurry, effective_strength * 5) - M.eye_blind = max(M.eye_blind, effective_strength * 2) + M.Blind(effective_strength * 2) M.Stun(5) M.Weaken(5) return @@ -1166,7 +1166,7 @@ if(M.dizziness) M.dizziness = max(0, M.dizziness - 15) if(M.confused) - M.confused = max(0, M.confused - 5) + M.Confuse(-5) /datum/reagent/drink/dry_ramen name = "Dry Ramen" @@ -2232,3 +2232,26 @@ glass_name = "special blend whiskey" glass_desc = "Just when you thought regular station whiskey was good... This silky, amber goodness has to come along and ruin everything." +/datum/reagent/ethanol/unathiliquor //Needs a better name + name = "Unathi Liquor" + id = "unathiliquor" + description = "This barely qualifies as a drink, and could give jetfuel a run for its money. Also known to cause feelings of euphoria and numbness." + taste_description = "spiced numbness" + color = "#242424" + strength = 5 + + glass_name = "unathi liquor" + glass_desc = "This barely qualifies as a drink, and may cause euphoria and numbness. Imbimber beware!" + +/datum/reagent/ethanol/unathiliquor/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + ..() + if(alien == IS_DIONA) + return + + var/drug_strength = 10 + if(alien == IS_SKRELL) + drug_strength = drug_strength * 0.8 + + M.druggy = max(M.druggy, drug_strength) + if(prob(10) && isturf(M.loc) && !istype(M.loc, /turf/space) && M.canmove && !M.restrained()) + step(M, pick(cardinal)) \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index e0307e07cc..ef6d8bb428 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -258,7 +258,7 @@ /datum/reagent/oxycodone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.add_chemical_effect(CE_PAINKILLER, 200) M.eye_blurry += 10 - M.confused += 5 + M.Confuse(5) /datum/reagent/oxycodone/overdose(var/mob/living/carbon/M, var/alien) ..() @@ -319,7 +319,7 @@ /datum/reagent/imidazoline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.eye_blurry = max(M.eye_blurry - 5, 0) - M.eye_blind = max(M.eye_blind - 5, 0) + M.AdjustBlinded(-5) if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] @@ -349,7 +349,7 @@ continue if(I.damage > 0) //Peridaxon heals only non-robotic organs I.damage = max(I.damage - removed, 0) - H.confused += 5 + H.Confuse(5) if(I.damage <= 5 && I.organ_tag == O_EYES) H.eye_blurry += 10 //Eyes need to reset, or something H.sdisabilities &= ~BLIND @@ -441,7 +441,7 @@ M.dizziness = 0 M.drowsyness = 0 M.stuttering = 0 - M.confused = 0 + M.SetConfused(0) if(M.ingested) for(var/datum/reagent/R in M.ingested.reagent_list) if(istype(R, /datum/reagent/ethanol)) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm index 4f8e17cb1e..0a7c78f952 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm @@ -133,7 +133,7 @@ M.disabilities = 0 M.sdisabilities = 0 M.eye_blurry = 0 - M.eye_blind = 0 + M.SetBlinded(0) M.SetWeakened(0) M.SetStunned(0) M.SetParalysis(0) @@ -141,7 +141,7 @@ M.dizziness = 0 M.drowsyness = 0 M.stuttering = 0 - M.confused = 0 + M.SetConfused(0) M.sleeping = 0 M.jitteriness = 0 diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index 6e34257e4a..12540c2d04 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -403,7 +403,7 @@ effective_dose *= 2 if(effective_dose == metabolism) - M.confused += 2 + M.Confuse(2) M.drowsyness += 2 else if(effective_dose < 2 * threshold) M.Weaken(30) @@ -429,6 +429,7 @@ glass_name = "beer" glass_desc = "A freezing pint of beer" + /* Drugs */ /datum/reagent/space_drugs @@ -490,7 +491,7 @@ if(alien == IS_SKRELL) drug_strength = drug_strength * 0.8 M.make_dizzy(drug_strength) - M.confused = max(M.confused, drug_strength * 5) + M.Confuse(drug_strength * 5) /datum/reagent/impedrezene name = "Impedrezene" diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 41ad4cb5c6..e20ee9459f 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -384,7 +384,7 @@ name = "Stimm" id = "stimm" result = "stimm" - required_reagents = list("sugar" = 1, "fuel" = 1) + required_reagents = list("left4zed" = 1, "fuel" = 1) catalysts = list("fuel" = 5) result_amount = 2 diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index ce377c8709..16a1cb3b26 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -121,7 +121,7 @@ recharge_time = 3 volume = 60 possible_transfer_amounts = list(5, 10, 20, 30) - reagent_ids = list("beer", "kahlua", "whiskey", "specialwhiskey", "wine", "vodka", "gin", "rum", "tequilla", "vermouth", "cognac", "ale", "mead", "water", "sugar", "ice", "tea", "icetea", "cola", "spacemountainwind", "dr_gibb", "space_up", "tonic", "sodawater", "lemon_lime", "orangejuice", "limejuice", "watermelonjuice") + reagent_ids = list("ale", "beer", "berryjuice", "coffee", "cognac", "cola", "dr_gibb", "egg", "gin", "hot_coco", "ice", "icetea", "kahlua", "lemonjuice", "lemon_lime", "limejuice", "mead", "milk", "mint", "orangejuice", "rum", "sodawater", "soymilk", "space_up", "spacemountainwind", "specialwhiskey", "sugar", "tea", "tequilla", "tomatojuice", "tonic", "vermouth", "vodka", "water", "watermelonjuice", "whiskey", "wine") /obj/item/weapon/reagent_containers/borghypo/service/attack(var/mob/M, var/mob/user) return diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index ed27e1a259..bd670cc8bc 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -243,6 +243,12 @@ user.drop_from_inventory(src) qdel(src) return + else if(istype(D, /obj/item/weapon/wirecutters)) + to_chat(user, "You cut a big hole in \the [src] with \the [D]. It's kinda useless as a bucket now.") + user.put_in_hands(new /obj/item/clothing/head/helmet/bucket) + user.drop_from_inventory(src) + qdel(src) + return else if(istype(D, /obj/item/weapon/mop)) if(reagents.total_volume < 1) user << "\The [src] is empty!" diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm index f7bc1d1c80..4872131429 100644 --- a/code/modules/shieldgen/emergency_shield.dm +++ b/code/modules/shieldgen/emergency_shield.dm @@ -290,7 +290,7 @@ else if(istype(W, /obj/item/stack/cable_coil) && malfunction && is_open) var/obj/item/stack/cable_coil/coil = W user << "You begin to replace the wires." - //if(do_after(user, min(60, round( ((maxhealth/health)*10)+(malfunction*10) ))) //Take longer to repair heavier damage + //if(do_after(user, min(60, round( ((getMaxHealth()/health)*10)+(malfunction*10) ))) //Take longer to repair heavier damage if(do_after(user, 30)) if (coil.use(1)) health = max_health diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm index b6857a3f82..980053bd5d 100644 --- a/code/modules/shuttles/shuttle_console.dm +++ b/code/modules/shuttles/shuttle_console.dm @@ -1,6 +1,5 @@ /obj/machinery/computer/shuttle_control name = "shuttle control console" - icon = 'icons/obj/computer.dmi' icon_keyboard = "atmos_key" icon_screen = "shuttle" circuit = null diff --git a/code/modules/spells/spellbook.dm b/code/modules/spells/spellbook.dm index a28f03e8fe..515453f6a3 100644 --- a/code/modules/spells/spellbook.dm +++ b/code/modules/spells/spellbook.dm @@ -322,7 +322,7 @@ /obj/item/weapon/spellbook/oneuse/blind/recoil(mob/user as mob) ..() user <<"You go blind!" - user.eye_blind = 10 + user.Blind(10) /obj/item/weapon/spellbook/oneuse/mindswap spell = /spell/targeted/mind_transfer diff --git a/code/modules/spells/targeted/targeted.dm b/code/modules/spells/targeted/targeted.dm index 498d363408..d9d581e050 100644 --- a/code/modules/spells/targeted/targeted.dm +++ b/code/modules/spells/targeted/targeted.dm @@ -138,8 +138,8 @@ Targeted spells have two useful flags: INCLUDEUSER and SELECTABLE. These are exp if(amt_weakened || amt_paralysis || amt_stunned) if(target.buckled) target.buckled = null - target.eye_blind += amt_eye_blind + target.Blind(amt_eye_blind) target.eye_blurry += amt_eye_blurry target.dizziness += amt_dizziness - target.confused += amt_confused + target.Confuse(amt_confused) target.stuttering += amt_stuttering \ No newline at end of file diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm index c9d08c3385..1ece024833 100644 --- a/code/modules/ventcrawl/ventcrawl.dm +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -44,10 +44,15 @@ var/list/ventcrawl_machinery = list( /mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item) if(carried_item == ability_master) return 1 + + var/list/allowed = list() for(var/type in can_enter_vent_with) - if(istype(carried_item, type)) //VOREStation Edit - It was a typo before maybe? - return 1 //VOREStation Edit also - return 0 + var/list/types = typesof(type) + allowed += types + + if(carried_item.type in allowed) + if(get_inventory_slot(carried_item) == 0) + return 1 /mob/living/carbon/is_allowed_vent_crawl_item(var/obj/item/carried_item) if(carried_item in internal_organs) diff --git a/code/modules/virus2/curer.dm b/code/modules/virus2/curer.dm index d6c5189f19..c297643e2a 100644 --- a/code/modules/virus2/curer.dm +++ b/code/modules/virus2/curer.dm @@ -1,6 +1,5 @@ /obj/machinery/computer/curer name = "cure research machine" - icon = 'icons/obj/computer.dmi' icon_keyboard = "med_key" icon_screen = "dna" circuit = /obj/item/weapon/circuitboard/curefab diff --git a/code/modules/virus2/diseasesplicer.dm b/code/modules/virus2/diseasesplicer.dm index 8d88639db3..298dc49f27 100644 --- a/code/modules/virus2/diseasesplicer.dm +++ b/code/modules/virus2/diseasesplicer.dm @@ -1,6 +1,5 @@ /obj/machinery/computer/diseasesplicer name = "disease splicer" - icon = 'icons/obj/computer.dmi' icon_keyboard = "med_key" icon_screen = "crew" diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index 5243bae35f..310f223159 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -264,7 +264,7 @@ stage = 3 activate(var/mob/living/carbon/mob,var/multiplier) mob << "You have trouble telling right and left apart all of a sudden." - mob.confused += 10 + mob.Confuse(10) /datum/disease2/effect/mutation name = "DNA Degradation" diff --git a/code/modules/xenobio2/machinery/injector_computer.dm b/code/modules/xenobio2/machinery/injector_computer.dm index 6c2dc375e8..9dff9d43fb 100644 --- a/code/modules/xenobio2/machinery/injector_computer.dm +++ b/code/modules/xenobio2/machinery/injector_computer.dm @@ -76,7 +76,7 @@ if(injector.occupant) data["occupantHealth"] = injector.occupant.health - data["occupantHealthMax"] = injector.occupant.maxHealth + data["occupantHealthMax"] = injector.occupant.getMaxHealth() else data["occupantHealth"] = null data["occupantHealthMax"] = null diff --git a/config/example/game_options.txt b/config/example/game_options.txt index 035431b8ba..9e122db423 100644 --- a/config/example/game_options.txt +++ b/config/example/game_options.txt @@ -57,6 +57,8 @@ ALIEN_DELAY 0 METROID_DELAY 0 ANIMAL_DELAY 0 +## Volume of footstep sound effects. Range: 1-100, Set to 0 to disable footstep sounds. +FOOTSTEP_VOLUME 60 ### Miscellaneous ### diff --git a/html/changelog.html b/html/changelog.html index beb8c38c32..f4d1c782d5 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -57,6 +57,41 @@

Anewbe updated:

  • Wooden circlets can now be worn on the head.
  • +

    19 April 2017

    +

    Anewbe updated:

    +
      +
    • Unathi ribcages now reach down to their lower torso.
    • +
    • Unathi no longer have appendices or kidneys, the function of the kidneys is now a function of their liver.
    • +
    • Unathi are more slightly more difficult to damage.
    • +
    • Unathi now process medicine 15% slower. Additionally, it's harder for them to get drunk.
    • +
    • Unathi age range is now 32 to 260.
    • +
    • Unathi are not as slowed by heavy items.
    • +
    +

    Atermonera updated:

    +
      +
    • Translators no longer try to translate null languages.
    • +
    +

    LorenLuke updated:

    +
      +
    • Allows Blast doors to be attacked and broken like regular airlocks.
    • +
    • Changelings can bank up to a maximum of 3 respecs at one time.
    • +
    • Changelings begin with 2 respecs.
    • +
    • Firing a silenced weapon gives a message in text to the user.
    • +
    +

    MagmaRam updated:

    +
      +
    • Added instructions on how to use the changelog updating scripts.
    • +
    • Updated in-game EVA manual.
    • +
    +

    Neerti updated:

    +
      +
    • Adds makeshift armor for the head and chest regions. How protective they are depends on the material used to craft it. The helmet is made by using wirecutters on a bucket, then using a stack of material. The chestpiece is made by crafting two armor plate, using wires on one of them, then hiting one with the other.
    • +
    +

    Yoshax updated:

    +
      +
    • Water such as the pool will no longer apply fire stacks when you enter, meaning you will no longer be flammable from swimming.
    • +
    +

    16 April 2017

    Anewbe updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index d65fec13f5..9ade78534e 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -3423,3 +3423,31 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - tweak: Scrubbers now scrub Phoron by default. - tweak: Scrubbers now have the first dangerzone at anything more than 0 Phoron. - bugfix: No longer will you attack Alarms with your ID when trying to unlock them. +2017-04-19: + Anewbe: + - rscadd: Unathi ribcages now reach down to their lower torso. + - rscadd: Unathi no longer have appendices or kidneys, the function of the kidneys + is now a function of their liver. + - rscadd: Unathi are more slightly more difficult to damage. + - rscadd: Unathi now process medicine 15% slower. Additionally, it's harder for + them to get drunk. + - rscadd: Unathi age range is now 32 to 260. + - rscadd: Unathi are not as slowed by heavy items. + Atermonera: + - bugfix: Translators no longer try to translate null languages. + LorenLuke: + - rscadd: Allows Blast doors to be attacked and broken like regular airlocks. + - tweak: Changelings can bank up to a maximum of 3 respecs at one time. + - tweak: Changelings begin with 2 respecs. + - tweak: Firing a silenced weapon gives a message in text to the user. + MagmaRam: + - rscadd: Added instructions on how to use the changelog updating scripts. + - tweak: Updated in-game EVA manual. + Neerti: + - rscadd: Adds makeshift armor for the head and chest regions. How protective they + are depends on the material used to craft it. The helmet is made by using wirecutters + on a bucket, then using a stack of material. The chestpiece is made by crafting + two armor plate, using wires on one of them, then hiting one with the other. + Yoshax: + - bugfix: Water such as the pool will no longer apply fire stacks when you enter, + meaning you will no longer be flammable from swimming. diff --git a/html/changelogs/MagmaRam - changelog_instructions.yml b/html/changelogs/Anewbe - CultRobesEnergy.yml similarity index 93% rename from html/changelogs/MagmaRam - changelog_instructions.yml rename to html/changelogs/Anewbe - CultRobesEnergy.yml index 82235bc8f6..1d865cb090 100644 --- a/html/changelogs/MagmaRam - changelog_instructions.yml +++ b/html/changelogs/Anewbe - CultRobesEnergy.yml @@ -22,7 +22,7 @@ ################################# # Your name. -author: MagmaRam +author: Anewbe # Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. delete-after: True @@ -33,4 +33,4 @@ delete-after: True # Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. # Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. changes: - - rscadd: "Added instructions on how to use the changelog updating scripts." + - rscadd: "Cultist armor now has better protection from strange energies." diff --git a/html/changelogs/Yoshax-HumanTorch.yml b/html/changelogs/Anewbe - Ion Pistol.yml similarity index 89% rename from html/changelogs/Yoshax-HumanTorch.yml rename to html/changelogs/Anewbe - Ion Pistol.yml index 5ecdc4dd9a..efc5c77c0e 100644 --- a/html/changelogs/Yoshax-HumanTorch.yml +++ b/html/changelogs/Anewbe - Ion Pistol.yml @@ -22,7 +22,7 @@ ################################# # Your name. -author: Yoshax +author: Anewbe # Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. delete-after: True @@ -33,4 +33,5 @@ delete-after: True # Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. # Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. changes: - - bugfix: "Water such as the pool will no longer apply fire stacks when you enter, meaning you will no longer be flammable from swimming." + - rscadd: "Adds the ion pistol to the uplink." + - tweak: "The ion pistol can now be holstered. \ No newline at end of file diff --git a/html/changelogs/MagmaRam - evabook.yml b/html/changelogs/Anewbe - Smoking Pipes.yml similarity index 94% rename from html/changelogs/MagmaRam - evabook.yml rename to html/changelogs/Anewbe - Smoking Pipes.yml index f94057e6a4..33ebbe8158 100644 --- a/html/changelogs/MagmaRam - evabook.yml +++ b/html/changelogs/Anewbe - Smoking Pipes.yml @@ -22,7 +22,7 @@ ################################# # Your name. -author: MagmaRam +author: Anewbe # Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. delete-after: True @@ -33,4 +33,4 @@ delete-after: True # Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. # Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. changes: - - tweak: "Updated in-game EVA manual." + - bugfix: "Sprites on the smoking pipes should be fixed." diff --git a/html/changelogs/Atermonera - Translators2.yml b/html/changelogs/Atermonera - Records.yml similarity index 92% rename from html/changelogs/Atermonera - Translators2.yml rename to html/changelogs/Atermonera - Records.yml index f330795d80..9b66e57129 100644 --- a/html/changelogs/Atermonera - Translators2.yml +++ b/html/changelogs/Atermonera - Records.yml @@ -1,36 +1,36 @@ -################################ -# Example Changelog File -# -# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. -# -# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) -# When it is, any changes listed below will disappear. -# -# Valid Prefixes: -# bugfix -# wip (For works in progress) -# tweak -# soundadd -# sounddel -# rscadd (general adding of nice things) -# rscdel (general deleting of nice things) -# imageadd -# imagedel -# maptweak -# spellcheck (typo fixes) -# experiment -################################# - -# Your name. -author: Atermonera - -# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. -delete-after: True - -# Any changes you've made. See valid prefix list above. -# INDENT WITH TWO SPACES. NOT TABS. SPACES. -# SCREW THIS UP AND IT WON'T WORK. -# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. -# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. -changes: - - bugfix: "Translators no longer try to translate null languages." +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Atermonera + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Brain type (Organic, cyborg, posi, or drone) is now displayed in all records." diff --git a/html/changelogs/Leshana-footstep-sounds.yml b/html/changelogs/Leshana-footstep-sounds.yml new file mode 100644 index 0000000000..2e0045dd90 --- /dev/null +++ b/html/changelogs/Leshana-footstep-sounds.yml @@ -0,0 +1,4 @@ +author: Leshana +delete-after: True +changes: + - rscadd: "Implements footstep sound system and adds sounds to various floor types including plating, tiles, wood, and carpet." diff --git a/html/changelogs/LorenLuke - Bodybags.yml b/html/changelogs/LorenLuke - Bodybags.yml new file mode 100644 index 0000000000..e9dbd37406 --- /dev/null +++ b/html/changelogs/LorenLuke - Bodybags.yml @@ -0,0 +1,37 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Belsima + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "Changes relaymove() code in bodybags." + - bugfix: "Above tweak used to allow exiting bodybag while in closed morgue tray." diff --git a/html/changelogs/LorenLuke - Buckle-Give.yml b/html/changelogs/LorenLuke - Buckle-Give.yml new file mode 100644 index 0000000000..1332c7c576 --- /dev/null +++ b/html/changelogs/LorenLuke - Buckle-Give.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: LorenLuke + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - bugfix: "Allows people who are bucked to give/receive items." diff --git a/html/changelogs/LorenLuke - Bucklechanges.yml b/html/changelogs/LorenLuke - Bucklechanges.yml new file mode 100644 index 0000000000..771cce1148 --- /dev/null +++ b/html/changelogs/LorenLuke - Bucklechanges.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: LorenLuke + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "Can click-drag people onto chairs/beds from 1 tile away to buckle them." diff --git a/html/changelogs/LorenLuke - Tape.yml b/html/changelogs/LorenLuke - Tape.yml new file mode 100644 index 0000000000..42135bb9ca --- /dev/null +++ b/html/changelogs/LorenLuke - Tape.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: LorenLuke + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "Allows you to place tape masks/restraints back on the roll (roll is still infinite)." diff --git a/html/changelogs/LorenLuke - Ventcrawl.yml b/html/changelogs/LorenLuke - Ventcrawl.yml new file mode 100644 index 0000000000..ad43257fdc --- /dev/null +++ b/html/changelogs/LorenLuke - Ventcrawl.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: LorenLuke + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - bugfix: "Fixes ventcrawling for spiderbots/implants/etc." diff --git a/html/changelogs/Neerti-DroneID.yml b/html/changelogs/Neerti-DroneID.yml new file mode 100644 index 0000000000..15837f65b8 --- /dev/null +++ b/html/changelogs/Neerti-DroneID.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Neerti + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Drones will now spawn with an EIO-mandated ID card alongside their NT ID." diff --git a/html/changelogs/Yoshax-Tape.yml b/html/changelogs/Yoshax-Tape.yml new file mode 100644 index 0000000000..ffc7f56037 --- /dev/null +++ b/html/changelogs/Yoshax-Tape.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Yoshax + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "Tape color is different now. Security tape is red rather than yellow, Engineering tape remains yellow and Atmos tape is a lighter cyan rather than blue." \ No newline at end of file diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index a69e893b6f..c13a604dba 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 7407aeefb5..44f920fe30 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/human_races/r_lizard.dmi b/icons/mob/human_races/r_lizard.dmi index 5fb2c58be4..97e6f04bdc 100644 Binary files a/icons/mob/human_races/r_lizard.dmi and b/icons/mob/human_races/r_lizard.dmi differ diff --git a/icons/mob/items/lefthand_guns.dmi b/icons/mob/items/lefthand_guns.dmi index ff49dc5577..7b2b705c94 100644 Binary files a/icons/mob/items/lefthand_guns.dmi and b/icons/mob/items/lefthand_guns.dmi differ diff --git a/icons/mob/items/righthand_guns.dmi b/icons/mob/items/righthand_guns.dmi index 44521ed36e..7c05fbd61d 100644 Binary files a/icons/mob/items/righthand_guns.dmi and b/icons/mob/items/righthand_guns.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 00f14c373e..8a4ce2c73e 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/species/tajaran/helmet.dmi b/icons/mob/species/tajaran/helmet.dmi index 87a3d3f58f..ff89b2dcdd 100644 Binary files a/icons/mob/species/tajaran/helmet.dmi and b/icons/mob/species/tajaran/helmet.dmi differ diff --git a/icons/mob/species/tajaran/mask.dmi b/icons/mob/species/tajaran/mask.dmi index cf3be6425f..d7028d66a6 100644 Binary files a/icons/mob/species/tajaran/mask.dmi and b/icons/mob/species/tajaran/mask.dmi differ diff --git a/icons/mob/species/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi index 1af66a7d08..618d3be573 100644 Binary files a/icons/mob/species/unathi/helmet.dmi and b/icons/mob/species/unathi/helmet.dmi differ diff --git a/icons/mob/species/unathi/mask.dmi b/icons/mob/species/unathi/mask.dmi index cf3be6425f..25cc585aed 100644 Binary files a/icons/mob/species/unathi/mask.dmi and b/icons/mob/species/unathi/mask.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 5d7180da7c..b2eb9c72fe 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi index e1a2c1c2ae..390fdb88ea 100644 Binary files a/icons/obj/card.dmi and b/icons/obj/card.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 9337d5127c..ef18c7bf49 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index b6b28fdfbe..fd3ff5ceca 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index b1750efa36..c1183a4e93 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index d9e2dfef95..ba02b5a324 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index dc3456ba67..778ec461bb 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index b2ff3108ea..39ed73fc3d 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi index 5671731aab..9bb3378c8e 100755 Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ diff --git a/icons/policetape.dmi b/icons/policetape.dmi index bc469f2eab..5dde02f1b5 100644 Binary files a/icons/policetape.dmi and b/icons/policetape.dmi differ diff --git a/nano/templates/pai_medrecords.tmpl b/nano/templates/pai_medrecords.tmpl index 89926d3915..24e00e949f 100644 --- a/nano/templates/pai_medrecords.tmpl +++ b/nano/templates/pai_medrecords.tmpl @@ -19,6 +19,10 @@ code/modules/mob/living/silicon/pai/software_modules.dm
      Record ID
      {{:data.general.id}}
      +
      +
      Entity Classification
      +
      {{:data.general.brain_type}}
      +
      Sex
      {{:data.general.sex}}
      diff --git a/nano/templates/pai_secrecords.tmpl b/nano/templates/pai_secrecords.tmpl index 51cb45dee2..5ba1e4d90d 100644 --- a/nano/templates/pai_secrecords.tmpl +++ b/nano/templates/pai_secrecords.tmpl @@ -19,6 +19,10 @@ code/modules/mob/living/silicon/pai/software_modules.dm
      Record ID
      {{:data.general.id}}
      +
      +
      Entity Classification
      +
      {{:data.general.brain_type}}
      +
      Sex
      {{:data.general.sex}}
      diff --git a/nano/templates/pda.tmpl b/nano/templates/pda.tmpl index 6cd3004654..77f026a349 100644 --- a/nano/templates/pda.tmpl +++ b/nano/templates/pda.tmpl @@ -568,6 +568,7 @@ Used In File(s): \code\game\objects\items\devices\PDA\PDA.dm
      {{if data.records.general_exists == 1}} Name: {{:data.records.general.name}}
      + Entity Class: {{:data.records.general.brain_type}}
      Sex: {{:data.records.general.sex}}
      Species: {{:data.records.general.species}}
      Age: {{:data.records.general.age}}
      diff --git a/sound/effects/footstep/carpet1.ogg b/sound/effects/footstep/carpet1.ogg new file mode 100644 index 0000000000..2735a9bf3d Binary files /dev/null and b/sound/effects/footstep/carpet1.ogg differ diff --git a/sound/effects/footstep/carpet2.ogg b/sound/effects/footstep/carpet2.ogg new file mode 100644 index 0000000000..07e5f2320a Binary files /dev/null and b/sound/effects/footstep/carpet2.ogg differ diff --git a/sound/effects/footstep/carpet3.ogg b/sound/effects/footstep/carpet3.ogg new file mode 100644 index 0000000000..edb0193f6e Binary files /dev/null and b/sound/effects/footstep/carpet3.ogg differ diff --git a/sound/effects/footstep/carpet4.ogg b/sound/effects/footstep/carpet4.ogg new file mode 100644 index 0000000000..c9598e2b73 Binary files /dev/null and b/sound/effects/footstep/carpet4.ogg differ diff --git a/sound/effects/footstep/carpet5.ogg b/sound/effects/footstep/carpet5.ogg new file mode 100644 index 0000000000..076818323a Binary files /dev/null and b/sound/effects/footstep/carpet5.ogg differ diff --git a/sound/effects/footstep/floor1.ogg b/sound/effects/footstep/floor1.ogg new file mode 100644 index 0000000000..1e3e155839 Binary files /dev/null and b/sound/effects/footstep/floor1.ogg differ diff --git a/sound/effects/footstep/floor2.ogg b/sound/effects/footstep/floor2.ogg new file mode 100644 index 0000000000..cce5a25d82 Binary files /dev/null and b/sound/effects/footstep/floor2.ogg differ diff --git a/sound/effects/footstep/floor3.ogg b/sound/effects/footstep/floor3.ogg new file mode 100644 index 0000000000..16ab67f729 Binary files /dev/null and b/sound/effects/footstep/floor3.ogg differ diff --git a/sound/effects/footstep/floor4.ogg b/sound/effects/footstep/floor4.ogg new file mode 100644 index 0000000000..9ef15430ff Binary files /dev/null and b/sound/effects/footstep/floor4.ogg differ diff --git a/sound/effects/footstep/floor5.ogg b/sound/effects/footstep/floor5.ogg new file mode 100644 index 0000000000..0f6a66057d Binary files /dev/null and b/sound/effects/footstep/floor5.ogg differ diff --git a/sound/effects/footstep/hull1.ogg b/sound/effects/footstep/hull1.ogg new file mode 100644 index 0000000000..615df6c550 Binary files /dev/null and b/sound/effects/footstep/hull1.ogg differ diff --git a/sound/effects/footstep/hull2.ogg b/sound/effects/footstep/hull2.ogg new file mode 100644 index 0000000000..3aecb743f7 Binary files /dev/null and b/sound/effects/footstep/hull2.ogg differ diff --git a/sound/effects/footstep/hull3.ogg b/sound/effects/footstep/hull3.ogg new file mode 100644 index 0000000000..03339131f6 Binary files /dev/null and b/sound/effects/footstep/hull3.ogg differ diff --git a/sound/effects/footstep/hull4.ogg b/sound/effects/footstep/hull4.ogg new file mode 100644 index 0000000000..2fba89d318 Binary files /dev/null and b/sound/effects/footstep/hull4.ogg differ diff --git a/sound/effects/footstep/hull5.ogg b/sound/effects/footstep/hull5.ogg new file mode 100644 index 0000000000..10c5912b97 Binary files /dev/null and b/sound/effects/footstep/hull5.ogg differ diff --git a/sound/effects/footstep/plating1.ogg b/sound/effects/footstep/plating1.ogg new file mode 100644 index 0000000000..0df770e663 Binary files /dev/null and b/sound/effects/footstep/plating1.ogg differ diff --git a/sound/effects/footstep/plating2.ogg b/sound/effects/footstep/plating2.ogg new file mode 100644 index 0000000000..314b9133d2 Binary files /dev/null and b/sound/effects/footstep/plating2.ogg differ diff --git a/sound/effects/footstep/plating3.ogg b/sound/effects/footstep/plating3.ogg new file mode 100644 index 0000000000..5c571d77eb Binary files /dev/null and b/sound/effects/footstep/plating3.ogg differ diff --git a/sound/effects/footstep/plating4.ogg b/sound/effects/footstep/plating4.ogg new file mode 100644 index 0000000000..5953262764 Binary files /dev/null and b/sound/effects/footstep/plating4.ogg differ diff --git a/sound/effects/footstep/plating5.ogg b/sound/effects/footstep/plating5.ogg new file mode 100644 index 0000000000..4676a637a6 Binary files /dev/null and b/sound/effects/footstep/plating5.ogg differ diff --git a/sound/effects/footstep/wood1.ogg b/sound/effects/footstep/wood1.ogg new file mode 100644 index 0000000000..c76fc423fc Binary files /dev/null and b/sound/effects/footstep/wood1.ogg differ diff --git a/sound/effects/footstep/wood2.ogg b/sound/effects/footstep/wood2.ogg new file mode 100644 index 0000000000..71dc1aa967 Binary files /dev/null and b/sound/effects/footstep/wood2.ogg differ diff --git a/sound/effects/footstep/wood3.ogg b/sound/effects/footstep/wood3.ogg new file mode 100644 index 0000000000..bf86889006 Binary files /dev/null and b/sound/effects/footstep/wood3.ogg differ diff --git a/sound/effects/footstep/wood4.ogg b/sound/effects/footstep/wood4.ogg new file mode 100644 index 0000000000..44734425ce Binary files /dev/null and b/sound/effects/footstep/wood4.ogg differ diff --git a/sound/effects/footstep/wood5.ogg b/sound/effects/footstep/wood5.ogg new file mode 100644 index 0000000000..5ad4fa81e7 Binary files /dev/null and b/sound/effects/footstep/wood5.ogg differ diff --git a/vorestation.dme b/vorestation.dme index d2cc5088d9..fcc0e50d77 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -36,6 +36,7 @@ #include "code\__defines\misc.dm" #include "code\__defines\misc_vr.dm" #include "code\__defines\mobs.dm" +#include "code\__defines\planets.dm" #include "code\__defines\process_scheduler.dm" #include "code\__defines\research.dm" #include "code\__defines\roguemining_vr.dm" @@ -947,6 +948,7 @@ #include "code\game\objects\items\weapons\material\foam.dm" #include "code\game\objects\items\weapons\material\kitchen.dm" #include "code\game\objects\items\weapons\material\knives.dm" +#include "code\game\objects\items\weapons\material\material_armor.dm" #include "code\game\objects\items\weapons\material\material_weapons.dm" #include "code\game\objects\items\weapons\material\misc.dm" #include "code\game\objects\items\weapons\material\shards.dm" @@ -1612,6 +1614,7 @@ #include "code\modules\mob\mob_helpers.dm" #include "code\modules\mob\mob_movement.dm" #include "code\modules\mob\mob_transformation_simple.dm" +#include "code\modules\mob\modifiers.dm" #include "code\modules\mob\say.dm" #include "code\modules\mob\say_vr.dm" #include "code\modules\mob\transform_procs.dm" @@ -1944,6 +1947,7 @@ #include "code\modules\organs\subtypes\machine.dm" #include "code\modules\organs\subtypes\seromi.dm" #include "code\modules\organs\subtypes\standard.dm" +#include "code\modules\organs\subtypes\unathi.dm" #include "code\modules\organs\subtypes\unbreakable.dm" #include "code\modules\organs\subtypes\vox.dm" #include "code\modules\overmap\_defines.dm"