diff --git a/code/__HELPERS/logging.dm b/code/__HELPERS/logging.dm index 083ce666..99dca9cf 100644 --- a/code/__HELPERS/logging.dm +++ b/code/__HELPERS/logging.dm @@ -110,7 +110,7 @@ if(C.prefs.toggles & CHAT_SCOPES_DEBUG) C << msg -/proc/msg_scopes_list(var/thing, var/name = "") +/proc/msg_scopes_list(var/thing, var/name = "No name set") if(!thing) return diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index e2c1b007..3bbd38bf 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -316,3 +316,34 @@ proc/TextPreview(var/string,var/len=40) return string else return "[copytext(string, 1, 37)]..." + + +//This proc strips html properly, but it's not lazy like the other procs. +//This means that it doesn't just remove < and > and call it a day. +//Also limit the size of the input, if specified. +/proc/strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN) + if(!input) + return + var/opentag = 1 //These store the position of < and > respectively. + var/closetag = 1 + while(1) + opentag = findtext(input, "<") + closetag = findtext(input, ">") + if(closetag && opentag) + if(closetag < opentag) + input = copytext(input, (closetag + 1)) + else + input = copytext(input, 1, opentag) + copytext(input, (closetag + 1)) + else if(closetag || opentag) + if(opentag) + input = copytext(input, 1, opentag) + else + input = copytext(input, (closetag + 1)) + else + break + if(max_length) + input = copytext(input,1,max_length) + return sanitize(input) + +/proc/trim_strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN) + return trim(strip_html_properly(input, max_length)) diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 29a64007..589a7d24 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -407,6 +407,10 @@ occupantData["isViableSubject"] = 1 if (NOCLONE in connected.occupant.mutations || !src.connected.occupant.dna) occupantData["isViableSubject"] = 0 + if(ishuman(connected.occupant)) + var/mob/living/carbon/human/C = connected.occupant + if (C.species.flags & (NO_SCAN)) + occupantData["isViableSubject"] = 0 occupantData["health"] = connected.occupant.health occupantData["maxHealth"] = connected.occupant.maxHealth occupantData["minHealth"] = config.health_threshold_dead @@ -424,15 +428,15 @@ if (connected.beaker.reagents && connected.beaker.reagents.reagent_list.len) for(var/datum/reagent/R in connected.beaker.reagents.reagent_list) data["beakerVolume"] += R.volume - + // update the ui if it exists, returns null if no ui is passed/found - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm ui = new(user, src, ui_key, "dna_modifier.tmpl", "DNA Modifier Console", 660, 700) // when the ui is first opened this is the data it will use - ui.set_initial_data(data) + ui.set_initial_data(data) // open the new ui window ui.open() // auto update every Master Controller tick diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 936039dc..c3102af0 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -93,16 +93,16 @@ Implants; if((player.client)&&(player.ready)) playerC++ - msg_scopes("playerC: [playerC]") + msg_scopes("[src] playerC: [playerC]") if(master_mode=="secret") - msg_scopes("req [required_players_secret]") + msg_scopes("[src] req [required_players_secret]") if(playerC >= required_players_secret) return 1 else - msg_scopes("req [required_players]") + msg_scopes("[src] req [required_players]") if(playerC >= required_players) return 1 - msg_scopes("Nope, players not here or something") + msg_scopes("[src] Nope, players not here or something") return 0 @@ -323,6 +323,7 @@ Implants; for(var/datum/mind/player in candidates) for(var/job in restricted_jobs) if(player.assigned_role == job) + msg_scopes("[player.key] has a Restricted Job [job]") candidates -= player /*if(candidates.len < recommended_enemies) diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index 5fc4a3c3..b54efcc6 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -215,9 +215,9 @@ M.current << "You're blindfolded!" return for(var/mob/living/carbon/C in view(1)) - if(!C.vampire_affected(M)) - if(!C.get_species() == "Machine") - continue + if(C == M.current) continue //Don't stunn yourself + if(!C.vampire_affected(M) && !C.get_species() == "Machine") //Or machines + continue if(!M.current.vampire_can_reach(C, 1)) continue // C.Stun(8) C.Weaken(8) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index f4dcf090..52fbed37 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -423,6 +423,9 @@ var/list/obj/machinery/requests_console/allConsoles = list() screen = 11 if(href_list["print"]) + if(paperstock == 0) + alert("Error! No paper to print on! Aborting!") + return var/printid = sanitizeSQL(href_list["print"]) establish_db_connection() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 47504766..6f70b1fb 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -610,10 +610,10 @@ /obj/mecha/meteorhit() return ex_act(rand(1,3))//should do for now -/obj/mecha/emp_act(severity) +/obj/mecha/emp_act(severity) // Lower severity = greater effect, higher = smaller. Damage = (50 / severity), cell drain = ((current charge / 2) / severity) if(get_charge()) - use_power((cell.charge/2)/severity) - take_damage(50 / severity,"energy") + use_power((cell.charge/2)/severity) //rip your energy, dude + take_damage(50/severity,"energy") src.log_message("EMP detected",1) check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) return diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index 98ac9f5b..8e0e3184 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -108,7 +108,11 @@ proc/shock() var/obj/mecha/M = in_mecha() if(M) - M.emp_act(2) + M.emp_act(0.8) + M.emp_act(0.8) + M.emp_act(0.8) + M.emp_act(0.8) //we call this four times to get the necessary damage + add a much higher chance of subsystem failures + empulse(src.loc, 0, 1, 1) del(src) proc/get_mecha_log() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 71311338..5f1686e8 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -39,6 +39,8 @@ var/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) var/list/allowed = null //suit storage stuff. var/obj/item/device/uplink/hidden/hidden_uplink = null // All items can have an uplink hidden inside, just remember to add the triggers. + var/zoomdevicename = null //name used for message when binoculars/scope is used + var/zoom = 0 //1 if item is actively being used to zoom. For scoped guns and binoculars. /* Species-specific sprites, concept stolen from Paradise//vg/. ex: @@ -219,6 +221,11 @@ // apparently called whenever an item is removed from a slot, container, or anything else. /obj/item/proc/dropped(mob/user as mob) ..() + if(zoom) //binoculars, scope, etc + user.client.view = world.view + user.client.pixel_x = 0 + user.client.pixel_y = 0 + zoom = 0 // called just as an item is picked up (loc is not yet changed) /obj/item/proc/pickup(mob/user) @@ -644,3 +651,78 @@ if(I && !I.abstract) I.showoff(src) +/* +For zooming with scope or binoculars. This is called from +modules/mob/mob_movement.dm if you move you will be zoomed out +modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. +*/ + +/obj/item/proc/zoom(var/tileoffset = 11,var/viewsize = 12) //tileoffset is client view offset in the direction the user is facing. viewsize is how far out this thing zooms. 7 is normal view + + var/devicename + + if(zoomdevicename) + devicename = zoomdevicename + else + devicename = src.name + + var/cannotzoom + + if(usr.stat || !(istype(usr,/mob/living/carbon/human))) + usr << "You are unable to focus through the [devicename]" + cannotzoom = 1 + else if(!zoom && global_hud.darkMask[1] in usr.client.screen) + usr << "Your welding equipment gets in the way of you looking through the [devicename]" + cannotzoom = 1 + else if(!zoom && usr.get_active_hand() != src) + usr << "You are too distracted to look through the [devicename], perhaps if it was in your active hand this might work better" + cannotzoom = 1 + + if(!zoom && !cannotzoom) + if(!usr.hud_used.hud_shown) + usr.button_pressed_F12(1) // If the user has already limited their HUD this avoids them having a HUD when they zoom in + usr.button_pressed_F12(1) + usr.client.view = viewsize + zoom = 1 + + var/tilesize = 32 + var/viewoffset = tilesize * tileoffset + + switch(usr.dir) + if (NORTH) + usr.client.pixel_x = 0 + usr.client.pixel_y = viewoffset + if (SOUTH) + usr.client.pixel_x = 0 + usr.client.pixel_y = -viewoffset + if (EAST) + usr.client.pixel_x = viewoffset + usr.client.pixel_y = 0 + if (WEST) + usr.client.pixel_x = -viewoffset + usr.client.pixel_y = 0 + + usr.visible_message("[usr] peers through the [zoomdevicename ? "[zoomdevicename] of the [src.name]" : "[src.name]"].") + + /* + if(istype(usr,/mob/living/carbon/human/)) + var/mob/living/carbon/human/H = usr + usr.visible_message("[usr] holds [devicename] up to [H.get_visible_gender() == MALE ? "his" : H.get_visible_gender() == FEMALE ? "her" : "their"] eyes.") + else + usr.visible_message("[usr] holds [devicename] up to its eyes.") + */ + + else + usr.client.view = world.view + if(!usr.hud_used.hud_shown) + usr.button_pressed_F12(1) + zoom = 0 + + usr.client.pixel_x = 0 + usr.client.pixel_y = 0 + + if(!cannotzoom) + usr.visible_message("[zoomdevicename ? "[usr] looks up from the [zoomdevicename] of the [src.name]" : "[usr] lowers the [src.name]"].") + + return + diff --git a/code/game/objects/items/devices/binoculars.dm b/code/game/objects/items/devices/binoculars.dm new file mode 100644 index 00000000..e1c7b18a --- /dev/null +++ b/code/game/objects/items/devices/binoculars.dm @@ -0,0 +1,18 @@ +/obj/item/device/binoculars + + name = "binoculars" + desc = "A pair of binoculars." + icon_state = "binoculars" + + flags = FPRINT | TABLEPASS| CONDUCT + force = 5.0 + w_class = 2.0 + throwforce = 5.0 + throw_range = 15 + throw_speed = 3 + + //matter = list("metal" = 50,"glass" = 50) + + +/obj/item/device/binoculars/attack_self(mob/user) + zoom() \ No newline at end of file diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm index ca58f39d..e57380e7 100644 --- a/code/game/objects/items/devices/suit_cooling.dm +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -4,7 +4,8 @@ w_class = 4 icon = 'icons/obj/device.dmi' icon_state = "suitcooler0" - slot_flags = SLOT_BACK //you can carry it on your back if you want, but it won't do anything unless attached to suit storage + item_state = "suitcooler0" //hacky, but yeah, works for now. + slot_flags = SLOT_BACK //will now work while on back - Skull132 //copied from tank.dm flags = FPRINT | TABLEPASS | CONDUCT @@ -84,10 +85,10 @@ var/mob/living/carbon/human/H = M - if (!H.wear_suit || H.s_store != src) - return 0 + if (H.wear_suit && (H.back == src || H.s_store == src)) + return 1 - return 1 + return 0 /obj/item/device/suit_cooling_unit/proc/turn_on() if(!cell) diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index 65d77c54..44a06ad4 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -142,6 +142,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid randomItems.Add("/obj/item/weapon/gun/energy/crossbow") //Energy Crossbow randomItems.Add("/obj/item/device/powersink") //Powersink randomItems.Add("/obj/item/weapon/cane/syndie") + randomItems.Add("/obj/item/clothing/gloves/force/syndicate") if(uses > 3) randomItems.Add("/obj/item/weapon/melee/energy/sword") //Energy Sword @@ -198,7 +199,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid uses -= 6 if("/obj/item/weapon/gun/energy/crossbow" , "/obj/item/device/powersink" , "/obj/item/weapon/cane/syndie") uses -= 5 - if("/obj/item/weapon/melee/energy/sword" , "/obj/item/clothing/mask/gas/voice" , "/obj/item/device/chameleon" , "/obj/item/weapon/melee/baton/stunrod/loaded") + if("/obj/item/weapon/melee/energy/sword" , "/obj/item/clothing/mask/gas/voice" , "/obj/item/device/chameleon" , "/obj/item/weapon/melee/baton/stunrod/loaded", "/obj/item/clothing/gloves/force/syndicate") uses -= 4 if("/obj/item/weapon/storage/box/emps" , "/obj/item/weapon/pen/paralysis" , "/obj/item/weapon/cartridge/syndicate" , "/obj/item/clothing/under/chameleon" , \ "/obj/item/weapon/card/emag" , "/obj/item/weapon/storage/box/syndie_kit/space" , "/obj/item/device/encryptionkey/binary" , \ @@ -278,6 +279,8 @@ A list of items and costs is stored under the datum of every game mode, alongsid feedback_add_details("traitor_uplink_items_bought","MM") if("/obj/item/weapon/melee/baton/stunrod/loaded") feedback_add_details("traitor_uplink_items_bought","SR") + if("/obj/item/clothing/gloves/force/syndicate") + feedback_add_details("traitor_uplink_items_bought","FG") diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index e65abf26..c32dda79 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -111,6 +111,9 @@ if (user) if (istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/C = M + if (C.species.flags & (IS_SYNTHETIC | NO_SCAN)) + return if(!inuse) var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( ) O.source = user diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm index 83edc196..32b863d1 100644 --- a/code/game/objects/items/weapons/storage/wallets.dm +++ b/code/game/objects/items/weapons/storage/wallets.dm @@ -23,7 +23,8 @@ "/obj/item/weapon/photo", "/obj/item/weapon/reagent_containers/dropper", "/obj/item/weapon/screwdriver", - "/obj/item/weapon/stamp") + "/obj/item/weapon/stamp", + "/obj/item/clothing/tie/fluff/kane_badge") slot_flags = SLOT_ID var/obj/item/weapon/card/id/front_id = null diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index c37e6ce2..9ac82b03 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -173,7 +173,7 @@ attack_verb = list("jabbed","stabbed","ripped") /obj/item/weapon/canesword - name = "cane sword" + name = "thin sword" sharp = 1 edge = 1 desc = "A thin, sharp blade with an elegant handle." @@ -190,7 +190,7 @@ //Using a modified cane, with a storage var, instead of a box. Because the box idea is meh, in terms of the interface. /obj/item/weapon/cane/syndie - var/sword //For holding the blade + var/obj/item/weapon/canesword/sword //For holding the blade var/locked //A small lock, so that you can't accidentally unsheathe it New() @@ -201,7 +201,9 @@ proc/unsheathe(mob/user as mob) if(sword) user.put_in_hands(sword) - user.visible_message("[user] takes the handle and draws a sword from inside the [src].", "You take the [src] by the handle and draw out a sharp blade from it.") + user.visible_message("\blue [user] takes the handle and draws a sword from inside the [src].", "\blue You take the [src] by the handle and draw out a sharp blade from it.") + sword.add_fingerprint(user) + add_fingerprint(user) sword = null icon_state = "cane_empty" update_icon() @@ -211,10 +213,10 @@ switch(locked) if(1) locked = 0 - user << "You twist and unlock the sword handle from the [src]." + user << "\blue You twist and unlock the sword handle from the [src]." if(0) locked = 1 - user << "You twist and lock the sword handle to the [src]." + user << "\blue You twist and lock the sword handle to the [src]." attack_self(mob/user as mob) if(iscarbon(user)) @@ -235,7 +237,7 @@ W.add_fingerprint(user) add_fingerprint(user) icon_state = "cane" - user << "You sheathe the sword, and lock its handle to the [src]." + user << "\blue You sheathe the sword, and lock its handle to the [src]." locked = 1 update_icon() diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 78bcab82..49948f13 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -555,6 +555,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that "blue wizard", "red wizard", "marisa wizard", + "protection detail", "emergency response team", "ert trooper", "ert leading trooper", @@ -565,6 +566,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that "nanotrasen officer", "nanotrasen captain", "shadowling" +// "iac_medic" ) var/dresscode = input("Select dress for [M]", "Robust quick dress shop") as null|anything in dresspacks if (isnull(dresscode)) @@ -854,6 +856,36 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that W.registered_name = M.real_name M.equip_if_possible(W, slot_wear_id) + if("protection detail") + + var/obj/item/clothing/tie/holster/hold = new(M) + var/obj/item/weapon/gun/energy/gun/pistol/weapon = new(M) + hold.contents += weapon + hold.holstered = weapon + + var/obj/item/clothing/under/rank/ert/under = new(M) + under.hastie = hold + hold.has_suit = under + hold.has_suit.overlays += hold.inv_overlay + + M.equip_to_slot_or_del(under, slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/ert(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset/ert(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_belt) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back) + + var/obj/item/weapon/card/id/W = new(M) + W.name = "[M.real_name]'s ID Card" + W.icon_state = "centcom" + W.access = get_all_accesses() + W.access += get_ert_access() + W.assignment = "ERT Protection Detail" + W.registered_name = M.real_name + M.equip_to_slot_or_del(W, slot_wear_id) + if("emergency response team") M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/ert(M), slot_w_uniform) M.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/ert(M), slot_wear_suit) @@ -868,7 +900,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that W.name = "[M.real_name]'s ID Card" W.icon_state = "centcom" W.access = get_all_accesses() - W.access += get_all_centcom_access() + W.access += get_ert_access() W.assignment = "Emergency Response Team" W.registered_name = M.real_name M.equip_to_slot_or_del(W, slot_wear_id) @@ -1095,7 +1127,45 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that W.assignment = "Field Operator" W.registered_name = M.real_name M.equip_to_slot_or_del(W, slot_wear_id) +/* REMOVED BECAUSE STUCK + if("iac_medic") + var/obj/item/clothing/under/rank/medical/iac = new(M) + iac.hastie = new /obj/item/clothing/tie/armband/iac(iac) + M.equip_to_slot_or_del(iac, slot_w_uniform) + + M.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/iac(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/latex(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_med(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health(M), slot_glasses) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(M), slot_wear_mask) + + var/obj/item/weapon/storage/belt/medical/medical = new(M) + medical.contents += new /obj/item/weapon/reagent_containers/hypospray + medical.contents += new /obj/item/weapon/reagent_containers/glass/bottle/antitoxin + medical.contents += new /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline + medical.contents += new /obj/item/weapon/reagent_containers/glass/bottle/bicaridine + medical.contents += new /obj/item/weapon/reagent_containers/glass/bottle/dex_plus + medical.contents += new /obj/item/weapon/reagent_containers/glass/bottle/dermaline + medical.contents += new /obj/item/stack/medical/advanced/bruise_pack + medical.contents += new /obj/item/stack/medical/advanced/ointment + M.equip_to_slot_or_del(medical, slot_belt) + + M.equip_to_slot_or_del(new /obj/item/device/healthanalyzer(M), slot_l_store) + M.equip_to_slot_or_del(new /obj/item/device/flash(M), slot_r_store) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/emt(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(M), slot_s_store) + + var/obj/item/weapon/card/id/silver/W = new(src) + W.name = "[M.real_name]'s ID Card" + W.icon_state = "id" + W.access = get_all_accesses()//Full station access because, DOCTOR HAAAAAAAALP MEEEEEE + W.access += list(access_cent_general, access_cent_specops, access_cent_storage)//CC access to the ERT area(s) so they can gear up and get to the station. + W.assignment = "IAC Worker" + W.registered_name = M.real_name + M.equip_to_slot_or_del(W, slot_wear_id) +*/ M.regenerate_icons() log_admin("[key_name(usr)] changed the equipment of [key_name(M)] to [dresscode].") diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 51f5351a..cbe7f4fd 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -131,6 +131,7 @@ var/list/forbidden_varedit_object_types = list( if(!istype(L,/list)) src << "Not a List." var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine", "poo", "icon", "icon_state") + var/list/forbidden = list("holder") //Why this way, fuck knows. var/list/names = sortList(L) var/variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)" @@ -149,6 +150,9 @@ var/list/forbidden_varedit_object_types = list( if(variable in locked) if(!check_rights(R_DEBUG|R_DEV|R_FUN)) return + if(variable in forbidden) + if(!check_rights(R_SERVER)) return + if(isnull(variable)) usr << "Unable to determine variable type." @@ -290,8 +294,10 @@ var/list/forbidden_varedit_object_types = list( src << "A variable with this name ([param_var_name]) doesn't exist in this atom ([O])" return - if(param_var_name == "holder" || (param_var_name in locked)) + if(param_var_name in locked) if(!check_rights(R_DEBUG|R_DEV|R_FUN)) return + if(param_var_name == "holder") + if(!check_rights(R_SERVER)) return variable = param_var_name @@ -348,8 +354,10 @@ var/list/forbidden_varedit_object_types = list( if(!variable) return var_value = O.vars[variable] - if(variable == "holder" || (variable in locked)) + if(param_var_name in locked) if(!check_rights(R_DEBUG|R_DEV|R_FUN)) return + if(param_var_name == "holder") + if(!check_rights(R_SERVER)) return if(!autodetect_class) diff --git a/code/modules/aurora/duty officer.dm b/code/modules/aurora/duty officer.dm index 9a104d65..b5053b8b 100644 --- a/code/modules/aurora/duty officer.dm +++ b/code/modules/aurora/duty officer.dm @@ -124,6 +124,14 @@ M.equip_if_possible(new /obj/item/weapon/melee/telebaton(M), slot_l_store) M.equip_if_possible(new /obj/item/device/taperecorder(M), slot_r_store) + var /obj/item/weapon/storage/lockbox/lockbox = new(M) + lockbox.req_access = list(access_cent_captain) + lockbox.name = "A Duty Officer briefcase" + lockbox.desc = "A smart looking briefcase with a NT logo on the side" + lockbox.storage_slots = 8 + lockbox.max_combined_w_class = 16 + M.equip_if_possible(lockbox, slot_l_hand) + var/obj/item/device/pda/central/pda = new(M) pda.owner = M.real_name pda.ownjob = "Central Command Duty Officer" diff --git a/code/modules/aurora/sqlnews_controller.dm b/code/modules/aurora/sqlnews_controller.dm index f3120494..22d6b4db 100644 --- a/code/modules/aurora/sqlnews_controller.dm +++ b/code/modules/aurora/sqlnews_controller.dm @@ -20,11 +20,16 @@ datum/sqlnews var/time //publishtime, time in gametime var/id //id, primary-key, of the news article that's destined for pulling. var/running = 1 //whenever no results are found, this ticks over to a 0, and thus, no more updates. + var/fails = 0 datum/sqlnews/proc/process() if(!running == 1) //No more news, immediate kill and return. return + if(fails >= 5) //If it sucks at running, we'll off it. + kill() + return + if(!id && !time) //No entry loaded, update and load one. update() return @@ -37,6 +42,7 @@ datum/sqlnews/proc/update() //Updates the stored variables and preppes it for a establish_db_connection() if(!dbcon.IsConnected()) error("SQL database connection failed. Attempted to fetch news information.") + fails++ return var/DBQuery/query = dbcon.NewQuery("SELECT id, publishtime FROM aurora_news WHERE isnull(notpublishing) ORDER BY publishtime ASC LIMIT [count],1") @@ -59,6 +65,7 @@ datum/sqlnews/proc/publish() //Uses data stored from the update() proc and: pull establish_db_connection() if(!dbcon.IsConnected()) error("SQL database connection failed. Attempted to fetch news information.") + fails++ return var/DBQuery/fetchquery = dbcon.NewQuery("SELECT channel, author, body FROM aurora_news WHERE id=[id]") @@ -93,4 +100,8 @@ datum/sqlnews/proc/publish() //Uses data stored from the update() proc and: pull NEWSCASTER.newsAlert("[channel]") id = null - time = null \ No newline at end of file + time = null + +datum/sqlnews/proc/kill() + running = 0 + return \ No newline at end of file diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index eb45fc0f..d7456e40 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -164,6 +164,7 @@ host = key world.update_status() + admin_memo_player_show() if(holder) add_admin_verbs() admin_memo_show() diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index cdb23053..1a87c6ca 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -80,12 +80,7 @@ if("labgreen_all") src.icon_state = "labgreen_open" usr << "You unbotton the labcoat." - if("fabian_coat_open") - src.icon_state = "fabian_coat_closed" - usr << "You button up the coat's buttons." - if("fabian_coat_closed") - src.icon_state = "fabian_coat_open" - usr << "You unbutton the coat's buttons." + else usr << "You attempt to button-up the velcro on your [src], before promptly realising how retarded you are." return diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 6a6baec4..a74cd84c 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -533,18 +533,42 @@ item_state = "amy_gloves" clipped = 1 -/obj/item/clothing/tie/storage/fluff/cecillia_locket //Old locket - Cecillia Lambert - casperf1 - DONE +/obj/item/clothing/tie/fluff/cecillia_locket //Old locket - Cecillia Lambert - casperf1 - DONE name = "old locket" desc = "A dark metal locket, it seems at least sixty years old. The photo that was once inside is gone." icon = 'icons/obj/custom_items.dmi' icon_state = "cecillia_locket1" //Keep as one, to indicate glass. item_state = "cecillia_locket1" item_color = "cecillia_locket1" - slots = 1 + slot_flags = SLOT_MASK + + var/pill + + attack_self(mob/user as mob) + if(pill) + user.put_in_hands(pill) + user << "\blue You take out the pill that was housed in the [src]." + pill = null + icon_state = "cecillia_locket0" + item_state = icon_state + update_icon() + + attackby(obj/item/I, mob/usr) + if(istype(I, /obj/item/weapon/reagent_containers/pill/) && !pill) + usr.u_equip(I) + I.loc = src + pill = I + I.dropped(usr) + I.add_fingerprint(usr) + add_fingerprint(usr) + icon_state = "cecillia_locket1" + item_state = icon_state + usr << "\blue You securely fit the [I] into the [src]." + update_icon() New() ..() - new /obj/item/weapon/reagent_containers/pill/cecillia_pill(hold) + pill = new /obj/item/weapon/reagent_containers/pill/cecillia_pill() return /obj/item/weapon/reagent_containers/pill/cecillia_pill @@ -732,20 +756,16 @@ src.item_state = "ushanka_avadown" user << "You lower the ear flaps on the ushanka." -/obj/item/clothing/tie/fluff/hamil_badge // Internal Investigations Badge - Muhammad Hamil - Jackboot - DONE +/obj/item/clothing/tie/holobadge/fluff/hamil_badge // Internal Investigations Badge - Muhammad Hamil - Jackboot - DONE name = "Internal Investigations Badge" desc = "An Internal Investigation badge. Used by a special branch of the Elyran police force." icon = 'icons/obj/custom_items.dmi' - item_state = "hamil_badge" + icon_state = "hamil_badge" attack_self(mob/user as mob) if(isliving(user)) user.visible_message("\red [user] flashes their [src].\nIt reads: Muhammad Hamil, Internal Investigations, Persepolis..","\red You display the [src].\nIt reads: Muhammad Hamil, Internal Investigations, Persepolis.") - attack(mob/living/carbon/human/M, mob/living/user) - if(isliving(user)) - user.visible_message("\red [user] invades [M]'s personal space, thrusting [src] into their face insistently.","\red You invade [M]'s personal space, thrusting [src] into their face insistently. You are the law.") - /obj/item/clothing/mask/gas/fluff/stefan_mask // Modified Gas Mask - Oliver Stefan - Nbielinski - DONE desc = "This odd looking gas mask is quite clearly not of NanoTrasen origin as it sports a black metal polish, as well as a reflective face plate that mirrors the view of the mask itself. This particular mask appears to breathe with the user, hissing when they exhale, and whining softly as they inhale." name = "Modified Gas Mask" @@ -887,7 +907,8 @@ /obj/item/device/taperecorder/fluff/language_processor //Advanced Language Processing Board - Android - TheCritsyBear name = "Advanced Language Processing Board" desc = "A slightly advanced, but not uncommon upgrade module considered to be the cheapest of its kind. It has the markings of an independent retailer- not standard NanoTrasen hardware." - icon_state = "paragon_datachip" + icon = 'icons/obj/module.dmi' + icon_state = "cyborg_upgrade3" item_state = "dermal" slot_flags = SLOT_HEAD @@ -917,3 +938,260 @@ item_state = "dove_necklace" item_color = "dove_necklace" slot_flags = SLOT_MASK + +/obj/item/weapon/nullrod/fluff/hartam_rod // Faol's resolve - Hartam Bartam + name = "Faol's resolve" + desc = "A symbol forged of steel, tempered in holy water, it has several gold-colored rings on it. Judging by the numerous dents and scratches on this thing, it has seen a lot of years..." + icon = 'icons/obj/custom_items.dmi' + icon_state = "hartam_rod" + +/obj/item/device/radio/headset/fluff/sam_implant // Cochlear Implant - Samantha Mason - Bakagaijin + name = "Cochlear Implant" + desc = "A specialized earpiece and headset combination. It appears to help those who are deaf hear." + icon = 'icons/obj/custom_items.dmi' + icon_state = "sam_implant" + +/obj/item/weapon/melee/fluff/tina_knife // Consecrated Athame - Tina Kaekel - Tainevva + name = "Consecrated Athame" + desc = "An athame used in occult rituals. The double-edged dagger is dull. The handle is black with a pink/white occult design strewn about it, and 'Tina' is inscribed into it in decorated letters." + icon = 'icons/obj/custom_items.dmi' + icon_state = "tina_knife" + flags = FPRINT | TABLEPASS + slot_flags = SLOT_BELT + w_class = 1 + force = 2 + +/obj/item/clothing/tie/holobadge/fluff/peter_badge // Peter Stone's badge - Peter Stone - Jakers457 + name = "Peter Stone's badge" + desc = "An old looking badge that has seen as many ordeals as its owner. It has the name 'Peter Stone' inscribed on it." + icon = 'icons/obj/custom_items.dmi' + icon_state = "peter_badge" + stored_name = "Peter Stone" + +/obj/item/clothing/tie/armband/iac_armband // Interstellar Aid Corps armband - Grey Ryan - Jackboot + name = "Interstellar Aid Corps armband" + desc = "An armband denoting its wearer as a medical worker of the Interstellar Aid Corps." + icon = 'icons/obj/custom_items.dmi' + icon_state = "iac_armband" + item_color = "iac" + +/obj/item/clothing/gloves/fluff/imraj_kara // kara - Imraj Brar - Canon35 + name = "kara" + desc = "A bracelet made of what looks like steel." + icon = 'icons/obj/custom_items.dmi' + icon_state = "imraj_kara" + item_color = "imraj_kara" + +/obj/item/weapon/melee/fluff/imraj_kirpan // kirban - Imraj Brar - Canon35 + name = "kirpan" + desc = "A knife with a metal grip and blade, has strange characters written on the sides." + icon = 'icons/obj/custom_items.dmi' + icon_state = "imraj_kirpan" + item_state = "imraj_kirpan" + w_class = 2.0 + throwforce = 0 + throw_speed = 4 + throw_range = 20 + +/obj/item/clothing/head/fluff/imraj_turban // turban - Imraj Brar - Canon35 + name = "turban" + desc = "A piece of soft headgear." + icon = 'icons/obj/custom_items.dmi' + icon_state = "imraj_turban" + item_state = "imraj_turban" + armor = list(melee = 20, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) + +/obj/item/weapon/fluff/imraj_kangha // kangha - Imraj Brar - Canon35 + name = "kangha" + desc = "A small wooden comb." + w_class = 1.0 + icon = 'icons/obj/custom_items.dmi' + icon_state = "imraj_kangha" + + attack_self(mob/user) + if(user.r_hand == src || user.l_hand == src) + var/mobgender + if(user.gender == "male") + mobgender = "guy" + else + mobgender = "gal" + for(var/mob/O in viewers(user, null)) + O.show_message(text("\red [] uses [] to comb their hair with incredible style and sophistication. What a [mobgender].", user, src), 1) + return + +/obj/item/clothing/suit/fluff/apophis_coat // Thick Jacket - Apophis Quihtzin - Kingmatt9 + name = "thick jacket" + desc = "A brown leather trenchcoat-like jacket, it smells of snow." + icon = 'icons/obj/custom_items.dmi' + icon_state = "apophis_jacket" + item_state = "apophis_jacket" + +/obj/item/clothing/suit/armor/vest/fluff/sam_armour // Stabproof Vest - Sam Macnaughton - Sgtsammac + name = "stab proof vest" + desc = "It's a red vest, with high visibility strips. You can see the emblem of the NanoTrasen security division on the right breast." + icon = 'icons/obj/custom_items.dmi' + icon_state = "sam_armour" + item_state = "sam_armour" + +////////////////////////////////////////// +////////////REDO THIS///////////// +////////////////////////////////////////// +/obj/item/device/radio/fluff/smile_bara // Dr. Smile - Daniela Baranova - Rechkalov + name = "Dr. Smile" + desc = "A black suitcase with a simple yet soothing/supportive smiley-face on them." + icon = 'icons/obj/custom_items.dmi' + icon_state = "smilemotherfucker" + item_state = "smilemotherfucker_m" + +/obj/item/weapon/coin/fluff/luna_coin //Purple Coin - Luna Tsuki - Wer6 + name = "purple coin" + desc = "An anodized purple titanium coin in a sealed transparent case. The stamped portrait of a woman adorns one side, with the name 'Luna Tsuki' beneath. A hawk symbol rests on the opposing side, with the words 'We will miss you!' stamped beneath." + icon = 'icons/obj/custom_items.dmi' + icon_state = "luna_coin" + + attack_self(mob/user as mob) + user << "\blue You find it unwise to flip the encased coin." + return + + attackby(obj/item/weapon/W as obj, mob/user as mob) + return + +/obj/item/clothing/suit/storage/fluff/varick_coat //Frontier Duffle Coat - Talia Varick - OneOneThreeEight + name = "Frontier duffle coat" + desc = "A lightweight, navy duffle coat. This frontier coat is fashioned with horn-toggles, a golden leopard pin, cuff tassles and even intentional decorative tears in the fabric itself." + icon = 'icons/obj/custom_items.dmi' + icon_state = "varick_coat_open" + item_state = "varick_coat_open" + + verb/toggle() + set name = "Toggle horn toggles" + set category = "Object" + set src in usr + + if(!usr.canmove || usr.stat || usr.restrained()) + return 0 + + switch(icon_state) + if("varick_coat_open") + src.icon_state = "varick_coat_closed" + usr << "You fasten the coat's horn-toggles." + if("varick_coat_closed") + src.icon_state = "varick_coat_open" + usr << "You unfasten the coat's horn-toggles" + + usr.update_inv_wear_suit() + +/obj/item/clothing/under/rank/fluff/faust_uniform //Eridani Federal Army uniform - Bryce Faust - Hackie Mhan + name = "Eridani Federal Army uniform" + desc = "This uniform is old, with multiple stitches. Certain parts of the uniform are missing and yet it is still of a distinctly high quality" + icon = 'icons/obj/custom_items.dmi' + icon_state = "faust_uniform" + item_color = "faust_uniform" + item_state = "faust_uniform" + +/obj/item/clothing/head/beret/fluff/faust_beret //military beret - Bryce Faust - Hackie Mhan + name = "military beret" + desc = "This beret has the Eridani Federal Army symbol, it's old but still in good shape." + icon = 'icons/obj/custom_items.dmi' + icon_state = "faust_beret" + item_state = "faust_beret" + +/obj/item/clothing/head/ushanka/fluff/kuznetsov_ushanka // Ushanka - Dominika Kuznetsov - Kerbal22 + name = "ushanka" + desc = "A comfortable fur ushanka with a small red star embroidered on the front." + +/obj/item/clothing/mask/cigarette/pipe/fluff/hazeri_pipe //Hazeri's Pipe - Hazeri Saakhat - BlueSp34r + name = "Hazeri's Pipe" + desc = "A worn smoking pipe. It is made out of rare wood only found in Moghes, with little leaves sticking out of it." + icon = 'icons/obj/custom_items.dmi' + icon_state = "hazeri_pipe_off" + item_state = "hazeri_pipe_off" + icon_on = "hazeri_pipe_on" + icon_off = "hazeri_pipe_off" + smoketime = 200 + can_hurt_mob = 0 + +/obj/item/weapon/cane/fluff/hazeri_cane //Hazeri's Cane - Hazeri Saakhat - BlueSp34r + name = "Hazeri's Cane" + desc = "An old warped cane with a flat bottom. It appears leafy; crafted from Moghian wood." + icon = 'icons/obj/custom_items.dmi' + icon_state = "hazeri_cane" + item_state = "hazeri_cane" + +/obj/item/clothing/tie/fluff/kane_badge // Detective's Badge - Kane DeWitt - Joe Kane + name = "Detective's Badge" + desc = "A shiny brass detective's badge, backed by brown leather. Inscribed on the front is 'Kane DeWitt, DeWitt Detective Agency'." + icon = 'icons/obj/custom_items.dmi' + icon_state = "kane_badge" + item_color = "kane_badge" + + slot_flags = SLOT_BELT + + attack_self(mob/user as mob) + if(isliving(user)) + user.visible_message("\red [user] flashes their [src].\nIt reads: Kane DeWitt, DeWitt Detective Agency.","\red You display the [src].\nIt reads: Kane DeWitt, DeWitt Detective Agency.") + + attack(mob/living/carbon/human/M, mob/living/user) + if(isliving(user)) + user.visible_message("\red [user] invades [M]'s personal space, thrusting your [src] into their face insistently.","\red You invade [M]'s personal space, thrusting [src] into their face insistently. You are the law.") + +/obj/item/clothing/gloves/fluff/odanu_gloves //Old Unathi Handwraps - Odanu Adanutha - Prospekt1559 + name = "old Unathi handwraps" + desc = "Old, stained hand wraps made of cloth. Holds in a miniscule amount of warmth and offers slight protection to one's knuckles." + icon = 'icons/obj/custom_items.dmi' + icon_state = "odanu_gloves" + item_state = "odanu_gloves" + species_restricted = list("Unathi") + clipped = 1 + cold_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE + +/obj/item/fluff/red_gemstone //Red Gemstone - Mister Dosh - Somekindofpony + name = "red gemstone" + desc = "A small red piece of glass, cut into the shape of a gemstone." + icon = 'icons/obj/custom_items.dmi' + icon_state = "red_gemstone" + item_state = "" + w_class = 2.0 + force = 1 + throwforce = 2 + + attack_self(mob/user as mob) + if(isliving(user)) + user.visible_message("\blue [user] appears to be fondling [src] obsessively.","\blue You obsess over [src], rolling it from hand to hand.") + + attack(mob/living/carbon/human/M, mob/living/user) + if(isliving(user)) + user.visible_message("\red [user] brushes up against [M], driving [src] into their face intrusively.","\red You brush up against [M], intrusively thrusting [src] into their face.") + +/obj/item/clothing/tie/fluff/epsilon_badge // EPSILON PI Badge - EPSiLON - Prospekt1559 + name = "EPSiLON private investigator badge" + desc = "A leather badge with gold plating on the front. When looked at closely it can be seen to be engraved with an eyeglass, with the letters 'E' and 'I' underneath." + icon = 'icons/obj/custom_items.dmi' + icon_state = "epsilon_badge" + item_color = "kane_badge" + + slot_flags = SLOT_BELT + + attack_self(mob/user as mob) + if(isliving(user)) + user.visible_message("\red [user] flashes [src].\nIt reads: EPSilLON, Private Investigator.","\red You display [src].\nIt reads: EPSiLON, Private Investigator.") + + attack(mob/living/carbon/human/M, mob/living/user) + if(isliving(user)) + user.visible_message("\red [user] invades [M]'s personal space, thrusting [src] into their face insistently.","\red You invade [M]'s personal space, thrusting [src] into their face insistently. You are the law.") + +/obj/item/clothing/tie/ert_dogtags // D O G T A G Z B O Y Z + name = "ERT dogtags" + desc = "Tpr Doe - Funsquad" + icon_state = "ert_tags" + item_color = "holobadge-cord" + slot_flags = SLOT_MASK + slot_flags = SLOT_BELT + var/rank = "Tpr" + var/surname = "Doe" + var/spec = "Security" + + attack_self(mob/user as mob) + if(isliving(user)) + user.visible_message("\red [user] raises [src].\nThey read: [rank] [surname] - [spec], Emergency Response Team.","\red You raise [src].\nThey read: [rank] [surname] - [spec], Emergency Response Team.") \ No newline at end of file diff --git a/code/modules/customitems/item_spawning.dm b/code/modules/customitems/item_spawning.dm index 1facd074..750e552c 100644 --- a/code/modules/customitems/item_spawning.dm +++ b/code/modules/customitems/item_spawning.dm @@ -1,8 +1,85 @@ -//switch this out to use a database at some point -//list of ckey/ real_name and item paths -//gives item to specific people when they join if it can -//for multiple items just add mutliple entries, unless i change it to be a listlistlist -//yes, it has to be an item, you can't pick up nonitems +/* + * + *New proc, SQL based, for custom item spawning starts here. + * + */ + +/proc/EquipCustomItems(mob/living/carbon/human/M) + establish_db_connection() + if(!dbcon.IsConnected()) + error("Custom item check failed: unable to connect to database.") + return + + var/ckeyl = sanitizeSQL(M.ckey) + var/DBQuery/query = dbcon.NewQuery("SELECT item, job, real_name FROM aurora_customitems WHERE ckey='[ckeyl]'") + query.Execute() + + while(query.NextRow()) + var/path = query.item[1] + var/jobs = query.item[2] + var/char = query.item[3] + + if(char == M.real_name) + path = trim(path) + path = text2path(path) + var/obj/item/Item = new path() + var/ok = 0 + + //ERT fluff items are speshul, K? K. + //Because they use the jobs var for data carrying, they get to be made before a job check + if(istype(Item,/obj/item/clothing/tie/ert_dogtags)) + var/obj/item/clothing/tie/ert_dogtags/I = Item + var/datas = text2list(jobs, ",") + I.rank = datas[1] + I.surname = datas[2] + I.spec = datas[3] + I.desc = "[datas[1]] [datas[2]] - [datas[3]]" + jobs = null + if(istype(Item,/obj/item/clothing/suit/storage/ert)) + var/obj/item/clothing/suit/storage/ert/I = Item + var/datas = text2list(jobs, ",") + I.desc = "A militaristic duty jacket worn by members of the NanoTrasen Emergency Response Teams. The nameplate reads: [datas[1]] [datas[2]]." + jobs = null + + //Job restriction check. + if(jobs) + jobs = text2list(jobs, ",") + if(!M.mind.role_alt_title in jobs) + del(Item) + ok = 1 + continue + + //A place, where we have things that control item replacement and so on. + if(istype(Item,/obj/item/device/radio/headset/)) + var/obj/item/device/radio/headset/I = Item + for(var/obj/item/device/radio/headset/A in M) + I.keyslot1 = A.keyslot1 + I.keyslot2 = A.keyslot2 + del(A) + ok = M.equip_if_possible(I, slot_l_ear, 0) + break + I.recalculateChannels() + else if(istype(Item,/obj/item/clothing/glasses/)) + var/obj/item/clothing/glasses/I = Item + for(var/obj/item/clothing/glasses/A in M) + del(A) + M.glasses = null + break + ok = M.equip_if_possible(I, slot_glasses, 0) + + if(ok == 0) + if(istype(M.back,/obj/item/weapon/storage) && M.back:contents.len < M.back:storage_slots) // Try to place it in something on the mob's back + Item.loc = M.back + ok = 1 + continue + else if(ok == 0) + for(var/obj/item/weapon/storage/S in M.contents) // Try to place it in any item that can store stuff, on the mob. + if (S.contents.len < S.storage_slots) + Item.loc = S + ok = 1 + continue + else if(ok == 0)// Finally, since everything else failed, place it on the ground + Item.loc = get_turf(M.loc) /* *Old procs for custom items start here @@ -124,62 +201,4 @@ proc/EquipCustomItems(mob/living/carbon/human/M) skip: if (ok == 0) // Finally, since everything else failed, place it on the ground - Item.loc = get_turf(M.loc) - * - * - *New proc, SQL based, for custom item spawning starts here. - * - */ - -/proc/EquipCustomItems(mob/living/carbon/human/M) - establish_db_connection() - if(!dbcon.IsConnected()) - error("Custom item check failed: unable to connect to database.") - return - - var/ckeyl = sanitizeSQL(M.ckey) - var/DBQuery/query = dbcon.NewQuery("SELECT item, job, real_name FROM aurora_customitems WHERE ckey='[ckeyl]'") - query.Execute() - - while(query.NextRow()) - var/path = query.item[1] - var/jobs = query.item[2] - var/char = query.item[3] - //Okay, so we have a query. It will only fill the var/path if the character actually has an item. - //I guess recursive spawn code is a thing to do, creating a list, and running a for() on that list seems excessive - - //Getting lazy, alternative would be to use two variables, but this is just self-updating, really - if(char == M.real_name) - path = trim(path) - path = text2path(path) - var/obj/item/Item = new path() - - var/ok = 0 - - if(!jobs) - goto skip - - if(jobs) - jobs = text2list(jobs, ",") - if(M.mind.role_alt_title in jobs) - goto skip - else - del(Item) - ok = 1 - continue - - - skip: - if(ok == 0) - if(istype(M.back,/obj/item/weapon/storage) && M.back:contents.len < M.back:storage_slots) // Try to place it in something on the mob's back - Item.loc = M.back - ok = 1 - continue - else if(ok == 0) - for(var/obj/item/weapon/storage/S in M.contents) // Try to place it in any item that can store stuff, on the mob. - if (S.contents.len < S.storage_slots) - Item.loc = S - ok = 1 - continue - else if(ok == 0)// Finally, since everything else failed, place it on the ground - Item.loc = get_turf(M.loc) + Item.loc = get_turf(M.loc)*/ \ No newline at end of file diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 47778073..d74fab95 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -9,26 +9,37 @@ //Or someone snoring. So we make it where they won't hear it. return + //make sure the air can transmit speech - hearer's side + var/turf/T = get_turf(src) + if ((T) && (!(istype(src, /mob/dead/observer)))) //Ghosts can hear even in vacuum. + var/datum/gas_mixture/environment = T.return_air() + var/pressure = (environment)? environment.return_pressure() : 0 + if(pressure < SOUND_MINIMUM_PRESSURE && get_dist(speaker, src) > 1) + return + + if (pressure < ONE_ATMOSPHERE*0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet + italics = 1 + sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact + if(sleeping || stat == 1) hear_sleep(message) return - var/style = "body" - //non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet. if (language && (language.flags & NONVERBAL)) if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src))) message = stars(message) - if(!say_understands(speaker,language)) - if(istype(speaker,/mob/living/simple_animal)) - var/mob/living/simple_animal/S = speaker - message = pick(S.speak) - else - message = stars(message) - - if(language) - style = language.colour + if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages + if(!say_understands(speaker,language)) + if(istype(speaker,/mob/living/simple_animal)) + var/mob/living/simple_animal/S = speaker + message = pick(S.speak) + else + if(language) + message = language.scramble(message) + else + message = stars(message) var/speaker_name = speaker.name if(istype(speaker, /mob/living/carbon/human)) @@ -41,8 +52,7 @@ var/track = null if(istype(src, /mob/dead/observer)) if(italics && client.prefs.toggles & CHAT_GHOSTRADIO) - if(!verb == ("whispers" || " quietly" || " softly")) - return + return if(speaker_name != speaker.real_name && speaker.real_name) speaker_name = "[speaker.real_name] ([speaker_name])" track = "(follow) " @@ -50,12 +60,16 @@ message = "[message]" if(sdisabilities & DEAF || ear_deaf) - if(speaker == src) - src << "You cannot hear yourself speak!" - else - src << "[speaker_name][alt_name] talks but you cannot hear \him." + if(!language || !(language.flags & INNATE)) // INNATE is the flag for audible-emote-language, so we don't want to show an "x talks but you cannot hear them" message if it's set + if(speaker == src) + src << "You cannot hear yourself speak!" + else + src << "[speaker_name][alt_name] talks but you cannot hear \him." else - src << "[speaker_name][alt_name] [track][verb], \"[message]\"" + if(language) + src << "[speaker_name][alt_name] [track][language.format_message(message, verb)]" + else + src << "[speaker_name][alt_name] [track][verb], \"[message]\"" if (speech_sound && (get_dist(speaker, src) <= world.view && src.z == speaker.z)) var/turf/source = speaker? get_turf(speaker) : get_turf(src) src.playsound_local(source, speech_sound, sound_vol, 1) @@ -71,40 +85,35 @@ return var/track = null - var/speaker_name - var/style = "body" - - if(!language) - language = new /datum/language/common -// if(!speaker) //non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet. if (language && (language.flags & NONVERBAL)) if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src))) message = stars(message) - if(!say_understands(speaker,language)) - if(istype(speaker,/mob/living/simple_animal)) - var/mob/living/simple_animal/S = speaker - message = pick(S.speak) - else + if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages + if(!say_understands(speaker,language)) + if(istype(speaker,/mob/living/simple_animal)) + var/mob/living/simple_animal/S = speaker + if(S.speak && S.speak.len) + message = pick(S.speak) + else + return + else + if(language) + message = language.scramble(message) + else + message = stars(message) + + if(hard_to_hear) message = stars(message) - if(language) - verb = language.speech_verb - style = language.colour - - - - if(hard_to_hear) - message = stars(message) - if(speaker) - speaker_name = speaker.name + var/speaker_name = speaker.name if(vname) speaker_name = vname - if(speaker && (istype(speaker, /mob/living/carbon/human))) + if(istype(speaker, /mob/living/carbon/human)) var/mob/living/carbon/human/H = speaker if(H.voice) speaker_name = H.voice @@ -118,7 +127,7 @@ var/jobname // the mob's "job" var/mob/living/carbon/human/impersonating //The crewmember being impersonated, if any. - if (speaker && (ishuman(speaker))) + if (ishuman(speaker)) var/mob/living/carbon/human/H = speaker if((H.wear_id && istype(H.wear_id,/obj/item/weapon/card/id/syndicate)) && (H.wear_mask && istype(H.wear_mask,/obj/item/clothing/mask/gas/voice))) @@ -158,13 +167,18 @@ speaker_name = "[speaker.real_name] ([speaker_name])" track = "[speaker_name] (follow)" + var/formatted + if(language) + formatted = language.format_message_radio(message, verb) + else + formatted = "[verb], \"[message]\"" if(sdisabilities & DEAF || ear_deaf) if(prob(20)) src << "You feel your headset vibrate but can hear nothing from it!" else if(track) - src << "[part_a][track][part_b][verb], \"[message]\"" + src << "[part_a][track][part_b][formatted]" else - src << "[part_a][speaker_name][part_b][verb], \"[message]\"" + src << "[part_a][speaker_name][part_b][formatted]" /mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null) if(!client) @@ -205,8 +219,6 @@ M.show_message(message) src << message -//////////////////////////////////////////////////////////////////////// - /mob/proc/hear_sleep(var/message) var/heard = "" if(prob(15)) diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 253a54a4..b61bb94e 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -1,3 +1,5 @@ +#define SCRAMBLE_CACHE_LEN 20 + /* Datum based languages. Easily editable and modular. */ @@ -8,29 +10,103 @@ var/speech_verb = "says" // 'says', 'hisses', 'farts'. var/ask_verb = "asks" // Used when sentence ends in a ? var/exclaim_verb = "exclaims" // Used when sentence ends in a ! + var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead. var/signlang_verb = list() // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags - var/colour = "body" // CSS style to use for strings in this language. + var/colour = "body" // CSS style to use for strings in this language. var/key = "x" // Character used to speak in language eg. :o for Unathi. var/flags = 0 // Various language flags. var/native // If set, non-native speakers will have trouble speaking. + var/list/syllables // Used when scrambling text for a non-speaker. + var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string. + +/datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4) + if(!syllables || !syllables.len) + if(gender==FEMALE) + return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) + else + return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + + var/full_name = "" + var/new_name = "" + + for(var/i = 0;i0;x--) + new_name += pick(syllables) + full_name += " [capitalize(lowertext(new_name))]" + + return "[trim(full_name)]" + +/datum/language + var/list/scramble_cache = list() + +/datum/language/proc/scramble(var/input) + + if(!syllables || !syllables.len) + return stars(input) + + // If the input is cached already, move it to the end of the cache and return it + if(input in scramble_cache) + var/n = scramble_cache[input] + scramble_cache -= input + scramble_cache[input] = n + return n + + var/input_size = length(input) + var/scrambled_text = "" + var/capitalize = 1 + + while(length(scrambled_text) < input_size) + var/next = pick(syllables) + if(capitalize) + next = capitalize(next) + capitalize = 0 + scrambled_text += next + var/chance = rand(100) + if(chance <= 5) + scrambled_text += ". " + capitalize = 1 + else if(chance > 5 && chance <= space_chance) + scrambled_text += " " + + scrambled_text = trim(scrambled_text) + var/ending = copytext(scrambled_text, length(scrambled_text)) + if(ending == ".") + scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1) + var/input_ending = copytext(input, input_size) + if(input_ending in list("!","?",".")) + scrambled_text += input_ending + + // Add it to cache, cutting old entries if the list is too long + scramble_cache[input] = scrambled_text + if(scramble_cache.len > SCRAMBLE_CACHE_LEN) + scramble_cache.Cut(1, scramble_cache.len-SCRAMBLE_CACHE_LEN-1) + + + return scrambled_text + +/datum/language/proc/format_message(message, verb) + return "[verb], \"[capitalize(message)]\"" + +/datum/language/proc/format_message_plain(message, verb) + return "[verb], \"[capitalize(message)]\"" + +/datum/language/proc/format_message_radio(message, verb) + return "[verb], \"[capitalize(message)]\"" + +/datum/language/proc/get_talkinto_msg_range(message) + // if you yell, you'll be heard from two tiles over instead of one + return (copytext(message, length(message)) == "!") ? 2 : 1 /datum/language/proc/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) - log_say("[key_name(speaker)] : ([name]) [message]") + if(!speaker_mask) speaker_mask = speaker.name + var/msg = "[name], [speaker_mask] [format_message(message, get_spoken_verb(message))]" + for(var/mob/player in player_list) - - var/understood = 0 - - if(istype(player,/mob/dead)) - understood = 1 - else if((src in player.languages) && check_special_condition(player)) - understood = 1 - - if(understood) - if(!speaker_mask) speaker_mask = speaker.name - var/msg = "[name], [speaker_mask] [speech_verb], \"[message]\"" - player << "[msg]" + if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player))) + player << msg /datum/language/proc/check_special_condition(var/mob/other) return 1 @@ -43,6 +119,26 @@ return ask_verb return speech_verb +// Noise "language", for audible emotes. +/datum/language/noise + name = "Noise" + desc = "Noises" + key = "" + flags = RESTRICTED|NONGLOBAL|INNATE|NO_TALK_MSG|NO_STUTTER + +/datum/language/noise/format_message(message, verb) + return "[message]" + +/datum/language/noise/format_message_plain(message, verb) + return message + +/datum/language/noise/format_message_radio(message, verb) + return "[message]" + +/datum/language/noise/get_talkinto_msg_range(message) + // if you make a loud noise (screams etc), you'll be heard from 4 tiles over instead of two + return (copytext(message, length(message)) == "!") ? 4 : 2 + /datum/language/unathi name = "Sinta'unathi" desc = "The common language of Moghes, composed of sibilant hisses and rattles. Spoken natively by Unathi." @@ -52,16 +148,37 @@ colour = "soghun" key = "o" flags = WHITELISTED + syllables = list("ss","ss","ss","ss","skak","seeki","resh","las","esi","kor","sh") + +/datum/language/unathi/get_random_name() + + var/new_name = ..() + while(findtextEx(new_name,"sss",1,null)) + new_name = replacetext(new_name, "sss", "ss") + return capitalize(new_name) /datum/language/tajaran name = "Siik'Maas" - desc = "An expressive language that combines yowls and chirps with posture, tail and ears. Native to the Tajaran." + desc = "The traditionally employed tongue of Ahdomai, composed of expressive yowls and chirps. Native to the Tajaran." speech_verb = "mrowls" ask_verb = "mrowls" exclaim_verb = "yowls" colour = "tajaran" key = "j" flags = WHITELISTED + syllables = list("rr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr", \ + "mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", \ + "ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", \ + "hal","ket","jurl","mah","tul","cresh","azu","ragh") + +/datum/language/tajaran/get_random_name(var/gender) + + var/new_name = ..(gender,1) + if(prob(80)) + new_name += " [pick(list("Hadii","Kaytam","Zhan-Khazan","Hharar","Njarir'Akhan"))]" + else + new_name += ..(gender,1) + return new_name /datum/language/skrell name = "Skrellian" @@ -72,6 +189,35 @@ colour = "skrell" key = "k" flags = WHITELISTED + syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!") + +/datum/language/sign + name = "Sign language" + desc = "A mixture of manual communication and body-languaged, used to communication with those who have impaired hearing." + speech_verb = "signs" + signlang_verb = list("signs") + key = "4" + flags = SIGNLANG + +/datum/language/sini + name = "Sini" + desc = "Kocasslani traditional language" + speech_verb = "sings" + colour = "skrell" + key = "z" + flags = WHITELISTED + syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!") + + +/datum/language/vaurcese + name = "Vaurcese" + desc = "Vaurca native language made of clicks and sputters, \"It's a bugs life.\"" + speech_verb = "clicks" + colour = "vaurca" + key = "p" + flags = WHITELISTED + syllables = list("kic","klic","\'tic","kit","lit","xic","vil","xrit","tshh","qix","qlit","zix","\'","!") + /datum/language/vox name = "Vox-pidgin" @@ -81,7 +227,12 @@ exclaim_verb = "SHRIEKS" colour = "vox" key = "v" - flags = RESTRICTED + flags = WHITELISTED + syllables = list("ti","ti","ti","hi","hi","ki","ki","ki","ki","ya","ta","ha","ka","ya","chi","cha","kah", \ + "SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA") + +/datum/language/vox/get_random_name() + return ..(FEMALE,1,6) /datum/language/diona name = "Rootspeak" @@ -92,14 +243,23 @@ colour = "soghun" key = "q" flags = RESTRICTED + syllables = list("hs","zt","kr","st","sh") + +/datum/language/diona/get_random_name() + var/new_name = "[pick(list("To Sleep Beneath","Wind Over","Embrace of","Dreams of","Witnessing","To Walk Beneath","Approaching the"))]" + new_name += " [pick(list("the Void","the Sky","Encroaching Night","Planetsong","Starsong","the Wandering Star","the Empty Day","Daybreak","Nightfall","the Rain"))]" + return new_name /datum/language/common name = "Ceti Basic" desc = "The common galactic tongue." speech_verb = "says" + whisper_verb = "whispers" key = "0" flags = RESTRICTED + syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah") +//TODO flag certain languages to use the mob-type specific say_quote and then get rid of these. /datum/language/common/get_spoken_verb(var/msg_end) switch(msg_end) if("!") @@ -111,9 +271,20 @@ /datum/language/human name = "Sol Common" desc = "A bastardized hybrid of informal English and elements of Mandarin Chinese; the common language of the Sol system." - colour = "rough" + speech_verb = "says" + whisper_verb = "whispers" + colour = "solcom" key = "1" flags = RESTRICTED + syllables = list("tao","shi","tzu","yi","com","be","is","i","op","vi","ed","lec","mo","cle","te","dis","e") + +/datum/language/human/get_spoken_verb(var/msg_end) + switch(msg_end) + if("!") + return pick("exclaims","shouts","yells") //TODO: make the basic proc handle lists of verbs. + if("?") + return ask_verb + return speech_verb // Galactic common languages (systemwide accepted standards). /datum/language/trader @@ -122,6 +293,15 @@ speech_verb = "enunciates" colour = "say_quote" key = "2" + space_chance = 100 + syllables = list("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", + "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", + "magna", "aliqua", "ut", "enim", "ad", "minim", "veniam", "quis", "nostrud", + "exercitation", "ullamco", "laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo", + "consequat", "duis", "aute", "irure", "dolor", "in", "reprehenderit", "in", + "voluptate", "velit", "esse", "cillum", "dolore", "eu", "fugiat", "nulla", + "pariatur", "excepteur", "sint", "occaecat", "cupidatat", "non", "proident", "sunt", + "in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum") /datum/language/gutter name = "Gutter" @@ -129,34 +309,8 @@ speech_verb = "growls" colour = "rough" key = "3" + syllables = list ("gra","ba","ba","breh","bra","rah","dur","ra","ro","gro","go","ber","bar","geh","heh", "gra") -/datum/language/sini - name = "Sini" - desc = "Kocasslani traditional language" - speech_verb = "sings" - colour = "skrell" - key = "z" - flags = WHITELISTED - -/datum/language/sign - name = "Sign language" - desc = "A mixture of manual communication and body-languaged, used to communication with those who have impaired hearing." - speech_verb = "signs" - signlang_verb = list("signs") - key = "4" - flags = SIGNLANG - -/datum/language/vaurcese - name = "Vaurcese" - desc = "Vaurca native language made of clicks and sputters, \"It's a bugs life.\"" - speech_verb = "clicks" - colour = "vaurca" - key = "p" - flags = WHITELISTED - -//////////////////////////////////// -//Not sure if stuff but yeah -//////////////////////////////////// /datum/language/xenocommon name = "Xenomorph" colour = "alien" @@ -166,6 +320,7 @@ exclaim_verb = "hisses" key = "5" flags = RESTRICTED + syllables = list("sss","sSs","SSS") /datum/language/xenos name = "Hivemind" @@ -257,7 +412,7 @@ if(drone_only && !istype(S,/mob/living/silicon/robot/drone)) continue else if(istype(S , /mob/living/silicon/ai)) - message_start = "[name], [speaker.name]" + message_start = "[name], [speaker.name]" else if (!S.binarycheck()) continue @@ -270,13 +425,13 @@ if(istype(M, /mob/living/silicon) || M.binarycheck()) continue M.show_message("synthesised voice beeps, \"beep beep beep\"",2) -/* + //robot binary xmitter component power usage - if (isrobot(speaker)) - var/mob/living/silicon/robot/R = speaker - var/datum/robot_component/C = R.components["comms"] - R.cell_use_power(C.active_usage) -*/ +// if (isrobot(speaker)) +// var/mob/living/silicon/robot/R = speaker +// var/datum/robot_component/C = R.components["comms"] +// R.cell_use_power(C.active_usage) + /datum/language/binary/drone name = "Drone Talk" desc = "A heavily encoded damage control coordination stream." @@ -287,9 +442,6 @@ key = "d" flags = RESTRICTED | HIVEMIND drone_only = 1 -/////////////////////////////////////// -//Yeah but stuff if sure not -/////////////////////////////////////// // Language handling. /mob/proc/add_language(var/language) @@ -303,15 +455,14 @@ return 1 /mob/proc/remove_language(var/rem_language) - - languages.Remove(all_languages[rem_language]) - - return 0 + var/datum/language/L = all_languages[rem_language] + . = (L in languages) + languages.Remove(L) // Can we speak this language, as opposed to just understanding it? /mob/proc/can_speak(datum/language/speaking) - return (universal_speak || speaking in src.languages) + return (universal_speak || (speaking && speaking.flags & INNATE) || speaking in src.languages) //TBD /mob/verb/check_languages() @@ -322,7 +473,10 @@ var/dat = "Known Languages

