diff --git a/code/_macros.dm b/code/_macros.dm index 7e8d581b90..e8caac8345 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -7,6 +7,8 @@ #define isanimal(A) istype(A, /mob/living/simple_animal) +#define isairlock(A) istype(A, /obj/machinery/door/airlock) + #define isbrain(A) istype(A, /mob/living/carbon/brain) #define iscarbon(A) istype(A, /mob/living/carbon) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index bd817baf41..d456c52e71 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -21,7 +21,7 @@ var/list/gamemode_cache = list() var/log_pda = 0 // log pda messages var/log_hrefs = 0 // logs all links clicked in-game. Could be used for debugging and tracking down exploits var/log_runtime = 0 // logs world.log to a file - var/sql_enabled = 1 // for sql switching + var/sql_enabled = 0 // for sql switching var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour var/allow_vote_restart = 0 // allow votes to restart var/ert_admin_call_only = 0 @@ -289,7 +289,7 @@ var/list/gamemode_cache = list() config.log_access = 1 if ("sql_enabled") - config.sql_enabled = text2num(value) + config.sql_enabled = 1 if ("log_say") config.log_say = 1 diff --git a/code/controllers/hooks-defs.dm b/code/controllers/hooks-defs.dm index 001372b4e3..e330024475 100644 --- a/code/controllers/hooks-defs.dm +++ b/code/controllers/hooks-defs.dm @@ -1,87 +1,87 @@ -/** - * Startup hook. - * Called in world.dm when the server starts. - */ -/hook/startup - -/** - * Roundstart hook. - * Called in gameticker.dm when a round starts. - */ -/hook/roundstart - -/** - * Roundend hook. - * Called in gameticker.dm when a round ends. - */ -/hook/roundend - -/** - * Death hook. - * Called in death.dm when someone dies. - * Parameters: var/mob/living/carbon/human, var/gibbed - */ -/hook/death - -/** - * Cloning hook. - * Called in cloning.dm when someone is brought back by the wonders of modern science. - * Parameters: var/mob/living/carbon/human - */ -/hook/clone - -/** - * Debrained hook. - * Called in brain_item.dm when someone gets debrained. - * Parameters: var/obj/item/organ/brain - */ -/hook/debrain - -/** - * Borged hook. - * Called in robot_parts.dm when someone gets turned into a cyborg. - * Parameters: var/mob/living/silicon/robot - */ -/hook/borgify - -/** - * Podman hook. - * Called in podmen.dm when someone is brought back as a Diona. - * Parameters: var/mob/living/carbon/alien/diona - */ -/hook/harvest_podman - -/** - * Payroll revoked hook. - * Called in Accounts_DB.dm when someone's payroll is stolen at the Accounts terminal. - * Parameters: var/datum/money_account - */ -/hook/revoke_payroll - -/** - * Account suspension hook. - * Called in Accounts_DB.dm when someone's account is suspended or unsuspended at the Accounts terminal. - * Parameters: var/datum/money_account - */ -/hook/change_account_status - -/** - * Employee reassignment hook. - * Called in card.dm when someone's card is reassigned at the HoP's desk. - * Parameters: var/obj/item/weapon/card/id - */ -/hook/reassign_employee - -/** - * Employee terminated hook. - * Called in card.dm when someone's card is terminated at the HoP's desk. - * Parameters: var/obj/item/weapon/card/id - */ -/hook/terminate_employee - -/** - * Crate sold hook. - * Called in supplyshuttle.dm when a crate is sold on the shuttle. - * Parameters: var/obj/structure/closet/crate/sold, var/area/shuttle - */ -/hook/sell_crate +/** + * Startup hook. + * Called in world.dm when the server starts. + */ +/hook/startup + +/** + * Roundstart hook. + * Called in gameticker.dm when a round starts. + */ +/hook/roundstart + +/** + * Roundend hook. + * Called in gameticker.dm when a round ends. + */ +/hook/roundend + +/** + * Death hook. + * Called in death.dm when someone dies. + * Parameters: var/mob/living/carbon/human, var/gibbed + */ +/hook/death + +/** + * Cloning hook. + * Called in cloning.dm when someone is brought back by the wonders of modern science. + * Parameters: var/mob/living/carbon/human + */ +/hook/clone + +/** + * Debrained hook. + * Called in brain_item.dm when someone gets debrained. + * Parameters: var/obj/item/organ/brain + */ +/hook/debrain + +/** + * Borged hook. + * Called in robot_parts.dm when someone gets turned into a cyborg. + * Parameters: var/mob/living/silicon/robot + */ +/hook/borgify + +/** + * Podman hook. + * Called in podmen.dm when someone is brought back as a Diona. + * Parameters: var/mob/living/carbon/alien/diona + */ +/hook/harvest_podman + +/** + * Payroll revoked hook. + * Called in Accounts_DB.dm when someone's payroll is stolen at the Accounts terminal. + * Parameters: var/datum/money_account + */ +/hook/revoke_payroll + +/** + * Account suspension hook. + * Called in Accounts_DB.dm when someone's account is suspended or unsuspended at the Accounts terminal. + * Parameters: var/datum/money_account + */ +/hook/change_account_status + +/** + * Employee reassignment hook. + * Called in card.dm when someone's card is reassigned at the HoP's desk. + * Parameters: var/obj/item/weapon/card/id + */ +/hook/reassign_employee + +/** + * Employee terminated hook. + * Called in card.dm when someone's card is terminated at the HoP's desk. + * Parameters: var/obj/item/weapon/card/id + */ +/hook/terminate_employee + +/** + * Crate sold hook. + * Called in supplyshuttle.dm when a crate is sold on the shuttle. + * Parameters: var/obj/structure/closet/crate/sold, var/area/shuttle + */ +/hook/sell_crate diff --git a/code/controllers/observer_listener/atom/observer.dm b/code/controllers/observer_listener/atom/observer.dm new file mode 100644 index 0000000000..da38580414 --- /dev/null +++ b/code/controllers/observer_listener/atom/observer.dm @@ -0,0 +1,31 @@ +#define OBSERVER_EVENT_DESTROY "OnDestroy" + +/atom + var/list/observer_events + +/atom/Destroy() + var/list/destroy_listeners = get_listener_list_from_event(OBSERVER_EVENT_DESTROY) + if(destroy_listeners) + for(var/destroy_listener in destroy_listeners) + call(destroy_listener, destroy_listeners[destroy_listener])(src) + + for(var/list/listeners in observer_events) + listeners.Cut() + + return ..() + +/atom/proc/register(var/event, var/procOwner, var/proc_call) + var/list/listeners = get_listener_list_from_event(event) + listeners[procOwner] = proc_call + +/atom/proc/unregister(var/event, var/procOwner) + var/list/listeners = get_listener_list_from_event(event) + listeners -= procOwner + +/atom/proc/get_listener_list_from_event(var/observer_event) + if(!observer_events) observer_events = list() + var/list/listeners = observer_events[observer_event] + if(!listeners) + listeners = list() + observer_events[observer_event] = listeners + return listeners diff --git a/code/controllers/observer_listener/datum/observer.dm b/code/controllers/observer_listener/datum/observer.dm new file mode 100644 index 0000000000..61f6fbf180 --- /dev/null +++ b/code/controllers/observer_listener/datum/observer.dm @@ -0,0 +1,28 @@ +/* +#define OBSERVER_EVENT_DESTROY "OnDestroy" + +/datum + var/list/observer_events + +/datum/Destroy() + for(var/list/listeners in observer_events) + listeners.Cut() + + return ..() + +/datum/proc/register(var/event, var/procOwner, var/proc_call) + var/list/listeners = get_listener_list_from_event(event) + listeners[procOwner] = proc_call + +/datum/proc/unregister(var/event, var/procOwner) + var/list/listeners = get_listener_list_from_event(event) + listeners -= procOwner + +/datum/proc/get_listener_list_from_event(var/observer_event) + if(!observer_events) observer_events = list() + var/list/listeners = observer_events[observer_event] + if(!listeners) + listeners = list() + observer_events[observer_event] = listeners + return listeners +*/ diff --git a/code/game/gamemodes/changeling/absorbed_dna.dm b/code/game/gamemodes/changeling/absorbed_dna.dm index bdf243b412..3c23f0270c 100644 --- a/code/game/gamemodes/changeling/absorbed_dna.dm +++ b/code/game/gamemodes/changeling/absorbed_dna.dm @@ -4,11 +4,13 @@ var/speciesName var/list/languages var/identifying_gender + var/list/flavour_texts -/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender) +/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender, var/list/newFlavour) ..() name = newName dna = newDNA speciesName = newSpecies languages = newLanguages - identifying_gender = newIdentifying_Gender \ No newline at end of file + identifying_gender = newIdentifying_Gender + flavour_texts = newFlavour ? newFlavour.Copy() : null \ No newline at end of file diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index ae5ede1566..a89fe95d95 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -85,7 +85,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E var/mob/living/carbon/human/H = src if(istype(H)) - var/datum/absorbed_dna/newDNA = new(H.real_name, H.dna, H.species.name, H.languages, H.identifying_gender) + var/datum/absorbed_dna/newDNA = new(H.real_name, H.dna, H.species.name, H.languages, H.identifying_gender, H.flavor_texts) absorbDNA(newDNA) return 1 diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 16f34357b5..e75020fc59 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -71,7 +71,7 @@ src.verbs += /mob/proc/changeling_respec 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) + var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts) absorbDNA(newDNA) if(T.mind && T.mind.changeling) diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm index 0eec3ed213..57a55e2e21 100644 --- a/code/game/gamemodes/changeling/powers/transform.dm +++ b/code/game/gamemodes/changeling/powers/transform.dm @@ -37,11 +37,9 @@ if(ishuman(src)) var/mob/living/carbon/human/H = src H.b_type = "AB+" //For some reason we have two blood types on the mob. - for(var/flavor in H.flavor_texts) //Nulls out flavor text, so we don't keep our previous mob's flavor. - flavor = null H.identifying_gender = chosen_dna.identifying_gender + H.flavor_texts = chosen_dna.flavour_texts ? chosen_dna.flavour_texts.Copy() : null src.real_name = chosen_dna.name - src.flavor_text = "" src.UpdateAppearance() domutcheck(src, null) changeling_update_languages(changeling.absorbed_languages) diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index 7f82a34f1c..831edadcbf 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -327,7 +327,7 @@ src.updateUsrDialog() /obj/machinery/microwave/proc/dispose() - for (var/obj/O in (contents-component_parts)) + for (var/obj/O in ((contents-component_parts)-circuit)) O.loc = src.loc if (src.reagents.total_volume) src.dirty++ diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 74f60a3a72..7d8e75764c 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -13,6 +13,7 @@ var/on = 1 var/area/area = null var/otherarea = null + var/image/overlay /obj/machinery/light_switch/New() ..() @@ -31,14 +32,18 @@ /obj/machinery/light_switch/proc/updateicon() + if(!overlay) + overlay = image(icon, "light1-overlay", LIGHTING_LAYER+0.1) + + overlays.Cut() if(stat & NOPOWER) icon_state = "light-p" set_light(0) - layer = OBJ_LAYER else icon_state = "light[on]" - set_light(2, 1.5, on ? "#82FF4C" : "#F86060") - layer = LIGHTING_LAYER+0.1 + overlay.icon_state = "light[on]-overlay" + overlays += overlay + set_light(2, 0.1, on ? "#82FF4C" : "#F86060") /obj/machinery/light_switch/examine(mob/user) if(..(user, 1)) diff --git a/code/game/machinery/pda_multicaster.dm b/code/game/machinery/pda_multicaster.dm new file mode 100644 index 0000000000..a7d5c780c3 --- /dev/null +++ b/code/game/machinery/pda_multicaster.dm @@ -0,0 +1,101 @@ +/obj/machinery/pda_multicaster + name = "\improper PDA multicaster" + desc = "This machine mirrors messages sent to it to specific departments." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "controller" + density = 1 + anchored = 1 + circuit = /obj/item/weapon/circuitboard/telecomms/pda_multicaster + use_power = 1 + idle_power_usage = 750 + var/on = 1 // If we're currently active, + var/toggle = 1 // If we /should/ be active or not, + var/list/internal_PDAs = list() // Assoc list of PDAs inside of this, with the department name being the index, + +/obj/machinery/pda_multicaster/New() + ..() + internal_PDAs = list("command" = new /obj/item/device/pda/multicaster/command(src), + "security" = new /obj/item/device/pda/multicaster/security(src), + "engineering" = new /obj/item/device/pda/multicaster/engineering(src), + "medical" = new /obj/item/device/pda/multicaster/medical(src), + "research" = new /obj/item/device/pda/multicaster/research(src), + "cargo" = new /obj/item/device/pda/multicaster/cargo(src), + "civilian" = new /obj/item/device/pda/multicaster/civilian(src)) + +/obj/machinery/pda_multicaster/prebuilt/New() + ..() + + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/telecomms/pda_multicaster(src) + component_parts += new /obj/item/weapon/stock_parts/subspace/ansible(src) + component_parts += new /obj/item/weapon/stock_parts/subspace/filter(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/subspace/treatment(src) + component_parts += new /obj/item/stack/cable_coil(src, 2) + RefreshParts() + +/obj/machinery/pda_multicaster/Destroy() + for(var/atom/movable/AM in contents) + qdel(AM) + ..() + +/obj/machinery/pda_multicaster/update_icon() + if(on) + icon_state = initial(icon_state) + else + icon_state = "[initial(icon_state)]-p" + +/obj/machinery/pda_multicaster/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/screwdriver)) + default_deconstruction_screwdriver(user, I) + else if(istype(I, /obj/item/weapon/crowbar)) + default_deconstruction_crowbar(user, I) + else + ..() + +/obj/machinery/pda_multicaster/attack_ai(mob/user) + attack_hand(user) + +/obj/machinery/pda_multicaster/attack_hand(mob/user) + toggle_power(user) + +/obj/machinery/pda_multicaster/proc/toggle_power(mob/user) + toggle = !toggle + visible_message("\the [user] turns \the [src] [toggle ? "on" : "off"].") + update_power() + if(!toggle) + var/msg = "[usr.client.key] ([usr]) has turned [src] off, at [x],[y],[z]." + message_admins(msg) + log_game(msg) + +/obj/machinery/pda_multicaster/proc/update_PDAs(var/turn_off) + for(var/obj/item/device/pda/pda in contents) + pda.toff = turn_off + +/obj/machinery/pda_multicaster/proc/update_power() + if(toggle) + if(stat & (BROKEN|NOPOWER|EMPED)) + on = 0 + update_PDAs(1) // 1 being to turn off. + idle_power_usage = 0 + else + on = 1 + update_PDAs(0) + idle_power_usage = 750 + else + on = 0 + update_PDAs(1) + idle_power_usage = 0 + update_icon() + +/obj/machinery/pda_multicaster/process() + update_power() + +/obj/machinery/pda_multicaster/emp_act(severity) + if(!(stat & EMPED)) + stat |= EMPED + var/duration = (300 * 10)/severity + spawn(rand(duration - 20, duration + 20)) + stat &= ~EMPED + update_icon() + ..() diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index fcb52986a4..01fc592690 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -213,10 +213,10 @@ steam.start() -- spawns the effect icon = 'icons/effects/effects.dmi' icon_state = "sparks" -/obj/effect/effect/smoke/illumination/New(var/newloc, var/brightness=15, var/lifetime=10) +/obj/effect/effect/smoke/illumination/New(var/newloc, var/lifetime=10, var/range=null, var/power=null, var/color=null) time_to_live=lifetime ..() - set_light(brightness) + set_light(range, power, color) ///////////////////////////////////////////// // Bad smoke diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index a3db6b15a1..f0bb82efd0 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -163,6 +163,7 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/shaftminer icon_state = "pda-miner" + default_cartridge = /obj/item/weapon/cartridge/miner /obj/item/device/pda/syndicate default_cartridge = /obj/item/weapon/cartridge/syndicate @@ -172,6 +173,7 @@ var/global/list/obj/item/device/pda/PDAs = list() hidden = 1 /obj/item/device/pda/chaplain + default_cartridge = /obj/item/weapon/cartridge/service icon_state = "pda-holy" ttone = "holy" @@ -181,13 +183,15 @@ var/global/list/obj/item/device/pda/PDAs = list() ttone = "..." /obj/item/device/pda/botanist - //default_cartridge = /obj/item/weapon/cartridge/botanist + default_cartridge = /obj/item/weapon/cartridge/service icon_state = "pda-hydro" /obj/item/device/pda/roboticist + default_cartridge = /obj/item/weapon/cartridge/signal/science icon_state = "pda-robot" /obj/item/device/pda/librarian + default_cartridge = /obj/item/weapon/cartridge/service icon_state = "pda-libb" desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a WGW-11 series e-reader." note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!" @@ -200,9 +204,11 @@ var/global/list/obj/item/device/pda/PDAs = list() note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition!" /obj/item/device/pda/chef + default_cartridge = /obj/item/weapon/cartridge/service icon_state = "pda-chef" /obj/item/device/pda/bar + default_cartridge = /obj/item/weapon/cartridge/service icon_state = "pda-bar" /obj/item/device/pda/atmos @@ -304,6 +310,99 @@ var/global/list/obj/item/device/pda/PDAs = list() ttone = "assist" +// Used for the PDA multicaster, which mirrors messages sent to it to a specific department, +/obj/item/device/pda/multicaster + ownjob = "Relay" + icon_state = "NONE" + ttone = "data" + detonate = 0 + news_silent = 1 + var/list/cartridges_to_send_to = list() + +// This is what actually mirrors the message, +/obj/item/device/pda/multicaster/new_message(var/sending_unit, var/sender, var/sender_job, var/message) + if(sender) + var/list/targets = list() + for(var/obj/item/device/pda/pda in PDAs) + if(pda.cartridge && pda.owner && is_type_in_list(pda.cartridge, cartridges_to_send_to)) + targets |= pda + if(targets.len) + for(var/obj/item/device/pda/target in targets) + create_message(target, sender, sender_job, message) + +// This has so much copypasta, +/obj/item/device/pda/multicaster/create_message(var/obj/item/device/pda/P, var/original_sender, var/original_job, var/t) + t = sanitize(t, MAX_MESSAGE_LEN, 0) + t = replace_characters(t, list(""" = "\"")) + if (!t || !istype(P)) + return + + if (isnull(P)||P.toff || toff) + return + + last_text = world.time + var/datum/reception/reception = get_reception(src, P, t) + t = reception.message + + if(reception.message_server && (reception.telecomms_reception & TELECOMMS_RECEPTION_SENDER)) // only send the message if it's stable, + if(reception.telecomms_reception & TELECOMMS_RECEPTION_RECEIVER == 0) // Does our recipient have a broadcaster on their level?, + return + var/send_result = reception.message_server.send_pda_message("[P.owner]","[owner]","[t]") + if (send_result) + return + + P.tnote.Add(list(list("sent" = 0, "owner" = "[owner]", "job" = "[ownjob]", "message" = "[t]", "target" = "\ref[src]"))) + + if(!P.conversations.Find("\ref[src]")) + P.conversations.Add("\ref[src]") + + P.new_message(src, "[original_sender] \[Relayed\]", original_job, t, 0) + + else + return + +/obj/item/device/pda/multicaster/command/New() + ..() + owner = "Command Department" + name = "Command Department (Relay)" + cartridges_to_send_to = command_cartridges + +/obj/item/device/pda/multicaster/security/New() + ..() + owner = "Security Department" + name = "Security Department (Relay)" + cartridges_to_send_to = security_cartridges + +/obj/item/device/pda/multicaster/engineering/New() + ..() + owner = "Engineering Department" + name = "Engineering Department (Relay)" + cartridges_to_send_to = engineering_cartridges + +/obj/item/device/pda/multicaster/medical/New() + ..() + owner = "Medical Department" + name = "Medical Department (Relay)" + cartridges_to_send_to = medical_cartridges + +/obj/item/device/pda/multicaster/research/New() + ..() + owner = "Research Department" + name = "Research Department (Relay)" + cartridges_to_send_to = research_cartridges + +/obj/item/device/pda/multicaster/cargo/New() + ..() + owner = "Cargo Department" + name = "Cargo Department (Relay)" + cartridges_to_send_to = cargo_cartridges + +/obj/item/device/pda/multicaster/civilian/New() + ..() + owner = "Civilian Services Department" + name = "Civilian Services Department (Relay)" + cartridges_to_send_to = civilian_cartridges + /* * The Actual PDA */ @@ -932,7 +1031,7 @@ var/global/list/obj/item/device/pda/PDAs = list() message += "Your [P] bleeps loudly." j = prob(10) - if(j) //This kills the PDA + if(j && detonate) //This kills the PDA qdel(P) if(message) message += "It melts in a puddle of plastic." @@ -1046,8 +1145,8 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/proc/new_message_from_pda(var/obj/item/device/pda/sending_device, var/message) new_message(sending_device, sending_device.owner, sending_device.ownjob, message) -/obj/item/device/pda/proc/new_message(var/sending_unit, var/sender, var/sender_job, var/message) - var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" (Reply)" +/obj/item/device/pda/proc/new_message(var/sending_unit, var/sender, var/sender_job, var/message, var/reply = 1) + var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" ([reply ? "Reply" : "Unable to Reply"])" new_info(message_silent, ttone, reception_message) log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]") diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index 5d576959fb..a0e37e28b8 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -1,3 +1,48 @@ +var/list/command_cartridges = list( + /obj/item/weapon/cartridge/captain, + /obj/item/weapon/cartridge/hop, + /obj/item/weapon/cartridge/hos, + /obj/item/weapon/cartridge/ce, + /obj/item/weapon/cartridge/rd, + /obj/item/weapon/cartridge/head, + /obj/item/weapon/cartridge/lawyer // Internal Affaris, + ) + +var/list/security_cartridges = list( + /obj/item/weapon/cartridge/security, + /obj/item/weapon/cartridge/detective, + /obj/item/weapon/cartridge/hos + ) + +var/list/engineering_cartridges = list( + /obj/item/weapon/cartridge/engineering, + /obj/item/weapon/cartridge/atmos, + /obj/item/weapon/cartridge/ce + ) + +var/list/medical_cartridges = list( + /obj/item/weapon/cartridge/medical, + /obj/item/weapon/cartridge/chemistry, + /obj/item/weapon/cartridge/cmo + ) + +var/list/research_cartridges = list( + /obj/item/weapon/cartridge/signal/science, + /obj/item/weapon/cartridge/rd + ) + +var/list/cargo_cartridges = list( + /obj/item/weapon/cartridge/quartermaster, // This also covers cargo-techs, apparently, + /obj/item/weapon/cartridge/miner, + /obj/item/weapon/cartridge/hop + ) + +var/list/civilian_cartridges = list( + /obj/item/weapon/cartridge/janitor, + /obj/item/weapon/cartridge/service, + /obj/item/weapon/cartridge/hop + ) + /obj/item/weapon/cartridge name = "generic cartridge" desc = "A data cartridge for portable microcomputers." @@ -98,6 +143,10 @@ access_flora = 1 */ +/obj/item/weapon/cartridge/service + name = "\improper Serv-U Pro" + desc = "A data cartridge designed to serve YOU!" + /obj/item/weapon/cartridge/signal name = "generic signaler cartridge" desc = "A data cartridge with an integrated radio signaler module." @@ -124,6 +173,11 @@ icon_state = "cart-q" access_quartermaster = 1 +/obj/item/weapon/cartridge/miner + name = "\improper Drill-Jockey 4.5" + desc = "It's covered in some sort of sand." + icon_state = "cart-q" + /obj/item/weapon/cartridge/head name = "\improper Easy-Record DELUXE" icon_state = "cart-h" diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index da512f9449..0024a05c62 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -60,6 +60,10 @@ else //can only use it 5 times a minute user << "*click* *click*" return + + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + user.do_attack_animation(M) + playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) var/flashfail = 0 @@ -112,6 +116,7 @@ /obj/item/device/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0) if(!user || !clown_check(user)) return + if(broken) user.show_message("The [src.name] is broken", 2) return @@ -131,6 +136,7 @@ else //can only use it 5 times a minute user.show_message("*click* *click*", 2) return + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) flick("flash2", src) if(user && isrobot(user)) diff --git a/code/game/objects/items/devices/hacktool.dm b/code/game/objects/items/devices/hacktool.dm new file mode 100644 index 0000000000..0cf4af6c74 --- /dev/null +++ b/code/game/objects/items/devices/hacktool.dm @@ -0,0 +1,100 @@ +/obj/item/device/multitool/hacktool + var/is_hacking = 0 + var/max_known_targets + + var/in_hack_mode = 0 + var/list/known_targets + var/list/supported_types + var/datum/topic_state/default/must_hack/hack_state + +/obj/item/device/multitool/hacktool/New() + ..() + known_targets = list() + max_known_targets = 5 + rand(1,3) + supported_types = list(/obj/machinery/door/airlock) + hack_state = new(src) + +/obj/item/device/multitool/hacktool/Destroy() + for(var/T in known_targets) + var/atom/target = T + target.unregister(OBSERVER_EVENT_DESTROY, src) + known_targets.Cut() + qdel(hack_state) + hack_state = null + return ..() + +/obj/item/device/multitool/hacktool/attackby(var/obj/W, var/mob/user) + if(isscrewdriver(W)) + in_hack_mode = !in_hack_mode + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + else + ..() + +/obj/item/device/multitool/hacktool/resolve_attackby(atom/A, mob/user) + sanity_check() + + if(!in_hack_mode) + return ..() + + if(!attempt_hack(user, A)) + return 0 + + A.ui_interact(user, state = hack_state) + return 1 + +/obj/item/device/multitool/hacktool/proc/attempt_hack(var/mob/user, var/atom/target) + if(is_hacking) + user << "You are already hacking!" + return 0 + if(!is_type_in_list(target, supported_types)) + user << "\icon[src] Unable to hack this target!" + return 0 + var/found = known_targets.Find(target) + if(found) + known_targets.Swap(1, found) // Move the last hacked item first + return 1 + + user << "You begin hacking \the [target]..." + is_hacking = 1 + // On average hackin takes ~30 seconds. Fairly small random span to avoid people simply aborting and trying again + var/hack_result = do_after(user, (20 SECONDS + rand(0, 10 SECONDS) + rand(0, 10 SECONDS))) + is_hacking = 0 + + if(hack_result && in_hack_mode) + user << "Your hacking attempt was succesful!" + playsound(src.loc, 'sound/piano/A#6.ogg', 75) + else + user << "Your hacking attempt failed!" + return 0 + + known_targets.Insert(1, target) // Insert the newly hacked target first, + target.register(OBSERVER_EVENT_DESTROY, src, /obj/item/device/multitool/hacktool/proc/on_target_destroy) + return 1 + +/obj/item/device/multitool/hacktool/proc/sanity_check() + if(max_known_targets < 1) max_known_targets = 1 + // Cut away the oldest items if the capacity has been reached + if(known_targets.len > max_known_targets) + for(var/i = (max_known_targets + 1) to known_targets.len) + var/atom/A = known_targets[i] + A.unregister(OBSERVER_EVENT_DESTROY, src) + known_targets.Cut(max_known_targets + 1) + +/obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target) + known_targets -= target + +/datum/topic_state/default/must_hack + var/obj/item/device/multitool/hacktool/hacktool + +/datum/topic_state/default/must_hack/New(var/hacktool) + src.hacktool = hacktool + ..() + +/datum/topic_state/default/must_hack/Destroy() + hacktool = null + return ..() + +/datum/topic_state/default/must_hack/can_use_topic(var/src_object, var/mob/user) + if(!hacktool || !hacktool.in_hack_mode || !(src_object in hacktool.known_targets)) + return STATUS_CLOSE + return ..() diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 867e64f446..e7cb6f3475 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -20,4 +20,4 @@ origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1) var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage - var/obj/machinery/clonepod/connecting //same for cryopod linkage \ No newline at end of file + var/obj/machinery/clonepod/connecting //same for cryopod linkage diff --git a/code/game/objects/items/devices/uplink_items.dm b/code/game/objects/items/devices/uplink_items.dm index bc9666990b..b0ee3689a1 100644 --- a/code/game/objects/items/devices/uplink_items.dm +++ b/code/game/objects/items/devices/uplink_items.dm @@ -411,6 +411,14 @@ datum/uplink_item/dd_SortValue() item_cost = 3 path = /obj/item/weapon/card/emag +/datum/uplink_item/item/tools/hacking_tool + name = "Door Hacking Tool" + item_cost = 2 + path = /obj/item/device/multitool/hacktool + desc = "Appears and functions as a standard multitool until the mode is toggled by applying a screwdriver appropriately. \ + When in hacking mode this device will grant full access to any standard airlock within 20 to 40 seconds. \ + This device will also be able to immediately access the last 6 to 8 hacked airlocks." + /datum/uplink_item/item/tools/clerical name = "Morphic Clerical Kit" item_cost = 3 diff --git a/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm b/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm index 43b654d58d..8a7516f476 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm @@ -87,3 +87,14 @@ /obj/item/weapon/stock_parts/subspace/crystal = 1, /obj/item/weapon/stock_parts/subspace/treatment = 2, /obj/item/stack/cable_coil = 2) + +/obj/item/weapon/circuitboard/telecomms/pda_multicaster + name = T_BOARD("pda multicaster") + build_path = "/obj/machinery/pda_multicaster" + origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2, TECH_BLUESPACE = 2) + req_components = list( + /obj/item/weapon/stock_parts/subspace/ansible = 1, + /obj/item/weapon/stock_parts/subspace/filter = 1, + /obj/item/weapon/stock_parts/manipulator = 1, + /obj/item/weapon/stock_parts/subspace/treatment = 1, + /obj/item/stack/cable_coil = 2) diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index a95d3b1382..17616942c1 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -22,13 +22,13 @@ B.update_icon() new/obj/effect/effect/sparks(src.loc) - new/obj/effect/effect/smoke/illumination(src.loc, brightness=15) + new/obj/effect/effect/smoke/illumination(src.loc, 5, range=30, power=30, color="#FFFFFF") qdel(src) return proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged. M << "BANG" // Called during the loop that bangs people in lockers/containers and when banging - playsound(src.loc, 'sound/effects/bang.ogg', 50, 1, 5) // people in normal view. Could theroetically be called during other explosions. + playsound(src.loc, 'sound/effects/bang.ogg', 50, 1, 30) // people in normal view. Could theroetically be called during other explosions. // -- Polymorph //Checking for protections diff --git a/code/game/objects/items/weapons/material/kitchen.dm b/code/game/objects/items/weapons/material/kitchen.dm index b5c966ebd5..ff1d347c74 100644 --- a/code/game/objects/items/weapons/material/kitchen.dm +++ b/code/game/objects/items/weapons/material/kitchen.dm @@ -57,6 +57,8 @@ name = "fork" desc = "It's a fork. Sure is pointy." icon_state = "fork" + sharp = 1 + edge = 0 /obj/item/weapon/material/kitchen/utensil/fork/plastic default_material = "plastic" diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm index 80d3771f0e..dcd33fa172 100644 --- a/code/game/objects/items/weapons/material/misc.dm +++ b/code/game/objects/items/weapons/material/misc.dm @@ -1,7 +1,7 @@ /obj/item/weapon/material/harpoon name = "harpoon" sharp = 1 - edge = 1 + edge = 0 desc = "Tharr she blows!" icon_state = "harpoon" item_state = "harpoon" diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm index 52b949cf35..f821ab1db6 100644 --- a/code/game/objects/items/weapons/material/twohanded.dm +++ b/code/game/objects/items/weapons/material/twohanded.dm @@ -68,7 +68,7 @@ /obj/item/weapon/material/twohanded/update_icon() icon_state = "[base_icon][wielded]" item_state = icon_state - + /obj/item/weapon/material/twohanded/dropped() ..() if(wielded) @@ -119,7 +119,7 @@ unwielded_force_divisor = 0.65 // 14 when unwielded based on above thrown_force_divisor = 1.5 // 20 when thrown with weight 15 (glass) throw_speed = 3 - edge = 1 + edge = 0 sharp = 1 hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "poked", "jabbed", "torn", "gored") diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index a79d6575e5..a9e6192796 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -46,6 +46,7 @@ throw_range = 5 matter = list(DEFAULT_WALL_MATERIAL = 75) attack_verb = list("stabbed") + sharp = 1 suicide_act(mob/user) viewers(user) << pick("\The [user] is stabbing the [src.name] into \his temple! It looks like \he's trying to commit suicide.", \ diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 8ce2a88f24..2dcb1ddaad 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -55,6 +55,9 @@ /obj/structure/displaycase/attackby(obj/item/weapon/W as obj, mob/user as mob) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + user.do_attack_animation(src) + playsound(loc, 'sound/effects/Glasshit.ogg', 50, 1) src.health -= W.force src.healthcheck() ..() diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm index 369f42fc38..ad7a0f91ce 100644 --- a/code/game/turfs/flooring/flooring.dm +++ b/code/game/turfs/flooring/flooring.dm @@ -69,7 +69,7 @@ var/list/flooring_types name = "carpet" icon_base = "bcarpet" build_type = null - flags = TURF_HAS_EDGES | TURF_HAS_CORNERS | TURF_REMOVE_CROWBAR | TURF_CAN_BURN + flags = TURF_HAS_EDGES | TURF_REMOVE_CROWBAR /decl/flooring/tiling name = "floor" diff --git a/code/game/verbs/ignore.dm b/code/game/verbs/ignore.dm index b772bd4e81..c154628087 100644 --- a/code/game/verbs/ignore.dm +++ b/code/game/verbs/ignore.dm @@ -10,6 +10,10 @@ if(key_to_ignore in prefs.ignored_players) usr << "[key_to_ignore] is already being ignored." return + if(key_to_ignore == usr.ckey) + usr <<"You can't ignore yourself." + return + prefs.ignored_players |= key_to_ignore prefs.save_preferences() usr << "Now ignoring [key_to_ignore]." diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 701f24dc2e..2588836df5 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -41,7 +41,8 @@ datum/preferences/proc/set_biological_gender(var/gender) pref.be_random_name = sanitize_integer(pref.be_random_name, 0, 1, initial(pref.be_random_name)) /datum/category_item/player_setup_item/general/basic/content() - . = "Name: " + . = list() + . += "Name: " . += "[pref.real_name]
" . += "Randomize Name
" . += "Always Random Name: [pref.be_random_name ? "Yes" : "No"]" @@ -52,6 +53,7 @@ datum/preferences/proc/set_biological_gender(var/gender) . += "Spawn Point: [pref.spawnpoint]
" if(config.allow_Metadata) . += "OOC Notes: Edit
" + . = jointext(.,null) /datum/category_item/player_setup_item/general/basic/OnTopic(var/href,var/list/href_list, var/mob/user) var/datum/species/S = all_species[pref.species] diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index ef9b419d97..0f26f2d55b 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -73,6 +73,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O if(!pref.rlimb_data) pref.rlimb_data = list() /datum/category_item/player_setup_item/general/body/content(var/mob/user) + . = list() pref.update_preview_icon() if(pref.preview_icon_front && pref.preview_icon_side) user << browse_rsc(pref.preview_icon_front, "preview_icon.png") @@ -186,6 +187,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O if(has_flag(mob_species, HAS_SKIN_COLOR)) . += "
Body Color
" . += "Change Color
__

