mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 04:30:44 +01:00
@@ -7,6 +7,7 @@
|
||||
var/special_role = ROLE_HIVE
|
||||
var/list/hivemembers = list()
|
||||
var/hive_size = 0
|
||||
var/threat_level = 0 // Part of what determines how strong the radar is, on a scale of 0 to 10
|
||||
var/static/datum/objective/hivemind/assimilate_common/common_assimilation_obj //Make it static since we want a common target for all the antags
|
||||
|
||||
var/list/upgrade_tiers = list(
|
||||
@@ -34,6 +35,10 @@
|
||||
if(hive_size != old_size)
|
||||
check_powers()
|
||||
|
||||
/datum/antagonist/hivemind/proc/get_threat_multiplier()
|
||||
calc_size()
|
||||
return min(hive_size/50 + threat_level/20, 1)
|
||||
|
||||
/datum/antagonist/hivemind/proc/check_powers()
|
||||
for(var/power in upgrade_tiers)
|
||||
var/level = upgrade_tiers[power]
|
||||
@@ -43,27 +48,13 @@
|
||||
if(hive_size > 0)
|
||||
to_chat(owner, "<span class='assimilator'>We have unlocked [the_spell.name].</span><span class='bold'> [the_spell.desc]</span>")
|
||||
|
||||
/datum/antagonist/hivemind/proc/get_real_name() //Gets the real name of the host, even if they're temporarily in another one
|
||||
var/obj/effect/proc_holder/spell/target_hive/hive_control/the_spell = locate(/obj/effect/proc_holder/spell/target_hive/hive_control) in owner.spell_list
|
||||
var/datum/mind/M = owner
|
||||
if(M)
|
||||
var/mob/living/L = owner.current
|
||||
if(L)
|
||||
if(the_spell && the_spell.active)
|
||||
if(the_spell.original_body)
|
||||
return the_spell.original_body.real_name
|
||||
return L.real_name
|
||||
return ""
|
||||
|
||||
/datum/antagonist/hivemind/proc/add_to_hive(var/mob/living/carbon/human/H)
|
||||
var/warning = "<span class='userdanger'>We detect a surge of psionic energy from [H.real_name] before they disappear from the hive. An enemy host, or simply a stolen vessel?</span>"
|
||||
var/user_warning = "<span class='userdanger'>We have detected an enemy hivemind using our physical form as a vessel and have begun ejecting their mind! They will be alerted of our disappearance once we succeed!</span>"
|
||||
for(var/datum/antagonist/hivemind/enemy_hive in GLOB.antagonists)
|
||||
if(H.mind == enemy_hive.owner)
|
||||
if(is_real_hivehost(H))
|
||||
var/eject_time = rand(1400,1600) //2.5 minutes +- 10 seconds
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, H, user_warning), rand(500,1300)) // If the host has assimilated an enemy hive host, alert the enemy before booting them from the hive after a short while
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, owner, warning), eject_time) //As well as the host who just added them as soon as they're ejected
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/remove_hivemember, H), eject_time)
|
||||
addtimer(CALLBACK(src, .proc/handle_ejection, H), eject_time)
|
||||
hivemembers |= H
|
||||
calc_size()
|
||||
|
||||
@@ -71,6 +62,30 @@
|
||||
hivemembers -= H
|
||||
calc_size()
|
||||
|
||||
/datum/antagonist/hivemind/proc/handle_ejection(mob/living/carbon/human/H)
|
||||
var/user_warning = "The enemy host has been ejected from our mind"
|
||||
|
||||
if(!H || !owner)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H2 = owner.current
|
||||
if(!H2)
|
||||
return
|
||||
|
||||
var/mob/living/real_H = H.get_real_hivehost()
|
||||
var/mob/living/real_H2 = H2.get_real_hivehost()
|
||||
|
||||
if(is_real_hivehost(H))
|
||||
real_H2.apply_status_effect(STATUS_EFFECT_HIVE_TRACKER, real_H)
|
||||
real_H.apply_status_effect(STATUS_EFFECT_HIVE_RADAR)
|
||||
to_chat(real_H, "<span class='userdanger'>We detect a surge of psionic energy from a far away vessel before they disappear from the hive. Whatever happened, there's a good chance they're after us now.</span>")
|
||||
if(is_real_hivehost(H2))
|
||||
real_H.apply_status_effect(STATUS_EFFECT_HIVE_TRACKER, real_H2)
|
||||
real_H2.apply_status_effect(STATUS_EFFECT_HIVE_RADAR)
|
||||
user_warning += " and we've managed to pinpoint their location"
|
||||
|
||||
to_chat(H2, "<span class='userdanger'>[user_warning]!</span>")
|
||||
|
||||
/datum/antagonist/hivemind/proc/destroy_hive()
|
||||
hivemembers = list()
|
||||
calc_size()
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
var/minimum_range = PINPOINTER_MINIMUM_RANGE
|
||||
var/range_fuzz_factor = PINPOINTER_EXTRA_RANDOM_RANGE
|
||||
var/mob/scan_target = null
|
||||
var/range_mid = 8
|
||||
var/range_far = 16
|
||||
|
||||
/obj/screen/alert/status_effect/agent_pinpointer
|
||||
name = "Internal Affairs Integrated Pinpointer"
|
||||
@@ -66,13 +68,13 @@
|
||||
linked_alert.icon_state = "pinondirect"
|
||||
else
|
||||
linked_alert.setDir(get_dir(here, there))
|
||||
switch(get_dist(here, there))
|
||||
if(1 to 8)
|
||||
linked_alert.icon_state = "pinonclose"
|
||||
if(9 to 16)
|
||||
linked_alert.icon_state = "pinonmedium"
|
||||
if(16 to INFINITY)
|
||||
linked_alert.icon_state = "pinonfar"
|
||||
var/dist = (get_dist(here, there))
|
||||
if(dist >= 1 && dist <= range_mid)
|
||||
linked_alert.icon_state = "pinonclose"
|
||||
else if(dist > range_mid && dist <= range_far)
|
||||
linked_alert.icon_state = "pinonmedium"
|
||||
else if(dist > range_far)
|
||||
linked_alert.icon_state = "pinonfar"
|
||||
|
||||
/datum/status_effect/agent_pinpointer/proc/scan_for_target()
|
||||
scan_target = null
|
||||
|
||||
@@ -248,7 +248,7 @@
|
||||
|
||||
/obj/effect/proc_holder/spell/target_hive/hive_control
|
||||
name = "Mind Control"
|
||||
desc = "We assume direct control of one of our vessels, leaving our current body for up to ten seconds, although a larger hive may be able to sustain it for up to two minutes. It can be cancelled at any time by casting it again. Powers can be used via our vessel, although if it dies, the entire hivemind will come down with it."
|
||||
desc = "We assume direct control of one of our vessels, leaving our current body for up to ten seconds, although a larger hive may be able to sustain it for up to two minutes. It can be cancelled at any time by casting it again. Powers can be used via our vessel, although if it dies, the entire hivemind will come down with it. Our ability to sense psionic energy is completely nullified while using this power."
|
||||
charge_max = 600
|
||||
action_icon_state = "force"
|
||||
active = FALSE
|
||||
@@ -285,6 +285,14 @@
|
||||
|
||||
QDEL_NULL(backseat)
|
||||
|
||||
if(original_body?.mind)
|
||||
var/datum/antagonist/hivemind/hive = original_body.mind.has_antag_datum(/datum/antagonist/hivemind)
|
||||
if(hive)
|
||||
if((world.time-time_initialized) <= 300)
|
||||
hive.threat_level += 0.5
|
||||
else
|
||||
hive.threat_level += 1
|
||||
|
||||
/obj/effect/proc_holder/spell/target_hive/hive_control/on_lose(mob/user)
|
||||
release_control()
|
||||
|
||||
@@ -456,6 +464,9 @@
|
||||
deadchat_broadcast("<span class='deadsay'><span class='name'>[target]</span> has suffered a mysterious heart attack!</span>", target)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>We are unable to induce a heart attack!</span>")
|
||||
var/datum/antagonist/hivemind/hive = user.mind.has_antag_datum(/datum/antagonist/hivemind)
|
||||
if(hive)
|
||||
hive.threat_level += 2
|
||||
|
||||
/obj/effect/proc_holder/spell/target_hive/hive_warp
|
||||
name = "Distortion Field"
|
||||
@@ -516,7 +527,6 @@
|
||||
var/mob/living/carbon/human/target = targets[1]
|
||||
var/in_hive = hive.hivemembers.Find(target)
|
||||
var/list/enemies = list()
|
||||
var/enemy_names = ""
|
||||
|
||||
to_chat(user, "<span class='notice'>We begin probing [target.name]'s mind!</span>")
|
||||
if(do_after(user,100,0,target))
|
||||
@@ -528,22 +538,26 @@
|
||||
return
|
||||
for(var/datum/antagonist/hivemind/enemy in GLOB.antagonists)
|
||||
var/datum/mind/M = enemy.owner
|
||||
if(!M || M.current == user)
|
||||
if(M?.current == user)
|
||||
continue
|
||||
if(enemy.hivemembers.Find(target))
|
||||
var/hive_name = enemy.get_real_name()
|
||||
if(hive_name)
|
||||
enemies += hive_name
|
||||
var/mob/living/real_enemy = (M.current.get_real_hivehost())
|
||||
enemies += real_enemy
|
||||
enemy.remove_from_hive(target)
|
||||
to_chat(M.current, "<span class='userdanger'>We detect a surge of psionic energy from [target.real_name] before they disappear from the hive. An enemy host, or simply a stolen vessel?</span>")
|
||||
real_enemy.apply_status_effect(STATUS_EFFECT_HIVE_TRACKER, user)
|
||||
if(is_real_hivehost(M.current)) //If they were using mind control, too bad
|
||||
real_enemy.apply_status_effect(STATUS_EFFECT_HIVE_RADAR)
|
||||
target.apply_status_effect(STATUS_EFFECT_HIVE_TRACKER, real_enemy)
|
||||
to_chat(real_enemy, "<span class='userdanger'>We detect a surge of psionic energy from a far away vessel before they disappear from the hive. Whatever happened, there's a good chance they're after us now.</span>")
|
||||
|
||||
if(enemy.owner == target && is_real_hivehost(target))
|
||||
user.Stun(70)
|
||||
user.Jitter(14)
|
||||
to_chat(user, "<span class='userdanger'>A sudden surge of psionic energy rushes into your mind, only a Hive host could have such power!!</span>")
|
||||
return
|
||||
if(enemies.len)
|
||||
enemy_names = enemies.Join(". ")
|
||||
to_chat(user, "<span class='userdanger'>In a moment of clarity, we see all. Another hive. Faces. Our nemesis. [enemy_names]. They are watching us. They know we are coming.</span>")
|
||||
to_chat(user, "<span class='userdanger'>In a moment of clarity, we see all. Another hive. Faces. Our nemesis. They have heard our call. They know we are coming.</span>")
|
||||
user.apply_status_effect(STATUS_EFFECT_HIVE_RADAR)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>We peer into the inner depths of their mind and see nothing, no enemies lurk inside this mind.</span>")
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user