diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm index ce10cf9d500..6c4caa70556 100644 --- a/code/datums/wires/vending.dm +++ b/code/datums/wires/vending.dm @@ -1,6 +1,8 @@ /datum/wires/vending holder_type = /obj/machinery/vending proper_name = "Vending Unit" + /// Keeps track of which language is selected + var/language_iterator = 1 /datum/wires/vending/New(atom/holder) wires = list( @@ -8,57 +10,72 @@ WIRE_CONTRABAND, WIRE_IDSCAN ) add_duds(1) + + var/obj/machinery/vending/vending_machine = holder + var/datum/language_holder/vending_languages = vending_machine.get_language_holder() + + if(!length(vending_languages.spoken_languages)) + CRASH("Vending machine [vending_machine] does not have any spoken languages in it's language holder.") + + // synch the current language to the language_iterator + for(var/i in vending_languages.spoken_languages) + if(vending_languages.selected_language == vending_languages.spoken_languages[i]) + language_iterator = i + break ..() /datum/wires/vending/interactable(mob/user) if(!..()) return FALSE - var/obj/machinery/vending/V = holder - if(!issilicon(user) && V.seconds_electrified && V.shock(user, 100)) + var/obj/machinery/vending/vending_machine = holder + if(!issilicon(user) && vending_machine.seconds_electrified && vending_machine.shock(user, 100)) return FALSE - if(V.panel_open) + if(vending_machine.panel_open) return TRUE /datum/wires/vending/get_status() - var/obj/machinery/vending/V = holder + var/obj/machinery/vending/vending_machine = holder + var/datum/language_holder/vending_languages = vending_machine.get_language_holder() + var/datum/language/current_language = GLOB.language_datum_instances[vending_languages.get_selected_language()] var/list/status = list() - status += "The orange light is [V.seconds_electrified ? "on" : "off"]." - status += "The red light is [V.shoot_inventory ? "off" : "blinking"]." - status += "The green light is [V.extended_inventory ? "on" : "off"]." - status += "A [V.scan_id ? "purple" : "yellow"] light is on." - status += "A white light is [V.age_restrictions ? "on" : "off"]." - status += "The speaker light is [V.shut_up ? "off" : "on"]." + status += "The orange light is [vending_machine.seconds_electrified ? "on" : "off"]." + status += "The red light is [vending_machine.shoot_inventory ? "off" : "blinking"]." + status += "The green light is [vending_machine.extended_inventory ? "on" : "off"]." + status += "A [vending_machine.scan_id ? "purple" : "yellow"] light is on." + status += "A white light is [vending_machine.age_restrictions ? "on" : "off"]." + status += "The speaker light is [vending_machine.shut_up ? "off" : "on"]. The language is set to [current_language.name]." return status /datum/wires/vending/on_pulse(wire) - var/obj/machinery/vending/V = holder + var/obj/machinery/vending/vending_machine = holder + var/datum/language_holder/vending_languages = vending_machine.get_language_holder() + switch(wire) if(WIRE_THROW) - V.shoot_inventory = !V.shoot_inventory + vending_machine.shoot_inventory = !vending_machine.shoot_inventory if(WIRE_CONTRABAND) - V.extended_inventory = !V.extended_inventory + vending_machine.extended_inventory = !vending_machine.extended_inventory if(WIRE_SHOCK) - V.seconds_electrified = MACHINE_DEFAULT_ELECTRIFY_TIME + vending_machine.seconds_electrified = MACHINE_DEFAULT_ELECTRIFY_TIME if(WIRE_IDSCAN) - V.scan_id = !V.scan_id + vending_machine.scan_id = !vending_machine.scan_id if(WIRE_SPEAKER) - V.shut_up = !V.shut_up + language_iterator %= length(vending_languages.spoken_languages) + language_iterator += 1 + vending_languages.selected_language = vending_languages.spoken_languages[language_iterator] if(WIRE_AGELIMIT) - V.age_restrictions = !V.age_restrictions + vending_machine.age_restrictions = !vending_machine.age_restrictions /datum/wires/vending/on_cut(wire, mend) - var/obj/machinery/vending/V = holder + var/obj/machinery/vending/vending_machine = holder switch(wire) if(WIRE_THROW) - V.shoot_inventory = !mend + vending_machine.shoot_inventory = !mend if(WIRE_CONTRABAND) - V.extended_inventory = FALSE + vending_machine.extended_inventory = FALSE if(WIRE_SHOCK) - if(mend) - V.seconds_electrified = MACHINE_NOT_ELECTRIFIED - else - V.seconds_electrified = MACHINE_ELECTRIFIED_PERMANENT + vending_machine.seconds_electrified = mend ? MACHINE_NOT_ELECTRIFIED : MACHINE_ELECTRIFIED_PERMANENT if(WIRE_IDSCAN) - V.scan_id = mend + vending_machine.scan_id = mend if(WIRE_SPEAKER) - V.shut_up = mend + vending_machine.shut_up = mend diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 852c60a2cf5..58e858d77dc 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1421,6 +1421,29 @@ var/datum/language_holder/language_holder = get_language_holder() return language_holder.update_atom_languages(src) +/** + * Randomizes our atom's language to an uncommon language if: + * - They are on the station Z level + * OR + * - They are on the escape shuttle + */ +/atom/movable/proc/randomize_language_if_on_station() + var/turf/atom_turf = get_turf(src) + var/area/atom_area = get_area(src) + + if(!atom_turf) // some machines spawn in nullspace + return + + if(!is_station_level(atom_turf.z) && !istype(atom_area, /area/shuttle/escape)) + // Why snowflake check for escape shuttle? Well, a lot of shuttles spawn with machines + // but docked at centcom, and I wanted those machines to also speak funny languages + return FALSE + + /// The atom's language holder - so we can randomize and change their language + var/datum/language_holder/atom_languages = get_language_holder() + atom_languages.selected_language = atom_languages.get_random_spoken_uncommon_language() + return TRUE + /* End language procs */ //Returns an atom's power cell, if it has one. Overload for individual items. diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 9fc13ed0c60..577eab46a14 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -100,6 +100,7 @@ anchored = TRUE interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT blocks_emissive = EMISSIVE_BLOCK_GENERIC + initial_language_holder = /datum/language_holder/synthetic var/machine_stat = NONE var/use_power = IDLE_POWER_USE @@ -172,6 +173,9 @@ flags_1 |= PREVENT_CONTENTS_EXPLOSION_1 } + if(HAS_TRAIT(SSstation, STATION_TRAIT_BOTS_GLITCHED)) + randomize_language_if_on_station() + return INITIALIZE_HINT_LATELOAD /obj/machinery/LateInitialize() @@ -306,6 +310,10 @@ use_power(7500/severity) new /obj/effect/temp_visual/emp(loc) + if(prob(70/severity)) + var/datum/language_holder/machine_languages = get_language_holder() + machine_languages.selected_language = machine_languages.get_random_spoken_language() + /** * Opens the machine. * diff --git a/code/modules/language/language_holder.dm b/code/modules/language/language_holder.dm index 4658edd71ec..fbde52425f9 100644 --- a/code/modules/language/language_holder.dm +++ b/code/modules/language/language_holder.dm @@ -409,6 +409,20 @@ Key procs /datum/language/monkey = list(LANGUAGE_ATOM)) spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM), /datum/language/monkey = list(LANGUAGE_ATOM)) + +/datum/language_holder/syndicate + understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM), + /datum/language/codespeak = list(LANGUAGE_ATOM)) + spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM), + /datum/language/codespeak = list(LANGUAGE_ATOM)) + +/datum/language_holder/beachbum + understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM), + /datum/language/beachbum = list(LANGUAGE_ATOM)) + spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM), + /datum/language/beachbum = list(LANGUAGE_ATOM)) + selected_language = /datum/language/beachbum + /datum/language_holder/empty understood_languages = list() spoken_languages = list() diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 40d072ef62b..41e2e61507b 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -429,6 +429,11 @@ paicard.emp_act(severity) src.visible_message(span_notice("[paicard] is flies out of [initial(src.name)]!"), span_warning("You are forcefully ejected from [initial(src.name)]!")) ejectpai(0) + + if(prob(70/severity)) + var/datum/language_holder/bot_languages = get_language_holder() + bot_languages.selected_language = bot_languages.get_random_spoken_language() + if(bot_mode_flags & BOT_MODE_ON) turn_off() addtimer(CALLBACK(src, PROC_REF(emp_reset), was_on), severity * 30 SECONDS) @@ -1093,22 +1098,3 @@ Pass a positive integer as an argument to override a bot's default speed. /mob/living/simple_animal/bot/rust_heretic_act() adjustBruteLoss(400) - -/** - * Randomizes our bot's language if: - * - They are on the setation Z level - * OR - * - They are on the escape shuttle - */ -/mob/living/simple_animal/bot/proc/randomize_language_if_on_station() - var/turf/bot_turf = get_turf(src) - var/area/bot_area = get_area(src) - if(!is_station_level(bot_turf.z) && !istype(bot_area, /area/shuttle/escape)) - // Why snowflake check for escape shuttle? Well, a lot of shuttles spawn with bots - // but docked at centcom, and I wanted those bots to also speak funny languages - return FALSE - - /// The bot's language holder - so we can randomize and change their language - var/datum/language_holder/bot_languages = get_language_holder() - bot_languages.selected_language = bot_languages.get_random_spoken_uncommon_language() - return TRUE diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index a375cba9e4e..63c2fb5f404 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -64,6 +64,7 @@ payment_department = ACCOUNT_SRV light_power = 0.5 light_range = MINIMUM_USEFUL_LIGHT_RANGE + /// Is the machine active (No sales pitches if off)! var/active = 1 ///Are we ready to vend?? Is it time?? @@ -237,6 +238,13 @@ /obj/machinery/vending/can_speak() return !shut_up +/obj/machinery/vending/emp_act(severity) + . = ..() + var/datum/language_holder/vending_languages = get_language_holder() + var/datum/wires/vending/vending_wires = wires + // if the language wire got pulsed during an EMP, this will make sure the language_iterator is synched correctly + vending_languages.selected_language = vending_languages.spoken_languages[vending_wires.language_iterator] + //Better would be to make constructable child /obj/machinery/vending/RefreshParts() SHOULD_CALL_PARENT(FALSE) @@ -1037,7 +1045,7 @@ message_admins("Vending machine exploit attempted by [ADMIN_LOOKUPFLW(usr)]!") return if (R.amount <= 0) - say("Sold out of [R.name].") + speak("Sold out of [R.name].") flick(icon_deny,src) vend_ready = TRUE return @@ -1047,22 +1055,22 @@ var/mob/living/L = usr C = L.get_idcard(TRUE) if(!C) - say("No card found.") + speak("No card found.") flick(icon_deny,src) vend_ready = TRUE return else if (!C.registered_account) - say("No account found.") + speak("No account found.") flick(icon_deny,src) vend_ready = TRUE return else if(!C.registered_account.account_job) - say("Departmental accounts have been blacklisted from personal expenses due to embezzlement.") + speak("Departmental accounts have been blacklisted from personal expenses due to embezzlement.") flick(icon_deny, src) vend_ready = TRUE return else if(age_restrictions && R.age_restricted && (!C.registered_age || C.registered_age < AGE_MINOR)) - say("You are not of legal age to purchase [R.name].") + speak("You are not of legal age to purchase [R.name].") if(!(usr in GLOB.narcd_underages)) if (isnull(sec_radio)) sec_radio = new @@ -1081,7 +1089,7 @@ if(LAZYLEN(R.returned_products)) price_to_use = 0 //returned items are free if(price_to_use && !account.adjust_money(-price_to_use, "Vending: [R.name]")) - say("You do not possess the funds to purchase [R.name].") + speak("You do not possess the funds to purchase [R.name].") flick(icon_deny,src) vend_ready = TRUE return @@ -1092,7 +1100,8 @@ SSeconomy.track_purchase(account, price_to_use, name) log_econ("[price_to_use] credits were inserted into [src] by [account.account_holder] to buy [R].") if(last_shopper != REF(usr) || purchase_message_cooldown < world.time) - say("Thank you for shopping with [src]!") + var/vend_response = vend_reply || "Thank you for shopping with [src]!" + speak(vend_response) purchase_message_cooldown = world.time + 5 SECONDS //This is not the best practice, but it's safe enough here since the chances of two people using a machine with the same ref in 5 seconds is fuck low last_shopper = REF(usr) @@ -1279,13 +1288,13 @@ /obj/machinery/vending/custom/canLoadItem(obj/item/I, mob/user) . = FALSE if(I.flags_1 & HOLOGRAM_1) - say("This vendor cannot accept nonexistent items.") + speak("This vendor cannot accept nonexistent items.") return if(loaded_items >= max_loaded_items) - say("There are too many items in stock.") + speak("There are too many items in stock.") return if(isstack(I)) - say("Loose items may cause problems, try to use it inside wrapping paper.") + speak("Loose items may cause problems, try to use it inside wrapping paper.") return if(I.custom_price) return TRUE @@ -1340,7 +1349,7 @@ var/obj/item/card/id/C = L.get_idcard(TRUE) if(C?.registered_account) linked_account = C.registered_account - say("\The [src] has been linked to [C].") + speak("\The [src] has been linked to [C].") if(compartmentLoadAccessCheck(user)) if(istype(I, /obj/item/pen)) @@ -1402,7 +1411,7 @@ [dispensed_item] by [payee.account_holder], owned by [linked_account.account_holder].") /// Make an alert if(last_shopper != REF(usr) || purchase_message_cooldown < world.time) - say("Thank you for your patronage [user]!") + speak("Thank you for your patronage [user]!") purchase_message_cooldown = world.time + 5 SECONDS last_shopper = REF(usr) /// Remove the item diff --git a/code/modules/vending/boozeomat.dm b/code/modules/vending/boozeomat.dm index 9615cce10e7..1421c0cbf36 100644 --- a/code/modules/vending/boozeomat.dm +++ b/code/modules/vending/boozeomat.dm @@ -91,6 +91,7 @@ /obj/machinery/vending/boozeomat/syndicate_access req_access = list(ACCESS_SYNDICATE) age_restrictions = FALSE + initial_language_holder = /datum/language_holder/syndicate /obj/item/vending_refill/boozeomat machine_name = "Booze-O-Mat" diff --git a/code/modules/vending/cigarette.dm b/code/modules/vending/cigarette.dm index 620e0cbbdf6..ddcfd9bb244 100644 --- a/code/modules/vending/cigarette.dm +++ b/code/modules/vending/cigarette.dm @@ -46,6 +46,7 @@ /obj/item/lighter/greyscale = 4, /obj/item/storage/fancy/rollingpapers = 5, ) + initial_language_holder = /datum/language_holder/syndicate /obj/machinery/vending/cigarette/beach //Used in the lavaland_biodome_beach.dmm ruin name = "\improper ShadyCigs Ultra" @@ -68,6 +69,7 @@ /obj/item/clothing/mask/vape = 5, /obj/item/lighter = 3, ) + initial_language_holder = /datum/language_holder/beachbum /obj/item/vending_refill/cigarette machine_name = "ShadyCigs Deluxe" diff --git a/code/modules/vending/cola.dm b/code/modules/vending/cola.dm index 1522ecb210e..947db7f2274 100644 --- a/code/modules/vending/cola.dm +++ b/code/modules/vending/cola.dm @@ -103,6 +103,16 @@ /obj/item/reagent_containers/cup/soda_cans/shamblers = 10, ) product_slogans = "~Shake me up some of that Shambler's Juice!~" - product_ads = "Refreshing!;Jyrbv dv lg jfdv fw kyrk Jyrdscvi'j Alztv!;Over 1 trillion souls drank!;Thirsty? Nyp efk uizeb kyv uribevjj?;Kyv Jyrdscvi uizebj kyv ezxyk!;Drink up!;Krjkp." + product_ads = "Refreshing!;Thirsty for DNA? Satiate your craving!;Over 1 trillion souls drank!;Made with real DNA!;The hivemind demands your thirst!;Drink up!;Absorb your thirst." light_mask = "shamblers-light-mask" light_color = COLOR_MOSTLY_PURE_PINK + +/obj/machinery/vending/cola/shamblers/Initialize(mapload) + . = ..() + var/datum/language_holder/ling_languages = get_language_holder() + ling_languages.selected_language = ling_languages.get_random_spoken_language() + +/obj/machinery/vending/cola/shamblers/speak(message) + . = ..() + var/datum/language_holder/ling_languages = get_language_holder() + ling_languages.selected_language = ling_languages.get_random_spoken_language() diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index de96f918aaf..4031e296d0c 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -45,6 +45,7 @@ /obj/machinery/vending/medical/syndicate_access name = "\improper SyndiMed Plus" req_access = list(ACCESS_SYNDICATE) + initial_language_holder = /datum/language_holder/syndicate //Created out of a necessity to get these dumb chems out of the medical tools vendor. /obj/machinery/vending/drugs