" + . = jointext(.,null) /datum/category_item/player_setup_item/general/body/proc/has_flag(var/datum/species/mob_species, var/flag) return mob_species && (mob_species.appearance_flags & flag) diff --git a/code/modules/client/preference_setup/global/02_settings.dm b/code/modules/client/preference_setup/global/02_settings.dm index 60eeeb144e..c7635cbb91 100644 --- a/code/modules/client/preference_setup/global/02_settings.dm +++ b/code/modules/client/preference_setup/global/02_settings.dm @@ -61,9 +61,9 @@ . += "[client_pref.description]: " if(pref_mob.is_preference_enabled(client_pref.key)) - . += "[client_pref.enabled_description] [client_pref.disabled_description]" + . += "[client_pref.enabled_description] [client_pref.disabled_description]" else - . += "[client_pref.enabled_description] [client_pref.disabled_description]" + . += "[client_pref.enabled_description] [client_pref.disabled_description]" . += "" . += "" diff --git a/code/modules/client/preference_setup/global/05_ooc.dm b/code/modules/client/preference_setup/global/05_ooc.dm index 08aa97836a..1b9d45dc89 100644 --- a/code/modules/client/preference_setup/global/05_ooc.dm +++ b/code/modules/client/preference_setup/global/05_ooc.dm @@ -9,7 +9,7 @@ /datum/category_item/player_setup_item/player_global/ooc/save_preferences(var/savefile/S) S["ignored_players"] << pref.ignored_players - +/* /datum/category_item/player_setup_item/player_global/ooc/sanitize_preferences() if(isnull(pref.ignored_players)) pref.ignored_players = list() @@ -32,7 +32,11 @@ var/player_to_ignore = input(user, "Who do you want to ignore?","Ignore") as null|text if(player_to_ignore) player_to_ignore = sanitize(ckey(player_to_ignore)) + if(player_to_ignore == user.ckey) + user <<"You can't ignore yourself." + return TOPIC_REFRESH pref.ignored_players |= player_to_ignore return TOPIC_REFRESH return ..() +*/ \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index e8794a4256..cd1e3eff4c 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -82,6 +82,7 @@ var/list/gear_datums = list() total_cost += G.cost /datum/category_item/player_setup_item/loadout/content() + . = list() var/total_cost = 0 if(pref.gear && pref.gear.len) for(var/i = 1; i <= pref.gear.len; i++) @@ -92,8 +93,8 @@ var/list/gear_datums = list() var/fcolor = "#3366CC" if(total_cost < MAX_GEAR_COST) fcolor = "#E67300" - . += list() - . += "" + + . += "
" . += "" . += "" var/datum/loadout_category/LC = loadout_categories[current_tab] @@ -117,7 +127,7 @@ var/list/gear_datums = list() for(var/gear_name in LC.gear) var/datum/gear/G = LC.gear[gear_name] var/ticked = (G.display_name in pref.gear) - . += "" + . += "" . += "" . += "" if(ticked) diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno.dm b/code/modules/client/preference_setup/loadout/loadout_xeno.dm index 79e6a1ec7f..9f814743ae 100644 --- a/code/modules/client/preference_setup/loadout/loadout_xeno.dm +++ b/code/modules/client/preference_setup/loadout/loadout_xeno.dm @@ -12,55 +12,81 @@ whitelisted = "Unathi" sort_category = "Xenowear" -/datum/gear/ears/skrell - display_name = "headtail-wear, female, chain (Skrell)" +/datum/gear/ears/skrell/chains //Chains + display_name = "headtail chain selection (Skrell)" path = /obj/item/clothing/ears/skrell/chain sort_category = "Xenowear" whitelisted = "Skrell" -/datum/gear/ears/skrell/plate - display_name = "headtail-wear, male, bands (Skrell)" +/datum/gear/ears/skrell/chains/New() + ..() + var/list/chaintypes = list() + for(var/chain_style in typesof(/obj/item/clothing/ears/skrell/chain)) + var/obj/item/clothing/ears/skrell/chain/chain = chain_style + chaintypes[initial(chain.name)] = chain + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(chaintypes)) + +/datum/gear/ears/skrell/bands + display_name = "headtail band selection (Skrell)" path = /obj/item/clothing/ears/skrell/band + sort_category = "Xenowear" + whitelisted = "Skrell" -/datum/gear/ears/skrell/cloth //male/red - display_name = "headtail-wear, male, red, cloth (Skrell)" +/datum/gear/ears/skrell/bands/New() + ..() + var/list/bandtypes = list() + for(var/band_style in typesof(/obj/item/clothing/ears/skrell/band)) + var/obj/item/clothing/ears/skrell/band/band = band_style + bandtypes[initial(band.name)] = band + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(bandtypes)) + +/datum/gear/ears/skrell/cloth/male + display_name = "male headtail cloth selection (Skrell)" path = /obj/item/clothing/ears/skrell/cloth_male + sort_category = "Xenowear" + whitelisted = "Skrell" -/datum/gear/ears/skrell/cloth/male //black - display_name = "headtail-wear, male, black, cloth (Skrell)" - path = /obj/item/clothing/ears/skrell/cloth_male/black - -/datum/gear/ears/skrell/cloth/male/blue - display_name = "headtail-wear, male, blue, cloth (Skrell)" - path = /obj/item/clothing/ears/skrell/cloth_male/blue - -/datum/gear/ears/skrell/cloth/male/green - display_name = "headtail-wear, male, green, cloth (Skrell)" - path = /obj/item/clothing/ears/skrell/cloth_male/green - -/datum/gear/ears/skrell/cloth/male/pink - display_name = "headtail-wear, male, pink, cloth (Skrell)" - path = /obj/item/clothing/ears/skrell/cloth_male/pink +/datum/gear/ears/skrell/cloth/male/New() + ..() + var/list/clothtypes = list() + for(var/cloth_style in typesof(/obj/item/clothing/ears/skrell/cloth_male)) + var/obj/item/clothing/ears/skrell/cloth_male/cloth = cloth_style + clothtypes[initial(cloth.name)] = cloth + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(clothtypes)) /datum/gear/ears/skrell/cloth/female - display_name = "headtail-wear, female, red, cloth (Skrell)" + display_name = "female headtail cloth selection (Skrell)" path = /obj/item/clothing/ears/skrell/cloth_female + sort_category = "Xenowear" + whitelisted = "Skrell" -/datum/gear/ears/skrell/cloth/female/black - display_name = "headtail-wear, female, black, cloth (Skrell)" - path = /obj/item/clothing/ears/skrell/cloth_female/black +/datum/gear/ears/skrell/cloth/female/New() + ..() + var/list/clothtypes = list() + for(var/cloth_style in typesof(/obj/item/clothing/ears/skrell/cloth_female)) + var/obj/item/clothing/ears/skrell/cloth_female/cloth = cloth_style + clothtypes[initial(cloth.name)] = cloth + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(clothtypes)) -/datum/gear/ears/skrell/cloth/female/blue - display_name = "headtail-wear, female, blue, cloth (Skrell)" - path = /obj/item/clothing/ears/skrell/cloth_female/blue - -/datum/gear/ears/skrell/cloth/female/green - display_name = "headtail-wear, female, green, cloth (Skrell)" - path = /obj/item/clothing/ears/skrell/cloth_female/green - -/datum/gear/ears/skrell/cloth/female/pink - display_name = "headtail-wear, female, pink, cloth (Skrell)" - path = /obj/item/clothing/ears/skrell/cloth_female/pink +/datum/gear/ears/skrell/colored/band + display_name = "Colored bands (Skrell)" + path = /obj/item/clothing/ears/skrell/colored/band + sort_category = "Xenowear" + whitelisted = "Skrell" + +/datum/gear/ears/skrell/colored/band/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) + +/datum/gear/ears/skrell/colored/chain + display_name = "Colored chain (Skrell)" + path = /obj/item/clothing/ears/skrell/colored/chain + sort_category = "Xenowear" + whitelisted = "Skrell" + +/datum/gear/ears/skrell/colored/chain/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) /datum/gear/uniform/teshari display_name = "smock, grey (Teshari)" diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index b177b7773f..b74e7035b3 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -58,6 +58,7 @@ if(!job_master) return + . = list() . += "
" . += "Choose occupation chances
Unavailable occupations are crossed out.
" . += "
[total_cost]/[MAX_GEAR_COST] loadout points spent. \[Clear Loadout\]
" @@ -105,9 +106,18 @@ var/list/gear_datums = list() else . += " |" if(category == current_tab) - . += " [category] " + . += " [category] " else - . += " [category] " + var/datum/loadout_category/LC = loadout_categories[category] + var/make_orange = FALSE + for(var/thing in LC.gear) + if(thing in pref.gear) + make_orange = TRUE + break + if(make_orange) + . += " [category] " + else + . += " [category] " . += "
[G.display_name]
[G.display_name][G.cost][G.description]
" . += "" - . += "
" // Table within a table for alignment, also allows you to easily add more columns. @@ -125,21 +126,20 @@ if(job.alt_titles) . += "
 \[[pref.GetPlayerAltTitle(job)]\]
