Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit156
This commit is contained in:
@@ -46,7 +46,7 @@
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s imaginary friend?", ROLE_PAI, null, null, 75, friend)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
friend.key = C.key
|
||||
C.transfer_ckey(friend, FALSE)
|
||||
friend_initialized = TRUE
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s split personality?", ROLE_PAI, null, null, 75, stranger_backseat)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
stranger_backseat.key = C.key
|
||||
C.transfer_ckey(stranger_backseat, FALSE)
|
||||
log_game("[key_name(stranger_backseat)] became [key_name(owner)]'s split personality.")
|
||||
message_admins("[ADMIN_LOOKUPFLW(stranger_backseat)] became [ADMIN_LOOKUPFLW(owner)]'s split personality.")
|
||||
else
|
||||
@@ -184,7 +184,7 @@
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s brainwashed mind?", null, null, null, 75, stranger_backseat)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
stranger_backseat.key = C.key
|
||||
C.transfer_ckey(stranger_backseat, FALSE)
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -26,5 +26,5 @@
|
||||
if(!HAS_TRAIT(wearer, TRAIT_DEAF))
|
||||
var/obj/item/organ/ears/ears = wearer.getorganslot(ORGAN_SLOT_EARS)
|
||||
if (ears)
|
||||
ears.deaf = max(ears.deaf - 1, (ears.ear_damage < UNHEALING_EAR_DAMAGE ? 0 : 1)) // Do not clear deafness while above the unhealing ear damage threshold
|
||||
ears.ear_damage = max(ears.ear_damage - 0.1, 0)
|
||||
ears.deaf = max(ears.deaf - 1, (ears.damage < ears.maxHealth ? 0 : 1)) // Do not clear deafness if our ears are too damaged
|
||||
ears.damage = max(ears.damage - 0.1, 0)
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event)
|
||||
RegisterSignal(parent, COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event)
|
||||
RegisterSignal(parent, COMSIG_INCREASE_SANITY, .proc/IncreaseSanity)
|
||||
RegisterSignal(parent, COMSIG_DECREASE_SANITY, .proc/DecreaseSanity)
|
||||
|
||||
RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud)
|
||||
var/mob/living/owner = parent
|
||||
@@ -129,23 +131,23 @@
|
||||
|
||||
switch(mood_level)
|
||||
if(1)
|
||||
DecreaseSanity(0.2)
|
||||
DecreaseSanity(src, 0.2)
|
||||
if(2)
|
||||
DecreaseSanity(0.125, SANITY_CRAZY)
|
||||
DecreaseSanity(src, 0.125, SANITY_CRAZY)
|
||||
if(3)
|
||||
DecreaseSanity(0.075, SANITY_UNSTABLE)
|
||||
DecreaseSanity(src, 0.075, SANITY_UNSTABLE)
|
||||
if(4)
|
||||
DecreaseSanity(0.025, SANITY_DISTURBED)
|
||||
DecreaseSanity(src, 0.025, SANITY_DISTURBED)
|
||||
if(5)
|
||||
IncreaseSanity(0.1)
|
||||
IncreaseSanity(src, 0.1)
|
||||
if(6)
|
||||
IncreaseSanity(0.15)
|
||||
IncreaseSanity(src, 0.15)
|
||||
if(7)
|
||||
IncreaseSanity(0.20)
|
||||
IncreaseSanity(src, 0.20)
|
||||
if(8)
|
||||
IncreaseSanity(0.25, SANITY_GREAT)
|
||||
IncreaseSanity(src, 0.25, SANITY_GREAT)
|
||||
if(9)
|
||||
IncreaseSanity(0.4, SANITY_GREAT)
|
||||
IncreaseSanity(src, 0.4, SANITY_GREAT)
|
||||
|
||||
if(insanity_effect != holdmyinsanityeffect)
|
||||
if(insanity_effect > holdmyinsanityeffect)
|
||||
@@ -218,9 +220,9 @@
|
||||
master.crit_threshold = (master.crit_threshold - insanity_effect) + newval
|
||||
insanity_effect = newval
|
||||
|
||||
/datum/component/mood/proc/DecreaseSanity(amount, minimum = SANITY_INSANE)
|
||||
/datum/component/mood/proc/DecreaseSanity(datum/source, amount, minimum = SANITY_INSANE)
|
||||
if(sanity < minimum) //This might make KevinZ stop fucking pinging me.
|
||||
IncreaseSanity(0.5)
|
||||
IncreaseSanity(src, 0.5)
|
||||
else
|
||||
sanity = max(minimum, sanity - amount)
|
||||
if(sanity < SANITY_UNSTABLE)
|
||||
@@ -229,13 +231,13 @@
|
||||
else
|
||||
insanity_effect = (MINOR_INSANITY_PEN)
|
||||
|
||||
/datum/component/mood/proc/IncreaseSanity(amount, maximum = SANITY_NEUTRAL)
|
||||
/datum/component/mood/proc/IncreaseSanity(datum/source, amount, maximum = SANITY_NEUTRAL)
|
||||
// Disturbed stops you from getting any more sane - I'm just gonna bung this in here
|
||||
var/mob/living/owner = parent
|
||||
if(HAS_TRAIT(owner, TRAIT_UNSTABLE))
|
||||
return
|
||||
if(sanity > maximum)
|
||||
DecreaseSanity(0.5) //Removes some sanity to go back to our current limit.
|
||||
DecreaseSanity(src, 0.5) //Removes some sanity to go back to our current limit.
|
||||
else
|
||||
sanity = min(maximum, sanity + amount)
|
||||
if(sanity > SANITY_CRAZY)
|
||||
@@ -262,6 +264,8 @@
|
||||
if(the_event.timeout)
|
||||
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||
|
||||
return the_event
|
||||
|
||||
/datum/component/mood/proc/clear_event(datum/source, category)
|
||||
var/datum/mood_event/event = mood_events[category]
|
||||
if(!event)
|
||||
|
||||
@@ -162,12 +162,12 @@
|
||||
if(!Process_Spacemove(direction) || !isturf(AM.loc))
|
||||
return
|
||||
step(AM, direction)
|
||||
|
||||
|
||||
if((direction & (direction - 1)) && (AM.loc == next)) //moved diagonally
|
||||
last_move_diagonal = TRUE
|
||||
else
|
||||
last_move_diagonal = FALSE
|
||||
|
||||
|
||||
handle_vehicle_layer()
|
||||
handle_vehicle_offsets()
|
||||
else
|
||||
@@ -234,7 +234,7 @@
|
||||
return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(0, 6), TEXT_WEST = list(0, 6))
|
||||
else
|
||||
return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(-6, 4), TEXT_WEST = list( 6, 4))
|
||||
|
||||
|
||||
|
||||
/datum/component/riding/human/force_dismount(mob/living/user)
|
||||
var/atom/movable/AM = parent
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
|
||||
/datum/component/storage/proc/quick_empty(mob/M)
|
||||
var/atom/A = parent
|
||||
if((!ishuman(M) && (A.loc != M)) || (M.stat != CONSCIOUS) || M.restrained() || !M.canmove)
|
||||
if(!M.canUseStorage() || !A.Adjacent(M) || M.incapacitated())
|
||||
return
|
||||
if(check_locked(null, M, TRUE))
|
||||
return FALSE
|
||||
|
||||
@@ -24,8 +24,9 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
var/unlock_note
|
||||
var/unlock_code
|
||||
var/failsafe_code
|
||||
var/datum/ui_state/checkstate
|
||||
|
||||
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20)
|
||||
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20, datum/ui_state/_checkstate)
|
||||
if(!isitem(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
@@ -57,6 +58,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
active = _enabled
|
||||
gamemode = _gamemode
|
||||
telecrystals = starting_tc
|
||||
checkstate = _checkstate
|
||||
if(!lockable)
|
||||
active = TRUE
|
||||
locked = FALSE
|
||||
@@ -115,6 +117,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
|
||||
/datum/component/uplink/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
|
||||
state = checkstate ? checkstate : state
|
||||
active = TRUE
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
@@ -123,6 +126,12 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
ui.set_style("syndicate")
|
||||
ui.open()
|
||||
|
||||
/datum/component/uplink/ui_host(mob/user)
|
||||
if(istype(parent, /obj/item/implant)) //implants are like organs, not really located inside mobs codewise.
|
||||
var/obj/item/implant/I = parent
|
||||
return I.imp_in
|
||||
return ..()
|
||||
|
||||
/datum/component/uplink/ui_data(mob/user)
|
||||
if(!user.mind)
|
||||
return
|
||||
|
||||
128
code/datums/components/virtual_reality.dm
Normal file
128
code/datums/components/virtual_reality.dm
Normal file
@@ -0,0 +1,128 @@
|
||||
/datum/component/virtual_reality
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED //mindswap memes, shouldn't stack up otherwise.
|
||||
var/datum/mind/mastermind // where is my mind t. pixies
|
||||
var/datum/mind/current_mind
|
||||
var/obj/machinery/vr_sleeper/vr_sleeper
|
||||
var/datum/action/quit_vr/quit_action
|
||||
var/you_die_in_the_game_you_die_for_real = FALSE
|
||||
var/datum/component/virtual_reality/inception //The component works on a very fragile link betwixt mind, ckey and death.
|
||||
|
||||
/datum/component/virtual_reality/Initialize(mob/M, obj/machinery/vr_sleeper/gaming_pod, yolo = FALSE, new_char = TRUE)
|
||||
if(!ismob(parent) || !istype(M))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
var/mob/vr_M = parent
|
||||
mastermind = M.mind
|
||||
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED), .proc/game_over)
|
||||
RegisterSignal(M, COMSIG_MOB_KEY_CHANGE, .proc/switch_player)
|
||||
RegisterSignal(mastermind, COMSIG_MIND_TRANSFER, .proc/switch_player)
|
||||
you_die_in_the_game_you_die_for_real = yolo
|
||||
quit_action = new()
|
||||
if(gaming_pod)
|
||||
vr_sleeper = gaming_pod
|
||||
RegisterSignal(vr_sleeper, COMSIG_ATOM_EMAG_ACT, .proc/you_only_live_once)
|
||||
RegisterSignal(vr_sleeper, COMSIG_MACHINE_EJECT_OCCUPANT, .proc/revert_to_reality)
|
||||
vr_M.ckey = M.ckey
|
||||
var/datum/component/virtual_reality/clusterfk = M.GetComponent(/datum/component/virtual_reality)
|
||||
if(clusterfk && !clusterfk.inception)
|
||||
clusterfk.inception = src
|
||||
SStgui.close_user_uis(M, src)
|
||||
|
||||
/datum/component/virtual_reality/RegisterWithParent()
|
||||
var/mob/M = parent
|
||||
current_mind = M.mind
|
||||
quit_action.Grant(M)
|
||||
RegisterSignal(quit_action, COMSIG_ACTION_TRIGGER, .proc/revert_to_reality)
|
||||
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED), .proc/game_over)
|
||||
RegisterSignal(M, COMSIG_MOB_GHOSTIZE, .proc/be_a_quitter)
|
||||
RegisterSignal(M, COMSIG_MOB_KEY_CHANGE, .proc/pass_me_the_remote)
|
||||
RegisterSignal(current_mind, COMSIG_MIND_TRANSFER, .proc/pass_me_the_remote)
|
||||
mastermind.current.audiovisual_redirect = M
|
||||
if(vr_sleeper)
|
||||
vr_sleeper.vr_mob = M
|
||||
|
||||
/datum/component/virtual_reality/UnregisterFromParent()
|
||||
quit_action.Remove(parent)
|
||||
UnregisterSignal(parent, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED, COMSIG_MOB_KEY_CHANGE, COMSIG_MOB_GHOSTIZE))
|
||||
UnregisterSignal(current_mind, COMSIG_MIND_TRANSFER)
|
||||
UnregisterSignal(quit_action, COMSIG_ACTION_TRIGGER)
|
||||
current_mind = null
|
||||
mastermind.current.audiovisual_redirect = null
|
||||
|
||||
/datum/component/virtual_reality/proc/switch_player(datum/source, mob/new_mob, mob/old_mob)
|
||||
if(vr_sleeper || !new_mob.mind)
|
||||
// Machineries currently don't deal up with the occupant being polymorphed et similar... Or did something fuck up?
|
||||
revert_to_reality()
|
||||
return
|
||||
old_mob.audiovisual_redirect = null
|
||||
new_mob.audiovisual_redirect = parent
|
||||
|
||||
/datum/component/virtual_reality/proc/action_trigger(datum/signal_source, datum/action/source)
|
||||
if(source != quit_action)
|
||||
return COMPONENT_ACTION_BLOCK_TRIGGER
|
||||
revert_to_reality(signal_source)
|
||||
|
||||
/datum/component/virtual_reality/proc/you_only_live_once()
|
||||
if(you_die_in_the_game_you_die_for_real || vr_sleeper?.only_current_user_can_interact)
|
||||
return FALSE
|
||||
you_die_in_the_game_you_die_for_real = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/component/virtual_reality/proc/pass_me_the_remote(datum/source, mob/new_mob)
|
||||
if(new_mob == mastermind.current)
|
||||
revert_to_reality(source)
|
||||
return TRUE
|
||||
new_mob.TakeComponent(src)
|
||||
return TRUE
|
||||
|
||||
/datum/component/virtual_reality/PostTransfer()
|
||||
if(!ismob(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
/datum/component/virtual_reality/proc/revert_to_reality(datum/source)
|
||||
quit_it()
|
||||
|
||||
/datum/component/virtual_reality/proc/game_over(datum/source)
|
||||
quit_it(TRUE, TRUE)
|
||||
|
||||
/datum/component/virtual_reality/proc/be_a_quitter(datum/source, can_reenter_corpse)
|
||||
quit_it()
|
||||
return COMPONENT_BLOCK_GHOSTING
|
||||
|
||||
/datum/component/virtual_reality/proc/virtual_reality_in_a_virtual_reality(mob/player, killme = FALSE, datum/component/virtual_reality/yo_dawg)
|
||||
var/mob/M = parent
|
||||
quit_it(FALSE, killme, player, yo_dawg)
|
||||
yo_dawg.inception = null
|
||||
if(killme)
|
||||
M.death(FALSE)
|
||||
|
||||
/datum/component/virtual_reality/proc/quit_it(deathcheck = FALSE, cleanup = FALSE, mob/override)
|
||||
var/mob/M = parent
|
||||
var/mob/dreamer = override ? override : mastermind.current
|
||||
if(!mastermind)
|
||||
to_chat(M, "<span class='warning'>You feel a dreadful sensation, something terrible happened. You try to wake up, but you find yourself unable to...</span>")
|
||||
else
|
||||
var/key_transfer = FALSE
|
||||
if(inception?.parent)
|
||||
inception.virtual_reality_in_a_virtual_reality(dreamer, cleanup, src)
|
||||
else
|
||||
key_transfer = TRUE
|
||||
if(key_transfer)
|
||||
M.transfer_ckey(dreamer, FALSE)
|
||||
dreamer.stop_sound_channel(CHANNEL_HEARTBEAT)
|
||||
dreamer.audiovisual_redirect = null
|
||||
if(deathcheck && you_die_in_the_game_you_die_for_real)
|
||||
to_chat(mastermind, "<span class='warning'>You feel everything fading away...</span>")
|
||||
dreamer.death(FALSE)
|
||||
if(cleanup)
|
||||
var/obj/effect/vr_clean_master/cleanbot = locate() in get_area(M)
|
||||
if(cleanbot)
|
||||
LAZYADD(cleanbot.corpse_party, M)
|
||||
if(vr_sleeper)
|
||||
vr_sleeper.vr_mob = null
|
||||
vr_sleeper = null
|
||||
qdel(src)
|
||||
|
||||
/datum/component/virtual_reality/Destroy()
|
||||
var/datum/action/quit_vr/delet_me = quit_action
|
||||
. = ..()
|
||||
qdel(delet_me)
|
||||
@@ -94,10 +94,23 @@
|
||||
TOXIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=toxin' id='toxin'>[M.getToxLoss()]</a>
|
||||
OXY:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=oxygen' id='oxygen'>[M.getOxyLoss()]</a>
|
||||
CLONE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=clone' id='clone'>[M.getCloneLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brain' id='brain'>[M.getBrainLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brain' id='brain'>[M.getOrganLoss(ORGAN_SLOT_BRAIN)]</a>
|
||||
STAMINA:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=stamina' id='stamina'>[M.getStaminaLoss()]</a>
|
||||
AROUSAL:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=arousal' id='arousal'>[M.getArousalLoss()]</a>
|
||||
</font>
|
||||
"}
|
||||
if(GLOB.Debug2)
|
||||
atomsnowflake += {"
|
||||
HEART:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=heart' id='heart'>[M.getOrganLoss(ORGAN_SLOT_HEART)]</a>
|
||||
LIVER:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=liver' id='liver'>[M.getOrganLoss(ORGAN_SLOT_LIVER)]</a>
|
||||
LUNGS:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=lungs' id='lungs'>[M.getOrganLoss(ORGAN_SLOT_LUNGS)]</a>
|
||||
EYES:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=eye_sight' id='eye_sight'>[M.getOrganLoss(ORGAN_SLOT_EYES)]</a>
|
||||
EARS:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=ears' id='ears'>[M.getOrganLoss(ORGAN_SLOT_EARS)]</a>
|
||||
STOMACH:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=stomach' id='stomach'>[M.getOrganLoss(ORGAN_SLOT_STOMACH)]</a>
|
||||
TONGUE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=tongue' id='tongue'>[M.getOrganLoss(ORGAN_SLOT_TONGUE)]</a>
|
||||
APPENDIX:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=appendix' id='appendix'>[M.getOrganLoss(ORGAN_SLOT_APPENDIX)]</a>
|
||||
"}
|
||||
atomsnowflake += {"
|
||||
</font>
|
||||
"}
|
||||
else
|
||||
atomsnowflake += "<a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=name'><b id='name'>[D]</b></a>"
|
||||
@@ -1334,8 +1347,8 @@
|
||||
L.adjustOxyLoss(amount)
|
||||
newamt = L.getOxyLoss()
|
||||
if("brain")
|
||||
L.adjustBrainLoss(amount)
|
||||
newamt = L.getBrainLoss()
|
||||
L.adjustOrganLoss(ORGAN_SLOT_BRAIN, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
if("clone")
|
||||
L.adjustCloneLoss(amount)
|
||||
newamt = L.getCloneLoss()
|
||||
@@ -1345,6 +1358,30 @@
|
||||
if("arousal")
|
||||
L.adjustArousalLoss(amount)
|
||||
newamt = L.getArousalLoss()
|
||||
if("heart")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_HEART, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_HEART)
|
||||
if("liver")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_LIVER, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_LIVER)
|
||||
if("lungs")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_LUNGS, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_LUNGS)
|
||||
if("eye_sight")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_EYES, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_EYES)
|
||||
if("ears")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_EARS, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_EARS)
|
||||
if("stomach")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_STOMACH, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_STOMACH)
|
||||
if("tongue")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_TONGUE, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_TONGUE)
|
||||
if("appendix")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_APPENDIX, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_APPENDIX)
|
||||
else
|
||||
to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]")
|
||||
return
|
||||
@@ -1360,4 +1397,4 @@
|
||||
return
|
||||
var/mob/living/carbon/human/H = locate(href_list["copyoutfit"]) in GLOB.carbon_list
|
||||
if(istype(H))
|
||||
H.copy_outfit()
|
||||
H.copy_outfit()
|
||||
|
||||
@@ -144,3 +144,9 @@
|
||||
if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs)))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/proc/CanSpreadAirborneDisease()
|
||||
return !is_mouth_covered()
|
||||
|
||||
/mob/living/carbon/CanSpreadAirborneDisease()
|
||||
return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating("bio") >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating("bio") >= 25)))
|
||||
@@ -55,6 +55,13 @@
|
||||
D.after_add()
|
||||
infectee.med_hud_set_status()
|
||||
|
||||
var/turf/source_turf = get_turf(infectee)
|
||||
log_virus("[key_name(infectee)] was infected by virus: [src.admin_details()] at [loc_name(source_turf)]")
|
||||
|
||||
//Return a string for admin logging uses, should describe the disease in detail
|
||||
/datum/disease/proc/admin_details()
|
||||
return "[src.name] : [src.type]"
|
||||
|
||||
/datum/disease/proc/stage_act()
|
||||
var/cure = has_cure()
|
||||
|
||||
@@ -65,15 +72,17 @@
|
||||
|
||||
if(!cure)
|
||||
if(prob(stage_prob))
|
||||
stage = min(stage + 1,max_stages)
|
||||
update_stage(min(stage + 1,max_stages))
|
||||
else
|
||||
if(prob(cure_chance))
|
||||
stage = max(stage - 1, 1)
|
||||
update_stage(max(stage - 1, 1))
|
||||
|
||||
if(disease_flags & CURABLE)
|
||||
if(cure && prob(cure_chance))
|
||||
cure()
|
||||
|
||||
/datum/disease/proc/update_stage(new_stage)
|
||||
stage = new_stage
|
||||
|
||||
/datum/disease/proc/has_cure()
|
||||
if(!(disease_flags & CURABLE))
|
||||
|
||||
@@ -31,9 +31,9 @@
|
||||
var/id = ""
|
||||
var/processing = FALSE
|
||||
var/mutable = TRUE //set to FALSE to prevent most in-game methods of altering the disease via virology
|
||||
var/oldres
|
||||
var/oldres //To prevent setting new cures unless resistance changes.
|
||||
|
||||
// The order goes from easy to cure to hard to cure.
|
||||
// The order goes from easy to cure to hard to cure. Keep in mind that sentient diseases pick two cures from tier 6 and up, ensure they wont react away in bodies.
|
||||
var/static/list/advance_cures = list(
|
||||
list( // level 1
|
||||
"copper", "silver", "iodine", "iron", "carbon"
|
||||
@@ -110,15 +110,22 @@
|
||||
return
|
||||
|
||||
if(symptoms && symptoms.len)
|
||||
|
||||
if(!processing)
|
||||
processing = TRUE
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.Start(src)
|
||||
if(S.Start(src)) //this will return FALSE if the symptom is neutered
|
||||
S.next_activation = world.time + rand(S.symptom_delay_min * 10, S.symptom_delay_max * 10)
|
||||
S.on_stage_change(src)
|
||||
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.Activate(src)
|
||||
|
||||
// Tell symptoms stage changed
|
||||
/datum/disease/advance/update_stage(new_stage)
|
||||
..()
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.on_stage_change(src)
|
||||
|
||||
// Compares type then ID.
|
||||
/datum/disease/advance/IsSame(datum/disease/advance/D)
|
||||
|
||||
@@ -138,9 +145,18 @@
|
||||
A.properties = properties.Copy()
|
||||
A.id = id
|
||||
A.mutable = mutable
|
||||
A.oldres = oldres
|
||||
//this is a new disease starting over at stage 1, so processing is not copied
|
||||
return A
|
||||
|
||||
//Describe this disease to an admin in detail (for logging)
|
||||
/datum/disease/advance/admin_details()
|
||||
var/list/name_symptoms = list()
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
name_symptoms += S.name
|
||||
return "[name] sym:[english_list(name_symptoms)] r:[totalResistance()] s:[totalStealth()] ss:[totalStageSpeed()] t:[totalTransmittable()]"
|
||||
|
||||
|
||||
/*
|
||||
|
||||
NEW PROCS
|
||||
@@ -191,6 +207,10 @@
|
||||
/datum/disease/advance/proc/Refresh(new_name = FALSE)
|
||||
GenerateProperties()
|
||||
AssignProperties()
|
||||
if(processing && symptoms && symptoms.len)
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.Start(src)
|
||||
S.on_stage_change(src)
|
||||
id = null
|
||||
|
||||
var/the_id = GetDiseaseID()
|
||||
@@ -342,28 +362,28 @@
|
||||
return id
|
||||
|
||||
|
||||
// Add a symptom, if it is over the limit (with a small chance to be able to go over)
|
||||
// we take a random symptom away and add the new one.
|
||||
// Add a symptom, if it is over the limit we take a random symptom away and add the new one.
|
||||
/datum/disease/advance/proc/AddSymptom(datum/symptom/S)
|
||||
|
||||
if(HasSymptom(S))
|
||||
return
|
||||
|
||||
if(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1))
|
||||
symptoms += S
|
||||
else
|
||||
if(!(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1)))
|
||||
RemoveSymptom(pick(symptoms))
|
||||
symptoms += S
|
||||
symptoms += S
|
||||
S.OnAdd(src)
|
||||
|
||||
// Simply removes the symptom.
|
||||
/datum/disease/advance/proc/RemoveSymptom(datum/symptom/S)
|
||||
symptoms -= S
|
||||
S.OnRemove(src)
|
||||
|
||||
// Neuter a symptom, so it will only affect stats
|
||||
/datum/disease/advance/proc/NeuterSymptom(datum/symptom/S)
|
||||
if(!S.neutered)
|
||||
S.neutered = TRUE
|
||||
S.name += " (neutered)"
|
||||
S.OnRemove(src)
|
||||
|
||||
/*
|
||||
|
||||
@@ -417,7 +437,7 @@
|
||||
|
||||
var/i = VIRUS_SYMPTOM_LIMIT
|
||||
|
||||
var/datum/disease/advance/D = new(0, null)
|
||||
var/datum/disease/advance/D = new()
|
||||
D.symptoms = list()
|
||||
|
||||
var/list/symptoms = list()
|
||||
@@ -445,9 +465,6 @@
|
||||
D.AssignName(new_name)
|
||||
D.Refresh()
|
||||
|
||||
for(var/datum/disease/advance/AD in SSdisease.active_diseases)
|
||||
AD.Refresh()
|
||||
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
|
||||
if(!is_station_level(H.z))
|
||||
continue
|
||||
@@ -458,8 +475,8 @@
|
||||
var/list/name_symptoms = list()
|
||||
for(var/datum/symptom/S in D.symptoms)
|
||||
name_symptoms += S.name
|
||||
message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.name]! It has these symptoms: [english_list(name_symptoms)]")
|
||||
|
||||
message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.admin_details()]")
|
||||
log_virus("[key_name(user)] has triggered a custom virus outbreak of [D.admin_details()]!")
|
||||
|
||||
/datum/disease/advance/proc/totalStageSpeed()
|
||||
return properties["stage_rate"]
|
||||
|
||||
@@ -144,5 +144,5 @@ Bonus
|
||||
/datum/symptom/asphyxiation/proc/Asphyxiate_death(mob/living/M, datum/disease/advance/A)
|
||||
var/get_damage = rand(25,35) * power
|
||||
M.adjustOxyLoss(get_damage)
|
||||
M.adjustBrainLoss(get_damage/2)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, get_damage/2)
|
||||
return 1
|
||||
|
||||
@@ -55,7 +55,7 @@ Bonus
|
||||
to_chat(M, "<span class='userdanger'>You can't think straight!</span>")
|
||||
M.confused = min(100 * power, M.confused + 8)
|
||||
if(brain_damage)
|
||||
M.adjustBrainLoss(3 * power, 80)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * power, 80)
|
||||
M.updatehealth()
|
||||
|
||||
return
|
||||
|
||||
@@ -70,6 +70,6 @@ BONUS
|
||||
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 6)
|
||||
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 12)
|
||||
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 18)
|
||||
if(infective)
|
||||
if(infective && M.CanSpreadAirborneDisease())
|
||||
A.spread(1)
|
||||
|
||||
|
||||
@@ -50,9 +50,9 @@ Bonus
|
||||
if(5)
|
||||
if(power > 2)
|
||||
var/obj/item/organ/ears/ears = M.getorganslot(ORGAN_SLOT_EARS)
|
||||
if(istype(ears) && ears.ear_damage < UNHEALING_EAR_DAMAGE)
|
||||
if(istype(ears) && ears.damage < ears.maxHealth)
|
||||
to_chat(M, "<span class='userdanger'>Your ears pop painfully and start bleeding!</span>")
|
||||
ears.ear_damage = max(ears.ear_damage, UNHEALING_EAR_DAMAGE)
|
||||
ears.damage = max(ears.damage, ears.maxHealth)
|
||||
M.emote("scream")
|
||||
else
|
||||
to_chat(M, "<span class='userdanger'>Your ears pop and begin ringing loudly!</span>")
|
||||
|
||||
@@ -219,8 +219,10 @@
|
||||
level = 8
|
||||
passive_message = "<span class='notice'>The pain from your wounds makes you feel oddly sleepy...</span>"
|
||||
var/deathgasp = FALSE
|
||||
var/stabilize = FALSE
|
||||
var/active_coma = FALSE //to prevent multiple coma procs
|
||||
threshold_desc = "<b>Stealth 2:</b> Host appears to die when falling into a coma.<br>\
|
||||
<b>Resistance 4:</b> The virus also stabilizes the host while they are in critical condition.<br>\
|
||||
<b>Stage Speed 7:</b> Increases healing speed."
|
||||
|
||||
/datum/symptom/heal/coma/Start(datum/disease/advance/A)
|
||||
@@ -228,9 +230,25 @@
|
||||
return
|
||||
if(A.properties["stage_rate"] >= 7)
|
||||
power = 1.5
|
||||
if(A.properties["resistance"] >= 4)
|
||||
stabilize = TRUE
|
||||
if(A.properties["stealth"] >= 2)
|
||||
deathgasp = TRUE
|
||||
|
||||
/datum/symptom/heal/coma/on_stage_change(datum/disease/advance/A) //mostly copy+pasted from the code for self-respiration's TRAIT_NOBREATH stuff
|
||||
if(!..())
|
||||
return FALSE
|
||||
if(A.stage >= 4 && stabilize)
|
||||
ADD_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
|
||||
else
|
||||
REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
|
||||
return TRUE
|
||||
|
||||
/datum/symptom/heal/coma/End(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
|
||||
|
||||
/datum/symptom/heal/coma/CanHeal(datum/disease/advance/A)
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(HAS_TRAIT(M, TRAIT_DEATHCOMA))
|
||||
|
||||
@@ -50,3 +50,19 @@ Bonus
|
||||
if(prob(base_message_chance))
|
||||
to_chat(M, "<span class='notice'>[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]</span>")
|
||||
return
|
||||
|
||||
/datum/symptom/oxygen/on_stage_change(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
if(A.stage >= 4)
|
||||
ADD_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT)
|
||||
else
|
||||
REMOVE_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT)
|
||||
return TRUE
|
||||
|
||||
/datum/symptom/oxygen/End(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.stage >= 4)
|
||||
REMOVE_TRAIT(A.affected_mob, TRAIT_NOBREATH, DISEASE_TRAIT)
|
||||
@@ -51,7 +51,7 @@
|
||||
M.hallucination = max(0, M.hallucination - 10)
|
||||
|
||||
if(A.stage >= 5)
|
||||
M.adjustBrainLoss(-3)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3)
|
||||
if(trauma_heal_mild && iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
if(prob(10))
|
||||
@@ -100,8 +100,8 @@
|
||||
else if(M.eye_blind || M.eye_blurry)
|
||||
M.set_blindness(0)
|
||||
M.set_blurriness(0)
|
||||
else if(eyes.eye_damage > 0)
|
||||
M.adjust_eye_damage(-1)
|
||||
else if(eyes.damage > 0)
|
||||
eyes.applyOrganDamage(-1)
|
||||
else
|
||||
if(prob(base_message_chance))
|
||||
to_chat(M, "<span class='notice'>[pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.","Your ears feel great.","Your healing feels more acute.")]</span>")
|
||||
to_chat(M, "<span class='notice'>[pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.","Your ears feel great.","Your healing feels more acute.")]</span>")
|
||||
|
||||
@@ -48,4 +48,5 @@ Bonus
|
||||
M.emote("sniff")
|
||||
else
|
||||
M.emote("sneeze")
|
||||
A.spread(4 + power)
|
||||
if(M.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth
|
||||
A.spread(4 + power)
|
||||
@@ -8,12 +8,14 @@
|
||||
level = 5
|
||||
severity = 0
|
||||
|
||||
/datum/symptom/undead_adaptation/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
/datum/symptom/undead_adaptation/OnAdd(datum/disease/advance/A)
|
||||
A.process_dead = TRUE
|
||||
A.infectable_biotypes |= MOB_UNDEAD
|
||||
|
||||
/datum/symptom/undead_adaptation/OnRemove(datum/disease/advance/A)
|
||||
A.process_dead = FALSE
|
||||
A.infectable_biotypes -= MOB_UNDEAD
|
||||
|
||||
/datum/symptom/inorganic_adaptation
|
||||
name = "Inorganic Biology"
|
||||
desc = "The virus can survive and replicate even in an inorganic environment, increasing its resistance and infection rate."
|
||||
@@ -24,7 +26,8 @@
|
||||
level = 5
|
||||
severity = 0
|
||||
|
||||
/datum/symptom/inorganic_adaptation/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
A.infectable_biotypes |= MOB_INORGANIC
|
||||
/datum/symptom/inorganic_adaptation/OnAdd(datum/disease/advance/A)
|
||||
A.infectable_biotypes |= MOB_INORGANIC
|
||||
|
||||
/datum/symptom/inorganic_adaptation/OnRemove(datum/disease/advance/A)
|
||||
A.infectable_biotypes -= MOB_INORGANIC
|
||||
@@ -38,11 +38,10 @@
|
||||
return
|
||||
CRASH("We couldn't assign an ID!")
|
||||
|
||||
// Called when processing of the advance disease, which holds this symptom, starts.
|
||||
// Called when processing of the advance disease that holds this symptom infects a host and upon each Refresh() of that advance disease.
|
||||
/datum/symptom/proc/Start(datum/disease/advance/A)
|
||||
if(neutered)
|
||||
return FALSE
|
||||
next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10) //so it doesn't instantly activate on infection
|
||||
return TRUE
|
||||
|
||||
// Called when the advance disease is going to be deleted or when the advance disease stops processing.
|
||||
@@ -60,6 +59,11 @@
|
||||
next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10)
|
||||
return TRUE
|
||||
|
||||
/datum/symptom/proc/on_stage_change(datum/disease/advance/A)
|
||||
if(neutered)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/symptom/proc/Copy()
|
||||
var/datum/symptom/new_symp = new type
|
||||
new_symp.name = name
|
||||
@@ -69,3 +73,9 @@
|
||||
|
||||
/datum/symptom/proc/generate_threshold_desc()
|
||||
return
|
||||
|
||||
/datum/symptom/proc/OnAdd(datum/disease/advance/A) //Overload when a symptom needs to be active before processing, like changing biotypes.
|
||||
return
|
||||
|
||||
/datum/symptom/proc/OnRemove(datum/disease/advance/A) //But dont forget to remove them too.
|
||||
return
|
||||
@@ -45,7 +45,7 @@ Bonus
|
||||
return
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
|
||||
if(istype(eyes))
|
||||
if(eyes)
|
||||
switch(A.stage)
|
||||
if(1, 2)
|
||||
if(prob(base_message_chance) && !suppress_warning)
|
||||
@@ -53,20 +53,20 @@ Bonus
|
||||
if(3, 4)
|
||||
to_chat(M, "<span class='warning'><b>Your eyes burn!</b></span>")
|
||||
M.blur_eyes(10)
|
||||
M.adjust_eye_damage(1)
|
||||
eyes.applyOrganDamage(1)
|
||||
else
|
||||
M.blur_eyes(20)
|
||||
M.adjust_eye_damage(5)
|
||||
if(eyes.eye_damage >= 10)
|
||||
eyes.applyOrganDamage(5)
|
||||
if(eyes.damage >= 10)
|
||||
M.become_nearsighted(EYE_DAMAGE)
|
||||
if(prob(eyes.eye_damage - 10 + 1))
|
||||
if(prob(eyes.damage - 10 + 1))
|
||||
if(!remove_eyes)
|
||||
if(!HAS_TRAIT(M, TRAIT_BLIND))
|
||||
to_chat(M, "<span class='userdanger'>You go blind!</span>")
|
||||
M.become_blind(EYE_DAMAGE)
|
||||
eyes.applyOrganDamage(eyes.maxHealth)
|
||||
else
|
||||
M.visible_message("<span class='warning'>[M]'s eyes fall off their sockets!</span>", "<span class='userdanger'>Your eyes fall off their sockets!</span>")
|
||||
eyes.Remove(M)
|
||||
eyes.forceMove(get_turf(M))
|
||||
else
|
||||
to_chat(M, "<span class='userdanger'>Your eyes burn horrifically!</span>")
|
||||
to_chat(M, "<span class='userdanger'>Your eyes burn horrifically!</span>")
|
||||
|
||||
@@ -27,8 +27,10 @@
|
||||
A.update_icon()
|
||||
if(prob(3))
|
||||
to_chat(affected_mob, "<span class='warning'>You feel a stabbing pain in your abdomen!</span>")
|
||||
affected_mob.adjustOrganLoss(ORGAN_SLOT_APPENDIX, 5)
|
||||
affected_mob.Stun(rand(40,60))
|
||||
affected_mob.adjustToxLoss(1)
|
||||
if(3)
|
||||
if(prob(1))
|
||||
affected_mob.vomit(95)
|
||||
affected_mob.adjustOrganLoss(ORGAN_SLOT_APPENDIX, 15)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
if(prob(2))
|
||||
to_chat(affected_mob, "<span class='danger'>You don't feel like yourself.</span>")
|
||||
if(prob(5))
|
||||
affected_mob.adjustBrainLoss(1, 170)
|
||||
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, 170)
|
||||
affected_mob.updatehealth()
|
||||
if(3)
|
||||
if(prob(2))
|
||||
@@ -32,7 +32,7 @@
|
||||
if(prob(2))
|
||||
affected_mob.emote("drool")
|
||||
if(prob(10))
|
||||
affected_mob.adjustBrainLoss(2, 170)
|
||||
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2, 170)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(2))
|
||||
to_chat(affected_mob, "<span class='danger'>Your try to remember something important...but can't.</span>")
|
||||
@@ -43,7 +43,7 @@
|
||||
if(prob(2))
|
||||
affected_mob.emote("drool")
|
||||
if(prob(15))
|
||||
affected_mob.adjustBrainLoss(3, 170)
|
||||
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 170)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(2))
|
||||
to_chat(affected_mob, "<span class='danger'>Strange buzzing fills your head, removing all thoughts.</span>")
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
if(affected_mob.mind)
|
||||
affected_mob.mind.transfer_to(new_mob)
|
||||
else
|
||||
new_mob.key = affected_mob.key
|
||||
affected_mob.transfer_ckey(new_mob)
|
||||
|
||||
new_mob.name = affected_mob.real_name
|
||||
new_mob.real_name = new_mob.name
|
||||
@@ -82,7 +82,7 @@
|
||||
to_chat(affected_mob, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
|
||||
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(affected_mob)]) to replace a jobbaned player.")
|
||||
affected_mob.ghostize(0)
|
||||
affected_mob.key = C.key
|
||||
C.transfer_ckey(affected_mob)
|
||||
else
|
||||
to_chat(new_mob, "Your mob has been claimed by death! Appeal your job ban if you want to avoid this in the future!")
|
||||
new_mob.death()
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
"<span class='userdanger'>[A] kicks your head, knocking you out!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1)
|
||||
D.SetSleeping(300)
|
||||
D.adjustBrainLoss(15, 150)
|
||||
D.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 150)
|
||||
return TRUE
|
||||
|
||||
/datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
D.apply_damage(rand(5,10), BRUTE, BODY_ZONE_HEAD)
|
||||
A.apply_damage(rand(5,10), BRUTE, BODY_ZONE_HEAD)
|
||||
if(!istype(D.head,/obj/item/clothing/head/helmet/) && !istype(D.head,/obj/item/clothing/head/hardhat))
|
||||
D.adjustBrainLoss(5)
|
||||
D.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
|
||||
A.Stun(rand(10,45))
|
||||
D.Knockdown(rand(5,30))//CIT CHANGE - makes stuns from martial arts always use Knockdown instead of Stun for the sake of consistency
|
||||
if(5,6)
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
H.visible_message("<span class='warning'>[user] delivers a heavy hit to [H]'s head, knocking [H.p_them()] out cold!</span>", \
|
||||
"<span class='userdanger'>[user] knocks you unconscious!</span>")
|
||||
H.SetSleeping(600)
|
||||
H.adjustBrainLoss(15, 150)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 150)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
- IMPORTANT NOTE 2, if you want a player to become a ghost, use mob.ghostize() It does all the hard work for you.
|
||||
|
||||
- When creating a new mob which will be a new IC character (e.g. putting a shade in a construct or randomly selecting
|
||||
a ghost to become a xeno during an event). Simply assign the key or ckey like you've always done.
|
||||
a ghost to become a xeno during an event), use this mob proc.
|
||||
|
||||
new_mob.key = key
|
||||
mob.transfer_ckey(new_mob)
|
||||
|
||||
The Login proc will handle making a new mind for that mobtype (including setting up stuff like mind.name). Simple!
|
||||
However if you want that mind to have any special properties like being a traitor etc you will have to do that
|
||||
@@ -89,6 +89,7 @@
|
||||
return language_holder
|
||||
|
||||
/datum/mind/proc/transfer_to(mob/new_character, var/force_key_move = 0)
|
||||
var/old_character = current
|
||||
if(current) // remove ourself from our old body's mind variable
|
||||
current.mind = null
|
||||
SStgui.on_transfer(current, new_character)
|
||||
@@ -99,7 +100,7 @@
|
||||
|
||||
if(key)
|
||||
if(new_character.key != key) //if we're transferring into a body with a key associated which is not ours
|
||||
new_character.ghostize(1) //we'll need to ghostize so that key isn't mobless.
|
||||
new_character.ghostize(TRUE, TRUE) //we'll need to ghostize so that key isn't mobless.
|
||||
else
|
||||
key = new_character.key
|
||||
|
||||
@@ -123,6 +124,7 @@
|
||||
transfer_martial_arts(new_character)
|
||||
if(active || force_key_move)
|
||||
new_character.key = key //now transfer the key to link the client to our new body
|
||||
SEND_SIGNAL(src, COMSIG_MIND_TRANSFER, new_character, old_character)
|
||||
|
||||
//CIT CHANGE - makes arousal update when transfering bodies
|
||||
if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs.
|
||||
|
||||
@@ -169,3 +169,10 @@
|
||||
|
||||
/datum/mood_event/sad_empath/add_effects(mob/sadtarget)
|
||||
description = "<span class='warning'>[sadtarget.name] seems upset...</span>\n"
|
||||
|
||||
/datum/mood_event/revenant_blight
|
||||
description = "<span class='umbra'>Just give up, honk...</span>\n"
|
||||
mood_change = -5
|
||||
|
||||
/datum/mood_event/revenant_blight/add_effects()
|
||||
description = "<span class='umbra'>Just give up, [pick("no one will miss you", "there is nothing you can do to help", "even a clown would be more useful than you", "does it even matter in the end?")]...</span>\n"
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
H.update_action_buttons_icon()
|
||||
if(implants)
|
||||
for(var/implant_type in implants)
|
||||
var/obj/item/implant/I = new implant_type(H)
|
||||
var/obj/item/implant/I = new implant_type
|
||||
I.implant(H, null, TRUE)
|
||||
|
||||
H.update_body()
|
||||
|
||||
@@ -103,7 +103,6 @@
|
||||
/obj/structure/cable,
|
||||
/obj/machinery/atmospherics,
|
||||
/obj/item/ammo_casing,
|
||||
/obj/item/implant,
|
||||
/obj/singularity
|
||||
))
|
||||
if(!can_contaminate || blacklisted[thing.type])
|
||||
|
||||
@@ -521,7 +521,7 @@
|
||||
itemUser.adjustToxLoss(-1.5, forced = TRUE) //Because Slime People are people too
|
||||
itemUser.adjustOxyLoss(-1.5)
|
||||
itemUser.adjustStaminaLoss(-1.5)
|
||||
itemUser.adjustBrainLoss(-1.5)
|
||||
itemUser.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1.5)
|
||||
itemUser.adjustCloneLoss(-0.5) //Becasue apparently clone damage is the bastion of all health
|
||||
//Heal all those around you, unbiased
|
||||
for(var/mob/living/L in view(7, owner))
|
||||
@@ -533,7 +533,7 @@
|
||||
L.adjustToxLoss(-3.5, forced = TRUE) //Because Slime People are people too
|
||||
L.adjustOxyLoss(-3.5)
|
||||
L.adjustStaminaLoss(-3.5)
|
||||
L.adjustBrainLoss(-3.5)
|
||||
L.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3.5)
|
||||
L.adjustCloneLoss(-1) //Becasue apparently clone damage is the bastion of all health
|
||||
else if(issilicon(L))
|
||||
L.adjustBruteLoss(-3.5)
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
status_type = STATUS_EFFECT_REPLACE
|
||||
alert_type = null
|
||||
var/mutable_appearance/marked_underlay
|
||||
var/obj/item/twohanded/required/kinetic_crusher/hammer_synced
|
||||
var/obj/item/twohanded/kinetic_crusher/hammer_synced
|
||||
|
||||
/datum/status_effect/crusher_mark/on_creation(mob/living/new_owner, obj/item/twohanded/required/kinetic_crusher/new_hammer_synced)
|
||||
/datum/status_effect/crusher_mark/on_creation(mob/living/new_owner, obj/item/twohanded/kinetic_crusher/new_hammer_synced)
|
||||
. = ..()
|
||||
if(.)
|
||||
hammer_synced = new_hammer_synced
|
||||
@@ -358,19 +358,20 @@
|
||||
else
|
||||
new /obj/effect/temp_visual/bleed(get_turf(owner))
|
||||
|
||||
/mob/living/proc/apply_necropolis_curse(set_curse)
|
||||
/mob/living/proc/apply_necropolis_curse(set_curse, duration = 10 MINUTES)
|
||||
var/datum/status_effect/necropolis_curse/C = has_status_effect(STATUS_EFFECT_NECROPOLIS_CURSE)
|
||||
if(!set_curse)
|
||||
set_curse = pick(CURSE_BLINDING, CURSE_SPAWNING, CURSE_WASTING, CURSE_GRASPING)
|
||||
if(QDELETED(C))
|
||||
apply_status_effect(STATUS_EFFECT_NECROPOLIS_CURSE, set_curse)
|
||||
apply_status_effect(STATUS_EFFECT_NECROPOLIS_CURSE, set_curse, duration)
|
||||
|
||||
else
|
||||
C.apply_curse(set_curse)
|
||||
C.duration += 3000 //additional curses add 5 minutes
|
||||
C.duration += duration * 0.5 //additional curses add half their duration
|
||||
|
||||
/datum/status_effect/necropolis_curse
|
||||
id = "necrocurse"
|
||||
duration = 6000 //you're cursed for 10 minutes have fun
|
||||
duration = 10 MINUTES //you're cursed for 10 minutes have fun
|
||||
tick_interval = 50
|
||||
alert_type = null
|
||||
var/curse_flags = NONE
|
||||
@@ -378,7 +379,9 @@
|
||||
var/effect_cooldown = 100
|
||||
var/obj/effect/temp_visual/curse/wasting_effect = new
|
||||
|
||||
/datum/status_effect/necropolis_curse/on_creation(mob/living/new_owner, set_curse)
|
||||
/datum/status_effect/necropolis_curse/on_creation(mob/living/new_owner, set_curse, _duration)
|
||||
if(_duration)
|
||||
duration = _duration
|
||||
. = ..()
|
||||
if(.)
|
||||
apply_curse(set_curse)
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death."
|
||||
|
||||
/datum/quirk/brainproblems/on_process()
|
||||
quirk_holder.adjustBrainLoss(0.2)
|
||||
quirk_holder.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2)
|
||||
|
||||
/datum/quirk/nearsighted //t. errorage
|
||||
name = "Nearsighted"
|
||||
@@ -345,16 +345,19 @@
|
||||
gain_text = "<span class='danger'>You find yourself unable to speak!</span>"
|
||||
lose_text = "<span class='notice'>You feel a growing strength in your vocal chords.</span>"
|
||||
medical_record_text = "Functionally mute, patient is unable to use their voice in any capacity."
|
||||
var/datum/brain_trauma/severe/mute/mute
|
||||
|
||||
/datum/quirk/mute/add()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
H.gain_trauma(TRAIT_MUTE, TRAUMA_RESILIENCE_SURGERY)
|
||||
mute = new
|
||||
H.gain_trauma(mute, TRAUMA_RESILIENCE_SURGERY)
|
||||
|
||||
/datum/quirk/mute/on_process()
|
||||
if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums))
|
||||
to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused your voice to be heard.</span>")
|
||||
qdel(src)
|
||||
|
||||
|
||||
/datum/quirk/unstable
|
||||
name = "Unstable"
|
||||
desc = "Due to past troubles, you are unable to recover your sanity if you lose it. Be very careful managing your mood!"
|
||||
@@ -363,3 +366,21 @@
|
||||
gain_text = "<span class='danger'>There's a lot on your mind right now.</span>"
|
||||
lose_text = "<span class='notice'>Your mind finally feels calm.</span>"
|
||||
medical_record_text = "Patient's mind is in a vulnerable state, and cannot recover from traumatic events."
|
||||
|
||||
/datum/quirk/blindness
|
||||
name = "Blind"
|
||||
desc = "You are completely blind, nothing can counteract this."
|
||||
value = -4
|
||||
gain_text = "<span class='danger'>You can't see anything.</span>"
|
||||
lose_text = "<span class='notice'>You miraculously gain back your vision.</span>"
|
||||
medical_record_text = "Subject has permanent blindness."
|
||||
|
||||
/datum/quirk/blindness/add()
|
||||
quirk_holder.become_blind(ROUNDSTART_TRAIT)
|
||||
|
||||
/datum/quirk/blindness/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/obj/item/clothing/glasses/sunglasses/blindfold/white/glasses = new(get_turf(H))
|
||||
if(!H.equip_to_slot_if_possible(glasses, SLOT_GLASSES, bypass_equip_delay_self = TRUE)) //if you can't put it on the user's eyes, put it in their hands, otherwise put it on their eyes eyes
|
||||
H.put_in_hands(glasses)
|
||||
H.regenerate_icons()
|
||||
|
||||
Reference in New Issue
Block a user