mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Merge pull request #8387 from PsiOmegaDelta/ChangeAppearance
Mirror and ERT appearance improvement.
This commit is contained in:
@@ -1096,6 +1096,7 @@
|
||||
#include "code\modules\mob\living\carbon\brain\posibrain.dm"
|
||||
#include "code\modules\mob\living\carbon\brain\robot.dm"
|
||||
#include "code\modules\mob\living\carbon\brain\say.dm"
|
||||
#include "code\modules\mob\living\carbon\human\appearance.dm"
|
||||
#include "code\modules\mob\living\carbon\human\death.dm"
|
||||
#include "code\modules\mob\living\carbon\human\emote.dm"
|
||||
#include "code\modules\mob\living\carbon\human\examine.dm"
|
||||
@@ -1257,6 +1258,7 @@
|
||||
#include "code\modules\nano\nanoui.dm"
|
||||
#include "code\modules\nano\modules\alarm_monitor.dm"
|
||||
#include "code\modules\nano\modules\crew_monitor.dm"
|
||||
#include "code\modules\nano\modules\human_appearance.dm"
|
||||
#include "code\modules\nano\modules\power_monitor.dm"
|
||||
#include "code\modules\nano\modules\rcon.dm"
|
||||
#include "code\modules\organs\blood.dm"
|
||||
|
||||
@@ -184,6 +184,8 @@
|
||||
|
||||
var/starlight = 0 // Whether space turfs have ambient light or not
|
||||
|
||||
var/list/ert_species = list("Human")
|
||||
|
||||
/datum/configuration/New()
|
||||
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
|
||||
for (var/T in L)
|
||||
@@ -609,6 +611,10 @@
|
||||
value = text2num(value)
|
||||
config.starlight = value >= 0 ? value : 0
|
||||
|
||||
if("ert_species")
|
||||
config.ert_species = text2list(value, ";")
|
||||
if(!config.ert_species.len)
|
||||
config.ert_species += "Human"
|
||||
else
|
||||
log_misc("Unknown setting in configuration: '[name]'")
|
||||
|
||||
|
||||
@@ -7,59 +7,19 @@
|
||||
density = 0
|
||||
anchored = 1
|
||||
var/shattered = 0
|
||||
var/list/ui_users = list()
|
||||
|
||||
/obj/structure/mirror/attack_hand(mob/user as mob)
|
||||
|
||||
if(shattered) return
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
if(H.a_intent == "hurt")
|
||||
if(prob(30) || H.species.can_shred(H))
|
||||
attack_generic(user,1)
|
||||
else
|
||||
attack_generic(user)
|
||||
return
|
||||
|
||||
var/userloc = H.loc
|
||||
|
||||
//see code/modules/mob/new_player/preferences.dm at approx line 545 for comments!
|
||||
//this is largely copypasted from there.
|
||||
|
||||
//handle facial hair (if necessary)
|
||||
if(H.gender == MALE)
|
||||
var/list/species_facial_hair = list()
|
||||
if(H.species)
|
||||
for(var/i in facial_hair_styles_list)
|
||||
var/datum/sprite_accessory/facial_hair/tmp_facial = facial_hair_styles_list[i]
|
||||
if(H.species.name in tmp_facial.species_allowed)
|
||||
species_facial_hair += i
|
||||
else
|
||||
species_facial_hair = facial_hair_styles_list
|
||||
|
||||
var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in species_facial_hair
|
||||
if(userloc != H.loc) return //no tele-grooming
|
||||
if(new_style)
|
||||
H.f_style = new_style
|
||||
|
||||
//handle normal hair
|
||||
var/list/species_hair = list()
|
||||
if(H.species)
|
||||
for(var/i in hair_styles_list)
|
||||
var/datum/sprite_accessory/hair/tmp_hair = hair_styles_list[i]
|
||||
if(H.species.name in tmp_hair.species_allowed)
|
||||
species_hair += i
|
||||
else
|
||||
species_hair = hair_styles_list
|
||||
|
||||
var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in species_hair
|
||||
if(userloc != H.loc) return //no tele-grooming
|
||||
if(new_style)
|
||||
H.h_style = new_style
|
||||
|
||||
H.update_hair()
|
||||
|
||||
var/obj/nano_module/appearance_changer/AC = ui_users[user]
|
||||
if(!AC)
|
||||
AC = new(src, user)
|
||||
AC.name = "SalonPro Nano-Mirror(TM)"
|
||||
ui_users[user] = AC
|
||||
AC.ui_interact(user)
|
||||
|
||||
/obj/structure/mirror/proc/shatter()
|
||||
if(shattered) return
|
||||
|
||||
@@ -1,331 +1,245 @@
|
||||
//STRIKE TEAMS
|
||||
//Thanks to Kilakk for the admin-button portion of this code.
|
||||
|
||||
var/list/response_team_members = list()
|
||||
var/global/send_emergency_team = 0 // Used for automagic response teams
|
||||
// 'admin_emergency_team' for admin-spawned response teams
|
||||
var/ert_base_chance = 10 // Default base chance. Will be incremented by increment ERT chance.
|
||||
var/can_call_ert
|
||||
|
||||
/client/proc/response_team()
|
||||
set name = "Dispatch Emergency Response Team"
|
||||
set category = "Special Verbs"
|
||||
set desc = "Send an emergency response team to the station"
|
||||
|
||||
if(!holder)
|
||||
usr << "\red Only administrators may use this command."
|
||||
return
|
||||
if(!ticker)
|
||||
usr << "\red The game hasn't started yet!"
|
||||
return
|
||||
if(ticker.current_state == 1)
|
||||
usr << "\red The round hasn't started yet!"
|
||||
return
|
||||
if(send_emergency_team)
|
||||
usr << "\red Central Command has already dispatched an emergency response team!"
|
||||
return
|
||||
if(alert("Do you want to dispatch an Emergency Response Team?",,"Yes","No") != "Yes")
|
||||
return
|
||||
if(get_security_level() != "red") // Allow admins to reconsider if the alert level isn't Red
|
||||
switch(alert("The station is not in red alert. Do you still want to dispatch a response team?",,"Yes","No"))
|
||||
if("No")
|
||||
return
|
||||
if(send_emergency_team)
|
||||
usr << "\red Looks like somebody beat you to it!"
|
||||
return
|
||||
|
||||
message_admins("[key_name_admin(usr)] is dispatching an Emergency Response Team.", 1)
|
||||
log_admin("[key_name(usr)] used Dispatch Response Team.")
|
||||
trigger_armed_response_team(1)
|
||||
|
||||
|
||||
client/verb/JoinResponseTeam()
|
||||
set category = "IC"
|
||||
|
||||
if(istype(usr,/mob/dead/observer) || istype(usr,/mob/new_player))
|
||||
if(!send_emergency_team)
|
||||
usr << "No emergency response team is currently being sent."
|
||||
return
|
||||
/* if(admin_emergency_team)
|
||||
usr << "An emergency response team has already been sent."
|
||||
return */
|
||||
if(jobban_isbanned(usr, "Syndicate") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer"))
|
||||
usr << "<font color=red><b>You are jobbanned from the emergency reponse team!"
|
||||
return
|
||||
|
||||
if(response_team_members.len > 5) usr << "The emergency response team is already full!"
|
||||
|
||||
|
||||
for (var/obj/effect/landmark/L in landmarks_list) if (L.name == "Commando")
|
||||
L.name = null//Reserving the place.
|
||||
var/new_name = input(usr, "Pick a name","Name") as null|text
|
||||
if(!new_name)//Somebody changed his mind, place is available again.
|
||||
L.name = "Commando"
|
||||
return
|
||||
var/leader_selected = isemptylist(response_team_members)
|
||||
var/mob/living/carbon/human/new_commando = create_response_team(L.loc, leader_selected, new_name)
|
||||
del(L)
|
||||
new_commando.mind.key = usr.key
|
||||
new_commando.key = usr.key
|
||||
|
||||
new_commando << "\blue You are [!leader_selected?"a member":"the <B>LEADER</B>"] of an Emergency Response Team, a type of military division, under CentComm's service. There is a code red alert on [station_name()], you are tasked to go and fix the problem."
|
||||
new_commando << "<b>You should first gear up and discuss a plan with your team. More members may be joining, don't move out before you're ready."
|
||||
if(!leader_selected)
|
||||
new_commando << "<b>As member of the Emergency Response Team, you answer only to your leader and CentComm officials.</b>"
|
||||
else
|
||||
new_commando << "<b>As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however."
|
||||
return
|
||||
|
||||
else
|
||||
usr << "You need to be an observer or new player to use this."
|
||||
|
||||
// returns a number of dead players in %
|
||||
proc/percentage_dead()
|
||||
var/total = 0
|
||||
var/deadcount = 0
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
if(H.client) // Monkeys and mice don't have a client, amirite?
|
||||
if(H.stat == 2) deadcount++
|
||||
total++
|
||||
|
||||
if(total == 0) return 0
|
||||
else return round(100 * deadcount / total)
|
||||
|
||||
// counts the number of antagonists in %
|
||||
proc/percentage_antagonists()
|
||||
var/total = 0
|
||||
var/antagonists = 0
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
if(is_special_character(H) >= 1)
|
||||
antagonists++
|
||||
total++
|
||||
|
||||
if(total == 0) return 0
|
||||
else return round(100 * antagonists / total)
|
||||
|
||||
// Increments the ERT chance automatically, so that the later it is in the round,
|
||||
// the more likely an ERT is to be able to be called.
|
||||
proc/increment_ert_chance()
|
||||
while(send_emergency_team == 0) // There is no ERT at the time.
|
||||
if(get_security_level() == "green")
|
||||
ert_base_chance += 1
|
||||
if(get_security_level() == "blue")
|
||||
ert_base_chance += 2
|
||||
if(get_security_level() == "red")
|
||||
ert_base_chance += 3
|
||||
if(get_security_level() == "delta")
|
||||
ert_base_chance += 10 // Need those big guns
|
||||
sleep(600 * 3) // Minute * Number of Minutes
|
||||
|
||||
|
||||
proc/trigger_armed_response_team(var/force = 0)
|
||||
if(!can_call_ert && !force)
|
||||
return
|
||||
if(send_emergency_team)
|
||||
return
|
||||
|
||||
var/send_team_chance = ert_base_chance // Is incremented by increment_ert_chance.
|
||||
send_team_chance += 2*percentage_dead() // the more people are dead, the higher the chance
|
||||
send_team_chance += percentage_antagonists() // the more antagonists, the higher the chance
|
||||
send_team_chance = min(send_team_chance, 100)
|
||||
|
||||
if(force) send_team_chance = 100
|
||||
|
||||
// there's only a certain chance a team will be sent
|
||||
if(!prob(send_team_chance))
|
||||
command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. Unfortunately, we were unable to send one at this time.", "Central Command")
|
||||
can_call_ert = 0 // Only one call per round, ladies.
|
||||
return
|
||||
|
||||
command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. We will prepare and send one as soon as possible.", "Central Command")
|
||||
|
||||
can_call_ert = 0 // Only one call per round, gentleman.
|
||||
send_emergency_team = 1
|
||||
|
||||
sleep(600 * 5)
|
||||
send_emergency_team = 0 // Can no longer join the ERT.
|
||||
|
||||
/* var/area/security/nuke_storage/nukeloc = locate()//To find the nuke in the vault
|
||||
var/obj/machinery/nuclearbomb/nuke = locate() in nukeloc
|
||||
if(!nuke)
|
||||
nuke = locate() in world
|
||||
var/obj/item/weapon/paper/P = new
|
||||
P.info = "Your orders, Commander, are to use all means necessary to return the station to a survivable condition.<br>To this end, you have been provided with the best tools we can give in the three areas of Medicine, Engineering, and Security. The nuclear authorization code is: <b>[ nuke ? nuke.r_code : "AHH, THE NUKE IS GONE!"]</b>. Be warned, if you detonate this without good reason, we will hold you to account for damages. Memorise this code, and then burn this message."
|
||||
P.name = "Emergency Nuclear Code, and ERT Orders"
|
||||
for (var/obj/effect/landmark/A in world)
|
||||
if (A.name == "nukecode")
|
||||
P.loc = A.loc
|
||||
del(A)
|
||||
continue
|
||||
*/
|
||||
|
||||
/client/proc/create_response_team(obj/spawn_location, leader_selected = 0, commando_name)
|
||||
|
||||
//usr << "\red ERT has been temporarily disabled. Talk to a coder."
|
||||
//return
|
||||
|
||||
var/mob/living/carbon/human/M = new(null)
|
||||
response_team_members |= M
|
||||
|
||||
//todo: god damn this.
|
||||
//make it a panel, like in character creation
|
||||
var/new_facial = input("Please select facial hair color.", "Character Generation") as color
|
||||
if(new_facial)
|
||||
M.r_facial = hex2num(copytext(new_facial, 2, 4))
|
||||
M.g_facial = hex2num(copytext(new_facial, 4, 6))
|
||||
M.b_facial = hex2num(copytext(new_facial, 6, 8))
|
||||
|
||||
var/new_hair = input("Please select hair color.", "Character Generation") as color
|
||||
if(new_facial)
|
||||
M.r_hair = hex2num(copytext(new_hair, 2, 4))
|
||||
M.g_hair = hex2num(copytext(new_hair, 4, 6))
|
||||
M.b_hair = hex2num(copytext(new_hair, 6, 8))
|
||||
|
||||
var/new_eyes = input("Please select eye color.", "Character Generation") as color
|
||||
if(new_eyes)
|
||||
M.r_eyes = hex2num(copytext(new_eyes, 2, 4))
|
||||
M.g_eyes = hex2num(copytext(new_eyes, 4, 6))
|
||||
M.b_eyes = hex2num(copytext(new_eyes, 6, 8))
|
||||
|
||||
var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation") as text
|
||||
|
||||
if (!new_tone)
|
||||
new_tone = 35
|
||||
M.s_tone = max(min(round(text2num(new_tone)), 220), 1)
|
||||
M.s_tone = -M.s_tone + 35
|
||||
|
||||
// hair
|
||||
var/list/all_hairs = typesof(/datum/sprite_accessory/hair) - /datum/sprite_accessory/hair
|
||||
var/list/hairs = list()
|
||||
|
||||
// loop through potential hairs
|
||||
for(var/x in all_hairs)
|
||||
var/datum/sprite_accessory/hair/H = new x // create new hair datum based on type x
|
||||
hairs.Add(H.name) // add hair name to hairs
|
||||
del(H) // delete the hair after it's all done
|
||||
|
||||
// var/new_style = input("Please select hair style", "Character Generation") as null|anything in hairs
|
||||
//hair
|
||||
var/new_hstyle = input(usr, "Select a hair style", "Grooming") as null|anything in hair_styles_list
|
||||
if(new_hstyle)
|
||||
M.h_style = new_hstyle
|
||||
|
||||
// facial hair
|
||||
var/new_fstyle = input(usr, "Select a facial hair style", "Grooming") as null|anything in facial_hair_styles_list
|
||||
if(new_fstyle)
|
||||
M.f_style = new_fstyle
|
||||
|
||||
// if new style selected (not cancel)
|
||||
/* if (new_style)
|
||||
M.h_style = new_style
|
||||
|
||||
for(var/x in all_hairs) // loop through all_hairs again. Might be slightly CPU expensive, but not significantly.
|
||||
var/datum/sprite_accessory/hair/H = new x // create new hair datum
|
||||
if(H.name == new_style)
|
||||
M.h_style = H // assign the hair_style variable a new hair datum
|
||||
break
|
||||
else
|
||||
del(H) // if hair H not used, delete. BYOND can garbage collect, but better safe than sorry
|
||||
|
||||
// facial hair
|
||||
var/list/all_fhairs = typesof(/datum/sprite_accessory/facial_hair) - /datum/sprite_accessory/facial_hair
|
||||
var/list/fhairs = list()
|
||||
|
||||
for(var/x in all_fhairs)
|
||||
var/datum/sprite_accessory/facial_hair/H = new x
|
||||
fhairs.Add(H.name)
|
||||
del(H)
|
||||
|
||||
new_style = input("Please select facial style", "Character Generation") as null|anything in fhairs
|
||||
|
||||
if(new_style)
|
||||
M.f_style = new_style
|
||||
for(var/x in all_fhairs)
|
||||
var/datum/sprite_accessory/facial_hair/H = new x
|
||||
if(H.name == new_style)
|
||||
M.f_style = H
|
||||
break
|
||||
else
|
||||
del(H)
|
||||
*/
|
||||
var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female")
|
||||
if (new_gender)
|
||||
if(new_gender == "Male")
|
||||
M.gender = MALE
|
||||
else
|
||||
M.gender = FEMALE
|
||||
//M.rebuild_appearance()
|
||||
M.update_hair()
|
||||
M.update_body()
|
||||
M.check_dna(M)
|
||||
|
||||
M.real_name = commando_name
|
||||
M.name = commando_name
|
||||
M.age = !leader_selected ? rand(23,35) : rand(35,45)
|
||||
|
||||
M.dna.ready_dna(M)//Creates DNA.
|
||||
|
||||
//Creates mind stuff.
|
||||
M.mind = new
|
||||
M.mind.current = M
|
||||
M.mind.original = M
|
||||
M.mind.assigned_role = "MODE"
|
||||
M.mind.special_role = "Response Team"
|
||||
if(!(M.mind in ticker.minds))
|
||||
ticker.minds += M.mind//Adds them to regular mind list.
|
||||
M.loc = spawn_location
|
||||
M.equip_strike_team(leader_selected)
|
||||
return M
|
||||
|
||||
/mob/living/carbon/human/proc/equip_strike_team(leader_selected = 0)
|
||||
|
||||
//Special radio setup
|
||||
equip_to_slot_or_del(new /obj/item/device/radio/headset/ert(src), slot_l_ear)
|
||||
|
||||
//Replaced with new ERT uniform
|
||||
equip_to_slot_or_del(new /obj/item/clothing/under/ert(src), slot_w_uniform)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(src), slot_glasses)
|
||||
/*
|
||||
|
||||
//Old ERT Uniform
|
||||
//Basic Uniform
|
||||
equip_to_slot_or_del(new /obj/item/clothing/under/syndicate/tacticool(src), slot_w_uniform)
|
||||
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_l_store)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/clipboard(src), slot_r_store)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(src), slot_belt)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat(src), slot_wear_mask)
|
||||
|
||||
//Glasses
|
||||
equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/sechud(src), slot_glasses)
|
||||
|
||||
//Shoes & gloves
|
||||
equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves)
|
||||
|
||||
//Removed
|
||||
// equip_to_slot_or_del(new /obj/item/clothing/suit/armor/swat(src), slot_wear_suit)
|
||||
// equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad(src), slot_head)
|
||||
|
||||
//Backpack
|
||||
equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(src), slot_back)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(src), slot_in_backpack)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(src), slot_in_backpack)
|
||||
*/
|
||||
var/obj/item/weapon/card/id/W = new(src)
|
||||
W.assignment = "Emergency Response Team[leader_selected ? " Leader" : ""]"
|
||||
W.registered_name = real_name
|
||||
W.name = "[real_name]'s ID Card ([W.assignment])"
|
||||
W.icon_state = "centcom"
|
||||
W.access = get_all_accesses()
|
||||
W.access += get_all_centcom_access()
|
||||
equip_to_slot_or_del(W, slot_wear_id)
|
||||
|
||||
return 1
|
||||
|
||||
//debug verb (That is horribly coded, LEAVE THIS OFF UNLESS PRIVATELY TESTING. Seriously.
|
||||
/*client/verb/ResponseTeam()
|
||||
set category = "Admin"
|
||||
if(!send_emergency_team)
|
||||
send_emergency_team = 1*/
|
||||
//STRIKE TEAMS
|
||||
//Thanks to Kilakk for the admin-button portion of this code.
|
||||
|
||||
var/list/response_team_members = list()
|
||||
var/global/send_emergency_team = 0 // Used for automagic response teams
|
||||
// 'admin_emergency_team' for admin-spawned response teams
|
||||
var/ert_base_chance = 10 // Default base chance. Will be incremented by increment ERT chance.
|
||||
var/can_call_ert
|
||||
|
||||
/client/proc/response_team()
|
||||
set name = "Dispatch Emergency Response Team"
|
||||
set category = "Special Verbs"
|
||||
set desc = "Send an emergency response team to the station"
|
||||
|
||||
if(!holder)
|
||||
usr << "\red Only administrators may use this command."
|
||||
return
|
||||
if(!ticker)
|
||||
usr << "\red The game hasn't started yet!"
|
||||
return
|
||||
if(ticker.current_state == 1)
|
||||
usr << "\red The round hasn't started yet!"
|
||||
return
|
||||
if(send_emergency_team)
|
||||
usr << "\red Central Command has already dispatched an emergency response team!"
|
||||
return
|
||||
if(alert("Do you want to dispatch an Emergency Response Team?",,"Yes","No") != "Yes")
|
||||
return
|
||||
if(get_security_level() != "red") // Allow admins to reconsider if the alert level isn't Red
|
||||
switch(alert("The station is not in red alert. Do you still want to dispatch a response team?",,"Yes","No"))
|
||||
if("No")
|
||||
return
|
||||
if(send_emergency_team)
|
||||
usr << "\red Looks like somebody beat you to it!"
|
||||
return
|
||||
|
||||
message_admins("[key_name_admin(usr)] is dispatching an Emergency Response Team.", 1)
|
||||
log_admin("[key_name(usr)] used Dispatch Response Team.")
|
||||
trigger_armed_response_team(1)
|
||||
|
||||
|
||||
client/verb/JoinResponseTeam()
|
||||
set category = "IC"
|
||||
|
||||
if(istype(usr,/mob/dead/observer) || istype(usr,/mob/new_player))
|
||||
if(!send_emergency_team)
|
||||
usr << "No emergency response team is currently being sent."
|
||||
return
|
||||
/* if(admin_emergency_team)
|
||||
usr << "An emergency response team has already been sent."
|
||||
return */
|
||||
if(jobban_isbanned(usr, "Syndicate") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer"))
|
||||
usr << "<font color=red><b>You are jobbanned from the emergency reponse team!"
|
||||
return
|
||||
|
||||
if(response_team_members.len > 5) usr << "The emergency response team is already full!"
|
||||
|
||||
|
||||
for (var/obj/effect/landmark/L in landmarks_list) if (L.name == "Commando")
|
||||
L.name = null//Reserving the place.
|
||||
var/new_name = input(usr, "Pick a name","Name") as null|text
|
||||
if(!new_name)//Somebody changed his mind, place is available again.
|
||||
L.name = "Commando"
|
||||
return
|
||||
var/leader_selected = isemptylist(response_team_members)
|
||||
var/mob/living/carbon/human/new_commando = create_response_team(L.loc, leader_selected, new_name)
|
||||
del(L)
|
||||
//Creates mind stuff.
|
||||
new_commando.mind.key = usr.key
|
||||
new_commando.key = usr.key
|
||||
|
||||
new_commando << "\blue You are [!leader_selected?"a member":"the <B>LEADER</B>"] of an Emergency Response Team, a type of military division, under CentComm's service. There is a code red alert on [station_name()], you are tasked to go and fix the problem."
|
||||
new_commando << "<b>You should first gear up and discuss a plan with your team. More members may be joining, don't move out before you're ready."
|
||||
if(!leader_selected)
|
||||
new_commando << "<b>As member of the Emergency Response Team, you answer only to your leader and CentComm officials.</b>"
|
||||
else
|
||||
new_commando << "<b>As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however."
|
||||
|
||||
// By setting an explicit location the mob cannot wander off and decide change appearance elsewhere
|
||||
new_commando.change_appearance(APPEARANCE_ALL, new_commando.loc, new_commando, species_whitelist = config.ert_species)
|
||||
|
||||
return
|
||||
|
||||
else
|
||||
usr << "You need to be an observer or new player to use this."
|
||||
|
||||
// returns a number of dead players in %
|
||||
proc/percentage_dead()
|
||||
var/total = 0
|
||||
var/deadcount = 0
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
if(H.client) // Monkeys and mice don't have a client, amirite?
|
||||
if(H.stat == 2) deadcount++
|
||||
total++
|
||||
|
||||
if(total == 0) return 0
|
||||
else return round(100 * deadcount / total)
|
||||
|
||||
// counts the number of antagonists in %
|
||||
proc/percentage_antagonists()
|
||||
var/total = 0
|
||||
var/antagonists = 0
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
if(is_special_character(H) >= 1)
|
||||
antagonists++
|
||||
total++
|
||||
|
||||
if(total == 0) return 0
|
||||
else return round(100 * antagonists / total)
|
||||
|
||||
// Increments the ERT chance automatically, so that the later it is in the round,
|
||||
// the more likely an ERT is to be able to be called.
|
||||
proc/increment_ert_chance()
|
||||
while(send_emergency_team == 0) // There is no ERT at the time.
|
||||
if(get_security_level() == "green")
|
||||
ert_base_chance += 1
|
||||
if(get_security_level() == "blue")
|
||||
ert_base_chance += 2
|
||||
if(get_security_level() == "red")
|
||||
ert_base_chance += 3
|
||||
if(get_security_level() == "delta")
|
||||
ert_base_chance += 10 // Need those big guns
|
||||
sleep(600 * 3) // Minute * Number of Minutes
|
||||
|
||||
|
||||
proc/trigger_armed_response_team(var/force = 0)
|
||||
if(!can_call_ert && !force)
|
||||
return
|
||||
if(send_emergency_team)
|
||||
return
|
||||
|
||||
var/send_team_chance = ert_base_chance // Is incremented by increment_ert_chance.
|
||||
send_team_chance += 2*percentage_dead() // the more people are dead, the higher the chance
|
||||
send_team_chance += percentage_antagonists() // the more antagonists, the higher the chance
|
||||
send_team_chance = min(send_team_chance, 100)
|
||||
|
||||
if(force) send_team_chance = 100
|
||||
|
||||
// there's only a certain chance a team will be sent
|
||||
if(!prob(send_team_chance))
|
||||
command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. Unfortunately, we were unable to send one at this time.", "Central Command")
|
||||
can_call_ert = 0 // Only one call per round, ladies.
|
||||
return
|
||||
|
||||
command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. We will prepare and send one as soon as possible.", "Central Command")
|
||||
|
||||
can_call_ert = 0 // Only one call per round, gentleman.
|
||||
send_emergency_team = 1
|
||||
|
||||
sleep(600 * 5)
|
||||
send_emergency_team = 0 // Can no longer join the ERT.
|
||||
|
||||
/* var/area/security/nuke_storage/nukeloc = locate()//To find the nuke in the vault
|
||||
var/obj/machinery/nuclearbomb/nuke = locate() in nukeloc
|
||||
if(!nuke)
|
||||
nuke = locate() in world
|
||||
var/obj/item/weapon/paper/P = new
|
||||
P.info = "Your orders, Commander, are to use all means necessary to return the station to a survivable condition.<br>To this end, you have been provided with the best tools we can give in the three areas of Medicine, Engineering, and Security. The nuclear authorization code is: <b>[ nuke ? nuke.r_code : "AHH, THE NUKE IS GONE!"]</b>. Be warned, if you detonate this without good reason, we will hold you to account for damages. Memorise this code, and then burn this message."
|
||||
P.name = "Emergency Nuclear Code, and ERT Orders"
|
||||
for (var/obj/effect/landmark/A in world)
|
||||
if (A.name == "nukecode")
|
||||
P.loc = A.loc
|
||||
del(A)
|
||||
continue
|
||||
*/
|
||||
|
||||
/client/proc/create_response_team(obj/spawn_location, leader_selected = 0, commando_name)
|
||||
|
||||
//usr << "\red ERT has been temporarily disabled. Talk to a coder."
|
||||
//return
|
||||
|
||||
var/mob/living/carbon/human/M = new(null)
|
||||
response_team_members |= M
|
||||
|
||||
M.real_name = commando_name
|
||||
M.name = commando_name
|
||||
M.age = !leader_selected ? rand(23,35) : rand(35,45)
|
||||
|
||||
M.check_dna(M)
|
||||
M.dna.ready_dna(M)//Creates DNA.
|
||||
|
||||
M.mind = new
|
||||
M.mind.current = M
|
||||
M.mind.original = M
|
||||
M.mind.assigned_role = "MODE"
|
||||
M.mind.special_role = "Response Team"
|
||||
if(!(M.mind in ticker.minds))
|
||||
ticker.minds += M.mind//Adds them to regular mind list.
|
||||
M.loc = spawn_location
|
||||
M.equip_strike_team(leader_selected)
|
||||
|
||||
return M
|
||||
|
||||
/mob/living/carbon/human/proc/equip_strike_team(leader_selected = 0)
|
||||
|
||||
//Special radio setup
|
||||
equip_to_slot_or_del(new /obj/item/device/radio/headset/ert(src), slot_l_ear)
|
||||
|
||||
//Replaced with new ERT uniform
|
||||
equip_to_slot_or_del(new /obj/item/clothing/under/ert(src), slot_w_uniform)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(src), slot_glasses)
|
||||
/*
|
||||
|
||||
//Old ERT Uniform
|
||||
//Basic Uniform
|
||||
equip_to_slot_or_del(new /obj/item/clothing/under/syndicate/tacticool(src), slot_w_uniform)
|
||||
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_l_store)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/clipboard(src), slot_r_store)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(src), slot_belt)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat(src), slot_wear_mask)
|
||||
|
||||
//Glasses
|
||||
equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/sechud(src), slot_glasses)
|
||||
|
||||
//Shoes & gloves
|
||||
equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves)
|
||||
|
||||
//Removed
|
||||
// equip_to_slot_or_del(new /obj/item/clothing/suit/armor/swat(src), slot_wear_suit)
|
||||
// equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad(src), slot_head)
|
||||
|
||||
//Backpack
|
||||
equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(src), slot_back)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(src), slot_in_backpack)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(src), slot_in_backpack)
|
||||
*/
|
||||
var/obj/item/weapon/card/id/W = new(src)
|
||||
W.assignment = "Emergency Response Team[leader_selected ? " Leader" : ""]"
|
||||
W.registered_name = real_name
|
||||
W.name = "[real_name]'s ID Card ([W.assignment])"
|
||||
W.icon_state = "centcom"
|
||||
W.access = get_all_accesses()
|
||||
W.access += get_all_centcom_access()
|
||||
equip_to_slot_or_del(W, slot_wear_id)
|
||||
|
||||
return 1
|
||||
|
||||
//debug verb (That is horribly coded, LEAVE THIS OFF UNLESS PRIVATELY TESTING. Seriously.
|
||||
/*client/verb/ResponseTeam()
|
||||
set category = "Admin"
|
||||
if(!send_emergency_team)
|
||||
send_emergency_team = 1*/
|
||||
|
||||
@@ -79,7 +79,9 @@ var/list/admin_verbs_admin = list(
|
||||
/client/proc/toggle_antagHUD_restrictions,
|
||||
/client/proc/allow_character_respawn, /* Allows a ghost to respawn */
|
||||
/client/proc/event_manager_panel,
|
||||
/client/proc/empty_ai_core_toggle_latejoin
|
||||
/client/proc/empty_ai_core_toggle_latejoin,
|
||||
/client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */
|
||||
/client/proc/change_human_appearance_self /* Allows the human-based mob itself change its basic appearance */
|
||||
)
|
||||
var/list/admin_verbs_ban = list(
|
||||
/client/proc/unban_panel,
|
||||
@@ -715,6 +717,9 @@ var/list/admin_verbs_mentor = list(
|
||||
set name = "Rename Silicon"
|
||||
set category = "Admin"
|
||||
|
||||
if(!istype(S))
|
||||
return
|
||||
|
||||
if(holder)
|
||||
var/new_name = trim_strip_input(src, "Enter new name. Leave blank or as is to cancel.", "Enter new silicon name", S.real_name)
|
||||
if(new_name && new_name != S.real_name)
|
||||
@@ -722,6 +727,41 @@ var/list/admin_verbs_mentor = list(
|
||||
S.SetName(new_name)
|
||||
feedback_add_details("admin_verb","RAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/change_human_appearance_admin(mob/living/carbon/human/H in world)
|
||||
set name = "Change Mob Appearance - Admin"
|
||||
set desc = "Allows you to change the mob appearance"
|
||||
set category = "Admin"
|
||||
|
||||
if(!istype(H))
|
||||
return
|
||||
|
||||
if(holder)
|
||||
admin_log_and_message_admins("is altering the appearance of [H].")
|
||||
H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0)
|
||||
feedback_add_details("admin_verb","CHAA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/change_human_appearance_self(mob/living/carbon/human/H in world)
|
||||
set name = "Change Mob Appearance - Self"
|
||||
set desc = "Allows the mob to change its appearance"
|
||||
set category = "Admin"
|
||||
|
||||
if(!istype(H))
|
||||
return
|
||||
|
||||
if(!H.client)
|
||||
usr << "Only mobs with clients can alter their own appearance."
|
||||
return
|
||||
|
||||
if(holder)
|
||||
switch(alert("Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel"))
|
||||
if("Yes")
|
||||
admin_log_and_message_admins("has allowed [H] to change \his appearance, without whitelisting of races.")
|
||||
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0)
|
||||
if("No")
|
||||
admin_log_and_message_admins("has allowed [H] to change \his appearance, with whitelisting of races.")
|
||||
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
|
||||
feedback_add_details("admin_verb","CMAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
//---- bs12 verbs ----
|
||||
|
||||
|
||||
187
code/modules/mob/living/carbon/human/appearance.dm
Normal file
187
code/modules/mob/living/carbon/human/appearance.dm
Normal file
@@ -0,0 +1,187 @@
|
||||
/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list())
|
||||
var/obj/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist)
|
||||
AC.flags = flags
|
||||
AC.ui_interact(user)
|
||||
|
||||
/mob/living/carbon/human/proc/change_species(var/new_species)
|
||||
if(!new_species)
|
||||
return
|
||||
|
||||
if(species == new_species)
|
||||
return
|
||||
|
||||
if(!(new_species in all_species))
|
||||
return
|
||||
|
||||
set_species(new_species)
|
||||
reset_hair()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/change_gender(var/gender)
|
||||
if(src.gender == gender)
|
||||
return
|
||||
|
||||
src.gender = gender
|
||||
reset_hair()
|
||||
update_body()
|
||||
update_dna()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/change_hair(var/hair_style)
|
||||
if(!hair_style)
|
||||
return
|
||||
|
||||
if(h_style == hair_style)
|
||||
return
|
||||
|
||||
if(!(hair_style in hair_styles_list))
|
||||
return
|
||||
|
||||
h_style = hair_style
|
||||
|
||||
update_hair()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/change_facial_hair(var/facial_hair_style)
|
||||
if(!facial_hair_style)
|
||||
return
|
||||
|
||||
if(f_style == facial_hair_style)
|
||||
return
|
||||
|
||||
if(!(facial_hair_style in facial_hair_styles_list))
|
||||
return
|
||||
|
||||
f_style = facial_hair_style
|
||||
|
||||
update_hair()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/reset_hair()
|
||||
var/list/valid_hairstyles = generate_valid_hairstyles()
|
||||
var/list/valid_facial_hairstyles = generate_valid_facial_hairstyles()
|
||||
|
||||
if(valid_hairstyles.len)
|
||||
h_style = pick(valid_hairstyles)
|
||||
else
|
||||
//this shouldn't happen
|
||||
h_style = "Bald"
|
||||
|
||||
if(valid_facial_hairstyles.len)
|
||||
f_style = pick(valid_facial_hairstyles)
|
||||
else
|
||||
//this shouldn't happen
|
||||
f_style = "Shaved"
|
||||
|
||||
update_hair()
|
||||
|
||||
/mob/living/carbon/human/proc/change_eye_color(var/red, var/green, var/blue)
|
||||
if(red == r_eyes && green == g_eyes && blue == b_eyes)
|
||||
return
|
||||
|
||||
r_eyes = red
|
||||
g_eyes = green
|
||||
b_eyes = blue
|
||||
|
||||
update_body()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/change_hair_color(var/red, var/green, var/blue)
|
||||
if(red == r_eyes && green == g_eyes && blue == b_eyes)
|
||||
return
|
||||
|
||||
r_hair = red
|
||||
g_hair = green
|
||||
b_hair = blue
|
||||
|
||||
update_hair()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/change_facial_hair_color(var/red, var/green, var/blue)
|
||||
if(red == r_facial && green == g_facial && blue == b_facial)
|
||||
return
|
||||
|
||||
r_facial = red
|
||||
g_facial = green
|
||||
b_facial = blue
|
||||
|
||||
update_hair()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/change_skin_color(var/red, var/green, var/blue)
|
||||
if(red == r_skin && green == g_skin && blue == b_skin || !(species.flags & HAS_SKIN_COLOR))
|
||||
return
|
||||
|
||||
r_skin = red
|
||||
g_skin = green
|
||||
b_skin = blue
|
||||
|
||||
update_body()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/change_skin_tone(var/tone)
|
||||
if(s_tone == tone || !(species.flags & HAS_SKIN_TONE))
|
||||
return
|
||||
|
||||
s_tone = tone
|
||||
|
||||
update_body()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/update_dna()
|
||||
check_dna()
|
||||
dna.ready_dna(src)
|
||||
|
||||
/mob/living/carbon/human/proc/generate_valid_species(var/check_whitelist = 1, var/list/whitelist = list(), var/list/blacklist = list())
|
||||
var/list/valid_species = new()
|
||||
for(var/current_species_name in all_species)
|
||||
var/datum/species/current_species = all_species[current_species_name]
|
||||
|
||||
if(check_whitelist && config.usealienwhitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it!
|
||||
if(!(current_species.flags & CAN_JOIN))
|
||||
continue
|
||||
if(whitelist.len && !(current_species_name in whitelist))
|
||||
continue
|
||||
if(blacklist.len && (current_species_name in blacklist))
|
||||
continue
|
||||
if((current_species.flags & IS_WHITELISTED) && !is_alien_whitelisted(src, current_species_name))
|
||||
continue
|
||||
|
||||
valid_species += current_species_name
|
||||
|
||||
return valid_species
|
||||
|
||||
/mob/living/carbon/human/proc/generate_valid_hairstyles()
|
||||
var/list/valid_hairstyles = new()
|
||||
for(var/hairstyle in hair_styles_list)
|
||||
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
|
||||
|
||||
if(gender == MALE && S.gender == FEMALE)
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
if(!(species.name in S.species_allowed))
|
||||
continue
|
||||
valid_hairstyles += hairstyle
|
||||
|
||||
return valid_hairstyles
|
||||
|
||||
/mob/living/carbon/human/proc/generate_valid_facial_hairstyles()
|
||||
var/list/valid_facial_hairstyles = new()
|
||||
for(var/facialhairstyle in facial_hair_styles_list)
|
||||
var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
|
||||
|
||||
if(gender == MALE && S.gender == FEMALE)
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
if(!(species.name in S.species_allowed))
|
||||
continue
|
||||
|
||||
valid_facial_hairstyles += facialhairstyle
|
||||
|
||||
return valid_facial_hairstyles
|
||||
|
||||
/proc/q()
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.change_appearance(APPEARANCE_ALL)
|
||||
163
code/modules/nano/modules/human_appearance.dm
Normal file
163
code/modules/nano/modules/human_appearance.dm
Normal file
@@ -0,0 +1,163 @@
|
||||
/obj/nano_module/appearance_changer
|
||||
name = "Appearance Editor"
|
||||
flags = APPEARANCE_ALL_HAIR
|
||||
var/mob/living/carbon/human/owner = null
|
||||
var/list/valid_species = list()
|
||||
var/list/valid_hairstyles = list()
|
||||
var/list/valid_facial_hairstyles = list()
|
||||
|
||||
var/check_whitelist
|
||||
var/list/whitelist
|
||||
var/list/blacklist
|
||||
|
||||
/obj/nano_module/appearance_changer/New(var/location, var/mob/living/carbon/human/H, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list())
|
||||
..()
|
||||
loc = location
|
||||
owner = H
|
||||
src.check_whitelist = check_species_whitelist
|
||||
src.whitelist = species_whitelist
|
||||
src.blacklist = species_blacklist
|
||||
|
||||
/obj/nano_module/appearance_changer/Topic(ref, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["race"])
|
||||
if(can_change(APPEARANCE_RACE) && (href_list["race"] in valid_species))
|
||||
if(owner.change_species(href_list["race"]))
|
||||
cut_and_generate_data()
|
||||
return 1
|
||||
if(href_list["gender"])
|
||||
if(can_change(APPEARANCE_GENDER))
|
||||
if(owner.change_gender(href_list["gender"]))
|
||||
cut_and_generate_data()
|
||||
return 1
|
||||
if(href_list["skin_tone"])
|
||||
if(can_change_skin_tone())
|
||||
var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", owner.s_tone) as num|null
|
||||
if(isnum(new_s_tone) && CanUseTopic(usr) == STATUS_INTERACTIVE)
|
||||
new_s_tone = 35 - max(min( round(new_s_tone), 220),1)
|
||||
return owner.change_skin_tone(new_s_tone)
|
||||
if(href_list["skin_color"])
|
||||
if(can_change_skin_color())
|
||||
var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", rgb(owner.r_skin, owner.g_skin, owner.b_skin)) as color|null
|
||||
if(new_skin && can_still_topic())
|
||||
var/r_skin = hex2num(copytext(new_skin, 2, 4))
|
||||
var/g_skin = hex2num(copytext(new_skin, 4, 6))
|
||||
var/b_skin = hex2num(copytext(new_skin, 6, 8))
|
||||
if(owner.change_skin_color(r_skin, g_skin, b_skin))
|
||||
update_dna()
|
||||
return 1
|
||||
if(href_list["hair"])
|
||||
if(can_change(APPEARANCE_HAIR) && (href_list["hair"] in valid_hairstyles))
|
||||
if(owner.change_hair(href_list["hair"]))
|
||||
update_dna()
|
||||
return 1
|
||||
if(href_list["hair_color"])
|
||||
if(can_change(APPEARANCE_HAIR_COLOR))
|
||||
var/new_hair = input("Please select hair color.", "Hair Color", rgb(owner.r_hair, owner.g_hair, owner.b_hair)) as color|null
|
||||
if(new_hair && can_still_topic())
|
||||
var/r_hair = hex2num(copytext(new_hair, 2, 4))
|
||||
var/g_hair = hex2num(copytext(new_hair, 4, 6))
|
||||
var/b_hair = hex2num(copytext(new_hair, 6, 8))
|
||||
if(owner.change_hair_color(r_hair, g_hair, b_hair))
|
||||
update_dna()
|
||||
return 1
|
||||
if(href_list["facial_hair"])
|
||||
if(can_change(APPEARANCE_FACIAL_HAIR) && (href_list["facial_hair"] in valid_facial_hairstyles))
|
||||
if(owner.change_facial_hair(href_list["facial_hair"]))
|
||||
update_dna()
|
||||
return 1
|
||||
if(href_list["facial_hair_color"])
|
||||
if(can_change(APPEARANCE_FACIAL_HAIR_COLOR))
|
||||
var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(owner.r_facial, owner.g_facial, owner.b_facial)) as color|null
|
||||
if(new_facial && can_still_topic())
|
||||
var/r_facial = hex2num(copytext(new_facial, 2, 4))
|
||||
var/g_facial = hex2num(copytext(new_facial, 4, 6))
|
||||
var/b_facial = hex2num(copytext(new_facial, 6, 8))
|
||||
if(owner.change_facial_hair_color(r_facial, g_facial, b_facial))
|
||||
update_dna()
|
||||
return 1
|
||||
if(href_list["eye_color"])
|
||||
if(can_change(APPEARANCE_EYE_COLOR))
|
||||
var/new_eyes = input("Please select eye color.", "Eye Color", rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)) as color|null
|
||||
if(new_eyes && can_still_topic())
|
||||
var/r_eyes = hex2num(copytext(new_eyes, 2, 4))
|
||||
var/g_eyes = hex2num(copytext(new_eyes, 4, 6))
|
||||
var/b_eyes = hex2num(copytext(new_eyes, 6, 8))
|
||||
if(owner.change_eye_color(r_eyes, g_eyes, b_eyes))
|
||||
update_dna()
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/nano_module/appearance_changer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
generate_data(check_whitelist, whitelist, blacklist)
|
||||
var/data[0]
|
||||
|
||||
data["specimen"] = owner.species.name
|
||||
data["gender"] = owner.gender
|
||||
data["change_race"] = can_change(APPEARANCE_RACE)
|
||||
if(data["change_race"])
|
||||
var/species[0]
|
||||
for(var/specimen in valid_species)
|
||||
species[++species.len] = list("specimen" = specimen)
|
||||
data["species"] = species
|
||||
|
||||
data["change_gender"] = can_change(APPEARANCE_GENDER)
|
||||
data["change_skin_tone"] = can_change_skin_tone()
|
||||
data["change_skin_color"] = can_change_skin_color()
|
||||
data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR)
|
||||
data["change_hair"] = can_change(APPEARANCE_HAIR)
|
||||
if(data["change_hair"])
|
||||
var/hair_styles[0]
|
||||
for(var/hair_style in valid_hairstyles)
|
||||
hair_styles[++hair_styles.len] = list("hairstyle" = hair_style)
|
||||
data["hair_styles"] = hair_styles
|
||||
data["hair_style"] = owner.h_style
|
||||
|
||||
data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR)
|
||||
if(data["change_facial_hair"])
|
||||
var/facial_hair_styles[0]
|
||||
for(var/facial_hair_style in valid_facial_hairstyles)
|
||||
facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_style)
|
||||
data["facial_hair_styles"] = facial_hair_styles
|
||||
data["facial_hair_style"] = owner.f_style
|
||||
|
||||
data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR)
|
||||
data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR)
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src.name]", 800, 450)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/nano_module/appearance_changer/proc/update_dna()
|
||||
if(owner && (flags & APPEARANCE_UPDATE_DNA))
|
||||
owner.update_dna()
|
||||
|
||||
/obj/nano_module/appearance_changer/proc/can_change(var/flag)
|
||||
return owner && (flags & flag)
|
||||
|
||||
/obj/nano_module/appearance_changer/proc/can_change_skin_tone()
|
||||
return owner && (flags & APPEARANCE_SKIN) && owner.species.flags & HAS_SKIN_TONE
|
||||
|
||||
/obj/nano_module/appearance_changer/proc/can_change_skin_color()
|
||||
return owner && (flags & APPEARANCE_SKIN) && owner.species.flags & HAS_SKIN_COLOR
|
||||
|
||||
/obj/nano_module/appearance_changer/proc/can_still_topic()
|
||||
return CanUseTopic(usr, list(), default_state) == STATUS_INTERACTIVE
|
||||
|
||||
/obj/nano_module/appearance_changer/proc/cut_and_generate_data()
|
||||
// Making the assumption that the available species remain constant
|
||||
valid_facial_hairstyles.Cut()
|
||||
valid_facial_hairstyles.Cut()
|
||||
generate_data()
|
||||
|
||||
/obj/nano_module/appearance_changer/proc/generate_data()
|
||||
if(!valid_species.len)
|
||||
valid_species = owner.generate_valid_species(check_whitelist, whitelist, blacklist)
|
||||
if(!valid_hairstyles.len || !valid_facial_hairstyles.len)
|
||||
valid_hairstyles = owner.generate_valid_hairstyles()
|
||||
valid_facial_hairstyles = owner.generate_valid_facial_hairstyles()
|
||||
@@ -1,11 +1,11 @@
|
||||
/atom/movable/proc/nano_host()
|
||||
/atom/proc/nano_host()
|
||||
return src
|
||||
|
||||
/obj/nano_module/nano_host()
|
||||
return loc
|
||||
|
||||
|
||||
/atom/movable/proc/CanUseTopic(var/mob/user, href_list, var/datum/topic_state/custom_state)
|
||||
/atom/proc/CanUseTopic(var/mob/user, href_list, var/datum/topic_state/custom_state)
|
||||
return user.can_use_topic(nano_host(), custom_state)
|
||||
|
||||
|
||||
|
||||
@@ -772,8 +772,23 @@ var/list/be_special_flags = list(
|
||||
#define STATUS_UPDATE 1 // ORANGE Visability
|
||||
#define STATUS_DISABLED 0 // RED Visability
|
||||
#define STATUS_CLOSE -1 // Close the interface
|
||||
|
||||
//General-purpose life speed define for plants.
|
||||
#define HYDRO_SPEED_MULTIPLIER 1
|
||||
|
||||
#define NANO_IGNORE_DISTANCE 1
|
||||
|
||||
#define DEFAULT_JOB_TYPE /datum/job/assistant
|
||||
#define DEFAULT_JOB_TYPE /datum/job/assistant
|
||||
|
||||
// Appearance change flags
|
||||
#define APPEARANCE_UPDATE_DNA 1
|
||||
#define APPEARANCE_RACE 2|APPEARANCE_UPDATE_DNA
|
||||
#define APPEARANCE_GENDER 4|APPEARANCE_UPDATE_DNA
|
||||
#define APPEARANCE_SKIN 8
|
||||
#define APPEARANCE_HAIR 16
|
||||
#define APPEARANCE_HAIR_COLOR 32
|
||||
#define APPEARANCE_FACIAL_HAIR 64
|
||||
#define APPEARANCE_FACIAL_HAIR_COLOR 128
|
||||
#define APPEARANCE_EYE_COLOR 256
|
||||
#define APPEARANCE_ALL_HAIR APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR
|
||||
#define APPEARANCE_ALL 511
|
||||
|
||||
@@ -322,5 +322,9 @@ EVENT_CUSTOM_START_MAJOR 80;100
|
||||
## Uncomment to disable respawning by default.
|
||||
#DISABLE_RESPAWN
|
||||
|
||||
## Strength of ambient star light. Set to 0 or less to turn off.
|
||||
## Strength of ambient star light. Set to 0 or less to turn off. A value of 1 is unlikely to have a noticeable effect in most lightning systems.
|
||||
STARLIGHT 0
|
||||
|
||||
## Defines which races are allowed to join as ERT, in singular form. If unset, defaults to only human. Casing matters, separate using ;
|
||||
## Example races include: Human, Tajara, Skrell, Unathi
|
||||
# ERT_SPECIES Human;Skrell;Unathi
|
||||
|
||||
75
nano/templates/appearance_changer.tmpl
Normal file
75
nano/templates/appearance_changer.tmpl
Normal file
@@ -0,0 +1,75 @@
|
||||
{{if data.change_race}}
|
||||
<div class="item">
|
||||
<div class="itemLabelNarrow">
|
||||
Species:
|
||||
</div>
|
||||
<div class="itemContentWide">
|
||||
{{for data.species}}
|
||||
{{:helper.link(value.specimen, null, { 'race' : value.specimen}, null, data.specimen == value.specimen ? 'selected' : null)}}
|
||||
{{/for}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{if data.change_gender}}
|
||||
<div class="item">
|
||||
<div class="itemLabelNarrow">
|
||||
Gender:
|
||||
</div>
|
||||
<div class="itemContentWide">
|
||||
{{:helper.link('Male', null, { 'gender' : 'male'}, null, data.gender == 'male' ? 'selected' : null)}}
|
||||
{{:helper.link('Female', null, { 'gender' : 'female'}, null, data.gender == 'female' ? 'selected' : null)}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{if data.change_eye_color || data.change_skin_tone || data.change_skin_color || data.change_hair_color || data.change_facial_hair_color}}
|
||||
<div class="item">
|
||||
<div class="itemLabelNarrow">
|
||||
Colors:
|
||||
</div>
|
||||
<div class="itemContentWide">
|
||||
{{if data.change_eye_color}}
|
||||
{{:helper.link('Change eye color', null, { 'eye_color' : 1})}}
|
||||
{{/if}}
|
||||
{{if data.change_skin_tone}}
|
||||
{{:helper.link('Change skin tone', null, { 'skin_tone' : 1})}}
|
||||
{{/if}}
|
||||
{{if data.change_skin_color}}
|
||||
{{:helper.link('Change skin color', null, { 'skin_color' : 1})}}
|
||||
{{/if}}
|
||||
{{if data.change_hair_color}}
|
||||
{{:helper.link('Change hair color', null, { 'hair_color' : 1})}}
|
||||
{{/if}}
|
||||
{{if data.change_facial_hair_color}}
|
||||
{{:helper.link('Change facial hair color', null, { 'facial_hair_color' : 1})}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{if data.change_hair}}
|
||||
<div class="item">
|
||||
<div class="itemLabelNarrow">
|
||||
Hair styles:
|
||||
</div>
|
||||
<div class="itemContentWide">
|
||||
{{for data.hair_styles}}
|
||||
{{:helper.link(value.hairstyle, null, { 'hair' : value.hairstyle}, null, data.hair_style == value.hairstyle ? 'selected' : null)}}
|
||||
{{/for}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{if data.change_facial_hair}}
|
||||
<div class="item">
|
||||
<div class="itemLabelNarrow">
|
||||
Facial hair styles:
|
||||
</div>
|
||||
<div class="itemContentWide">
|
||||
{{for data.facial_hair_styles}}
|
||||
{{:helper.link(value.facialhairstyle, null, { 'facial_hair' : value.facialhairstyle}, null, data.facial_hair_style == value.facialhairstyle ? 'selected' : null)}}
|
||||
{{/for}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
Reference in New Issue
Block a user