Files
fulpstation/code/__HELPERS/mobs.dm
vuonojenmustaturska 4f0b0b7ec1 Replaces /atom.initialized and .admin_spawned with flags (#37981)
kill .initialized and .admin_spawned from /atom
2018-05-24 02:20:50 -07:00

531 lines
16 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", "caps" = pick(GLOB.caps_list), "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(pick(GLOB.moth_first)) + " " + capitalize(pick(GLOB.moth_last))
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]"
if(addition)
addition = " [addition]"
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][(sobject||addition) ? " 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][(sobject||addition) ? " with ":""][sobject][addition][hp][sattackloc]</font>"
target.log_message(message, INDIVIDUAL_ATTACK_LOG)
log_attack("[ssource] [what_done] [starget][(sobject||addition) ? " 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, var/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
delay *= user.do_after_coefficent()
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)
/mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1
. = 1
return
/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))
if (admin_spawn)
X.flags_1 |= ADMIN_SPAWNED_1
/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)
if (admin_spawn)
X.flags_1 |= ADMIN_SPAWNED_1
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