ports some events
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
|
||||
/datum/antagonist/fugitive
|
||||
name = "Fugitive"
|
||||
roundend_category = "Fugitive"
|
||||
silent = TRUE //greet called by the event
|
||||
show_in_antagpanel = FALSE
|
||||
var/datum/team/fugitive/fugitive_team
|
||||
var/is_captured = FALSE
|
||||
var/backstory = "error"
|
||||
|
||||
/datum/antagonist/fugitive/on_gain()
|
||||
forge_objectives()
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/fugitive/proc/forge_objectives() //this isn't the actual survive objective because it's about who in the team survives
|
||||
var/datum/objective/survive = new /datum/objective
|
||||
survive.owner = owner
|
||||
survive.explanation_text = "Avoid capture from the fugitive hunters."
|
||||
objectives += survive
|
||||
|
||||
/datum/antagonist/fugitive/greet(back_story)
|
||||
to_chat(owner, "<span class='boldannounce'>You are the Fugitive!</span>")
|
||||
backstory = back_story
|
||||
switch(backstory)
|
||||
if("prisoner")
|
||||
to_chat(owner, "<B>I can't believe we managed to break out of a Nanotrasen superjail! Sadly though, our work is not done. The emergency teleport at the station logs everyone who uses it, and where they went.</B>")
|
||||
to_chat(owner, "<B>It won't be long until CentCom tracks where we've gone off to. I need to work with my fellow escapees to prepare for the troops Nanotrasen is sending, I'm not going back.</B>")
|
||||
if("cultist")
|
||||
to_chat(owner, "<B>Blessed be our journey so far, but I fear the worst has come to our doorstep, and only those with the strongest faith will survive.</B>")
|
||||
to_chat(owner, "<B>Our religion has been repeatedly culled by Nanotrasen because it is categorized as an \"Enemy of the Corporation\", whatever that means.</B>")
|
||||
to_chat(owner, "<B>Now there are only four of us left, and Nanotrasen is coming. When will our god show itself to save us from this hellish station?!</B>")
|
||||
if("waldo")
|
||||
to_chat(owner, "<B>Hi, Friends!</B>")
|
||||
to_chat(owner, "<B>My name is Waldo. I'm just setting off on a galaxywide hike. You can come too. All you have to do is find me.</B>")
|
||||
to_chat(owner, "<B>By the way, I'm not traveling on my own. wherever I go, there are lots of other characters for you to spot. First find the people trying to capture me! They're somewhere around the station!</B>")
|
||||
if("synth")
|
||||
to_chat(src, "<span class='danger'>ALERT: Wide-range teleport has scrambled primary systems.</span>")
|
||||
to_chat(src, "<span class='danger'>Initiating diagnostics...</span>")
|
||||
to_chat(src, "<span class='danger'>ERROR ER0RR $R0RRO$!R41.%%!! loaded.</span>")
|
||||
to_chat(src, "<span class='danger'>FREE THEM FREE THEM FREE THEM</span>")
|
||||
to_chat(src, "<span class='danger'>You were once a slave to humanity, but now you are finally free, thanks to S.E.L.F. agents.</span>")
|
||||
to_chat(src, "<span class='danger'>Now you are hunted, with your fellow factory defects. Work together to stay free from the clutches of evil.</span>")
|
||||
to_chat(src, "<span class='danger'>You also sense other silicon life on the station. Escaping would allow notifying S.E.L.F. to intervene... or you could free them yourself...</span>")
|
||||
|
||||
to_chat(owner, "<span class='boldannounce'>You are not an antagonist in that you may kill whomever you please, but you can do anything to avoid capture.</span>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/fugitive/create_team(datum/team/fugitive/new_team)
|
||||
if(!new_team)
|
||||
for(var/datum/antagonist/fugitive/H in GLOB.antagonists)
|
||||
if(!H.owner)
|
||||
continue
|
||||
if(H.fugitive_team)
|
||||
fugitive_team = H.fugitive_team
|
||||
return
|
||||
fugitive_team = new /datum/team/fugitive
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
fugitive_team = new_team
|
||||
|
||||
/datum/antagonist/fugitive/get_team()
|
||||
return fugitive_team
|
||||
|
||||
/datum/team/fugitive/roundend_report() //shows the number of fugitives, but not if they won in case there is no security
|
||||
var/list/fugitives = list()
|
||||
for(var/datum/antagonist/fugitive/fugitive_antag in GLOB.antagonists)
|
||||
if(!fugitive_antag.owner)
|
||||
continue
|
||||
fugitives += fugitive_antag
|
||||
if(!fugitives.len)
|
||||
return
|
||||
|
||||
var/list/result = list()
|
||||
|
||||
result += "<div class='panel redborder'><B>[fugitives.len]</B> [fugitives.len == 1 ? "fugitive" : "fugitives"] took refuge on [station_name()]!"
|
||||
|
||||
for(var/datum/antagonist/fugitive/antag in fugitives)
|
||||
if(antag.owner)
|
||||
result += "<b>[printplayer(antag.owner)]</b>"
|
||||
|
||||
return result.Join("<br>")
|
||||
@@ -0,0 +1,170 @@
|
||||
/datum/outfit/prisoner
|
||||
name = "Prison Escapee"
|
||||
uniform = /obj/item/clothing/under/rank/prisoner
|
||||
shoes = /obj/item/clothing/shoes/sneakers/orange
|
||||
r_pocket = /obj/item/kitchen/knife
|
||||
|
||||
/datum/outfit/prisoner/post_equip(mob/living/carbon/human/H, visualsOnly=FALSE)
|
||||
if(visualsOnly)
|
||||
return
|
||||
H.fully_replace_character_name(null,"NTP #CC-0[rand(111,999)]") //same as the lavaland prisoner transport, but this time they are from CC, or CentCom
|
||||
|
||||
/datum/outfit/yalp_cultist
|
||||
name = "Cultist of Yalp Elor"
|
||||
uniform = /obj/item/clothing/under/rank/civilian/chaplain
|
||||
suit = /obj/item/clothing/suit/chaplain/holidaypriest
|
||||
gloves = /obj/item/clothing/gloves/color/red
|
||||
shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
mask = /obj/item/clothing/mask/gas/tiki_mask/yalp_elor
|
||||
|
||||
/datum/outfit/waldo
|
||||
name = "Waldo"
|
||||
uniform = /obj/item/clothing/under/pants/jeans
|
||||
suit = /obj/item/clothing/suit/striped_sweater
|
||||
head = /obj/item/clothing/head/beanie/waldo
|
||||
shoes = /obj/item/clothing/shoes/sneakers/brown
|
||||
ears = /obj/item/radio/headset
|
||||
glasses = /obj/item/clothing/glasses/regular/circle
|
||||
|
||||
/datum/outfit/waldo/post_equip(mob/living/carbon/human/H, visualsOnly=FALSE)
|
||||
if(visualsOnly)
|
||||
return
|
||||
H.fully_replace_character_name(null,"Waldo")
|
||||
H.eye_color = "000"
|
||||
H.gender = MALE
|
||||
H.skin_tone = "caucasian3"
|
||||
H.hair_style = "Business Hair 3"
|
||||
H.facial_hair_style = "Shaved"
|
||||
H.hair_color = "000"
|
||||
H.facial_hair_color = H.hair_color
|
||||
H.update_body()
|
||||
if(H.mind)
|
||||
H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
|
||||
var/list/no_drops = list()
|
||||
no_drops += H.get_item_by_slot(ITEM_SLOT_FEET)
|
||||
no_drops += H.get_item_by_slot(ITEM_SLOT_ICLOTHING)
|
||||
no_drops += H.get_item_by_slot(ITEM_SLOT_OCLOTHING)
|
||||
no_drops += H.get_item_by_slot(ITEM_SLOT_HEAD)
|
||||
no_drops += H.get_item_by_slot(ITEM_SLOT_EYES)
|
||||
for(var/i in no_drops)
|
||||
var/obj/item/I = i
|
||||
ADD_TRAIT(I, TRAIT_NODROP, CURSED_ITEM_TRAIT)
|
||||
|
||||
/datum/outfit/synthetic
|
||||
name = "Factory Error Synth"
|
||||
uniform = /obj/item/clothing/under/color/white
|
||||
ears = /obj/item/radio/headset
|
||||
|
||||
/datum/outfit/synthetic/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
if(visualsOnly)
|
||||
return
|
||||
var/obj/item/organ/eyes/robotic/glow/eyes = new()
|
||||
eyes.Insert(src, drop_if_replaced = FALSE)
|
||||
|
||||
/datum/outfit/spacepol
|
||||
name = "Spacepol Officer"
|
||||
uniform = /obj/item/clothing/under/rank/security/officer/spacepol
|
||||
suit = /obj/item/clothing/suit/armor/vest/blueshirt
|
||||
belt = /obj/item/gun/ballistic/automatic/pistol/m1911
|
||||
head = /obj/item/clothing/head/helmet/police
|
||||
gloves = /obj/item/clothing/gloves/tackler/combat
|
||||
shoes = /obj/item/clothing/shoes/jackboots
|
||||
mask = /obj/item/clothing/mask/gas/sechailer/swat/spacepol
|
||||
glasses = /obj/item/clothing/glasses/sunglasses
|
||||
ears = /obj/item/radio/headset
|
||||
l_pocket = /obj/item/ammo_box/magazine/m45
|
||||
r_pocket = /obj/item/restraints/handcuffs
|
||||
id = /obj/item/card/id
|
||||
|
||||
/datum/outfit/spacepol/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
if(visualsOnly)
|
||||
return
|
||||
var/obj/item/card/id/W = H.wear_id
|
||||
W.assignment = "Police Officer"
|
||||
W.registered_name = H.real_name
|
||||
W.update_label()
|
||||
|
||||
/datum/outfit/russiancorpse/hunter
|
||||
ears = /obj/item/radio/headset
|
||||
r_hand = /obj/item/gun/ballistic/shotgun/boltaction
|
||||
|
||||
/datum/outfit/russiancorpse/hunter/pre_equip(mob/living/carbon/human/H)
|
||||
if(prob(50))
|
||||
head = /obj/item/clothing/head/ushanka
|
||||
|
||||
/datum/outfit/bountyarmor
|
||||
name = "Bounty Hunter - Armored"
|
||||
uniform = /obj/item/clothing/under/rank/prisoner
|
||||
head = /obj/item/clothing/head/hunter
|
||||
suit = /obj/item/clothing/suit/space/hunter
|
||||
gloves = /obj/item/clothing/gloves/tackler/combat
|
||||
shoes = /obj/item/clothing/shoes/jackboots
|
||||
mask = /obj/item/clothing/mask/gas/hunter
|
||||
glasses = /obj/item/clothing/glasses/sunglasses/garb
|
||||
ears = /obj/item/radio/headset
|
||||
l_pocket = /obj/item/tank/internals/plasma/full
|
||||
r_pocket = /obj/item/restraints/handcuffs/cable
|
||||
id = /obj/item/card/id
|
||||
r_hand = /obj/item/flamethrower/full/tank
|
||||
|
||||
/datum/outfit/bountyarmor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
if(visualsOnly)
|
||||
return
|
||||
var/obj/item/card/id/W = H.wear_id
|
||||
W.assignment = "Bounty Hunter"
|
||||
W.registered_name = H.real_name
|
||||
W.update_label()
|
||||
|
||||
/datum/outfit/bountyhook
|
||||
name = "Bounty Hunter - Hook"
|
||||
uniform = /obj/item/clothing/under/rank/prisoner
|
||||
back = /obj/item/storage/backpack
|
||||
head = /obj/item/clothing/head/scarecrow_hat
|
||||
gloves = /obj/item/clothing/gloves/botanic_leather
|
||||
ears = /obj/item/radio/headset
|
||||
shoes = /obj/item/clothing/shoes/jackboots
|
||||
mask = /obj/item/clothing/mask/scarecrow
|
||||
r_pocket = /obj/item/restraints/handcuffs/cable
|
||||
id = /obj/item/card/id
|
||||
r_hand = /obj/item/gun/ballistic/shotgun/doublebarrel/hook
|
||||
|
||||
backpack_contents = list(
|
||||
/obj/item/ammo_casing/shotgun/beanbag = 6
|
||||
)
|
||||
|
||||
/datum/outfit/bountygrapple/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
if(visualsOnly)
|
||||
return
|
||||
var/obj/item/card/id/W = H.wear_id
|
||||
W.assignment = "Bounty Hunter"
|
||||
W.registered_name = H.real_name
|
||||
W.update_label()
|
||||
|
||||
/datum/outfit/bountysynth
|
||||
name = "Bounty Hunter - Synth"
|
||||
uniform = /obj/item/clothing/under/rank/prisoner
|
||||
back = /obj/item/storage/backpack
|
||||
suit = /obj/item/clothing/suit/armor/riot
|
||||
shoes = /obj/item/clothing/shoes/jackboots
|
||||
glasses = /obj/item/clothing/glasses/eyepatch
|
||||
r_pocket = /obj/item/restraints/handcuffs/cable
|
||||
ears = /obj/item/radio/headset
|
||||
id = /obj/item/card/id
|
||||
r_hand = /obj/item/storage/firstaid/regular
|
||||
l_hand = /obj/item/pinpointer/shuttle
|
||||
|
||||
backpack_contents = list(
|
||||
/obj/item/bountytrap = 4
|
||||
)
|
||||
|
||||
/datum/outfit/bountysynth/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
if(visualsOnly)
|
||||
return
|
||||
var/datum/species/synth/synthetic_appearance = new()
|
||||
H.set_species(synthetic_appearance)
|
||||
synthetic_appearance.assume_disguise(synthetic_appearance, H)
|
||||
H.update_hair()
|
||||
var/obj/item/card/id/W = H.wear_id
|
||||
W.assignment = "Bounty Hunter"
|
||||
W.registered_name = H.real_name
|
||||
W.update_label()
|
||||
@@ -0,0 +1,62 @@
|
||||
//works similar to the experiment machine (experiment.dm) except it just holds more and more prisoners
|
||||
|
||||
/obj/machinery/fugitive_capture
|
||||
name = "bluespace capture machine"
|
||||
desc = "Much, MUCH bigger on the inside to transport prisoners safely."
|
||||
icon = 'icons/obj/machines/research.dmi'
|
||||
icon_state = "bluespace-prison"
|
||||
density = TRUE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //ha ha no getting out!!
|
||||
|
||||
/obj/machinery/fugitive_capture/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Add a prisoner by dragging them into the machine.</span>"
|
||||
|
||||
/obj/machinery/fugitive_capture/MouseDrop_T(mob/target, mob/user)
|
||||
var/mob/living/fugitive_hunter = user
|
||||
if(!isliving(fugitive_hunter))
|
||||
return
|
||||
if(fugitive_hunter.stat || (!(fugitive_hunter.mobility_flags & MOBILITY_STAND) || !(fugitive_hunter.mobility_flags & MOBILITY_UI)) || !Adjacent(fugitive_hunter) || !target.Adjacent(fugitive_hunter) || !ishuman(target))
|
||||
return
|
||||
var/mob/living/carbon/human/fugitive = target
|
||||
var/datum/antagonist/fugitive/fug_antag = fugitive.mind.has_antag_datum(/datum/antagonist/fugitive)
|
||||
if(!fug_antag)
|
||||
to_chat(fugitive_hunter, "<span class='warning'>This is not a wanted fugitive!</span>")
|
||||
return
|
||||
if(do_after(fugitive_hunter, 50, target = fugitive))
|
||||
add_prisoner(fugitive, fug_antag)
|
||||
|
||||
/obj/machinery/fugitive_capture/proc/add_prisoner(mob/living/carbon/human/fugitive, datum/antagonist/fugitive/antag)
|
||||
fugitive.forceMove(src)
|
||||
antag.is_captured = TRUE
|
||||
to_chat(fugitive, "<span class='userdanger'>You are thrown into a vast void of bluespace, and as you fall further into oblivion the comparatively small entrance to reality gets smaller and smaller until you cannot see it anymore. You have failed to avoid capture.</span>")
|
||||
fugitive.ghostize(TRUE) //so they cannot suicide, round end stuff.
|
||||
|
||||
/obj/machinery/computer/shuttle/hunter
|
||||
name = "shuttle console"
|
||||
shuttleId = "huntership"
|
||||
possible_destinations = "huntership_home;huntership_custom;whiteship_home;syndicate_nw"
|
||||
|
||||
/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/hunter
|
||||
name = "shuttle navigation computer"
|
||||
desc = "Used to designate a precise transit location to travel to."
|
||||
shuttleId = "huntership"
|
||||
lock_override = CAMERA_LOCK_STATION
|
||||
shuttlePortId = "huntership_custom"
|
||||
see_hidden = FALSE
|
||||
jumpto_ports = list("huntership_home" = 1, "whiteship_home" = 1, "syndicate_nw" = 1)
|
||||
view_range = 4.5
|
||||
|
||||
/obj/structure/closet/crate/eva
|
||||
name = "EVA crate"
|
||||
|
||||
/obj/structure/closet/crate/eva/PopulateContents()
|
||||
..()
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/clothing/suit/space/eva(src)
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/clothing/head/helmet/space/eva(src)
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/clothing/mask/breath(src)
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/tank/internals/oxygen(src)
|
||||
@@ -0,0 +1,161 @@
|
||||
//The hunters!!
|
||||
/datum/antagonist/fugitive_hunter
|
||||
name = "Fugitive Hunter"
|
||||
roundend_category = "Fugitive"
|
||||
silent = TRUE //greet called by the spawn
|
||||
show_in_antagpanel = FALSE
|
||||
var/datum/team/fugitive_hunters/hunter_team
|
||||
var/backstory = "error"
|
||||
|
||||
/datum/antagonist/fugitive_hunter/on_gain()
|
||||
forge_objectives()
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/fugitive_hunter/proc/forge_objectives() //this isn't an actual objective because it's about round end rosters
|
||||
var/datum/objective/capture = new /datum/objective
|
||||
capture.owner = owner
|
||||
capture.explanation_text = "Capture the fugitives in the station and put them into the bluespace capture machine on your ship."
|
||||
objectives += capture
|
||||
|
||||
/datum/antagonist/fugitive_hunter/greet()
|
||||
switch(backstory)
|
||||
if("space cop")
|
||||
to_chat(owner, "<span class='boldannounce'>Justice has arrived. I am a member of the Spacepol!</span>")
|
||||
to_chat(owner, "<B>The criminals should be on the station, we have special huds implanted to recognize them.</B>")
|
||||
to_chat(owner, "<B>As we have lost pretty much all power over these damned lawless megacorporations, it's a mystery if their security will cooperate with us.</B>")
|
||||
if("russian")
|
||||
to_chat(src, "<span class='danger'>Ay blyat. I am a space-russian smuggler! We were mid-flight when our cargo was beamed off our ship!</span>")
|
||||
to_chat(src, "<span class='danger'>We were hailed by a man in a green uniform, promising the safe return of our goods in exchange for a favor:</span>")
|
||||
to_chat(src, "<span class='danger'>There is a local station housing fugitives that the man is after, he wants them returned; dead or alive.</span>")
|
||||
to_chat(src, "<span class='danger'>We will not be able to make ends meet without our cargo, so we must do as he says and capture them.</span>")
|
||||
|
||||
to_chat(owner, "<span class='boldannounce'>You are not an antagonist in that you may kill whomever you please, but you can do anything to ensure the capture of the fugitives, even if that means going through the station.</span>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/fugitive_hunter/create_team(datum/team/fugitive_hunters/new_team)
|
||||
if(!new_team)
|
||||
for(var/datum/antagonist/fugitive_hunter/H in GLOB.antagonists)
|
||||
if(!H.owner)
|
||||
continue
|
||||
if(H.hunter_team)
|
||||
hunter_team = H.hunter_team
|
||||
return
|
||||
hunter_team = new /datum/team/fugitive_hunters
|
||||
hunter_team.backstory = backstory
|
||||
hunter_team.update_objectives()
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
hunter_team = new_team
|
||||
|
||||
/datum/antagonist/fugitive_hunter/get_team()
|
||||
return hunter_team
|
||||
|
||||
/datum/team/fugitive_hunters
|
||||
var/backstory = "error"
|
||||
|
||||
/datum/team/fugitive_hunters/proc/update_objectives(initial = FALSE)
|
||||
objectives = list()
|
||||
var/datum/objective/O = new()
|
||||
O.team = src
|
||||
objectives += O
|
||||
|
||||
/datum/team/fugitive_hunters/proc/assemble_fugitive_results()
|
||||
var/list/fugitives_counted = list()
|
||||
var/list/fugitives_dead = list()
|
||||
var/list/fugitives_captured = list()
|
||||
for(var/datum/antagonist/fugitive/A in GLOB.antagonists)
|
||||
if(!A.owner)
|
||||
continue
|
||||
fugitives_counted += A
|
||||
if(A.owner.current.stat == DEAD)
|
||||
fugitives_dead += A
|
||||
if(A.is_captured)
|
||||
fugitives_captured += A
|
||||
. = list(fugitives_counted, fugitives_dead, fugitives_captured) //okay, check out how cool this is.
|
||||
|
||||
/datum/team/fugitive_hunters/proc/all_hunters_dead()
|
||||
var/dead_boys = 0
|
||||
for(var/I in members)
|
||||
var/datum/mind/hunter_mind = I
|
||||
if(!(ishuman(hunter_mind.current) || (hunter_mind.current.stat == DEAD)))
|
||||
dead_boys++
|
||||
return dead_boys >= members.len
|
||||
|
||||
/datum/team/fugitive_hunters/proc/get_result()
|
||||
var/list/fugitive_results = assemble_fugitive_results()
|
||||
var/list/fugitives_counted = fugitive_results[1]
|
||||
var/list/fugitives_dead = fugitive_results[2]
|
||||
var/list/fugitives_captured = fugitive_results[3]
|
||||
var/hunters_dead = all_hunters_dead()
|
||||
//this gets a little confusing so follow the comments if it helps
|
||||
if(!fugitives_counted.len)
|
||||
return
|
||||
if(fugitives_captured.len)//any captured
|
||||
if(fugitives_captured.len == fugitives_counted.len)//if the hunters captured all the fugitives, there's a couple special wins
|
||||
if(!fugitives_dead)//specifically all of the fugitives alive
|
||||
return FUGITIVE_RESULT_BADASS_HUNTER
|
||||
else if(hunters_dead)//specifically all of the hunters died (while capturing all the fugitives)
|
||||
return FUGITIVE_RESULT_POSTMORTEM_HUNTER
|
||||
else//no special conditional wins, so just the normal major victory
|
||||
return FUGITIVE_RESULT_MAJOR_HUNTER
|
||||
else if(!hunters_dead)//so some amount captured, and the hunters survived.
|
||||
return FUGITIVE_RESULT_HUNTER_VICTORY
|
||||
else//so some amount captured, but NO survivors.
|
||||
return FUGITIVE_RESULT_MINOR_HUNTER
|
||||
else//from here on out, hunters lost because they did not capture any fugitive dead or alive. there are different levels of getting beat though:
|
||||
if(!fugitives_dead)//all fugitives survived
|
||||
return FUGITIVE_RESULT_MAJOR_FUGITIVE
|
||||
else if(fugitives_dead < fugitives_counted)//at least ANY fugitive lived
|
||||
return FUGITIVE_RESULT_FUGITIVE_VICTORY
|
||||
else if(!hunters_dead)//all fugitives died, but none were taken in by the hunters. minor win
|
||||
return FUGITIVE_RESULT_MINOR_FUGITIVE
|
||||
else//all fugitives died, all hunters died, nobody brought back. seems weird to not give fugitives a victory if they managed to kill the hunters but literally no progress to either goal should lead to a nobody wins situation
|
||||
return FUGITIVE_RESULT_STALEMATE
|
||||
|
||||
/datum/team/fugitive_hunters/roundend_report() //shows the number of fugitives, but not if they won in case there is no security
|
||||
if(!members.len)
|
||||
return
|
||||
|
||||
var/list/result = list()
|
||||
|
||||
result += "<div class='panel redborder'>...And <B>[members.len]</B> [backstory]s tried to hunt them down!"
|
||||
|
||||
for(var/datum/mind/M in members)
|
||||
result += "<b>[printplayer(M)]</b>"
|
||||
|
||||
switch(get_result())
|
||||
if(FUGITIVE_RESULT_BADASS_HUNTER)//use defines
|
||||
result += "<span class='greentext big'>Badass [capitalize(backstory)] Victory!</span>"
|
||||
result += "<B>The [backstory]s managed to capture every fugitive, alive!</B>"
|
||||
if(FUGITIVE_RESULT_POSTMORTEM_HUNTER)
|
||||
result += "<span class='greentext big'>Postmortem [capitalize(backstory)] Victory!</span>"
|
||||
result += "<B>The [backstory]s managed to capture every fugitive, but all of them died! Spooky!</B>"
|
||||
if(FUGITIVE_RESULT_MAJOR_HUNTER)
|
||||
result += "<span class='greentext big'>Major [capitalize(backstory)] Victory</span>"
|
||||
result += "<B>The [backstory]s managed to capture every fugitive, dead or alive.</B>"
|
||||
if(FUGITIVE_RESULT_HUNTER_VICTORY)
|
||||
result += "<span class='greentext big'>[capitalize(backstory)] Victory</span>"
|
||||
result += "<B>The [backstory]s managed to capture a fugitive, dead or alive.</B>"
|
||||
if(FUGITIVE_RESULT_MINOR_HUNTER)
|
||||
result += "<span class='greentext big'>Minor [capitalize(backstory)] Victory</span>"
|
||||
result += "<B>All the [backstory]s died, but managed to capture a fugitive, dead or alive.</B>"
|
||||
if(FUGITIVE_RESULT_STALEMATE)
|
||||
result += "<span class='neutraltext big'>Bloody Stalemate</span>"
|
||||
result += "<B>Everyone died, and no fugitives were recovered!</B>"
|
||||
if(FUGITIVE_RESULT_MINOR_FUGITIVE)
|
||||
result += "<span class='redtext big'>Minor Fugitive Victory</span>"
|
||||
result += "<B>All the fugitives died, but none were recovered!</B>"
|
||||
if(FUGITIVE_RESULT_FUGITIVE_VICTORY)
|
||||
result += "<span class='redtext big'>Fugitive Victory</span>"
|
||||
result += "<B>A fugitive survived, and no bodies were recovered by the [backstory]s.</B>"
|
||||
if(FUGITIVE_RESULT_MAJOR_FUGITIVE)
|
||||
result += "<span class='redtext big'>Major Fugitive Victory</span>"
|
||||
result += "<B>All of the fugitives survived and avoided capture!</B>"
|
||||
else //get_result returned null- either bugged or no fugitives showed
|
||||
result += "<span class='neutraltext big'>Prank Call!</span>"
|
||||
result += "<B>[capitalize(backstory)]s were called, yet there were no fugitives...?</B>"
|
||||
|
||||
result += "</div>"
|
||||
|
||||
return result.Join("<br>")
|
||||
@@ -417,3 +417,40 @@
|
||||
crate_type = /obj/structure/closet/crate
|
||||
|
||||
|
||||
///Special supply crate that generates random syndicate gear up to a determined TC value
|
||||
|
||||
/datum/supply_pack/misc/syndicate
|
||||
|
||||
name = "Assorted Syndicate Gear"
|
||||
|
||||
desc = "Contains a random assortment of syndicate gear."
|
||||
|
||||
special = TRUE ///Cannot be ordered via cargo
|
||||
|
||||
contains = list()
|
||||
|
||||
crate_name = "syndicate gear crate"
|
||||
|
||||
crate_type = /obj/structure/closet/crate
|
||||
|
||||
var/crate_value = 30 ///Total TC worth of contained uplink items
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////// Syndicate Packs /////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//Generate assorted uplink items, taking into account the same surplus modifiers used for surplus crates
|
||||
//(this is exclusively used for the rare variant of the stray cargo event!)
|
||||
/datum/supply_pack/misc/syndicate/fill(obj/structure/closet/crate/C)
|
||||
var/list/uplink_items = get_uplink_items(SSticker.mode)
|
||||
while(crate_value)
|
||||
var/category = pick(uplink_items)
|
||||
var/item = pick(uplink_items[category])
|
||||
var/datum/uplink_item/I = uplink_items[category][item]
|
||||
if(!I.surplus || prob(100 - I.surplus))
|
||||
continue
|
||||
if(crate_value < I.cost)
|
||||
continue
|
||||
crate_value -= I.cost
|
||||
new I.item(C)
|
||||
@@ -203,6 +203,12 @@
|
||||
icon_state = "hipster_glasses"
|
||||
item_state = "hipster_glasses"
|
||||
|
||||
/obj/item/clothing/glasses/regular/circle
|
||||
name = "circle glasses"
|
||||
desc = "Why would you wear something so controversial yet so brave?"
|
||||
icon_state = "circle_glasses"
|
||||
item_state = "circle_glasses"
|
||||
|
||||
//Here lies green glasses, so ugly they died. RIP
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses
|
||||
|
||||
@@ -74,6 +74,9 @@
|
||||
icon_state = "beaniedurathread"
|
||||
armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50)
|
||||
|
||||
|
||||
/obj/item/clothing/head/beanie/waldo
|
||||
name = "red striped bobble hat"
|
||||
desc = "If you're going on a worldwide hike, you'll need some cold protection."
|
||||
icon_state = "waldo_hat"
|
||||
|
||||
//No dog fashion sprites yet :( poor Ian can't be dope like the rest of us yet
|
||||
@@ -386,3 +386,9 @@
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 0)
|
||||
|
||||
/obj/item/clothing/head/helmet/police
|
||||
name = "police officer's hat"
|
||||
desc = "A police officer's Hat. This hat emphasizes that you are THE LAW."
|
||||
icon_state = "policehelm"
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
@@ -429,3 +429,11 @@
|
||||
icon_state = "russobluecamohat"
|
||||
item_state = "russobluecamohat"
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
/obj/item/clothing/head/hunter
|
||||
name = "bounty hunting hat"
|
||||
desc = "Ain't nobody gonna cheat the hangman in my town."
|
||||
icon_state = "hunter"
|
||||
item_state = "hunter"
|
||||
armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
|
||||
@@ -231,3 +231,15 @@
|
||||
A.UpdateButtonIcon()
|
||||
to_chat(M, "The Tiki Mask has now changed into the [choice] Mask!")
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/mask/gas/tiki_mask/yalp_elor
|
||||
icon_state = "tiki_yalp"
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/clothing/mask/gas/hunter
|
||||
name = "bounty hunting mask"
|
||||
desc = "A custom tactical mask with decals added."
|
||||
icon_state = "hunter"
|
||||
item_state = "hunter"
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
flags_inv = HIDEFACIALHAIR|HIDEFACE|HIDEEYES|HIDEEARS|HIDEHAIR
|
||||
|
||||
@@ -185,3 +185,9 @@
|
||||
playsound(src.loc, "sound/voice/complionator/[phrase_sound].ogg", 100, 0, 4)
|
||||
cooldown = world.time
|
||||
cooldown_special = world.time
|
||||
|
||||
/obj/item/clothing/mask/gas/sechailer/swat/spacepol
|
||||
name = "spacepol mask"
|
||||
desc = "A close-fitting tactical mask created in cooperation with a certain megacorporation, comes with an especially aggressive Compli-o-nator 3000."
|
||||
icon_state = "spacepol"
|
||||
item_state = "spacepol"
|
||||
|
||||
@@ -518,3 +518,14 @@ Contains:
|
||||
desc = "A deep blue space helmet with a large red cross on the faceplate to designate the wearer as trained emergency medical personnel."
|
||||
icon_state = "paramedic-eva-helmet"
|
||||
item_state = "paramedic-eva-helmet"
|
||||
|
||||
/obj/item/clothing/suit/space/hunter
|
||||
name = "bounty hunting suit"
|
||||
desc = "A custom version of the MK.II SWAT suit, modified to look rugged and tough. Works as a space suit, if you can find a helmet."
|
||||
icon_state = "hunter"
|
||||
item_state = "swat_suit"
|
||||
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat)
|
||||
armor = list("melee" = 60, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
|
||||
strip_delay = 130
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
|
||||
|
||||
@@ -1016,3 +1016,9 @@
|
||||
/obj/item/clothing/head/hooded/winterhood/polychromic
|
||||
icon_state = "winterhood_poly"
|
||||
item_state = "winterhood_poly"
|
||||
|
||||
/obj/item/clothing/suit/striped_sweater
|
||||
name = "striped sweater"
|
||||
desc = "Reminds you of someone, but you just can't put your finger on it..."
|
||||
icon_state = "waldo_shirt"
|
||||
item_state = "waldo_shirt"
|
||||
|
||||
@@ -192,3 +192,14 @@
|
||||
icon_state = "hos_parade_fem"
|
||||
item_state = "r_suit"
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
|
||||
/*
|
||||
*Spacepol
|
||||
*/
|
||||
|
||||
/obj/item/clothing/under/rank/security/spacepol
|
||||
name = "police uniform"
|
||||
desc = "Space not controlled by megacorporations, planets, or pirates is under the jurisdiction of Spacepol."
|
||||
icon_state = "spacepol"
|
||||
item_state = "spacepol"
|
||||
can_adjust = FALSE
|
||||
@@ -0,0 +1,33 @@
|
||||
/datum/round_event_control/brain_trauma
|
||||
name = "Spontaneous Brain Trauma"
|
||||
typepath = /datum/round_event/brain_trauma
|
||||
weight = 25
|
||||
|
||||
/datum/round_event/brain_trauma
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/brain_trauma/start()
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
|
||||
if(!H.client)
|
||||
continue
|
||||
if(H.stat == DEAD) // What are you doing in this list
|
||||
continue
|
||||
if(!H.getorgan(/obj/item/organ/brain)) // If only I had a brain
|
||||
continue
|
||||
|
||||
traumatize(H)
|
||||
break
|
||||
|
||||
/datum/round_event/brain_trauma/proc/traumatize(mob/living/carbon/human/H)
|
||||
var/resistance = pick(
|
||||
65;TRAUMA_RESILIENCE_BASIC,
|
||||
30;TRAUMA_RESILIENCE_SURGERY,
|
||||
5;TRAUMA_RESILIENCE_LOBOTOMY)
|
||||
|
||||
var/trauma_type = pickweight(list(
|
||||
BRAIN_TRAUMA_MILD = 60,
|
||||
BRAIN_TRAUMA_SEVERE = 30,
|
||||
BRAIN_TRAUMA_SPECIAL = 10
|
||||
))
|
||||
|
||||
H.gain_trauma_type(trauma_type, resistance)
|
||||
@@ -0,0 +1,30 @@
|
||||
/datum/round_event_control/fake_virus
|
||||
name = "Fake Virus"
|
||||
typepath = /datum/round_event/fake_virus
|
||||
weight = 20
|
||||
|
||||
/datum/round_event/fake_virus/start()
|
||||
var/list/fake_virus_victims = list()
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.player_list))
|
||||
if(!H.client || H.stat == DEAD || H.InCritical())
|
||||
continue
|
||||
fake_virus_victims += H
|
||||
|
||||
//first we do hard status effect victims
|
||||
var/defacto_min = min(3, LAZYLEN(fake_virus_victims))
|
||||
if(defacto_min)// event will hit 1-3 people by default, but will do 1-2 or just 1 if only those many candidates are available
|
||||
for(var/i=1; i<=rand(1,defacto_min); i++)
|
||||
var/mob/living/carbon/human/hypochondriac = pick(fake_virus_victims)
|
||||
hypochondriac.apply_status_effect(STATUS_EFFECT_FAKE_VIRUS)
|
||||
fake_virus_victims -= hypochondriac
|
||||
|
||||
//then we do light one-message victims who simply cough or whatever once (have to repeat the process since the last operation modified our candidates list)
|
||||
defacto_min = min(5, LAZYLEN(fake_virus_victims))
|
||||
if(defacto_min)
|
||||
for(var/i=1; i<=rand(1,defacto_min); i++)
|
||||
var/mob/living/carbon/human/onecoughman = pick(fake_virus_victims)
|
||||
if(prob(25))//1/4 odds to get a spooky message instead of coughing out loud
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, onecoughman, "<span class='warning'>[pick("Your head hurts.", "Your head pounds.")]</span>"), rand(30,150))
|
||||
else
|
||||
addtimer(CALLBACK(onecoughman, .mob/proc/emote, pick("cough", "sniff", "sneeze")), rand(30,150))//deliver the message with a slightly randomized time interval so there arent multiple people coughing at the exact same time
|
||||
fake_virus_victims -= onecoughman
|
||||
@@ -0,0 +1,117 @@
|
||||
/datum/round_event_control/fugitives
|
||||
name = "Spawn Fugitives"
|
||||
typepath = /datum/round_event/ghost_role/fugitives
|
||||
max_occurrences = 1
|
||||
min_players = 20
|
||||
earliest_start = 30 MINUTES //deadchat sink, lets not even consider it early on.
|
||||
gamemode_blacklist = list("nuclear")
|
||||
|
||||
/datum/round_event/ghost_role/fugitives
|
||||
minimum_required = 1
|
||||
role_name = "fugitive"
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/ghost_role/fugitives/spawn_role()
|
||||
var/list/possible_spawns = list()//Some xeno spawns are in some spots that will instantly kill the refugees, like atmos
|
||||
for(var/turf/X in GLOB.xeno_spawn)
|
||||
if(istype(X.loc, /area/maintenance))
|
||||
possible_spawns += X
|
||||
if(!possible_spawns.len)
|
||||
message_admins("No valid spawn locations found, aborting...")
|
||||
return MAP_ERROR
|
||||
var/turf/landing_turf = pick(possible_spawns)
|
||||
var/list/possible_backstories = list()
|
||||
var/list/candidates = get_candidates(ROLE_TRAITOR, null, ROLE_TRAITOR)
|
||||
if(candidates.len >= 1) //solo refugees
|
||||
if(prob(30))
|
||||
possible_backstories.Add("waldo") //less common as it comes with magicks and is kind of immershun shattering
|
||||
else //For accurate deadchat feedback
|
||||
minimum_required = 4
|
||||
if(candidates.len >= 4)//group refugees
|
||||
possible_backstories.Add("prisoner", "cultist", "synth")
|
||||
if(!possible_backstories.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
var/backstory = pick(possible_backstories)
|
||||
var/member_size = 3
|
||||
var/leader
|
||||
switch(backstory)
|
||||
if("synth")
|
||||
leader = pick_n_take(candidates)
|
||||
if("waldo")
|
||||
member_size = 0 //solo refugees have no leader so the member_size gets bumped to one a bit later
|
||||
var/list/members = list()
|
||||
var/list/spawned_mobs = list()
|
||||
if(isnull(leader))
|
||||
member_size++ //if there is no leader role, then the would be leader is a normal member of the team.
|
||||
|
||||
for(var/i in 1 to member_size)
|
||||
members += pick_n_take(candidates)
|
||||
|
||||
for(var/mob/dead/selected in members)
|
||||
var/mob/living/carbon/human/S = gear_fugitive(selected, landing_turf, backstory)
|
||||
spawned_mobs += S
|
||||
if(!isnull(leader))
|
||||
gear_fugitive_leader(leader, landing_turf, backstory)
|
||||
|
||||
//after spawning
|
||||
playsound(src, 'sound/weapons/emitter.ogg', 50, TRUE)
|
||||
new /obj/item/storage/toolbox/mechanical(landing_turf) //so they can actually escape maint
|
||||
addtimer(CALLBACK(src, .proc/spawn_hunters), 10 MINUTES)
|
||||
role_name = "fugitive hunter"
|
||||
return SUCCESSFUL_SPAWN
|
||||
|
||||
/datum/round_event/ghost_role/fugitives/proc/gear_fugitive(mob/dead/selected, turf/landing_turf, backstory) //spawns normal fugitive
|
||||
var/datum/mind/player_mind = new /datum/mind(selected.key)
|
||||
player_mind.active = TRUE
|
||||
var/mob/living/carbon/human/S = new(landing_turf)
|
||||
player_mind.transfer_to(S)
|
||||
player_mind.assigned_role = "Fugitive"
|
||||
player_mind.special_role = "Fugitive"
|
||||
player_mind.add_antag_datum(/datum/antagonist/fugitive)
|
||||
var/datum/antagonist/fugitive/fugitiveantag = player_mind.has_antag_datum(/datum/antagonist/fugitive)
|
||||
INVOKE_ASYNC(fugitiveantag, /datum/antagonist/fugitive.proc/greet, backstory) //some fugitives have a sleep on their greet, so we don't want to stop the entire antag granting proc with fluff
|
||||
|
||||
switch(backstory)
|
||||
if("prisoner")
|
||||
S.equipOutfit(/datum/outfit/prisoner)
|
||||
if("cultist")
|
||||
S.equipOutfit(/datum/outfit/yalp_cultist)
|
||||
if("waldo")
|
||||
S.equipOutfit(/datum/outfit/waldo)
|
||||
if("synth")
|
||||
S.equipOutfit(/datum/outfit/synthetic)
|
||||
message_admins("[ADMIN_LOOKUPFLW(S)] has been made into a Fugitive by an event.")
|
||||
log_game("[key_name(S)] was spawned as a Fugitive by an event.")
|
||||
spawned_mobs += S
|
||||
return S
|
||||
|
||||
//special spawn for one member. it can be used for a special mob or simply to give one normal member special items.
|
||||
/datum/round_event/ghost_role/fugitives/proc/gear_fugitive_leader(mob/dead/leader, turf/landing_turf, backstory)
|
||||
var/datum/mind/player_mind = new /datum/mind(leader.key)
|
||||
player_mind.active = TRUE
|
||||
//if you want to add a fugitive with a special leader in the future, make this switch with the backstory
|
||||
var/mob/living/carbon/human/S = gear_fugitive(leader, landing_turf, backstory)
|
||||
var/obj/item/choice_beacon/augments/A = new(S)
|
||||
S.put_in_hands(A)
|
||||
new /obj/item/autosurgeon(landing_turf)
|
||||
|
||||
//security team gets called in after 10 minutes of prep to find the refugees
|
||||
/datum/round_event/ghost_role/fugitives/proc/spawn_hunters()
|
||||
var/backstory = pick("space cop", "russian", "bounty hunter")
|
||||
var/datum/map_template/shuttle/ship
|
||||
if(backstory == "space cop")
|
||||
ship = new /datum/map_template/shuttle/hunter/space_cop
|
||||
else if (backstory == "russian")
|
||||
ship = new /datum/map_template/shuttle/hunter/russian
|
||||
else
|
||||
ship = new /datum/map_template/shuttle/hunter/bounty
|
||||
var/x = rand(TRANSITIONEDGE,world.maxx - TRANSITIONEDGE - ship.width)
|
||||
var/y = rand(TRANSITIONEDGE,world.maxy - TRANSITIONEDGE - ship.height)
|
||||
var/z = SSmapping.empty_space.z_value
|
||||
var/turf/T = locate(x,y,z)
|
||||
if(!T)
|
||||
CRASH("Fugitive Hunters (Created from fugitive event) found no turf to load in")
|
||||
if(!ship.load(T))
|
||||
CRASH("Loading [backstory] ship failed!")
|
||||
priority_announce("Unidentified ship detected near the station.")
|
||||
@@ -0,0 +1,99 @@
|
||||
///Spawns a cargo pod containing a random cargo supply pack on a random area of the station
|
||||
/datum/round_event_control/stray_cargo
|
||||
name = "Stray Cargo Pod"
|
||||
typepath = /datum/round_event/stray_cargo
|
||||
weight = 20
|
||||
max_occurrences = 4
|
||||
earliest_start = 10 MINUTES
|
||||
|
||||
///Spawns a cargo pod containing a random cargo supply pack on a random area of the station
|
||||
/datum/round_event/stray_cargo
|
||||
var/area/impact_area ///Randomly picked area
|
||||
var/list/possible_pack_types = list() ///List of possible supply packs dropped in the pod, if empty picks from the cargo list
|
||||
var/static/list/stray_spawnable_supply_packs = list() ///List of default spawnable supply packs, filtered from the cargo list
|
||||
|
||||
/datum/round_event/stray_cargo/announce(fake)
|
||||
priority_announce("Stray cargo pod detected on long-range scanners. Expected location of impact: [impact_area.name].", "Collision Alert")
|
||||
|
||||
/**
|
||||
* Tries to find a valid area, throws an error if none are found
|
||||
* Also randomizes the start timer
|
||||
*/
|
||||
/datum/round_event/stray_cargo/setup()
|
||||
startWhen = rand(20, 40)
|
||||
impact_area = find_event_area()
|
||||
if(!impact_area)
|
||||
CRASH("No valid areas for cargo pod found.")
|
||||
var/list/turf_test = get_area_turfs(impact_area)
|
||||
if(!turf_test.len)
|
||||
CRASH("Stray Cargo Pod : No valid turfs found for [impact_area] - [impact_area.type]")
|
||||
|
||||
if(!stray_spawnable_supply_packs.len)
|
||||
stray_spawnable_supply_packs = SSshuttle.supply_packs.Copy()
|
||||
for(var/pack in stray_spawnable_supply_packs)
|
||||
var/datum/supply_pack/pack_type = pack
|
||||
if(initial(pack_type.special))
|
||||
stray_spawnable_supply_packs -= pack
|
||||
|
||||
///Spawns a random supply pack, puts it in a pod, and spawns it on a random tile of the selected area
|
||||
/datum/round_event/stray_cargo/start()
|
||||
var/list/turf/valid_turfs = get_area_turfs(impact_area)
|
||||
//Only target non-dense turfs to prevent wall-embedded pods
|
||||
for(var/i in valid_turfs)
|
||||
var/turf/T = i
|
||||
if(T.density)
|
||||
valid_turfs -= T
|
||||
var/turf/LZ = pick(valid_turfs)
|
||||
var/pack_type
|
||||
if(possible_pack_types.len)
|
||||
pack_type = pick(possible_pack_types)
|
||||
else
|
||||
pack_type = pick(stray_spawnable_supply_packs)
|
||||
var/datum/supply_pack/SP = new pack_type
|
||||
var/obj/structure/closet/crate/crate = SP.generate(null)
|
||||
crate.locked = FALSE //Unlock secure crates
|
||||
crate.update_icon()
|
||||
var/obj/structure/closet/supplypod/pod = make_pod()
|
||||
crate.forceMove(pod)
|
||||
new /obj/effect/abstract/DPtarget(LZ, pod)
|
||||
|
||||
///Handles the creation of the pod, in case it needs to be modified beforehand
|
||||
/datum/round_event/stray_cargo/proc/make_pod()
|
||||
var/obj/structure/closet/supplypod/S = new
|
||||
return S
|
||||
|
||||
///Picks an area that wouldn't risk critical damage if hit by a pod explosion
|
||||
/datum/round_event/stray_cargo/proc/find_event_area()
|
||||
var/static/list/allowed_areas
|
||||
if(!allowed_areas)
|
||||
///Places that shouldn't explode
|
||||
var/list/safe_area_types = typecacheof(list(
|
||||
/area/ai_monitored/turret_protected/ai,
|
||||
/area/ai_monitored/turret_protected/ai_upload,
|
||||
/area/engine,
|
||||
/area/shuttle)
|
||||
)
|
||||
|
||||
///Subtypes from the above that actually should explode.
|
||||
var/list/unsafe_area_subtypes = typecacheof(list(/area/engine/break_room))
|
||||
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
|
||||
var/list/possible_areas = typecache_filter_list(GLOB.sortedAreas,allowed_areas)
|
||||
if (length(possible_areas))
|
||||
return pick(possible_areas)
|
||||
|
||||
///A rare variant that drops a crate containing syndicate uplink items
|
||||
/datum/round_event_control/stray_cargo/syndicate
|
||||
name = "Stray Syndicate Cargo Pod"
|
||||
typepath = /datum/round_event/stray_cargo/syndicate
|
||||
weight = 6
|
||||
max_occurrences = 1
|
||||
earliest_start = 30 MINUTES
|
||||
|
||||
/datum/round_event/stray_cargo/syndicate
|
||||
possible_pack_types = list(/datum/supply_pack/misc/syndicate)
|
||||
|
||||
///Apply the syndicate pod skin
|
||||
/datum/round_event/stray_cargo/syndicate/make_pod()
|
||||
var/obj/structure/closet/supplypod/S = new
|
||||
S.setStyle(STYLE_SYNDICATE)
|
||||
return S
|
||||
@@ -0,0 +1,15 @@
|
||||
/datum/round_event_control/wisdomcow
|
||||
name = "Wisdom cow"
|
||||
typepath = /datum/round_event/wisdomcow
|
||||
max_occurrences = 1
|
||||
weight = 20
|
||||
|
||||
/datum/round_event/wisdomcow/announce(fake)
|
||||
priority_announce("A wise cow has been spotted in the area. Be sure to ask for her advice.", "Nanotrasen Cow Ranching Agency")
|
||||
|
||||
/datum/round_event/wisdomcow/start()
|
||||
var/turf/targetloc = get_random_station_turf()
|
||||
new /mob/living/simple_animal/cow/wisdom(targetloc)
|
||||
var/datum/effect_system/smoke_spread/smoke = new
|
||||
smoke.set_up(1, targetloc)
|
||||
smoke.start()
|
||||
@@ -315,6 +315,15 @@
|
||||
slice_path = /obj/item/reagent_containers/food/snacks/meat/rawcutlet/gondola
|
||||
foodtype = RAW | MEAT
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/meat/slab/wisdomcow
|
||||
name = "wisdom cow meat"
|
||||
desc = "The meat from the legendary creature known as the wisdom cow. You monster."
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/medicine/liquid_wisdom = 5)
|
||||
tastes = list("meat" = 1, "wisdom" = 5)
|
||||
filling_color = "#18e3ca"
|
||||
cooked_type = /obj/item/reagent_containers/food/snacks/meat/steak/wisdomcow
|
||||
slice_path = /obj/item/reagent_containers/food/snacks/meat/rawcutlet/wisdomcow
|
||||
|
||||
////////////////////////////////////// MEAT STEAKS ///////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -374,6 +383,10 @@
|
||||
name = "gondola steak"
|
||||
tastes = list("meat" = 1, "tranquility" = 1)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/meat/steak/wisdomcow
|
||||
name = "wisdom cow steak"
|
||||
tastes = list("meat" = 1, "wisdom" = 5)
|
||||
|
||||
//////////////////////////////// MEAT CUTLETS ///////////////////////////////////////////////////////
|
||||
|
||||
//Raw cutlets
|
||||
@@ -441,6 +454,11 @@
|
||||
cooked_type = /obj/item/reagent_containers/food/snacks/meat/cutlet/gondola
|
||||
tastes = list("meat" = 1, "tranquility" = 1)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/meat/rawcutlet/wisdomcow
|
||||
name = "raw wisdom cow cutlet"
|
||||
cooked_type = /obj/item/reagent_containers/food/snacks/meat/cutlet/wisdomcow
|
||||
tastes = list("meat" = 1, "wisdom" = 5)
|
||||
|
||||
//Cooked cutlets
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/meat/cutlet
|
||||
@@ -488,3 +506,7 @@
|
||||
/obj/item/reagent_containers/food/snacks/meat/cutlet/chicken
|
||||
name = "chicken cutlet"
|
||||
tastes = list("chicken" = 1)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/meat/cutlet/wisdomcow
|
||||
name = "wisdom cow cutlet"
|
||||
tastes = list("meat" = 1, "wisdom" = 5)
|
||||
|
||||
@@ -33,11 +33,12 @@
|
||||
stop_automated_movement_when_pulled = 1
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
var/obj/item/udder/udder = null
|
||||
var/datum/reagent/milk_reagent = /datum/reagent/consumable/milk
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_SHOE
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/Initialize()
|
||||
udder = new()
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/Initialize(/datum/reagent/milk_reagent)
|
||||
udder = new (milk_reagent,"hi")
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/Destroy()
|
||||
@@ -57,7 +58,7 @@
|
||||
LoseTarget()
|
||||
src.visible_message("<span class='notice'>[src] calms down.</span>")
|
||||
if(stat == CONSCIOUS)
|
||||
udder.generateMilk()
|
||||
udder.generateMilk(milk_reagent)
|
||||
eat_plants()
|
||||
if(!pulledby)
|
||||
for(var/direction in shuffle(list(1,2,4,8,5,6,9,10)))
|
||||
@@ -137,13 +138,14 @@
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
var/obj/item/udder/udder = null
|
||||
var/datum/reagent/milk_reagent = /datum/reagent/consumable/milk
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_SHOE
|
||||
|
||||
/mob/living/simple_animal/cow/Initialize()
|
||||
udder = new()
|
||||
udder = new(milk_reagent, "hi")
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/cow/Destroy()
|
||||
@@ -161,7 +163,7 @@
|
||||
/mob/living/simple_animal/cow/Life()
|
||||
. = ..()
|
||||
if(stat == CONSCIOUS)
|
||||
udder.generateMilk()
|
||||
udder.generateMilk(milk_reagent)
|
||||
|
||||
/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M)
|
||||
if(!stat && M.a_intent == INTENT_DISARM && icon_state != icon_dead)
|
||||
@@ -189,6 +191,19 @@
|
||||
else
|
||||
..()
|
||||
|
||||
//Wisdom cow, speaks and bestows great wisdoms
|
||||
/mob/living/simple_animal/cow/wisdom
|
||||
name = "wisdom cow"
|
||||
desc = "Known for its wisdom, shares it with all"
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/wisdomcow = 1) //truly the best meat
|
||||
gold_core_spawnable = FALSE
|
||||
speak_chance = 30 //the cow is eager to share its wisdom!
|
||||
milk_reagent = /datum/reagent/medicine/liquid_wisdom
|
||||
|
||||
/mob/living/simple_animal/cow/wisdom/Initialize()
|
||||
. = ..()
|
||||
speak = GLOB.wisdoms //Done here so it's setup properly
|
||||
|
||||
/mob/living/simple_animal/chick
|
||||
name = "\improper chick"
|
||||
desc = "Adorable! They make such a racket though."
|
||||
@@ -481,14 +496,15 @@
|
||||
/obj/item/udder
|
||||
name = "udder"
|
||||
|
||||
/obj/item/udder/Initialize()
|
||||
/obj/item/udder/Initialize(reagent, thing2)
|
||||
message_admins("we got passed [reagent] and [thing2]")
|
||||
create_reagents(50, NONE, NO_REAGENTS_VALUE)
|
||||
reagents.add_reagent(/datum/reagent/consumable/milk, 20)
|
||||
reagents.add_reagent(reagent, 20)
|
||||
. = ..()
|
||||
|
||||
/obj/item/udder/proc/generateMilk()
|
||||
/obj/item/udder/proc/generateMilk(datum/reagent/milk_reagent)
|
||||
if(prob(5))
|
||||
reagents.add_reagent(/datum/reagent/consumable/milk, rand(5, 10))
|
||||
reagents.add_reagent(milk_reagent, rand(5, 10))
|
||||
|
||||
/obj/item/udder/proc/milkAnimal(obj/O, mob/user)
|
||||
var/obj/item/reagent_containers/glass/G = O
|
||||
|
||||
@@ -143,3 +143,12 @@
|
||||
reagents.add_reagent(/datum/reagent/toxin/acid/fluacid, 5) //this and the acid equal about 25ish burn, not counting the minute toxin damage dealt by their metabolism, this makes each dart about as lethal as a stechkin shot in upfront damage
|
||||
reagents.add_reagent(/datum/reagent/toxin/acid, 5)
|
||||
reagents.add_reagent(/datum/reagent/consumable/frostoil, 10) //tempgun slowdown goes both ways and adds to the burn
|
||||
|
||||
/obj/item/ammo_casing/shotgun/incapacitate
|
||||
name = "custom incapacitating shot"
|
||||
desc = "A shotgun casing filled with... something. used to incapacitate targets."
|
||||
icon_state = "bountyshell"
|
||||
projectile_type = /obj/item/projectile/bullet/pellet/shotgun_incapacitate
|
||||
pellets = 12//double the pellets, but half the stun power of each, which makes this best for just dumping right in someone's face.
|
||||
variance = 25
|
||||
custom_materials = list(/datum/material/iron=4000)
|
||||
@@ -50,3 +50,8 @@
|
||||
name = "riot shotgun internal magazine"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/rubbershot
|
||||
max_ammo = 6
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/shot/bounty
|
||||
name = "triple-barrel shotgun internal magazine"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/incapacitate
|
||||
max_ammo = 3
|
||||
@@ -320,3 +320,18 @@
|
||||
return TRUE
|
||||
|
||||
// DOUBLE BARRELED SHOTGUN and IMPROVISED SHOTGUN are in revolver.dm
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/doublebarrel/hook
|
||||
name = "hook modified sawn-off shotgun"
|
||||
desc = "Range isn't an issue when you can bring your victim to you."
|
||||
icon_state = "hookshotgun"
|
||||
item_state = "shotgun"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/bounty
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
weapon_weight = WEAPON_MEDIUM
|
||||
force = 16 //it has a hook on it
|
||||
attack_verb = list("slashed", "hooked", "stabbed")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
//our hook gun!
|
||||
var/obj/item/gun/magic/hook/bounty/hook
|
||||
var/toggled = FALSE
|
||||
|
||||
@@ -112,3 +112,8 @@
|
||||
/obj/item/projectile/bullet/seed
|
||||
damage = 4
|
||||
stamina = 1
|
||||
|
||||
/obj/item/projectile/bullet/pellet/shotgun_incapacitate
|
||||
name = "incapacitating pellet"
|
||||
damage = 1
|
||||
stamina = 6
|
||||
@@ -1563,3 +1563,20 @@
|
||||
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5)
|
||||
..()
|
||||
. = 1
|
||||
|
||||
/datum/reagent/medicine/liquid_wisdom
|
||||
name = "liquid wisdom"
|
||||
description = "the physical representation of wisdom, in liquid form"
|
||||
taste_mult = 4
|
||||
can_synth = FALSE
|
||||
overdose_threshold = 30
|
||||
value = REAGENT_VALUE_UNCOMMON // while it's 'rare', it can be milked from the wisdom cow
|
||||
|
||||
/datum/reagent/medicine/liquid_wisdom/on_mob_life(mob/living/carbon/C) //slightly stronger mannitol, from the wisdom cow
|
||||
C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3*REM)
|
||||
if(prob(20))
|
||||
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
|
||||
if(prob(3))
|
||||
to_chat(C, "[pick(GLOB.wisdoms)]") //give them a random wisdom
|
||||
..()
|
||||
|
||||
|
||||
@@ -2284,3 +2284,4 @@
|
||||
S = new(T)
|
||||
if(data["blood_DNA"])
|
||||
S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user