" for(var/datum/language/L in languages) - dat += "[L.name] (:[L.key])
[L.desc]

" + if(!(L.flags & NONGLOBAL)) + dat += "[L.name] (:[L.key])
[L.desc]

" src << browse(dat, "window=checklanguage") - return \ No newline at end of file + return + +#undef SCRAMBLE_CACHE_LEN diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 0e41a169..1a0399fa 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1344,7 +1344,14 @@ if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO if(healths) healths.icon_state = "health7" //DEAD healthmeter if(client) - if(client.view != world.view)if(client.view != world.view) // If mob moves while zoomed in with device, unzoom them. + if(client.view != world.view) // If mob moves while zoomed in with device, unzoom them. + for(var/obj/item/item in contents) + if(item.zoom) + item.zoom() + break + + + /* if(locate(/obj/item/weapon/gun/energy/rifle/sniperrifle, contents)) var/obj/item/weapon/gun/energy/rifle/sniperrifle/s = locate() in src if(s.zoom) @@ -1353,7 +1360,7 @@ var/obj/item/weapon/gun/energy/laser/modular/s = locate() in src if(s.zoom) s.zoom() - + */ else sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS) see_in_dark = species.darksight diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index b679a874..648bcefa 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -1,4 +1,6 @@ -/mob/living/carbon/human/say(var/message, var/verb = "says") +/mob/living/carbon/human/say(var/message) + + var/verb = "says" var/alt_name = "" var/message_range = world.view var/italics = 0 @@ -8,16 +10,19 @@ src << "\red You cannot speak in IC (Muted)." return - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + message = trim_strip_html_properly(message) - if(stat == 2) - return say_dead(message) + if(stat) + if(stat == 2) + return say_dead(message) + return + + if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) + src << "You're muzzled and cannot speak!" + return var/message_mode = parse_message_mode(message, "headset") -// if (istype(wear_mask, /obj/item/clothing/mask/muzzle) && message_mode != "changeling") //Todo: Add this to speech_problem_flag checks. -// return -// if(copytext(message,1,2) == "*") return emote(copytext(message,2)) @@ -31,6 +36,8 @@ else message = copytext(message,3) + message = trim_left(message) + //parse the language code and consume it var/datum/language/speaking = parse_language(message) if(speaking) @@ -66,7 +73,6 @@ if(!message || stat) return - if(speaking && speaking.flags & SIGNLANG) message_mode = null ..(message, speaking, verb, alt_name, italics, message_range) @@ -123,27 +129,14 @@ if("whisper") whisper_say(message, speaking, alt_name) return -/* if("binary") - if(robot_talk_understand || binarycheck()) - robot_talk(message) - return - if("changeling") - if(mind && mind.changeling) - for(var/mob/Changeling in mob_list) - if((Changeling.mind && Changeling.mind.changeling) || istype(Changeling, /mob/dead/observer)) - Changeling << "[mind.changeling.changelingID]: [message]" - return -*/ else - if(!(stunned >= 4)) - if(message_mode) - if(message_mode in (radiochannels | "department" | "special")) - if(l_ear && istype(l_ear,/obj/item/device/radio)) - l_ear.talk_into(src,message, message_mode, verb, speaking) - used_radios += l_ear - else if(r_ear && istype(r_ear,/obj/item/device/radio)) - r_ear.talk_into(src,message, message_mode, verb, speaking) - used_radios += r_ear + if(message_mode) + if(l_ear && istype(l_ear,/obj/item/device/radio)) + l_ear.talk_into(src,message, message_mode, verb, speaking) + used_radios += l_ear + else if(r_ear && istype(r_ear,/obj/item/device/radio)) + r_ear.talk_into(src,message, message_mode, verb, speaking) + used_radios += r_ear var/sound/speech_sound var/sound_vol @@ -155,10 +148,14 @@ if(used_radios.len) italics = 1 message_range = 1 - + if(speaking) + message_range = speaking.get_talkinto_msg_range(message) + var/msg + if(!speaking || !(speaking.flags & NO_TALK_MSG)) + msg = "\The [src] talks into \the [used_radios[1]]" for(var/mob/living/M in hearers(5, src)) - if(M != src) - M.show_message("[src] talks into [used_radios.len ? used_radios[1] : "the radio."]") + if((M != src) && msg) + M.show_message(msg) if (speech_sound) sound_vol *= 0.5 @@ -237,6 +234,7 @@ return GetSpecialVoice() return real_name + /mob/living/carbon/human/proc/SetSpecialVoice(var/new_voice) if(new_voice) special_voice = new_voice @@ -274,45 +272,46 @@ return verb /mob/living/carbon/human/proc/handle_speech_problems(var/message) + var/list/returns[3] var/verb = "says" var/handled = 0 - if(silent) + if(silent || (sdisabilities & MUTE)) message = "" handled = 1 - if(sdisabilities & MUTE) - message = "" - handled = 1 - if(wear_mask) - if(istype(wear_mask, /obj/item/clothing/mask/horsehead)) - var/obj/item/clothing/mask/horsehead/hoers = wear_mask - if(hoers.voicechange) - if(mind && mind.changeling && department_radio_keys[copytext(message, 1, 3)] != "changeling") - message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") - verb = pick("whinnies","neighs", "says") - handled = 1 + if(istype(wear_mask, /obj/item/clothing/mask/horsehead)) + var/obj/item/clothing/mask/horsehead/hoers = wear_mask + if(hoers.voicechange) + if(mind && mind.changeling && department_radio_keys[copytext(message, 1, 3)] != "changeling") + message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") + verb = pick("whinnies","neighs", "says") + handled = 1 - if((HULK in mutations) && health >= 25 && length(message)) -// message = "[uppertext(message)]!!!" //No! - verb = pick("yells","roars","hollers") - handled = 1 - if(slurring) - message = slur(message) - verb = pick("stammers","stutters") - handled = 1 - - var/braindam = getBrainLoss() - if(braindam >= 60) - handled = 1 - if(prob(braindam/4)) + if(message != "") + if((HULK in mutations) && health >= 25 && length(message)) + message = "[uppertext(message)]!!!" + verb = pick("yells","roars","hollers") + handled = 1 + if(slurring) + message = slur(message) + verb = pick("slobbers","slurs") + handled = 1 + if(stuttering) message = stutter(message) - verb = pick("stammers", "stutters") - if(prob(braindam)) - message = uppertext(message) - verb = pick("yells like an idiot","says rather loudly") + verb = pick("stammers","stutters") + handled = 1 + + var/braindam = getBrainLoss() + if(braindam >= 60) + handled = 1 + if(prob(braindam/4)) + message = stutter(message) + verb = pick("stammers", "stutters") + if(prob(braindam)) + message = uppertext(message) + verb = "yells loudly" returns[1] = message returns[2] = verb returns[3] = handled - return returns diff --git a/code/modules/mob/living/simple_animal/friendly/mushroom.dm b/code/modules/mob/living/simple_animal/friendly/mushroom.dm index 9bd464db..c39a3031 100644 --- a/code/modules/mob/living/simple_animal/friendly/mushroom.dm +++ b/code/modules/mob/living/simple_animal/friendly/mushroom.dm @@ -1,9 +1,10 @@ /mob/living/simple_animal/mushroom name = "walking mushroom" desc = "It's a massive mushroom... with legs?" - icon_state = "mushroom" - icon_living = "mushroom" - icon_dead = "mushroom_dead" + icon = 'icons/mob/livestock.dmi' + icon_state = "walkingmushroom" + icon_living = "walkingmushroom" + icon_dead = "walkingmushroom_d" small = 1 speak_chance = 0 turns_per_move = 1 diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index dd72497f..e4a8f93e 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -243,6 +243,12 @@ if ((O.client && !( O.blinded ))) O.show_message("\blue [M] [response_help] [src]") + if("disarm") + if (health > 0) + for(var/mob/O in viewers(src, null)) + if ((O.client && !( O.blinded ))) + O.show_message("\blue [M] [response_disarm] [src]") + if("grab") if (M == src) return @@ -262,7 +268,7 @@ if ((O.client && !( O.blinded ))) O.show_message(text("\red [] has grabbed [] passively!", M, src), 1) - if("hurt", "disarm") + if("hurt") adjustBruteLoss(harm_intent_damage) for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 3e58626b..3fcdecb0 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -190,6 +190,12 @@ return if(mob.client) if(mob.client.view != world.view) + for(var/obj/item/item in mob.contents) + if(item.zoom) + item.zoom() + break + + /* if(locate(/obj/item/weapon/gun/energy/rifle/sniperrifle, mob.contents)) // If mob moves while zoomed in with sniper rifle, unzoom them. var/obj/item/weapon/gun/energy/rifle/sniperrifle/s = locate() in mob if(s.zoom) @@ -198,6 +204,7 @@ var/obj/item/weapon/gun/energy/laser/modular/s = locate() in mob if(s.zoom) s.zoom() + */ if(Process_Grab()) return diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index ad2e5977..454c962f 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -12,6 +12,21 @@ if(say_disabled) //This is here to try to identify lag problems usr << "\red Speech is currently admin-disabled." return + //Let's try to make users fix their errors - we try to detect single, out-of-place letters and 'unintended' words + /* + var/first_letter = copytext(message,1,2) + if((copytext(message,2,3) == " " && first_letter != "I" && first_letter != "A" && first_letter != ";") || cmptext(copytext(message,1,5), "say ") || cmptext(copytext(message,1,4), "me ") || cmptext(copytext(message,1,6), "looc ") || cmptext(copytext(message,1,5), "ooc ") || cmptext(copytext(message,2,6), "say ")) + var/response = alert(usr, "Do you really want to say this using the *say* verb?\n\n[message]\n", "Confirm your message", "Yes", "Edit message", "No") + if(response == "Edit message") + message = input(usr, "Please edit your message carefully:", "Edit message", message) + if(!message) + return + else if(response == "No") + return + */ + +//We do not have typing indicator code yet - Waiting for the okay from Skull before considering adding - Jamini +// set_typing_indicator(0) usr.say(message) /mob/verb/me_verb(message as text) @@ -22,8 +37,9 @@ usr << "\red Speech is currently admin-disabled." return - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - + message = strip_html_properly(message) +//We do not have typing indicator code yet - Waiting for the okay from Skull before considering adding - Jamini +// set_typing_indicator(0) if(use_me) usr.emote("me",usr.emote_type,message) else @@ -68,7 +84,6 @@ return - /mob/proc/say_understands(var/mob/other,var/datum/language/speaking = null) if (src.stat == 2) //Dead @@ -90,6 +105,9 @@ return 1 return 0 + if(speaking.flags & INNATE) + return 1 + //Language check. for(var/datum/language/L in src.languages) if(speaking.name == L.name) @@ -153,6 +171,9 @@ //parses the language code (e.g. :j) from text, such as that supplied to say. //returns the language object only if the code corresponds to a language that src can speak, otherwise null. /mob/proc/parse_language(var/message) + if(length(message) >= 1 && copytext(message,1,2) == "!") + return all_languages["Noise"] + if(length(message) >= 2) var/language_prefix = lowertext(copytext(message, 1 ,3)) var/datum/language/L = language_keys[language_prefix] diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 512b9429..515f2e51 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -37,7 +37,7 @@ spawn(5) if(!powernet) connect_to_network() - + dir_loop: for(var/d in cardinal) var/turf/T = get_step(src, d) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 89608e7e..ff8a05e0 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -249,6 +249,11 @@ mouthshoot = 0 return + if(istype(in_chamber, /obj/item/projectile/beam/practice)) + user.show_message("You feel rather silly, trying to commit suicide with a practice gun.") + mouthshoot = 0 + return + in_chamber.on_hit(M) if (in_chamber.damage_type != HALLOSS) user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1) diff --git a/code/modules/projectiles/guns/energy/erifles.dm b/code/modules/projectiles/guns/energy/erifles.dm index 1ef01d0d..230f1119 100644 --- a/code/modules/projectiles/guns/energy/erifles.dm +++ b/code/modules/projectiles/guns/energy/erifles.dm @@ -133,61 +133,17 @@ Commenting out right now, due to a lack of sprites existing. I hate on-mob weapo w_class = 4.0 fire_delay_wielded = 35 //35 is normal fire_delay -- this is going to suck. Yiss, what we want! fire_delay_unwielded = 105 //3x difference, let's be an arse about this, and push the issue - var/zoom = 0 + zoomdevicename = "sniper scope" accuracy = -110 - rangedrop = -5 // fully accurate up to first 10 tiles. the last 4 zoomed tiles you are on your + rangedrop = -2 // fully accurate up to first 10 tiles. the last 4 zoomed tiles you are on your -/obj/item/weapon/gun/energy/rifle/sniperrifle/dropped(mob/user) - user.client.view = world.view - ..() - -/obj/item/weapon/gun/energy/rifle/sniperrifle/ready_to_fire() - if(!zoom) - return 0 - if(world.time >= last_fired + fire_delay) - last_fired = world.time - return 1 - else - return 0 - -///obj/item/weapon/gun/energy/rifle/sniperrifle/update_icon() //Currently only here to fuck with the on-mob icons. -// icon_state = "sniper[wielded]" -// return - -/* -This is called from -modules/mob/mob_movement.dm if you move you will be zoomed out -modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. -*/ - -/obj/item/weapon/gun/energy/rifle/sniperrifle/verb/zoom() +/obj/item/weapon/gun/energy/rifle/sniperrifle/verb/scope() set category = "Object" - set name = "Use Sniper Scope" - set popup_menu = 0 - if(usr.stat || !(istype(usr,/mob/living/carbon/human))) - usr << "You are unable to focus down the scope of the rifle." - return - if(!zoom && global_hud.darkMask[1] in usr.client.screen) - usr << "Your welding equipment gets in the way of you looking down the scope" - return - if(!zoom && usr.get_active_hand() != src) - usr << "You are too distracted to look down the scope, perhaps if it was in your active hand this might work better" - return + set name = "Use Scope" + set popup_menu = 1 - if(usr.client.view == world.view) - if(!usr.hud_used.hud_shown) - usr.button_pressed_F12(1) // If the user has already limited their HUD this avoids them having a HUD when they zoom in - usr.button_pressed_F12(1) - usr.client.view = 12 - zoom = 1 - else - usr.client.view = world.view - if(!usr.hud_used.hud_shown) - usr.button_pressed_F12(1) - zoom = 0 - usr << "Zoom mode [zoom?"en":"dis"]abled." - return + zoom() ///////////LASER CANNON////////////// diff --git a/code/modules/projectiles/guns/energy/modular.dm b/code/modules/projectiles/guns/energy/modular.dm index 87564873..0f41b1d7 100644 --- a/code/modules/projectiles/guns/energy/modular.dm +++ b/code/modules/projectiles/guns/energy/modular.dm @@ -13,7 +13,7 @@ cell_type = "/obj/item/weapon/cell" var/canzoom = 0 - var/zoom = 0 + zoomdevicename = "scan screen" var/open = 0 var/upgradepointtotal = 16 //KNOWN BUG: Crashes if you try to VV it with a lot of stuff inside. By a lot, I mean 'everything.' At least in all my tests. @@ -358,34 +358,9 @@ /obj/item/weapon/gun/energy/laser/modular/dropped(mob/user) user.client.view = world.view -/obj/item/weapon/gun/energy/laser/modular/verb/zoom() +/obj/item/weapon/gun/energy/laser/modular/verb/scope() set category = "Object" set name = "Use Scan-Screen" - set popup_menu = 0 + set popup_menu = 1 - if(usr.stat || !(istype(usr,/mob/living/carbon/human))) - usr << "You are unable to focus on the screen." - return - if(!zoom && global_hud.darkMask[1] in usr.client.screen) - usr << "Your welding equipment makes it hard to see the screen." - return - if(!zoom && usr.get_active_hand() != src) - usr << "You are too distracted to watch the screen, perhaps if it was in your active hand this might work better" - return - if((hasscreen == 0) || (canzoom == 0)) - usr << "This gun lacks the parts for components for zooming." - return - - if(usr.client.view == world.view) - if(!usr.hud_used.hud_shown) - usr.button_pressed_F12(1) // If the user has already limited their HUD this avoids them having a HUD when they zoom in - usr.button_pressed_F12(1) - usr.client.view = 12 - zoom = 1 - else - usr.client.view = world.view - if(!usr.hud_used.hud_shown) - usr.button_pressed_F12(1) - zoom = 0 - usr << "Zoom mode [zoom?"en":"dis"]abled." - return \ No newline at end of file + zoom() \ No newline at end of file diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index bb11ef81..a54e5df2 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -95,6 +95,10 @@ miss_modifier += -30 def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier + 15*distance + daddy.accuracy + daddy.rangedrop) // add +daddy.missmod vars to gun and this. snowflake accuracy //moving def_zone to be a child of the daddyblock because i need the daddy. all projectiles should be fired from guns anyway + + if (istype(shot_from,/obj/item/mecha_parts/mecha_equipment/weapon)) //If you shoot with a mecha weapon instead, check accuracy without a steady variable + def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier + 10*distance) + if(!def_zone) visible_message("\blue \The [src] misses [M] narrowly!") forcedodge = -1 diff --git a/code/setup.dm b/code/setup.dm index 9f687a5b..37517f27 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -710,6 +710,9 @@ var/list/be_special_flags = list( #define LEFT 1 #define RIGHT 2 + + + // for secHUDs and medHUDs and variants. The number is the location of the image on the list hud_list of humans. #define HEALTH_HUD 1 // a simple line rounding the mob's number health #define STATUS_HUD 2 // alive, dead, diseased, etc. @@ -773,6 +776,10 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse #define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight #define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand. #define HIVEMIND 16 // Broadcast to all mobs with this language. +#define NONGLOBAL 32 // Do not add to general languages list +#define INNATE 64 // All mobs can be assumed to speak and understand this language (audible emotes) +#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message +#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems //Flags for zone sleeping #define ZONE_ACTIVE 1 diff --git a/html/changelog.html b/html/changelog.html index 46dc21c1..6182eb63 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,35 @@ should be listed in the changelog upon commit though. Thanks. --> +
+

