mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 16:05:07 +00:00
[READY] New Side Antagonist: The Creep! (#42021)
cl
add: Added a new antagonist, the Creep!
add: Chosen from a random event, the Creep will become obsessed with one person, feeling amazing around them and terrible when they aren't. They will have objectives to steal heirlooms, take pictures, hug, and kill coworkers. They also have to kill the obsession but some objectives can only be completed while the obsession is alive, requiring you to protect the obsession!
/cl
There really is no reason to betray people, generally. Maybe some stuff with security and traitors working things out, but a traitor based around betrayal and the general insane creep idea is just cool.
One Creep can show up, and they get objectives to mess with their obsession leading to the obsession's death. Here is their objectives:
A random creepy objective. It could be taking a photo with them in it, hugging them, etc
After your are done with your objectives, kill them. you can't complete the objectives when they are dead!
Creeps do not get the determination mood. Instead, when they are around their obsession, they feel AMAZING! If they are around too long, they will stutter, cough, and generally spaghetti out when talking near their obsession. So if you are going to talk near them, do it when you aren't entranced.
This commit is contained in:
@@ -58,6 +58,7 @@
|
||||
#define ANTAG_HUD_CLOCKWORK 22
|
||||
#define ANTAG_HUD_BROTHER 23
|
||||
#define ANTAG_HUD_HIVE 24
|
||||
#define ANTAG_HUD_CREEP 25
|
||||
|
||||
// Notification action types
|
||||
#define NOTIFY_JUMP "jump"
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define ROLE_BRAINWASHED "Brainwashed Victim"
|
||||
#define ROLE_OVERTHROW "Syndicate Mutineer"
|
||||
#define ROLE_HIVE "Hivemind Host"
|
||||
#define ROLE_CREEP "Creep"
|
||||
#define ROLE_SENTIENCE "Sentience Potion Spawn"
|
||||
#define ROLE_MIND_TRANSFER "Mind Transfer Potion"
|
||||
#define ROLE_POSIBRAIN "Posibrain"
|
||||
@@ -52,6 +53,7 @@ GLOBAL_LIST_INIT(special_roles, list(
|
||||
ROLE_CULTIST = /datum/game_mode/cult,
|
||||
ROLE_BLOB,
|
||||
ROLE_NINJA,
|
||||
ROLE_CREEP,
|
||||
ROLE_MONKEY = /datum/game_mode/monkey,
|
||||
ROLE_REVENANT,
|
||||
ROLE_ABDUCTOR,
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
#define STATUS_EFFECT_GOOD_MUSIC /datum/status_effect/good_music
|
||||
|
||||
#define STATUS_EFFECT_CREEP /datum/status_effect/creep //you feel fuckin great around your obsession
|
||||
|
||||
/////////////
|
||||
// DEBUFFS //
|
||||
/////////////
|
||||
|
||||
@@ -48,3 +48,7 @@
|
||||
//Called when speaking
|
||||
/datum/brain_trauma/proc/on_say(message)
|
||||
return message
|
||||
|
||||
//Called when hugging. expand into generally interacting, where future coders could switch the intent?
|
||||
/datum/brain_trauma/proc/on_hug(mob/living/hugger, mob/living/hugged)
|
||||
return
|
||||
120
code/datums/brain_damage/creepy_trauma.dm
Normal file
120
code/datums/brain_damage/creepy_trauma.dm
Normal file
@@ -0,0 +1,120 @@
|
||||
/datum/brain_trauma/special/creep
|
||||
name = "Erotomania"
|
||||
desc = "Patient has a subtype of delusional disorder, becoming irrationally attached to someone."
|
||||
scan_desc = "severe erotomaniac delusions"
|
||||
gain_text = "If you see this message, make a github issue report. The trauma initialized wrong."
|
||||
lose_text = "<span class='warning'>You no longer feel so attached.</span>"
|
||||
can_gain = TRUE
|
||||
resilience = TRAUMA_RESILIENCE_SURGERY
|
||||
var/mob/living/obsession
|
||||
var/datum/objective/spendtime/attachedcreepobj
|
||||
var/datum/antagonist/creep/antagonist
|
||||
var/viewing = FALSE //it's a lot better to store if the owner is watching the obsession than checking it twice between two procs
|
||||
|
||||
var/total_time_creeping = 0 //just for roundend fun
|
||||
var/time_spent_away = 0
|
||||
var/obsession_hug_count = 0
|
||||
|
||||
/datum/brain_trauma/special/creep/on_gain()
|
||||
|
||||
//setup, linking, etc//
|
||||
if(!obsession)//admins didn't set one
|
||||
obsession = find_obsession()
|
||||
if(!obsession)//we didn't find one
|
||||
lose_text = ""
|
||||
qdel(src)
|
||||
gain_text = "<span class='warning'>You feel a strange attachment to [obsession].</span>"
|
||||
owner.apply_status_effect(STATUS_EFFECT_INLOVE, obsession)
|
||||
owner.mind.add_antag_datum(/datum/antagonist/creep)
|
||||
antagonist = owner.mind.has_antag_datum(/datum/antagonist/creep)
|
||||
antagonist.trauma = src
|
||||
..()
|
||||
//antag stuff//
|
||||
antagonist.forge_objectives(obsession.mind)
|
||||
antagonist.greet()
|
||||
|
||||
/datum/brain_trauma/special/creep/on_life()
|
||||
if(!obsession || obsession.stat == DEAD)
|
||||
viewing = FALSE//important, makes sure you no longer stutter when happy if you murdered them while viewing
|
||||
return
|
||||
if(get_dist(get_turf(owner), get_turf(obsession)) > 7)
|
||||
viewing = FALSE //they are further than our viewrange they are not viewing us
|
||||
out_of_view()
|
||||
return//so we're not searching everything in view every tick
|
||||
if(obsession in view(7, owner))
|
||||
viewing = TRUE
|
||||
else
|
||||
viewing = FALSE
|
||||
if(viewing)
|
||||
SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "creeping", /datum/mood_event/creeping, obsession.name)
|
||||
total_time_creeping += 20
|
||||
time_spent_away = 0
|
||||
if(attachedcreepobj)//if an objective needs to tick down, we can do that since traumas coexist with the antagonist datum
|
||||
attachedcreepobj.timer -= 20 //mob subsystem ticks every 2 seconds(?), remove 20 deciseconds from the timer. sure, that makes sense.
|
||||
else
|
||||
out_of_view()
|
||||
|
||||
/datum/brain_trauma/special/creep/proc/out_of_view()
|
||||
time_spent_away += 20
|
||||
if(time_spent_away > 1800) //3 minutes
|
||||
SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "creeping", /datum/mood_event/notcreepingsevere, obsession.name)
|
||||
else
|
||||
SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "creeping", /datum/mood_event/notcreeping, obsession.name)
|
||||
/datum/brain_trauma/special/creep/on_lose()
|
||||
..()
|
||||
owner.remove_status_effect(STATUS_EFFECT_INLOVE)
|
||||
owner.mind.remove_antag_datum(/datum/antagonist/creep)
|
||||
|
||||
/datum/brain_trauma/special/creep/on_say(message)
|
||||
if(!viewing)
|
||||
return message
|
||||
var/choked_up
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, owner)
|
||||
if(mood)
|
||||
if(mood.sanity >= SANITY_GREAT)
|
||||
choked_up = social_interaction()
|
||||
if(choked_up)
|
||||
return ""
|
||||
return message
|
||||
|
||||
/datum/brain_trauma/special/creep/on_hug(mob/living/hugger, mob/living/hugged)
|
||||
if(hugged == obsession)
|
||||
obsession_hug_count++
|
||||
|
||||
/datum/brain_trauma/special/creep/proc/social_interaction()
|
||||
var/fail = FALSE //whether you can finish a sentence while doing it
|
||||
owner.stuttering = max(3, owner.stuttering)
|
||||
owner.blur_eyes(10)
|
||||
switch(rand(1,4))
|
||||
if(1)
|
||||
shake_camera(owner, 15, 1)
|
||||
owner.vomit()
|
||||
fail = TRUE
|
||||
if(2)
|
||||
owner.emote("cough")
|
||||
owner.dizziness += 10
|
||||
fail = TRUE
|
||||
if(3)
|
||||
to_chat(owner, "<span class='userdanger'>You feel your heart lurching in your chest...</span>")
|
||||
owner.Stun(20)
|
||||
shake_camera(owner, 15, 1)
|
||||
if(4)
|
||||
to_chat(owner, "<span class='warning'>You faint.</span>")
|
||||
owner.Unconscious(80)
|
||||
fail = TRUE
|
||||
return fail
|
||||
|
||||
|
||||
/datum/brain_trauma/special/creep/proc/find_obsession()
|
||||
var/chosen_victim
|
||||
var/list/possible_targets = list()
|
||||
var/list/viable_minds = list()
|
||||
for(var/mob/Player in GLOB.player_list)//prevents crewmembers falling in love with nuke ops they never met
|
||||
if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) && !isbrain(Player) && Player.client && Player != owner && !(Player.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL] || Player.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_ANTAG]))
|
||||
viable_minds += Player.mind
|
||||
for(var/datum/mind/possible_target in viable_minds)
|
||||
if(possible_target != owner && ishuman(possible_target.current))
|
||||
possible_targets += possible_target.current
|
||||
if(possible_targets.len > 0)
|
||||
chosen_victim = pick(possible_targets)
|
||||
return chosen_victim
|
||||
@@ -14,3 +14,6 @@
|
||||
/datum/component/heirloom/proc/examine(datum/source, mob/user)
|
||||
if(user.mind == owner)
|
||||
to_chat(user, "<span class='notice'>It is your precious [family_name] family heirloom. Keep it safe!</span>")
|
||||
var/datum/antagonist/creep/creeper = user.mind.has_antag_datum(/datum/antagonist/creep)
|
||||
if(creeper && creeper.trauma.obsession == owner)
|
||||
to_chat(user, "<span class='nicegreen'>This must be [owner]'s family heirloom! It smells just like them...</span>")
|
||||
@@ -28,6 +28,7 @@ GLOBAL_LIST_INIT(huds, list(
|
||||
ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_HIVE = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_CREEP = new/datum/atom_hud/antag/hidden()
|
||||
))
|
||||
|
||||
/datum/atom_hud
|
||||
|
||||
@@ -137,12 +137,37 @@
|
||||
mood_change = -5
|
||||
timeout = 600
|
||||
|
||||
/datum/mood_event/notcreeping
|
||||
description = "<span class='warning'>I sure wish I was around my obsession...</span>\n"
|
||||
mood_change = -6
|
||||
timeout = 30
|
||||
hidden = TRUE
|
||||
|
||||
/datum/mood_event/notcreeping/add_effects(name)
|
||||
description = "<span class='warning'>I sure wish I was around [name]...</span>\n"
|
||||
|
||||
/datum/mood_event/notcreepingsevere//not hidden since it's so severe
|
||||
description = "<span class='boldwarning'>OBSESSIONNNN WHERE ARE YOUUUUUUUUUUUUU?!</span>\n"
|
||||
mood_change = -30
|
||||
timeout = 30
|
||||
|
||||
/datum/mood_event/notcreepingsevere/add_effects(name)
|
||||
var/list/unstable = list(name)
|
||||
for(var/i in 1 to rand(3,5))
|
||||
unstable += copytext(name, -1)
|
||||
var/unhinged = uppertext(unstable.Join(""))//example Tinea Luxor > TINEA LUXORRRR (with randomness in how long that slur is)
|
||||
description = "<span class='boldwarning'>[unhinged] WHERE ARE YOUUUUUUUUUUUUU?!</span>\n"
|
||||
|
||||
/datum/mood_event/idiot_shower
|
||||
description = "<span class='warning'>I showered with my clothes on, I'm a fucking idiot.</span>\n"
|
||||
mood_change = -3
|
||||
timeout = 900
|
||||
|
||||
//These are unused so far but I want to remember them to use them later
|
||||
/datum/mood_event/cloned_corpse
|
||||
description = "<span class='boldwarning'>I recently saw my own corpse...</span>\n"
|
||||
mood_change = -6
|
||||
|
||||
/datum/mood_event/surgery
|
||||
description = "<span class='boldwarning'>HE'S CUTTING ME OPEN!!</span>\n"
|
||||
mood_change = -8
|
||||
mood_change = -8
|
||||
@@ -57,6 +57,15 @@
|
||||
mood_change = 15
|
||||
hidden = TRUE
|
||||
|
||||
/datum/mood_event/creeping
|
||||
description = "<span class='greentext'>I'm so close to my obsession and I never want this to end.</span>\n" //creeps get it when they are around their obsession
|
||||
mood_change = 18
|
||||
timeout = 30
|
||||
hidden = TRUE
|
||||
|
||||
/datum/mood_event/creeping/add_effects(name)
|
||||
description = "<span class='greentext'>I'm so close to [name] and I NEVER want this to end.</span>\n"
|
||||
|
||||
/datum/mood_event/revolution
|
||||
description = "<span class='nicegreen'>VIVA LA REVOLUTION!</span>\n"
|
||||
mood_change = 3
|
||||
|
||||
@@ -68,4 +68,4 @@
|
||||
|
||||
/datum/status_effect/in_love/tick()
|
||||
if(date)
|
||||
new /obj/effect/temp_visual/love_heart/invisible(get_turf(date.loc), owner)
|
||||
new /obj/effect/temp_visual/love_heart/invisible(get_turf(date.loc), owner)
|
||||
284
code/modules/antagonists/creep/creep.dm
Normal file
284
code/modules/antagonists/creep/creep.dm
Normal file
@@ -0,0 +1,284 @@
|
||||
/datum/antagonist/creep
|
||||
name = "Creep"
|
||||
show_in_antagpanel = TRUE
|
||||
antagpanel_category = "Other"
|
||||
job_rank = ROLE_CREEP
|
||||
show_name_in_check_antagonists = TRUE
|
||||
roundend_category = "creeps"
|
||||
silent = TRUE //not actually silent, because greet will be called by the trauma anyway.
|
||||
var/datum/brain_trauma/special/creep/trauma
|
||||
|
||||
/datum/antagonist/creep/admin_add(datum/mind/new_owner,mob/admin)
|
||||
var/mob/living/carbon/C = new_owner.current
|
||||
if(!istype(C))
|
||||
to_chat(admin, "[roundend_category] come from a brain trauma, so they need to at least be a carbon!")
|
||||
return
|
||||
if(!C.getorgan(/obj/item/organ/brain)) // If only I had a brain
|
||||
to_chat(admin, "[roundend_category] come from a brain trauma, so they need to HAVE A BRAIN.")
|
||||
return
|
||||
message_admins("[key_name_admin(admin)] made [key_name_admin(new_owner)] into [name].")
|
||||
log_admin("[key_name(admin)] made [key_name(new_owner)] into [name].")
|
||||
//PRESTO FUCKIN MAJESTO
|
||||
C.gain_trauma(/datum/brain_trauma/special/creep)//ZAP
|
||||
|
||||
/datum/antagonist/creep/greet()
|
||||
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/creepalert.ogg', 100, FALSE, pressure_affected = FALSE)
|
||||
to_chat(owner, "<span class='boldannounce'>You are the Creep!</span>")
|
||||
to_chat(owner, "<B>They would call it an obsession. They would call you crazy, because they don't understand your unrequited love.<br>All you know is that you love [trauma.obsession]. And you. will. show them.</B>")
|
||||
to_chat(owner, "<B>I will surely go insane if I don't spend enough time around [trauma.obsession], but when i'm near them too long it gets too difficult to speak properly, making me look like a CREEP!</B>")
|
||||
to_chat(owner, "<span class='boldannounce'>The gods would like to remind you that this role, as with all other antags, does not allow you to break ANY server rules, especially Rule 8 (These rules being listed from the \"Rules\" button at the top right of your mind's screen). Feel free to murder and pillage just like any other antag, though.</span>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/creep/Destroy()
|
||||
if(trauma)
|
||||
qdel(trauma)
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/creep/apply_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_creep_icons_added(M)
|
||||
|
||||
/datum/antagonist/creep/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_creep_icons_removed(M)
|
||||
|
||||
/datum/antagonist/creep/proc/forge_objectives(var/datum/mind/obsessionmind)
|
||||
var/list/objectives_left = list("spendtime", "polaroid", "hug")
|
||||
var/datum/objective/assassinate/creep/kill = new
|
||||
kill.owner = owner
|
||||
kill.target = obsessionmind
|
||||
var/datum/quirk/family_heirloom/family_heirloom
|
||||
|
||||
for(var/datum/quirk/quirky in obsessionmind.current.roundstart_quirks)
|
||||
if(istype(quirky, /datum/quirk/family_heirloom))
|
||||
family_heirloom = quirky
|
||||
break
|
||||
if(family_heirloom)//oh, they have an heirloom? Well you know we have to steal that.
|
||||
objectives_left += "heirloom"
|
||||
|
||||
if(obsessionmind.assigned_role && obsessionmind.assigned_role != "Captain" && !(obsessionmind.assigned_role in GLOB.nonhuman_positions))
|
||||
objectives_left += "jealous"//while this will sometimes be a free objective during lowpop, this works fine most of the time and is less intensive
|
||||
|
||||
for(var/i in 1 to 3)
|
||||
var/chosen_objective = pick(objectives_left)
|
||||
objectives_left.Remove(chosen_objective)
|
||||
switch(chosen_objective)
|
||||
if("spendtime")
|
||||
var/datum/objective/spendtime/spendtime = new
|
||||
spendtime.owner = owner
|
||||
spendtime.target = obsessionmind
|
||||
objectives += spendtime
|
||||
if("polaroid")
|
||||
var/datum/objective/polaroid/polaroid = new
|
||||
polaroid.owner = owner
|
||||
polaroid.target = obsessionmind
|
||||
objectives += polaroid
|
||||
if("hug")
|
||||
var/datum/objective/hug/hug = new
|
||||
hug.owner = owner
|
||||
hug.target = obsessionmind
|
||||
objectives += hug
|
||||
if("heirloom")
|
||||
var/datum/objective/steal/heirloom_thief/heirloom_thief = new
|
||||
heirloom_thief.owner = owner
|
||||
heirloom_thief.target = obsessionmind//while you usually wouldn't need this for stealing, we need the name of the obsession
|
||||
heirloom_thief.steal_target = family_heirloom.heirloom
|
||||
objectives += heirloom_thief
|
||||
if("jealous")
|
||||
var/datum/objective/assassinate/jealous/jealous = new
|
||||
jealous.owner = owner
|
||||
jealous.target = obsessionmind//will reroll into a coworker on the objective itself
|
||||
objectives += jealous
|
||||
|
||||
objectives += kill//finally add the assassinate last, because you'd have to complete it last to greentext.
|
||||
for(var/datum/objective/O in objectives)
|
||||
O.update_explanation_text()
|
||||
|
||||
/datum/antagonist/creep/roundend_report_header()
|
||||
return "<span class='header'>Someone became a creep!</span><br>"
|
||||
|
||||
/datum/antagonist/creep/roundend_report()
|
||||
var/list/report = list()
|
||||
|
||||
if(!owner)
|
||||
CRASH("antagonist datum without owner")
|
||||
|
||||
report += "<b>[printplayer(owner)]</b>"
|
||||
|
||||
var/objectives_complete = TRUE
|
||||
if(objectives.len)
|
||||
report += printobjectives(objectives)
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(!objective.check_completion())
|
||||
objectives_complete = FALSE
|
||||
break
|
||||
if(trauma)
|
||||
if(trauma.total_time_creeping > 0)
|
||||
report += "<span class='greentext'>The [name] spent a total of [DisplayTimeText(trauma.total_time_creeping)] being near [trauma.obsession]!</span>"
|
||||
else
|
||||
report += "<span class='redtext'>The [name] did not go near their obsession the entire round! That's extremely impressive, but you are a shit [name]!</span>"
|
||||
else
|
||||
report += "<span class='redtext'>The [name] had no trauma attached to their antagonist ways! Either it bugged out or an admin incorrectly gave this good samaritan antag and it broke! You might as well show yourself!!</span>"
|
||||
|
||||
if(objectives.len == 0 || objectives_complete)
|
||||
report += "<span class='greentext big'>The [name] was successful!</span>"
|
||||
else
|
||||
report += "<span class='redtext big'>The [name] has failed!</span>"
|
||||
|
||||
return report.Join("<br>")
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
///CREEPY objectives (few chosen per obsession)///
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
/datum/objective/assassinate/creep //just a creepy version of assassinate
|
||||
|
||||
/datum/objective/assassinate/creep/update_explanation_text()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Murder [target.name], the [!target_role_type ? target.assigned_role : target.special_role]."
|
||||
else
|
||||
message_admins("WARNING! [ADMIN_LOOKUPFLW(owner)] creep objectives forged without an obsession!")
|
||||
explanation_text = "Free Objective"
|
||||
|
||||
/datum/objective/assassinate/jealous //assassinate, but it changes the target to someone else in the previous target's department. cool, right?
|
||||
var/datum/mind/old //the target the coworker was picked from.
|
||||
|
||||
/datum/objective/assassinate/jealous/update_explanation_text()
|
||||
..()
|
||||
old = find_coworker(target)
|
||||
if(target && target.current && old)
|
||||
explanation_text = "Murder [target.name], [old]'s coworker."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
|
||||
/datum/objective/assassinate/jealous/proc/find_coworker(datum/mind/oldmind)//returning null = free objective
|
||||
if(!oldmind.assigned_role)
|
||||
return
|
||||
var/list/viable_coworkers = list()
|
||||
var/list/all_coworkers = list()
|
||||
var/chosen_department
|
||||
var/their_chosen_department
|
||||
//note that command and sillycone are gone because borgs can't be obsessions and the heads have their respective department. Sorry cap, your place is more with centcom or something
|
||||
if(oldmind.assigned_role in GLOB.security_positions)
|
||||
chosen_department = "security"
|
||||
if(oldmind.assigned_role in GLOB.engineering_positions)
|
||||
chosen_department = "engineering"
|
||||
if(oldmind.assigned_role in GLOB.medical_positions)
|
||||
chosen_department = "medical"
|
||||
if(oldmind.assigned_role in GLOB.science_positions)
|
||||
chosen_department = "science"
|
||||
if(oldmind.assigned_role in GLOB.supply_positions)
|
||||
chosen_department = "supply"
|
||||
if(oldmind.assigned_role in GLOB.civilian_positions)
|
||||
chosen_department = "civilian"
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
if(!H.mind)
|
||||
continue
|
||||
if(!H.mind.assigned_role || H == oldmind.current || H.mind.has_antag_datum(/datum/antagonist/creep)) //the jealousy target has to have a job, and not be the obsession or creep.
|
||||
continue
|
||||
//this won't be called often thankfully.
|
||||
if(H.mind.assigned_role in GLOB.security_positions)
|
||||
their_chosen_department = "security"
|
||||
if(H.mind.assigned_role in GLOB.engineering_positions)
|
||||
their_chosen_department = "engineering"
|
||||
if(H.mind.assigned_role in GLOB.medical_positions)
|
||||
their_chosen_department = "medical"
|
||||
if(H.mind.assigned_role in GLOB.science_positions)
|
||||
their_chosen_department = "science"
|
||||
if(H.mind.assigned_role in GLOB.supply_positions)
|
||||
their_chosen_department = "supply"
|
||||
if(H.mind.assigned_role in GLOB.civilian_positions)
|
||||
their_chosen_department = "civilian"
|
||||
if(their_chosen_department != chosen_department)
|
||||
continue
|
||||
viable_coworkers += H
|
||||
|
||||
if(viable_coworkers.len > 0)//find someone in the same department
|
||||
target = pick(viable_coworkers)
|
||||
else if(all_coworkers.len > 0)//find someone who works on the station
|
||||
else
|
||||
return//there is nobody but you and the obsession
|
||||
return oldmind
|
||||
|
||||
/datum/objective/spendtime //spend some time around someone, handled by the creep trauma since that ticks
|
||||
name = "spendtime"
|
||||
var/timer = 1800 //5 minutes
|
||||
|
||||
/datum/objective/spendtime/update_explanation_text()
|
||||
if(timer == initial(timer))//just so admins can mess with it
|
||||
timer += pick(-600, 0)
|
||||
var/datum/antagonist/creep/creeper = owner.has_antag_datum(/datum/antagonist/creep)
|
||||
if(target && target.current && creeper)
|
||||
creeper.trauma.attachedcreepobj = src
|
||||
explanation_text = "Spend [DisplayTimeText(timer)] around [target.name] while they're alive."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
|
||||
/datum/objective/spendtime/check_completion()
|
||||
return timer <= 0 || explanation_text == "Free Objective"
|
||||
|
||||
|
||||
/datum/objective/hug//this objective isn't perfect. hugging the correct amount of times, then switching bodies, might fail the objective anyway. maybe i'll come back and fix this sometime.
|
||||
name = "hugs"
|
||||
var/hugs_needed
|
||||
|
||||
/datum/objective/hug/update_explanation_text()
|
||||
..()
|
||||
if(!hugs_needed)//just so admins can mess with it
|
||||
hugs_needed = rand(4,6)
|
||||
var/datum/antagonist/creep/creeper = owner.has_antag_datum(/datum/antagonist/creep)
|
||||
if(target && target.current && creeper)
|
||||
explanation_text = "Hug [target.name] [hugs_needed] times while they're alive."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
|
||||
/datum/objective/hug/check_completion()
|
||||
var/datum/antagonist/creep/creeper = owner.has_antag_datum(/datum/antagonist/creep)
|
||||
if(!creeper || !creeper.trauma || !hugs_needed)
|
||||
return TRUE//free objective
|
||||
return creeper.trauma.obsession_hug_count >= hugs_needed
|
||||
|
||||
/datum/objective/polaroid //take a picture of the target with you in it.
|
||||
name = "polaroid"
|
||||
|
||||
/datum/objective/polaroid/update_explanation_text()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Take a photo with [target.name] while they're alive."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
|
||||
/datum/objective/polaroid/check_completion()
|
||||
var/list/datum/mind/owners = get_owners()
|
||||
for(var/datum/mind/M in owners)
|
||||
if(!isliving(M.current))
|
||||
continue
|
||||
var/list/all_items = M.current.GetAllContents() //this should get things in cheesewheels, books, etc.
|
||||
for(var/obj/I in all_items) //Check for wanted items
|
||||
if(istype(I, /obj/item/photo))
|
||||
var/obj/item/photo/P = I
|
||||
if(P.picture.mobs_seen.Find(owner) && P.picture.mobs_seen.Find(target) && !P.picture.dead_seen.Find(target))//you are in the picture, they are but they are not dead.
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/objective/steal/heirloom_thief //exactly what it sounds like, steal someone's heirloom.
|
||||
name = "heirloomthief"
|
||||
|
||||
/datum/objective/steal/heirloom_thief/update_explanation_text()
|
||||
..()
|
||||
if(steal_target)
|
||||
explanation_text = "Steal [target.name]'s family heirloom, [steal_target] they cherish."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
|
||||
/datum/antagonist/creep/proc/update_creep_icons_added(var/mob/living/carbon/human/creep)
|
||||
var/datum/atom_hud/antag/creephud = GLOB.huds[ANTAG_HUD_CREEP]
|
||||
creephud.join_hud(creep)
|
||||
set_antag_hud(creep, "creep")
|
||||
|
||||
/datum/antagonist/creep/proc/update_creep_icons_removed(var/mob/living/carbon/human/creep)
|
||||
var/datum/atom_hud/antag/creephud = GLOB.huds[ANTAG_HUD_CREEP]
|
||||
creephud.leave_hud(creep)
|
||||
set_antag_hud(creep, null)
|
||||
25
code/modules/events/creep_awakening.dm
Normal file
25
code/modules/events/creep_awakening.dm
Normal file
@@ -0,0 +1,25 @@
|
||||
/datum/round_event_control/creep
|
||||
name = "Creep Awakening"
|
||||
typepath = /datum/round_event/creep
|
||||
max_occurrences = 1
|
||||
min_players = 20
|
||||
|
||||
/datum/round_event/creep
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/creep/start()
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.player_list))
|
||||
if(!H.client)
|
||||
continue
|
||||
if(H.stat == DEAD)
|
||||
continue
|
||||
if(!H.mind.assigned_role || H.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL] || H.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_ANTAG]) //prevents ashwalkers falling in love with crewmembers they never met
|
||||
continue
|
||||
var/alreadycreepy = H.mind.has_antag_datum(/datum/antagonist/creep)
|
||||
if(alreadycreepy)
|
||||
continue
|
||||
if(!H.getorgan(/obj/item/organ/brain))
|
||||
continue
|
||||
H.gain_trauma(/datum/brain_trauma/special/creep)
|
||||
announce_to_ghosts(H)
|
||||
break
|
||||
@@ -273,6 +273,8 @@
|
||||
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug)
|
||||
for(var/datum/brain_trauma/trauma in M.get_traumas())
|
||||
trauma.on_hug(M, src)
|
||||
AdjustStun(-60)
|
||||
AdjustKnockdown(-60)
|
||||
AdjustUnconscious(-60)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/picture
|
||||
var/picture_name = "picture"
|
||||
var/picture_desc = "This is a picture."
|
||||
var/list/mobs_seen = list()
|
||||
var/list/dead_seen = list()
|
||||
var/caption
|
||||
var/icon/picture_image
|
||||
var/icon/picture_icon
|
||||
@@ -10,11 +12,15 @@
|
||||
var/logpath //If the picture has been logged this is the path.
|
||||
var/id //this var is NOT protected because the worst you can do with this that you couldn't do otherwise is overwrite photos, and photos aren't going to be used as attack logs/investigations anytime soon.
|
||||
|
||||
/datum/picture/New(name, desc, image, icon, size_x, size_y, bp, caption_, autogenerate_icon)
|
||||
/datum/picture/New(name, desc, mobs_spotted, dead_spotted, image, icon, size_x, size_y, bp, caption_, autogenerate_icon)
|
||||
if(!isnull(name))
|
||||
picture_name = name
|
||||
if(!isnull(desc))
|
||||
picture_desc = desc
|
||||
if(!isnull(mobs_spotted))
|
||||
mobs_seen = mobs_spotted
|
||||
if(!isnull(dead_spotted))
|
||||
dead_seen = dead_spotted
|
||||
if(!isnull(image))
|
||||
picture_image = image
|
||||
if(!isnull(icon))
|
||||
|
||||
@@ -155,6 +155,8 @@
|
||||
size_x = CLAMP(size_x, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
|
||||
size_y = CLAMP(size_y, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
|
||||
var/list/desc = list("This is a photo of an area of [size_x+1] meters by [size_y+1] meters.")
|
||||
var/list/mobs_spotted = list()
|
||||
var/list/dead_spotted = list()
|
||||
var/ai_user = isAI(user)
|
||||
var/list/seen
|
||||
var/list/viewlist = (user && user.client)? getviewsize(user.client.view) : getviewsize(world.view)
|
||||
@@ -174,6 +176,9 @@
|
||||
blueprints = TRUE
|
||||
for(var/i in mobs)
|
||||
var/mob/M = i
|
||||
mobs_spotted += M
|
||||
if(M.stat == DEAD)
|
||||
dead_spotted += M
|
||||
desc += M.get_photo_description(src)
|
||||
|
||||
var/psize_x = (size_x * 2 + 1) * world.icon_size
|
||||
@@ -185,7 +190,7 @@
|
||||
temp.Scale(psize_x, psize_y)
|
||||
temp.Blend(get_icon, ICON_OVERLAY)
|
||||
|
||||
var/datum/picture/P = new("picture", desc.Join(" "), temp, null, psize_x, psize_y, blueprints)
|
||||
var/datum/picture/P = new("picture", desc.Join(" "), mobs_spotted, dead_spotted, temp, null, psize_x, psize_y, blueprints)
|
||||
after_picture(user, P, flag)
|
||||
blending = FALSE
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
BIN
sound/ambience/antag/creepalert.ogg
Normal file
BIN
sound/ambience/antag/creepalert.ogg
Normal file
Binary file not shown.
@@ -319,6 +319,7 @@
|
||||
#include "code\datums\actions\beam_rifle.dm"
|
||||
#include "code\datums\actions\ninja.dm"
|
||||
#include "code\datums\brain_damage\brain_trauma.dm"
|
||||
#include "code\datums\brain_damage\creepy_trauma.dm"
|
||||
#include "code\datums\brain_damage\hypnosis.dm"
|
||||
#include "code\datums\brain_damage\imaginary_friend.dm"
|
||||
#include "code\datums\brain_damage\magic.dm"
|
||||
@@ -1254,6 +1255,7 @@
|
||||
#include "code\modules\antagonists\clockcult\clock_structures\trap_triggers\repeater.dm"
|
||||
#include "code\modules\antagonists\clockcult\clock_structures\traps\brass_skewer.dm"
|
||||
#include "code\modules\antagonists\clockcult\clock_structures\traps\steam_vent.dm"
|
||||
#include "code\modules\antagonists\creep\creep.dm"
|
||||
#include "code\modules\antagonists\cult\blood_magic.dm"
|
||||
#include "code\modules\antagonists\cult\cult.dm"
|
||||
#include "code\modules\antagonists\cult\cult_comms.dm"
|
||||
@@ -1566,6 +1568,7 @@
|
||||
#include "code\modules\events\camerafailure.dm"
|
||||
#include "code\modules\events\carp_migration.dm"
|
||||
#include "code\modules\events\communications_blackout.dm"
|
||||
#include "code\modules\events\creep_awakening.dm"
|
||||
#include "code\modules\events\devil.dm"
|
||||
#include "code\modules\events\disease_outbreak.dm"
|
||||
#include "code\modules\events\dust.dm"
|
||||
|
||||
Reference in New Issue
Block a user