Borer Stuff 2: Electric Boogaloo (#11423)

This commit is contained in:
Geeves
2021-04-10 18:30:31 +02:00
committed by GitHub
parent 6d2da2d893
commit 138a7a7a45
13 changed files with 214 additions and 36 deletions
@@ -160,7 +160,7 @@
return O
/mob/living/carbon/human/proc/awaken_psi_basic(var/source)
/mob/living/carbon/human/proc/awaken_psi_basic(var/source, var/allow_latency = TRUE)
var/static/list/psi_operancy_messages = list(
"There's something in your skull!",
"Something is eating your thoughts!",
@@ -176,11 +176,9 @@
var/list/faculties = list(PSI_COERCION, PSI_REDACTION, PSI_ENERGISTICS, PSI_PSYCHOKINESIS)
for(var/i = 1 to new_latencies)
custom_pain(SPAN_DANGER("<font size = 3>[pick(psi_operancy_messages)]</font>"), 25)
set_psi_rank(pick_n_take(faculties), 1)
set_psi_rank(pick_n_take(faculties), allow_latency ? PSI_RANK_LATENT : PSI_RANK_OPERANT) // if set to latent, it spikes anywhere from OPERANT to PARAMOUNT
sleep(30)
psi.update()
sleep(45)
psi.check_latency_trigger(100, source, TRUE)
addtimer(CALLBACK(psi, /datum/psi_complexus/.proc/check_latency_trigger, 100, source, TRUE), 4.5 SECONDS)
/mob/living/carbon/human/get_resist_power()
return species.resist_mod
@@ -28,11 +28,15 @@
hunger_enabled = FALSE
var/used_dominate
var/datum/progressbar/autocomplete/ability_bar
var/ability_start_time = 0
var/obj/screen/borer/chemicals/chem_hud
var/chemicals = 10 // Chemicals used for reproduction and spitting neurotoxin.
var/mob/living/carbon/human/host // Human host for the brain worm.
var/truename // Name used for brainworm-speak.
var/mob/living/captive_brain/host_brain // Used for swapping control of the body back and forth.
var/controlling // Used in human death check.
var/list/static/controlling_emotes = list("blink","blink_r","choke","drool","twitch","twitch_v","gasp")
var/has_reproduced
var/request_player = TRUE
@@ -43,6 +47,8 @@
..()
if(mind)
borers.add_antagonist(mind)
if(client && host)
client.screen += host.healths
/mob/living/simple_animal/borer/Initialize()
. = ..()
@@ -56,6 +62,11 @@
if(request_player && !ckey && !client)
SSghostroles.add_spawn_atom("borer", src)
/mob/living/simple_animal/borer/Destroy()
QDEL_NULL(ability_bar)
QDEL_NULL(host_brain)
return ..()
/mob/living/simple_animal/borer/death(gibbed, deathmessage)
SSghostroles.remove_spawn_atom("borer", src)
return ..(gibbed,deathmessage)
@@ -64,14 +75,28 @@
return FALSE
/mob/living/simple_animal/borer/Life()
..()
if(host)
if(!stat && host.stat != DEAD)
if(chemicals < 250)
chemicals++
if(host && !host.stat)
if(controlling && prob(host.getBrainLoss()/20))
host.say("*[pick(list("blink","blink_r","choke","drool","twitch","twitch_s","gasp"))]")
if(!host.stat && controlling && prob(2))
host.emote(pick(controlling_emotes))
..()
if(!QDELETED(ability_bar))
ability_bar.update(world.time - ability_start_time)
/mob/living/simple_animal/borer/proc/start_ability(var/atom/target, var/time)
if(!QDELETED(ability_bar))
return FALSE
ability_bar = new /datum/progressbar/autocomplete(src, time, target)
ability_start_time = world.time
ability_bar.update(0)
return TRUE
/mob/living/simple_animal/borer/handle_regular_hud_updates()
. = ..()
if(chem_hud)
chem_hud.maptext = SMALL_FONTS(7, chemicals)
/mob/living/simple_animal/borer/Stat()
..()
@@ -89,6 +114,9 @@
if(!host || !controlling)
return
if(ability_bar)
QDEL_NULL(ability_bar)
if(istype(host,/mob/living/carbon/human))
var/mob/living/carbon/human/H = host
var/obj/item/organ/external/head = H.get_organ(BP_HEAD)
@@ -158,8 +186,27 @@
host.machine = null
host.status_flags &= ~PASSEMOTES
if(client)
client.screen -= host.healths
host = null
return
/mob/living/simple_animal/borer/cannot_use_vents()
return
/mob/living/simple_animal/borer/UnarmedAttack(atom/A, proximity)
if(iscarbon(A))
var/mob/living/carbon/C = A
if(C.lying || C.weakened)
do_infest(C)
else
do_paralyze(C)
return
return ..()
/mob/living/simple_animal/borer/RangedAttack(atom/A, params)
if(iscarbon(A) && get_dist(src, A) <= 2)
var/mob/living/carbon/C = A
do_paralyze(C)
return
return ..()
@@ -3,6 +3,9 @@
real_name = "host brain"
universal_understand = TRUE
var/datum/progressbar/resist_bar
var/resist_start_time = 0
/mob/living/captive_brain/say(var/message)
if(istype(src.loc,/mob/living/simple_animal/borer))
message = sanitize(message)
@@ -22,19 +25,36 @@
else if(M.stat == DEAD && M.client.prefs.toggles & CHAT_GHOSTEARS)
to_chat(M, "The captive mind of [src] whispers, \"[message]\"")
/mob/living/captive_brain/Destroy()
QDEL_NULL(resist_bar)
return ..()
/mob/living/captive_brain/emote(var/message)
return
/mob/living/captive_brain/Life()
if(resist_bar)
resist_bar.update(world.time - resist_start_time)
return ..()
/mob/living/captive_brain/process_resist()
//Resisting control by an alien mind.
if(resist_bar)
to_chat(src, SPAN_WARNING("You're already resisting the alien control!"))
return
if(istype(src.loc,/mob/living/simple_animal/borer))
var/mob/living/simple_animal/borer/B = src.loc
var/mob/living/captive_brain/H = src
to_chat(H, SPAN_DANGER("You begin doggedly resisting the parasite's control (this will take approximately sixty seconds)."))
to_chat(H, SPAN_DANGER("You begin doggedly resisting the parasite's control."))
to_chat(B.host, SPAN_DANGER("You feel the captive mind of [src] begin to resist your control."))
addtimer(CALLBACK(src, .proc/eject_borer, B, H), rand(200, 250) + B.host.getBrainLoss())
var/resist_time = rand(40 SECONDS, 1 MINUTE)
addtimer(CALLBACK(src, .proc/eject_borer, B, H), resist_time)
resist_bar = new /datum/progressbar/autocomplete(src, resist_time, B.host)
resist_start_time = world.time
resist_bar.update(0)
return
..()
@@ -10,12 +10,16 @@
to_chat(src, SPAN_NOTICE("You cannot leave your host in your current state."))
return
to_chat(src, SPAN_NOTICE("You begin disconnecting from [host]'s synapses and prodding at their internal ear canal."))
var/exit_time = 10 SECONDS
if(!start_ability(host, exit_time))
to_chat(src, SPAN_WARNING("You're busy doing something else, complete that task first."))
return
to_chat(src, SPAN_NOTICE("You begin disconnecting from [host]'s synapses and prodding at their internal ear canal."))
if(!host.stat)
to_chat(host, SPAN_WARNING("An odd, uncomfortable pressure begins to build inside your skull, behind your ear..."))
addtimer(CALLBACK(src, .proc/exit_host), 100)
addtimer(CALLBACK(src, .proc/exit_host), exit_time)
/mob/living/simple_animal/borer/proc/exit_host()
if(!host || !src)
@@ -48,19 +52,28 @@
return
var/list/choices = list()
for(var/mob/living/carbon/C in view(1,src))
for(var/mob/living/carbon/C in view(2, src))
if(src.Adjacent(C))
choices += C
if(!choices.len)
if(!length(choices))
to_chat(src, SPAN_NOTICE("There are no viable hosts within range."))
return
var/mob/living/carbon/M = input(src,"Who do you wish to infest?") in null|choices
if(M)
do_infest(M)
/mob/living/simple_animal/borer/proc/do_infest(var/mob/living/carbon/M)
if(host)
to_chat(src, SPAN_NOTICE("You are already within a host."))
return
if(stat)
to_chat(src, SPAN_NOTICE("You cannot infest a target in your current state."))
return
if(!M || !src)
return
if(!(src.Adjacent(M)))
if(!Adjacent(M))
return
if(M.has_brain_worms())
to_chat(src, SPAN_WARNING("You cannot infest someone who is already infested!"))
@@ -108,6 +121,9 @@
src.host.status_flags |= PASSEMOTES
src.forceMove(M)
if(client)
client.screen += host.healths
//Update their traitor status.
if(host.mind)
borers.add_antagonist_mind(host.mind, 1, borers.faction_role_text, borers.faction_welcome)
@@ -240,12 +256,14 @@
if(C.stat != 2)
choices += C
var/mob/living/carbon/M = input(src, "Who do you wish to dominate?") in null|choices
if(M)
do_paralyze(M)
/mob/living/simple_animal/borer/proc/do_paralyze(var/mob/living/carbon/M)
if(world.time - used_dominate < 150)
to_chat(src, SPAN_NOTICE("You cannot use that ability again so soon."))
return
var/mob/living/carbon/M = input(src, "Who do you wish to dominate?") in null|choices
if(!M || !src)
return
if(M.isSynthetic())
@@ -283,10 +301,15 @@
to_chat(src, SPAN_WARNING("\The [host]'s mind is shielded against your powers."))
return
var/takeover_time = 10 SECONDS + (host.getBrainLoss() * 5)
if(!start_ability(host, takeover_time))
to_chat(src, SPAN_WARNING("You're busy doing something else, complete that task first."))
return
to_chat(src, SPAN_WARNING("You begin delicately adjusting your connection to the host brain..."))
to_chat(host, SPAN_WARNING("You feel a tingling sensation at the back of your head."))
addtimer(CALLBACK(src, .proc/host_takeover), 100+(host.getBrainLoss()*5))
addtimer(CALLBACK(src, .proc/host_takeover), takeover_time)
/mob/living/simple_animal/borer/proc/host_takeover()
if(!host || !src || controlling)
@@ -307,8 +330,8 @@
host_brain = new(src)
host_brain.ckey = host.ckey
host_brain.name = host.name
host_brain.name = host.real_name
host_brain.real_name = "[host_brain.name] (captive host)"
if(!host_brain.computer_id)
host_brain.computer_id = h2b_id
@@ -441,20 +464,30 @@
to_chat(src, SPAN_WARNING("\The [host]'s mind is shielded against your powers."))
return
var/jumpstart_time = 15 SECONDS
if(!start_ability(host, jumpstart_time))
to_chat(src, SPAN_WARNING("You're busy doing something else, complete that task first."))
return
chemicals -= 150
to_chat(src, SPAN_NOTICE("You probe your tendrils deep within your host's zona bovinae, seeking to unleash their potential."))
to_chat(host, SPAN_DANGER("You feel some tendrils probe at the back of your head..."))
to_chat(host, FONT_LARGE(SPAN_WARNING("You feel something terrible coming on...")))
addtimer(CALLBACK(src, .proc/jumpstart_psi), 150)
addtimer(CALLBACK(src, .proc/jumpstart_psi), jumpstart_time)
/mob/living/simple_animal/borer/proc/jumpstart_psi()
if(!host)
return
to_chat(src, SPAN_NOTICE("You succeed in interfacing with the host's zona bovinae, this will be a painful process for them."))
host.awaken_psi_basic("something in your head")
host.awaken_psi_basic("something in your head", FALSE)
host.add_language(LANGUAGE_TCB) // if we don't have TCB, give them TCB | this allows monkey borers to RP
/mob/living/simple_animal/borer/verb/advance_faculty()
set category = "Abilities"
set name = "Advance Psionic Faculty (75)"
set desc = "Advance one of your host's psionic faculties' by one step."
set desc = "Advance one of your host's psionic faculties by one step."
if(!host)
to_chat(src, SPAN_NOTICE("You are not inside a host body."))
@@ -479,19 +512,31 @@
if(!selected_faculty)
return
selected_faculty = lowertext(selected_faculty)
if(host.psi.get_rank(selected_faculty) >= PSI_RANK_GRANDMASTER)
var/max_rank = islesserform(host) ? PSI_RANK_OPERANT : PSI_RANK_MASTER
if(host.psi.get_rank(selected_faculty) >= max_rank)
to_chat(src, SPAN_NOTICE("This faculty has already been pushed to the max potential you can achieve!"))
return
var/faculty_time = 10 SECONDS
if(!start_ability(host, faculty_time))
to_chat(src, SPAN_WARNING("You're busy doing something else, complete that task first."))
return
chemicals -= 75
to_chat(src, SPAN_NOTICE("You probe your tendrils deep within your host's zona bovinae, seeking to upgrade their abilities."))
to_chat(host, SPAN_WARNING("You feel a burning, tingling sensation at the back of your head..."))
addtimer(CALLBACK(src, .proc/faculty_upgrade, selected_faculty), 100)
addtimer(CALLBACK(src, .proc/faculty_upgrade, selected_faculty), faculty_time)
/mob/living/simple_animal/borer/proc/faculty_upgrade(var/selected_faculty)
host.psi.set_rank(selected_faculty, host.psi.get_rank(selected_faculty) + 1)
host.psi.update()
to_chat(src, SPAN_NOTICE("You successfully manage to upgrade your host's [selected_faculty] faculty."))
if(!host)
return
var/host_psi_rank = host.psi.get_rank(selected_faculty)
var/next_rank = host_psi_rank > PSI_RANK_BLUNT ? host_psi_rank + 1 : PSI_RANK_OPERANT
host.psi.set_rank(selected_faculty, next_rank)
host.psi.update(TRUE)
to_chat(src, SPAN_NOTICE("You successfully manage to upgrade your host to [psychic_ranks_to_strings[host.psi.ranks[selected_faculty]]] [selected_faculty]."))
to_chat(host, SPAN_GOOD("A breeze of fresh air washes over your mind, you feel powerful!"))
to_chat(host, SPAN_NOTICE("You have been psionically enlightened. You are now a [psychic_ranks_to_strings[host.psi.ranks[selected_faculty]]] in the [selected_faculty] faculty."))
@@ -31,15 +31,14 @@
to_chat(src, SPAN_NOTICE("There are no viable hosts to speak with."))
else
var/mob/living/carbon/human/chosen_sayer = pick(viable_sayers)
log_say("[key_name(src)] : ([name]) [message]", ckey=key_name(src))
log_say("[key_name(src)] : (forcing [key_name(chosen_sayer)]) [message]", ckey=key_name(src))
chosen_sayer.say(message)
return
to_chat(src, "<b>You drop words into [host]'s mind:</b> \"[message]\"")
to_chat(host, "<b>Your own thoughts speak:</b> \"[message]\"")
log_say("[key_name(src)] : (borer whisper -> [key_name(host)]) [message]")
for(var/mob/M in player_list)
if(istype(M, /mob/abstract/new_player))
continue
else if(M.stat == DEAD && M.client.prefs.toggles & CHAT_GHOSTEARS)
to_chat(M, "<b>[src.truename]</b> whispers to <b>[host]</b>, \"[message]\"")
for(var/mob/M in mob_list)
if(M.client && M.stat == DEAD && !isnewplayer(M) && (M.client.prefs.toggles & CHAT_GHOSTEARS))
to_chat(M, "<b>[src.truename]</b> whispers to <b>[host]</b>, \"[message]\"")