29 March 2015

+

SoundScopes updated:

+
    +
  • Languages no longer come out as ***********
  • +
  • Changelings can change thier arms into Blades
  • +
  • Changelings can change thier arms into a Shield
  • +
  • Force gloves (Trial)
  • +
  • Binoculars
  • +
  • No longer able to modify the genomes for IPCs, nor inject them with the DNA injectors(Might carry over to Diona)
  • +
  • Vampires can no longer stunn themselves when using glare
  • +
  • (Server)Security flaw
  • +
  • Player Memo's show up again
  • +
  • Mech projectile weapons will now hit their target
  • +
  • Suit cooling units will now work while on back as well, much like an oxygen tank
  • +
  • Walking mushrooms are now visible
  • +
  • Altered the EMP code so that mechas are actually affected by the exosuit computer commands
  • +
  • Requests consoles no longer print when out of paper
  • +
  • Duty Officer things
  • +
  • Zoom code.
  • +
  • Cane Sword is now called a thin sword, so you don't know what it's from.
  • +
  • No longer able to suicide with a practice rifle
  • +
  • Added disarm to simple mobs rather than defaulting to harm
  • +
  • Tables are a little more resistant to damage (100% increase) and has a better chance of deflecting projectiles
  • +
+
+ + +

16 March 2015

