From a3dd455a37ce46bb17960c991c1c4216892ee343 Mon Sep 17 00:00:00 2001 From: Remie Richards Date: Sat, 2 Apr 2016 20:52:00 +0100 Subject: [PATCH 1/5] Adds a framework for alternate appearances (override images), the Cardborg costume now makes you look like a real Standard Cyborg --- code/_globalvars/lists/mobs.dm | 1 + code/game/alternate_appearance.dm | 151 +++++++++++++++++++ code/game/atoms.dm | 11 ++ code/game/objects/items.dm | 2 +- code/modules/clothing/head/misc.dm | 8 - code/modules/clothing/head/misc_special.dm | 23 ++- code/modules/clothing/suits/miscellaneous.dm | 21 ++- code/modules/mob/living/silicon/silicon.dm | 2 + code/modules/mob/login.dm | 5 + tgstation.dme | 1 + 10 files changed, 214 insertions(+), 11 deletions(-) create mode 100644 code/game/alternate_appearance.dm diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 74b68d6b05b..4d6d82147f2 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -12,3 +12,4 @@ var/global/list/mob_list = list() //all mobs, including clientless var/global/list/living_mob_list = list() //all alive mobs, including clientless. Excludes /mob/new_player var/global/list/dead_mob_list = list() //all dead mobs, including clientless. Excludes /mob/new_player var/global/list/joined_player_list = list() //all clients that have joined the game at round-start or as a latejoin. +var/global/list/silicon_mobs = list() //all silicon mobs \ No newline at end of file diff --git a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm new file mode 100644 index 00000000000..2ee9b4ae984 --- /dev/null +++ b/code/game/alternate_appearance.dm @@ -0,0 +1,151 @@ +/* + Alternate Appearances! + A framework for replacing an atom (and it's overlays) with an override = 1 image, that's less shit! + Example uses: + * hallucinating all mobs looking like skeletons + * people wearing cardborg suits appearing as Standard Cyborgs to the other Silicons + * !!use your imagination!! + +*/ + + +//This datum is built on-the-fly by some of the procs below +//no need to instantiate it +/datum/alternate_appearance + var/key = "" + var/image/img + var/list/viewers = list() + var/atom/owner = null + + +/* + Displays the alternate_appearance + displayTo - a list of MOBS to show this appearance to +*/ +/datum/alternate_appearance/proc/display_to(list/displayTo) + if(!displayTo || !displayTo.len) + return + for(var/m in displayTo) + var/mob/M = m + if(!M.viewing_alternate_appearances) + M.viewing_alternate_appearances = list() + viewers |= M + M.viewing_alternate_appearances[key] = src + if(M.client) + M.client.images |= img + +/* + Hides the alternate_appearance +*/ +/datum/alternate_appearance/proc/hide() + for(var/m in viewers) + var/mob/M = m + if(M.client) + M.client.images -= img + if(M.viewing_alternate_appearances && M.viewing_alternate_appearances.len) + M.viewing_alternate_appearances[key] = null + M.viewing_alternate_appearances -= key + if(!M.viewing_alternate_appearances.len) + M.viewing_alternate_appearances = null + viewers -= M + + +/* + Removes the alternate_appearance from its owner's alternate_appearances list, hiding it also +*/ +/datum/alternate_appearance/proc/remove() + hide() + if(owner && owner.alternate_appearances) + owner.alternate_appearances[key] = null + owner.alternate_appearances -= key + if(!owner.alternate_appearances.len) + owner.alternate_appearances = null + + +/datum/alternate_appearance/Destroy() + remove() + return ..() + + + +/atom + var/list/alternate_appearances //the alternate appearances we own + var/list/viewing_alternate_appearances //the alternate appearances we're viewing, stored here to reestablish them after Logout()s + //these lists are built/destroyed as necessary, so atoms aren't all lugging around lists full of datums + +/* + Builds an alternate_appearance datum for the supplied args, optionally displaying it straight away + key - the key to the assoc list of key = /datum/alternate_appearances + img - the image file to be the "alternate appearance" + WORKS BEST IF: + * it has override = 1 set + * the image's loc is the atom that will use the appearance (otherwise... it's not exactly an alt appearance of this atom is it?) + displayTo - optional list of MOBS to display to immediately + + Example: + var/image/I = image(icon = 'disguise.dmi', icon_state = "disguise", loc = src) + I.override = 1 + add_alt_appearance("super_secret_disguise", I, players) + +*/ +/atom/proc/add_alt_appearance(key, img, list/displayTo = list()) + if(!key || !img) + return + if(!alternate_appearances) + alternate_appearances = list() + + var/datum/alternate_appearance/AA = new() + AA.img = img + AA.key = key + AA.owner = src + + alternate_appearances[key] = AA + if(displayTo && displayTo.len) + display_alt_appearance(key, displayTo) + + +////////////// +// WRAPPERS // +////////////// + +/* + Removes an alternate_appearance from src's alternate_appearances list + Wrapper for: alternate_appearance/remove() + key - the key to the assoc list of key = /datum/alternate_appearance +*/ +/atom/proc/remove_alt_appearance(key) + if(alternate_appearances) + if(alternate_appearances[key]) + var/datum/alternate_appearance/AA = alternate_appearances[key] + qdel(AA) + + +/* + Displays an alternate appearance from src's alternate_appearances list + Wrapper for: alternate_appearance/display_to() + key - the key to the assoc list of key = /datum/alternate_appearance + displayTo - a list of MOBS to show this appearance to +*/ +/atom/proc/display_alt_appearance(key, list/displayTo) + if(!alternate_appearances || !key) + return + var/datum/alternate_appearance/AA = alternate_appearances[key] + if(!AA || !AA.img) + return + AA.display_to(displayTo) + + +/* + Hides an alternate appearance from src's alternate_appearances list + Wrapper for: alternate_appearance/hide() + key - the key to the assoc list of key = /datum/alternate_appearance +*/ +/atom/proc/hide_alt_appearance(key) + if(!alternate_appearances || !key) + return + var/datum/alternate_appearance/AA = alternate_appearances[key] + if(!AA) + return + AA.hide() + + diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 87881a756ff..38d6c30f658 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -18,6 +18,17 @@ //Value used to increment ex_act() if reactionary_explosions is on var/explosion_block = 0 + +/atom/Destroy() + if(alternate_appearances) + for(var/aakey in alternate_appearances) + var/datum/alternate_appearance/AA = alternate_appearances[aakey] + qdel(AA) + alternate_appearances = null + + return ..() + + /atom/proc/onCentcom() var/turf/T = get_turf(src) if(!T) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d6bce4278bf..f634e1eca8b 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -388,7 +388,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s /obj/item/proc/on_found(mob/finder) return -// called after an item is placed in an equipment slot +// called after an item is placed in an equipment slot //NOPE, for example, if you put a helmet in slot_head, it is NOT in user's head variable yet, how stupid. // user is mob that equipped it // slot uses the slot_X defines found in setup.dm // for items that can be placed in multiple slots diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index e0b2c348d8f..83eed76aeee 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -62,14 +62,6 @@ desc = "A plastic replica of a Syndicate agent's space helmet. You'll look just like a real murderous Syndicate agent in this! This is a toy, it is not made for use in space!" flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR -/obj/item/clothing/head/cardborg - name = "cardborg helmet" - desc = "A helmet made out of a box." - icon_state = "cardborg_h" - item_state = "cardborg_h" - flags_cover = HEADCOVERSEYES - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR - /obj/item/clothing/head/snowman name = "Snowman Head" desc = "A ball of white styrofoam. So festive." diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 9b660fb015c..fb35aceb6b6 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -5,7 +5,7 @@ * Ushanka * Pumpkin head * Kitty ears - * + * Cardborg disguise */ /* @@ -147,3 +147,24 @@ flags_inv = 0 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) brightness_on = 1 //luminosity when on + + +/obj/item/clothing/head/cardborg + name = "cardborg helmet" + desc = "A helmet made out of a box." + icon_state = "cardborg_h" + item_state = "cardborg_h" + flags_cover = HEADCOVERSEYES + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + +/obj/item/clothing/head/cardborg/equipped(mob/living/user, slot) + ..() + if(ishuman(user) && slot == slot_head) + var/mob/living/carbon/human/H = user + if(istype(H.wear_suit, /obj/item/clothing/suit/cardborg)) + var/obj/item/clothing/suit/cardborg/CB = H.wear_suit + CB.disguise(user, src) + +/obj/item/clothing/head/cardborg/dropped(mob/living/user) + ..() + user.remove_alt_appearance("standard_borg_disguise") \ No newline at end of file diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 179e9ab28c6..c5cabc497af 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -155,7 +155,6 @@ allowed = list(/obj/item/weapon/storage/book/bible, /obj/item/weapon/nullrod, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, /obj/item/weapon/storage/fancy/candle_box, /obj/item/candle, /obj/item/weapon/tank/internals/emergency_oxygen) - /obj/item/clothing/suit/cardborg name = "cardborg suit" desc = "An ordinary cardboard box with holes cut in the sides." @@ -164,6 +163,26 @@ body_parts_covered = CHEST|GROIN flags_inv = HIDEJUMPSUIT +/obj/item/clothing/suit/cardborg/equipped(mob/living/user, slot) + ..() + if(slot == slot_wear_suit) + disguise(user) + +/obj/item/clothing/suit/cardborg/dropped(mob/living/user) + ..() + user.remove_alt_appearance("standard_borg_disguise") + +/obj/item/clothing/suit/cardborg/proc/disguise(mob/living/carbon/human/H, obj/item/clothing/head/cardborg/borghead) + if(istype(H)) + if(!borghead) + borghead = H.head + if(istype(borghead, /obj/item/clothing/head/cardborg)) //why is this done this way? because equipped() is called BEFORE THE ITEM IS IN THE SLOT WHYYYY + var/image/I = image(icon = 'icons/mob/robots.dmi' , icon_state = "robot", loc = H) + I.override = 1 + I.overlays += image(icon = 'icons/mob/robots.dmi' , icon_state = "eyes-standard") //gotta look realistic + H.add_alt_appearance("standard_borg_disguise", I, silicon_mobs+H) //you look like a robot to robots! (including yourself because you're totally a robot) + + /obj/item/clothing/suit/snowman name = "snowman outfit" desc = "Two white spheres covered in white glitter. 'Tis the season." diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index c2aa78a467a..f25becac68c 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -35,6 +35,7 @@ /mob/living/silicon/New() ..() + silicon_mobs |= src var/datum/atom_hud/data/diagnostic/diag_hud = huds[DATA_HUD_DIAGNOSTIC] diag_hud.add_to_hud(src) diag_hud_set_status() @@ -43,6 +44,7 @@ /mob/living/silicon/Destroy() radio = null aicamera = null + silicon_mobs -= src return ..() /mob/living/silicon/contents_explosion(severity, target) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index ed0e6f7dac4..f9a79b77a26 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -64,3 +64,8 @@ winset(src, null, "mainwindow.macro=[macro_hotkeys] mapwindow.map.focus=true input.background-color=#e0e0e0") else winset(src, null, "mainwindow.macro=[macro_default] input.focus=true input.background-color=#d3b5b5") + + if(viewing_alternate_appearances && viewing_alternate_appearances.len) + for(var/aa in viewing_alternate_appearances) + var/datum/alternate_appearance/AA = aa + AA.display_to(list(src)) diff --git a/tgstation.dme b/tgstation.dme index 1e4d7a2ce66..4d573aab27d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -234,6 +234,7 @@ #include "code\datums\wires\syndicatebomb.dm" #include "code\datums\wires\vending.dm" #include "code\datums\wires\wires.dm" +#include "code\game\alternate_appearance.dm" #include "code\game\asteroid.dm" #include "code\game\atoms.dm" #include "code\game\atoms_movable.dm" From 30564f29a83ef44e6baa6c1fc6c54fc5c547869d Mon Sep 17 00:00:00 2001 From: Remie Richards Date: Sat, 2 Apr 2016 21:20:03 +0100 Subject: [PATCH 2/5] allows hide() and hide_alt_appearance() to specify a list of mobs to hide it from (as opposed to all of them) --- code/game/alternate_appearance.dm | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm index 2ee9b4ae984..5b8d35a4d9a 100644 --- a/code/game/alternate_appearance.dm +++ b/code/game/alternate_appearance.dm @@ -36,9 +36,14 @@ /* Hides the alternate_appearance + hideFrom - optional list of MOBS to hide it from the list's mobs specifically */ -/datum/alternate_appearance/proc/hide() - for(var/m in viewers) +/datum/alternate_appearance/proc/hide(list/hideFrom) + var/list/hiding = viewers + if(hideFrom) + hiding = hideFrom + + for(var/m in hiding) var/mob/M = m if(M.client) M.client.images -= img @@ -139,13 +144,14 @@ Hides an alternate appearance from src's alternate_appearances list Wrapper for: alternate_appearance/hide() key - the key to the assoc list of key = /datum/alternate_appearance + hideFrom - optional list of MOBS to hide it from the list's mobs specifically */ -/atom/proc/hide_alt_appearance(key) +/atom/proc/hide_alt_appearance(key, list/hideFrom) if(!alternate_appearances || !key) return var/datum/alternate_appearance/AA = alternate_appearances[key] if(!AA) return - AA.hide() + AA.hide(hideFrom) From 065d6c2851b7824c52e278beee9700d7fd50fca2 Mon Sep 17 00:00:00 2001 From: Remie Richards Date: Sun, 3 Apr 2016 00:06:49 +0100 Subject: [PATCH 3/5] fixes leftover logic from a previous build. --- code/modules/mob/login.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index f9a79b77a26..1ce7aed14f9 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -66,6 +66,7 @@ winset(src, null, "mainwindow.macro=[macro_default] input.focus=true input.background-color=#d3b5b5") if(viewing_alternate_appearances && viewing_alternate_appearances.len) - for(var/aa in viewing_alternate_appearances) - var/datum/alternate_appearance/AA = aa - AA.display_to(list(src)) + for(var/aakey in viewing_alternate_appearances) + var/datum/alternate_appearance/AA = viewing_alternate_appearances[aakey] + if(AA) + AA.display_to(list(src)) From 146699b8bcd5e3e72ed8d891baafab42bffdf136 Mon Sep 17 00:00:00 2001 From: Remie Richards Date: Sun, 3 Apr 2016 17:04:35 +0100 Subject: [PATCH 4/5] fixes doubly-removing references. --- code/game/alternate_appearance.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm index 5b8d35a4d9a..cd0c7b5a004 100644 --- a/code/game/alternate_appearance.dm +++ b/code/game/alternate_appearance.dm @@ -48,7 +48,6 @@ if(M.client) M.client.images -= img if(M.viewing_alternate_appearances && M.viewing_alternate_appearances.len) - M.viewing_alternate_appearances[key] = null M.viewing_alternate_appearances -= key if(!M.viewing_alternate_appearances.len) M.viewing_alternate_appearances = null @@ -61,7 +60,6 @@ /datum/alternate_appearance/proc/remove() hide() if(owner && owner.alternate_appearances) - owner.alternate_appearances[key] = null owner.alternate_appearances -= key if(!owner.alternate_appearances.len) owner.alternate_appearances = null From b80d9c9285895475ca01e4df0ba014b8eb605f7e Mon Sep 17 00:00:00 2001 From: Remie Richards Date: Wed, 6 Apr 2016 21:28:01 +0100 Subject: [PATCH 5/5] Adds accreditation for myself because I forgot to and it's fine to credit yourself when it's like a mini-system thing instead of just like one line fixes gosh. --- code/game/alternate_appearance.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm index cd0c7b5a004..005876e8ccc 100644 --- a/code/game/alternate_appearance.dm +++ b/code/game/alternate_appearance.dm @@ -1,5 +1,5 @@ /* - Alternate Appearances! + Alternate Appearances! By RemieRichards A framework for replacing an atom (and it's overlays) with an override = 1 image, that's less shit! Example uses: * hallucinating all mobs looking like skeletons