" - - . += "" + . += "
" switch(pref.alternate_option) if(GET_RANDOM_JOB) - . += "

Get random job if preferences unavailable

" + . += "Get random job if preferences unavailable" if(BE_ASSISTANT) - . += "

Be assistant if preference unavailable

" + . += "Be assistant if preference unavailable" if(RETURN_TO_LOBBY) - . += "

Return to lobby if preference unavailable

" + . += "Return to lobby if preference unavailable" - . += "
\[Reset\]
" + . += "\[Reset\]
" . += "
" + . = jointext(.,null) /datum/category_item/player_setup_item/occupation/OnTopic(href, href_list, user) if(href_list["reset_jobs"]) diff --git a/code/modules/client/preference_setup/skills/skills.dm b/code/modules/client/preference_setup/skills/skills.dm index 8370f35668..7255e25bc4 100644 --- a/code/modules/client/preference_setup/skills/skills.dm +++ b/code/modules/client/preference_setup/skills/skills.dm @@ -19,6 +19,7 @@ if(pref.used_skillpoints < 0) pref.used_skillpoints = 0 /datum/category_item/player_setup_item/skills/content() + . = list() . += "Select your Skills
" . += "Current skill level: [pref.GetSkillClass(pref.used_skillpoints)] ([pref.used_skillpoints])
" . += "Use preconfigured skillset
" @@ -30,16 +31,22 @@ var/level = pref.skills[S.ID] . += "" . += "[S.name]" - . += "\[Untrained\]" + . += skill_to_button(S, "Untrained", level, SKILL_NONE) // secondary skills don't have an amateur level if(S.secondary) . += "" else - . += "\[Amateur\]" - . += "\[Trained\]" - . += "\[Professional\]" + . += skill_to_button(S, "Amateur", level, SKILL_BASIC) + . += skill_to_button(S, "Trained", level, SKILL_ADEPT) + . += skill_to_button(S, "Professional", level, SKILL_EXPERT) . += "" . += "" + . = jointext(.,null) + +/datum/category_item/player_setup_item/proc/skill_to_button(var/skill, var/level_name, var/current_level, var/selection_level) + if(current_level == selection_level) + return "[level_name]" + return "[level_name]" /datum/category_item/player_setup_item/skills/OnTopic(href, href_list, user) if(href_list["skillinfo"]) diff --git a/code/modules/clothing/ears/skrell.dm b/code/modules/clothing/ears/skrell.dm index 59428fa5d9..e8bc3e8534 100644 --- a/code/modules/clothing/ears/skrell.dm +++ b/code/modules/clothing/ears/skrell.dm @@ -11,73 +11,135 @@ species_restricted = list("Skrell") /obj/item/clothing/ears/skrell/chain - name = "skrell headtail chains" + name = "Gold headtail chains" desc = "A delicate golden chain worn by female skrell to decorate their head tails." icon_state = "skrell_chain" item_state = "skrell_chain" - + +/obj/item/clothing/ears/skrell/chain/silver + name = "Silver headtail chains" + desc = "A delicate silver chain worn by female skrell to decorate their head tails." + icon_state = "skrell_chain_sil" + item_state = "skrell_chain_sil" + +/obj/item/clothing/ears/skrell/chain/bluejewels + name = "Blue jeweled golden headtail chains" + desc = "A delicate golden chain adorned with blue jewels worn by female skrell to decorate their head tails." + icon_state = "skrell_chain_bjewel" + item_state = "skrell_chain_bjewel" + +/obj/item/clothing/ears/skrell/chain/redjewels + name = "Red jeweled golden headtail chains" + desc = "A delicate golden chain adorned with red jewels worn by female skrell to decorate their head tails." + icon_state = "skrell_chain_rjewel" + item_state = "skrell_chain_rjewel" + +/obj/item/clothing/ears/skrell/chain/ebony + name = "Ebony headtail chains" + desc = "A delicate ebony chain worn by female skrell to decorate their head tails." + icon_state = "skrell_chain_ebony" + item_state = "skrell_chain_ebony" + /obj/item/clothing/ears/skrell/band - name = "skrell headtail bands" + name = "Gold headtail bands" desc = "Golden metallic bands worn by male skrell to adorn their head tails." icon_state = "skrell_band" item_state = "skrell_band" + +/obj/item/clothing/ears/skrell/band/silver + name = "Silver headtail bands" + desc = "Silver metallic bands worn by male skrell to adorn their head tails." + icon_state = "skrell_band_sil" + item_state = "skrell_band_sil" + +/obj/item/clothing/ears/skrell/band/bluejewels + name = "Blue jeweled golden headtail bands" + desc = "Golden metallic bands adorned with blue jewels worn by male skrell to adorn their head tails." + icon_state = "skrell_band_bjewel" + item_state = "skrell_band_bjewel" + +/obj/item/clothing/ears/skrell/band/redjewels + name = "Red jeweled golden headtail bands" + desc = "Golden metallic bands adorned with red jewels worn by male skrell to adorn their head tails." + icon_state = "skrell_band_rjewel" + item_state = "skrell_band_rjewel" + +/obj/item/clothing/ears/skrell/band/ebony + name = "Ebony headtail bands" + desc = "Ebony bands worn by male skrell to adorn their head tails." + icon_state = "skrell_band_ebony" + item_state = "skrell_band_ebony" +/obj/item/clothing/ears/skrell/colored/band + name = "Colored headtail bands" + desc = "Metallic bands worn by male skrell to adorn their head tails." + icon_state = "skrell_band_sil" + item_state = "skrell_band_sil" + +/obj/item/clothing/ears/skrell/colored/chain + name = "Colored headtail chains" + desc = "A delicate chain worn by female skrell to decorate their head tails." + icon_state = "skrell_chain_sil" + item_state = "skrell_chain_sil" + /obj/item/clothing/ears/skrell/cloth_female - name = "skrell headtail cloth" + name = "red headtail cloth" desc = "A cloth shawl worn by female skrell draped around their head tails." icon_state = "skrell_cloth_female" item_state = "skrell_cloth_female" /obj/item/clothing/ears/skrell/cloth_female/black - name = "skrell headtail cloth" - desc = "A cloth shawl worn by female skrell draped around their head tails." + name = "black headtail cloth" icon_state = "skrell_cloth_black_female" item_state = "skrell_cloth_black_female" /obj/item/clothing/ears/skrell/cloth_female/blue - name = "skrell headtail cloth" - desc = "A cloth shawl worn by female skrell draped around their head tails." + name = "blue headtail cloth" icon_state = "skrell_cloth_blue_female" item_state = "skrell_cloth_blue_female" /obj/item/clothing/ears/skrell/cloth_female/green - name = "skrell headtail cloth" - desc = "A cloth shawl worn by female skrell draped around their head tails." + name = "green headtail cloth" icon_state = "skrell_cloth_green_female" item_state = "skrell_cloth_green_female" /obj/item/clothing/ears/skrell/cloth_female/pink - name = "skrell headtail cloth" - desc = "A cloth shawl worn by female skrell draped around their head tails." + name = "pink headtail cloth" icon_state = "skrell_cloth_pink_female" item_state = "skrell_cloth_pink_female" +/obj/item/clothing/ears/skrell/cloth_female/lightblue + name = "light blue headtail cloth" + icon_state = "skrell_cloth_lblue_female" + item_state = "skrell_cloth_lblue_female" + /obj/item/clothing/ears/skrell/cloth_male - name = "skrell headtail cloth" + name = "red headtail cloth" desc = "A cloth band worn by male skrell around their head tails." icon_state = "skrell_cloth_male" item_state = "skrell_cloth_male" /obj/item/clothing/ears/skrell/cloth_male/black - name = "skrell headtail cloth" - desc = "A cloth band worn by male skrell around their head tails." + name = "black headtail cloth" icon_state = "skrell_cloth_black_male" item_state = "skrell_cloth_black_male" /obj/item/clothing/ears/skrell/cloth_male/blue - name = "skrell headtail cloth" - desc = "A cloth band worn by male skrell around their head tails." + name = "blue headtail cloth" icon_state = "skrell_cloth_blue_male" item_state = "skrell_cloth_blue_male" /obj/item/clothing/ears/skrell/cloth_male/green - name = "skrell headtail cloth" - desc = "A cloth band worn by male skrell around their head tails." + name = "green headtail cloth" icon_state = "skrell_cloth_green_male" item_state = "skrell_cloth_green_male" /obj/item/clothing/ears/skrell/cloth_male/pink - name = "skrell headtail cloth" - desc = "A cloth band worn by male skrell around their head tails." + name = "pink headtail cloth" icon_state = "skrell_cloth_pink_male" - item_state = "skrell_cloth_pink_male" \ No newline at end of file + item_state = "skrell_cloth_pink_male" + +/obj/item/clothing/ears/skrell/cloth_male/lightblue + name = "light blue headtail cloth" + icon_state = "skrell_cloth_lblue_male" + item_state = "skrell_cloth_lblue_male" \ No newline at end of file diff --git a/code/modules/economy/economy_misc.dm b/code/modules/economy/economy_misc.dm index 8c39fcac8d..1e87b98e4c 100644 --- a/code/modules/economy/economy_misc.dm +++ b/code/modules/economy/economy_misc.dm @@ -48,11 +48,12 @@ /var/list/economic_species_modifier = list( - /datum/species/human = 10, - /datum/species/skrell = 12, - /datum/species/teshari = 9, // Skrell sponsored, - /datum/species/tajaran = 7, - /datum/species/unathi = 7 + /datum/species/human = 10, + /datum/species/skrell = 12, + /datum/species/teshari = 9, // Skrell sponsored, + /datum/species/tajaran = 7, + /datum/species/unathi = 7, + /datum/species/diona = 7 ) //---- The following corporations are friendly with NanoTrasen and loosely enable trade and travel: diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 0fb90dbc75..4195f963c2 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -561,13 +561,15 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/update_inv_glasses(var/update_icons=1) if(glasses) - + var/image/standing if(glasses.icon_override) - overlays_standing[GLASSES_LAYER] = image("icon" = glasses.icon_override, "icon_state" = "[glasses.icon_state]") + standing = image("icon" = glasses.icon_override, "icon_state" = "[glasses.icon_state]") else if(glasses.sprite_sheets && glasses.sprite_sheets[species.get_bodytype(src)]) - overlays_standing[GLASSES_LAYER]= image("icon" = glasses.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[glasses.icon_state]") + standing = image("icon" = glasses.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[glasses.icon_state]") else - overlays_standing[GLASSES_LAYER]= image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]") + standing = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]") + standing.color = glasses.color + overlays_standing[GLASSES_LAYER] = standing else overlays_standing[GLASSES_LAYER] = null @@ -580,29 +582,37 @@ var/global/list/damage_icon_parts = list() return if(l_ear || r_ear) + var/image/both = image("icon" = null) + if(l_ear) - + var/image/standing var/t_type = l_ear.icon_state if(l_ear.icon_override) t_type = "[t_type]_l" - overlays_standing[EARS_LAYER] = image("icon" = l_ear.icon_override, "icon_state" = "[t_type]") + standing = image("icon" = l_ear.icon_override, "icon_state" = "[t_type]") else if(l_ear.sprite_sheets && l_ear.sprite_sheets[species.get_bodytype(src)]) t_type = "[t_type]_l" - overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_type]") + standing = image("icon" = l_ear.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_type]") else - overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]") - + standing = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]") + standing.color = l_ear.color + both.overlays += standing + if(r_ear) - + var/image/standing var/t_type = r_ear.icon_state if(r_ear.icon_override) t_type = "[t_type]_r" - overlays_standing[EARS_LAYER] = image("icon" = r_ear.icon_override, "icon_state" = "[t_type]") + standing = image("icon" = r_ear.icon_override, "icon_state" = "[t_type]") else if(r_ear.sprite_sheets && r_ear.sprite_sheets[species.get_bodytype(src)]) t_type = "[t_type]_r" - overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_type]") + standing = image("icon" = r_ear.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_type]") else - overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]") + standing = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]") + standing.color = r_ear.color + both.overlays += standing + + overlays_standing[EARS_LAYER] = both else overlays_standing[EARS_LAYER] = null diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 53927668f8..0052b77578 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -31,9 +31,9 @@ if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) if(ready) - output += "