Skull132 updated:

diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 654d35b6..52db8a3d 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index 8d7f7f0c..e784cc74 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/mob/hands.dmi b/icons/mob/hands.dmi index c6acbcf8..635146b9 100644 Binary files a/icons/mob/hands.dmi and b/icons/mob/hands.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index ab05d894..bda8b2a1 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi index f383fb50..66ea91d0 100644 Binary files a/icons/mob/items_lefthand.dmi and b/icons/mob/items_lefthand.dmi differ diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi index 30636b09..77ee1897 100644 Binary files a/icons/mob/items_righthand.dmi and b/icons/mob/items_righthand.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 7b448e9c..37c84f14 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/species/skrell/helmet.dmi b/icons/mob/species/skrell/helmet.dmi index 1a7219ab..99ee56a1 100644 Binary files a/icons/mob/species/skrell/helmet.dmi and b/icons/mob/species/skrell/helmet.dmi differ diff --git a/icons/mob/species/skrell/suit.dmi b/icons/mob/species/skrell/suit.dmi index 2cf6c293..bc0eafe0 100644 Binary files a/icons/mob/species/skrell/suit.dmi and b/icons/mob/species/skrell/suit.dmi differ diff --git a/icons/mob/species/tajaran/helmet.dmi b/icons/mob/species/tajaran/helmet.dmi index 3461fd47..a492b871 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/suit.dmi b/icons/mob/species/tajaran/suit.dmi index be9e7e6e..5ebfbfd2 100644 Binary files a/icons/mob/species/tajaran/suit.dmi and b/icons/mob/species/tajaran/suit.dmi differ diff --git a/icons/mob/species/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi index 367693a6..b4b3c859 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/suit.dmi b/icons/mob/species/unathi/suit.dmi index 9a2fe5a4..74c29181 100644 Binary files a/icons/mob/species/unathi/suit.dmi and b/icons/mob/species/unathi/suit.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 6229066b..105e29c0 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi index 87293f95..83099df9 100644 Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 89a7b011..206b00ec 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/clothing/species/skrell/hats.dmi b/icons/obj/clothing/species/skrell/hats.dmi index faf209c3..83547faf 100644 Binary files a/icons/obj/clothing/species/skrell/hats.dmi and b/icons/obj/clothing/species/skrell/hats.dmi differ diff --git a/icons/obj/clothing/species/skrell/suits.dmi b/icons/obj/clothing/species/skrell/suits.dmi index 5f6f5843..eedbbf78 100644 Binary files a/icons/obj/clothing/species/skrell/suits.dmi and b/icons/obj/clothing/species/skrell/suits.dmi differ diff --git a/icons/obj/clothing/species/tajaran/hats.dmi b/icons/obj/clothing/species/tajaran/hats.dmi index 65b959c8..0de513c2 100644 Binary files a/icons/obj/clothing/species/tajaran/hats.dmi and b/icons/obj/clothing/species/tajaran/hats.dmi differ diff --git a/icons/obj/clothing/species/tajaran/suits.dmi b/icons/obj/clothing/species/tajaran/suits.dmi index 0028463f..7af157fd 100644 Binary files a/icons/obj/clothing/species/tajaran/suits.dmi and b/icons/obj/clothing/species/tajaran/suits.dmi differ diff --git a/icons/obj/clothing/species/unathi/hats.dmi b/icons/obj/clothing/species/unathi/hats.dmi index f8cb49ed..7f541867 100644 Binary files a/icons/obj/clothing/species/unathi/hats.dmi and b/icons/obj/clothing/species/unathi/hats.dmi differ diff --git a/icons/obj/clothing/species/unathi/suits.dmi b/icons/obj/clothing/species/unathi/suits.dmi index f67b2668..095313ee 100644 Binary files a/icons/obj/clothing/species/unathi/suits.dmi and b/icons/obj/clothing/species/unathi/suits.dmi differ diff --git a/icons/obj/clothing/ties.dmi b/icons/obj/clothing/ties.dmi index da88859f..01d3193f 100644 Binary files a/icons/obj/clothing/ties.dmi and b/icons/obj/clothing/ties.dmi differ diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index 9b215b9c..1f4cb48b 100644 Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 449854fb..db13b108 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