[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:
tralezab
2019-01-06 22:18:35 -08:00
committed by oranges
parent e5304a95ee
commit 240cb31e12
18 changed files with 496 additions and 4 deletions

View File

@@ -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"

View File

@@ -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,

View File

@@ -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 //
/////////////

View File

@@ -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

View 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

View File

@@ -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>")

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View 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)

View 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

View File

@@ -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)

View File

@@ -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))

View File

@@ -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

Binary file not shown.

View File

@@ -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"