Merge remote-tracking branch 'upstream/master' into unlockable-loadout-items
This commit is contained in:
@@ -679,8 +679,8 @@
|
||||
set category = "Server"
|
||||
set desc="Respawn basically"
|
||||
set name="Toggle Respawn"
|
||||
var/new_nores = !CONFIG_GET(flag/norespawn)
|
||||
CONFIG_SET(flag/norespawn, new_nores)
|
||||
var/new_nores = CONFIG_GET(flag/respawns_enabled)
|
||||
CONFIG_SET(flag/respawns_enabled, !new_nores)
|
||||
if (!new_nores)
|
||||
to_chat(world, "<B>You may now respawn.</B>", confidential = TRUE)
|
||||
else
|
||||
|
||||
@@ -44,6 +44,11 @@ GLOBAL_PROTECT(protected_ranks)
|
||||
/datum/admin_rank/vv_edit_var(var_name, var_value)
|
||||
return FALSE
|
||||
|
||||
/datum/admin_rank/CanProcCall(procname)
|
||||
. = ..()
|
||||
if(!check_rights(R_SENSITIVE))
|
||||
return FALSE
|
||||
|
||||
/proc/admin_keyword_to_flag(word, previous_rights=0)
|
||||
var/flag = 0
|
||||
switch(ckey(word))
|
||||
@@ -79,6 +84,8 @@ GLOBAL_PROTECT(protected_ranks)
|
||||
flag = R_AUTOLOGIN
|
||||
if("dbranks")
|
||||
flag = R_DBRANKS
|
||||
if("sensitive")
|
||||
flag = R_SENSITIVE
|
||||
if("@","prev")
|
||||
flag = previous_rights
|
||||
return flag
|
||||
|
||||
@@ -78,8 +78,11 @@ GLOBAL_PROTECT(admin_verbs_admin)
|
||||
/client/proc/mark_datum_mapview,
|
||||
/client/proc/hide_verbs, /*hides all our adminverbs*/
|
||||
/client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/
|
||||
/datum/admins/proc/open_borgopanel
|
||||
/datum/admins/proc/open_borgopanel,
|
||||
/client/proc/admin_cmd_respawn_return_to_lobby,
|
||||
/client/proc/admin_cmd_remove_ghost_respawn_timer
|
||||
)
|
||||
|
||||
GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/DB_ban_panel, /client/proc/stickybanpanel))
|
||||
GLOBAL_PROTECT(admin_verbs_ban)
|
||||
GLOBAL_LIST_INIT(admin_verbs_sounds, list(/client/proc/play_local_sound, /client/proc/play_sound, /client/proc/manual_play_web_sound, /client/proc/set_round_end_sound))
|
||||
|
||||
@@ -28,6 +28,11 @@ GLOBAL_PROTECT(href_token)
|
||||
|
||||
var/deadmined
|
||||
|
||||
/datum/admins/CanProcCall(procname)
|
||||
. = ..()
|
||||
if(!check_rights(R_SENSITIVE))
|
||||
return FALSE
|
||||
|
||||
/datum/admins/New(datum/admin_rank/R, ckey, force_active = FALSE, protected)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
var/msg = " has tried to elevate permissions!"
|
||||
@@ -147,6 +152,8 @@ GLOBAL_PROTECT(href_token)
|
||||
return 0
|
||||
|
||||
/datum/admins/vv_edit_var(var_name, var_value)
|
||||
if(var_name == NAMEOF(src, fakekey))
|
||||
return ..()
|
||||
return FALSE //nice try trialmin
|
||||
|
||||
/*
|
||||
|
||||
@@ -298,7 +298,9 @@
|
||||
browse_messages(target_ckey = ckey(target_key), agegate = TRUE)
|
||||
qdel(query_find_message_secret)
|
||||
|
||||
/proc/browse_messages(type, target_ckey, index, linkless = FALSE, filter, agegate = FALSE)
|
||||
/proc/browse_messages(type, target_ckey, index, linkless = FALSE, filter, agegate = FALSE, override = FALSE)
|
||||
if((!override || IsAdminAdvancedProcCall()) && !check_rights(R_SENSITIVE))
|
||||
return
|
||||
if(!SSdbcore.Connect())
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
|
||||
@@ -936,6 +936,12 @@
|
||||
else
|
||||
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_MIND_TRANSFER];jobban4=[REF(M)]'>Mind Transfer Potion</a></td>"
|
||||
|
||||
//Respawns
|
||||
if(jobban_isbanned(M, ROLE_RESPAWN))
|
||||
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_RESPAWN];jobban4=[REF(M)]'><font color=red>Respawns</font></a></td>"
|
||||
else
|
||||
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_RESPAWN];jobban4=[REF(M)]'>Respawns</a></td>"
|
||||
|
||||
dat += "</tr></table>"
|
||||
usr << browse(dat, "window=jobban2;size=800x450")
|
||||
return
|
||||
@@ -1799,12 +1805,15 @@
|
||||
if(alert(usr, "Send [key_name(M)] back to Lobby?", "Message", "Yes", "No") != "Yes")
|
||||
return
|
||||
|
||||
log_admin("[key_name(usr)] has sent [key_name(M)] back to the Lobby.")
|
||||
message_admins("[key_name(usr)] has sent [key_name(M)] back to the Lobby.")
|
||||
log_admin("[key_name(usr)] has sent [key_name(M)] back to the Lobby, removing their respawn restrictions if they existed.")
|
||||
message_admins("[key_name(usr)] has sent [key_name(M)] back to the Lobby, removing their respawn restrictions if they existed.")
|
||||
|
||||
var/mob/dead/new_player/NP = new()
|
||||
NP.ckey = M.ckey
|
||||
qdel(M)
|
||||
if(GLOB.preferences_datums[NP.ckey])
|
||||
var/datum/preferences/P = GLOB.preferences_datums[NP.ckey]
|
||||
P.respawn_restrictions_active = FALSE
|
||||
|
||||
else if(href_list["tdome1"])
|
||||
if(!check_rights(R_FUN))
|
||||
|
||||
@@ -23,13 +23,6 @@
|
||||
|
||||
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>[uppertext(holder.rank)]([src.holder.fakekey ? pick(nicknames) : src.key])</span> says, <span class='message'>\"[emoji_parse(msg)]\"</span></span>"
|
||||
|
||||
// var/rank_name = holder.rank
|
||||
// var/admin_name = key
|
||||
// if(holder.fakekey)
|
||||
// rank_name = pick(strings("admin_nicknames.json", "ranks", "config")) please use this soon.
|
||||
// admin_name = pick(strings("admin_nicknames.json", "names", "config"))
|
||||
// var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>[rank_name]([admin_name])</span> says, <span class='message'>\"[emoji_parse(msg)]\"</span></span>"
|
||||
|
||||
for (var/mob/M in GLOB.player_list)
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
browseserverlogs("[GLOB.log_directory]/")
|
||||
|
||||
/client/proc/browseserverlogs(path = "data/logs/")
|
||||
if(!check_rights(R_SENSITIVE))
|
||||
return
|
||||
path = browse_files(path)
|
||||
if(!path)
|
||||
return
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
L.adjustFireLoss(amount)
|
||||
newamt = L.getFireLoss()
|
||||
if("toxin")
|
||||
L.adjustToxLoss(amount, toxins_type = TOX_OMNI)
|
||||
L.adjustToxLoss(amount, toxins_type = TOX_OMNI, forced = TRUE)
|
||||
newamt = L.getToxLoss()
|
||||
if("oxygen")
|
||||
L.adjustOxyLoss(amount)
|
||||
|
||||
@@ -120,9 +120,14 @@
|
||||
if(bruteheal + fireheal + toxinheal > 0) // Just a check? Don't heal/spend, and return.
|
||||
if(mult == 0)
|
||||
return TRUE
|
||||
|
||||
// We have damage. Let's heal (one time)
|
||||
C.adjustBruteLoss(-bruteheal * mult, forced = TRUE)// Heal BRUTE / BURN in random portions throughout the body.
|
||||
C.adjustFireLoss(-fireheal * mult, forced = TRUE)
|
||||
var/list/damaged_parts = C.get_damaged_bodyparts(TRUE,TRUE, status = list(BODYPART_ORGANIC, BODYPART_HYBRID, BODYPART_NANITES))
|
||||
if(damaged_parts.len)
|
||||
for(var/obj/item/bodypart/part in damaged_parts) // Heal BRUTE / BURN equally distibuted over all damaged bodyparts.
|
||||
part.heal_damage((bruteheal * mult)/damaged_parts.len, (fireheal * mult)/damaged_parts.len, only_organic = FALSE, updating_health = FALSE)
|
||||
C.updatehealth()
|
||||
C.update_damage_overlays()
|
||||
C.adjustToxLoss(-toxinheal * mult * 2, forced = TRUE) //Toxin healing because vamps arent immune
|
||||
//C.heal_overall_damage(bruteheal * mult, fireheal * mult) // REMOVED: We need to FORCE this, because otherwise, vamps won't heal EVER. Swapped to above.
|
||||
AddBloodVolume((bruteheal * -0.5 + fireheal * -1 + toxinheal * -0.2) / mult * costMult) // Costs blood to heal
|
||||
@@ -276,7 +281,7 @@
|
||||
/datum/antagonist/bloodsucker/proc/FinalDeath()
|
||||
//Dont bother if we are already supposed to be dead
|
||||
if(FinalDeath)
|
||||
return
|
||||
return
|
||||
FinalDeath = TRUE //We are now supposed to die. Lets not spam it.
|
||||
if(!iscarbon(owner.current)) //Check for non carbons.
|
||||
owner.current.gib()
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
var/can_be_staked = FALSE // Only Feed can happen with a stake in you.
|
||||
var/cooldown_static = FALSE // Feed, Masquerade, and One-Shot powers don't improve their cooldown.
|
||||
//var/not_bloodsucker = FALSE // This goes to Vassals or Hunters, but NOT bloodsuckers.
|
||||
var/must_be_concious = TRUE //Can't use this ability while unconcious.
|
||||
|
||||
/datum/action/bloodsucker/New()
|
||||
if(bloodcost > 0)
|
||||
@@ -101,6 +102,11 @@
|
||||
if(display_error)
|
||||
to_chat(owner, "<span class='warning'>Garlic in your blood is interfering with your powers!</span>")
|
||||
return FALSE
|
||||
if(must_be_concious)
|
||||
if(owner.stat != CONSCIOUS)
|
||||
if(display_error)
|
||||
to_chat(owner, "<span class='warning'>You can't do this while you are unconcious!</span>")
|
||||
return FALSE
|
||||
// Incap?
|
||||
if(must_be_capacitated)
|
||||
var/mob/living/L = owner
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
can_use_in_torpor = TRUE
|
||||
must_be_capacitated = TRUE
|
||||
can_be_immobilized = TRUE
|
||||
must_be_concious = FALSE
|
||||
|
||||
/datum/action/bloodsucker/gohome/CheckCanUse(display_error)
|
||||
. = ..()
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
warn_constant_cost = TRUE
|
||||
can_use_in_torpor = TRUE // Masquerade is maybe the only one that can do this. It stops your healing.
|
||||
cooldown_static = TRUE
|
||||
must_be_concious = FALSE
|
||||
|
||||
// NOTE: Firing off vulgar powers disables your Masquerade!
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
if(user.stat != DEAD)
|
||||
user.emote("deathgasp")
|
||||
user.tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)
|
||||
user.fakedeath("changeling") //play dead
|
||||
user.fakedeath("changeling", TRUE) //play dead
|
||||
user.update_stat()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME, TIMER_UNIQUE)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
chemical_cost = 1000
|
||||
dna_cost = -1
|
||||
|
||||
var/recharge_slowdown = 0
|
||||
var/silent = FALSE
|
||||
var/weapon_type
|
||||
var/weapon_name_simple
|
||||
@@ -37,6 +38,8 @@
|
||||
if(!silent)
|
||||
playsound(user, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
user.visible_message("<span class='warning'>With a sickening crunch, [user] reforms [user.p_their()] [weapon_name_simple] into an arm!</span>", "<span class='notice'>We assimilate the [weapon_name_simple] back into our body.</span>", "<span class='italics>You hear organic matter ripping and tearing!</span>")
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
changeling.chem_recharge_slowdown -= recharge_slowdown
|
||||
user.update_inv_hands()
|
||||
return 1
|
||||
|
||||
@@ -57,6 +60,8 @@
|
||||
user.put_in_hands(W)
|
||||
if(!silent)
|
||||
playsound(user, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
changeling.chem_recharge_slowdown += recharge_slowdown
|
||||
return W
|
||||
|
||||
/obj/effect/proc_holder/changeling/weapon/on_refund(mob/user)
|
||||
@@ -141,10 +146,11 @@
|
||||
name = "Arm Blade"
|
||||
desc = "We reform one of our arms into a deadly blade."
|
||||
helptext = "We may retract our armblade in the same manner as we form it. Cannot be used while in lesser form. This ability is loud, and might cause our blood to react violently to heat."
|
||||
chemical_cost = 10
|
||||
chemical_cost = 5
|
||||
dna_cost = 2
|
||||
loudness = 2
|
||||
req_human = 1
|
||||
recharge_slowdown = 0.6
|
||||
weapon_type = /obj/item/melee/arm_blade
|
||||
weapon_name_simple = "blade"
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
@@ -487,7 +493,7 @@
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/changeling
|
||||
suit_name_simple = "flesh shell"
|
||||
helmet_name_simple = "space helmet"
|
||||
recharge_slowdown = 0.5
|
||||
recharge_slowdown = 0.6
|
||||
blood_on_castoff = 1
|
||||
|
||||
/obj/item/clothing/suit/space/changeling
|
||||
@@ -532,11 +538,11 @@
|
||||
name = "Chitinous Armor"
|
||||
desc = "We turn our skin into tough chitin to protect us from damage."
|
||||
helptext = "Upkeep of the armor requires a constant expenditure of chemicals, resulting in a reduced chemical generation. The armor is strong against brute force, but does not provide much protection from lasers. Cannot be used in lesser form. This ability is loud, and might cause our blood to react violently to heat."
|
||||
chemical_cost = 20
|
||||
chemical_cost = 10
|
||||
dna_cost = 1
|
||||
loudness = 2
|
||||
req_human = 1
|
||||
recharge_slowdown = 0.5
|
||||
recharge_slowdown = 0.6
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_armor"
|
||||
action_background_icon_state = "bg_ling"
|
||||
@@ -662,10 +668,11 @@
|
||||
name = "Bone Gauntlets"
|
||||
desc = "We turn our hands into solid bone and chitin, sacrificing dexterity for raw strength."
|
||||
helptext = "These grotesque, bone-and-chitin gauntlets are remarkably good at beating victims senseless, and cannot be used in lesser form. This ability is loud, and might cause our blood to react violently to heat."
|
||||
chemical_cost = 10 // same cost as armblade because its a sidegrade (sacrifice utility for punching people violently)
|
||||
chemical_cost = 5 // same cost as armblade because its a sidegrade (sacrifice utility for punching people violently)
|
||||
dna_cost = 2
|
||||
loudness = 2
|
||||
req_human = 1
|
||||
recharge_slowdown = 0.6
|
||||
action_icon = 'icons/mob/actions/actions_changeling.dmi'
|
||||
action_icon_state = "ling_gauntlets"
|
||||
action_background_icon_state = "bg_ling"
|
||||
@@ -689,8 +696,8 @@
|
||||
wound_enhancement = 6
|
||||
var/fast_enhancement = 6
|
||||
var/fast_wound_enhancement = 6
|
||||
var/slow_enhancement = 20
|
||||
var/slow_wound_enhancement = 20
|
||||
var/slow_enhancement = 12
|
||||
var/slow_wound_enhancement = 15
|
||||
silent = TRUE
|
||||
inherited_trait = TRAIT_CHUNKYFINGERS // how do you expect to shoot anyone with bone covered hands
|
||||
secondary_trait = TRAIT_MAULER // just punch them idiot
|
||||
|
||||
@@ -445,7 +445,7 @@
|
||||
if(L.move_resist < MOVE_FORCE_STRONG)
|
||||
var/atom/throw_target = get_edge_target_turf(L, user.dir)
|
||||
L.throw_at(throw_target, 7, 1, user)
|
||||
else if(!iscultist(L))
|
||||
else if(!is_servant_of_ratvar(L))
|
||||
L.DefaultCombatKnockdown(160)
|
||||
L.adjustStaminaLoss(140) //Ensures hard stamcrit
|
||||
L.flash_act(1,1)
|
||||
@@ -465,7 +465,7 @@
|
||||
C.drowsyness = max(10, C.drowsyness)
|
||||
C.confused += clamp(20 - C.confused, 0, 10)
|
||||
L.adjustBruteLoss(15)
|
||||
to_chat(user, "<span class='cultitalic'>In an brilliant flash of red, [L] [iscultist(L) ? "writhes in pain" : "falls to the ground!"]</span>")
|
||||
to_chat(user, "<span class='cultitalic'>In an brilliant flash of red, [L] [is_servant_of_ratvar(L) ? "writhes in pain!" : "falls to the ground!"]</span>")
|
||||
uses--
|
||||
..()
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
var/pck = pick("assasinate","protect")
|
||||
switch(pck)
|
||||
if("assasinate")
|
||||
var/datum/objective/assassinate/A = new
|
||||
var/datum/objective/assassinate/once/A = new
|
||||
A.owner = owner
|
||||
var/list/owners = A.get_owners()
|
||||
A.find_target(owners,protection)
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
name = "Codex Cicatrix"
|
||||
desc = "Book describing the secrets of the veil."
|
||||
icon = 'icons/obj/eldritch.dmi'
|
||||
icon_state = "book"
|
||||
item_state = "book"
|
||||
icon_state = "codex"
|
||||
item_state = "codex"
|
||||
lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
///Last person that touched this
|
||||
var/mob/living/last_user
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
var/mob/living/living_user = user
|
||||
living_user.adjustBruteLoss(-3, FALSE)
|
||||
living_user.adjustFireLoss(-3, FALSE)
|
||||
living_user.adjustToxLoss(-3, FALSE)
|
||||
living_user.adjustToxLoss(-3, FALSE, TRUE)
|
||||
living_user.adjustOxyLoss(-1, FALSE)
|
||||
living_user.adjustStaminaLoss(-6)
|
||||
|
||||
|
||||
@@ -68,10 +68,6 @@
|
||||
R.reaction(turfing ? target : target.loc, TOUCH, 1, 0)
|
||||
if(!turfing)
|
||||
R.trans_to(target, R.total_volume * (spill ? G.fluid_transfer_factor : 1))
|
||||
|
||||
overlay_fullscreen("flash", /obj/screen/fullscreen/flash) // To be more true to the hentai
|
||||
clear_fullscreen("flash", 20)
|
||||
|
||||
G.last_orgasmed = world.time
|
||||
R.clear_reagents()
|
||||
|
||||
|
||||
@@ -34,10 +34,57 @@
|
||||
|
||||
/datum/supply_pack/critter/parrot/generate()
|
||||
. = ..()
|
||||
for(var/i in 1 to 4)
|
||||
new /mob/living/simple_animal/parrot(.)
|
||||
if(prob(1))
|
||||
new /mob/living/simple_animal/parrot/clock_hawk(.)
|
||||
for(var/i in 1 to 5)
|
||||
switch(rand(1, 24))
|
||||
if(1)
|
||||
new /mob/living/simple_animal/parrot(.)
|
||||
if(2)
|
||||
new /mob/living/simple_animal/parrot/clock_hawk(.)
|
||||
if(3)
|
||||
new /mob/living/simple_animal/parrot/kea(.)
|
||||
if(4)
|
||||
new /mob/living/simple_animal/parrot/eclectus(.)
|
||||
if(5)
|
||||
new /mob/living/simple_animal/parrot/eclectusf(.)
|
||||
if(6)
|
||||
new /mob/living/simple_animal/parrot/greybird(.)
|
||||
if(7)
|
||||
new /mob/living/simple_animal/parrot/blue_caique(.)
|
||||
if(8)
|
||||
new /mob/living/simple_animal/parrot/white_caique(.)
|
||||
if(9)
|
||||
new /mob/living/simple_animal/parrot/green_budgerigar(.)
|
||||
if(10)
|
||||
new /mob/living/simple_animal/parrot/blue_Budgerigar(.)
|
||||
if(11)
|
||||
new /mob/living/simple_animal/parrot/bluegreen_Budgerigar(.)
|
||||
if(12)
|
||||
new /mob/living/simple_animal/parrot/commonblackbird(.)
|
||||
if(13)
|
||||
new /mob/living/simple_animal/parrot/azuretit(.)
|
||||
if(14)
|
||||
new /mob/living/simple_animal/parrot/europeanrobin(.)
|
||||
if(15)
|
||||
new /mob/living/simple_animal/parrot/goldcrest(.)
|
||||
if(16)
|
||||
new /mob/living/simple_animal/parrot/ringneckdove(.)
|
||||
if(17)
|
||||
new /mob/living/simple_animal/parrot/cockatiel(.)
|
||||
if(18)
|
||||
new /mob/living/simple_animal/parrot/white_cockatiel(.)
|
||||
if(19)
|
||||
new /mob/living/simple_animal/parrot/yellowish_cockatiel(.)
|
||||
if(20)
|
||||
new /mob/living/simple_animal/parrot/grey_cockatiel(.)
|
||||
if(21)
|
||||
new /mob/living/simple_animal/parrot/too(.)
|
||||
if(22)
|
||||
new /mob/living/simple_animal/parrot/hooded_too(.)
|
||||
if(23)
|
||||
new /mob/living/simple_animal/parrot/pink_too(.)
|
||||
if(24)
|
||||
new /mob/living/simple_animal/parrot/eclectusr(.)
|
||||
|
||||
|
||||
/datum/supply_pack/critter/butterfly
|
||||
name = "Butterflies Crate"
|
||||
|
||||
@@ -101,6 +101,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
keyUp(keycode)
|
||||
return
|
||||
|
||||
if(href_list["statpanel_item_target"])
|
||||
handle_statpanel_click(href_list)
|
||||
return
|
||||
|
||||
// Tgui Topic middleware
|
||||
if(tgui_Topic(href_list))
|
||||
return
|
||||
@@ -141,6 +145,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
|
||||
..() //redirect to hsrc.Topic()
|
||||
|
||||
/client/proc/handle_statpanel_click(list/href_list)
|
||||
var/atom/target = locate(href_list["statpanel_item_target"])
|
||||
Click(target, target.loc, null, "[href_list["statpanel_item_shiftclick"]?"shift=1;":null][href_list["statpanel_item_ctrlclick"]?"ctrl=1;":null]&alt=[href_list["statpanel_item_altclick"]?"alt=1;":null]", FALSE, "statpanel")
|
||||
|
||||
/client/proc/is_content_unlocked()
|
||||
if(!prefs.unlock_content)
|
||||
to_chat(src, "Become a BYOND member to access member-perks and features, as well as support the engine that makes this game possible. Only 10 bucks for 3 months! <a href=\"https://secure.byond.com/membership\">Click Here to find out more</a>.")
|
||||
@@ -798,7 +806,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
message_admins("<span class='adminnotice'>Proxy Detection: [key_name_admin(src)] IP intel rated [res.intel*100]% likely to be a Proxy/VPN.</span>")
|
||||
ip_intel = res.intel
|
||||
|
||||
/client/Click(atom/object, atom/location, control, params, ignore_spam = FALSE)
|
||||
/client/Click(atom/object, atom/location, control, params, ignore_spam = FALSE, extra_info)
|
||||
if(last_click > world.time - world.tick_lag)
|
||||
return
|
||||
last_click = world.time
|
||||
@@ -851,7 +859,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
return
|
||||
|
||||
if(prefs.log_clicks)
|
||||
log_click(object, location, control, params, src)
|
||||
log_click(object, location, control, params, src, extra_info? "clicked ([extra_info])" : null)
|
||||
|
||||
if (prefs.hotkeys)
|
||||
// If hotkey mode is enabled, then clicking the map will automatically
|
||||
@@ -921,8 +929,22 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
if (NAMEOF(src, view))
|
||||
view_size.setDefault(var_value)
|
||||
return TRUE
|
||||
if(NAMEOF(src, computer_id))
|
||||
return FALSE
|
||||
if(NAMEOF(src, address))
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
/client/vv_get_var(var_name)
|
||||
. = ..()
|
||||
switch(var_name)
|
||||
if(NAMEOF(src, computer_id))
|
||||
if(!check_rights(R_SENSITIVE, FALSE))
|
||||
return "SENSITIVE"
|
||||
if(NAMEOF(src, address))
|
||||
if(!check_rights(R_SENSITIVE, FALSE))
|
||||
return "SENSITIVE"
|
||||
|
||||
/client/proc/rescale_view(change, min, max)
|
||||
var/viewscale = getviewsize(view)
|
||||
var/x = viewscale[1]
|
||||
|
||||
@@ -12,11 +12,29 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used
|
||||
var/max_save_slots = 24
|
||||
|
||||
//non-preference stuff
|
||||
var/muted = 0
|
||||
// Intra-round persistence begin
|
||||
/// Flags for admin mutes
|
||||
var/muted = NONE
|
||||
/// Last IP the person was seen on
|
||||
var/last_ip
|
||||
/// Last CID the person was seen on
|
||||
var/last_id
|
||||
/// Do we log their clicks to disk?
|
||||
var/log_clicks = FALSE
|
||||
/// Characters they have joined the round under - Lazylist of names
|
||||
var/list/characters_joined_as
|
||||
/// Slots they have joined the round under - Lazylist of numbers
|
||||
var/list/slots_joined_as
|
||||
/// Are we currently subject to respawn restrictions? Usually set by us using the "respawn" verb, but can be lifted by admins.
|
||||
var/respawn_restrictions_active = FALSE
|
||||
/// time of death we consider for respawns
|
||||
var/respawn_time_of_death = -INFINITY
|
||||
/// did they DNR? used to prevent respawns.
|
||||
var/dnr_triggered = FALSE
|
||||
/// did they cryo on their last ghost?
|
||||
var/respawn_did_cryo = FALSE
|
||||
|
||||
// Intra-round persistence end
|
||||
|
||||
var/icon/custom_holoform_icon
|
||||
var/list/cached_holoform_icons
|
||||
|
||||
@@ -179,7 +179,7 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8")
|
||||
to_chat(usr, "<span class='notice'>Sorry, that function is not enabled on this server.</span>")
|
||||
return
|
||||
|
||||
browse_messages(null, usr.ckey, null, TRUE)
|
||||
browse_messages(null, usr.ckey, null, TRUE, override = TRUE)
|
||||
|
||||
/client/proc/self_playtime()
|
||||
set name = "View tracked playtime"
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
body_parts_covered = ARMS
|
||||
cold_protection = ARMS
|
||||
strip_delay = 300 //you can't just yank them off
|
||||
obj_flags = UNIQUE_RENAME
|
||||
/// did you ever get around to wearing these or no
|
||||
var/wornonce = FALSE
|
||||
///Extra damage through the punch.
|
||||
|
||||
@@ -873,9 +873,9 @@
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight
|
||||
name = "cydonian helmet"
|
||||
desc = "A helmet designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips."
|
||||
icon_state = "knight_cydonia"
|
||||
icon_state = "hardsuit0-knight_cydonia"
|
||||
item_state = "knight_yellow"
|
||||
hardsuit_type = null
|
||||
hardsuit_type = "knight_cydonia"
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
resistance_flags = FIRE_PROOF | LAVA_PROOF
|
||||
heat_protection = HEAD
|
||||
|
||||
@@ -256,7 +256,7 @@ Contains:
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/alert
|
||||
armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 50)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC|STYLE_PAW_TAURIC
|
||||
|
||||
//ERT Security
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ert/alert/sec
|
||||
|
||||
@@ -554,7 +554,7 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and
|
||||
|
||||
/datum/holiday/xmas
|
||||
name = CHRISTMAS
|
||||
begin_day = 10
|
||||
begin_day = 18
|
||||
begin_month = DECEMBER
|
||||
end_day = 27
|
||||
drone_hat = /obj/item/clothing/head/santa
|
||||
|
||||
@@ -73,6 +73,12 @@
|
||||
/// Starting skill modifiers.
|
||||
var/list/starting_modifiers
|
||||
|
||||
// These can be flags but I don't care because they're never changed
|
||||
/// Can you always join as this job even while respawning (should probably only be on for assistant)
|
||||
var/always_can_respawn_as = FALSE
|
||||
/// Is this job considered a combat role for respawning? (usually sec/command)
|
||||
var/considered_combat_role = FALSE
|
||||
|
||||
/**
|
||||
* Checks if we should be created on a certain map
|
||||
*/
|
||||
@@ -118,15 +124,21 @@
|
||||
|
||||
//Used for a special check of whether to allow a client to latejoin as this job.
|
||||
/datum/job/proc/special_check_latejoin(client/C)
|
||||
var/joined = LAZYLEN(C.prefs?.characters_joined_as)
|
||||
if(C.prefs?.respawn_restrictions_active && (joined || CONFIG_GET(flag/respawn_penalty_includes_observe)))
|
||||
if(!CONFIG_GET(flag/allow_non_assistant_respawn) && !always_can_respawn_as)
|
||||
return FALSE
|
||||
if(!CONFIG_GET(flag/allow_combat_role_respawn) && considered_combat_role)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/job/proc/GetAntagRep()
|
||||
. = CONFIG_GET(keyed_list/antag_rep)[lowertext(title)]
|
||||
. = CONFIG_GET(keyed_list/antag_rep)[ckey(title)]
|
||||
if(. == null)
|
||||
return antag_rep
|
||||
|
||||
/datum/job/proc/GetThreat()
|
||||
. = CONFIG_GET(keyed_list/job_threat)[lowertext(title)]
|
||||
. = CONFIG_GET(keyed_list/job_threat)[ckey(title)]
|
||||
if(. == null)
|
||||
return threat
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
display_order = JOB_DISPLAY_ORDER_AI
|
||||
var/do_special_check = TRUE
|
||||
threat = 5
|
||||
considered_combat_role = TRUE
|
||||
|
||||
starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic)
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ Assistant
|
||||
paycheck_department = ACCOUNT_CIV
|
||||
display_order = JOB_DISPLAY_ORDER_ASSISTANT
|
||||
dresscodecompliant = FALSE
|
||||
always_can_respawn_as = TRUE
|
||||
threat = 0.2
|
||||
|
||||
/datum/job/assistant/get_access()
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_COMMAND
|
||||
exp_type_department = EXP_TYPE_COMMAND
|
||||
considered_combat_role = TRUE
|
||||
|
||||
|
||||
outfit = /datum/outfit/job/captain
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type_department = EXP_TYPE_ENGINEERING
|
||||
considered_combat_role = TRUE
|
||||
|
||||
outfit = /datum/outfit/job/ce
|
||||
plasma_outfit = /datum/outfit/plasmaman/ce
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type_department = EXP_TYPE_MEDICAL
|
||||
considered_combat_role = TRUE
|
||||
|
||||
outfit = /datum/outfit/job/cmo
|
||||
plasma_outfit = /datum/outfit/plasmaman/cmo
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 120
|
||||
exp_type = EXP_TYPE_CREW
|
||||
considered_combat_role = TRUE
|
||||
|
||||
starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic)
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
outfit = /datum/outfit/job/detective
|
||||
plasma_outfit = /datum/outfit/plasmaman/detective
|
||||
considered_combat_role = TRUE
|
||||
|
||||
access = list(ACCESS_SEC_DOORS, ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_COURT, ACCESS_BRIG, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM)
|
||||
minimal_access = list(ACCESS_SEC_DOORS, ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_COURT, ACCESS_BRIG, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type_department = EXP_TYPE_SERVICE
|
||||
|
||||
considered_combat_role = TRUE
|
||||
outfit = /datum/outfit/job/hop
|
||||
plasma_outfit = /datum/outfit/plasmaman/hop
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
minimal_player_age = 10
|
||||
exp_requirements = 300
|
||||
exp_type = EXP_TYPE_CREW
|
||||
considered_combat_role = TRUE
|
||||
exp_type_department = EXP_TYPE_SECURITY
|
||||
|
||||
outfit = /datum/outfit/job/hos
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type_department = EXP_TYPE_SUPPLY
|
||||
considered_combat_role = TRUE
|
||||
|
||||
outfit = /datum/outfit/job/quartermaster
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
exp_type_department = EXP_TYPE_SCIENCE
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
considered_combat_role = TRUE
|
||||
|
||||
outfit = /datum/outfit/job/rd
|
||||
plasma_outfit = /datum/outfit/plasmaman/rd
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
minimal_player_age = 7
|
||||
exp_requirements = 300
|
||||
exp_type = EXP_TYPE_CREW
|
||||
considered_combat_role = TRUE
|
||||
|
||||
outfit = /datum/outfit/job/security
|
||||
plasma_outfit = /datum/outfit/plasmaman/security
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
minimal_player_age = 7
|
||||
exp_requirements = 300
|
||||
exp_type = EXP_TYPE_CREW
|
||||
considered_combat_role = TRUE
|
||||
|
||||
outfit = /datum/outfit/job/warden
|
||||
plasma_outfit = /datum/outfit/plasmaman/warden
|
||||
|
||||
@@ -124,7 +124,8 @@
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/living/hold_sprint
|
||||
hotkey_keys = list("Shift")
|
||||
hotkey_keys = list()
|
||||
classic_keys = list()
|
||||
name = "hold_sprint"
|
||||
full_name = "Sprint (hold down)"
|
||||
description = "Hold down to sprint"
|
||||
@@ -144,7 +145,8 @@
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/living/toggle_sprint
|
||||
hotkey_keys = list()
|
||||
hotkey_keys = list("Shift")
|
||||
classic_keys = list("Shift")
|
||||
name = "toggle_sprint"
|
||||
full_name = "Sprint (toggle)"
|
||||
description = "Press to toggle sprint"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
/datum/proc/keyLoop(client/user) // Called once every frame
|
||||
//SHOULD_NOT_SLEEP(TRUE)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
/client/verb/fix_macros()
|
||||
set name = "Fix Keybindings"
|
||||
|
||||
@@ -81,11 +81,10 @@
|
||||
STOP_PROCESSING(SSmachines, src)
|
||||
icon_state = "coinpress0"
|
||||
|
||||
/obj/machinery/mineral/mint/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/mineral/mint/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Mint", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "Mint", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/mineral/mint/ui_data()
|
||||
|
||||
@@ -375,7 +375,9 @@
|
||||
ready = PLAYER_NOT_READY
|
||||
return FALSE
|
||||
|
||||
var/this_is_like_playing_right = alert(src,"Are you sure you wish to observe? You will not be able to play this round!","Player Setup","Yes","No")
|
||||
var/mintime = max(CONFIG_GET(number/respawn_delay), (SSticker.round_start_time + (CONFIG_GET(number/respawn_minimum_delay_roundstart) * 600)) - world.time, 0)
|
||||
|
||||
var/this_is_like_playing_right = alert(src,"Are you sure you wish to observe? You will not be able to respawn for [round(mintime / 600, 0.1)] minutes!!","Player Setup","Yes","No")
|
||||
|
||||
if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes")
|
||||
ready = PLAYER_NOT_READY
|
||||
@@ -397,6 +399,7 @@
|
||||
stack_trace("There's no freaking observer landmark available on this map or you're making observers before the map is initialised")
|
||||
transfer_ckey(observer, FALSE)
|
||||
observer.client = client
|
||||
observer.client.prefs?.respawn_time_of_death = world.time
|
||||
observer.set_ghost_appearance()
|
||||
if(observer.client && observer.client.prefs)
|
||||
observer.real_name = observer.client.prefs.real_name
|
||||
@@ -463,6 +466,9 @@
|
||||
alert(src, "An administrator has disabled late join spawning.")
|
||||
return FALSE
|
||||
|
||||
if(!respawn_latejoin_check(notify = TRUE))
|
||||
return FALSE
|
||||
|
||||
var/arrivals_docked = TRUE
|
||||
if(SSshuttle.arrivals)
|
||||
close_spawn_windows() //In case we get held up
|
||||
@@ -526,6 +532,8 @@
|
||||
|
||||
GLOB.joined_player_list += character.ckey
|
||||
GLOB.latejoiners += character
|
||||
LAZYOR(character.client.prefs.slots_joined_as, character.client.prefs.default_slot)
|
||||
LAZYOR(character.client.prefs.characters_joined_as, character.real_name)
|
||||
|
||||
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)
|
||||
|
||||
@@ -264,7 +264,7 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body
|
||||
Works together with spawning an observer, noted above.
|
||||
*/
|
||||
|
||||
/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE)
|
||||
/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE, cryo = FALSE)
|
||||
var/sig_flags = SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize)
|
||||
penalize = !(sig_flags & COMPONENT_DO_NOT_PENALIZE_GHOSTING) && (suiciding || penalize) // suicide squad.
|
||||
voluntary_ghosted = voluntary
|
||||
@@ -277,6 +277,12 @@ Works together with spawning an observer, noted above.
|
||||
if (client && client.prefs && client.prefs.auto_ooc)
|
||||
if (!(client.prefs.chat_toggles & CHAT_OOC))
|
||||
client.prefs.chat_toggles ^= CHAT_OOC
|
||||
if(ckey && penalize)
|
||||
var/datum/preferences/P = GLOB.preferences_datums[ckey]
|
||||
if(P)
|
||||
P.respawn_restrictions_active = TRUE
|
||||
P.respawn_time_of_death = world.time
|
||||
P.respawn_did_cryo = cryo
|
||||
transfer_ckey(ghost, FALSE)
|
||||
ghost.client.init_verbs()
|
||||
if(penalize)
|
||||
@@ -423,12 +429,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
to_chat(usr, "<span class='warning'>You're already stuck out of your body!</span>")
|
||||
return FALSE
|
||||
|
||||
var/response = alert(src, "Are you sure you want to prevent (almost) all means of resuscitation? This cannot be undone. ","Are you sure you want to stay dead?","Yes","No")
|
||||
var/response = alert(src, "Are you sure you want to prevent (almost) all means of resuscitation? This cannot be undone. THIS WILL ALSO STOP YOU FROM RESPAWNING!!!","Are you sure you want to stay dead and never respawn?","Yes","No")
|
||||
|
||||
if(response != "Yes")
|
||||
return
|
||||
|
||||
can_reenter_corpse = FALSE
|
||||
to_chat(src, "You can no longer be brought back into your body.")
|
||||
client.prefs?.dnr_triggered = TRUE
|
||||
to_chat(src, "You can no longer be brought back into your body or respawn.")
|
||||
return TRUE
|
||||
|
||||
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source, flashwindow = TRUE)
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
// ADMIN VERBS BEGIN
|
||||
/**
|
||||
* Fully returns a player to lobby, allowing them to bypass all respawn restrictions
|
||||
* Works on ghosts or new players (lobby players)
|
||||
* If a lobby player is selected, their restrictions are removed.
|
||||
*/
|
||||
/client/proc/admin_cmd_respawn_return_to_lobby()
|
||||
set name = "Respawn Player (Unrestricted)"
|
||||
set desc = "Gives a player an unrestricted respawn, resetting all respawn restrictions for them."
|
||||
set category = "Admin"
|
||||
|
||||
var/list/mob/valid = list()
|
||||
for(var/mob/dead/observer/I in GLOB.dead_mob_list)
|
||||
if(!I.client)
|
||||
continue
|
||||
valid["[I.ckey] - Observing: [I]"] = I.ckey
|
||||
for(var/mob/dead/new_player/I in GLOB.dead_mob_list)
|
||||
if(!I.client || !I.client.prefs.respawn_restrictions_active)
|
||||
continue
|
||||
valid["[I.ckey] - IN LOBBY"] = I.ckey
|
||||
if(!valid.len)
|
||||
to_chat(src, "<span class='warning'>No player found that is either a ghost or is in lobby with restrictions active.</span>")
|
||||
return
|
||||
var/ckey = valid[input(src, "Choose a player (only showing logged in players who have restrictions)", "Unrestricted Respawn") as null|anything in valid]
|
||||
var/client/player = GLOB.directory[ckey]
|
||||
if(!player)
|
||||
to_chat(src, "<span class='warning'>Client not found.</span>")
|
||||
return
|
||||
var/mob/M = player.mob
|
||||
if(istype(M, /mob/dead/observer))
|
||||
var/mob/dead/observer/O = M
|
||||
var/confirm = alert(src, "Send [O]([ckey]) back to the lobby without respawn restrictions?", "Send to Lobby", "Yes", "No")
|
||||
if(confirm != "Yes")
|
||||
return
|
||||
message_admins("[key_name_admin(src)] gave [key_name_admin(O)] a full respawn and sent them back to the lobby.")
|
||||
log_admin("[key_name(src)] gave [key_name(O)] a full respawn and sent them back to the lobby.")
|
||||
to_chat(O, "<span class='userdanger'>You have been given a full respawn.</span>")
|
||||
O.do_respawn(FALSE)
|
||||
O.client.prefs.dnr_triggered = FALSE
|
||||
else if(istype(M, /mob/dead/new_player))
|
||||
var/mob/dead/new_player/NP = M
|
||||
var/confirm = alert(src, "Remove [NP]'s respawn restrictions?", "Remove Restrictions", "Yes", "No")
|
||||
if(confirm != "Yes")
|
||||
return
|
||||
message_admins("[key_name_admin(src)] removed [ckey]'s respawn restrictions.")
|
||||
log_admin("[key_name(src)] removed [ckey]'s respawn restrictions")
|
||||
NP.client.prefs.respawn_restrictions_active = FALSE
|
||||
NP.client.prefs.dnr_triggered = FALSE
|
||||
to_chat(NP, "<span class='boldnotie'>Your respawn restrictions have been removed.")
|
||||
else
|
||||
CRASH("Invalid mobtype")
|
||||
|
||||
/**
|
||||
* Allows a ghost to bypass respawn delay without lifting respawn restrictions
|
||||
*/
|
||||
/client/proc/admin_cmd_remove_ghost_respawn_timer()
|
||||
set name = "Remove Respawn Timer for Player"
|
||||
set desc = "Removes a player's respawn timer without removing their respawning restrictions."
|
||||
set category = "Admin"
|
||||
|
||||
var/list/mob/dead/observer/valid = list()
|
||||
for(var/mob/dead/observer/I in GLOB.dead_mob_list)
|
||||
if(!I.client)
|
||||
continue
|
||||
valid["[I.ckey] - [I.name]"] = I
|
||||
|
||||
if(!valid.len)
|
||||
to_chat(src, "<span class='warning'>No logged in ghosts found.</span>")
|
||||
return
|
||||
var/mob/dead/observer/O = valid[input(src, "Choose a player (only showing logged in)", "Remove Respawn Timer") as null|anything in valid]
|
||||
|
||||
if(!O.client)
|
||||
to_chat(src, "<span class='warning'>[O] has no client.</span>")
|
||||
return
|
||||
var/timeleft = O.time_left_to_respawn()
|
||||
if(!timeleft)
|
||||
to_chat(src, "<span class='warning'>[O] can already respawn.")
|
||||
return
|
||||
message_admins("[key_name_admin(src)] removed [key_name_admin(O)]'s respawn timer.")
|
||||
log_admin("[key_name(src)] removed [key_name(O)]'s respawn timer.")
|
||||
O.client.prefs.respawn_time_of_death = -INFINITY
|
||||
to_chat(O, "<span class='boldnotice'>Your respawn timer has been removed.")
|
||||
|
||||
// ADMIN VERBS END
|
||||
|
||||
/**
|
||||
* Checks if we can latejoin on the currently selected slot, taking into account respawn status.
|
||||
*/
|
||||
/mob/dead/new_player/proc/respawn_latejoin_check(notify = FALSE)
|
||||
if(!client.prefs.respawn_restrictions_active)
|
||||
return TRUE
|
||||
var/can_same_person = CONFIG_GET(flag/allow_same_character_respawn)
|
||||
if(can_same_person)
|
||||
return TRUE
|
||||
var/nameless = client.prefs.nameless
|
||||
var/randomname = client.prefs.be_random_name
|
||||
var/randombody = client.prefs.be_random_body
|
||||
if(randombody && (nameless || randomname))
|
||||
return TRUE // somewhat unrecognizable
|
||||
if(client.prefs.slots_joined_as && (client.prefs.default_slot in client.prefs.slots_joined_as))
|
||||
if(notify)
|
||||
to_chat(src, "<span class='userdanger'>You cannot respawn on the same slot. Joined slots: [english_list(client.prefs.slots_joined_as)].")
|
||||
return FALSE
|
||||
if((!nameless && !randomname) && (client.prefs.characters_joined_as && (client.prefs.real_name in client.prefs.characters_joined_as)))
|
||||
if(notify)
|
||||
to_chat(src, "<span class='userdanger'>You cannot respawn on the same character. Joined slots: [english_list(client.prefs.characters_joined_as)].")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Attempts to respawn.
|
||||
*/
|
||||
/mob/dead/observer/verb/respawn()
|
||||
set name = "Respawn"
|
||||
set category = "OOC"
|
||||
|
||||
if(!CONFIG_GET(flag/respawns_enabled))
|
||||
to_chat(src, "<span class='warning'>Respawns are disabled in configuration.</span>")
|
||||
return
|
||||
|
||||
if(client.prefs.dnr_triggered)
|
||||
to_chat(src, "<span class='danger'>You cannot respawn as you have enabled DNR.</span>")
|
||||
return
|
||||
|
||||
var/roundstart_timeleft = (SSticker.round_start_time + (CONFIG_GET(number/respawn_minimum_delay_roundstart) * 600)) - world.time
|
||||
if(roundstart_timeleft > 0)
|
||||
to_chat(src, "<span class='warning'>It's been too short of a time since the round started! Please wait [CEILING(roundstart_timeleft / 600, 0.1)] more minutes.</span>")
|
||||
return
|
||||
|
||||
var/list/banned_modes = CONFIG_GET(keyed_list/respawn_chaos_gamemodes)
|
||||
if(SSticker.mode && banned_modes[lowertext(SSticker.mode.config_tag)])
|
||||
to_chat(src, "<span class='warning'>The current mode tag, [SSticker.mode.config_tag], is not eligible for respawn.</span>")
|
||||
return
|
||||
|
||||
var/timeleft = time_left_to_respawn()
|
||||
if(timeleft)
|
||||
to_chat(src, "<span class='warning'>It's been too short of a time since you died/observed! Please wait [round(timeleft / 600, 0.1)] more minutes.</span>")
|
||||
return
|
||||
do_respawn(TRUE)
|
||||
|
||||
/**
|
||||
* Gets time left until we can respawn. Returns 0 if we can respawn now.
|
||||
*/
|
||||
/mob/dead/observer/verb/time_left_to_respawn()
|
||||
ASSERT(client)
|
||||
return max(0, ((client.prefs.respawn_did_cryo? CONFIG_GET(number/respawn_delay_cryo) : CONFIG_GET(number/respawn_delay)) MINUTES + client.prefs.respawn_time_of_death) - world.time)
|
||||
|
||||
/**
|
||||
* Handles respawning
|
||||
*/
|
||||
/mob/dead/observer/proc/do_respawn(penalize)
|
||||
if(!client)
|
||||
return
|
||||
if(isnull(penalize))
|
||||
penalize = client.prefs.respawn_restrictions_active
|
||||
client.prefs.respawn_restrictions_active = penalize
|
||||
|
||||
message_admins("[key_name_admin(src)] was respawned to lobby [penalize? "with" : "without"] restrictions.")
|
||||
log_game("[key_name(src)] was respawned to lobby [penalize? "with" : "without"] restrictions.")
|
||||
var/mob/dead/new_player/N = transfer_to_lobby()
|
||||
|
||||
to_chat(N, "<span class='userdanger'>You have been respawned to the lobby. \
|
||||
Remember to take heed of rules regarding round knowledge - notably, that ALL past lives are forgotten. \
|
||||
Any character you join as has NO knowledge of round events unless specified otherwise by an admin.</span>")
|
||||
|
||||
/**
|
||||
* Actual proc that removes us and puts us back on lobby
|
||||
*
|
||||
* Returns the new mob.
|
||||
*/
|
||||
/mob/dead/observer/proc/transfer_to_lobby()
|
||||
if(!client) // if no one's in us we can just be deleted
|
||||
qdel(src)
|
||||
return
|
||||
client.screen.Cut()
|
||||
client.view_size.resetToDefault()
|
||||
client.generate_clickcatcher()
|
||||
client.apply_clickcatcher()
|
||||
client.view_size.setDefault(getScreenSize(client.prefs.widescreenpref))
|
||||
client.view_size.resetToDefault()
|
||||
|
||||
var/mob/dead/new_player/M = new /mob/dead/new_player
|
||||
M.ckey = ckey
|
||||
return M
|
||||
@@ -5,7 +5,7 @@
|
||||
silent = FALSE
|
||||
losebreath = 0
|
||||
|
||||
if(!gibbed)
|
||||
if(!gibbed && !HAS_TRAIT(src, TRAIT_DEATHCOMA))
|
||||
emote("deathgasp")
|
||||
|
||||
. = ..()
|
||||
|
||||
@@ -190,6 +190,11 @@
|
||||
message = "chimes."
|
||||
sound = 'sound/machines/chime.ogg'
|
||||
|
||||
/datum/emote/sound/human/squeak
|
||||
key = "squeak"
|
||||
message = "squeaks."
|
||||
sound = 'sound/effects/mousesqueek.ogg'
|
||||
|
||||
//rock paper scissors emote handling
|
||||
/mob/living/carbon/human/proc/beginRockPaperScissors(var/chosen_move)
|
||||
GLOB.rockpaperscissors_players[src] = list(chosen_move, ROCKPAPERSCISSORS_NOT_DECIDED)
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
AddComponent(/datum/component/mood)
|
||||
AddComponent(/datum/component/combat_mode)
|
||||
AddElement(/datum/element/flavor_text/carbon, _name = "Flavor Text", _save_key = "flavor_text")
|
||||
AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!")
|
||||
AddElement(/datum/element/flavor_text/carbon/temporary, "", "Set Pose (Temporary Flavor Text)", "This should be used only for things pertaining to the current round!", _save_key = null)
|
||||
AddElement(/datum/element/flavor_text, _name = "OOC Notes", _addendum = "Put information on ERP/vore/lewd-related preferences here. THIS SHOULD NOT CONTAIN REGULAR FLAVORTEXT!!", _always_show = TRUE, _save_key = "ooc_notes", _examine_no_preview = TRUE)
|
||||
|
||||
/mob/living/carbon/human/Destroy()
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
|
||||
|
||||
block_parry_data = /datum/block_parry_data/unarmed/human
|
||||
default_block_parry_data = /datum/block_parry_data/unarmed/human
|
||||
|
||||
//Hair colour and style
|
||||
var/hair_color = "000"
|
||||
@@ -98,20 +99,54 @@
|
||||
parry_failed_clickcd_duration = 0.4
|
||||
|
||||
parry_data = list( // yeah it's snowflake
|
||||
"HUMAN_PARRY_STAGGER" = 3 SECONDS,
|
||||
"HUMAN_PARRY_PUNCH" = TRUE,
|
||||
"HUMAN_PARRY_MININUM_EFFICIENCY" = 0.9
|
||||
"UNARMED_PARRY_STAGGER" = 3 SECONDS,
|
||||
"UNARMED_PARRY_PUNCH" = TRUE,
|
||||
"UNARMED_PARRY_MININUM_EFFICIENCY" = 90
|
||||
)
|
||||
|
||||
/mob/living/carbon/human/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time)
|
||||
/mob/living/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time)
|
||||
var/datum/block_parry_data/D = return_block_parry_datum(block_parry_data)
|
||||
. = ..()
|
||||
if(!owner.Adjacent(attacker))
|
||||
return ..()
|
||||
if(parry_efficiency < D.parry_data["HUMAN_PARRY_MINIMUM_EFFICIENCY"])
|
||||
return ..()
|
||||
return
|
||||
if(parry_efficiency < D.parry_data["UNARMED_PARRY_MINIMUM_EFFICIENCY"])
|
||||
return
|
||||
visible_message("<span class='warning'>[src] strikes back perfectly at [attacker], staggering them!</span>")
|
||||
if(D.parry_data["HUMAN_PARRY_PUNCH"])
|
||||
if(D.parry_data["UNARMED_PARRY_PUNCH"])
|
||||
UnarmedAttack(attacker, TRUE, INTENT_HARM, ATTACK_IS_PARRY_COUNTERATTACK | ATTACK_IGNORE_ACTION | ATTACK_IGNORE_CLICKDELAY | NO_AUTO_CLICKDELAY_HANDLING)
|
||||
var/mob/living/L = attacker
|
||||
if(istype(L))
|
||||
L.Stagger(D.parry_data["HUMAN_PARRY_STAGGER"])
|
||||
L.Stagger(D.parry_data["UNARMED_PARRY_STAGGER"])
|
||||
|
||||
/// Unarmed parry data for pugilists
|
||||
/datum/block_parry_data/unarmed/pugilist
|
||||
parry_respect_clickdelay = FALSE
|
||||
parry_stamina_cost = 4
|
||||
parry_attack_types = ATTACK_TYPE_UNARMED | ATTACK_TYPE_PROJECTILE | ATTACK_TYPE_TACKLE | ATTACK_TYPE_THROWN | ATTACK_TYPE_MELEE
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING
|
||||
|
||||
parry_time_windup = 0
|
||||
parry_time_spindown = 0
|
||||
parry_time_active = 5
|
||||
|
||||
parry_time_perfect = 1.5
|
||||
parry_time_perfect_leeway = 1.5
|
||||
parry_imperfect_falloff_percent = 20
|
||||
parry_efficiency_perfect = 100
|
||||
parry_efficiency_perfect_override = list(
|
||||
ATTACK_TYPE_PROJECTILE_TEXT = 60,
|
||||
)
|
||||
|
||||
parry_efficiency_considered_successful = 0.01
|
||||
parry_efficiency_to_counterattack = 0.01
|
||||
parry_max_attacks = INFINITY
|
||||
parry_failed_cooldown_duration = 1.5 SECONDS
|
||||
parry_failed_stagger_duration = 0
|
||||
parry_cooldown = 0
|
||||
parry_failed_clickcd_duration = 0.8
|
||||
|
||||
parry_data = list( // yeah it's snowflake
|
||||
"UNARMED_PARRY_STAGGER" = 3 SECONDS,
|
||||
"UNARMED_PARRY_PUNCH" = TRUE,
|
||||
"UNARMED_PARRY_MININUM_EFFICIENCY" = 90
|
||||
)
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
|
||||
H.add_movespeed_modifier(/datum/movespeed_modifier/slime_puddle)
|
||||
|
||||
H.layer -= 1 //go one layer down so people go over you
|
||||
ENABLE_BITFIELD(H.pass_flags, PASSMOB) //this actually lets people pass over you
|
||||
squeak = H.AddComponent(/datum/component/squeak, custom_sounds = list('sound/effects/blobattack.ogg')) //blorble noise when people step on you
|
||||
|
||||
@@ -103,7 +102,6 @@
|
||||
REMOVE_TRAIT(H, TRAIT_HUMAN_NO_RENDER, SLIMEPUDDLE_TRAIT)
|
||||
H.update_disabled_bodyparts(silent = TRUE)
|
||||
H.remove_movespeed_modifier(/datum/movespeed_modifier/slime_puddle)
|
||||
H.layer += 1 //go one layer back above!
|
||||
DISABLE_BITFIELD(H.pass_flags, PASSMOB)
|
||||
is_puddle = FALSE
|
||||
if(squeak)
|
||||
|
||||
@@ -139,6 +139,18 @@
|
||||
if(E.web_ready == FALSE)
|
||||
to_chat(H, "<span class='warning'>You need to wait awhile to regenerate web fluid.</span>")
|
||||
return
|
||||
if(!H.Adjacent(A)) //No.
|
||||
return
|
||||
if(!isliving(A) && A.anchored)
|
||||
to_chat(H, "<span class='warning'>[A] is bolted to the floor!</span>")
|
||||
return
|
||||
if(istype(A, /obj/structure/arachnid))
|
||||
to_chat(H, "<span class='warning'>No double wrapping.</span>")
|
||||
return
|
||||
if(istype(A, /obj/effect))
|
||||
to_chat(H, "<span class='warning'>You cannot wrap this.</span>")
|
||||
return
|
||||
H.visible_message("<span class='danger'>[H] starts to wrap [A] into a cocoon!</span>","<span class='warning'>You start to wrap [A] into a cocoon.</span>")
|
||||
if(!do_after(H, 10 SECONDS, 1, A))
|
||||
to_chat(H, "<span class='warning'>Your web spinning was interrupted!</span>")
|
||||
return
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
/datum/species/dullahan/check_roundstart_eligible()
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
|
||||
return TRUE
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/species/dullahan/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
|
||||
. = ..()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR,HAS_FLESH)
|
||||
mutantlungs = /obj/item/organ/lungs/slime
|
||||
mutant_heart = /obj/item/organ/heart/slime
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None", "legs" = "Plantigrade")
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
|
||||
gib_types = list(/obj/effect/gibspawner/slime, /obj/effect/gibspawner/slime/bodypartless)
|
||||
@@ -406,7 +406,7 @@
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None", "legs" = "Plantigrade")
|
||||
say_mod = "says"
|
||||
hair_color = "mutcolor"
|
||||
hair_alpha = 160 //a notch brighter so it blends better.
|
||||
|
||||
@@ -66,6 +66,10 @@
|
||||
GLOB.alive_mob_list -= src
|
||||
if(!gibbed)
|
||||
GLOB.dead_mob_list += src
|
||||
if(ckey)
|
||||
var/datum/preferences/P = GLOB.preferences_datums[ckey]
|
||||
if(P)
|
||||
P.respawn_time_of_death = world.time
|
||||
set_drugginess(0)
|
||||
set_disgust(0)
|
||||
SetSleeping(0, 0)
|
||||
|
||||
@@ -264,9 +264,9 @@
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/has_tail()
|
||||
if(!dna || !dna.features)
|
||||
if(!dna || !dna.species)
|
||||
return ..()
|
||||
var/list/L = dna.features // caches list because i refuse to type it out and because performance
|
||||
var/list/L = dna.species.mutant_bodyparts // caches list because i refuse to type it out and because performance
|
||||
return (L["mam_tail"] && (L["mam_tail"] != "None")) || (L["tail_human"] && (L["tail_human"] != "None")) || (L["tail_lizard"] && (L["tail_lizard"] != "None"))
|
||||
|
||||
/mob/living/start_pulling(atom/movable/AM, state, force = pull_force, supress_message = FALSE)
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
handle_parry_ending_effects(data, effect_text)
|
||||
parrying = NOT_PARRYING
|
||||
parry_start_time = 0
|
||||
parry_end_time_last = world.time
|
||||
parry_end_time_last = world.time + (successful? 0 : data.parry_failed_cooldown_duration)
|
||||
successful_parries = null
|
||||
|
||||
/**
|
||||
|
||||
@@ -154,6 +154,8 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
var/parry_failed_stagger_duration = 3.5 SECONDS
|
||||
/// Clickdelay duration post-parry if you fail to parry an attack
|
||||
var/parry_failed_clickcd_duration = 2 SECONDS
|
||||
/// Parry cooldown post-parry if failed. This is ADDED to parry_cooldown!!!
|
||||
var/parry_failed_cooldown_duration = 0 SECONDS
|
||||
|
||||
/**
|
||||
* Quirky proc to get average of flags in list that are in attack_type because why is attack_type a flag.
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
// Combat - Blocking/Parrying system
|
||||
/// Our block_parry_data for unarmed blocks/parries. Currently only used for parrying, as unarmed block isn't implemented yet. YOU MUST RUN [get_block_parry_data(this)] INSTEAD OF DIRECTLY ACCESSING!
|
||||
var/datum/block_parry_data/block_parry_data = /datum/block_parry_data // defaults to *something* because [combat_flags] dictates whether or not we can unarmed block/parry.
|
||||
/// Default
|
||||
var/datum/block_parry_data/default_block_parry_data = /datum/block_parry_data
|
||||
/// If we're a pugilist
|
||||
var/datum/block_parry_data/pugilist_block_parry_data = /datum/block_parry_data/unarmed/pugilist
|
||||
// Blocking
|
||||
/// The item the user is actively blocking with if any.
|
||||
var/obj/item/active_block_item
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
/// IN THE FUTURE, WE WILL PROBABLY REFACTOR TO LESSEN THE NEED FOR UPDATE_MOBILITY, BUT FOR NOW.. WE CAN START DOING THIS.
|
||||
/// FOR BLOCKING MOVEMENT, USE TRAIT_MOBILITY_NOMOVE AS MUCH AS POSSIBLE. IT WILL MAKE REFACTORS IN THE FUTURE EASIER.
|
||||
/mob/living/ComponentInitialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOMOVE), .proc/update_mobility)
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOPICKUP), .proc/update_mobility)
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOUSE), .proc/update_mobility)
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOREST), .proc/update_mobility)
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_LIVING_NO_DENSITY), .proc/update_density)
|
||||
|
||||
//Stuff like mobility flag updates, resting updates, etc.
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/// IN THE FUTURE, WE WILL PROBABLY REFACTOR TO LESSEN THE NEED FOR UPDATE_MOBILITY, BUT FOR NOW.. WE CAN START DOING THIS.
|
||||
/// FOR BLOCKING MOVEMENT, USE TRAIT_MOBILITY_NOMOVE AS MUCH AS POSSIBLE. IT WILL MAKE REFACTORS IN THE FUTURE EASIER.
|
||||
/mob/living/ComponentInitialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOMOVE), .proc/update_mobility)
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOPICKUP), .proc/update_mobility)
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOUSE), .proc/update_mobility)
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOREST), .proc/update_mobility)
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_LIVING_NO_DENSITY), .proc/update_density)
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_PUGILIST), .proc/update_pugilism)
|
||||
|
||||
/mob/living/proc/update_pugilism()
|
||||
if(HAS_TRAIT(src, TRAIT_PUGILIST))
|
||||
combat_flags |= COMBAT_FLAG_UNARMED_PARRY
|
||||
block_parry_data = pugilist_block_parry_data
|
||||
else
|
||||
var/initial_combat_flags = initial(combat_flags)
|
||||
if(!(initial_combat_flags & COMBAT_FLAG_UNARMED_PARRY))
|
||||
combat_flags &= ~COMBAT_FLAG_UNARMED_PARRY
|
||||
block_parry_data = default_block_parry_data
|
||||
@@ -1,3 +1,30 @@
|
||||
/mob/living/silicon/verb/clear_custom_holoform()
|
||||
set name = "Clear Custom Holoform"
|
||||
set desc = "Clear your current custom holoform"
|
||||
set category = "OOC"
|
||||
if(!client.prefs)
|
||||
to_chat(src, "<span class='boldwarning'>No preferences datum on your client, contact an admin/coder!</span>")
|
||||
return
|
||||
client.prefs.custom_holoform_icon = null
|
||||
client.prefs.cached_holoform_icons = null
|
||||
to_chat(src, "<span class='boldnotice'>Holoform removed.</span>")
|
||||
|
||||
/mob/living/silicon/verb/set_custom_holoform()
|
||||
set name = "Set Custom Holoform"
|
||||
set desc = "Set your custom holoform using your current preferences slot and a specified set of gear."
|
||||
if(!client.prefs)
|
||||
to_chat(src, "<span class='boldwarning'>No preferences datum on your client, contact an admin/coder!</span>")
|
||||
return
|
||||
if(client.prefs.last_custom_holoform > world.time - CUSTOM_HOLOFORM_DELAY)
|
||||
to_chat(src, "<span class='warning'>You are attempting to change custom holoforms too fast!</span>")
|
||||
|
||||
var/icon/new_holoform = user_interface_custom_holoform(client)
|
||||
if(new_holoform)
|
||||
client.prefs.custom_holoform_icon = new_holoform
|
||||
client.prefs.cached_holoform_icons = null
|
||||
client.prefs.last_custom_holoform = world.time
|
||||
to_chat(src, "<span class='boldnotice'>Holoform set.</span>")
|
||||
|
||||
/mob/living/silicon/proc/attempt_set_custom_holoform()
|
||||
if(!client.prefs)
|
||||
to_chat(src, "<span class='boldwarning'>No preferences datum on your client, contact an admin/coder!</span>")
|
||||
|
||||
@@ -9,6 +9,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
real_name = "Guardian Spirit"
|
||||
desc = "A mysterious being that stands by its charge, ever vigilant."
|
||||
speak_emote = list("hisses")
|
||||
rad_flags = RAD_NO_CONTAMINATE | RAD_PROTECT_CONTENTS
|
||||
gender = NEUTER
|
||||
mob_biotypes = NONE
|
||||
bubble_icon = "guardian"
|
||||
|
||||
@@ -1034,3 +1034,159 @@
|
||||
|
||||
/mob/living/simple_animal/parrot/clock_hawk/ratvar_act()
|
||||
return
|
||||
|
||||
// Different Parrot Breeds
|
||||
|
||||
/mob/living/simple_animal/parrot/kea
|
||||
name = "Kea"
|
||||
icon_state = "kea-flap"
|
||||
icon_living = "kea-flap"
|
||||
icon_dead = "kea-dead"
|
||||
icon_sit = "kea_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/eclectusr
|
||||
name = "Eclectus"
|
||||
icon_state = "eclectusr-flap"
|
||||
icon_living = "eclectusr-flap"
|
||||
icon_dead = "eclectusr-dead"
|
||||
icon_sit = "electusr_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/eclectus
|
||||
name = "Eclectus"
|
||||
icon_state = "eclectus-flap"
|
||||
icon_living = "eclectus-flap"
|
||||
icon_dead = "eclectus-dead"
|
||||
icon_sit = "electus_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/eclectusf
|
||||
name = "Eclectus"
|
||||
icon_state = "eclectusf-flap"
|
||||
icon_living = "eclectusf-flap"
|
||||
icon_dead = "eclectusf-dead"
|
||||
icon_sit = "electusf_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/greybird
|
||||
name = "Grey Bird"
|
||||
icon_state = "agrey-flap"
|
||||
icon_living = "agrey-flap"
|
||||
icon_dead = "agrey-dead"
|
||||
icon_sit = "agrey_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/blue_caique
|
||||
name = "Blue Caique "
|
||||
icon_state = "bcaique-flap"
|
||||
icon_living = "bcaique-flap"
|
||||
icon_dead = "bcaique-dead"
|
||||
icon_sit = "bcaique_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/white_caique
|
||||
name = "White caique"
|
||||
icon_state = "wcaique-flap"
|
||||
icon_living = "wcaique-flap"
|
||||
icon_dead = "wcaique-dead"
|
||||
icon_sit = "wcaique_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/green_budgerigar
|
||||
name = "Green Budgerigar"
|
||||
icon_state = "gbudge-flap"
|
||||
icon_living = "gbudge-flap"
|
||||
icon_dead = "gbudge-dead"
|
||||
icon_sit = "gbudge_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/blue_Budgerigar
|
||||
name = "Blue Budgerigar"
|
||||
icon_state = "bbudge-flap"
|
||||
icon_living = "bbudge-flap"
|
||||
icon_dead = "bbudge-dead"
|
||||
icon_sit = "bbudge_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/bluegreen_Budgerigar
|
||||
name = "Bluegreen Budgerigar"
|
||||
icon_state = "bgbudge-flap"
|
||||
icon_living = "bgbudge-flap"
|
||||
icon_dead = "bgbudge-dead"
|
||||
icon_sit = "bgbudge_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/commonblackbird
|
||||
name = "Black Bird"
|
||||
icon_state = "commonblackbird"
|
||||
icon_living = "commonblackbird"
|
||||
icon_dead = "commonblackbird-dead"
|
||||
icon_sit = "commonblackbird_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/azuretit
|
||||
name = "Azure Tit"
|
||||
icon_state = "azuretit"
|
||||
icon_living = "azuretit"
|
||||
icon_dead = "azuretit-dead"
|
||||
icon_sit = "azuretit_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/europeanrobin
|
||||
name = "European Robin"
|
||||
icon_state = "europeanrobin"
|
||||
icon_living = "europeanrobin"
|
||||
icon_dead = "europeanrobin-dead"
|
||||
icon_sit = "europeanrobin_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/goldcrest
|
||||
name = "Goldcrest"
|
||||
icon_state = "goldcrest"
|
||||
icon_living = "goldcrest"
|
||||
icon_dead = "goldcrest-dead"
|
||||
icon_sit = "goldencrest_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/ringneckdove
|
||||
name = "Ringneck Dove"
|
||||
icon_state = "ringneckdove"
|
||||
icon_living = "ringneckdove"
|
||||
icon_dead = "ringneckdove-dead"
|
||||
icon_sit = "ringneckdove_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/cockatiel
|
||||
name = "Cockatiel"
|
||||
icon_state = "tiel-flap"
|
||||
icon_living = "tiel-flap"
|
||||
icon_dead = "tiel-dead"
|
||||
icon_sit = "tiel_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/white_cockatiel
|
||||
name = "White Cockatiel"
|
||||
icon_state = "wtiel-flap"
|
||||
icon_living = "wtiel-flap"
|
||||
icon_dead = "wtiel-dead"
|
||||
icon_sit = "wtiel_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/yellowish_cockatiel
|
||||
name = "Yellowish Cockatiel"
|
||||
icon_state = "luttiel-flap"
|
||||
icon_living = "luttiel-flap"
|
||||
icon_dead = "luttiel-dead"
|
||||
icon_sit = "luttiel_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/grey_cockatiel
|
||||
name = "Grey Cockatiel"
|
||||
icon_state = "blutiel-flap"
|
||||
icon_living = "blutiel-flap"
|
||||
icon_dead = "blutiel-dead"
|
||||
icon_sit = "blutiel_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/too
|
||||
name = "Too"
|
||||
icon_state = "too-flap"
|
||||
icon_living = "too-flap"
|
||||
icon_dead = "too-dead"
|
||||
icon_sit = "too_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/hooded_too
|
||||
name = "Utoo"
|
||||
icon_state = "utoo-flap"
|
||||
icon_living = "utoo-flap"
|
||||
icon_dead = "utoo-dead"
|
||||
icon_sit = "utoo_sit"
|
||||
|
||||
/mob/living/simple_animal/parrot/pink_too
|
||||
name = "Mtoo"
|
||||
icon_state = "mtoo-flap"
|
||||
icon_living = "mtoo-flap"
|
||||
icon_dead = "mtoo-dead"
|
||||
icon_sit = "mtoo_sit"
|
||||
+6
-33
@@ -457,39 +457,6 @@
|
||||
else
|
||||
to_chat(src, "You don't have a mind datum for some reason, so you can't add a note to it.")
|
||||
|
||||
/mob/verb/abandon_mob()
|
||||
set name = "Respawn"
|
||||
set category = "OOC"
|
||||
|
||||
if (CONFIG_GET(flag/norespawn))
|
||||
return
|
||||
if ((stat != DEAD || !( SSticker )))
|
||||
to_chat(usr, "<span class='boldnotice'>You must be dead to use this!</span>")
|
||||
return
|
||||
|
||||
log_game("[key_name(usr)] used abandon mob.")
|
||||
|
||||
to_chat(usr, "<span class='boldnotice'>Please roleplay correctly!</span>")
|
||||
|
||||
if(!client)
|
||||
log_game("[key_name(usr)] AM failed due to disconnect.")
|
||||
return
|
||||
client.screen.Cut()
|
||||
client.screen += client.void
|
||||
if(!client)
|
||||
log_game("[key_name(usr)] AM failed due to disconnect.")
|
||||
return
|
||||
|
||||
var/mob/dead/new_player/M = new /mob/dead/new_player()
|
||||
if(!client)
|
||||
log_game("[key_name(usr)] AM failed due to disconnect.")
|
||||
qdel(M)
|
||||
return
|
||||
|
||||
M.key = key
|
||||
// M.Login() //wat
|
||||
return
|
||||
|
||||
/mob/proc/transfer_ckey(mob/new_mob, send_signal = TRUE)
|
||||
if(!new_mob || (!ckey && new_mob.ckey))
|
||||
CRASH("transfer_ckey() called [new_mob ? "on ckey-less mob with a player mob as target" : "without a valid mob target"]!")
|
||||
@@ -1002,6 +969,12 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
switch(var_name)
|
||||
if("logging")
|
||||
return debug_variable(var_name, logging, 0, src, FALSE)
|
||||
if(NAMEOF(src, lastKnownIP))
|
||||
if(!check_rights(R_SENSITIVE, FALSE))
|
||||
return "SENSITIVE"
|
||||
if(NAMEOF(src, computer_id))
|
||||
if(!check_rights(R_SENSITIVE, FALSE))
|
||||
return "SENSITIVE"
|
||||
. = ..()
|
||||
|
||||
/mob/vv_auto_rename(new_name)
|
||||
|
||||
@@ -86,15 +86,6 @@ proc/get_top_level_mob(var/mob/S)
|
||||
else if(!params)
|
||||
var/subtle_emote = stripped_multiline_input_or_reflect(user, "Choose an emote to display.", "Subtler" , null, MAX_MESSAGE_LEN)
|
||||
if(subtle_emote && !check_invalid(user, subtle_emote))
|
||||
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
|
||||
switch(type)
|
||||
if("Visible")
|
||||
emote_type = EMOTE_VISIBLE
|
||||
if("Hearable")
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
else
|
||||
alert("Unable to use this emote, must be either hearable or visible.")
|
||||
return
|
||||
message = subtle_emote
|
||||
else
|
||||
return FALSE
|
||||
@@ -111,6 +102,80 @@ proc/get_top_level_mob(var/mob/S)
|
||||
|
||||
user.visible_message(message = message, self_message = message, vision_distance = 1, ignored_mobs = GLOB.dead_mob_list, omni = TRUE)
|
||||
|
||||
///////////////// SUBTLE 3: DARE DICE
|
||||
|
||||
/datum/emote/living/subtler_table
|
||||
key = "subtler_table"
|
||||
key_third_person = "subtler_table"
|
||||
message = null
|
||||
mob_type_blacklist_typecache = list(/mob/living/brain)
|
||||
|
||||
/datum/emote/living/subtler_table/proc/check_invalid(mob/user, input)
|
||||
if(stop_bad_mime.Find(input, 1, 1))
|
||||
to_chat(user, "<span class='danger'>Invalid emote.</span>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/emote/living/subtler_table/run_emote(mob/user, params, type_override = null)
|
||||
if(!locate(/obj/structure/table) in range(user, 1))
|
||||
to_chat(user, "There are no tables around you.")
|
||||
return FALSE
|
||||
if(jobban_isbanned(user, "emote"))
|
||||
to_chat(user, "You cannot send subtle emotes (banned).")
|
||||
return FALSE
|
||||
else if(user.client && user.client.prefs.muted & MUTE_IC)
|
||||
to_chat(user, "You cannot send IC messages (muted).")
|
||||
return FALSE
|
||||
else if(!params)
|
||||
var/subtle_emote = stripped_multiline_input_or_reflect(user, "Choose an emote to display.", "Subtler" , null, MAX_MESSAGE_LEN)
|
||||
if(subtle_emote && !check_invalid(user, subtle_emote))
|
||||
message = subtle_emote
|
||||
else
|
||||
return FALSE
|
||||
else
|
||||
message = params
|
||||
if(type_override)
|
||||
emote_type = type_override
|
||||
. = TRUE
|
||||
if(!can_run_emote(user))
|
||||
return FALSE
|
||||
|
||||
user.log_message("[message] (TABLE-WRAPPING)", LOG_SUBTLER)
|
||||
message = "<span class='emote'><b>[user]</b> <i>[user.say_emphasis(message)]</i></span>"
|
||||
|
||||
var/list/show_to = list()
|
||||
var/list/processing = list()
|
||||
var/safety = 25
|
||||
for(var/obj/structure/table/T in range(user, 1))
|
||||
processing |= T
|
||||
for(var/i in processing)
|
||||
var/obj/structure/table/T = i
|
||||
if(safety-- <= 0)
|
||||
to_chat(user, "Table scan aborted early, some people might have not received the message (max 25)")
|
||||
break
|
||||
if(get_dist(T, user) > 7)
|
||||
continue // nah
|
||||
processing |= T
|
||||
for(var/mob/living/M in range(T, 1)) // no ghosts/cameramobs
|
||||
show_to |= M
|
||||
var/obj/structure/table/other
|
||||
other = locate() in get_step(T, NORTH)
|
||||
if(other)
|
||||
processing |= other
|
||||
other = locate() in get_step(T, SOUTH)
|
||||
if(other)
|
||||
processing |= other
|
||||
other = locate() in get_step(T, WEST)
|
||||
if(other)
|
||||
processing |= other
|
||||
other = locate() in get_step(T, EAST)
|
||||
if(other)
|
||||
processing |= other
|
||||
|
||||
for(var/i in show_to)
|
||||
var/mob/M = i
|
||||
M.show_message(message)
|
||||
|
||||
///////////////// VERB CODE
|
||||
/mob/living/verb/subtle()
|
||||
set name = "Subtle"
|
||||
@@ -128,3 +193,12 @@ proc/get_top_level_mob(var/mob/S)
|
||||
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
|
||||
return
|
||||
usr.emote("subtler")
|
||||
|
||||
///////////////// VERB CODE 3
|
||||
/mob/living/verb/subtler_table()
|
||||
set name = "Subtler Around Table"
|
||||
set category = "IC"
|
||||
if(GLOB.say_disabled) //This is dumb but it's here because heehoo copypaste, who the FUCK uses this to identify lag?
|
||||
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
|
||||
return
|
||||
usr.emote("subtler_table")
|
||||
|
||||
@@ -1082,11 +1082,12 @@
|
||||
if("lockdown")
|
||||
var/celluse = rand(20,35)
|
||||
celluse = celluse /100
|
||||
if(!cell.use(cell.maxcharge*celluse))
|
||||
return
|
||||
for (var/obj/machinery/door/D in GLOB.airlocks)
|
||||
if (get_area(D) == area)
|
||||
INVOKE_ASYNC(D,/obj/machinery/door.proc/hostile_lockdown,usr, FALSE)
|
||||
addtimer(CALLBACK(D,/obj/machinery/door.proc/disable_lockdown, FALSE), 30 SECONDS)
|
||||
cell.charge -= cell.maxcharge*celluse
|
||||
var/obj/item/implant/hijack/H = usr.getImplant(/obj/item/implant/hijack)
|
||||
H.stealthcooldown = world.time + 3 MINUTES
|
||||
if("occupy")
|
||||
|
||||
@@ -86,6 +86,8 @@
|
||||
|
||||
// recharge the cell
|
||||
/obj/item/stock_parts/cell/proc/give(amount)
|
||||
if(amount < 0)
|
||||
return
|
||||
if(rigged && amount > 0)
|
||||
explode()
|
||||
return 0
|
||||
|
||||
@@ -100,6 +100,10 @@
|
||||
var/impact_light_intensity = 3
|
||||
var/impact_light_range = 2
|
||||
var/impact_light_color_override
|
||||
// Normal lighting effects
|
||||
var/fired_light_intensity = 1
|
||||
var/fired_light_range = 0
|
||||
var/fired_light_color = rgb(255, 255, 255)
|
||||
|
||||
//Homing
|
||||
var/homing = FALSE
|
||||
@@ -506,6 +510,7 @@
|
||||
transform = M
|
||||
trajectory_ignore_forcemove = TRUE
|
||||
forceMove(starting)
|
||||
set_light(fired_light_range, fired_light_intensity, fired_light_color)
|
||||
trajectory_ignore_forcemove = FALSE
|
||||
if(isnull(pixel_increment_amount))
|
||||
pixel_increment_amount = SSprojectiles.global_pixel_increment_amount
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
icon_state = "magjectile"
|
||||
damage = 20
|
||||
armour_penetration = 20
|
||||
light_range = 3
|
||||
fired_light_range = 3
|
||||
pixels_per_second = TILES_TO_PIXELS(16.667)
|
||||
range = 35
|
||||
light_color = LIGHT_COLOR_RED
|
||||
fired_light_color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/item/projectile/bullet/magnetic/disabler
|
||||
icon_state = "magjectile-nl" //nl stands for non-lethal
|
||||
damage = 2
|
||||
armour_penetration = 10
|
||||
stamina = 20
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
fired_light_color = LIGHT_COLOR_BLUE
|
||||
|
||||
/obj/item/projectile/bullet/magnetic/weak
|
||||
damage = 15
|
||||
armour_penetration = 10
|
||||
light_range = 2
|
||||
fired_light_range = 2
|
||||
range = 25
|
||||
|
||||
/obj/item/projectile/bullet/magnetic/weak/disabler
|
||||
@@ -30,8 +30,8 @@
|
||||
stamina = 10
|
||||
movement_type = FLYING | UNSTOPPABLE
|
||||
range = 6
|
||||
light_range = 1
|
||||
light_color = LIGHT_COLOR_RED
|
||||
fired_light_range = 1
|
||||
fired_light_color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/mag_inferno
|
||||
icon_state = "magjectile-large"
|
||||
@@ -40,8 +40,8 @@
|
||||
movement_type = FLYING | UNSTOPPABLE
|
||||
range = 20
|
||||
pixels_per_second = TILES_TO_PIXELS(12.5)
|
||||
light_range = 4
|
||||
light_color = LIGHT_COLOR_RED
|
||||
fired_light_range = 4
|
||||
fired_light_color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/mag_inferno/on_hit(atom/target, blocked = FALSE)
|
||||
..()
|
||||
|
||||
@@ -171,11 +171,13 @@
|
||||
|
||||
/datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/L)
|
||||
..()
|
||||
L.ignore_slowdown(type)
|
||||
ADD_TRAIT(L, TRAIT_IGNOREDAMAGESLOWDOWN, type)
|
||||
L.update_movespeed()
|
||||
ADD_TRAIT(L, TRAIT_TASED_RESISTANCE, type)
|
||||
|
||||
/datum/reagent/drug/methamphetamine/on_mob_end_metabolize(mob/living/L)
|
||||
L.unignore_slowdown(type)
|
||||
REMOVE_TRAIT(L, TRAIT_IGNOREDAMAGESLOWDOWN, type)
|
||||
L.update_movespeed()
|
||||
REMOVE_TRAIT(L, TRAIT_TASED_RESISTANCE, type)
|
||||
..()
|
||||
|
||||
|
||||
@@ -633,7 +633,7 @@
|
||||
value = REAGENT_VALUE_RARE
|
||||
|
||||
/datum/reagent/medicine/sal_acid
|
||||
name = "Salicyclic Acid"
|
||||
name = "Salicylic Acid"
|
||||
description = "Stimulates the healing of severe bruises. Extremely rapidly heals severe bruising and slowly heals minor ones. Overdose will worsen existing bruising."
|
||||
reagent_state = LIQUID
|
||||
color = "#D2D2D2"
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
required_reagents = list(/datum/reagent/medicine/pen_acid = 1, /datum/reagent/toxin/slimejelly = 1)
|
||||
|
||||
/datum/chemical_reaction/sal_acid
|
||||
name = "Salicyclic Acid"
|
||||
name = "Salicylic Acid"
|
||||
id = /datum/reagent/medicine/sal_acid
|
||||
results = list(/datum/reagent/medicine/sal_acid = 5)
|
||||
required_reagents = list(/datum/reagent/sodium = 1, /datum/reagent/phenol = 1, /datum/reagent/carbon = 1, /datum/reagent/oxygen = 1, /datum/reagent/toxin/acid = 1)
|
||||
@@ -305,12 +305,6 @@
|
||||
results = list(/datum/reagent/medicine/regen_jelly = 2)
|
||||
required_reagents = list(/datum/reagent/medicine/tricordrazine = 1, /datum/reagent/toxin/slimejelly = 1)
|
||||
|
||||
/datum/chemical_reaction/jelly_convert
|
||||
name = "Blood Jelly Conversion"
|
||||
id = /datum/reagent/toxin/slimejelly
|
||||
results = list(/datum/reagent/toxin/slimejelly = 1)
|
||||
required_reagents = list(/datum/reagent/toxin = 1, /datum/reagent/blood/jellyblood = 1)
|
||||
|
||||
/datum/chemical_reaction/corazone
|
||||
name = "Corazone"
|
||||
id = /datum/reagent/medicine/corazone
|
||||
|
||||
@@ -81,6 +81,12 @@
|
||||
var/obj/machinery/portable_atmospherics/P = item_to_retrieve.loc
|
||||
P.disconnect()
|
||||
P.update_icon()
|
||||
else if(istype(item_to_retrieve.loc, /obj/machinery/disposal) || istype(item_to_retrieve.loc, /obj/structure/disposalpipe)) //If it's in disposals, only recall the item.
|
||||
break
|
||||
else if(istype(item_to_retrieve.loc, /obj/machinery/nuclearbomb)) //I feel like yandev
|
||||
break //Just to be sure.
|
||||
|
||||
|
||||
|
||||
item_to_retrieve = item_to_retrieve.loc
|
||||
|
||||
|
||||
@@ -699,6 +699,8 @@
|
||||
else
|
||||
if(species_id in GLOB.greyscale_limb_types) //should they have greyscales?
|
||||
base_bp_icon = DEFAULT_BODYPART_ICON_ORGANIC
|
||||
else
|
||||
base_bp_icon = DEFAULT_BODYPART_ICON
|
||||
|
||||
if(base_bp_icon != DEFAULT_BODYPART_ICON)
|
||||
color_src = mut_colors ? MUTCOLORS : ((H.dna.skin_tone_override && S.use_skintones == USE_SKINTONES_GRAYSCALE_CUSTOM) ? CUSTOM_SKINTONE : SKINTONE)
|
||||
|
||||
@@ -98,18 +98,19 @@
|
||||
return json_encode(response)
|
||||
|
||||
/datum/tgs_api/v5/OnTopic(T)
|
||||
if(!initialized)
|
||||
return FALSE //continue world/Topic
|
||||
|
||||
var/list/params = params2list(T)
|
||||
var/json = params[DMAPI5_TOPIC_DATA]
|
||||
if(!json)
|
||||
return FALSE
|
||||
return FALSE // continue to /world/Topic
|
||||
|
||||
var/list/topic_parameters = json_decode(json)
|
||||
if(!topic_parameters)
|
||||
return TopicResponse("Invalid topic parameters json!");
|
||||
|
||||
if(!initialized)
|
||||
TGS_WARNING_LOG("Missed topic due to not being initialized: [T]")
|
||||
return TRUE // too early to handle, but it's still our responsibility
|
||||
|
||||
var/their_sCK = topic_parameters[DMAPI5_PARAMETER_ACCESS_IDENTIFIER]
|
||||
if(their_sCK != access_identifier)
|
||||
return TopicResponse("Failed to decode [DMAPI5_PARAMETER_ACCESS_IDENTIFIER] from: [json]!");
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
canmove = TRUE
|
||||
density = FALSE //Thought I couldn't fix this one easily, phew
|
||||
arms_required = 1
|
||||
var/override_movespeed = FALSE
|
||||
|
||||
/obj/vehicle/ridden/wheelchair/Initialize()
|
||||
. = ..()
|
||||
@@ -42,10 +43,11 @@
|
||||
canmove = FALSE
|
||||
addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
|
||||
return FALSE
|
||||
var/datum/component/riding/D = GetComponent(/datum/component/riding)
|
||||
//1.5 (movespeed as of this change) multiplied by 6.7 gets ABOUT 10 (rounded), the old constant for the wheelchair that gets divided by how many arms they have
|
||||
//if that made no sense this simply makes the wheelchair speed change along with movement speed delay
|
||||
D.vehicle_move_delay = round((CONFIG_GET(number/movedelay/run_delay) * 4) / min(user.get_num_arms(), 2), world.tick_lag)
|
||||
if(!override_movespeed)
|
||||
var/datum/component/riding/D = GetComponent(/datum/component/riding)
|
||||
//1.5 (movespeed as of this change) multiplied by 6.7 gets ABOUT 10 (rounded), the old constant for the wheelchair that gets divided by how many arms they have
|
||||
//if that made no sense this simply makes the wheelchair speed change along with movement speed delay
|
||||
D.vehicle_move_delay = round((CONFIG_GET(number/movedelay/run_delay) * 4) / min(user.get_num_arms(), 2), world.tick_lag)
|
||||
return ..()
|
||||
|
||||
/obj/vehicle/ridden/wheelchair/Moved()
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
/obj/belly
|
||||
name = "belly" // Name of this location
|
||||
desc = "It's a belly! You're in it!" // Flavor text description of inside sight/sound/smells/feels.
|
||||
rad_flags = RAD_NO_CONTAMINATE | RAD_PROTECT_CONTENTS
|
||||
var/vore_sound = "Gulp" // Sound when ingesting someone
|
||||
var/vore_verb = "ingest" // Verb for eating with this in messages
|
||||
var/release_sound = "Splatter" // Sound for letting someone out.
|
||||
|
||||
Reference in New Issue
Block a user