Merge branch 'master' into upstream-merge-31037
This commit is contained in:
@@ -11,7 +11,7 @@ INITIALIZE_IMMEDIATE(/mob/dead)
|
||||
|
||||
prepare_huds()
|
||||
|
||||
if(config.cross_allowed)
|
||||
if(CONFIG_GET(string/cross_server_address))
|
||||
verbs += /mob/dead/proc/server_hop
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
@@ -32,19 +32,20 @@ INITIALIZE_IMMEDIATE(/mob/dead)
|
||||
set desc= "Jump to the other server"
|
||||
if(notransform)
|
||||
return
|
||||
if(!config.cross_allowed)
|
||||
var/csa = CONFIG_GET(string/cross_server_address)
|
||||
if(csa)
|
||||
verbs -= /mob/dead/proc/server_hop
|
||||
to_chat(src, "<span class='notice'>Server Hop has been disabled.</span>")
|
||||
return
|
||||
if (alert(src, "Jump to server running at [config.cross_address]?", "Server Hop", "Yes", "No") != "Yes")
|
||||
if (alert(src, "Jump to server running at [csa]?", "Server Hop", "Yes", "No") != "Yes")
|
||||
return 0
|
||||
if (client && config.cross_allowed)
|
||||
to_chat(src, "<span class='notice'>Sending you to [config.cross_address].</span>")
|
||||
if (client && csa)
|
||||
to_chat(src, "<span class='notice'>Sending you to [csa].</span>")
|
||||
new /obj/screen/splash(client)
|
||||
notransform = TRUE
|
||||
sleep(29) //let the animation play
|
||||
notransform = FALSE
|
||||
winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources
|
||||
client << link(config.cross_address + "?server_hop=[key]")
|
||||
client << link(csa + "?server_hop=[key]")
|
||||
else
|
||||
to_chat(src, "<span class='error'>There is no other server configured!</span>")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/dead/new_player/Login()
|
||||
if(config.use_exp_tracking)
|
||||
if(CONFIG_GET(flag/use_exp_tracking))
|
||||
client.set_exp_from_db()
|
||||
client.set_db_player_flags()
|
||||
if(!mind)
|
||||
@@ -15,8 +15,9 @@
|
||||
if(GLOB.admin_notice)
|
||||
to_chat(src, "<span class='notice'><b>Admin Notice:</b>\n \t [GLOB.admin_notice]</span>")
|
||||
|
||||
if(config.soft_popcap && living_player_count() >= config.soft_popcap)
|
||||
to_chat(src, "<span class='notice'><b>Server Notice:</b>\n \t [config.soft_popcap_message]</span>")
|
||||
var/spc = CONFIG_GET(number/soft_popcap)
|
||||
if(spc && living_player_count() >= spc)
|
||||
to_chat(src, "<span class='notice'><b>Server Notice:</b>\n \t [CONFIG_GET(string/soft_popcap_message)]</span>")
|
||||
|
||||
sight |= SEE_TURFS
|
||||
|
||||
@@ -32,10 +33,10 @@
|
||||
new_player_panel()
|
||||
client.playtitlemusic()
|
||||
if(SSticker.current_state < GAME_STATE_SETTING_UP)
|
||||
var/tl = round(SSticker.GetTimeLeft(), 1)/10
|
||||
var/tl = SSticker.GetTimeLeft()
|
||||
var/postfix
|
||||
if(tl >= 0)
|
||||
postfix = "in about [tl] seconds"
|
||||
if(tl > 0)
|
||||
postfix = "in about [DisplayTimeText(tl)]"
|
||||
else
|
||||
postfix = "soon"
|
||||
to_chat(src, "Please set up your character and select \"Ready\". The game will start [postfix].")
|
||||
|
||||
@@ -97,10 +97,12 @@
|
||||
|
||||
//Determines Relevent Population Cap
|
||||
var/relevant_cap
|
||||
if(config.hard_popcap && config.extreme_popcap)
|
||||
relevant_cap = min(config.hard_popcap, config.extreme_popcap)
|
||||
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(config.hard_popcap, config.extreme_popcap)
|
||||
relevant_cap = max(hpc, epc)
|
||||
|
||||
if(href_list["show_preferences"])
|
||||
client.prefs.ShowChoices(src)
|
||||
@@ -133,7 +135,7 @@
|
||||
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.hard_popcap_message]</span>")
|
||||
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)
|
||||
@@ -309,7 +311,7 @@
|
||||
return 0
|
||||
if(job.required_playtime_remaining(client))
|
||||
return 0
|
||||
if(config.enforce_human_authority && !client.prefs.pref_species.qualifies_for_rank(rank, client.prefs.features))
|
||||
if(CONFIG_GET(flag/enforce_human_authority) && !client.prefs.pref_species.qualifies_for_rank(rank, client.prefs.features))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -326,11 +328,11 @@
|
||||
var/arrivals_docked = TRUE
|
||||
if(SSshuttle.arrivals)
|
||||
close_spawn_windows() //In case we get held up
|
||||
if(SSshuttle.arrivals.damaged && config.arrivals_shuttle_require_safe_latejoin)
|
||||
if(SSshuttle.arrivals.damaged && CONFIG_GET(flag/arrivals_shuttle_require_safe_latejoin))
|
||||
src << alert("The arrivals shuttle is currently malfunctioning! You cannot join.")
|
||||
return FALSE
|
||||
|
||||
if(config.arrivals_shuttle_require_undocked)
|
||||
if(CONFIG_GET(flag/arrivals_shuttle_require_undocked))
|
||||
SSshuttle.arrivals.RequireUndocked(src)
|
||||
arrivals_docked = SSshuttle.arrivals.mode != SHUTTLE_CALL
|
||||
|
||||
@@ -374,7 +376,7 @@
|
||||
GLOB.joined_player_list += character.ckey
|
||||
GLOB.latejoiners += character
|
||||
|
||||
if(config.allow_latejoin_antagonists && humanc) //Borgs aren't allowed to be antags. Will need to be tweaked if we get true latejoin ais.
|
||||
if(CONFIG_GET(flag/allow_latejoin_antagonists) && humanc) //Borgs aren't allowed to be antags. Will need to be tweaked if we get true latejoin ais.
|
||||
if(SSshuttle.emergency)
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_RECALL, SHUTTLE_IDLE)
|
||||
@@ -458,7 +460,7 @@
|
||||
|
||||
var/mob/living/carbon/human/H = new(loc)
|
||||
|
||||
if(config.force_random_names || jobban_isbanned(src, "appearance"))
|
||||
if(CONFIG_GET(flag/force_random_names) || jobban_isbanned(src, "appearance"))
|
||||
client.prefs.random_character()
|
||||
client.prefs.real_name = client.prefs.pref_species.random_name(gender,1)
|
||||
client.prefs.copy_to(H)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
facial_hair_color = hair_color
|
||||
eye_color = random_eye_color()
|
||||
if(!pref_species)
|
||||
var/rando_race = pick(config.roundstart_races)
|
||||
var/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
|
||||
pref_species = new rando_race()
|
||||
features = random_features()
|
||||
age = rand(AGE_MIN,AGE_MAX)
|
||||
|
||||
@@ -199,6 +199,8 @@
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The MMI indicates the brain is active.</span>")
|
||||
|
||||
/obj/item/device/mmi/relaymove()
|
||||
return //so that the MMI won't get a warning about not being able to move if it tries to move
|
||||
|
||||
/obj/item/device/mmi/syndie
|
||||
name = "Syndicate Man-Machine Interface"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
/mob/living/brain/proc/create_dna()
|
||||
stored_dna = new /datum/dna/stored(src)
|
||||
if(!stored_dna.species)
|
||||
var/rando_race = pick(config.roundstart_races)
|
||||
var/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
|
||||
stored_dna.species = new rando_race()
|
||||
|
||||
/mob/living/brain/Destroy()
|
||||
|
||||
@@ -10,15 +10,15 @@ Doesn't work on other aliens/AI.*/
|
||||
name = "Alien Power"
|
||||
panel = "Alien"
|
||||
var/plasma_cost = 0
|
||||
var/check_turf = 0
|
||||
var/has_action = 1
|
||||
var/datum/action/spell_action/alien/action = null
|
||||
var/action_icon = 'icons/mob/actions/actions_xeno.dmi'
|
||||
var/action_icon_state = "spell_default"
|
||||
var/action_background_icon_state = "bg_alien"
|
||||
var/check_turf = FALSE
|
||||
has_action = TRUE
|
||||
datum/action/spell_action/alien/action
|
||||
action_icon = 'icons/mob/actions/actions_xeno.dmi'
|
||||
action_icon_state = "spell_default"
|
||||
action_background_icon_state = "bg_alien"
|
||||
|
||||
/obj/effect/proc_holder/alien/New()
|
||||
..()
|
||||
/obj/effect/proc_holder/alien/Initialize()
|
||||
. = ..()
|
||||
action = new(src)
|
||||
|
||||
/obj/effect/proc_holder/alien/Click()
|
||||
@@ -30,15 +30,20 @@ Doesn't work on other aliens/AI.*/
|
||||
user.adjustPlasma(-plasma_cost)
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/alien/proc/on_gain(mob/living/carbon/user)
|
||||
/obj/effect/proc_holder/alien/on_gain(mob/living/carbon/user)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/alien/proc/on_lose(mob/living/carbon/user)
|
||||
/obj/effect/proc_holder/alien/on_lose(mob/living/carbon/user)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/alien/proc/fire(mob/living/carbon/user)
|
||||
/obj/effect/proc_holder/alien/fire(mob/living/carbon/user)
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/alien/get_panel_text()
|
||||
. = ..()
|
||||
if(plasma_cost > 0)
|
||||
return "[plasma_cost]"
|
||||
|
||||
/obj/effect/proc_holder/alien/proc/cost_check(check_turf=0,mob/living/carbon/user,silent = 0)
|
||||
if(user.stat)
|
||||
if(!silent)
|
||||
@@ -168,7 +173,6 @@ Doesn't work on other aliens/AI.*/
|
||||
if(user.getPlasma() > A.plasma_cost && A.corrode(O))
|
||||
user.adjustPlasma(-A.plasma_cost)
|
||||
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin
|
||||
name = "Spit Neurotoxin"
|
||||
desc = "Spits neurotoxin at someone, paralyzing them for a short time."
|
||||
@@ -179,7 +183,7 @@ Doesn't work on other aliens/AI.*/
|
||||
var/message
|
||||
if(active)
|
||||
message = "<span class='notice'>You empty your neurotoxin gland.</span>"
|
||||
remove_ranged_ability(user,message)
|
||||
remove_ranged_ability(message)
|
||||
else
|
||||
message = "<span class='notice'>You prepare your neurotoxin gland. <B>Left-click to fire at a target!</B></span>"
|
||||
add_ranged_ability(user, message, TRUE)
|
||||
@@ -193,7 +197,7 @@ Doesn't work on other aliens/AI.*/
|
||||
return
|
||||
var/p_cost = 50
|
||||
if(!iscarbon(ranged_ability_user) || ranged_ability_user.lying || ranged_ability_user.stat)
|
||||
remove_ranged_ability(ranged_ability_user)
|
||||
remove_ranged_ability()
|
||||
return
|
||||
|
||||
var/mob/living/carbon/user = ranged_ability_user
|
||||
@@ -219,8 +223,7 @@ Doesn't work on other aliens/AI.*/
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/on_lose(mob/living/carbon/user)
|
||||
if(user.ranged_ability == src)
|
||||
user.ranged_ability = null
|
||||
remove_ranged_ability()
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/add_ranged_ability(mob/living/user, msg)
|
||||
..()
|
||||
@@ -328,7 +331,3 @@ Doesn't work on other aliens/AI.*/
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
/proc/cmp_abilities_cost(obj/effect/proc_holder/alien/a, obj/effect/proc_holder/alien/b)
|
||||
return b.plasma_cost - a.plasma_cost
|
||||
|
||||
@@ -1,124 +1,126 @@
|
||||
/mob/living/carbon/alien/humanoid
|
||||
name = "alien"
|
||||
icon_state = "alien"
|
||||
pass_flags = PASSTABLE
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
|
||||
limb_destroyer = 1
|
||||
var/obj/item/r_store = null
|
||||
var/obj/item/l_store = null
|
||||
var/caste = ""
|
||||
var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files.
|
||||
var/leap_on_click = 0
|
||||
var/pounce_cooldown = 0
|
||||
var/pounce_cooldown_time = 30
|
||||
var/custom_pixel_x_offset = 0 //for admin fuckery.
|
||||
var/custom_pixel_y_offset = 0
|
||||
var/sneaking = 0 //For sneaky-sneaky mode and appropriate slowdown
|
||||
var/drooling = 0 //For Neruotoxic spit overlays
|
||||
bodyparts = list(/obj/item/bodypart/chest/alien, /obj/item/bodypart/head/alien, /obj/item/bodypart/l_arm/alien,
|
||||
/obj/item/bodypart/r_arm/alien, /obj/item/bodypart/r_leg/alien, /obj/item/bodypart/l_leg/alien)
|
||||
devourable = TRUE
|
||||
|
||||
|
||||
//This is fine right now, if we're adding organ specific damage this needs to be updated
|
||||
/mob/living/carbon/alien/humanoid/Initialize()
|
||||
AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
|
||||
. = ..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/movement_delay()
|
||||
. = ..()
|
||||
. += move_delay_add + config.alien_delay + sneaking //move_delay_add is used to slow aliens with stun
|
||||
|
||||
/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
|
||||
. = handcuffed
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/list/dat = list()
|
||||
dat += {"
|
||||
<HR>
|
||||
<B><FONT size=3>[name]</FONT></B>
|
||||
<HR>"}
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags_1 & ABSTRACT_1)) ? I : "<font color=grey>Empty</font>"]</a>"
|
||||
dat += "<BR><A href='?src=\ref[src];pouches=1'>Empty Pouches</A>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<BR><A href='?src=\ref[src];item=[slot_handcuffed]'>Handcuffed</A>"
|
||||
if(legcuffed)
|
||||
dat += "<BR><A href='?src=\ref[src];item=[slot_legcuffed]'>Legcuffed</A>"
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
user << browse(dat.Join(), "window=mob\ref[src];size=325x500")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/Topic(href, href_list)
|
||||
..()
|
||||
//strip panel
|
||||
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
|
||||
if(href_list["pouches"])
|
||||
visible_message("<span class='danger'>[usr] tries to empty [src]'s pouches.</span>", \
|
||||
"<span class='userdanger'>[usr] tries to empty [src]'s pouches.</span>")
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY * 0.5))
|
||||
dropItemToGround(r_store)
|
||||
dropItemToGround(l_store)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
|
||||
playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
|
||||
..(I, cuff_break = INSTANT_CUFFBREAK)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/resist_grab(moving_resist)
|
||||
if(pulledby.grab_state)
|
||||
visible_message("<span class='danger'>[src] has broken free of [pulledby]'s grip!</span>")
|
||||
pulledby.stop_pulling()
|
||||
. = 0
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0)
|
||||
if(leaping)
|
||||
return -32
|
||||
else if(custom_pixel_y_offset)
|
||||
return custom_pixel_y_offset
|
||||
else
|
||||
return initial(pixel_y)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_standard_pixel_x_offset(lying = 0)
|
||||
if(leaping)
|
||||
return -32
|
||||
else if(custom_pixel_x_offset)
|
||||
return custom_pixel_x_offset
|
||||
else
|
||||
return initial(pixel_x)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_permeability_protection()
|
||||
return 0.8
|
||||
|
||||
/mob/living/carbon/alien/humanoid/alien_evolve(mob/living/carbon/alien/humanoid/new_xeno)
|
||||
drop_all_held_items()
|
||||
for(var/atom/movable/A in stomach_contents)
|
||||
stomach_contents.Remove(A)
|
||||
new_xeno.stomach_contents.Add(A)
|
||||
A.loc = new_xeno
|
||||
..()
|
||||
|
||||
//For alien evolution/promotion/queen finder procs. Checks for an active alien of that type
|
||||
/proc/get_alien_type(var/alienpath)
|
||||
for(var/mob/living/carbon/alien/humanoid/A in GLOB.living_mob_list)
|
||||
if(!istype(A, alienpath))
|
||||
continue
|
||||
if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid.
|
||||
continue
|
||||
return A
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath)
|
||||
if(breath && breath.total_moles() > 0 && !sneaking)
|
||||
playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5)
|
||||
..()
|
||||
/mob/living/carbon/alien/humanoid
|
||||
name = "alien"
|
||||
icon_state = "alien"
|
||||
pass_flags = PASSTABLE
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
|
||||
limb_destroyer = 1
|
||||
var/obj/item/r_store = null
|
||||
var/obj/item/l_store = null
|
||||
var/caste = ""
|
||||
var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files.
|
||||
var/leap_on_click = 0
|
||||
var/pounce_cooldown = 0
|
||||
var/pounce_cooldown_time = 30
|
||||
var/custom_pixel_x_offset = 0 //for admin fuckery.
|
||||
var/custom_pixel_y_offset = 0
|
||||
var/sneaking = 0 //For sneaky-sneaky mode and appropriate slowdown
|
||||
var/drooling = 0 //For Neruotoxic spit overlays
|
||||
bodyparts = list(/obj/item/bodypart/chest/alien, /obj/item/bodypart/head/alien, /obj/item/bodypart/l_arm/alien,
|
||||
/obj/item/bodypart/r_arm/alien, /obj/item/bodypart/r_leg/alien, /obj/item/bodypart/l_leg/alien)
|
||||
|
||||
|
||||
//This is fine right now, if we're adding organ specific damage this needs to be updated
|
||||
/mob/living/carbon/alien/humanoid/Initialize()
|
||||
AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
|
||||
. = ..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/movement_delay()
|
||||
. = ..()
|
||||
var/static/config_alien_delay
|
||||
if(isnull(config_alien_delay))
|
||||
config_alien_delay = CONFIG_GET(number/alien_delay)
|
||||
. += move_delay_add + config_alien_delay + sneaking //move_delay_add is used to slow aliens with stun
|
||||
|
||||
/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
|
||||
. = handcuffed
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/list/dat = list()
|
||||
dat += {"
|
||||
<HR>
|
||||
<B><FONT size=3>[name]</FONT></B>
|
||||
<HR>"}
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags_1 & ABSTRACT_1)) ? I : "<font color=grey>Empty</font>"]</a>"
|
||||
dat += "<BR><A href='?src=\ref[src];pouches=1'>Empty Pouches</A>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<BR><A href='?src=\ref[src];item=[slot_handcuffed]'>Handcuffed</A>"
|
||||
if(legcuffed)
|
||||
dat += "<BR><A href='?src=\ref[src];item=[slot_legcuffed]'>Legcuffed</A>"
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
user << browse(dat.Join(), "window=mob\ref[src];size=325x500")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/Topic(href, href_list)
|
||||
..()
|
||||
//strip panel
|
||||
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
|
||||
if(href_list["pouches"])
|
||||
visible_message("<span class='danger'>[usr] tries to empty [src]'s pouches.</span>", \
|
||||
"<span class='userdanger'>[usr] tries to empty [src]'s pouches.</span>")
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY * 0.5))
|
||||
dropItemToGround(r_store)
|
||||
dropItemToGround(l_store)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
|
||||
playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
|
||||
..(I, cuff_break = INSTANT_CUFFBREAK)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/resist_grab(moving_resist)
|
||||
if(pulledby.grab_state)
|
||||
visible_message("<span class='danger'>[src] has broken free of [pulledby]'s grip!</span>")
|
||||
pulledby.stop_pulling()
|
||||
. = 0
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0)
|
||||
if(leaping)
|
||||
return -32
|
||||
else if(custom_pixel_y_offset)
|
||||
return custom_pixel_y_offset
|
||||
else
|
||||
return initial(pixel_y)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_standard_pixel_x_offset(lying = 0)
|
||||
if(leaping)
|
||||
return -32
|
||||
else if(custom_pixel_x_offset)
|
||||
return custom_pixel_x_offset
|
||||
else
|
||||
return initial(pixel_x)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_permeability_protection()
|
||||
return 0.8
|
||||
|
||||
/mob/living/carbon/alien/humanoid/alien_evolve(mob/living/carbon/alien/humanoid/new_xeno)
|
||||
drop_all_held_items()
|
||||
for(var/atom/movable/A in stomach_contents)
|
||||
stomach_contents.Remove(A)
|
||||
new_xeno.stomach_contents.Add(A)
|
||||
A.loc = new_xeno
|
||||
..()
|
||||
|
||||
//For alien evolution/promotion/queen finder procs. Checks for an active alien of that type
|
||||
/proc/get_alien_type(var/alienpath)
|
||||
for(var/mob/living/carbon/alien/humanoid/A in GLOB.living_mob_list)
|
||||
if(!istype(A, alienpath))
|
||||
continue
|
||||
if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid.
|
||||
continue
|
||||
return A
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath)
|
||||
if(breath && breath.total_moles() > 0 && !sneaking)
|
||||
playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5)
|
||||
..()
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
if(L.handcuffed || L.legcuffed) // Cuffing larvas ? Eh ?
|
||||
to_chat(user, "<span class='danger'>You cannot evolve when you are cuffed.</span>")
|
||||
return
|
||||
|
||||
if(L.amount_grown >= L.max_grown) //TODO ~Carn
|
||||
to_chat(L, "<span class='name'>You are growing into a beautiful alien! It is time to choose a caste.</span>")
|
||||
|
||||
@@ -425,23 +425,6 @@
|
||||
var/turf/target = get_turf(loc)
|
||||
I.throw_at(target,I.throw_range,I.throw_speed,src)
|
||||
|
||||
/mob/living/carbon/proc/AddAbility(obj/effect/proc_holder/alien/A)
|
||||
abilities.Add(A)
|
||||
A.on_gain(src)
|
||||
if(A.has_action)
|
||||
A.action.Grant(src)
|
||||
sortInsert(abilities, /proc/cmp_abilities_cost, 0)
|
||||
|
||||
/mob/living/carbon/proc/RemoveAbility(obj/effect/proc_holder/alien/A)
|
||||
abilities.Remove(A)
|
||||
A.on_lose(src)
|
||||
if(A.action)
|
||||
A.action.Remove(src)
|
||||
|
||||
/mob/living/carbon/proc/add_abilities_to_panel()
|
||||
for(var/obj/effect/proc_holder/alien/A in abilities)
|
||||
statpanel("[A.panel]",A.plasma_cost > 0?"([A.plasma_cost])":"",A)
|
||||
|
||||
/mob/living/carbon/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
has_limbs = 1
|
||||
var/obj/item/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab
|
||||
|
||||
var/list/obj/effect/proc_holder/alien/abilities = list()
|
||||
var/gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
|
||||
var/rotate_on_lying = 1
|
||||
|
||||
@@ -311,7 +311,7 @@
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH, /obj/item/organ/cyberimp/eyes/hud/medical))
|
||||
var/cyberimp_detect
|
||||
for(var/obj/item/organ/cyberimp/CI in internal_organs)
|
||||
if(CI.status == ORGAN_ROBOTIC)
|
||||
if(CI.status == ORGAN_ROBOTIC && !CI.syndicate_implant)
|
||||
cyberimp_detect += "[name] is modified with a [CI.name].<br>"
|
||||
if(cyberimp_detect)
|
||||
msg += "Detected cybernetic modifications:<br>"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
. = 0
|
||||
. += ..()
|
||||
. += config.human_delay
|
||||
. += dna.species.movement_delay(src)
|
||||
var/static/config_human_delay
|
||||
if(isnull(config_human_delay))
|
||||
config_human_delay = CONFIG_GET(number/human_delay)
|
||||
. += ..() + config_human_delay + dna.species.movement_delay(src)
|
||||
|
||||
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
|
||||
if(isobj(shoes) && (shoes.flags_1&NOSLIP_1) && !(lube&GALOSHES_DONT_HELP))
|
||||
|
||||
@@ -586,6 +586,57 @@
|
||||
H.adjustFireLoss(-4)
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
|
||||
/datum/species/golem/clockwork
|
||||
name = "Clockwork Golem"
|
||||
id = "clockwork golem"
|
||||
say_mod = "clicks"
|
||||
limbs_id = "clockgolem"
|
||||
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>clockwork golem</span><span class='bold alloy'>, you are faster than \
|
||||
other types of golem (being a machine), and are immune to electric shocks.</span>"
|
||||
species_traits = list(NO_UNDERWEAR, NOTRANSSTING, NOBREATH, NOZOMBIE, VIRUSIMMUNE, RADIMMUNE, NOBLOOD, RESISTCOLD, RESISTPRESSURE)
|
||||
armor = 40 //Reinforced, but also slim to allow for fast movement
|
||||
attack_verb = "smash"
|
||||
attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg'
|
||||
sexes = FALSE
|
||||
speedmod = 0
|
||||
siemens_coeff = 0
|
||||
damage_overlay_type = "synth"
|
||||
prefix = "Clockwork"
|
||||
var/has_corpse
|
||||
|
||||
/datum/species/golem/clockwork/on_species_gain(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
H.faction |= "ratvar"
|
||||
|
||||
/datum/species/golem/clockwork/on_species_loss(mob/living/carbon/human/H)
|
||||
if(!is_servant_of_ratvar(H))
|
||||
H.faction -= "ratvar"
|
||||
. = ..()
|
||||
|
||||
/datum/species/golem/clockwork/get_spans()
|
||||
return SPAN_ROBOT //beep
|
||||
|
||||
/datum/species/golem/clockwork/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
gibbed = !has_corpse ? FALSE : gibbed
|
||||
. = ..()
|
||||
if(!has_corpse)
|
||||
var/turf/T = get_turf(H)
|
||||
H.visible_message("<span class='warning'>[H]'s exoskeleton shatters, collapsing into a heap of scrap!</span>")
|
||||
playsound(H, 'sound/magic/clockwork/anima_fragment_death.ogg', 50, TRUE)
|
||||
for(var/i in 1 to rand(3, 5))
|
||||
new/obj/item/clockwork/alloy_shards/small(T)
|
||||
new/obj/item/clockwork/alloy_shards/clockgolem_remains(T)
|
||||
qdel(H)
|
||||
|
||||
/datum/species/golem/clockwork/no_scrap //These golems are created through the herald's beacon and leave normal corpses on death.
|
||||
id = "clockwork golem servant"
|
||||
armor = 15 //Balance reasons make this armor weak
|
||||
no_equip = list()
|
||||
nojumpsuit = FALSE
|
||||
has_corpse = TRUE
|
||||
blacklisted = TRUE
|
||||
dangerous_existence = TRUE
|
||||
|
||||
/datum/species/golem/cloth
|
||||
name = "Cloth Golem"
|
||||
id = "cloth golem"
|
||||
|
||||
@@ -412,8 +412,9 @@
|
||||
liver_failure()
|
||||
else
|
||||
liver.failing = FALSE
|
||||
|
||||
if(((!(NOLIVER in dna.species.species_traits)) && (!liver)))
|
||||
else
|
||||
if((dna && dna.species && (NOLIVER in dna.species.species_traits)))
|
||||
return
|
||||
liver_failure()
|
||||
|
||||
/mob/living/carbon/proc/undergoing_liver_failure()
|
||||
|
||||
@@ -62,7 +62,11 @@
|
||||
|
||||
if (bodytemperature < 283.222)
|
||||
. += (283.222 - bodytemperature) / 10 * 1.75
|
||||
return . + config.monkey_delay
|
||||
|
||||
var/static/config_monkey_delay
|
||||
if(isnull(config_monkey_delay))
|
||||
config_monkey_delay = CONFIG_GET(number/monkey_delay)
|
||||
. += config_monkey_delay
|
||||
|
||||
/mob/living/carbon/monkey/Stat()
|
||||
..()
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
/mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
bruteloss = Clamp((bruteloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
bruteloss = Clamp((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
@@ -168,7 +168,7 @@
|
||||
/mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
oxyloss = Clamp((oxyloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
oxyloss = Clamp((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
@@ -187,7 +187,7 @@
|
||||
/mob/living/proc/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
toxloss = Clamp((toxloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
toxloss = Clamp((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
@@ -206,7 +206,7 @@
|
||||
/mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
fireloss = Clamp((fireloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
fireloss = Clamp((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
@@ -217,7 +217,7 @@
|
||||
/mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
cloneloss = Clamp((cloneloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
cloneloss = Clamp((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
@@ -236,7 +236,7 @@
|
||||
/mob/living/proc/adjustBrainLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
brainloss = Clamp((brainloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
brainloss = Clamp((brainloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
|
||||
/mob/living/proc/setBrainLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
|
||||
@@ -412,7 +412,7 @@
|
||||
set category = "OOC"
|
||||
set src in view()
|
||||
|
||||
if(config.allow_Metadata)
|
||||
if(CONFIG_GET(flag/allow_metadata))
|
||||
if(client)
|
||||
to_chat(src, "[src]'s Metainfo:<br>[client.prefs.metadata]")
|
||||
else
|
||||
@@ -464,16 +464,21 @@
|
||||
if(isopenturf(loc) && !is_flying())
|
||||
var/turf/open/T = loc
|
||||
. += T.slowdown
|
||||
var/static/config_run_delay
|
||||
var/static/config_walk_delay
|
||||
if(isnull(config_run_delay))
|
||||
config_run_delay = CONFIG_GET(number/run_delay)
|
||||
config_walk_delay = CONFIG_GET(number/walk_delay)
|
||||
if(ignorewalk)
|
||||
. += config.run_speed
|
||||
. += config_run_delay
|
||||
else
|
||||
switch(m_intent)
|
||||
if(MOVE_INTENT_RUN)
|
||||
if(drowsyness > 0)
|
||||
. += 6
|
||||
. += config.run_speed
|
||||
. += config_run_delay
|
||||
if(MOVE_INTENT_WALK)
|
||||
. += config.walk_speed
|
||||
. += config_walk_delay
|
||||
|
||||
/mob/living/proc/makeTrail(turf/target_turf, turf/start, direction)
|
||||
if(!has_gravity())
|
||||
@@ -982,3 +987,19 @@
|
||||
client.move_delay = world.time + movement_delay()
|
||||
lying_prev = lying
|
||||
return canmove
|
||||
|
||||
/mob/living/proc/AddAbility(obj/effect/proc_holder/A)
|
||||
abilities.Add(A)
|
||||
A.on_gain(src)
|
||||
if(A.has_action)
|
||||
A.action.Grant(src)
|
||||
|
||||
/mob/living/proc/RemoveAbility(obj/effect/proc_holder/A)
|
||||
abilities.Remove(A)
|
||||
A.on_lose(src)
|
||||
if(A.action)
|
||||
A.action.Remove(src)
|
||||
|
||||
/mob/living/proc/add_abilities_to_panel()
|
||||
for(var/obj/effect/proc_holder/A in abilities)
|
||||
statpanel("[A.panel]",A.get_panel_text(),A)
|
||||
@@ -77,3 +77,5 @@
|
||||
var/datum/language/selected_default_language
|
||||
|
||||
var/last_words //used for database logging
|
||||
|
||||
var/list/obj/effect/proc_holder/abilities = list()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
return "[radio_freq ? " (" + speaker.GetJob() + ")" : ""]" + "[speaker.GetSource() ? "</a>" : ""]"
|
||||
|
||||
/mob/living/silicon/ai/IsVocal()
|
||||
return !config.silent_ai
|
||||
return !CONFIG_GET(flag/silent_ai)
|
||||
|
||||
/mob/living/silicon/ai/radio(message, message_mode, list/spans, language)
|
||||
if(incapacitated())
|
||||
|
||||
@@ -211,9 +211,9 @@
|
||||
"MediHound" = /obj/item/robot_module/medihound, \
|
||||
"Security K9" = /obj/item/robot_module/k9, \
|
||||
"Scrub Puppy" = /obj/item/robot_module/scrubpup)
|
||||
if(!config.forbid_peaceborg)
|
||||
if(!CONFIG_GET(flag/disable_peaceborg))
|
||||
modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper
|
||||
if(!config.forbid_secborg)
|
||||
if(!CONFIG_GET(flag/disable_secborg))
|
||||
modulelist["Security"] = /obj/item/robot_module/security
|
||||
|
||||
var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in modulelist
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,8 +5,10 @@
|
||||
|
||||
/mob/living/silicon/robot/movement_delay()
|
||||
. = ..()
|
||||
. += speed
|
||||
. += config.robot_delay
|
||||
var/static/config_robot_delay
|
||||
if(isnull(config_robot_delay))
|
||||
config_robot_delay = CONFIG_GET(number/robot_delay)
|
||||
. += speed + config_robot_delay
|
||||
|
||||
/mob/living/silicon/robot/mob_negates_gravity()
|
||||
return magpulse
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
/mob/living/silicon/robot/IsVocal()
|
||||
return !config.silent_borg
|
||||
return !CONFIG_GET(flag/silent_borg)
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
/mob/living/silicon/forceMove(atom/destination)
|
||||
. = ..()
|
||||
update_camera_location(destination)
|
||||
//Only bother updating the camera if we actually managed to move
|
||||
if(.)
|
||||
update_camera_location(destination)
|
||||
|
||||
/mob/living/silicon/proc/do_camera_update(oldLoc)
|
||||
if(!QDELETED(builtInCamera) && oldLoc != get_turf(src))
|
||||
|
||||
@@ -9,33 +9,33 @@
|
||||
|
||||
/mob/living/simple_animal/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(forced)
|
||||
. = adjustHealth(amount * config.damage_multiplier, updating_health, forced)
|
||||
. = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
else if(damage_coeff[BRUTE])
|
||||
. = adjustHealth(amount * damage_coeff[BRUTE] * config.damage_multiplier, updating_health, forced)
|
||||
. = adjustHealth(amount * damage_coeff[BRUTE] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
|
||||
/mob/living/simple_animal/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(forced)
|
||||
. = adjustHealth(amount * config.damage_multiplier, updating_health, forced)
|
||||
. = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
else if(damage_coeff[BURN])
|
||||
. = adjustHealth(amount * damage_coeff[BURN] * config.damage_multiplier, updating_health, forced)
|
||||
. = adjustHealth(amount * damage_coeff[BURN] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
|
||||
/mob/living/simple_animal/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(forced)
|
||||
. = adjustHealth(amount * config.damage_multiplier, updating_health, forced)
|
||||
. = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
else if(damage_coeff[OXY])
|
||||
. = adjustHealth(amount * damage_coeff[OXY] * config.damage_multiplier, updating_health, forced)
|
||||
. = adjustHealth(amount * damage_coeff[OXY] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
|
||||
/mob/living/simple_animal/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(forced)
|
||||
. = adjustHealth(amount * config.damage_multiplier, updating_health, forced)
|
||||
. = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
else if(damage_coeff[TOX])
|
||||
. = adjustHealth(amount * damage_coeff[TOX] * config.damage_multiplier, updating_health, forced)
|
||||
. = adjustHealth(amount * damage_coeff[TOX] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
|
||||
/mob/living/simple_animal/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(forced)
|
||||
. = adjustHealth(amount * config.damage_multiplier, updating_health, forced)
|
||||
. = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
else if(damage_coeff[CLONE])
|
||||
. = adjustHealth(amount * damage_coeff[CLONE] * config.damage_multiplier, updating_health, forced)
|
||||
. = adjustHealth(amount * damage_coeff[CLONE] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
|
||||
/mob/living/simple_animal/adjustStaminaLoss(amount)
|
||||
return
|
||||
|
||||
@@ -424,6 +424,41 @@
|
||||
setDir(i)
|
||||
sleep(1)
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/narsie_act()
|
||||
playsound(src, 'sound/magic/demon_dies.ogg', 75, TRUE)
|
||||
var/mob/living/simple_animal/pet/dog/corgi/narsie/N = new(loc)
|
||||
N.setDir(dir)
|
||||
gib()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/narsie
|
||||
name = "Nars-Ian"
|
||||
desc = "Ia! Ia!"
|
||||
icon_state = "narsian"
|
||||
icon_living = "narsian"
|
||||
icon_dead = "narsian_dead"
|
||||
faction = list("dog", "cult")
|
||||
gold_core_spawnable = FALSE
|
||||
nofur = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/narsie/Life()
|
||||
..()
|
||||
for(var/mob/living/simple_animal/pet/P in range(1, src))
|
||||
if(P != src && prob(5))
|
||||
visible_message("<span class='warning'>[src] devours [P]!</span>", \
|
||||
"<span class='cult big bold'>DELICIOUS SOULS</span>")
|
||||
playsound(src, 'sound/magic/demon_attack1.ogg', 75, TRUE)
|
||||
narsie_act()
|
||||
P.gib()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/narsie/update_corgi_fluff()
|
||||
..()
|
||||
speak = list("Tari'karat-pasnar!", "IA! IA!", "BRRUUURGHGHRHR")
|
||||
speak_emote = list("growls", "barks ominously")
|
||||
emote_hear = list("barks echoingly!", "woofs hauntingly!", "yaps in an eldritch manner.", "mutters something unspeakable.")
|
||||
emote_see = list("communes with the unnameable.", "ponders devouring some souls.", "shakes.")
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/narsie/narsie_act()
|
||||
adjustBruteLoss(-maxHealth)
|
||||
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/regenerate_icons()
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
/obj/item/drone_shell/attack_ghost(mob/user)
|
||||
if(jobban_isbanned(user,"drone"))
|
||||
return
|
||||
if(config.use_age_restriction_for_jobs)
|
||||
if(CONFIG_GET(flag/use_age_restriction_for_jobs))
|
||||
if(!isnum(user.client.player_age)) //apparently what happens when there's no DB connected. just don't let anybody be a drone without admin intervention
|
||||
return
|
||||
if(user.client.player_age < DRONE_MINIMUM_AGE)
|
||||
|
||||
@@ -130,9 +130,9 @@
|
||||
hacked = TRUE
|
||||
visualAppearence = CLOCKDRONE
|
||||
can_be_held = FALSE
|
||||
flavortext = "<span class='heavy_brass'>You are a cogscarab</span><b>, a clockwork creation of Ratvar. As a cogscarab, you have low health, an inbuilt fabricator that can convert brass \
|
||||
to power, a set of relatively fast tools, </b><span class='heavy_brass'>can communicate over the Hierophant Network with :b</span><b>, and are immune to extreme \
|
||||
temperatures and pressures. \nYour goal is to serve the Justiciar and his servants by repairing and defending all they create.</b>"
|
||||
flavortext = "<b><span class='nezbere'>You are a cogscarab,</span> a tiny building construct of Ratvar. While you're weak and can't recite scripture, \
|
||||
you have a set of quick tools, as well as a replica fabricator that can create brass and convert objects.<br><br>Work with the servants of Ratvar \
|
||||
to construct and maintain defenses at the City of Cogs. If there are no servants, use this time to experiment with base designs!"
|
||||
|
||||
/mob/living/simple_animal/drone/cogscarab/ratvar //a subtype for spawning when ratvar is alive, has a slab that it can use and a normal fabricator
|
||||
default_storage = /obj/item/storage/toolbox/brass/prefilled/ratvar
|
||||
|
||||
@@ -49,6 +49,17 @@
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
|
||||
var/playable_spider = FALSE
|
||||
devourable = TRUE
|
||||
var/datum/action/innate/spider/lay_web/lay_web
|
||||
var/directive = "" //Message passed down to children, to relay the creator's orders
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/Initialize()
|
||||
. = ..()
|
||||
lay_web = new
|
||||
lay_web.Grant(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/Destroy()
|
||||
QDEL_NULL(lay_web)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/Topic(href, href_list)
|
||||
if(href_list["activate"])
|
||||
@@ -56,6 +67,12 @@
|
||||
if(istype(ghost) && playable_spider)
|
||||
humanize_spider(ghost)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/Login()
|
||||
..()
|
||||
if(directive)
|
||||
to_chat(src, "<span class='notice'>Your mother left you a directive! Follow it at all costs.</span>")
|
||||
to_chat(src, "<span class='spider'><b>[directive]</b></span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/attack_ghost(mob/user)
|
||||
if(!humanize_spider(user))
|
||||
return ..()
|
||||
@@ -87,8 +104,26 @@
|
||||
poison_per_bite = 3
|
||||
var/atom/movable/cocoon_target
|
||||
var/fed = 0
|
||||
var/obj/effect/proc_holder/wrap/wrap
|
||||
var/datum/action/innate/spider/lay_eggs/lay_eggs
|
||||
var/datum/action/innate/spider/set_directive/set_directive
|
||||
var/static/list/consumed_mobs = list() //the tags of mobs that have been consumed by nurse spiders to lay eggs
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/Initialize()
|
||||
. = ..()
|
||||
wrap = new
|
||||
AddAbility(wrap)
|
||||
lay_eggs = new
|
||||
lay_eggs.Grant(src)
|
||||
set_directive = new
|
||||
set_directive.Grant(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/Destroy()
|
||||
RemoveAbility(wrap)
|
||||
QDEL_NULL(lay_eggs)
|
||||
QDEL_NULL(set_directive)
|
||||
return ..()
|
||||
|
||||
//hunters have the most poison and move the fastest, so they can find prey
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/hunter
|
||||
desc = "Furry and black, it makes you shudder to look at it. This one has sparkling purple eyes."
|
||||
@@ -162,6 +197,9 @@
|
||||
letmetalkpls = new
|
||||
letmetalkpls.Grant(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/midwife/Destroy()
|
||||
QDEL_NULL(letmetalkpls)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/ice //spiders dont usually like tempatures of 140 kelvin who knew
|
||||
name = "giant ice spider"
|
||||
@@ -225,11 +263,11 @@
|
||||
//second, spin a sticky spiderweb on this tile
|
||||
var/obj/structure/spider/stickyweb/W = locate() in get_turf(src)
|
||||
if(!W)
|
||||
Web()
|
||||
lay_web.Activate()
|
||||
else
|
||||
//third, lay an egg cluster there
|
||||
if(fed)
|
||||
LayEggs()
|
||||
lay_eggs.Activate()
|
||||
else
|
||||
//fourthly, cocoon any nearby items so those pesky pinkskins can't use them
|
||||
for(var/obj/O in can_see)
|
||||
@@ -247,62 +285,28 @@
|
||||
|
||||
else if(busy == MOVING_TO_TARGET && cocoon_target)
|
||||
if(get_dist(src, cocoon_target) <= 1)
|
||||
Wrap()
|
||||
cocoon()
|
||||
|
||||
else
|
||||
busy = SPIDER_IDLE
|
||||
stop_automated_movement = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/verb/Web()
|
||||
set name = "Lay Web"
|
||||
set category = "Spider"
|
||||
set desc = "Spread a sticky web to slow down prey."
|
||||
|
||||
var/T = src.loc
|
||||
|
||||
if(stat == DEAD)
|
||||
return
|
||||
if(busy != SPINNING_WEB)
|
||||
busy = SPINNING_WEB
|
||||
src.visible_message("<span class='notice'>\the [src] begins to secrete a sticky substance.</span>")
|
||||
stop_automated_movement = 1
|
||||
if(do_after(src, 40, target = T))
|
||||
if(busy == SPINNING_WEB && src.loc == T)
|
||||
new /obj/structure/spider/stickyweb(T)
|
||||
busy = SPIDER_IDLE
|
||||
stop_automated_movement = FALSE
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/verb/Wrap()
|
||||
set name = "Wrap"
|
||||
set category = "Spider"
|
||||
set desc = "Wrap up prey to feast upon and objects for safe keeping."
|
||||
|
||||
if(stat == DEAD)
|
||||
return
|
||||
if(!cocoon_target)
|
||||
var/list/choices = list()
|
||||
for(var/mob/living/L in view(1,src))
|
||||
if(L == src || L.anchored)
|
||||
continue
|
||||
if(istype(L, /mob/living/simple_animal/hostile/poison/giant_spider))
|
||||
continue
|
||||
if(Adjacent(L))
|
||||
choices += L
|
||||
for(var/obj/O in src.loc)
|
||||
if(O.anchored)
|
||||
continue
|
||||
if(Adjacent(O))
|
||||
choices += O
|
||||
var/temp_input = input(src,"What do you wish to cocoon?") in null|choices
|
||||
if(temp_input && !cocoon_target)
|
||||
cocoon_target = temp_input
|
||||
|
||||
if(stat != DEAD && cocoon_target && Adjacent(cocoon_target) && !cocoon_target.anchored)
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/proc/cocoon()
|
||||
if(stat != DEAD && cocoon_target && !cocoon_target.anchored)
|
||||
if(cocoon_target == src)
|
||||
to_chat(src, "<span class='warning'>You can't wrap yourself!</span>")
|
||||
return
|
||||
if(istype(cocoon_target, /mob/living/simple_animal/hostile/poison/giant_spider))
|
||||
to_chat(src, "<span class='warning'>You can't wrap other spiders!</span>")
|
||||
return
|
||||
if(!Adjacent(cocoon_target))
|
||||
to_chat(src, "<span class='warning'>You can't reach [cocoon_target]!</span>")
|
||||
return
|
||||
if(busy == SPINNING_COCOON)
|
||||
to_chat(src, "<span class='warning'>You're already spinning a cocoon!</span>")
|
||||
return //we're already doing this, don't cancel out or anything
|
||||
busy = SPINNING_COCOON
|
||||
visible_message("<span class='notice'>\the [src] begins to secrete a sticky substance around \the [cocoon_target].</span>")
|
||||
visible_message("<span class='notice'>[src] begins to secrete a sticky substance around [cocoon_target].</span>","<span class='notice'>You begin wrapping [cocoon_target] into a cocoon.</span>")
|
||||
stop_automated_movement = TRUE
|
||||
walk(src,0)
|
||||
if(do_after(src, 50, target = cocoon_target))
|
||||
@@ -313,7 +317,8 @@
|
||||
if(L.blood_volume && (L.stat != DEAD || !consumed_mobs[L.tag])) //if they're not dead, you can consume them anyway
|
||||
consumed_mobs[L.tag] = TRUE
|
||||
fed++
|
||||
visible_message("<span class='danger'>\the [src] sticks a proboscis into \the [L] and sucks a viscous substance out.</span>")
|
||||
lay_eggs.UpdateButtonIcon(TRUE)
|
||||
visible_message("<span class='danger'>[src] sticks a proboscis into [L] and sucks a viscous substance out.</span>","<span class='notice'>You suck the nutriment out of [L], feeding you enough to lay a cluster of eggs.</span>")
|
||||
L.death() //you just ate them, they're dead.
|
||||
else
|
||||
to_chat(src, "<span class='warning'>[L] cannot sate your hunger!</span>")
|
||||
@@ -325,35 +330,155 @@
|
||||
busy = SPIDER_IDLE
|
||||
stop_automated_movement = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/verb/LayEggs()
|
||||
set name = "Lay Eggs"
|
||||
set category = "Spider"
|
||||
set desc = "Lay a clutch of eggs, but you must wrap a creature for feeding first."
|
||||
/datum/action/innate/spider
|
||||
icon_icon = 'icons/mob/actions/actions_animal.dmi'
|
||||
background_icon_state = "bg_alien"
|
||||
|
||||
var/obj/structure/spider/eggcluster/E = locate() in get_turf(src)
|
||||
if(stat == DEAD)
|
||||
/datum/action/innate/spider/lay_web
|
||||
name = "Spin Web"
|
||||
desc = "Spin a web to slow down potential prey."
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
button_icon_state = "lay_web"
|
||||
|
||||
/datum/action/innate/spider/lay_web/Activate()
|
||||
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
|
||||
return
|
||||
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/S = owner
|
||||
|
||||
if(!isturf(S.loc))
|
||||
return
|
||||
var/turf/T = get_turf(S)
|
||||
|
||||
var/obj/structure/spider/stickyweb/W = locate() in T
|
||||
if(W)
|
||||
to_chat(S, "<span class='warning'>There's already a web here!</span>")
|
||||
return
|
||||
|
||||
if(S.busy != SPINNING_WEB)
|
||||
S.busy = SPINNING_WEB
|
||||
S.visible_message("<span class='notice'>[S] begins to secrete a sticky substance.</span>","<span class='notice'>You begin to lay a web.</span>")
|
||||
S.stop_automated_movement = TRUE
|
||||
if(do_after(S, 40, target = T))
|
||||
if(S.busy == SPINNING_WEB && S.loc == T)
|
||||
new /obj/structure/spider/stickyweb(T)
|
||||
S.busy = SPIDER_IDLE
|
||||
S.stop_automated_movement = FALSE
|
||||
else
|
||||
to_chat(S, "<span class='warning'>You're already spinning a web!</span>")
|
||||
|
||||
/obj/effect/proc_holder/wrap
|
||||
name = "Wrap"
|
||||
panel = "Spider"
|
||||
active = FALSE
|
||||
datum/action/spell_action/action = null
|
||||
desc = "Wrap something or someone in a cocoon. If it's a living being, you'll also consume them, allowing you to lay eggs."
|
||||
ranged_mousepointer = 'icons/effects/wrap_target.dmi'
|
||||
action_icon = 'icons/mob/actions/actions_animal.dmi'
|
||||
action_icon_state = "wrap_0"
|
||||
action_background_icon_state = "bg_alien"
|
||||
|
||||
/obj/effect/proc_holder/wrap/Initialize()
|
||||
. = ..()
|
||||
action = new(src)
|
||||
|
||||
/obj/effect/proc_holder/wrap/update_icon()
|
||||
action.button_icon_state = "wrap_[active]"
|
||||
action.UpdateButtonIcon()
|
||||
|
||||
/obj/effect/proc_holder/wrap/Click()
|
||||
if(!istype(usr, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
|
||||
return TRUE
|
||||
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/user = usr
|
||||
activate(user)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/wrap/proc/activate(mob/living/user)
|
||||
var/message
|
||||
if(active)
|
||||
message = "<span class='notice'>You no longer prepare to wrap something in a cocoon.</span>"
|
||||
remove_ranged_ability(message)
|
||||
else
|
||||
message = "<span class='notice'>You prepare to wrap something in a cocoon. <B>Left-click your target to start wrapping!</B></span>"
|
||||
add_ranged_ability(user, message, TRUE)
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/wrap/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
if(..())
|
||||
return
|
||||
if(ranged_ability_user.incapacitated() || !istype(ranged_ability_user, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
|
||||
remove_ranged_ability()
|
||||
return
|
||||
|
||||
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/user = ranged_ability_user
|
||||
|
||||
if(user.Adjacent(target) && (ismob(target) || isobj(target)))
|
||||
var/atom/movable/target_atom = target
|
||||
if(target_atom.anchored)
|
||||
return
|
||||
user.cocoon_target = target_atom
|
||||
INVOKE_ASYNC(user, /mob/living/simple_animal/hostile/poison/giant_spider/nurse/.proc/cocoon)
|
||||
remove_ranged_ability()
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/wrap/on_lose(mob/living/carbon/user)
|
||||
remove_ranged_ability()
|
||||
|
||||
/datum/action/innate/spider/lay_eggs
|
||||
name = "Lay Eggs"
|
||||
desc = "Lay a cluster of eggs, which will soon grow into more spiders. You must wrap a living being to do this."
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
button_icon_state = "lay_eggs"
|
||||
|
||||
/datum/action/innate/spider/lay_eggs/IsAvailable()
|
||||
if(..())
|
||||
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
|
||||
return 0
|
||||
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/S = owner
|
||||
if(S.fed)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/action/innate/spider/lay_eggs/Activate()
|
||||
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
|
||||
return
|
||||
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/S = owner
|
||||
|
||||
var/obj/structure/spider/eggcluster/E = locate() in get_turf(S)
|
||||
if(E)
|
||||
to_chat(src, "<span class='warning'>There is already a cluster of eggs here!</span>")
|
||||
else if(!fed)
|
||||
to_chat(src, "<span class='warning'>You are too hungry to do this!</span>")
|
||||
else if(busy != LAYING_EGGS)
|
||||
busy = LAYING_EGGS
|
||||
src.visible_message("<span class='notice'>\the [src] begins to lay a cluster of eggs.</span>")
|
||||
stop_automated_movement = 1
|
||||
if(do_after(src, 50, target = src.loc))
|
||||
if(busy == LAYING_EGGS)
|
||||
E = locate() in get_turf(src)
|
||||
if(!E)
|
||||
var/obj/structure/spider/eggcluster/C = new /obj/structure/spider/eggcluster(src.loc)
|
||||
if(ckey)
|
||||
C.player_spiders = 1
|
||||
C.poison_type = poison_type
|
||||
C.poison_per_bite = poison_per_bite
|
||||
C.faction = faction.Copy()
|
||||
fed--
|
||||
busy = SPIDER_IDLE
|
||||
stop_automated_movement = FALSE
|
||||
to_chat(S, "<span class='warning'>There is already a cluster of eggs here!</span>")
|
||||
else if(!S.fed)
|
||||
to_chat(S, "<span class='warning'>You are too hungry to do this!</span>")
|
||||
else if(S.busy != LAYING_EGGS)
|
||||
S.busy = LAYING_EGGS
|
||||
S.visible_message("<span class='notice'>[S] begins to lay a cluster of eggs.</span>","<span class='notice'>You begin to lay a cluster of eggs.</span>")
|
||||
S.stop_automated_movement = TRUE
|
||||
if(do_after(S, 50, target = get_turf(S)))
|
||||
if(S.busy == LAYING_EGGS)
|
||||
E = locate() in get_turf(S)
|
||||
if(!E || !isturf(S.loc))
|
||||
var/obj/structure/spider/eggcluster/C = new /obj/structure/spider/eggcluster(get_turf(S))
|
||||
if(S.ckey)
|
||||
C.player_spiders = TRUE
|
||||
C.directive = S.directive
|
||||
C.poison_type = S.poison_type
|
||||
C.poison_per_bite = S.poison_per_bite
|
||||
C.faction = S.faction.Copy()
|
||||
S.fed--
|
||||
UpdateButtonIcon(TRUE)
|
||||
S.busy = SPIDER_IDLE
|
||||
S.stop_automated_movement = FALSE
|
||||
|
||||
/datum/action/innate/spider/set_directive
|
||||
name = "Set Directive"
|
||||
desc = "Set a directive for your children to follow."
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
button_icon_state = "directive"
|
||||
|
||||
/datum/action/innate/spider/set_directive/Activate()
|
||||
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
|
||||
return
|
||||
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/S = owner
|
||||
S.directive = stripped_input(S, "Enter the new directive", "Create directive", "[S.directive]", MAX_MESSAGE_LEN)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/Login()
|
||||
. = ..()
|
||||
@@ -365,7 +490,8 @@
|
||||
|
||||
/datum/action/innate/spider/comm
|
||||
name = "Command"
|
||||
button_icon_state = "cult_comms"
|
||||
desc = "Send a command to all living spiders."
|
||||
button_icon_state = "command"
|
||||
|
||||
/datum/action/innate/spider/comm/IsAvailable()
|
||||
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse/midwife))
|
||||
@@ -373,19 +499,22 @@
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/spider/comm/Trigger()
|
||||
var/input = stripped_input(usr, "Input a message for your legions to follow.", "Command", "")
|
||||
var/input = stripped_input(owner, "Input a command for your legions to follow.", "Command", "")
|
||||
if(QDELETED(src) || !input || !IsAvailable())
|
||||
return FALSE
|
||||
spider_command(usr, input)
|
||||
spider_command(owner, input)
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/spider/comm/proc/spider_command(mob/living/user, message)
|
||||
if(!message)
|
||||
return
|
||||
var/my_message
|
||||
my_message = "<FONT size = 3><b>COMMAND FROM SPIDER QUEEN:</b> [message]</FONT>"
|
||||
my_message = "<span class='spider'><b>Command from [user]:</b> [message]</span>"
|
||||
for(var/mob/living/simple_animal/hostile/poison/giant_spider/M in GLOB.spidermobs)
|
||||
to_chat(M, my_message)
|
||||
for(var/M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, user)
|
||||
to_chat(M, "[link] [my_message]")
|
||||
log_talk(user, "SPIDERCOMMAND: [key_name(user)] : [message]",LOGSAY)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/handle_temperature_damage()
|
||||
|
||||
@@ -164,6 +164,7 @@ Difficulty: Medium
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
var/storm_type = /datum/weather/ash_storm
|
||||
var/storm_cooldown = 0
|
||||
var/static/list/excluded_areas = list(/area/reebe/city_of_cogs)
|
||||
|
||||
/obj/item/staff/storm/attack_self(mob/user)
|
||||
if(storm_cooldown > world.time)
|
||||
@@ -171,6 +172,9 @@ Difficulty: Medium
|
||||
return
|
||||
|
||||
var/area/user_area = get_area(user)
|
||||
if(user_area.type in excluded_areas)
|
||||
to_chat(user, "<span class='warning'>Something is preventing you from using the staff here.</span>")
|
||||
return
|
||||
var/datum/weather/A
|
||||
for(var/V in SSweather.existing_weather)
|
||||
var/datum/weather/W = V
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
if(admin_spawned)
|
||||
return FALSE
|
||||
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
if(MedalsAvailable())
|
||||
for(var/mob/living/L in view(7,src))
|
||||
if(L.stat)
|
||||
continue
|
||||
@@ -147,10 +147,10 @@
|
||||
set waitfor = FALSE
|
||||
if(!player || !medal)
|
||||
return
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
var/result = world.SetMedal(medal, player, global.medal_hub, global.medal_pass)
|
||||
if(MedalsAvailable())
|
||||
var/result = world.SetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
|
||||
if(isnull(result))
|
||||
global.medals_enabled = FALSE
|
||||
GLOB.medals_enabled = FALSE
|
||||
log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.ckey]")
|
||||
message_admins("Error! Failed to contact hub to award [medal] medal to [player.ckey]!")
|
||||
else if (result)
|
||||
@@ -161,9 +161,8 @@
|
||||
set waitfor = FALSE
|
||||
if(!score || !player)
|
||||
return
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
if(MedalsAvailable())
|
||||
var/list/oldscore = GetScore(score,player,1)
|
||||
|
||||
if(increment)
|
||||
if(!oldscore[score])
|
||||
oldscore[score] = 1
|
||||
@@ -174,10 +173,10 @@
|
||||
|
||||
var/newscoreparam = list2params(oldscore)
|
||||
|
||||
var/result = world.SetScores(player.ckey, newscoreparam, global.medal_hub, global.medal_pass)
|
||||
var/result = world.SetScores(player.ckey, newscoreparam, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
|
||||
|
||||
if(isnull(result))
|
||||
global.medals_enabled = FALSE
|
||||
GLOB.medals_enabled = FALSE
|
||||
log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.ckey]")
|
||||
message_admins("Error! Failed to contact hub to set [score] score for [player.ckey]!")
|
||||
|
||||
@@ -186,11 +185,11 @@
|
||||
|
||||
if(!score || !player)
|
||||
return
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
if(MedalsAvailable())
|
||||
|
||||
var/scoreget = world.GetScores(player.ckey, score, global.medal_hub, global.medal_pass)
|
||||
var/scoreget = world.GetScores(player.ckey, score, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
|
||||
if(isnull(scoreget))
|
||||
global.medals_enabled = FALSE
|
||||
GLOB.medals_enabled = FALSE
|
||||
log_game("SCORE ERROR: Could not contact hub to get score. Score:[score] player:[player.ckey]")
|
||||
message_admins("Error! Failed to contact hub to get score: [score] for [player.ckey]!")
|
||||
return
|
||||
@@ -207,12 +206,12 @@
|
||||
|
||||
if(!player || !medal)
|
||||
return
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
if(MedalsAvailable())
|
||||
|
||||
var/result = world.GetMedal(medal, player, global.medal_hub, global.medal_pass)
|
||||
var/result = world.GetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
|
||||
|
||||
if(isnull(result))
|
||||
global.medals_enabled = FALSE
|
||||
GLOB.medals_enabled = FALSE
|
||||
log_game("MEDAL ERROR: Could not contact hub to get medal:[medal] player:[player.ckey]")
|
||||
message_admins("Error! Failed to contact hub to get [medal] medal for [player.ckey]!")
|
||||
else if (result)
|
||||
@@ -222,12 +221,12 @@
|
||||
|
||||
if(!player || !medal)
|
||||
return
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
if(MedalsAvailable())
|
||||
|
||||
var/result = world.ClearMedal(medal, player, global.medal_hub, global.medal_pass)
|
||||
var/result = world.ClearMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
|
||||
|
||||
if(isnull(result))
|
||||
global.medals_enabled = FALSE
|
||||
GLOB.medals_enabled = FALSE
|
||||
log_game("MEDAL ERROR: Could not contact hub to clear medal:[medal] player:[player.ckey]")
|
||||
message_admins("Error! Failed to contact hub to clear [medal] medal for [player.ckey]!")
|
||||
else if (result)
|
||||
@@ -237,6 +236,9 @@
|
||||
|
||||
|
||||
/proc/ClearScore(client/player)
|
||||
world.SetScores(player.ckey, "", global.medal_hub, global.medal_pass)
|
||||
world.SetScores(player.ckey, "", CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
|
||||
|
||||
/proc/MedalsAvailable()
|
||||
return CONFIG_GET(string/medal_hub_address) && CONFIG_GET(string/medal_hub_password) && GLOB.medals_enabled
|
||||
|
||||
#undef MEDAL_PREFIX
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
last_tendril = FALSE
|
||||
break
|
||||
if(last_tendril && !admin_spawned)
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
if(MedalsAvailable())
|
||||
for(var/mob/living/L in view(7,src))
|
||||
if(L.stat)
|
||||
continue
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
icon_state = "parrot_fly"
|
||||
icon_living = "parrot_fly"
|
||||
icon_dead = "parrot_dead"
|
||||
var/icon_sit = "parrot_sit"
|
||||
density = FALSE
|
||||
health = 80
|
||||
maxHealth = 80
|
||||
@@ -284,7 +285,7 @@
|
||||
return
|
||||
if(!stat && M.a_intent == INTENT_HARM)
|
||||
|
||||
icon_state = "parrot_fly" //It is going to be flying regardless of whether it flees or attacks
|
||||
icon_state = icon_living //It is going to be flying regardless of whether it flees or attacks
|
||||
|
||||
if(parrot_state == PARROT_PERCH)
|
||||
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
|
||||
@@ -320,7 +321,7 @@
|
||||
if(M.melee_damage_upper > 0 && !stat)
|
||||
parrot_interest = M
|
||||
parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless
|
||||
icon_state = "parrot_fly"
|
||||
icon_state = icon_living
|
||||
|
||||
//Mobs with objects
|
||||
/mob/living/simple_animal/parrot/attackby(obj/item/O, mob/living/user, params)
|
||||
@@ -335,7 +336,7 @@
|
||||
parrot_state |= PARROT_ATTACK
|
||||
else
|
||||
parrot_state |= PARROT_FLEE
|
||||
icon_state = "parrot_fly"
|
||||
icon_state = icon_living
|
||||
drop_held_item(0)
|
||||
else if(istype(O, /obj/item/reagent_containers/food/snacks/cracker)) //Poly wants a cracker.
|
||||
qdel(O)
|
||||
@@ -358,7 +359,7 @@
|
||||
parrot_interest = null
|
||||
parrot_state = PARROT_WANDER | PARROT_FLEE //Been shot and survived! RUN LIKE HELL!
|
||||
//parrot_been_shot += 5
|
||||
icon_state = "parrot_fly"
|
||||
icon_state = icon_living
|
||||
drop_held_item(0)
|
||||
return
|
||||
|
||||
@@ -371,7 +372,7 @@
|
||||
|
||||
//Sprite update for when a parrot gets pulled
|
||||
if(pulledby && stat == CONSCIOUS)
|
||||
icon_state = "parrot_fly"
|
||||
icon_state = icon_living
|
||||
if(!client)
|
||||
parrot_state = PARROT_WANDER
|
||||
return
|
||||
@@ -400,11 +401,11 @@
|
||||
if(parrot_perch && parrot_perch.loc != src.loc) //Make sure someone hasnt moved our perch on us
|
||||
if(parrot_perch in view(src))
|
||||
parrot_state = PARROT_SWOOP | PARROT_RETURN
|
||||
icon_state = "parrot_fly"
|
||||
icon_state = icon_living
|
||||
return
|
||||
else
|
||||
parrot_state = PARROT_WANDER
|
||||
icon_state = "parrot_fly"
|
||||
icon_state = icon_living
|
||||
return
|
||||
|
||||
if(--parrot_sleep_dur) //Zzz
|
||||
@@ -445,7 +446,7 @@
|
||||
if(parrot_interest)
|
||||
emote("me", 1, "looks in [parrot_interest]'s direction and takes flight.")
|
||||
parrot_state = PARROT_SWOOP | PARROT_STEAL
|
||||
icon_state = "parrot_fly"
|
||||
icon_state = icon_living
|
||||
return
|
||||
|
||||
//-----WANDERING - This is basically a 'I dont know what to do yet' state
|
||||
@@ -530,7 +531,7 @@
|
||||
src.loc = parrot_perch.loc
|
||||
drop_held_item()
|
||||
parrot_state = PARROT_PERCH
|
||||
icon_state = "parrot_sit"
|
||||
icon_state = icon_sit
|
||||
return
|
||||
|
||||
walk_to(src, parrot_perch, 1, parrot_speed)
|
||||
@@ -603,8 +604,8 @@
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/parrot/movement_delay()
|
||||
if(client && stat == CONSCIOUS && parrot_state != "parrot_fly")
|
||||
icon_state = "parrot_fly"
|
||||
if(client && stat == CONSCIOUS && parrot_state != icon_living)
|
||||
icon_state = icon_living
|
||||
//Because the most appropriate place to set icon_state is movement_delay(), clearly
|
||||
return ..()
|
||||
|
||||
@@ -797,12 +798,12 @@
|
||||
if(stat || !client)
|
||||
return
|
||||
|
||||
if(icon_state == "parrot_fly")
|
||||
if(icon_state == icon_living)
|
||||
for(var/atom/movable/AM in view(src,1))
|
||||
for(var/perch_path in desired_perches)
|
||||
if(istype(AM, perch_path))
|
||||
src.loc = AM.loc
|
||||
icon_state = "parrot_sit"
|
||||
icon_state = icon_sit
|
||||
return
|
||||
to_chat(src, "<span class='warning'>There is no perch nearby to sit on!</span>")
|
||||
return
|
||||
@@ -816,7 +817,7 @@
|
||||
if(stat || !client)
|
||||
return
|
||||
|
||||
if(icon_state == "parrot_fly")
|
||||
if(icon_state == icon_living)
|
||||
for(var/mob/living/carbon/human/H in view(src,1))
|
||||
if(H.has_buckled_mobs() && H.buckled_mobs.len >= H.max_buckled_mobs) //Already has a parrot, or is being eaten by a slime
|
||||
continue
|
||||
@@ -824,7 +825,7 @@
|
||||
return
|
||||
to_chat(src, "<span class='warning'>There is nobody nearby that you can sit on!</span>")
|
||||
else
|
||||
icon_state = "parrot_fly"
|
||||
icon_state = icon_living
|
||||
parrot_state = PARROT_WANDER
|
||||
if(buckled)
|
||||
to_chat(src, "<span class='notice'>You are no longer sitting on [buckled]'s shoulder.</span>")
|
||||
@@ -842,7 +843,7 @@
|
||||
H.buckle_mob(src, force=1)
|
||||
pixel_y = 9
|
||||
pixel_x = pick(-8,8) //pick left or right shoulder
|
||||
icon_state = "parrot_sit"
|
||||
icon_state = icon_sit
|
||||
parrot_state = PARROT_PERCH
|
||||
to_chat(src, "<span class='notice'>You sit on [H]'s shoulder.</span>")
|
||||
|
||||
@@ -961,6 +962,12 @@
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/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)
|
||||
dust()
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/ghost
|
||||
name = "The Ghost of Poly"
|
||||
desc = "Doomed to squawk the earth."
|
||||
@@ -996,4 +1003,23 @@
|
||||
loc = H
|
||||
H.ContractDisease(P)
|
||||
parrot_interest = null
|
||||
H.visible_message("<span class='danger'>[src] dive bombs into [H]'s chest and vanishes!</span>", "<span class='userdanger'>[src] dive bombs into your chest, vanishing! This can't be good!</span>")
|
||||
H.visible_message("<span class='danger'>[src] dive bombs into [H]'s chest and vanishes!</span>", "<span class='userdanger'>[src] dive bombs into your chest, vanishing! This can't be good!</span>")
|
||||
|
||||
|
||||
/mob/living/simple_animal/parrot/clock_hawk
|
||||
name = "clock hawk"
|
||||
desc = "Cbyl jnaan penpxre! Fdhnnnjx!"
|
||||
icon_state = "clock_hawk_fly"
|
||||
icon_living = "clock_hawk_fly"
|
||||
icon_sit = "clock_hawk_sit"
|
||||
speak = list("Penpxre!", "Ratvar vf n qhzo anzr naljnl!")
|
||||
speak_emote = list("squawks rustily", "says crassly", "yells brassly")
|
||||
emote_hear = list("squawks rustily.", "bawks metallically!")
|
||||
emote_see = list("flutters its metal wings.")
|
||||
faction = list("ratvar")
|
||||
gold_core_spawnable = FALSE
|
||||
del_on_death = TRUE
|
||||
death_sound = 'sound/magic/clockwork/anima_fragment_death.ogg'
|
||||
|
||||
/mob/living/simple_animal/parrot/clock_hawk/ratvar_act()
|
||||
return
|
||||
|
||||
@@ -1,66 +1,66 @@
|
||||
/mob/living/simple_animal/shade
|
||||
name = "Shade"
|
||||
real_name = "Shade"
|
||||
desc = "A bound spirit"
|
||||
gender = PLURAL
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "shade"
|
||||
icon_living = "shade"
|
||||
maxHealth = 50
|
||||
health = 50
|
||||
healable = 0
|
||||
speak_emote = list("hisses")
|
||||
emote_hear = list("wails.","screeches.")
|
||||
response_help = "puts their hand through"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
speak_chance = 1
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 15
|
||||
attacktext = "metaphysically strikes"
|
||||
minbodytemp = 0
|
||||
maxbodytemp = INFINITY
|
||||
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)
|
||||
speed = -1
|
||||
stop_automated_movement = 1
|
||||
status_flags = 0
|
||||
faction = list("cult")
|
||||
status_flags = CANPUSH
|
||||
movement_type = FLYING
|
||||
loot = list(/obj/item/ectoplasm)
|
||||
del_on_death = TRUE
|
||||
initial_language_holder = /datum/language_holder/construct
|
||||
|
||||
/mob/living/simple_animal/shade/death()
|
||||
deathmessage = "lets out a contented sigh as [p_their()] form unwinds."
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/shade/canSuicide()
|
||||
if(istype(loc, /obj/item/device/soulstone)) //do not suicide inside the soulstone
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/shade/Process_Spacemove(movement_dir = 0)
|
||||
return TRUE //this doesn't make much sense; you'd thing TRUE would mean it'd process spacemove but it means it doesn't
|
||||
|
||||
/mob/living/simple_animal/shade/attack_animal(mob/living/simple_animal/M)
|
||||
if(isconstruct(M))
|
||||
var/mob/living/simple_animal/hostile/construct/C = M
|
||||
if(!C.can_repair_constructs)
|
||||
return
|
||||
if(health < maxHealth)
|
||||
adjustHealth(-25)
|
||||
Beam(M,icon_state="sendbeam",time=4)
|
||||
M.visible_message("<span class='danger'>[M] heals \the <b>[src]</b>.</span>", \
|
||||
"<span class='cult'>You heal <b>[src]</b>, leaving <b>[src]</b> at <b>[health]/[maxHealth]</b> health.</span>")
|
||||
else
|
||||
to_chat(M, "<span class='cult'>You cannot heal <b>[src]</b>, as [p_they()] [p_are()] unharmed!</span>")
|
||||
else if(src != M)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/shade/attackby(obj/item/O, mob/user, params) //Marker -Agouri
|
||||
if(istype(O, /obj/item/device/soulstone))
|
||||
var/obj/item/device/soulstone/SS = O
|
||||
SS.transfer_soul("SHADE", src, user)
|
||||
else
|
||||
..()
|
||||
/mob/living/simple_animal/shade
|
||||
name = "Shade"
|
||||
real_name = "Shade"
|
||||
desc = "A bound spirit"
|
||||
gender = PLURAL
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "shade"
|
||||
icon_living = "shade"
|
||||
maxHealth = 50
|
||||
health = 50
|
||||
healable = 0
|
||||
speak_emote = list("hisses")
|
||||
emote_hear = list("wails.","screeches.")
|
||||
response_help = "puts their hand through"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
speak_chance = 1
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 15
|
||||
attacktext = "metaphysically strikes"
|
||||
minbodytemp = 0
|
||||
maxbodytemp = INFINITY
|
||||
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)
|
||||
speed = -1
|
||||
stop_automated_movement = 1
|
||||
status_flags = 0
|
||||
faction = list("cult")
|
||||
status_flags = CANPUSH
|
||||
movement_type = FLYING
|
||||
loot = list(/obj/item/ectoplasm)
|
||||
del_on_death = TRUE
|
||||
initial_language_holder = /datum/language_holder/construct
|
||||
|
||||
/mob/living/simple_animal/shade/death()
|
||||
deathmessage = "lets out a contented sigh as [p_their()] form unwinds."
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/shade/canSuicide()
|
||||
if(istype(loc, /obj/item/device/soulstone)) //do not suicide inside the soulstone
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/shade/Process_Spacemove(movement_dir = 0)
|
||||
return TRUE //this doesn't make much sense; you'd thing TRUE would mean it'd process spacemove but it means it doesn't
|
||||
|
||||
/mob/living/simple_animal/shade/attack_animal(mob/living/simple_animal/M)
|
||||
if(isconstruct(M))
|
||||
var/mob/living/simple_animal/hostile/construct/C = M
|
||||
if(!C.can_repair_constructs)
|
||||
return
|
||||
if(health < maxHealth)
|
||||
adjustHealth(-25)
|
||||
Beam(M,icon_state="sendbeam",time=4)
|
||||
M.visible_message("<span class='danger'>[M] heals \the <b>[src]</b>.</span>", \
|
||||
"<span class='cult'>You heal <b>[src]</b>, leaving <b>[src]</b> at <b>[health]/[maxHealth]</b> health.</span>")
|
||||
else
|
||||
to_chat(M, "<span class='cult'>You cannot heal <b>[src]</b>, as [p_they()] [p_are()] unharmed!</span>")
|
||||
else if(src != M)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/shade/attackby(obj/item/O, mob/user, params) //Marker -Agouri
|
||||
if(istype(O, /obj/item/device/soulstone))
|
||||
var/obj/item/device/soulstone/SS = O
|
||||
SS.transfer_soul("SHADE", src, user)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
Feedstop(0, 0)
|
||||
return
|
||||
|
||||
add_nutrition((rand(7,15) * config.damage_multiplier))
|
||||
add_nutrition((rand(7, 15) * CONFIG_GET(number/damage_multiplier)))
|
||||
|
||||
//Heal yourself.
|
||||
adjustBruteLoss(-3)
|
||||
|
||||
@@ -146,7 +146,10 @@
|
||||
if(health <= 0) // if damaged, the slime moves twice as slow
|
||||
. *= 2
|
||||
|
||||
. += config.slime_delay
|
||||
var/static/config_slime_delay
|
||||
if(isnull(config_slime_delay))
|
||||
config_slime_delay = CONFIG_GET(number/slime_delay)
|
||||
. += config_slime_delay
|
||||
|
||||
/mob/living/simple_animal/slime/ObjCollide(obj/O)
|
||||
if(!client && powerlevel > 0)
|
||||
|
||||
@@ -436,7 +436,7 @@
|
||||
set name = "Respawn"
|
||||
set category = "OOC"
|
||||
|
||||
if (!( GLOB.abandon_allowed ))
|
||||
if (CONFIG_GET(flag/norespawn))
|
||||
return
|
||||
if ((stat != DEAD || !( SSticker )))
|
||||
to_chat(usr, "<span class='boldnotice'>You must be dead to use this!</span>")
|
||||
|
||||
@@ -383,7 +383,7 @@
|
||||
else if(transfer_after)
|
||||
R.key = key
|
||||
|
||||
if (config.rename_cyborg)
|
||||
if (CONFIG_GET(flag/rename_cyborg))
|
||||
R.rename_self("cyborg")
|
||||
|
||||
if(R.mmi)
|
||||
|
||||
Reference in New Issue
Block a user