mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-13 08:03:43 +01:00
Alternate Appearance system (from tgstation/-tg-station#16586)
This adds an "alternate appearance system" using image overrides and a new
handler system.
Usage:
- Create a new `image()` casted as `var/image`
- Set image.override = 1
- Call mob.add_alt_appearance("appearance_ID", image, listOfMobsToDisplayTo).
- To remove an image, you use mob.remove_alt_appearance("appearance_ID")
Comes with one usage, cardborg costumes. They will now disguise you as a
standard borg to any silicon mobs and yourself.
As this is a per-client system, that means that only silicon mobs and you will
see yourself as a standard borg. All other mobs will see you as a silly
human in a cardborg costume.
This commit is contained in:
@@ -17,11 +17,11 @@ var/list/stealthminID = list() //reference list with IDs that store ckeys,
|
||||
|
||||
var/global/list/player_list = list() //List of all mobs **with clients attached**. Excludes /mob/new_player
|
||||
var/global/list/mob_list = list() //List of all mobs, including clientless
|
||||
var/global/list/silicon_mob_list = list() //List of all silicon mobs, including clientless
|
||||
var/global/list/silicon_mob_list = list() //List of all silicon mobs, including clientless
|
||||
var/global/list/spirits = list() //List of all the spirits, including Masks
|
||||
var/global/list/living_mob_list = list() //List of all alive mobs, including clientless. Excludes /mob/new_player
|
||||
var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless. Excludes /mob/new_player
|
||||
var/global/list/respawnable_list = list() //List of all mobs, dead or in mindless creatures that still be respawned.
|
||||
var/global/list/respawnable_list = list() //List of all mobs, dead or in mindless creatures that still be respawned.
|
||||
var/global/list/simple_animal_list = list() //List of all simple animals, including clientless
|
||||
|
||||
var/global/list/med_hud_users = list()
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
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
|
||||
* 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
|
||||
hideFrom - optional list of MOBS to hide it from the list's mobs specifically
|
||||
*/
|
||||
/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
|
||||
if(M.viewing_alternate_appearances && M.viewing_alternate_appearances.len)
|
||||
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
|
||||
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
|
||||
hideFrom - optional list of MOBS to hide it from the list's mobs specifically
|
||||
*/
|
||||
/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(hideFrom)
|
||||
|
||||
|
||||
@@ -67,6 +67,12 @@
|
||||
return 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
|
||||
|
||||
if(reagents)
|
||||
qdel(reagents)
|
||||
reagents = null
|
||||
|
||||
@@ -89,14 +89,6 @@
|
||||
item_state = "greenbandana"
|
||||
flags_inv = 0
|
||||
|
||||
/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 = HEADCOVERSEYES | HEADCOVERSMOUTH
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
|
||||
|
||||
/obj/item/clothing/head/justice
|
||||
name = "justice hat"
|
||||
desc = "Fight for what's righteous!"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Ushanka
|
||||
* Pumpkin head
|
||||
* Kitty ears
|
||||
*
|
||||
* Cardborg Disguise
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -207,4 +207,24 @@
|
||||
var/icon/earbit = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "mouseyinner")
|
||||
mob.Blend(earbit, ICON_OVERLAY)
|
||||
|
||||
icon_override = mob
|
||||
icon_override = mob
|
||||
|
||||
/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 = HEADCOVERSEYES | HEADCOVERSMOUTH
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
|
||||
|
||||
/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")
|
||||
|
||||
@@ -199,6 +199,26 @@
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO
|
||||
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-robot") //gotta look realistic
|
||||
H.add_alt_appearance("standard_borg_disguise", I, silicon_mob_list+H) //you look like a robot to robots! (including yourself because you're totally a robot)
|
||||
|
||||
|
||||
/obj/item/clothing/suit/poncho
|
||||
name = "poncho"
|
||||
desc = "Your classic, non-racist poncho."
|
||||
|
||||
@@ -70,6 +70,12 @@
|
||||
//readd this mob's HUDs (antag, med, etc)
|
||||
reload_huds()
|
||||
|
||||
if(viewing_alternate_appearances && viewing_alternate_appearances.len)
|
||||
for(var/aakey in viewing_alternate_appearances)
|
||||
var/datum/alternate_appearance/AA = viewing_alternate_appearances[aakey]
|
||||
if(AA)
|
||||
AA.display_to(list(src))
|
||||
|
||||
CallHook("Login", list("client" = src.client, "mob" = src))
|
||||
|
||||
// Calling update_interface() in /mob/Login() causes the Cyborg to immediately be ghosted; because of winget().
|
||||
|
||||
@@ -306,6 +306,7 @@
|
||||
#include "code\defines\procs\radio.dm"
|
||||
#include "code\defines\procs\records.dm"
|
||||
#include "code\defines\procs\statistics.dm"
|
||||
#include "code\game\alternate_appearance.dm"
|
||||
#include "code\game\asteroid.dm"
|
||||
#include "code\game\atoms.dm"
|
||||
#include "code\game\atoms_movable.dm"
|
||||
|
||||
Reference in New Issue
Block a user