\[ Ready | Not Ready \]

" + output += "

\[ Ready | Not Ready \]

" else - output += "

\[ Ready | Not Ready \]

" + output += "

\[ Ready | Not Ready \]

" else output += "View the Crew Manifest

" @@ -62,8 +62,7 @@ output += "" - //src << browse(output,"window=playersetup;size=210x280;can_close=0") - panel = new(src, "New Player","New Player", 210, 280, src) + panel = new(src, "Welcome","Welcome", 210, 280, src) panel.set_window_options("can_close=0") panel.set_content(output) panel.open() diff --git a/code/modules/organs/wound.dm b/code/modules/organs/wound.dm index 3cf3ecb239..2c97bf4cfc 100644 --- a/code/modules/organs/wound.dm +++ b/code/modules/organs/wound.dm @@ -13,6 +13,8 @@ var/damage = 0 // ticks of bleeding left. var/bleed_timer = 0 + // Above this amount wounds you will need to treat the wound to stop bleeding, regardless of bleed_timer + var/bleed_threshold = 30 // amount of damage the current wound type requires(less means we need to apply the next healing stage) var/min_damage = 0 @@ -187,7 +189,7 @@ return 0 //incompatible damage types if (src.amount > 1) - return 0 + return 0//merged wounds cannot be worsened. //with 1.5*, a shallow cut will be able to carry at most 30 damage, //37.5 for a deep cut @@ -208,8 +210,8 @@ if (bandaged||clamped) return 0 - if (wound_damage() <= 30 && bleed_timer <= 0) - return 0 //Bleed timer has run out. Wounds with more than 30 damage don't stop bleeding on their own. + if (bleed_timer <= 0 && wound_damage() <= bleed_threshold) + return 0 //Bleed timer has run out. Once a wound is big enough though, you'll need a bandage to stop it return 1 @@ -264,8 +266,9 @@ return null //no wound /** CUTS **/ -/datum/wound/cut/bleeding() - return ..() || wound_damage() >= 5 +/datum/wound/cut + bleed_threshold = 5 + damage_type = CUT /datum/wound/cut/small // link wound descriptions to amounts of damage @@ -273,40 +276,34 @@ // The major cut types have the max_bleeding_stage set to the clot stage (which is accordingly given the "blood soaked" descriptor). max_bleeding_stage = 3 stages = list("ugly ripped cut" = 20, "ripped cut" = 10, "cut" = 5, "healing cut" = 2, "small scab" = 0) - damage_type = CUT /datum/wound/cut/deep max_bleeding_stage = 3 stages = list("ugly deep ripped cut" = 25, "deep ripped cut" = 20, "deep cut" = 15, "clotted cut" = 8, "scab" = 2, "fresh skin" = 0) - damage_type = CUT /datum/wound/cut/flesh max_bleeding_stage = 4 stages = list("ugly ripped flesh wound" = 35, "ugly flesh wound" = 30, "flesh wound" = 25, "blood soaked clot" = 15, "large scab" = 5, "fresh skin" = 0) - damage_type = CUT /datum/wound/cut/gaping max_bleeding_stage = 3 stages = list("gaping wound" = 50, "large blood soaked clot" = 25, "blood soaked clot" = 15, "small angry scar" = 5, "small straight scar" = 0) - damage_type = CUT /datum/wound/cut/gaping_big max_bleeding_stage = 3 stages = list("big gaping wound" = 60, "healing gaping wound" = 40, "large blood soaked clot" = 25, "large angry scar" = 10, "large straight scar" = 0) - damage_type = CUT datum/wound/cut/massive max_bleeding_stage = 3 stages = list("massive wound" = 70, "massive healing wound" = 50, "massive blood soaked clot" = 25, "massive angry scar" = 10, "massive jagged scar" = 0) - damage_type = CUT /** PUNCTURES **/ +/datum/wound/puncture + bleed_threshold = 5 + damage_type = PIERCE + /datum/wound/puncture/can_worsen(damage_type, damage) - return 0 -/datum/wound/puncture/can_merge(var/datum/wound/other) - return 0 -/datum/wound/puncture/bleeding() - return ..() || wound_damage() >= 5 + return 0 //puncture wounds cannot be enlargened /datum/wound/puncture/small max_bleeding_stage = 2 @@ -334,41 +331,36 @@ datum/wound/puncture/massive damage_type = PIERCE /** BRUISES **/ -/datum/wound/bruise/bleeding() - return ..() || wound_damage() >= 20 - /datum/wound/bruise stages = list("monumental bruise" = 80, "huge bruise" = 50, "large bruise" = 30, "moderate bruise" = 20, "small bruise" = 10, "tiny bruise" = 5) + bleed_threshold = 20 max_bleeding_stage = 3 //only large bruise and above can bleed. autoheal_cutoff = 30 damage_type = BRUISE /** BURNS **/ /datum/wound/burn + damage_type = BURN max_bleeding_stage = 0 + /datum/wound/burn/bleeding() return 0 /datum/wound/burn/moderate stages = list("ripped burn" = 10, "moderate burn" = 5, "healing moderate burn" = 2, "fresh skin" = 0) - damage_type = BURN /datum/wound/burn/large stages = list("ripped large burn" = 20, "large burn" = 15, "healing large burn" = 5, "fresh skin" = 0) - damage_type = BURN /datum/wound/burn/severe stages = list("ripped severe burn" = 35, "severe burn" = 30, "healing severe burn" = 10, "burn scar" = 0) - damage_type = BURN /datum/wound/burn/deep stages = list("ripped deep burn" = 45, "deep burn" = 40, "healing deep burn" = 15, "large burn scar" = 0) - damage_type = BURN /datum/wound/burn/carbonised stages = list("carbonised area" = 50, "healing carbonised area" = 20, "massive burn scar" = 0) - damage_type = BURN /** INTERNAL BLEEDING **/ /datum/wound/internal_bleeding diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index d56c298b6c..66155da7ea 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -14,7 +14,7 @@ kill_count = 15 //if the shell hasn't hit anything after travelling this far it just explodes. var/flash_range = 0 var/brightness = 7 - var/light_duration = 5 + var/light_colour = "#ffffff" /obj/item/projectile/energy/flash/on_impact(var/atom/A) var/turf/T = flash_range? src.loc : get_turf(A) @@ -29,16 +29,25 @@ playsound(src, 'sound/effects/snap.ogg', 50, 1) src.visible_message("\The [src] explodes in a bright flash!") - new /obj/effect/decal/cleanable/ash(src.loc) //always use src.loc so that ash doesn't end up inside windows - new /obj/effect/effect/sparks(T) - new /obj/effect/effect/smoke/illumination(T, brightness=max(flash_range*2, brightness), lifetime=light_duration) + var/datum/effect/effect/system/spark_spread/sparks = PoolOrNew(/datum/effect/effect/system/spark_spread) + sparks.set_up(2, 1, T) + sparks.start() + new /obj/effect/decal/cleanable/ash(src.loc) //always use src.loc so that ash doesn't end up inside windows + new /obj/effect/effect/smoke/illumination(T, 5, brightness, brightness, light_colour) //blinds people like the flash round, but can also be used for temporary illumination /obj/item/projectile/energy/flash/flare damage = 10 flash_range = 1 - brightness = 9 //similar to a flare - light_duration = 200 + brightness = 15 + +/obj/item/projectile/energy/flash/flare/on_impact(var/atom/A) + light_colour = pick("#e58775", "#ffffff", "#90ff90", "#a09030") + + ..() //initial flash + + //residual illumination + new /obj/effect/effect/smoke/illumination(src.loc, rand(190,240) SECONDS, range=8, power=3, color=light_colour) //same lighting power as flare /obj/item/projectile/energy/electrode name = "electrode" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm index 26b58eed31..4c3e461a27 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm @@ -375,6 +375,24 @@ /datum/reagent/sugar/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.nutrition += removed * 3 + var/effective_dose = dose + if(issmall(M)) + effective_dose *= 2 + + if(alien == IS_UNATHI) + if(effective_dose < 2) + if(effective_dose == metabolism * 2 || prob(5)) + M.emote("yawn") + else if(effective_dose < 5) + M.eye_blurry = max(M.eye_blurry, 10) + else if(effective_dose < 20) + if(prob(50)) + M.Weaken(2) + M.drowsyness = max(M.drowsyness, 20) + else + M.sleeping = max(M.sleeping, 20) + M.drowsyness = max(M.drowsyness, 60) + /datum/reagent/sulfur name = "Sulfur" id = "sulfur" 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 637470e7cc..be96e6665a 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -17,6 +17,8 @@ affect_ingest(M, alien, removed) /datum/reagent/nutriment/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + switch(alien) + if(IS_UNATHI) removed *= 0.5 if(issmall(M)) removed *= 2 // Small bodymass, more effect from lower volume. M.heal_organ_damage(0.5 * removed, 0) M.nutrition += nutriment_factor * removed // For hunger and fatness @@ -42,6 +44,8 @@ if(IS_TESHARI) ..(M, alien, removed*1.2) // Teshari get a bit more nutrition from meat. return + if(IS_UNATHI) + ..(M, alien, removed*2.25) //Unathi get most of their nutrition from meat. ..() /datum/reagent/nutriment/protein/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -62,6 +66,27 @@ nutriment_factor = 10 color = "#FFFF00" +/datum/reagent/honey/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + ..() + + var/effective_dose = dose + if(issmall(M)) + effective_dose *= 2 + + if(alien == IS_UNATHI) + if(effective_dose < 2) + if(effective_dose == metabolism * 2 || prob(5)) + M.emote("yawn") + else if(effective_dose < 5) + M.eye_blurry = max(M.eye_blurry, 10) + else if(effective_dose < 20) + if(prob(50)) + M.Weaken(2) + M.drowsyness = max(M.drowsyness, 20) + else + M.sleeping = max(M.sleeping, 20) + M.drowsyness = max(M.drowsyness, 60) + /datum/reagent/nutriment/flour name = "flour" id = "flour" @@ -396,6 +421,27 @@ glass_name = "glass of grape juice" glass_desc = "It's grrrrrape!" +/datum/reagent/juice/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + ..() + + var/effective_dose = dose/2 + if(issmall(M)) + effective_dose *= 2 + + if(alien == IS_UNATHI) + if(effective_dose < 2) + if(effective_dose == metabolism * 2 || prob(5)) + M.emote("yawn") + else if(effective_dose < 5) + M.eye_blurry = max(M.eye_blurry, 10) + else if(effective_dose < 20) + if(prob(50)) + M.Weaken(2) + M.drowsyness = max(M.drowsyness, 20) + else + M.sleeping = max(M.sleeping, 20) + M.drowsyness = max(M.drowsyness, 60) + /datum/reagent/drink/juice/lemon name = "Lemon Juice" id = "lemonjuice" @@ -765,6 +811,27 @@ glass_desc = "Glorious brainfreezing mixture." glass_center_of_mass = list("x"=16, "y"=7) +/datum/reagent/milkshake/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + ..() + + var/effective_dose = dose/2 + if(issmall(M)) + effective_dose *= 2 + + if(alien == IS_UNATHI) + if(effective_dose < 2) + if(effective_dose == metabolism * 2 || prob(5)) + M.emote("yawn") + else if(effective_dose < 5) + M.eye_blurry = max(M.eye_blurry, 10) + else if(effective_dose < 20) + if(prob(50)) + M.Weaken(2) + M.drowsyness = max(M.drowsyness, 20) + else + M.sleeping = max(M.sleeping, 20) + M.drowsyness = max(M.drowsyness, 60) + /datum/reagent/drink/rewriter name = "Rewriter" description = "The secret of the sanctuary of the Libarian..." diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index f178a6a45b..7ea873c8d0 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -153,8 +153,12 @@ max_duration = 100 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] - return ..() && (!sponge || !sponge.damage) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(affected.organ_tag == BP_HEAD) + var/obj/item/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + return ..() && (!sponge || !sponge.damage) + else + return ..() begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) diff --git a/code/world.dm b/code/world.dm index d82b636e87..bfa399fe2a 100644 --- a/code/world.dm +++ b/code/world.dm @@ -558,8 +558,9 @@ var/failed_db_connections = 0 var/failed_old_db_connections = 0 /hook/startup/proc/connectDB() - if(!config.sql_enabled) return 1 - if(!setup_database_connection()) + if(!config.sql_enabled) + world.log << "SQL connection disabled in config." + else if(!setup_database_connection()) world.log << "Your server failed to establish a connection with the feedback database." else world.log << "Feedback database connection established." @@ -601,8 +602,9 @@ proc/establish_db_connection() /hook/startup/proc/connectOldDB() - if(!config.sql_enabled) return 1 - if(!setup_old_database_connection()) + if(!config.sql_enabled) + world.log << "SQL connection disabled in config." + else if(!setup_old_database_connection()) world.log << "Your server failed to establish a connection with the SQL database." else world.log << "SQL database connection established." diff --git a/config/example/config.txt b/config/example/config.txt index c1ce782235..ec93429827 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -67,8 +67,8 @@ LOG_PDA ## log admin warning messages ##LOG_ADMINWARN ## Also duplicates a bunch of other messages. -## sql switching -SQL_ENABLED 1 +## Enable/disable SQL connection (comment out to disable) +SQL_ENABLED ## disconnect players who did nothing during the set amount of minutes # KICK_INACTIVE 10 diff --git a/html/changelog.html b/html/changelog.html index 38b2166002..3ef596ac8c 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,17 @@ -->
+

12 May 2016

+

Yoshax updated:

+ +

05 May 2016

Datraen updated: