Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into station_traits
This commit is contained in:
@@ -9,6 +9,12 @@
|
||||
|
||||
..()
|
||||
|
||||
if(!age_verify())
|
||||
return
|
||||
|
||||
if(!client) //client can end up null as a result of age_verify() kicking those who fail
|
||||
return
|
||||
|
||||
var/motd = global.config.motd
|
||||
if(motd)
|
||||
to_chat(src, "<div class=\"motd\">[motd]</div>", handle_whitespace=FALSE)
|
||||
@@ -22,8 +28,11 @@
|
||||
|
||||
sight |= SEE_TURFS
|
||||
|
||||
new_player_panel()
|
||||
client.playtitlemusic()
|
||||
|
||||
var/datum/asset/asset_datum = get_asset_datum(/datum/asset/simple/lobby)
|
||||
asset_datum.send(client)
|
||||
|
||||
if(SSticker.current_state < GAME_STATE_SETTING_UP)
|
||||
var/tl = SSticker.GetTimeLeft()
|
||||
var/postfix
|
||||
@@ -32,3 +41,7 @@
|
||||
else
|
||||
postfix = "soon"
|
||||
to_chat(src, "Please set up your character and select \"Ready\". The game will start [postfix].")
|
||||
|
||||
var/datum/hud/new_player/NH = hud_used
|
||||
if(istype(NH))
|
||||
NH.populate_buttons(src)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define LINKIFY_READY(string, value) "<a href='byond://?src=[REF(src)];ready=[value]'>[string]</a>"
|
||||
|
||||
/mob/dead/new_player
|
||||
var/ready = 0
|
||||
var/spawning = 0//Referenced when you want to delete the new_player later on in the code.
|
||||
@@ -10,6 +8,8 @@
|
||||
|
||||
density = FALSE
|
||||
stat = DEAD
|
||||
hud_type = /datum/hud/new_player
|
||||
hud_possible = list()
|
||||
|
||||
var/mob/living/new_character //for instant transfer once the round is set up
|
||||
|
||||
@@ -43,69 +43,6 @@
|
||||
/mob/dead/new_player/prepare_huds()
|
||||
return
|
||||
|
||||
/mob/dead/new_player/proc/new_player_panel()
|
||||
var/output = "<center><p>Welcome, <b>[client ? client.prefs.real_name : "Unknown User"]</b></p>"
|
||||
output += "<center><p><a href='byond://?src=[REF(src)];show_preferences=1'>Setup Character</a></p>"
|
||||
|
||||
if(SSticker.current_state <= GAME_STATE_PREGAME)
|
||||
switch(ready)
|
||||
if(PLAYER_NOT_READY)
|
||||
output += "<p>\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | <b>Not Ready</b> | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]</p>"
|
||||
if(PLAYER_READY_TO_PLAY)
|
||||
output += "<p>\[ <b>Ready</b> | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]</p>"
|
||||
if(PLAYER_READY_TO_OBSERVE)
|
||||
output += "<p>\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | <b> Observe </b> \]</p>"
|
||||
else
|
||||
output += "<p><a href='byond://?src=[REF(src)];manifest=1'>View the Crew Manifest</a></p>"
|
||||
output += "<p><a href='byond://?src=[REF(src)];late_join=1'>Join Game!</a></p>"
|
||||
output += "<p>[LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)]</p>"
|
||||
|
||||
if(!IsGuestKey(src.key))
|
||||
output += playerpolls()
|
||||
|
||||
output += "</center>"
|
||||
|
||||
//src << browse(output,"window=playersetup;size=210x240;can_close=0")
|
||||
var/datum/browser/popup = new(src, "playersetup", "<div align='center'>New Player Options</div>", 250, 265)
|
||||
popup.set_window_options("can_close=0")
|
||||
popup.set_content(output)
|
||||
popup.open(FALSE)
|
||||
|
||||
/mob/dead/new_player/proc/playerpolls()
|
||||
var/output = "" //hey tg why is this a list?
|
||||
if (SSdbcore.Connect())
|
||||
var/isadmin = FALSE
|
||||
if(client?.holder)
|
||||
isadmin = TRUE
|
||||
var/datum/db_query/query_get_new_polls = SSdbcore.NewQuery({"
|
||||
SELECT id FROM [format_table_name("poll_question")]
|
||||
WHERE (adminonly = 0 OR :isadmin = 1)
|
||||
AND Now() BETWEEN starttime AND endtime
|
||||
AND deleted = 0
|
||||
AND id NOT IN (
|
||||
SELECT pollid FROM [format_table_name("poll_vote")]
|
||||
WHERE ckey = :ckey
|
||||
AND deleted = 0
|
||||
)
|
||||
AND id NOT IN (
|
||||
SELECT pollid FROM [format_table_name("poll_textreply")]
|
||||
WHERE ckey = :ckey
|
||||
AND deleted = 0
|
||||
)
|
||||
"}, list("isadmin" = isadmin, "ckey" = ckey))
|
||||
var/rs = REF(src)
|
||||
if(!query_get_new_polls.Execute())
|
||||
qdel(query_get_new_polls)
|
||||
return
|
||||
if(query_get_new_polls.NextRow())
|
||||
output += "<p><b><a href='byond://?src=[rs];showpoll=1'>Show Player Polls</A> (NEW!)</b></p>"
|
||||
else
|
||||
output += "<p><a href='byond://?src=[rs];showpoll=1'>Show Player Polls</A></p>"
|
||||
qdel(query_get_new_polls)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
return output
|
||||
|
||||
/mob/dead/new_player/proc/age_gate()
|
||||
var/list/dat = list("<center>")
|
||||
dat += "Enter your date of birth here, to confirm that you are over 18.<BR>"
|
||||
@@ -152,6 +89,9 @@
|
||||
if(!(client.prefs.db_flags & DB_FLAG_AGE_CONFIRMATION_INCOMPLETE)) //completed? Skip
|
||||
return TRUE
|
||||
|
||||
if(!client)
|
||||
return FALSE
|
||||
|
||||
var/age_verification = age_gate()
|
||||
//ban them and kick them
|
||||
if(age_verification != 1)
|
||||
@@ -269,61 +209,12 @@
|
||||
if(!age_verify())
|
||||
return
|
||||
|
||||
//Determines Relevent Population Cap
|
||||
var/relevant_cap
|
||||
var/hpc = CONFIG_GET(number/hard_popcap)
|
||||
var/epc = CONFIG_GET(number/extreme_popcap)
|
||||
if(hpc && epc)
|
||||
relevant_cap = min(hpc, epc)
|
||||
else
|
||||
relevant_cap = max(hpc, epc)
|
||||
|
||||
if(href_list["show_preferences"])
|
||||
client.prefs.ShowChoices(src)
|
||||
return 1
|
||||
|
||||
if(href_list["ready"])
|
||||
var/tready = text2num(href_list["ready"])
|
||||
//Avoid updating ready if we're after PREGAME (they should use latejoin instead)
|
||||
//This is likely not an actual issue but I don't have time to prove that this
|
||||
//no longer is required
|
||||
if(SSticker.current_state <= GAME_STATE_PREGAME)
|
||||
ready = tready
|
||||
//if it's post initialisation and they're trying to observe we do the needful
|
||||
if(!SSticker.current_state < GAME_STATE_PREGAME && tready == PLAYER_READY_TO_OBSERVE)
|
||||
ready = tready
|
||||
make_me_an_observer()
|
||||
return
|
||||
|
||||
if(href_list["refresh"])
|
||||
src << browse(null, "window=playersetup") //closes the player setup window
|
||||
new_player_panel()
|
||||
|
||||
if(href_list["late_join"])
|
||||
if(!SSticker || !SSticker.IsRoundInProgress())
|
||||
to_chat(usr, "<span class='danger'>The round is either not ready, or has already finished...</span>")
|
||||
return
|
||||
|
||||
if(href_list["late_join"] == "override")
|
||||
LateChoices()
|
||||
return
|
||||
|
||||
if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in GLOB.admin_datums)))
|
||||
to_chat(usr, "<span class='danger'>[CONFIG_GET(string/hard_popcap_message)]</span>")
|
||||
|
||||
var/queue_position = SSticker.queued_players.Find(usr)
|
||||
if(queue_position == 1)
|
||||
to_chat(usr, "<span class='notice'>You are next in line to join the game. You will be notified when a slot opens up.</span>")
|
||||
else if(queue_position)
|
||||
to_chat(usr, "<span class='notice'>There are [queue_position-1] players in front of you in the queue to join the game.</span>")
|
||||
else
|
||||
SSticker.queued_players += usr
|
||||
to_chat(usr, "<span class='notice'>You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len].</span>")
|
||||
return
|
||||
LateChoices()
|
||||
|
||||
if(href_list["manifest"])
|
||||
ViewManifest()
|
||||
return
|
||||
|
||||
if(href_list["SelectedJob"])
|
||||
if(!SSticker || !SSticker.IsRoundInProgress())
|
||||
@@ -337,6 +228,17 @@
|
||||
to_chat(usr, "<span class='notice'>There is an administrative lock on entering the game!</span>")
|
||||
return
|
||||
|
||||
//Determines Relevent Population Cap
|
||||
var/relevant_cap
|
||||
var/hpc = CONFIG_GET(number/hard_popcap)
|
||||
var/epc = CONFIG_GET(number/extreme_popcap)
|
||||
if(hpc && epc)
|
||||
relevant_cap = min(hpc, epc)
|
||||
else
|
||||
relevant_cap = max(hpc, epc)
|
||||
|
||||
|
||||
|
||||
if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums))
|
||||
if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1]))
|
||||
to_chat(usr, "<span class='warning'>Server is full.</span>")
|
||||
@@ -349,6 +251,15 @@
|
||||
if(!GLOB.enter_allowed)
|
||||
to_chat(usr, "<span class='notice'> There is an administrative lock on entering the game!</span>")
|
||||
|
||||
//Determines Relevent Population Cap
|
||||
var/relevant_cap
|
||||
var/hpc = CONFIG_GET(number/hard_popcap)
|
||||
var/epc = CONFIG_GET(number/extreme_popcap)
|
||||
if(hpc && epc)
|
||||
relevant_cap = min(hpc, epc)
|
||||
else
|
||||
relevant_cap = max(hpc, epc)
|
||||
|
||||
if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums))
|
||||
if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1]))
|
||||
to_chat(usr, "<span class='warning'>Server is full.</span>")
|
||||
@@ -360,13 +271,6 @@
|
||||
SSticker.queue_delay = 4
|
||||
qdel(src)
|
||||
|
||||
else if(!href_list["late_join"])
|
||||
new_player_panel()
|
||||
|
||||
if(href_list["showpoll"])
|
||||
handle_player_polling()
|
||||
return
|
||||
|
||||
if(href_list["pollid"])
|
||||
var/pollid = href_list["pollid"]
|
||||
if(istext(pollid))
|
||||
@@ -460,7 +364,6 @@
|
||||
if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes")
|
||||
ready = PLAYER_NOT_READY
|
||||
src << browse(null, "window=playersetup") //closes the player setup window
|
||||
new_player_panel()
|
||||
return FALSE
|
||||
|
||||
var/mob/dead/observer/observer = new()
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
var/rando_race = pick(GLOB.roundstart_races)
|
||||
pref_species = new rando_race()
|
||||
features = random_features(pref_species?.id, gender)
|
||||
bark_id = pick(GLOB.bark_random_list)
|
||||
bark_pitch = BARK_PITCH_RAND(gender)
|
||||
bark_variance = BARK_VARIANCE_RAND
|
||||
age = rand(AGE_MIN,AGE_MAX)
|
||||
|
||||
/datum/preferences/proc/update_preview_icon(current_tab)
|
||||
|
||||
@@ -121,7 +121,8 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
remove_verb(src, /mob/dead/observer/verb/boo)
|
||||
remove_verb(src, /mob/dead/observer/verb/possess)
|
||||
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1)
|
||||
animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
|
||||
add_to_dead_mob_list()
|
||||
|
||||
@@ -534,8 +535,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
/mob/dead/observer/stop_orbit(datum/component/orbiter/orbits)
|
||||
. = ..()
|
||||
//restart our floating animation after orbit is done.
|
||||
pixel_y = 0
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1)
|
||||
pixel_z = 0
|
||||
animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
|
||||
/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
|
||||
set category = "Ghost"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
|
||||
// Takes care blood loss and regeneration
|
||||
/mob/living/carbon/human/handle_blood()
|
||||
/mob/living/carbon/human/handle_blood(delta_time, times_fired)
|
||||
|
||||
if(NOBLOOD in dna.species.species_traits || bleedsuppress || (HAS_TRAIT(src, TRAIT_FAKEDEATH)))
|
||||
return
|
||||
@@ -39,56 +39,57 @@
|
||||
return
|
||||
|
||||
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood.
|
||||
if(integrating_blood > 0)
|
||||
var/blood_integrated = max(integrating_blood - 1, 0)
|
||||
var/blood_diff = integrating_blood - blood_integrated
|
||||
integrating_blood = blood_integrated
|
||||
if(blood_volume < BLOOD_VOLUME_MAXIMUM)
|
||||
blood_volume += blood_diff
|
||||
if(blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
var/nutrition_ratio = 0
|
||||
if(!HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
switch(nutrition)
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
nutrition_ratio = 0.2
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
nutrition_ratio = 0.4
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
nutrition_ratio = 0.6
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
nutrition_ratio = 0.8
|
||||
else
|
||||
nutrition_ratio = 1
|
||||
if(satiety > 80)
|
||||
nutrition_ratio *= 1.25
|
||||
adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR)
|
||||
blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio)
|
||||
if(dna.species.handle_blood(src, delta_time, times_fired)) // if this returns TRUE, then the species is not handling blood itself and we can control everything
|
||||
if(integrating_blood > 0)
|
||||
var/blood_integrated = max(integrating_blood - 1, 0)
|
||||
var/blood_diff = integrating_blood - blood_integrated
|
||||
integrating_blood = blood_integrated
|
||||
if(blood_volume < BLOOD_VOLUME_MAXIMUM)
|
||||
blood_volume += blood_diff
|
||||
if(blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
var/nutrition_ratio = 0
|
||||
if(!HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
switch(nutrition)
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
nutrition_ratio = 0.2
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
nutrition_ratio = 0.4
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
nutrition_ratio = 0.6
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
nutrition_ratio = 0.8
|
||||
else
|
||||
nutrition_ratio = 1
|
||||
if(satiety > 80)
|
||||
nutrition_ratio *= 1.25
|
||||
adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR)
|
||||
blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio)
|
||||
|
||||
//Effects of bloodloss
|
||||
if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) //Synths are immune to direct consequences of bloodloss, instead suffering penalties to heat exchange.
|
||||
var/word = pick("dizzy","woozy","faint")
|
||||
var/blood_effect_volume = blood_volume + integrating_blood
|
||||
switch(blood_effect_volume)
|
||||
if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS)
|
||||
if(prob(10))
|
||||
to_chat(src, "<span class='warning'>You feel terribly bloated.</span>")
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
if(prob(5))
|
||||
to_chat(src, "<span class='warning'>You feel [word].</span>")
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
|
||||
if(prob(5))
|
||||
blur_eyes(6)
|
||||
to_chat(src, "<span class='warning'>You feel very [word].</span>")
|
||||
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
|
||||
adjustOxyLoss(5)
|
||||
if(prob(15))
|
||||
Unconscious(rand(20,60))
|
||||
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
|
||||
if(-INFINITY to BLOOD_VOLUME_SURVIVE)
|
||||
if(!HAS_TRAIT(src, TRAIT_NODEATH))
|
||||
death()
|
||||
//Effects of bloodloss
|
||||
if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) //Synths are immune to direct consequences of bloodloss, instead suffering penalties to heat exchange.
|
||||
var/word = pick("dizzy","woozy","faint")
|
||||
var/blood_effect_volume = blood_volume + integrating_blood
|
||||
switch(blood_effect_volume)
|
||||
if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS)
|
||||
if(prob(10))
|
||||
to_chat(src, "<span class='warning'>You feel terribly bloated.</span>")
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
if(prob(5))
|
||||
to_chat(src, "<span class='warning'>You feel [word].</span>")
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
|
||||
if(prob(5))
|
||||
blur_eyes(6)
|
||||
to_chat(src, "<span class='warning'>You feel very [word].</span>")
|
||||
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
|
||||
adjustOxyLoss(5)
|
||||
if(prob(15))
|
||||
Unconscious(rand(20,60))
|
||||
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
|
||||
if(-INFINITY to BLOOD_VOLUME_SURVIVE)
|
||||
if(!HAS_TRAIT(src, TRAIT_NODEATH))
|
||||
death()
|
||||
|
||||
var/temp_bleed = 0
|
||||
//Bleeding out
|
||||
@@ -193,6 +194,7 @@
|
||||
|
||||
blood_data["blood_DNA"] = dna.unique_enzymes
|
||||
blood_data["bloodcolor"] = dna.species.exotic_blood_color
|
||||
blood_data["bloodblend"] = dna.species.exotic_blood_blend_mode
|
||||
if(disease_resistances && disease_resistances.len)
|
||||
blood_data["resistances"] = disease_resistances.Copy()
|
||||
var/list/temp_chem = list()
|
||||
@@ -264,7 +266,7 @@
|
||||
"O-" = list("O-","SY"),
|
||||
"O+" = list("O-", "O+","SY"),
|
||||
"L" = list("L","SY"),
|
||||
"U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY"),
|
||||
"U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY", "BUG"),
|
||||
"HF" = list("HF", "SY"),
|
||||
"X*" = list("X*", "SY"),
|
||||
"SY" = list("SY"),
|
||||
@@ -370,27 +372,6 @@
|
||||
if(!B)
|
||||
B = new(T)
|
||||
|
||||
//This is a terrible way of handling it.
|
||||
/mob/living/proc/ResetBloodVol()
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if (HAS_TRAIT(src, TRAIT_HIGH_BLOOD))
|
||||
blood_ratio = 1.2
|
||||
H.handle_blood()
|
||||
return
|
||||
blood_ratio = 1
|
||||
H.handle_blood()
|
||||
return
|
||||
blood_ratio = 1
|
||||
|
||||
/mob/living/proc/AdjustBloodVol(value)
|
||||
if(blood_ratio == value)
|
||||
return
|
||||
blood_ratio = value
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
H.handle_blood()
|
||||
|
||||
/mob/living/proc/adjust_integration_blood(value, remove_actual_blood, force)
|
||||
if(integrating_blood + value < 0 && remove_actual_blood)
|
||||
blood_volume += value + integrating_blood
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
/mob/living/brain/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/brain/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
handle_emp_damage()
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
// update_icons() //Handled in update_transform(), leaving this here as a reminder
|
||||
update_transform()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that.
|
||||
/mob/living/carbon/alien/humanoid/update_transform(do_animate) //The old method of updating lying/standing was update_icons(). Aliens still expect that.
|
||||
if(lying > 0)
|
||||
lying = 90 //Anything else looks silly
|
||||
..()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/alien/larva/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/alien/larva/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
// GROW!
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
else
|
||||
icon_state = "larva[state]"
|
||||
|
||||
/mob/living/carbon/alien/larva/update_transform() //All this is handled in update_icons()
|
||||
/mob/living/carbon/alien/larva/update_transform(do_animate) //All this is handled in update_icons()
|
||||
..()
|
||||
return update_icons()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/alien/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/alien/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
findQueen()
|
||||
|
||||
@@ -90,10 +90,12 @@
|
||||
/mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, toxins_type = TOX_DEFAULT)
|
||||
if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER) && toxins_type != TOX_SYSCORRUPT) //damage becomes healing and healing becomes damage
|
||||
amount = -amount
|
||||
// don't allow toxinlover to push blood levels past BLOOD_VOLUME_MAXIMUM, but also don't set it back down to this if it's higher from something else
|
||||
var/blood_cap = blood_volume > BLOOD_VOLUME_MAXIMUM ? blood_volume : BLOOD_VOLUME_MAXIMUM
|
||||
if(amount > 0)
|
||||
blood_volume -= 3 * amount //5x was too much, this is punishing enough.
|
||||
blood_volume = min((blood_volume - (3 * amount)), blood_cap) //5x was too much, this is punishing enough.
|
||||
else
|
||||
blood_volume -= amount
|
||||
blood_volume = min((blood_volume - amount), blood_cap)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/getStaminaLoss()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
var/t_has = p_have()
|
||||
var/t_is = p_are()
|
||||
|
||||
. = list("<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <EM>[src]</EM>!")
|
||||
. = list("<span class='info'>This is [icon2html(src, user)] \a <EM>[src]</EM>!")
|
||||
|
||||
if (handcuffed)
|
||||
. += "<span class='warning'>[t_He] [t_is] [icon2html(handcuffed, user)] handcuffed!</span>"
|
||||
@@ -152,8 +152,11 @@
|
||||
. += "[t_He] look[p_s()] very happy."
|
||||
if(MOOD_LEVEL_HAPPY4 to INFINITY)
|
||||
. += "[t_He] look[p_s()] ecstatic."
|
||||
|
||||
if(LAZYLEN(.) > 1)
|
||||
.[2] = "<hr>[.[2]]"
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
|
||||
. += "*---------*</span>"
|
||||
|
||||
/mob/living/carbon/examine_more(mob/user)
|
||||
if(!all_scars)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
if(HAS_TRAIT(L, TRAIT_PROSOPAGNOSIA))
|
||||
obscure_name = TRUE
|
||||
|
||||
. = list("<span class='info'>*---------*\nThis is <EM>[!obscure_name ? name : "Unknown"]</EM>!")
|
||||
. = list("<span class='info'>This is <EM>[!obscure_name ? name : "Unknown"]</EM>!")
|
||||
|
||||
var/vampDesc = ReturnVampExamine(user) // Vamps recognize the names of other vamps.
|
||||
var/vassDesc = ReturnVassalExamine(user) // Vassals recognize each other's marks.
|
||||
@@ -442,9 +442,10 @@
|
||||
else if(isobserver(user) && traitstring)
|
||||
. += "<span class='info'><b>Traits:</b> [traitstring]</span>"
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now
|
||||
if(LAZYLEN(.) > 2) //Want this to appear after species text
|
||||
.[3] = "<hr>[.[3]]"
|
||||
|
||||
. += "*---------*</span>"
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now
|
||||
|
||||
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
|
||||
var/list/dat = list()
|
||||
|
||||
@@ -550,7 +550,7 @@
|
||||
to_chat(src, "<span class='notice'>You succesfuly remove the durathread strand.</span>")
|
||||
remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND)
|
||||
return
|
||||
var/to_send = ""
|
||||
var/to_send = "<blockquote class ='notice'>"
|
||||
visible_message("[src] examines [p_them()]self.", \
|
||||
"<span class='notice'>You check yourself for injuries.</span>")
|
||||
|
||||
@@ -597,27 +597,27 @@
|
||||
var/no_damage
|
||||
if(status == "OK" || status == "no damage")
|
||||
no_damage = TRUE
|
||||
to_send += "\t <span class='[no_damage ? "notice" : "warning"]'>Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].</span>\n"
|
||||
to_send += "<span class='[no_damage ? "notice" : "warning"]'>Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].</span>\n"
|
||||
|
||||
for(var/thing in LB.wounds)
|
||||
var/datum/wound/W = thing
|
||||
var/msg
|
||||
switch(W.severity)
|
||||
if(WOUND_SEVERITY_TRIVIAL)
|
||||
msg = "\t <span class='danger'>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)].</span>"
|
||||
msg = "<span class='danger'>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)].</span>"
|
||||
if(WOUND_SEVERITY_MODERATE)
|
||||
msg = "\t <span class='warning'>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!</span>"
|
||||
msg = "<span class='warning'>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!</span>"
|
||||
if(WOUND_SEVERITY_SEVERE)
|
||||
msg = "\t <span class='warning'><b>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!</b></span>"
|
||||
msg = "<span class='warning'><b>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!</b></span>"
|
||||
if(WOUND_SEVERITY_CRITICAL)
|
||||
msg = "\t <span class='warning'><b>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!</b></span>"
|
||||
msg = "<span class='warning'><b>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!</b></span>"
|
||||
to_chat(src, msg)
|
||||
|
||||
for(var/obj/item/I in LB.embedded_objects)
|
||||
if(I.isEmbedHarmless())
|
||||
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] stuck to your [LB.name]!</a>")
|
||||
to_chat(src, "<a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] stuck to your [LB.name]!</a>")
|
||||
else
|
||||
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
|
||||
to_chat(src, "<a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
|
||||
|
||||
for(var/t in missing)
|
||||
to_send += "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>\n"
|
||||
@@ -724,6 +724,8 @@
|
||||
if(roundstart_quirks.len)
|
||||
to_send += "<span class='notice'>You have these quirks: [get_trait_string()].</span>\n"
|
||||
|
||||
to_send += "</blockquote>"
|
||||
|
||||
to_chat(src, to_send)
|
||||
else
|
||||
if(wear_suit)
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
FP.blood_DNA["color"] = S.last_blood_color
|
||||
else
|
||||
FP.blood_DNA["color"] = BlendRGB(FP.blood_DNA["color"], S.last_blood_color)
|
||||
FP.blood_DNA["blendmode"] = S.last_blood_blend
|
||||
FP.update_icon()
|
||||
update_inv_shoes()
|
||||
//End bloody footprints
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
currently_coiled.pixel_x = 12
|
||||
|
||||
/datum/action/innate/ability/coiling/proc/coil_mob(var/mob/living/carbon/human/H)
|
||||
if(currently_coiling)
|
||||
to_chat(owner, span_warning("You are already coiling someone!"))
|
||||
return
|
||||
|
||||
// begin the coiling action
|
||||
H.visible_message("<span class='warning'>[owner] coils [H] with their tail!</span>", \
|
||||
"<span class='userdanger'>[owner] coils you with their tail!</span>")
|
||||
@@ -58,6 +62,9 @@
|
||||
|
||||
/datum/action/innate/ability/coiling/proc/cancel_coil()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
|
||||
if(!currently_coiling)
|
||||
return
|
||||
|
||||
// cancel the coiling action by removing the overlay
|
||||
currently_coiled.pixel_x = 0
|
||||
|
||||
@@ -25,25 +25,21 @@
|
||||
/datum/action/innate/ability/limb_regrowth/Activate()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
var/list/limbs_to_heal = H.get_missing_limbs()
|
||||
if(limbs_to_heal.len < 1)
|
||||
to_chat(H, "<span class='notice'>You feel intact enough as it is.</span>")
|
||||
if(!length(limbs_to_heal))
|
||||
to_chat(H, span_notice("You feel intact enough as it is."))
|
||||
return
|
||||
to_chat(H, "<span class='notice'>You focus intently on your missing [limbs_to_heal.len >= 2 ? "limbs" : "limb"]...</span>")
|
||||
var/mode = H.get_ability_property(INNATE_ABILITY_LIMB_REGROWTH, PROPERTY_LIMB_REGROWTH_USAGE_TYPE)
|
||||
switch(mode)
|
||||
if(REGROWTH_USES_BLOOD)
|
||||
if(H.blood_volume >= 40*limbs_to_heal.len+(BLOOD_VOLUME_OKAY*H.blood_ratio))
|
||||
H.regenerate_limbs()
|
||||
H.blood_volume -= 40*limbs_to_heal.len
|
||||
to_chat(H, "<span class='notice'>...and after a moment you finish reforming!</span>")
|
||||
return
|
||||
else if(H.blood_volume >= 40)//We can partially heal some limbs
|
||||
while(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40)
|
||||
var/healed_limb = pick(limbs_to_heal)
|
||||
H.regenerate_limb(healed_limb)
|
||||
limbs_to_heal -= healed_limb
|
||||
H.blood_volume -= 40
|
||||
to_chat(H, "<span class='warning'>...but there is not enough of you to fix everything! You must attain more mass to heal completely!</span>")
|
||||
return
|
||||
to_chat(H, "<span class='warning'>...but there is not enough of you to go around! You must attain more mass to heal!</span>")
|
||||
|
||||
to_chat(H, span_notice("You focus intently on your missing [length(limbs_to_heal) >= 2 ? "limbs" : "limb"]..."))
|
||||
if(H.blood_volume >= 40*length(limbs_to_heal)+BLOOD_VOLUME_OKAY)
|
||||
H.regenerate_limbs()
|
||||
H.blood_volume -= 40*length(limbs_to_heal)
|
||||
to_chat(H, span_notice("...and after a moment you finish reforming!"))
|
||||
return
|
||||
else if(H.blood_volume >= 40)//We can partially heal some limbs
|
||||
while(H.blood_volume >= BLOOD_VOLUME_OKAY+40)
|
||||
var/healed_limb = pick(limbs_to_heal)
|
||||
H.regenerate_limb(healed_limb)
|
||||
limbs_to_heal -= healed_limb
|
||||
H.blood_volume -= 40
|
||||
to_chat(H, span_warning("...but there is not enough of you to fix everything! You must attain more mass to heal completely!"))
|
||||
return
|
||||
to_chat(H, span_warning("...but there is not enough of you to go around! You must attain more mass to heal!"))
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#define THERMAL_PROTECTION_HAND_LEFT 0.025
|
||||
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
|
||||
|
||||
/mob/living/carbon/human/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/human/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
handle_active_genes()
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
return
|
||||
|
||||
var/list/print_msg = list()
|
||||
print_msg += "<span class='info'>*---------*</span>"
|
||||
print_msg += "<span class='userdanger'>As you snap back to consciousness, you recall people messing with your stuff...</span>"
|
||||
print_msg += "<blockquote class='warning'>"
|
||||
|
||||
afk_thefts = reverseRange(afk_thefts)
|
||||
|
||||
@@ -22,13 +22,14 @@
|
||||
var/time_since = world.time - iter_theft[AFK_THEFT_TIME]
|
||||
|
||||
if(time_since > AFK_THEFT_FORGET_DETAILS_TIME)
|
||||
print_msg += "\t<span class='danger'><b>Someone [theft_message], but it was at least [DisplayTimeText(AFK_THEFT_FORGET_DETAILS_TIME)] ago.</b></span>"
|
||||
print_msg += "<span class='danger'><b>Someone [theft_message], but it was at least [DisplayTimeText(AFK_THEFT_FORGET_DETAILS_TIME)] ago.</b></span>"
|
||||
else
|
||||
print_msg += "\t<span class='danger'><b>[thief_name] [theft_message] roughly [DisplayTimeText(time_since, 10)] ago.</b></span>"
|
||||
print_msg += "<span class='danger'><b>[thief_name] [theft_message] roughly [DisplayTimeText(time_since, 10)] ago.</b></span>"
|
||||
|
||||
print_msg += "</blockquote>"
|
||||
|
||||
if(LAZYLEN(afk_thefts) >= AFK_THEFT_MAX_MESSAGES)
|
||||
print_msg += "<span class='warning'>There may have been more, but that's all you can remember...</span>"
|
||||
print_msg += "<span class='info'>*---------*</span>"
|
||||
|
||||
to_chat(src, print_msg.Join("\n"))
|
||||
LAZYNULL(afk_thefts)
|
||||
|
||||
@@ -65,6 +65,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/exotic_bloodtype = ""
|
||||
/// Assume human as the default blood colour, override this default by species subtypes
|
||||
var/exotic_blood_color = BLOOD_COLOR_HUMAN
|
||||
/// Which blend mode should this species blood use?
|
||||
var/exotic_blood_blend_mode = BLEND_MULTIPLY
|
||||
///What the species drops when gibbed by a gibber machine.
|
||||
var/meat = /obj/item/reagent_containers/food/snacks/meat/slab/human //What the species drops on gibbing
|
||||
var/list/gib_types = list(/obj/effect/gibspawner/human, /obj/effect/gibspawner/human/bodypartless)
|
||||
@@ -826,13 +828,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/left_state = DEFAULT_LEFT_EYE_STATE
|
||||
var/right_state = DEFAULT_RIGHT_EYE_STATE
|
||||
if(eye_type in GLOB.eye_types)
|
||||
left_state = eye_type + "_left_eye"
|
||||
right_state = eye_type + "_right_eye"
|
||||
left_state = "[eye_type]_left_eye"
|
||||
right_state = "[eye_type]_right_eye"
|
||||
var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER)
|
||||
var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER)
|
||||
if((EYECOLOR in species_traits) && has_eyes)
|
||||
left_eye.color = "#" + H.left_eye_color
|
||||
right_eye.color = "#" + H.right_eye_color
|
||||
left_eye.color = "#[H.left_eye_color]"
|
||||
right_eye.color = "#[H.right_eye_color]"
|
||||
if(OFFSET_EYES in offset_features)
|
||||
left_eye.pixel_x += offset_features[OFFSET_EYES][1]
|
||||
left_eye.pixel_y += offset_features[OFFSET_EYES][2]
|
||||
@@ -2450,6 +2452,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
////////////////
|
||||
//Blood Stuff///
|
||||
////////////////
|
||||
// true = handle blood normally, false = do not (and then handle blood in this proc instead please!!)
|
||||
/datum/species/proc/handle_blood(mob/living/carbon/human/H, delta_time, times_fired)
|
||||
return TRUE
|
||||
|
||||
////////////////
|
||||
//Tail Wagging//
|
||||
////////////////
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
exotic_blood = /datum/reagent/blood/jellyblood
|
||||
exotic_bloodtype = "GEL"
|
||||
exotic_blood_color = "BLOOD_COLOR_SLIME"
|
||||
exotic_blood_blend_mode = BLEND_DEFAULT
|
||||
damage_overlay_type = ""
|
||||
liked_food = TOXIC | MEAT
|
||||
disliked_food = null
|
||||
@@ -31,6 +32,7 @@
|
||||
species_category = SPECIES_CATEGORY_JELLY
|
||||
wings_icons = SPECIES_WINGS_JELLY
|
||||
ass_image = 'icons/ass/assslime.png'
|
||||
blacklisted_quirks = list(/datum/quirk/glass_bones)
|
||||
|
||||
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
|
||||
C.faction -= "slime"
|
||||
@@ -53,38 +55,46 @@
|
||||
//update blood color to body color
|
||||
exotic_blood_color = "#" + H.dna.features["mcolor"]
|
||||
|
||||
/datum/species/jelly/spec_life(mob/living/carbon/human/H)
|
||||
if(H.stat == DEAD || HAS_TRAIT(H, TRAIT_NOMARROW)) //can't farm slime jelly from a dead slime/jelly person indefinitely, and no regeneration for bloodsuckers
|
||||
return
|
||||
if(!H.blood_volume)
|
||||
H.adjust_integration_blood(5)
|
||||
H.adjustBruteLoss(5)
|
||||
to_chat(H, "<span class='danger'>You feel empty!</span>")
|
||||
/datum/species/jelly/handle_blood(mob/living/carbon/human/H, delta_time, times_fired)
|
||||
if(H.stat == DEAD) //can't farm slime jelly from a dead slime/jelly person indefinitely
|
||||
return TRUE // we dont handle blood when dead
|
||||
|
||||
if(H.blood_volume < (BLOOD_VOLUME_NORMAL * H.blood_ratio))
|
||||
if(H.blood_volume <= 0)
|
||||
H.blood_volume += 2.5 * delta_time
|
||||
H.adjustBruteLoss(2.5 * delta_time)
|
||||
to_chat(H, span_danger("You feel empty!"))
|
||||
|
||||
if(H.blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
if(H.nutrition >= NUTRITION_LEVEL_STARVING)
|
||||
H.adjust_integration_blood(3)
|
||||
H.nutrition -= 2.5
|
||||
if(H.blood_volume < (BLOOD_VOLUME_OKAY*H.blood_ratio))
|
||||
if(prob(5))
|
||||
to_chat(H, "<span class='danger'>You feel drained!</span>")
|
||||
if(H.blood_volume < (BLOOD_VOLUME_BAD*H.blood_ratio))
|
||||
H.blood_volume += 1.5 * delta_time
|
||||
H.adjust_nutrition(-1.25 * delta_time)
|
||||
|
||||
if(H.blood_volume < BLOOD_VOLUME_OKAY)
|
||||
if(DT_PROB(2.5, delta_time))
|
||||
to_chat(H, span_danger("You feel drained!"))
|
||||
|
||||
if(H.blood_volume < BLOOD_VOLUME_BAD)
|
||||
Cannibalize_Body(H)
|
||||
..()
|
||||
|
||||
var/datum/action/innate/ability/regrowth = H.ability_actions[INNATE_ABILITY_LIMB_REGROWTH]
|
||||
if(regrowth)
|
||||
regrowth.UpdateButtonIcon()
|
||||
|
||||
return FALSE // to let living/handle_blood know that the species is handling blood instead
|
||||
|
||||
/datum/species/jelly/proc/Cannibalize_Body(mob/living/carbon/human/H)
|
||||
var/list/limbs_to_consume = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - H.get_missing_limbs()
|
||||
var/obj/item/bodypart/consumed_limb
|
||||
if(!limbs_to_consume.len)
|
||||
if(!length(limbs_to_consume))
|
||||
H.losebreath++
|
||||
return
|
||||
if(H.get_num_legs(FALSE)) //Legs go before arms
|
||||
limbs_to_consume -= list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM)
|
||||
consumed_limb = H.get_bodypart(pick(limbs_to_consume))
|
||||
consumed_limb.drop_limb()
|
||||
to_chat(H, "<span class='userdanger'>Your [consumed_limb] is drawn back into your body, unable to maintain its shape!</span>")
|
||||
to_chat(H, span_userdanger("Your [consumed_limb] is drawn back into your body, unable to maintain its shape!"))
|
||||
qdel(consumed_limb)
|
||||
H.adjust_integration_blood(20)
|
||||
H.blood_volume += 20
|
||||
|
||||
////////////////////////////////////////////////////////SLIMEPEOPLE///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
wings_icons = SPECIES_WINGS_SKELETAL
|
||||
|
||||
ass_image = 'icons/ass/assplasma.png'
|
||||
blacklisted_quirks = list(/datum/quirk/paper_skin)
|
||||
|
||||
/datum/species/plasmaman/spec_life(mob/living/carbon/human/H)
|
||||
var/datum/gas_mixture/environment = H.loc.return_air()
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
species_category = SPECIES_CATEGORY_SKELETON //they have their own category that's disassociated from undead, paired with plasmapeople
|
||||
wings_icons = SPECIES_WINGS_SKELETAL
|
||||
blacklisted_quirks = list(/datum/quirk/paper_skin)
|
||||
|
||||
/datum/species/skeleton/New()
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) //skeletons are stronger during the spooky season!
|
||||
|
||||
@@ -209,7 +209,7 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(!gloves && bloody_hands)
|
||||
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color())
|
||||
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
|
||||
if(get_num_arms(FALSE) < 2)
|
||||
if(has_left_hand(FALSE))
|
||||
bloody_overlay.icon_state = "bloodyhands_left"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/mob/living/carbon/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/BiologicalLife(delta_time, times_fired)
|
||||
//Reagent processing needs to come before breathing, to prevent edge cases.
|
||||
handle_organs(seconds, times_fired)
|
||||
handle_organs(delta_time, times_fired)
|
||||
. = ..() // if . is false, we are dead.
|
||||
if(stat == DEAD)
|
||||
stop_sound_channel(CHANNEL_HEARTBEAT)
|
||||
@@ -9,7 +9,7 @@
|
||||
. = FALSE
|
||||
if(!.)
|
||||
return
|
||||
handle_blood()
|
||||
handle_blood(delta_time, times_fired)
|
||||
// handle_blood *could* kill us.
|
||||
// we should probably have a better system for if we need to check for death or something in the future hmw
|
||||
if(stat != DEAD)
|
||||
@@ -23,7 +23,7 @@
|
||||
handle_brain_damage()
|
||||
|
||||
if(stat != DEAD)
|
||||
handle_liver(seconds, times_fired)
|
||||
handle_liver(delta_time, times_fired)
|
||||
|
||||
if(stat != DEAD)
|
||||
handle_corruption()
|
||||
@@ -375,7 +375,7 @@
|
||||
|
||||
miasma_turf.air_update_turf()
|
||||
|
||||
/mob/living/carbon/proc/handle_blood()
|
||||
/mob/living/carbon/proc/handle_blood(delta_time, times_fired)
|
||||
return
|
||||
|
||||
/mob/living/carbon/proc/handle_bodyparts(seconds, times_fired)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/mob/living/carbon/monkey
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/monkey/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(client)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
if(relic_mask)
|
||||
equip_to_slot_or_del(new relic_mask, ITEM_SLOT_MASK)
|
||||
|
||||
/mob/living/carbon/monkey/punpun/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/monkey/punpun/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
@@ -46,6 +46,7 @@
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/punpun/proc/Read_Memory()
|
||||
var/saved_color
|
||||
if(fexists("data/npc_saves/Punpun.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Punpun.sav")
|
||||
S["ancestor_name"] >> ancestor_name
|
||||
@@ -62,6 +63,9 @@
|
||||
ancestor_chain = json["ancestor_chain"]
|
||||
relic_hat = json["relic_hat"]
|
||||
relic_mask = json["relic_hat"]
|
||||
saved_color = json["color"]
|
||||
if(!isnull(saved_color))
|
||||
add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY)
|
||||
|
||||
/mob/living/carbon/monkey/punpun/proc/Write_Memory(dead, gibbed)
|
||||
var/json_file = file("data/npc_saves/Punpun.json")
|
||||
@@ -71,10 +75,12 @@
|
||||
file_data["ancestor_chain"] = null
|
||||
file_data["relic_hat"] = null
|
||||
file_data["relic_mask"] = null
|
||||
file_data["color"] = null
|
||||
else
|
||||
file_data["ancestor_name"] = ancestor_name ? ancestor_name : name
|
||||
file_data["ancestor_chain"] = dead ? ancestor_chain + 1 : ancestor_chain
|
||||
file_data["relic_hat"] = head ? head.type : null
|
||||
file_data["relic_mask"] = wear_mask ? wear_mask.type : null
|
||||
file_data["color"] = color ? json_encode(color) : null
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
@@ -518,6 +518,8 @@
|
||||
|
||||
/datum/emote/living/circle/run_emote(mob/user, params)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/obj/item/circlegame/N = new(user)
|
||||
if(user.put_in_hands(N))
|
||||
to_chat(user, "<span class='notice'>You make a circle with your hand.</span>")
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
* Handles biological life processes like chemical metabolism, breathing, etc
|
||||
* Returns TRUE or FALSE based on if we were interrupted. This is used by overridden variants to check if they should stop.
|
||||
*/
|
||||
/mob/living/proc/BiologicalLife(seconds, times_fired)
|
||||
SEND_SIGNAL(src,COMSIG_LIVING_BIOLOGICAL_LIFE, seconds, times_fired)
|
||||
/mob/living/proc/BiologicalLife(delta_time, times_fired)
|
||||
SEND_SIGNAL(src,COMSIG_LIVING_BIOLOGICAL_LIFE, delta_time, times_fired)
|
||||
handle_diseases()// DEAD check is in the proc itself; we want it to spread even if the mob is dead, but to handle its disease-y properties only if you're not.
|
||||
|
||||
handle_wounds()
|
||||
@@ -67,7 +67,7 @@
|
||||
//stuff in the stomach
|
||||
handle_stomach()
|
||||
|
||||
handle_block_parry(seconds)
|
||||
handle_block_parry(delta_time)
|
||||
|
||||
handle_traits() // eye, ear, brain damages
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
|
||||
//Called when we bump onto a mob
|
||||
/mob/living/proc/MobBump(mob/M)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_MOB_BUMP, M)
|
||||
//Even if we don't push/swap places, we "touched" them, so spread fire
|
||||
spreadFire(M)
|
||||
|
||||
@@ -88,6 +89,7 @@
|
||||
return TRUE
|
||||
|
||||
var/they_can_move = TRUE
|
||||
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
they_can_move = CHECK_MOBILITY(L, MOBILITY_MOVE)
|
||||
@@ -105,16 +107,16 @@
|
||||
//Should stop you pushing a restrained person out of the way
|
||||
if(L.pulledby && L.pulledby != src && L.restrained())
|
||||
if(!(world.time % 5))
|
||||
to_chat(src, "<span class='warning'>[L] is restrained, you cannot push past.</span>")
|
||||
return 1
|
||||
to_chat(src, span_warning("[L] is restrained, you cannot push past."))
|
||||
return TRUE
|
||||
|
||||
if(L.pulling)
|
||||
if(ismob(L.pulling))
|
||||
var/mob/P = L.pulling
|
||||
if(P.restrained())
|
||||
if(!(world.time % 5))
|
||||
to_chat(src, "<span class='warning'>[L] is restraining [P], you cannot push past.</span>")
|
||||
return 1
|
||||
to_chat(src, span_warning("[L] is restraining [P], you cannot push past."))
|
||||
return TRUE
|
||||
|
||||
//CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks or over prone bodies without a short delay
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
@@ -142,7 +144,7 @@
|
||||
//END OF CIT CHANGES
|
||||
|
||||
if(moving_diagonally)//no mob swap during diagonal moves.
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(!M.buckled && !M.has_buckled_mobs())
|
||||
var/mob_swap = FALSE
|
||||
@@ -151,7 +153,8 @@
|
||||
if(!too_strong)
|
||||
mob_swap = TRUE
|
||||
else
|
||||
if(M.pulledby == src && a_intent == INTENT_GRAB)
|
||||
//You can swap with the person you are dragging on grab intent, and restrained people in most cases
|
||||
if(M.pulledby == src && !too_strong)
|
||||
mob_swap = TRUE
|
||||
//restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller
|
||||
else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP))
|
||||
@@ -159,8 +162,8 @@
|
||||
if(mob_swap)
|
||||
//switch our position with M
|
||||
if(loc && !loc.Adjacent(M.loc))
|
||||
return 1
|
||||
now_pushing = 1
|
||||
return TRUE
|
||||
now_pushing = TRUE
|
||||
var/oldloc = loc
|
||||
var/oldMloc = M.loc
|
||||
|
||||
@@ -180,27 +183,31 @@
|
||||
if(!M_passmob)
|
||||
M.pass_flags &= ~PASSMOB
|
||||
|
||||
now_pushing = 0
|
||||
now_pushing = FALSE
|
||||
|
||||
if(!move_failed)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//okay, so we didn't switch. but should we push?
|
||||
//not if he's not CANPUSH of course
|
||||
if(!(M.status_flags & CANPUSH))
|
||||
return 1
|
||||
return TRUE
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
if(HAS_TRAIT(L, TRAIT_PUSHIMMUNE))
|
||||
return 1
|
||||
//If they're a human, and they're not in help intent, block pushing
|
||||
if(ishuman(M) && (M.a_intent != INTENT_HELP))
|
||||
return TRUE
|
||||
return TRUE
|
||||
if(M.a_intent != INTENT_HELP)
|
||||
//If they're a human, and they're not in help intent, block pushing
|
||||
if(ishuman(M))
|
||||
return TRUE
|
||||
//if they are a cyborg, and they're alive and not in help intent, block pushing
|
||||
if(iscyborg(M) && M.stat != DEAD)
|
||||
return TRUE
|
||||
//anti-riot equipment is also anti-push
|
||||
for(var/obj/item/I in M.held_items)
|
||||
if(!istype(M, /obj/item/clothing))
|
||||
if(prob(I.block_chance*2))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/get_photo_description(obj/item/camera/camera)
|
||||
var/list/mob_details = list()
|
||||
@@ -231,21 +238,40 @@
|
||||
if(!client && (mob_size < MOB_SIZE_SMALL))
|
||||
return
|
||||
now_pushing = TRUE
|
||||
var/t = get_dir(src, AM)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_PUSHING_MOVABLE, AM)
|
||||
var/dir_to_target = get_dir(src, AM)
|
||||
|
||||
// If there's no dir_to_target then the player is on the same turf as the atom they're trying to push.
|
||||
// This can happen when a player is stood on the same turf as a directional window. All attempts to push
|
||||
// the window will fail as get_dir will return 0 and the player will be unable to move the window when
|
||||
// it should be pushable.
|
||||
// In this scenario, we will use the facing direction of the /mob/living attempting to push the atom as
|
||||
// a fallback.
|
||||
if(!dir_to_target)
|
||||
dir_to_target = dir
|
||||
|
||||
var/push_anchored = FALSE
|
||||
if((AM.move_resist * MOVE_FORCE_CRUSH_RATIO) <= force)
|
||||
if(move_crush(AM, move_force, t))
|
||||
if(move_crush(AM, move_force, dir_to_target))
|
||||
push_anchored = TRUE
|
||||
if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally
|
||||
if(force_push(AM, move_force, t, push_anchored))
|
||||
if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally
|
||||
if(force_push(AM, move_force, dir_to_target, push_anchored))
|
||||
push_anchored = TRUE
|
||||
if(ismob(AM))
|
||||
var/mob/mob_to_push = AM
|
||||
var/atom/movable/mob_buckle = mob_to_push.buckled
|
||||
// If we can't pull them because of what they're buckled to, make sure we can push the thing they're buckled to instead.
|
||||
// If neither are true, we're not pushing anymore.
|
||||
if(mob_buckle && (mob_buckle.buckle_prevents_pull || (force < (mob_buckle.move_resist * MOVE_FORCE_PUSH_RATIO))))
|
||||
now_pushing = FALSE
|
||||
return
|
||||
if((AM.anchored && !push_anchored) || (force < (AM.move_resist * MOVE_FORCE_PUSH_RATIO)))
|
||||
now_pushing = FALSE
|
||||
return
|
||||
if (istype(AM, /obj/structure/window))
|
||||
if(istype(AM, /obj/structure/window))
|
||||
var/obj/structure/window/W = AM
|
||||
if(W.fulltile)
|
||||
for(var/obj/structure/window/win in get_step(W,t))
|
||||
for(var/obj/structure/window/win in get_step(W, dir_to_target))
|
||||
now_pushing = FALSE
|
||||
return
|
||||
if(pulling == AM)
|
||||
@@ -253,8 +279,9 @@
|
||||
var/current_dir
|
||||
if(isliving(AM))
|
||||
current_dir = AM.dir
|
||||
if(step(AM, t) && Process_Spacemove(t))
|
||||
step(src, t)
|
||||
if(AM.Move(get_step(AM.loc, dir_to_target), dir_to_target, glide_size))
|
||||
AM.add_fingerprint(src)
|
||||
Move(get_step(loc, dir_to_target), dir_to_target)
|
||||
if(current_dir)
|
||||
AM.setDir(current_dir)
|
||||
now_pushing = FALSE
|
||||
@@ -354,29 +381,33 @@
|
||||
offset = GRAB_PIXEL_SHIFT_NECK
|
||||
if(GRAB_KILL)
|
||||
offset = GRAB_PIXEL_SHIFT_NECK
|
||||
M.setDir(get_dir(M, src))
|
||||
switch(M.dir)
|
||||
if(NORTH)
|
||||
animate(M, pixel_x = 0, pixel_y = offset, 3)
|
||||
if(SOUTH)
|
||||
animate(M, pixel_x = 0, pixel_y = -offset, 3)
|
||||
if(EAST)
|
||||
if(M.lying == 270) //update the dragged dude's direction if we've turned
|
||||
M.lying = 90
|
||||
M.update_transform() //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so
|
||||
M.lying_prev = M.lying
|
||||
animate(M, pixel_x = offset, pixel_y = 0, 3)
|
||||
if(WEST)
|
||||
if(M.lying == 90)
|
||||
M.lying = 270
|
||||
M.update_transform()
|
||||
M.lying_prev = M.lying
|
||||
animate(M, pixel_x = -offset, pixel_y = 0, 3)
|
||||
var/target_dir = get_dir(M, src)
|
||||
M.setDir(target_dir)
|
||||
var/target_x
|
||||
var/target_y
|
||||
if(target_dir & NORTH)
|
||||
target_y += offset
|
||||
if(target_dir & SOUTH)
|
||||
target_y -= offset
|
||||
if(target_dir & EAST)
|
||||
target_x += offset
|
||||
if(target_dir & WEST)
|
||||
target_x -= offset
|
||||
if(target_x || target_y)
|
||||
if(0 < target_x && M.lying == 270)
|
||||
M.lying = 90
|
||||
M.update_transform(FALSE) //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so
|
||||
M.lying_prev = M.lying
|
||||
if(0 > target_x && M.lying == 90)
|
||||
M.lying = 270
|
||||
M.update_transform(FALSE)
|
||||
M.lying_prev = M.lying
|
||||
animate(M, pixel_x = target_x, pixel_y = target_y, time = 3, flags = ANIMATION_PARALLEL)
|
||||
|
||||
/mob/living/proc/reset_pull_offsets(mob/living/M, override)
|
||||
if(!override && M.buckled)
|
||||
return
|
||||
animate(M, pixel_x = 0, pixel_y = 0, 1)
|
||||
animate(M, pixel_x = 0, pixel_y = 0, time = 3, flags = ANIMATION_PARALLEL)
|
||||
|
||||
//mob verbs are a lot faster than object verbs
|
||||
//for more info on why this is not atom/pull, see examinate() in mob.dm
|
||||
@@ -885,12 +916,11 @@
|
||||
if(anchored || (buckled && buckled.anchored))
|
||||
fixed = 1
|
||||
if(on && !(movement_type & FLOATING) && !fixed)
|
||||
animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
|
||||
sleep(10)
|
||||
animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
|
||||
animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
setMovetype(movement_type | FLOATING)
|
||||
else if(((!on || fixed) && (movement_type & FLOATING)))
|
||||
animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10)
|
||||
animate(src, pixel_z = get_standard_pixel_y_offset(lying), time = 10)
|
||||
setMovetype(movement_type & ~FLOATING)
|
||||
|
||||
// The src mob is trying to strip an item from someone
|
||||
@@ -989,7 +1019,7 @@
|
||||
var/pixel_y_diff = rand(-amplitude/3, amplitude/3)
|
||||
var/final_pixel_x = get_standard_pixel_x_offset(lying)
|
||||
var/final_pixel_y = get_standard_pixel_y_offset(lying)
|
||||
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6)
|
||||
animate(src, pixel_x = pixel_x_diff, pixel_y = pixel_y_diff , time = 2, loop = 6, flags = ANIMATION_PARALLEL | ANIMATION_RELATIVE)
|
||||
animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2)
|
||||
floating_need_update = TRUE
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
/mob/living/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args) //parent calls can't overwrite the current proc args.
|
||||
if(!client)
|
||||
if(!client && !audiovisual_redirect)
|
||||
return
|
||||
var/deaf_message
|
||||
var/deaf_type
|
||||
@@ -297,8 +297,9 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
AM.Hear(rendered, src, message_language, message, null, spans, message_mode, source)
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message)
|
||||
|
||||
if(client && !eavesdrop_range && say_test(message) == "2") // Yell hook
|
||||
process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source)
|
||||
var/is_yell = (say_test(message) == "2")
|
||||
if(client && !eavesdrop_range && is_yell) // Yell hook
|
||||
listening |= process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source)
|
||||
|
||||
//speech bubble
|
||||
var/list/speech_bubble_recipients = list()
|
||||
@@ -309,6 +310,23 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_recipients, 30)
|
||||
|
||||
//Listening gets trimmed here if a vocal bark's present. If anyone ever makes this proc return listening, make sure to instead initialize a copy of listening in here to avoid wonkiness
|
||||
if(SEND_SIGNAL(src, COMSIG_MOVABLE_QUEUE_BARK, listening, args) || vocal_bark || vocal_bark_id)
|
||||
for(var/mob/M in listening)
|
||||
if(!M.client)
|
||||
continue
|
||||
if(!(M.client.prefs.toggles & SOUND_BARK))
|
||||
listening -= M
|
||||
var/barks = min(round((LAZYLEN(message) / vocal_speed)) + 1, BARK_MAX_BARKS)
|
||||
var/total_delay
|
||||
vocal_current_bark = world.time
|
||||
for(var/i in 1 to barks)
|
||||
if(total_delay > BARK_MAX_TIME)
|
||||
break
|
||||
addtimer(CALLBACK(src, /atom/movable/proc/bark, listening, (message_range * (is_yell ? 4 : 1)), (vocal_volume * (is_yell ? 1.5 : 1)), BARK_DO_VARY(vocal_pitch, vocal_pitch_range), vocal_current_bark), total_delay)
|
||||
total_delay += rand(DS2TICKS(vocal_speed / BARK_SPEED_BASELINE), DS2TICKS(vocal_speed / BARK_SPEED_BASELINE) + DS2TICKS((vocal_speed / BARK_SPEED_BASELINE) * (is_yell ? 0.5 : 1))) TICKS
|
||||
|
||||
|
||||
/atom/movable/proc/process_yelling(list/already_heard, rendered, atom/movable/speaker, datum/language/message_language, message, list/spans, message_mode, obj/source)
|
||||
if(last_yell > (world.time - 10))
|
||||
to_chat(src, "<span class='warning'>Your voice doesn't project as far as you try to yell in such quick succession.") // yeah no, no spamming an expensive floodfill.
|
||||
@@ -333,6 +351,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
var/atom/movable/AM = _AM
|
||||
AM.Hear(rendered, speaker, message_language, message, null, spans, message_mode, source)
|
||||
|
||||
return overhearing
|
||||
|
||||
/mob/proc/binarycheck()
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
var/mob/living/simple_animal/bot/Bot
|
||||
var/tracking = FALSE //this is 1 if the AI is currently tracking somebody, but the track has not yet been completed.
|
||||
var/datum/effect_system/spark_spread/spark_system//So they can initialize sparks whenever/N
|
||||
var/obj/machinery/status_display/controlled_display
|
||||
|
||||
//MALFUNCTION
|
||||
var/datum/module_picker/malf_picker
|
||||
@@ -660,7 +661,7 @@
|
||||
"goat" = 'icons/mob/animal.dmi',
|
||||
"cat" = 'icons/mob/pets.dmi',
|
||||
"cat2" = 'icons/mob/pets.dmi',
|
||||
"poly" = 'icons/mob/animal.dmi',
|
||||
"polly" = 'icons/mob/animal.dmi',
|
||||
"pug" = 'icons/mob/pets.dmi',
|
||||
"spider" = 'icons/mob/animal.dmi'
|
||||
)
|
||||
@@ -669,7 +670,7 @@
|
||||
if(input)
|
||||
qdel(holo_icon)
|
||||
switch(input)
|
||||
if("poly")
|
||||
if("polly")
|
||||
holo_icon = getHologramIcon(icon(icon_list[input],"parrot_fly"))
|
||||
if("chicken")
|
||||
holo_icon = getHologramIcon(icon(icon_list[input],"chicken_brown"))
|
||||
@@ -1043,3 +1044,14 @@
|
||||
|
||||
/mob/living/silicon/ai/zMove(dir, feedback = FALSE)
|
||||
. = eyeobj.zMove(dir, feedback)
|
||||
|
||||
/mob/living/silicon/ai/proc/stop_controlling_display()
|
||||
if(!controlled_display)
|
||||
return
|
||||
controlled_display.master = null
|
||||
controlled_display.cut_overlay(controlled_display.ai_vtuber_overlay)
|
||||
controlled_display.ai_vtuber_overlay = null
|
||||
if(current == controlled_display)
|
||||
current = null
|
||||
controlled_display.update_appearance()
|
||||
controlled_display = null
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/silicon/ai/examine(mob/user)
|
||||
. = list("<span class='info'>*---------*\nThis is [icon2html(src, user)] <EM>[src]</EM>!")
|
||||
. = list("<span class='info'>This is [icon2html(src, user)] <EM>[src]</EM>!")
|
||||
if (stat == DEAD)
|
||||
. += "<span class='deadsay'>It appears to be powered-down.</span>"
|
||||
else
|
||||
@@ -17,6 +17,8 @@
|
||||
. += "The wireless networking light is blinking."
|
||||
else if (!shunted && !client)
|
||||
. += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem..."
|
||||
. += "*---------*</span>"
|
||||
|
||||
if(LAZYLEN(.) > 1)
|
||||
.[2] = "<hr>[.[2]]"
|
||||
|
||||
. += ..()
|
||||
|
||||
@@ -92,6 +92,8 @@
|
||||
ai.light_cameras()
|
||||
if(ai.master_multicam)
|
||||
ai.master_multicam.refresh_view()
|
||||
if(ai.controlled_display)
|
||||
ai.stop_controlling_display()
|
||||
|
||||
//it uses setLoc not forceMove, talks to the sillycone and not the camera mob
|
||||
/mob/camera/aiEye/zMove(dir, feedback = FALSE)
|
||||
@@ -168,6 +170,9 @@
|
||||
if(!user.tracking)
|
||||
user.cameraFollow = null
|
||||
|
||||
if(user.controlled_display)
|
||||
user.stop_controlling_display()
|
||||
|
||||
// Return to the Core.
|
||||
/mob/living/silicon/ai/proc/view_core()
|
||||
if(istype(current,/obj/machinery/holopad))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define POWER_RESTORATION_SEARCH_APC 2
|
||||
#define POWER_RESTORATION_APC_FOUND 3
|
||||
|
||||
/mob/living/silicon/ai/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/silicon/ai/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
//I'm not removing that shitton of tabs, unneeded as they are. -- Urist
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
|
||||
//For holopads only. Usable by AI.
|
||||
/mob/living/silicon/ai/proc/holopad_talk(message, language)
|
||||
|
||||
|
||||
message = trim(message)
|
||||
|
||||
if (!message)
|
||||
@@ -56,6 +54,29 @@
|
||||
to_chat(src, "No holopad connected.")
|
||||
|
||||
|
||||
//For status displays only. Usable by AI.
|
||||
/mob/living/silicon/ai/proc/statusdisplay_talk(message, language)
|
||||
message = trim(message)
|
||||
|
||||
if (!message)
|
||||
return
|
||||
|
||||
var/obj/machinery/status_display/T = controlled_display
|
||||
if(T)
|
||||
var/turf/padturf = get_turf(T)
|
||||
var/padloc
|
||||
if(padturf)
|
||||
padloc = AREACOORD(padturf)
|
||||
else
|
||||
padloc = "(UNKNOWN)"
|
||||
src.log_talk(message, LOG_SAY, tag="STATUS DISPLAY in [padloc]")
|
||||
send_speech(message, 7, T, "robot", message_language = language)
|
||||
to_chat(src, "<i><span class='game say'>Status Display message transmitted, <span class='name'>[real_name]</span> <span class='message robot'>\"[message]\"</span></span></i>")
|
||||
else
|
||||
to_chat(src, "No status display connected.")
|
||||
|
||||
|
||||
|
||||
// Make sure that the code compiles with AI_VOX undefined
|
||||
#ifdef AI_VOX
|
||||
#define VOX_DELAY 600
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/mob/living/silicon/examine(mob/user) //Displays a silicon's laws to ghosts
|
||||
. = ..()
|
||||
if(laws && isobserver(user))
|
||||
. += "<b>[src] has the following laws:</b>"
|
||||
for(var/law in laws.get_law_list(include_zeroth = TRUE))
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
if(possible_chassis[chassis])
|
||||
AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD)
|
||||
|
||||
/mob/living/silicon/pai/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/silicon/pai/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(hacking)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
var/unrestricted = TRUE
|
||||
|
||||
/datum/emote/sound/silicon/run_emote(mob/user, params)
|
||||
if(!unrestricted && !(issilicon(user) || isipcperson(user)))
|
||||
if(!unrestricted && !(issilicon(user) || isrobotic(user)))
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/silicon/robot/examine(mob/user)
|
||||
. = list("<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <EM>[src]</EM>, a [src.module.name] unit!")
|
||||
. = list("<span class='info'>This is [icon2html(src, user)] \a <EM>[src]</EM>, a [src.module.name] unit!")
|
||||
if(desc)
|
||||
. += "[desc]"
|
||||
|
||||
@@ -49,8 +49,9 @@
|
||||
if(DEAD)
|
||||
. += "<span class='deadsay'>It looks like its system is corrupted and requires a reset.</span>"
|
||||
|
||||
if(LAZYLEN(.) > 1)
|
||||
.[2] = "<hr>[.[2]]"
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, usr, .)
|
||||
|
||||
. += "*---------*</span>"
|
||||
|
||||
. += ..()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/silicon/robot/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/silicon/robot/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
adjustOxyLoss(-10) //we're a robot!
|
||||
|
||||
@@ -421,8 +421,8 @@
|
||||
if("Alina")
|
||||
cyborg_base_icon = "alina-med"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
special_light_key = "alina"
|
||||
sleeper_overlay = "alinasleeper"
|
||||
special_light_key = "alina-med"
|
||||
sleeper_overlay = "valemedsleeper"
|
||||
moduleselect_icon = "medihound"
|
||||
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
|
||||
dogborg = TRUE
|
||||
@@ -536,9 +536,9 @@
|
||||
dogborg = TRUE
|
||||
if("Alina")
|
||||
cyborg_base_icon = "alina-eng"
|
||||
special_light_key = "alina"
|
||||
special_light_key = "alina-eng"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
sleeper_overlay = "alinasleeper"
|
||||
sleeper_overlay = "valeengsleeper"
|
||||
dogborg = TRUE
|
||||
else
|
||||
return FALSE
|
||||
@@ -620,8 +620,8 @@
|
||||
dogborg = TRUE
|
||||
if("Alina")
|
||||
cyborg_base_icon = "alina-sec"
|
||||
special_light_key = "alina"
|
||||
sleeper_overlay = "alinasleeper"
|
||||
special_light_key = "alina-sec"
|
||||
sleeper_overlay = "valesecsleeper"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
dogborg = TRUE
|
||||
if("K9 Dark")
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
|
||||
typing_indicator_state = /obj/effect/overlay/typing_indicator/machine
|
||||
|
||||
vocal_bark_id = "synth"
|
||||
vocal_pitch_range = 0.1
|
||||
|
||||
/mob/living/silicon/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.silicon_mobs += src
|
||||
@@ -413,7 +416,7 @@
|
||||
src << browse(dat, "window=airoster")
|
||||
onclose(src, "airoster")
|
||||
|
||||
/mob/living/silicon/update_transform()
|
||||
/mob/living/silicon/update_transform(do_animate)
|
||||
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
|
||||
var/changed = 0
|
||||
if(resize != RESIZE_DEFAULT_SIZE)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
path_image_color = "#993299"
|
||||
weather_immunities = list("lava","ash")
|
||||
|
||||
var/base_icon = "cleanbot"
|
||||
var/clean_time = 50 //How long do we take to clean?
|
||||
var/upgrades = 0
|
||||
|
||||
@@ -126,13 +127,21 @@
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/turn_on()
|
||||
..()
|
||||
icon_state = "cleanbot[on]"
|
||||
bot_core.updateUsrDialog()
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/turn_off()
|
||||
..()
|
||||
icon_state = "cleanbot[on]"
|
||||
bot_core.updateUsrDialog()
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/update_icon_state()
|
||||
. = ..()
|
||||
switch(mode)
|
||||
if(BOT_CLEANING)
|
||||
icon_state = "[base_icon]-c"
|
||||
else
|
||||
icon_state = "[base_icon][on]"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/bot_reset()
|
||||
..()
|
||||
@@ -381,6 +390,12 @@
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
icon_state = "cleanbot[on]"
|
||||
else if(istype(A, /turf)) //for player-controlled cleanbots so they can clean unclickable messes like dirt
|
||||
var/turf/T = A
|
||||
for(var/atom/S in T.contents)
|
||||
if(istype(S, /obj/effect/decal/cleanable)) //clean the first mess found
|
||||
UnarmedAttack(S)
|
||||
return
|
||||
else if(istype(A, /obj/item) || istype(A, /obj/effect/decal/remains))
|
||||
visible_message("<span class='danger'>[src] sprays hydrofluoric acid at [A]!</span>")
|
||||
playsound(src, 'sound/effects/spray2.ogg', 50, TRUE, -6)
|
||||
|
||||
@@ -83,13 +83,12 @@
|
||||
/mob/living/simple_animal/hostile/construct/examine(mob/user)
|
||||
var/t_He = p_they(TRUE)
|
||||
var/t_s = p_s()
|
||||
. = list("<span class='cult'>*---------*\nThis is [icon2html(src, user)] \a <b>[src]</b>!\n[desc]")
|
||||
. = list("<span class='cult'>This is [icon2html(src, user)] \a <b>[src]</b>!\n[desc]</span>")
|
||||
if(health < maxHealth)
|
||||
if(health >= maxHealth/2)
|
||||
. += "<span class='warning'>[t_He] look[t_s] slightly dented.</span>"
|
||||
else
|
||||
. += "<span class='warning'><b>[t_He] look[t_s] severely dented!</b></span>"
|
||||
. += "*---------*</span>"
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/attack_animal(mob/living/simple_animal/M)
|
||||
if(isconstruct(M)) //is it a construct?
|
||||
|
||||
@@ -223,7 +223,7 @@
|
||||
QDEL_NULL(back) // chain destruction baby
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/eldritch/armsy/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/eldritch/armsy/BiologicalLife(delta_time, times_fired)
|
||||
adjustBruteLoss(-2)
|
||||
|
||||
/mob/living/simple_animal/hostile/eldritch/armsy/proc/heal()
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
collar_type = "cat"
|
||||
var/held_icon = "cat2"
|
||||
footstep_type = FOOTSTEP_MOB_CLAW
|
||||
vocal_bark_id = "mutedc4"
|
||||
vocal_pitch = 1.4
|
||||
vocal_pitch_range = 0.4
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -115,7 +118,7 @@
|
||||
Read_Memory()
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/pet/cat/Runtime/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!cats_deployed && SSticker.current_state >= GAME_STATE_SETTING_UP)
|
||||
@@ -136,6 +139,7 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory()
|
||||
var/saved_color
|
||||
if(fexists("data/npc_saves/Runtime.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
|
||||
S["family"] >> family
|
||||
@@ -146,14 +150,21 @@
|
||||
return
|
||||
var/list/json = json_decode(file2text(json_file))
|
||||
family = json["family"]
|
||||
saved_color = json["color"]
|
||||
if(isnull(family))
|
||||
family = list()
|
||||
if(!isnull(saved_color))
|
||||
add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY)
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Write_Memory(dead)
|
||||
var/json_file = file("data/npc_saves/Runtime.json")
|
||||
var/list/file_data = list()
|
||||
family = list()
|
||||
if(!dead)
|
||||
if(color)
|
||||
file_data["color"] = json_encode(color)
|
||||
else
|
||||
file_data["color"] = null
|
||||
for(var/mob/living/simple_animal/pet/cat/kitten/C in children)
|
||||
if(istype(C,type) || C.stat || !C.z || !C.butcher_results) //That last one is a work around for hologram cats
|
||||
continue
|
||||
@@ -161,6 +172,8 @@
|
||||
family[C.type] += 1
|
||||
else
|
||||
family[C.type] = 1
|
||||
else
|
||||
file_data["color"] = null
|
||||
file_data["family"] = family
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
@@ -178,7 +191,7 @@
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
unique_pet = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/cat/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/pet/cat/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!stat && !buckled && !client)
|
||||
@@ -272,7 +285,7 @@
|
||||
to_chat(src, "<span class='notice'>Your name is now <b>\"new_name\"</b>!</span>")
|
||||
name = new_name
|
||||
|
||||
/mob/living/simple_animal/pet/cat/cak/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/pet/cat/cak/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(stat)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
. = ..()
|
||||
AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
|
||||
/mob/living/simple_animal/crab/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/crab/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
//CRAB movement
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_CLAW
|
||||
|
||||
vocal_bark_id = "bullet"
|
||||
vocal_speed = 6
|
||||
|
||||
/mob/living/simple_animal/pet/dog/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/wuv, "yaps happily!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "growls!", EMOTE_AUDIBLE)
|
||||
@@ -424,7 +427,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
RemoveElement(/datum/element/mob_holder, held_icon)
|
||||
AddElement(/datum/element/mob_holder, "old_corgi")
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
@@ -438,6 +441,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/proc/Read_Memory()
|
||||
set waitfor = FALSE
|
||||
var/saved_color
|
||||
if(fexists("data/npc_saves/Ian.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Ian.sav")
|
||||
S["age"] >> age
|
||||
@@ -452,12 +456,15 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
age = json["age"]
|
||||
record_age = json["record_age"]
|
||||
saved_head = json["saved_head"]
|
||||
saved_color = json["color"]
|
||||
if(isnull(age))
|
||||
age = 0
|
||||
if(isnull(record_age))
|
||||
record_age = 1
|
||||
if(saved_head)
|
||||
place_on_head(new saved_head)
|
||||
if(!isnull(saved_color))
|
||||
add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY)
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/proc/Write_Memory(dead)
|
||||
var/json_file = file("data/npc_saves/Ian.json")
|
||||
@@ -472,10 +479,15 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
file_data["saved_head"] = inventory_head.type
|
||||
else
|
||||
file_data["saved_head"] = null
|
||||
if(color)
|
||||
file_data["color"] = json_encode(color)
|
||||
else
|
||||
file_data["color"] = null
|
||||
else
|
||||
file_data["age"] = 0
|
||||
file_data["record_age"] = record_age
|
||||
file_data["saved_head"] = null
|
||||
file_data["color"] = null
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
@@ -553,7 +565,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
nofur = TRUE
|
||||
unique_pet = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/narsie/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/pet/dog/corgi/narsie/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
for(var/mob/living/simple_animal/pet/P in range(1, src))
|
||||
@@ -632,6 +644,8 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
collar_type = "puppy"
|
||||
|
||||
vocal_pitch = 1.6
|
||||
|
||||
//puppies cannot wear anything.
|
||||
/mob/living/simple_animal/pet/dog/corgi/puppy/Topic(href, href_list)
|
||||
if(href_list["remove_inv"] || href_list["add_inv"])
|
||||
@@ -653,6 +667,8 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
maxbodytemp = T0C + 40
|
||||
held_icon = "void_puppy"
|
||||
|
||||
vocal_pitch = 0.6
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/puppy/void/Process_Spacemove(movement_dir = 0)
|
||||
return 1 //Void puppies can navigate space.
|
||||
|
||||
@@ -679,7 +695,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Lisa/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/pet/dog/corgi/Lisa/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
|
||||
@@ -693,7 +709,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
setDir(i)
|
||||
sleep(1)
|
||||
|
||||
/mob/living/simple_animal/pet/dog/pug/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/pet/dog/pug/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
|
||||
|
||||
@@ -178,7 +178,7 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/examine(mob/user)
|
||||
. = list("<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <b>[src]</b>!")
|
||||
. = list("<span class='info'>This is [icon2html(src, user)] \a <b>[src]</b>!")
|
||||
|
||||
//Hands
|
||||
for(var/obj/item/I in held_items)
|
||||
@@ -214,7 +214,7 @@
|
||||
. += "<span class='deadsay'>A message repeatedly flashes on its display: \"REBOOT -- REQUIRED\".</span>"
|
||||
else
|
||||
. += "<span class='deadsay'>A message repeatedly flashes on its display: \"ERROR -- OFFLINE\".</span>"
|
||||
. += "*---------*</span>"
|
||||
. += "</span>"
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) //Secbots won't hunt maintenance drones.
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
var/datum/reagent/milk_reagent = /datum/reagent/consumable/milk
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_SHOE
|
||||
vocal_bark_id = "banjoc3"
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/Initialize(mapload, /datum/reagent/milk_reagent)
|
||||
udder = new (null, milk_reagent)
|
||||
@@ -46,7 +47,7 @@
|
||||
udder = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(stat == CONSCIOUS)
|
||||
@@ -143,6 +144,8 @@
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_SHOE
|
||||
vocal_bark_id = "mutedc2"
|
||||
vocal_pitch = 1.2
|
||||
|
||||
/mob/living/simple_animal/cow/Initialize(mapload)
|
||||
udder = new(null, milk_reagent)
|
||||
@@ -160,7 +163,7 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/cow/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/cow/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(stat == CONSCIOUS)
|
||||
@@ -247,6 +250,8 @@
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_CLAW
|
||||
vocal_bark_id = "squeak"
|
||||
vocal_pitch = 1.4
|
||||
|
||||
/mob/living/simple_animal/chick/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -254,7 +259,7 @@
|
||||
pixel_y = rand(0, 10)
|
||||
AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
|
||||
/mob/living/simple_animal/chick/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/chick/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!stat && !ckey)
|
||||
@@ -263,7 +268,7 @@
|
||||
new /mob/living/simple_animal/chicken(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/chick/holo/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/chick/holo/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
amount_grown = 0
|
||||
@@ -309,6 +314,9 @@
|
||||
var/static/chicken_count = 0
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_CLAW
|
||||
vocal_bark_id = "synthgrunt"
|
||||
vocal_pitch = 1.4
|
||||
vocal_pitch_range = 0.4
|
||||
|
||||
/mob/living/simple_animal/chicken/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -339,7 +347,7 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/chicken/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/chicken/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if((!stat && prob(3) && eggsleft > 0) && egg_type)
|
||||
@@ -403,6 +411,8 @@
|
||||
var/static/kiwi_count = 0
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_CLAW
|
||||
vocal_bark_id = "squeak"
|
||||
vocal_pitch = 1.4
|
||||
|
||||
/mob/living/simple_animal/kiwi/Destroy()
|
||||
--kiwi_count
|
||||
@@ -414,7 +424,7 @@
|
||||
|
||||
AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
|
||||
/mob/living/simple_animal/kiwi/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/kiwi/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if((!stat && prob(3) && eggsleft > 0) && egg_type)
|
||||
@@ -481,6 +491,8 @@
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_CLAW
|
||||
vocal_bark_id = "squeak"
|
||||
vocal_pitch = 1.4
|
||||
|
||||
/mob/living/simple_animal/babyKiwi/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -489,7 +501,7 @@
|
||||
|
||||
AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
|
||||
/mob/living/simple_animal/babyKiwi/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/babyKiwi/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!stat && !ckey)
|
||||
@@ -557,3 +569,4 @@
|
||||
maxHealth = 75
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
footstep_type = FOOTSTEP_MOB_SHOE
|
||||
vocal_bark_id = "mutedc4"
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
footstep_type = FOOTSTEP_MOB_CLAW
|
||||
|
||||
vocal_bark_id = "bullet"
|
||||
vocal_speed = 2
|
||||
vocal_pitch = 1.6
|
||||
vocal_pitch_range = 0.4
|
||||
|
||||
/mob/living/simple_animal/pet/fox/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/mob_holder, "fox")
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
var/chew_probability = 1
|
||||
faction = list("rat")
|
||||
vocal_bark_id = "squeak"
|
||||
vocal_pitch = 1.4
|
||||
|
||||
/mob/living/simple_animal/mouse/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
pressure_resistance = 200
|
||||
vocal_bark_id = "squeak"
|
||||
vocal_pitch_range = 0.4
|
||||
|
||||
/mob/living/simple_animal/pet/plushie/ComponentInitialize()
|
||||
. = ..()
|
||||
@@ -72,7 +74,7 @@
|
||||
qdel(src)
|
||||
|
||||
//low regen over time
|
||||
/mob/living/simple_animal/pet/plushie/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/pet/plushie/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(health < maxHealth)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
var/charging = 0
|
||||
var/atom/movable/screen/alert/chargealert
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/charger/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/guardian/charger/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(ranged_cooldown <= world.time)
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/dextrous/examine(mob/user)
|
||||
if(dextrous)
|
||||
. = list("<span class='info'>*---------*\nThis is [icon2html(src)] \a <b>[src]</b>!\n[desc]")
|
||||
. = list("<span class='info'>This is [icon2html(src)] \a <b>[src]</b>!\n[desc]")
|
||||
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.item_flags & ABSTRACT))
|
||||
. += "It has [I.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(I))]."
|
||||
if(internal_storage && !(internal_storage.item_flags & ABSTRACT))
|
||||
. += "It is holding [internal_storage.get_examine_string(user)] in its internal storage."
|
||||
. += "*---------*</span>"
|
||||
. += "</span>"
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Crowd control modules activated. Holoparasite swarm online.</span>"
|
||||
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught one! OH GOD, EVERYTHING'S ON FIRE. Except you and the fish.</span>"
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/fire/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/guardian/fire/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(summoner)
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
attack_verb_continuous = "slaps"
|
||||
attack_verb_simple = "slap"
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/butter/BiologicalLife(seconds, times_fired) //Heals butter bear really fast when he takes damage.
|
||||
/mob/living/simple_animal/hostile/bear/butter/BiologicalLife(delta_time, times_fired) //Heals butter bear really fast when he takes damage.
|
||||
if(stat)
|
||||
return
|
||||
if(health < maxHealth)
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
if(regen_amount)
|
||||
regen_cooldown = world.time + REGENERATION_DELAY
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/carp/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(regen_amount && regen_cooldown < world.time)
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
foes = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
walk(src, 0) //stops walking
|
||||
return
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
deathmessage = "vanishes into thin air! It was a fake!"
|
||||
has_field_of_vision = FALSE //not meant to be played anyway.
|
||||
|
||||
/mob/living/simple_animal/hostile/illusion/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/illusion/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(world.time > life_span)
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
if(!hopping)
|
||||
Hop()
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
update_icons()
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_CLAW
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(target && ranged_cooldown > world.time && iscarbon(target))
|
||||
|
||||
@@ -89,7 +89,7 @@ Difficulty: Normal
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/spawn_crusher_loot()
|
||||
new /obj/item/crusher_trophy/vortex_talisman(get_turf(spawned_beacon))
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(spawned_beacon && !QDELETED(spawned_beacon) && !client)
|
||||
@@ -500,6 +500,8 @@ Difficulty: Normal
|
||||
var/obj/item/projectile/P = mover
|
||||
if(P.firer == caster)
|
||||
return TRUE
|
||||
if(mover != caster)
|
||||
return FALSE
|
||||
if(mover == caster)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
|
||||
step(R, ddir) //Step the swarmers, instead of spawning them there, incase the turf is solid
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
var/createtype = GetUncappedAISwarmerType()
|
||||
|
||||
@@ -118,7 +118,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
|
||||
overlay_googly_eyes = FALSE
|
||||
CopyObject(copy, creator, destroy_original)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/mimic/copy/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(idledamage && !target && !ckey) //Objects eventually revert to normal if no one is around to terrorize
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
wanted_objects = list(/obj/item/pen/survival, /obj/item/stack/ore/diamond)
|
||||
field_of_vision_type = FOV_270_DEGREES //Obviously, it's one eyeball.
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(stat == CONSCIOUS)
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@
|
||||
if(CALL_CHILDREN)
|
||||
call_children()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/broodmother/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/broodmother/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(health < maxHealth * 0.5 && rand_tent < world.time)
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
if(AOE_SQUARES)
|
||||
aoe_squares(target)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/pandora/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/pandora/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(health >= maxHealth * 0.5)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_HEAVY
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
handle_preattack()
|
||||
@@ -129,7 +129,7 @@
|
||||
var/turf/last_location
|
||||
var/tentacle_recheck_cooldown = 100
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(isturf(loc))
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
name = "guthen"
|
||||
gender = FEMALE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(udder.reagents.total_volume == udder.reagents.maximum_volume) //Only breed when we're full.
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
swarming = TRUE
|
||||
var/can_infest_dead = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(isturf(loc))
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
SLEEP_CHECK_DEATH(8)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_demon/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_demon/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(target)
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
var/list/burn_turfs = getline(src, T) - get_turf(src)
|
||||
dragon_fire_line(src, burn_turfs)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(target)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
aggressive_message_said = TRUE
|
||||
rapid_melee = 2
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(target)
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
retreat_message_said = TRUE
|
||||
retreat_distance = 30
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(target)
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
else
|
||||
. += "<span class='info'>It looks like it's been roughed up.</span>"
|
||||
|
||||
/mob/living/simple_animal/hostile/mushroom/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/mushroom/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!stat)//Mushrooms slowly regenerate if conscious, for people who want to save them from being eaten
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
var/chosen_sound = pick(migo_sounds)
|
||||
playsound(src, chosen_sound, 100, TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/netherworld/migo/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/netherworld/migo/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(stat)
|
||||
|
||||
@@ -86,7 +86,7 @@ GLOBAL_LIST_EMPTY(plague_rats)
|
||||
walk_to(src, entry_vent)
|
||||
break
|
||||
|
||||
/mob/living/simple_animal/hostile/plaguerat/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/plaguerat/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(isopenturf(loc))
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
..()
|
||||
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(banana_time && banana_time < world.time)
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/statue/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!client && target) // If we have a target and we're AI controlled
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
del_on_death = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/tree/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/tree/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(isopenturf(loc))
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/ghost_playable
|
||||
playable_plant = TRUE //For admins that want to buss some harmless plants
|
||||
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
pull_vines()
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
QDEL_NULL(E)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/fugu/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/asteroid/fugu/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!wumbo)
|
||||
|
||||
@@ -44,6 +44,10 @@
|
||||
emote_hear = list("squawks.","bawks!")
|
||||
emote_see = list("flutters its wings.")
|
||||
|
||||
vocal_bark_id = "banjoc4"
|
||||
vocal_pitch = 1.4
|
||||
vocal_pitch_range = 0.4
|
||||
|
||||
speak_chance = 1 //1% (1 in 100) chance every tick; So about once per 150 seconds, assuming an average tick is 1.5s
|
||||
turns_per_move = 5
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/cracker/ = 1)
|
||||
@@ -80,7 +84,7 @@
|
||||
var/speech_shuffle_rate = 20
|
||||
var/list/available_channels = list()
|
||||
|
||||
//Headset for Poly to yell at engineers :)
|
||||
//Headset for Polly to yell at engineers :)
|
||||
var/obj/item/radio/headset/ears = null
|
||||
/// spawns with headset
|
||||
var/spawns_with_headset = FALSE
|
||||
@@ -345,7 +349,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
parrot_state |= PARROT_FLEE
|
||||
icon_state = icon_living
|
||||
drop_held_item(0)
|
||||
else if(istype(O, /obj/item/reagent_containers/food/snacks/cracker)) //Poly wants a cracker.
|
||||
else if(istype(O, /obj/item/reagent_containers/food/snacks/cracker)) //Polly wants a cracker.
|
||||
qdel(O)
|
||||
if(health < maxHealth)
|
||||
adjustBruteLoss(-10)
|
||||
@@ -372,7 +376,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
/*
|
||||
* AI - Not really intelligent, but I'm calling it AI anyway.
|
||||
*/
|
||||
/mob/living/simple_animal/parrot/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/parrot/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
//Sprite update for when a parrot gets pulled
|
||||
@@ -890,10 +894,10 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
/*
|
||||
* Sub-types
|
||||
*/
|
||||
/mob/living/simple_animal/parrot/Poly
|
||||
name = "Poly"
|
||||
desc = "Poly the Parrot. An expert on quantum cracker theory."
|
||||
speak = list("Poly wanna cracker!", ":e Check the crystal, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS ABOUT TO DELAMINATE CALL THE SHUTTLE")
|
||||
/mob/living/simple_animal/parrot/Polly
|
||||
name = "Polly"
|
||||
desc = "Polly the Parrot. An expert on quantum cracker theory."
|
||||
speak = list("Polly wanna cracker!", ":e Check the crystal, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS ABOUT TO DELAMINATE CALL THE SHUTTLE")
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
speak_chance = 3
|
||||
spawns_with_headset = TRUE
|
||||
@@ -902,7 +906,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
var/longest_survival = 0
|
||||
var/longest_deathstreak = 0
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/Initialize(mapload)
|
||||
/mob/living/simple_animal/parrot/Polly/Initialize(mapload)
|
||||
ears = new /obj/item/radio/headset/headset_eng(src)
|
||||
available_channels = list(":e")
|
||||
Read_Memory()
|
||||
@@ -910,11 +914,13 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
speak += pick("...[longest_survival].", "The things I've seen!", "I have lived many lives!", "What are you before me?")
|
||||
desc += " Old as sin, and just as loud. Claimed to be [rounds_survived]."
|
||||
speak_chance = 20 //His hubris has made him more annoying/easier to justify killing
|
||||
add_atom_colour("#EEEE22", FIXED_COLOUR_PRIORITY)
|
||||
if(!color)
|
||||
add_atom_colour("#EEEE22", FIXED_COLOUR_PRIORITY)
|
||||
else if(rounds_survived == longest_deathstreak)
|
||||
speak += pick("What are you waiting for!", "Violence breeds violence!", "Blood! Blood!", "Strike me down if you dare!")
|
||||
desc += " The squawks of [-rounds_survived] dead parrots ring out in your ears..."
|
||||
add_atom_colour("#BB7777", FIXED_COLOUR_PRIORITY)
|
||||
if(!color)
|
||||
add_atom_colour("#BB7777", FIXED_COLOUR_PRIORITY)
|
||||
else if(rounds_survived > 0)
|
||||
speak += pick("...again?", "No, It was over!", "Let me out!", "It never ends!")
|
||||
desc += " Over [rounds_survived] shifts without a \"terrible\" \"accident\"!"
|
||||
@@ -923,30 +929,31 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
|
||||
/mob/living/simple_animal/parrot/Polly/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
|
||||
. = ..()
|
||||
if(. && !client && prob(1) && prob(1)) //Only the one true bird may speak across dimensions.
|
||||
world.TgsTargetedChatBroadcast("A stray squawk is heard... \"[message]\"", FALSE)
|
||||
if(. && !client && prob(1) && prob(1) && CONFIG_GET(string/chat_squawk_tag)) //Only the one true bird may speak across dimensions.
|
||||
send2chat("A stray squawk is heard... \"[message]\"", CONFIG_GET(string/chat_squawk_tag))
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/parrot/Polly/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
Write_Memory(FALSE)
|
||||
memory_saved = TRUE
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/death(gibbed)
|
||||
/mob/living/simple_animal/parrot/Polly/death(gibbed)
|
||||
if(!memory_saved)
|
||||
Write_Memory(TRUE)
|
||||
if(rounds_survived == longest_survival || rounds_survived == longest_deathstreak || prob(0.666))
|
||||
var/mob/living/simple_animal/parrot/Poly/ghost/G = new(loc)
|
||||
var/mob/living/simple_animal/parrot/Polly/ghost/G = new(loc)
|
||||
if(mind)
|
||||
mind.transfer_to(G)
|
||||
else
|
||||
transfer_ckey(G)
|
||||
..(gibbed)
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/proc/Read_Memory()
|
||||
/mob/living/simple_animal/parrot/Polly/proc/Read_Memory()
|
||||
var/saved_color
|
||||
if(fexists("data/npc_saves/Poly.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Poly.sav")
|
||||
S["phrases"] >> speech_buffer
|
||||
@@ -963,10 +970,13 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
rounds_survived = json["roundssurvived"]
|
||||
longest_survival = json["longestsurvival"]
|
||||
longest_deathstreak = json["longestdeathstreak"]
|
||||
saved_color = json["color"]
|
||||
if(!islist(speech_buffer))
|
||||
speech_buffer = list()
|
||||
if(!isnull(saved_color))
|
||||
add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY)
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/proc/Write_Memory(dead)
|
||||
/mob/living/simple_animal/parrot/Polly/proc/Write_Memory(dead)
|
||||
var/json_file = file("data/npc_saves/Poly.json")
|
||||
var/list/file_data = list()
|
||||
if(islist(speech_buffer))
|
||||
@@ -978,6 +988,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
file_data["longestdeathstreak"] = rounds_survived - 1
|
||||
else
|
||||
file_data["longestdeathstreak"] = longest_deathstreak
|
||||
file_data["color"] = null
|
||||
else
|
||||
file_data["roundssurvived"] = rounds_survived + 1
|
||||
if(rounds_survived + 1 > longest_survival)
|
||||
@@ -985,17 +996,21 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
else
|
||||
file_data["longestsurvival"] = longest_survival
|
||||
file_data["longestdeathstreak"] = longest_deathstreak
|
||||
if(color)
|
||||
file_data["color"] = json_encode(color)
|
||||
else
|
||||
file_data["color"] = null
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/ratvar_act()
|
||||
/mob/living/simple_animal/parrot/Polly/ratvar_act()
|
||||
playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 75, TRUE)
|
||||
var/mob/living/simple_animal/parrot/clock_hawk/H = new(loc)
|
||||
H.setDir(dir)
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/ghost
|
||||
name = "The Ghost of Poly"
|
||||
/mob/living/simple_animal/parrot/Polly/ghost
|
||||
name = "The Ghost of Polly"
|
||||
desc = "Doomed to squawk the Earth."
|
||||
color = "#FFFFFF"
|
||||
alpha = 77
|
||||
@@ -1004,16 +1019,16 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
incorporeal_move = INCORPOREAL_MOVE_BASIC
|
||||
butcher_results = list(/obj/item/ectoplasm = 1)
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/ghost/Initialize(mapload)
|
||||
/mob/living/simple_animal/parrot/Polly/ghost/Initialize(mapload)
|
||||
memory_saved = TRUE //At this point nothing is saved
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/ghost/handle_automated_speech()
|
||||
/mob/living/simple_animal/parrot/Polly/ghost/handle_automated_speech()
|
||||
if(ismob(loc))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/ghost/handle_automated_movement()
|
||||
/mob/living/simple_animal/parrot/Polly/ghost/handle_automated_movement()
|
||||
if(isliving(parrot_interest))
|
||||
if(!ishuman(parrot_interest))
|
||||
parrot_interest = null
|
||||
@@ -1022,7 +1037,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
Possess(parrot_interest)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/ghost/proc/Possess(mob/living/carbon/human/H)
|
||||
/mob/living/simple_animal/parrot/Polly/ghost/proc/Possess(mob/living/carbon/human/H)
|
||||
if(!ishuman(H))
|
||||
return
|
||||
var/datum/disease/parrot_possession/P = new
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
length += emote_see.len
|
||||
var/randomValue = rand(1,length)
|
||||
if(randomValue <= speak.len)
|
||||
say(pick(speak), forced = "poly")
|
||||
say(pick(speak), forced = "polly")
|
||||
else
|
||||
randomValue -= speak.len
|
||||
if(emote_see && randomValue <= emote_see.len)
|
||||
@@ -233,7 +233,7 @@
|
||||
else
|
||||
emote("me [pick(emote_hear)]", 2)
|
||||
else
|
||||
say(pick(speak), forced = "poly")
|
||||
say(pick(speak), forced = "polly")
|
||||
else
|
||||
if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len))
|
||||
emote("me", EMOTE_VISIBLE, pick(emote_see))
|
||||
@@ -482,7 +482,7 @@
|
||||
update_action_buttons_icon()
|
||||
return mobility_flags
|
||||
|
||||
/mob/living/simple_animal/update_transform()
|
||||
/mob/living/simple_animal/update_transform(do_animate)
|
||||
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
|
||||
var/changed = 0
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
/datum/emote/slime/mood/run_emote(mob/user, params)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/mob/living/simple_animal/slime/S = user
|
||||
S.mood = mood
|
||||
S.regenerate_icons()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
typing_indicator_state = /obj/effect/overlay/typing_indicator/slime
|
||||
|
||||
/mob/living/simple_animal/slime/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/slime/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(buckled)
|
||||
|
||||
@@ -421,7 +421,7 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/slime/examine(mob/user)
|
||||
. = list("<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <EM>[src]</EM>!")
|
||||
. = list("<span class='info'>This is [icon2html(src, user)] \a <EM>[src]</EM>!")
|
||||
if (src.stat == DEAD)
|
||||
. += "<span class='deadsay'>It is limp and unresponsive.</span>"
|
||||
else
|
||||
@@ -446,7 +446,7 @@
|
||||
if(10)
|
||||
. += "<span class='warning'><B>It is radiating with massive levels of electrical activity!</B></span>"
|
||||
|
||||
. += "*---------*</span>"
|
||||
. += "</span>"
|
||||
|
||||
/mob/living/simple_animal/slime/proc/discipline_slime(mob/user)
|
||||
if(stat)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
|
||||
/mob/living/update_transform()
|
||||
/mob/living/update_transform(do_animate = TRUE)
|
||||
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
|
||||
var/final_pixel_y = pixel_y
|
||||
var/changed = 0
|
||||
@@ -21,5 +21,9 @@
|
||||
resize = RESIZE_DEFAULT_SIZE
|
||||
|
||||
if(changed)
|
||||
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, easing = EASE_IN|EASE_OUT)
|
||||
if(do_animate)
|
||||
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, easing = EASE_IN|EASE_OUT, flags = ANIMATION_PARALLEL)
|
||||
else
|
||||
transform = ntransform
|
||||
pixel_y = final_pixel_y
|
||||
floating_need_update = TRUE
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
return
|
||||
hearers -= ignored_mobs
|
||||
|
||||
if(target_message && target && istype(target) && target.client)
|
||||
if(target_message && target && istype(target) && (target.client || target.audiovisual_redirect))
|
||||
hearers -= target
|
||||
if(omni)
|
||||
target.show_message(target_message)
|
||||
@@ -155,7 +155,7 @@
|
||||
if(self_message)
|
||||
hearers -= src
|
||||
for(var/mob/M in hearers)
|
||||
if(!M.client)
|
||||
if(!M.client && !M.audiovisual_redirect)
|
||||
continue
|
||||
if(omni)
|
||||
M.show_message(message)
|
||||
@@ -330,7 +330,7 @@
|
||||
else
|
||||
result = A.examine(src) // if a tree is examined but no client is there to see it, did the tree ever really exist?
|
||||
|
||||
to_chat(src, result.Join("\n"))
|
||||
to_chat(src, "<blockquote class='info'>[result.Join("\n")]</blockquote>")
|
||||
SEND_SIGNAL(src, COMSIG_MOB_EXAMINATE, A)
|
||||
|
||||
/mob/proc/clear_from_recent_examines(atom/A)
|
||||
|
||||
@@ -229,22 +229,38 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
return copytext_char(sanitize(.),1,MAX_MESSAGE_LEN)
|
||||
|
||||
/proc/shake_camera(mob/M, duration, strength=1)
|
||||
if(!M || !M.client || duration < 1)
|
||||
set waitfor = FALSE
|
||||
if(!M || !M.client || duration <= 0)
|
||||
return
|
||||
var/client/C = M.client
|
||||
if (C.prefs.screenshake==0)
|
||||
return
|
||||
var/oldx = C.pixel_x
|
||||
var/oldy = C.pixel_y
|
||||
var/max = strength*world.icon_size
|
||||
var/min = -(strength*world.icon_size)
|
||||
var/clientscreenshake = (C.prefs.screenshake * 0.01)
|
||||
var/max = (strength*clientscreenshake) * world.icon_size
|
||||
var/min = -((strength*clientscreenshake) * world.icon_size)
|
||||
var/roundedduration = -round(-duration) // round() with only one arg will always round down. so uh. this is Something all right
|
||||
|
||||
for(var/i in 0 to duration-1)
|
||||
for(var/i in 0 to roundedduration-1)
|
||||
duration--
|
||||
if (i == 0)
|
||||
animate(C, pixel_x=rand(min,max), pixel_y=rand(min,max), time=1)
|
||||
animate(C, pixel_x=(rand(min,max)*duration), pixel_y=(rand(min,max)*duration), time=1)
|
||||
else
|
||||
animate(pixel_x=rand(min,max), pixel_y=rand(min,max), time=1)
|
||||
animate(pixel_x=oldx, pixel_y=oldy, time=1)
|
||||
|
||||
|
||||
/proc/directional_recoil(mob/M, strength=1, angle = 0)
|
||||
if(!M || !M.client)
|
||||
return
|
||||
var/client/C = M.client
|
||||
var/client_screenshake = (C.prefs.recoil_screenshake * 0.01)
|
||||
strength *= client_screenshake
|
||||
var/recoil_x = -sin(angle)*4*strength + rand(-strength, strength)
|
||||
var/recoil_y = -cos(angle)*4*strength + rand(-strength, strength)
|
||||
animate(C, pixel_x=recoil_x, pixel_y=recoil_y, time=1, easing=SINE_EASING|EASE_OUT, flags=ANIMATION_PARALLEL|ANIMATION_RELATIVE)
|
||||
animate(pixel_x=0, pixel_y=0, time=3, easing=SINE_EASING|EASE_IN) // according to bhjin this works on more recent byond versions
|
||||
// if you havent updated uuh sucks to be you then
|
||||
|
||||
/proc/findname(msg)
|
||||
if(!istext(msg))
|
||||
|
||||
Reference in New Issue
Block a user