mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
* Moths, except with less conflicts * if I remove your wings, will you die? * it would be extremely painful
520 lines
15 KiB
Plaintext
520 lines
15 KiB
Plaintext
/proc/random_blood_type()
|
|
return pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
|
|
|
|
/proc/random_eye_color()
|
|
switch(pick(20;"brown",20;"hazel",20;"grey",15;"blue",15;"green",1;"amber",1;"albino"))
|
|
if("brown")
|
|
return "630"
|
|
if("hazel")
|
|
return "542"
|
|
if("grey")
|
|
return pick("666","777","888","999","aaa","bbb","ccc")
|
|
if("blue")
|
|
return "36c"
|
|
if("green")
|
|
return "060"
|
|
if("amber")
|
|
return "fc0"
|
|
if("albino")
|
|
return pick("c","d","e","f") + pick("0","1","2","3","4","5","6","7","8","9") + pick("0","1","2","3","4","5","6","7","8","9")
|
|
else
|
|
return "000"
|
|
|
|
/proc/random_underwear(gender)
|
|
if(!GLOB.underwear_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f)
|
|
switch(gender)
|
|
if(MALE)
|
|
return pick(GLOB.underwear_m)
|
|
if(FEMALE)
|
|
return pick(GLOB.underwear_f)
|
|
else
|
|
return pick(GLOB.underwear_list)
|
|
|
|
/proc/random_undershirt(gender)
|
|
if(!GLOB.undershirt_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f)
|
|
switch(gender)
|
|
if(MALE)
|
|
return pick(GLOB.undershirt_m)
|
|
if(FEMALE)
|
|
return pick(GLOB.undershirt_f)
|
|
else
|
|
return pick(GLOB.undershirt_list)
|
|
|
|
/proc/random_socks()
|
|
if(!GLOB.socks_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list)
|
|
return pick(GLOB.socks_list)
|
|
|
|
/proc/random_features()
|
|
if(!GLOB.tails_list_human.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human)
|
|
if(!GLOB.tails_list_lizard.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard)
|
|
if(!GLOB.snouts_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list)
|
|
if(!GLOB.horns_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, GLOB.horns_list)
|
|
if(!GLOB.ears_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.horns_list)
|
|
if(!GLOB.frills_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list)
|
|
if(!GLOB.spines_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, GLOB.spines_list)
|
|
if(!GLOB.legs_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list)
|
|
if(!GLOB.body_markings_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list)
|
|
if(!GLOB.wings_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list)
|
|
if(!GLOB.moth_wings_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_wings, GLOB.moth_wings_list)
|
|
|
|
//For now we will always return none for tail_human and ears.
|
|
return(list("mcolor" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), "tail_lizard" = pick(GLOB.tails_list_lizard), "tail_human" = "None", "wings" = "None", "snout" = pick(GLOB.snouts_list), "horns" = pick(GLOB.horns_list), "ears" = "None", "frills" = pick(GLOB.frills_list), "spines" = pick(GLOB.spines_list), "body_markings" = pick(GLOB.body_markings_list), "legs" = "Normal Legs", "moth_wings" = pick(GLOB.moth_wings_list)))
|
|
|
|
/proc/random_hair_style(gender)
|
|
switch(gender)
|
|
if(MALE)
|
|
return pick(GLOB.hair_styles_male_list)
|
|
if(FEMALE)
|
|
return pick(GLOB.hair_styles_female_list)
|
|
else
|
|
return pick(GLOB.hair_styles_list)
|
|
|
|
/proc/random_facial_hair_style(gender)
|
|
switch(gender)
|
|
if(MALE)
|
|
return pick(GLOB.facial_hair_styles_male_list)
|
|
if(FEMALE)
|
|
return pick(GLOB.facial_hair_styles_female_list)
|
|
else
|
|
return pick(GLOB.facial_hair_styles_list)
|
|
|
|
/proc/random_unique_name(gender, attempts_to_find_unique_name=10)
|
|
for(var/i in 1 to attempts_to_find_unique_name)
|
|
if(gender==FEMALE)
|
|
. = capitalize(pick(GLOB.first_names_female)) + " " + capitalize(pick(GLOB.last_names))
|
|
else
|
|
. = capitalize(pick(GLOB.first_names_male)) + " " + capitalize(pick(GLOB.last_names))
|
|
|
|
if(!findname(.))
|
|
break
|
|
|
|
/proc/random_unique_lizard_name(gender, attempts_to_find_unique_name=10)
|
|
for(var/i in 1 to attempts_to_find_unique_name)
|
|
. = capitalize(lizard_name(gender))
|
|
|
|
if(!findname(.))
|
|
break
|
|
|
|
/proc/random_unique_plasmaman_name(attempts_to_find_unique_name=10)
|
|
for(var/i in 1 to attempts_to_find_unique_name)
|
|
. = capitalize(plasmaman_name())
|
|
|
|
if(!findname(.))
|
|
break
|
|
|
|
/proc/random_unique_moth_name(attempts_to_find_unique_name=10)
|
|
for(var/i in 1 to attempts_to_find_unique_name)
|
|
. = capitalize(moth_name())
|
|
|
|
if(!findname(.))
|
|
break
|
|
|
|
/proc/random_skin_tone()
|
|
return pick(GLOB.skin_tones)
|
|
|
|
GLOBAL_LIST_INIT(skin_tones, list(
|
|
"albino",
|
|
"caucasian1",
|
|
"caucasian2",
|
|
"caucasian3",
|
|
"latino",
|
|
"mediterranean",
|
|
"asian1",
|
|
"asian2",
|
|
"arab",
|
|
"indian",
|
|
"african1",
|
|
"african2"
|
|
))
|
|
|
|
GLOBAL_LIST_EMPTY(species_list)
|
|
|
|
/proc/age2agedescription(age)
|
|
switch(age)
|
|
if(0 to 1)
|
|
return "infant"
|
|
if(1 to 3)
|
|
return "toddler"
|
|
if(3 to 13)
|
|
return "child"
|
|
if(13 to 19)
|
|
return "teenager"
|
|
if(19 to 30)
|
|
return "young adult"
|
|
if(30 to 45)
|
|
return "adult"
|
|
if(45 to 60)
|
|
return "middle-aged"
|
|
if(60 to 70)
|
|
return "aging"
|
|
if(70 to INFINITY)
|
|
return "elderly"
|
|
else
|
|
return "unknown"
|
|
|
|
/*
|
|
Proc for attack log creation, because really why not
|
|
1 argument is the actor
|
|
2 argument is the target of action
|
|
3 is the description of action(like punched, throwed, or any other verb)
|
|
4 is the tool with which the action was made(usually item) 4 and 5 are very similar(5 have "by " before it, that it) and are separated just to keep things in a bit more in order
|
|
5 is additional information, anything that needs to be added
|
|
*/
|
|
|
|
/proc/add_logs(mob/user, mob/target, what_done, object=null, addition=null)
|
|
var/turf/attack_location = get_turf(target)
|
|
|
|
var/is_mob_user = user && GLOB.typecache_mob[user.type]
|
|
var/is_mob_target = target && GLOB.typecache_mob[target.type]
|
|
|
|
var/mob/living/living_target
|
|
|
|
if(target && isliving(target))
|
|
living_target = target
|
|
|
|
var/hp =" "
|
|
if(living_target)
|
|
hp = "(NEWHP: [living_target.health])"
|
|
|
|
var/starget = "NON-EXISTENT SUBJECT"
|
|
if(target)
|
|
if(is_mob_target && target.ckey)
|
|
starget = "[target.name]([target.ckey])"
|
|
else
|
|
starget = "[target.name]"
|
|
|
|
var/ssource = "NON-EXISTENT USER" //How!?
|
|
if(user)
|
|
if(is_mob_user && user.ckey)
|
|
ssource = "[user.name]([user.ckey])"
|
|
else
|
|
ssource = "[user.name]"
|
|
|
|
var/sobject = ""
|
|
if(object)
|
|
sobject = "[object]"
|
|
|
|
var/sattackloc = ""
|
|
if(attack_location)
|
|
sattackloc = "([attack_location.x],[attack_location.y],[attack_location.z])"
|
|
|
|
if(is_mob_user)
|
|
var/message = "<font color='red'>has [what_done] [starget] with [sobject][addition] [hp] [sattackloc]</font>"
|
|
user.log_message(message, INDIVIDUAL_ATTACK_LOG)
|
|
|
|
if(is_mob_target)
|
|
var/message = "<font color='orange'>has been [what_done] by [ssource] with [sobject][addition] [hp] [sattackloc]</font>"
|
|
target.log_message(message, INDIVIDUAL_ATTACK_LOG)
|
|
|
|
log_attack("[ssource] [what_done] [starget] with [sobject][addition] [hp] [sattackloc]")
|
|
|
|
|
|
/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null)
|
|
if(!user || !target)
|
|
return 0
|
|
var/user_loc = user.loc
|
|
|
|
var/drifting = 0
|
|
if(!user.Process_Spacemove(0) && user.inertia_dir)
|
|
drifting = 1
|
|
|
|
var/target_loc = target.loc
|
|
|
|
var/holding = user.get_active_held_item()
|
|
var/datum/progressbar/progbar
|
|
if (progress)
|
|
progbar = new(user, time, target)
|
|
|
|
var/endtime = world.time+time
|
|
var/starttime = world.time
|
|
. = 1
|
|
while (world.time < endtime)
|
|
stoplag(1)
|
|
if (progress)
|
|
progbar.update(world.time - starttime)
|
|
if(QDELETED(user) || QDELETED(target))
|
|
. = 0
|
|
break
|
|
if(uninterruptible)
|
|
continue
|
|
|
|
if(drifting && !user.inertia_dir)
|
|
drifting = 0
|
|
user_loc = user.loc
|
|
|
|
if((!drifting && user.loc != user_loc) || target.loc != target_loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke()))
|
|
. = 0
|
|
break
|
|
if (progress)
|
|
qdel(progbar)
|
|
|
|
|
|
//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action
|
|
/mob/proc/break_do_after_checks(list/checked_health, check_clicks)
|
|
if(check_clicks && next_move > world.time)
|
|
return FALSE
|
|
return TRUE
|
|
|
|
//pass a list in the format list("health" = mob's health var) to check health during this
|
|
/mob/living/break_do_after_checks(list/checked_health, check_clicks)
|
|
if(islist(checked_health))
|
|
if(health < checked_health["health"])
|
|
return FALSE
|
|
checked_health["health"] = health
|
|
return ..()
|
|
|
|
/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null)
|
|
if(!user)
|
|
return 0
|
|
var/atom/Tloc = null
|
|
if(target && !isturf(target))
|
|
Tloc = target.loc
|
|
|
|
var/atom/Uloc = user.loc
|
|
|
|
var/drifting = 0
|
|
if(!user.Process_Spacemove(0) && user.inertia_dir)
|
|
drifting = 1
|
|
|
|
var/holding = user.get_active_held_item()
|
|
|
|
var/holdingnull = 1 //User's hand started out empty, check for an empty hand
|
|
if(holding)
|
|
holdingnull = 0 //Users hand started holding something, check to see if it's still holding that
|
|
|
|
var/datum/progressbar/progbar
|
|
if (progress)
|
|
progbar = new(user, delay, target)
|
|
|
|
var/endtime = world.time + delay
|
|
var/starttime = world.time
|
|
. = 1
|
|
while (world.time < endtime)
|
|
stoplag(1)
|
|
if (progress)
|
|
progbar.update(world.time - starttime)
|
|
|
|
if(drifting && !user.inertia_dir)
|
|
drifting = 0
|
|
Uloc = user.loc
|
|
|
|
if(QDELETED(user) || user.stat || user.IsKnockdown() || user.IsStun() || (!drifting && user.loc != Uloc) || (extra_checks && !extra_checks.Invoke()))
|
|
. = 0
|
|
break
|
|
|
|
if(!QDELETED(Tloc) && (QDELETED(target) || Tloc != target.loc))
|
|
if((Uloc != Tloc || Tloc != user) && !drifting)
|
|
. = 0
|
|
break
|
|
|
|
if(needhand)
|
|
//This might seem like an odd check, but you can still need a hand even when it's empty
|
|
//i.e the hand is used to pull some item/tool out of the construction
|
|
if(!holdingnull)
|
|
if(!holding)
|
|
. = 0
|
|
break
|
|
if(user.get_active_held_item() != holding)
|
|
. = 0
|
|
break
|
|
if (progress)
|
|
qdel(progbar)
|
|
|
|
/proc/do_after_mob(mob/user, var/list/targets, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks)
|
|
if(!user || !targets)
|
|
return 0
|
|
if(!islist(targets))
|
|
targets = list(targets)
|
|
var/user_loc = user.loc
|
|
|
|
var/drifting = 0
|
|
if(!user.Process_Spacemove(0) && user.inertia_dir)
|
|
drifting = 1
|
|
|
|
var/list/originalloc = list()
|
|
for(var/atom/target in targets)
|
|
originalloc[target] = target.loc
|
|
|
|
var/holding = user.get_active_held_item()
|
|
var/datum/progressbar/progbar
|
|
if(progress)
|
|
progbar = new(user, time, targets[1])
|
|
|
|
var/endtime = world.time + time
|
|
var/starttime = world.time
|
|
. = 1
|
|
mainloop:
|
|
while(world.time < endtime)
|
|
stoplag(1)
|
|
if(progress)
|
|
progbar.update(world.time - starttime)
|
|
if(QDELETED(user) || !targets)
|
|
. = 0
|
|
break
|
|
if(uninterruptible)
|
|
continue
|
|
|
|
if(drifting && !user.inertia_dir)
|
|
drifting = 0
|
|
user_loc = user.loc
|
|
|
|
for(var/atom/target in targets)
|
|
if((!drifting && user_loc != user.loc) || QDELETED(target) || originalloc[target] != target.loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke()))
|
|
. = 0
|
|
break mainloop
|
|
if(progbar)
|
|
qdel(progbar)
|
|
|
|
/proc/is_species(A, species_datum)
|
|
. = FALSE
|
|
if(ishuman(A))
|
|
var/mob/living/carbon/human/H = A
|
|
if(H.dna && istype(H.dna.species, species_datum))
|
|
. = TRUE
|
|
|
|
/proc/spawn_atom_to_turf(spawn_type, target, amount, admin_spawn=FALSE, list/extra_args)
|
|
var/turf/T = get_turf(target)
|
|
if(!T)
|
|
CRASH("attempt to spawn atom type: [spawn_type] in nullspace")
|
|
|
|
var/list/new_args = list(T)
|
|
if(extra_args)
|
|
new_args += extra_args
|
|
|
|
for(var/j in 1 to amount)
|
|
var/atom/X = new spawn_type(arglist(new_args))
|
|
X.admin_spawned = admin_spawn
|
|
|
|
/proc/spawn_and_random_walk(spawn_type, target, amount, walk_chance=100, max_walk=3, always_max_walk=FALSE, admin_spawn=FALSE)
|
|
var/turf/T = get_turf(target)
|
|
var/step_count = 0
|
|
if(!T)
|
|
CRASH("attempt to spawn atom type: [spawn_type] in nullspace")
|
|
|
|
for(var/j in 1 to amount)
|
|
var/atom/movable/X = new spawn_type(T)
|
|
X.admin_spawned = admin_spawn
|
|
|
|
if(always_max_walk || prob(walk_chance))
|
|
if(always_max_walk)
|
|
step_count = max_walk
|
|
else
|
|
step_count = rand(1, max_walk)
|
|
|
|
for(var/i in 1 to step_count)
|
|
step(X, pick(NORTH, SOUTH, EAST, WEST))
|
|
|
|
/proc/deadchat_broadcast(message, mob/follow_target=null, turf/turf_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR)
|
|
for(var/mob/M in GLOB.player_list)
|
|
var/datum/preferences/prefs
|
|
if(M.client && M.client.prefs)
|
|
prefs = M.client.prefs
|
|
else
|
|
prefs = new
|
|
|
|
var/adminoverride = 0
|
|
if(M.client && M.client.holder && (prefs.chat_toggles & CHAT_DEAD))
|
|
adminoverride = 1
|
|
if(isnewplayer(M) && !adminoverride)
|
|
continue
|
|
if(M.stat != DEAD && !adminoverride)
|
|
continue
|
|
if(speaker_key && speaker_key in prefs.ignoring)
|
|
continue
|
|
|
|
switch(message_type)
|
|
if(DEADCHAT_DEATHRATTLE)
|
|
if(prefs.toggles & DISABLE_DEATHRATTLE)
|
|
continue
|
|
if(DEADCHAT_ARRIVALRATTLE)
|
|
if(prefs.toggles & DISABLE_ARRIVALRATTLE)
|
|
continue
|
|
|
|
if(isobserver(M))
|
|
var/rendered_message = message
|
|
|
|
if(follow_target)
|
|
var/F
|
|
if(turf_target)
|
|
F = FOLLOW_OR_TURF_LINK(M, follow_target, turf_target)
|
|
else
|
|
F = FOLLOW_LINK(M, follow_target)
|
|
rendered_message = "[F] [message]"
|
|
else if(turf_target)
|
|
var/turf_link = TURF_LINK(M, turf_target)
|
|
rendered_message = "[turf_link] [message]"
|
|
|
|
to_chat(M, rendered_message)
|
|
else
|
|
to_chat(M, message)
|
|
|
|
|
|
/proc/log_talk(mob/user,message,logtype)
|
|
var/turf/say_turf = get_turf(user)
|
|
|
|
var/sayloc = ""
|
|
if(say_turf)
|
|
sayloc = "([say_turf.x],[say_turf.y],[say_turf.z])"
|
|
|
|
|
|
var/logmessage = "[message] [sayloc]"
|
|
|
|
switch(logtype)
|
|
|
|
if(LOGDSAY)
|
|
log_dsay(logmessage)
|
|
if(LOGSAY)
|
|
log_say(logmessage)
|
|
if(LOGWHISPER)
|
|
log_whisper(logmessage)
|
|
if(LOGEMOTE)
|
|
log_emote(logmessage)
|
|
if(LOGPDA)
|
|
log_pda(logmessage)
|
|
if(LOGCHAT)
|
|
log_chat(logmessage)
|
|
if(LOGCOMMENT)
|
|
log_comment(logmessage)
|
|
if(LOGASAY)
|
|
log_adminsay(logmessage)
|
|
if(LOGOOC)
|
|
log_ooc(logmessage)
|
|
else
|
|
warning("Invalid speech logging type detected. [logtype]. Defaulting to say")
|
|
log_say(logmessage)
|
|
|
|
//Used in chemical_mob_spawn. Generates a random mob based on a given gold_core_spawnable value.
|
|
/proc/create_random_mob(spawn_location, mob_class = HOSTILE_SPAWN)
|
|
var/static/list/mob_spawn_meancritters = list() // list of possible hostile mobs
|
|
var/static/list/mob_spawn_nicecritters = list() // and possible friendly mobs
|
|
|
|
if(mob_spawn_meancritters.len <= 0 || mob_spawn_nicecritters.len <= 0)
|
|
for(var/T in typesof(/mob/living/simple_animal))
|
|
var/mob/living/simple_animal/SA = T
|
|
switch(initial(SA.gold_core_spawnable))
|
|
if(HOSTILE_SPAWN)
|
|
mob_spawn_meancritters += T
|
|
if(FRIENDLY_SPAWN)
|
|
mob_spawn_nicecritters += T
|
|
|
|
var/chosen
|
|
if(mob_class == FRIENDLY_SPAWN)
|
|
chosen = pick(mob_spawn_nicecritters)
|
|
else
|
|
chosen = pick(mob_spawn_meancritters)
|
|
var/mob/living/simple_animal/C = new chosen(spawn_location)
|
|
return C |