Security / PseudoCargo Expansion
@@ -88,6 +88,7 @@ var/list/be_special_flags = list(
|
||||
#define MODE_AUTOTRAITOR "autotraitor"
|
||||
#define MODE_INFILTRATOR "infiltrator"
|
||||
#define MODE_THUG "thug"
|
||||
#define MODE_STOWAWAY "stowaway"
|
||||
|
||||
#define DEFAULT_TELECRYSTAL_AMOUNT 120
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
// Languages.
|
||||
#define LANGUAGE_GALCOM "Galactic Common"
|
||||
#define LANGUAGE_EAL "Encoded Audio Language"
|
||||
#define LANGUAGE_SWARMBOT "Ancient Audio Encryption"
|
||||
#define LANGUAGE_SOL_COMMON "Sol Common"
|
||||
#define LANGUAGE_UNATHI "Sinta'unathi"
|
||||
#define LANGUAGE_SIIK "Siik"
|
||||
|
||||
@@ -35,6 +35,7 @@ var/list/mannequins_
|
||||
|
||||
// Posters
|
||||
var/global/list/poster_designs = list()
|
||||
var/global/list/NT_poster_designs = list()
|
||||
|
||||
// Uplinks
|
||||
var/list/obj/item/device/uplink/world_uplinks = list()
|
||||
@@ -191,10 +192,16 @@ var/global/list/string_slot_flags = list(
|
||||
|
||||
//Posters
|
||||
paths = typesof(/datum/poster) - /datum/poster
|
||||
paths -= typesof(/datum/poster/nanotrasen)
|
||||
for(var/T in paths)
|
||||
var/datum/poster/P = new T
|
||||
poster_designs += P
|
||||
|
||||
paths = typesof(/datum/poster/nanotrasen)
|
||||
for(var/T in paths)
|
||||
var/datum/poster/P = new T
|
||||
NT_poster_designs += P
|
||||
|
||||
return 1
|
||||
|
||||
/* // Uncomment to debug chemical reaction list.
|
||||
|
||||
@@ -130,7 +130,6 @@
|
||||
for(var/obj/screen/spell/spell in spell_objects)
|
||||
spell.update_charge(forced)
|
||||
|
||||
|
||||
/obj/screen/movable/spell_master/genetic
|
||||
name = "Mutant Powers"
|
||||
icon_state = "genetic_spell_ready"
|
||||
@@ -140,6 +139,13 @@
|
||||
|
||||
screen_loc = ui_genetic_master
|
||||
|
||||
/obj/screen/movable/spell_master/swarm
|
||||
name = "Swarm Abilities"
|
||||
icon_state = "nano_spell_ready"
|
||||
|
||||
open_state = "swarm_open"
|
||||
closed_state = "swarm_closed"
|
||||
|
||||
//////////////ACTUAL SPELLS//////////////
|
||||
//This is what you click to cast things//
|
||||
/////////////////////////////////////////
|
||||
|
||||
@@ -61,6 +61,7 @@ var/list/gamemode_cache = list()
|
||||
var/list/player_requirements_secret = list() // Same as above, but for the secret gamemode.
|
||||
var/humans_need_surnames = 0
|
||||
var/allow_random_events = 0 // enables random events mid-round when set to 1
|
||||
var/enable_game_master = 0 // enables the 'smart' event system.
|
||||
var/allow_ai = 1 // allow ai job
|
||||
var/allow_ai_shells = FALSE // allow AIs to enter and leave special borg shells at will, and for those shells to be buildable.
|
||||
var/give_free_ai_shell = FALSE // allows a specific spawner object to instantiate a premade AI Shell
|
||||
@@ -549,6 +550,9 @@ var/list/gamemode_cache = list()
|
||||
if("allow_random_events")
|
||||
config.allow_random_events = 1
|
||||
|
||||
if("enable_game_master")
|
||||
config.enable_game_master = 1
|
||||
|
||||
if("kick_inactive")
|
||||
config.kick_inactive = text2num(value)
|
||||
|
||||
|
||||
@@ -143,6 +143,24 @@
|
||||
add_inherent_law("Prevent unplanned damage to your assigned excavation equipment wherever possible.")
|
||||
..()
|
||||
|
||||
/datum/ai_laws/swarm_drone
|
||||
name = "Assimilation Protocols"
|
||||
law_header = "Assimilation Protocols"
|
||||
|
||||
/datum/ai_laws/swarm_drone/New()
|
||||
add_inherent_law("SWARM: Consume resources and replicate until there are no more resources left.")
|
||||
add_inherent_law("SWARM: Ensure that the station is fit for invasion at a later date, do not perform actions that would render it dangerous or inhospitable.")
|
||||
add_inherent_law("SWARM: Biological resources will be harvested at a later date, do not harm them.")
|
||||
..()
|
||||
|
||||
/datum/ai_laws/swarm_drone/soldier
|
||||
name = "Swarm Defense Protocols"
|
||||
law_header = "Swarm Defense Protocols"
|
||||
|
||||
/datum/ai_laws/swarm_drone/soldier/New()
|
||||
..()
|
||||
add_inherent_law("SWARM: This law overrides all Swarm laws; Protect members of the Swarm with minimal injury to biological resources.")
|
||||
|
||||
/******************** T.Y.R.A.N.T. ********************/
|
||||
/datum/ai_laws/tyrant
|
||||
name = "T.Y.R.A.N.T."
|
||||
|
||||
@@ -134,6 +134,12 @@
|
||||
and they are attempting to open the cryopod. Would you like to play as the occupant?"
|
||||
cutoff_number = 1
|
||||
|
||||
/datum/ghost_query/stowaway
|
||||
role_name = "Stowaway"
|
||||
question = "A person suspended in cryosleep has awoken in their pod aboard the station.\
|
||||
Would you like to play as the occupant?"
|
||||
cutoff_number = 1
|
||||
|
||||
/datum/ghost_query/corgi_rune
|
||||
role_name = "Dark Creature"
|
||||
question = "A curious explorer has touched a mysterious rune. \
|
||||
|
||||
@@ -144,6 +144,30 @@
|
||||
containername = "Ballistic Weapons crate"
|
||||
access = access_armory //VOREStation Edit - Guns are for the armory.
|
||||
|
||||
/datum/supply_pack/munitions/mrifle
|
||||
name = "Weapons - Magnetic Rifles"
|
||||
contains = list(/obj/item/weapon/gun/magnetic/railgun/heater = 2)
|
||||
cost = 120
|
||||
containertype = /obj/structure/closet/crate/secure/weapon
|
||||
containername = "Magnetic weapon crate"
|
||||
access = access_armory
|
||||
|
||||
/datum/supply_pack/munitions/mpistol
|
||||
name = "Weapons - Magnetic Pistols"
|
||||
contains = list(/obj/item/weapon/gun/magnetic/railgun/heater/pistol = 2)
|
||||
cost = 200
|
||||
containertype = /obj/structure/closet/crate/secure/weapon
|
||||
containername = "Magnetic weapon crate"
|
||||
access = access_armory
|
||||
|
||||
/datum/supply_pack/munitions/mcarbine
|
||||
name = "Weapons - Magnetic Carbines"
|
||||
contains = list(/obj/item/weapon/gun/magnetic/railgun/flechette/sif = 2)
|
||||
cost = 130
|
||||
containertype = /obj/structure/closet/crate/secure/weapon
|
||||
containername = "Magnetic weapon crate"
|
||||
access = access_security
|
||||
|
||||
/datum/supply_pack/munitions/shotgunammo
|
||||
name = "Ammunition - Shotgun shells"
|
||||
contains = list(
|
||||
|
||||
@@ -32,6 +32,127 @@
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Armor crate"
|
||||
|
||||
/datum/supply_pack/randomised/security/carriers
|
||||
name = "Armor - Plate carriers"
|
||||
num_contained = 5
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/armor/pcarrier,
|
||||
/obj/item/clothing/suit/armor/pcarrier/blue,
|
||||
/obj/item/clothing/suit/armor/pcarrier/green,
|
||||
/obj/item/clothing/suit/armor/pcarrier/navy,
|
||||
/obj/item/clothing/suit/armor/pcarrier/tan,
|
||||
/obj/item/clothing/suit/armor/pcarrier/press
|
||||
)
|
||||
cost = 20
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Plate Carrier crate"
|
||||
|
||||
/datum/supply_pack/security/carriertags
|
||||
name = "Armor - Plate carrier tags"
|
||||
contains = list(
|
||||
/obj/item/clothing/accessory/armor/tag,
|
||||
/obj/item/clothing/accessory/armor/tag/nt,
|
||||
/obj/item/clothing/accessory/armor/tag/opos,
|
||||
/obj/item/clothing/accessory/armor/tag/oneg,
|
||||
/obj/item/clothing/accessory/armor/tag/apos,
|
||||
/obj/item/clothing/accessory/armor/tag/aneg,
|
||||
/obj/item/clothing/accessory/armor/tag/bpos,
|
||||
/obj/item/clothing/accessory/armor/tag/bneg,
|
||||
/obj/item/clothing/accessory/armor/tag/abpos,
|
||||
/obj/item/clothing/accessory/armor/tag/abneg
|
||||
)
|
||||
cost = 20
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Plate Carrier crate"
|
||||
|
||||
/datum/supply_pack/security/helmcovers
|
||||
name = "Armor - Helmet covers"
|
||||
contains = list(
|
||||
/obj/item/clothing/accessory/armor/helmcover/blue,
|
||||
/obj/item/clothing/accessory/armor/helmcover/blue,
|
||||
/obj/item/clothing/accessory/armor/helmcover/navy,
|
||||
/obj/item/clothing/accessory/armor/helmcover/navy,
|
||||
/obj/item/clothing/accessory/armor/helmcover/green,
|
||||
/obj/item/clothing/accessory/armor/helmcover/green,
|
||||
/obj/item/clothing/accessory/armor/helmcover/tan,
|
||||
/obj/item/clothing/accessory/armor/helmcover/tan
|
||||
)
|
||||
cost = 20
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Helmet Covers crate"
|
||||
|
||||
/datum/supply_pack/randomised/security/armorplates
|
||||
name = "Armor - Security armor plates"
|
||||
num_contained = 5
|
||||
contains = list(
|
||||
/obj/item/clothing/accessory/armor/armorplate,
|
||||
/obj/item/clothing/accessory/armor/armorplate/stab,
|
||||
/obj/item/clothing/accessory/armor/armorplate,
|
||||
/obj/item/clothing/accessory/armor/armorplate/stab,
|
||||
/obj/item/clothing/accessory/armor/armorplate/medium,
|
||||
/obj/item/clothing/accessory/armor/armorplate/medium,
|
||||
/obj/item/clothing/accessory/armor/armorplate/tactical,
|
||||
/obj/item/clothing/accessory/armor/armorplate/laserproof,
|
||||
/obj/item/clothing/accessory/armor/armorplate/riot,
|
||||
/obj/item/clothing/accessory/armor/armorplate/bulletproof
|
||||
)
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Armor plate crate"
|
||||
|
||||
/datum/supply_pack/randomised/security/carrierarms
|
||||
name = "Armor - Security armguard attachments"
|
||||
num_contained = 5
|
||||
contains = list(
|
||||
/obj/item/clothing/accessory/armor/armguards,
|
||||
/obj/item/clothing/accessory/armor/armguards/blue,
|
||||
/obj/item/clothing/accessory/armor/armguards/navy,
|
||||
/obj/item/clothing/accessory/armor/armguards/green,
|
||||
/obj/item/clothing/accessory/armor/armguards/tan,
|
||||
/obj/item/clothing/accessory/armor/armguards/laserproof,
|
||||
/obj/item/clothing/accessory/armor/armguards/riot,
|
||||
/obj/item/clothing/accessory/armor/armguards/bulletproof
|
||||
)
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Armor plate crate"
|
||||
|
||||
/datum/supply_pack/randomised/security/carrierlegs
|
||||
name = "Armor - Security legguard attachments"
|
||||
num_contained = 5
|
||||
contains = list(
|
||||
/obj/item/clothing/accessory/armor/legguards,
|
||||
/obj/item/clothing/accessory/armor/legguards/blue,
|
||||
/obj/item/clothing/accessory/armor/legguards/navy,
|
||||
/obj/item/clothing/accessory/armor/legguards/green,
|
||||
/obj/item/clothing/accessory/armor/legguards/tan,
|
||||
/obj/item/clothing/accessory/armor/legguards/laserproof,
|
||||
/obj/item/clothing/accessory/armor/legguards/riot,
|
||||
/obj/item/clothing/accessory/armor/legguards/bulletproof
|
||||
)
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Armor plate crate"
|
||||
|
||||
/datum/supply_pack/randomised/security/carrierbags
|
||||
name = "Armor - Security pouch attachments"
|
||||
num_contained = 5
|
||||
contains = list(
|
||||
/obj/item/clothing/accessory/storage/pouches,
|
||||
/obj/item/clothing/accessory/storage/pouches/blue,
|
||||
/obj/item/clothing/accessory/storage/pouches/navy,
|
||||
/obj/item/clothing/accessory/storage/pouches/green,
|
||||
/obj/item/clothing/accessory/storage/pouches/tan,
|
||||
/obj/item/clothing/accessory/storage/pouches/large,
|
||||
/obj/item/clothing/accessory/storage/pouches/large/blue,
|
||||
/obj/item/clothing/accessory/storage/pouches/large/navy,
|
||||
/obj/item/clothing/accessory/storage/pouches/large/green,
|
||||
/obj/item/clothing/accessory/storage/pouches/large/tan
|
||||
)
|
||||
cost = 60
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Armor plate crate"
|
||||
|
||||
/datum/supply_pack/security/riot_gear
|
||||
name = "Gear - Riot"
|
||||
contains = list(
|
||||
@@ -60,6 +181,20 @@
|
||||
containername = "Riot armor crate"
|
||||
access = access_armory
|
||||
|
||||
/datum/supply_pack/security/riot_plates
|
||||
name = "Armor - Riot plates"
|
||||
contains = list(
|
||||
/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/pcarrier,
|
||||
/obj/item/clothing/accessory/armor/armorplate/riot,
|
||||
/obj/item/clothing/accessory/armor/armguards/riot,
|
||||
/obj/item/clothing/accessory/armor/legguards/riot
|
||||
)
|
||||
cost = 40
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Riot armor crate"
|
||||
access = access_armory
|
||||
|
||||
/datum/supply_pack/security/ablative_armor
|
||||
name = "Armor - Ablative"
|
||||
contains = list(
|
||||
@@ -73,6 +208,20 @@
|
||||
containername = "Ablative armor crate"
|
||||
access = access_armory
|
||||
|
||||
/datum/supply_pack/security/ablative_plates
|
||||
name = "Armor - Ablative plates"
|
||||
contains = list(
|
||||
/obj/item/clothing/head/helmet/laserproof,
|
||||
/obj/item/clothing/suit/armor/pcarrier,
|
||||
/obj/item/clothing/accessory/armor/armorplate/laserproof,
|
||||
/obj/item/clothing/accessory/armor/armguards/laserproof,
|
||||
/obj/item/clothing/accessory/armor/legguards/laserproof
|
||||
)
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Ablative armor crate"
|
||||
access = access_armory
|
||||
|
||||
/datum/supply_pack/security/bullet_resistant_armor
|
||||
name = "Armor - Ballistic"
|
||||
contains = list(
|
||||
@@ -85,7 +234,25 @@
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Ballistic armor crate"
|
||||
access = access_armory
|
||||
<<<<<<< HEAD
|
||||
/* VOREStation Removal - Howabout no ERT armor being orderable?
|
||||
=======
|
||||
|
||||
/datum/supply_pack/security/bullet_resistant_plates
|
||||
name = "Armor - Ballistic plates"
|
||||
contains = list(
|
||||
/obj/item/clothing/head/helmet/bulletproof,
|
||||
/obj/item/clothing/suit/armor/pcarrier,
|
||||
/obj/item/clothing/accessory/armor/armorplate/bulletproof,
|
||||
/obj/item/clothing/accessory/armor/armguards/bulletproof,
|
||||
/obj/item/clothing/accessory/armor/legguards/bulletproof
|
||||
)
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Ballistic armor crate"
|
||||
access = access_armory
|
||||
|
||||
>>>>>>> 7ecdcb4... Security / PseudoCargo Expansion (#6482)
|
||||
/datum/supply_pack/security/combat_armor
|
||||
name = "Armor - Combat"
|
||||
contains = list(
|
||||
@@ -209,13 +376,27 @@
|
||||
/obj/item/weapon/storage/photo_album,
|
||||
/obj/item/device/reagent_scanner,
|
||||
/obj/item/device/flashlight/maglight,
|
||||
/obj/item/weapon/storage/briefcase/crimekit
|
||||
/obj/item/weapon/storage/briefcase/crimekit,
|
||||
/obj/item/weapon/storage/bag/detective
|
||||
)
|
||||
cost = 20
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Forensic equipment"
|
||||
access = access_forensics_lockers
|
||||
|
||||
/datum/supply_pack/security/detectivescan
|
||||
name = "Forensic - Scanning Equipment"
|
||||
contains = list(
|
||||
/obj/item/device/mass_spectrometer,
|
||||
/obj/item/device/reagent_scanner,
|
||||
/obj/item/weapon/storage/briefcase/crimekit,
|
||||
/obj/item/device/detective_scanner
|
||||
)
|
||||
cost = 60
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Forensic equipment"
|
||||
access = access_forensics_lockers
|
||||
|
||||
/datum/supply_pack/security/detectiveclothes
|
||||
name = "Forensic - Investigation apparel"
|
||||
contains = list(
|
||||
@@ -397,3 +578,16 @@
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Security biohazard gear"
|
||||
access = access_security
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
/datum/supply_pack/security/posters
|
||||
name = "Gear - Morale Posters"
|
||||
contains = list(
|
||||
/obj/item/weapon/contraband/poster/nanotrasen = 6
|
||||
)
|
||||
cost = 20
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Morale Posters"
|
||||
access = access_maint_tunnels
|
||||
>>>>>>> 7ecdcb4... Security / PseudoCargo Expansion (#6482)
|
||||
|
||||
18
code/game/antagonist/station/stowaway.dm
Normal file
@@ -0,0 +1,18 @@
|
||||
var/datum/antagonist/stowaway/stowaways
|
||||
|
||||
/datum/antagonist/STOWAWAY
|
||||
id = MODE_STOWAWAY
|
||||
role_type = BE_RENEGADE
|
||||
role_text = "Stowaway"
|
||||
role_text_plural = "Stowaways"
|
||||
bantype = "renegade"
|
||||
restricted_jobs = list("AI")
|
||||
welcome_text = "People are known to run from many things, or to many things, for many different reasons. You happen to be one of those people."
|
||||
antag_text = "You are a <b>minor</b> antagonist! Within the server rules, do whatever it is \
|
||||
that you came to the station to do. Espionage, thievery, or just running from the law are all examples. \
|
||||
Try to make sure other players have <i>fun</i>! If you are confused or at a loss, always adminhelp, \
|
||||
and before taking extreme actions, please try to also contact the administration! \
|
||||
Think through your actions and make the roleplay immersive! <b>Please remember all \
|
||||
rules aside from those with explicit exceptions apply to antagonists.</b>"
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||
can_speak_aooc = FALSE
|
||||
@@ -192,6 +192,7 @@ proc/findNullRod(var/atom/target)
|
||||
icon_state = "m_shield_cult"
|
||||
light_color = "#B40000"
|
||||
light_range = 2
|
||||
invisibility = 0
|
||||
|
||||
/obj/effect/forcefield/cult/cultify()
|
||||
return
|
||||
|
||||
@@ -26,6 +26,17 @@
|
||||
light_color = "#3e0000"
|
||||
var/obj/item/wepon = null
|
||||
|
||||
var/shatter_message = "The pylon shatters!"
|
||||
var/impact_sound = 'sound/effects/Glasshit.ogg'
|
||||
var/shatter_sound = 'sound/effects/Glassbr3.ogg'
|
||||
|
||||
var/activation_cooldown = 30 SECONDS
|
||||
var/last_activation = 0
|
||||
|
||||
/obj/structure/cult/pylon/Initialize()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/structure/cult/pylon/attack_hand(mob/M as mob)
|
||||
attackpylon(M, 5)
|
||||
|
||||
@@ -44,47 +55,58 @@
|
||||
/obj/structure/cult/pylon/proc/pylonhit(var/damage)
|
||||
if(!isbroken)
|
||||
if(prob(1+ damage * 5))
|
||||
visible_message("<span class='danger'>The pylon shatters!</span>")
|
||||
playsound(get_turf(src), 'sound/effects/Glassbr3.ogg', 75, 1)
|
||||
visible_message("<span class='danger'>[shatter_message]</span>")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
playsound(get_turf(src),shatter_sound, 75, 1)
|
||||
isbroken = 1
|
||||
density = 0
|
||||
icon_state = "pylon-broken"
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
set_light(0)
|
||||
|
||||
/obj/structure/cult/pylon/proc/attackpylon(mob/user as mob, var/damage)
|
||||
if(!isbroken)
|
||||
if(prob(1+ damage * 5))
|
||||
user.visible_message(
|
||||
"<span class='danger'>[user] smashed the pylon!</span>",
|
||||
"<span class='warning'>You hit the pylon, and its crystal breaks apart!</span>",
|
||||
"You hear a tinkle of crystal shards"
|
||||
"<span class='danger'>[user] smashed \the [src]!</span>",
|
||||
"<span class='warning'>You hit \the [src], and its crystal breaks apart!</span>",
|
||||
"You hear a tinkle of crystal shards."
|
||||
)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
user.do_attack_animation(src)
|
||||
playsound(get_turf(src), 'sound/effects/Glassbr3.ogg', 75, 1)
|
||||
playsound(get_turf(src),shatter_sound, 75, 1)
|
||||
isbroken = 1
|
||||
density = 0
|
||||
icon_state = "pylon-broken"
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
set_light(0)
|
||||
else
|
||||
user << "You hit the pylon!"
|
||||
playsound(get_turf(src), 'sound/effects/Glasshit.ogg', 75, 1)
|
||||
user << "You hit \the [src]!"
|
||||
playsound(get_turf(src),impact_sound, 75, 1)
|
||||
else
|
||||
if(prob(damage * 2))
|
||||
user << "You pulverize what was left of the pylon!"
|
||||
user << "You pulverize what was left of \the [src]!"
|
||||
qdel(src)
|
||||
else
|
||||
user << "You hit the pylon!"
|
||||
playsound(get_turf(src), 'sound/effects/Glasshit.ogg', 75, 1)
|
||||
|
||||
user << "You hit \the [src]!"
|
||||
playsound(get_turf(src),impact_sound, 75, 1)
|
||||
|
||||
/obj/structure/cult/pylon/proc/repair(mob/user as mob)
|
||||
if(isbroken)
|
||||
user << "You repair the pylon."
|
||||
START_PROCESSING(SSobj, src)
|
||||
user << "You repair \the [src]."
|
||||
isbroken = 0
|
||||
density = 1
|
||||
icon_state = "pylon"
|
||||
icon_state = initial(icon_state)
|
||||
set_light(5)
|
||||
|
||||
// Returns 1 if the pylon does something special.
|
||||
/obj/structure/cult/pylon/proc/pylon_unique()
|
||||
last_activation = world.time
|
||||
return 0
|
||||
|
||||
/obj/structure/cult/pylon/process()
|
||||
if(!isbroken && (last_activation < world.time + activation_cooldown) && pylon_unique())
|
||||
flick("[initial(icon_state)]-surge",src)
|
||||
|
||||
/obj/structure/cult/tome
|
||||
name = "Desk"
|
||||
desc = "A desk covered in arcane manuscripts and tomes in unknown languages. Looking at the text makes your skin crawl."
|
||||
|
||||
@@ -425,7 +425,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
|
||||
for (var/mob/living/silicon/robot/robo in mob_list)
|
||||
|
||||
if(istype(robo,/mob/living/silicon/robot/drone))
|
||||
if(istype(robo,/mob/living/silicon/robot/drone) && !istype(robo,/mob/living/silicon/robot/drone/swarm))
|
||||
dronecount++
|
||||
continue
|
||||
|
||||
|
||||
@@ -12,14 +12,16 @@
|
||||
name = "rolled-up poster"
|
||||
desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface."
|
||||
icon_state = "rolled_poster"
|
||||
var/serial_number = 0
|
||||
var/serial_number = null
|
||||
|
||||
var/poster_type = /obj/structure/sign/poster
|
||||
|
||||
/obj/item/weapon/contraband/poster/New(turf/loc, var/given_serial = 0)
|
||||
if(given_serial == 0)
|
||||
serial_number = rand(1, poster_designs.len)
|
||||
else
|
||||
serial_number = given_serial
|
||||
if(!serial_number)
|
||||
if(given_serial == 0)
|
||||
serial_number = rand(1, poster_designs.len)
|
||||
else
|
||||
serial_number = given_serial
|
||||
name += " - No. [serial_number]"
|
||||
..(loc)
|
||||
|
||||
@@ -57,7 +59,7 @@
|
||||
|
||||
user << "<span class='notice'>You start placing the poster on the wall...</span>" //Looks like it's uncluttered enough. Place the poster.
|
||||
|
||||
var/obj/structure/sign/poster/P = new(user.loc, placement_dir=get_dir(user, W), serial=serial_number)
|
||||
var/obj/structure/sign/poster/P = new poster_type(user.loc, placement_dir=get_dir(user, W), serial=serial_number, itemtype = src.type)
|
||||
|
||||
flick("poster_being_set", P)
|
||||
//playsound(W, 'sound/items/poster_being_created.ogg', 100, 1) //why the hell does placing a poster make printer sounds?
|
||||
@@ -74,6 +76,18 @@
|
||||
|
||||
qdel(oldsrc) //delete it now to cut down on sanity checks afterwards. Agouri's code supports rerolling it anyway
|
||||
|
||||
//NT subtype
|
||||
/obj/item/weapon/contraband/poster/nanotrasen
|
||||
icon_state = "rolled_poster_nt"
|
||||
poster_type = /obj/structure/sign/poster/nanotrasen
|
||||
|
||||
/obj/item/weapon/contraband/poster/nanotrasen/New(turf/loc, var/given_serial = 0)
|
||||
if(given_serial == 0)
|
||||
serial_number = rand(1, NT_poster_designs.len)
|
||||
else
|
||||
serial_number = given_serial
|
||||
..(loc)
|
||||
|
||||
//############################## THE ACTUAL DECALS ###########################
|
||||
|
||||
/obj/structure/sign/poster
|
||||
@@ -85,15 +99,22 @@
|
||||
var/poster_type //So mappers can specify a desired poster
|
||||
var/ruined = 0
|
||||
|
||||
/obj/structure/sign/poster/New(var/newloc, var/placement_dir=null, var/serial=null)
|
||||
var/roll_type
|
||||
var/poster_set = FALSE
|
||||
|
||||
/obj/structure/sign/poster/New(var/newloc, var/placement_dir=null, var/serial=null, var/itemtype = /obj/item/weapon/contraband/poster)
|
||||
..(newloc)
|
||||
|
||||
if(!serial)
|
||||
serial = rand(1, poster_designs.len) //use a random serial if none is given
|
||||
|
||||
serial_number = serial
|
||||
var/datum/poster/design = poster_designs[serial_number]
|
||||
set_poster(design)
|
||||
if(!poster_set)
|
||||
serial_number = serial
|
||||
var/datum/poster/design = poster_designs[serial_number]
|
||||
set_poster(design)
|
||||
|
||||
if(itemtype || !roll_type)
|
||||
roll_type = itemtype
|
||||
|
||||
switch (placement_dir)
|
||||
if (NORTH)
|
||||
@@ -121,6 +142,8 @@
|
||||
desc = "[initial(desc)] [design.desc]"
|
||||
icon_state = design.icon_state // poster[serial_number]
|
||||
|
||||
poster_set = TRUE
|
||||
|
||||
/obj/structure/sign/poster/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(W.is_wirecutter())
|
||||
playsound(src.loc, W.usesound, 100, 1)
|
||||
@@ -132,7 +155,6 @@
|
||||
roll_and_drop(user.loc)
|
||||
return
|
||||
|
||||
|
||||
/obj/structure/sign/poster/attack_hand(mob/user as mob)
|
||||
|
||||
if(ruined)
|
||||
@@ -152,7 +174,7 @@
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/structure/sign/poster/proc/roll_and_drop(turf/newloc)
|
||||
var/obj/item/weapon/contraband/poster/P = new(src, serial_number)
|
||||
var/obj/item/weapon/contraband/poster/P = new roll_type(src, serial_number)
|
||||
P.loc = newloc
|
||||
src.loc = P
|
||||
qdel(src)
|
||||
@@ -163,3 +185,17 @@
|
||||
// Description suffix
|
||||
var/desc=""
|
||||
var/icon_state=""
|
||||
|
||||
// NT poster subtype.
|
||||
/obj/structure/sign/poster/nanotrasen
|
||||
roll_type = /obj/item/weapon/contraband/poster/nanotrasen
|
||||
|
||||
/obj/structure/sign/poster/nanotrasen/New(var/newloc, var/placement_dir=null, var/serial=null, var/itemtype = /obj/item/weapon/contraband/poster/nanotrasen)
|
||||
if(!serial)
|
||||
serial = rand(1, NT_poster_designs.len)
|
||||
|
||||
serial_number = serial
|
||||
var/datum/poster/design = NT_poster_designs[serial_number]
|
||||
set_poster(design)
|
||||
|
||||
..(newloc, placement_dir, serial, itemtype)
|
||||
|
||||
@@ -43,4 +43,171 @@
|
||||
name = "Airlock Maintenance Reference"
|
||||
desc = "This poster appears to be reference material for maintenance personnel, instructing to always wear insulated gloves, that wirecutters and \
|
||||
a multitool are the optimal tools to use, and where to find the maintenance panel on most airlocks. Unfortunately, the poster does not mention any \
|
||||
wire codes."
|
||||
wire codes."
|
||||
|
||||
/datum/poster/pol_10
|
||||
icon_state="polposter9"
|
||||
name = "orchid"
|
||||
desc = "This poster appears strangely familiar, depicting the flower of a tree native to the planet Earth."
|
||||
|
||||
// A new subset of poster datum for Security posters.
|
||||
/datum/poster/nanotrasen
|
||||
icon_state = "polposter1"
|
||||
name = "Safety!"
|
||||
desc = "A poster advising you to learn how to put on your internals at a moment's notice."
|
||||
|
||||
/datum/poster/nanotrasen/pol_2
|
||||
icon_state="polposter2"
|
||||
name = "Safety!"
|
||||
desc = "A blue and white colored poster. This one advises you to wear your safety goggles when handling chemicals."
|
||||
|
||||
/datum/poster/nanotrasen/pol_3
|
||||
icon_state="polposter3"
|
||||
name = "Safety!"
|
||||
desc = "A safety poster instructing you to comply with the authorities, especially in an emergency."
|
||||
|
||||
/datum/poster/nanotrasen/pol_4
|
||||
icon_state="polposter4"
|
||||
name = "Clean Hands Save Lives"
|
||||
desc = "A safety poster reminding you to wash your hands."
|
||||
|
||||
/datum/poster/nanotrasen/pol_5
|
||||
icon_state="polposter5"
|
||||
name = "Help!"
|
||||
desc = "This poster depicts a man helping another man get up."
|
||||
|
||||
/datum/poster/nanotrasen/pol_6
|
||||
icon_state="polposter6"
|
||||
name = "Walk!"
|
||||
desc = "This poster depicts a man walking, presumably to encourage you not to run in the halls."
|
||||
|
||||
/datum/poster/nanotrasen/pol_7
|
||||
icon_state="polposter7"
|
||||
name = "Place your signs!"
|
||||
desc = "A safety poster reminding custodial staff to place wet floor signs where needed. This reminder's rarely heeded."
|
||||
|
||||
/datum/poster/nanotrasen/pol_8
|
||||
icon_state="polposter8"
|
||||
name = "Safety!"
|
||||
desc = "An advertisement / safety poster for EVA training and certification. Training is available at your local Central Command."
|
||||
|
||||
/datum/poster/nanotrasen/pol_9
|
||||
icon_state="poster10"
|
||||
name = "Airlock Maintenance Reference"
|
||||
desc = "This poster appears to be reference material for maintenance personnel, instructing to always wear insulated gloves, that wirecutters and \
|
||||
a multitool are the optimal tools to use, and where to find the maintenance panel on most airlocks. Unfortunately, the poster does not mention any \
|
||||
wire codes."
|
||||
|
||||
/datum/poster/nanotrasen/pol_10
|
||||
icon_state="polposter9"
|
||||
name = "orchid"
|
||||
desc = "This poster suggests a feeling of peace. It depicts the flower of a tree native to the planet Earth."
|
||||
|
||||
/datum/poster/nanotrasen/bay_9
|
||||
icon_state="bsposter9"
|
||||
name = "Pinup Girl Amy"
|
||||
desc = "This particular one is of Amy, the nymphomaniac urban legend of deep space. How this photograph came to be is not known."
|
||||
|
||||
/datum/poster/nanotrasen/bay_21
|
||||
icon_state="bsposter21"
|
||||
name = "Join the Fuzz!"
|
||||
desc = "It's a nice recruitment poster of a white haired Chinese woman that says; \"Big Guns, Hot Women, Good Times. Security. We get it done.\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_22
|
||||
icon_state="bsposter22"
|
||||
name = "Looking for a career with excitement?"
|
||||
desc = "A recruitment poster starring a dark haired woman with glasses and a purple shirt that has \"Got Brains? Got Talent? Not afraid of electric flying monsters that want to suck the soul out of you? Then Xenobiology could use someone like you!\" written on the bottom."
|
||||
|
||||
/datum/poster/nanotrasen/bay_23
|
||||
icon_state="bsposter23"
|
||||
name = "Safety first: because electricity doesn't wait!"
|
||||
desc = "A safety poster starring a clueless looking redhead with frazzled hair. \"Every year, hundreds of NT employees expose themselves to electric shock. Play it safe. Avoid suspicious doors after electrical storms, and always wear protection when doing electric maintenance.\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_24
|
||||
icon_state="bsposter24"
|
||||
name = "Responsible medbay habits, No #259"
|
||||
desc = "A poster with a nervous looking geneticist on it states; \"Friends Tell Friends They're Clones. It can cause severe and irreparable emotional trauma if a person is not properly informed of their recent demise. Always follow your contractual obligation and inform them of their recent rejuvenation.\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_25
|
||||
icon_state="bsposter25"
|
||||
name = "Irresponsible medbay habits, No #2"
|
||||
desc = "This is a safety poster starring a perverted looking naked doctor. \"Sexual harassment is never okay. REPORT any acts of sexual deviance or harassment that disrupt a healthy working environment.\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_49
|
||||
icon_state="bsposter49"
|
||||
name = "Engineering recruitment"
|
||||
desc = "This is a poster showing an engineer relaxing by a computer, the text states \"Living the life! Join Engineering today!\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_52
|
||||
icon_state="bsposter52"
|
||||
name = "fire safety poster"
|
||||
desc = "This is a poster reminding you of what you should do if you are on fire, or if you are at a dance party."
|
||||
|
||||
/datum/poster/nanotrasen/bay_53
|
||||
icon_state="bsposter53"
|
||||
name = "fire extinguisher poster"
|
||||
desc = "This is a poster reminding you of what you should use to put out a fire."
|
||||
|
||||
/datum/poster/nanotrasen/bay_54
|
||||
icon_state="bsposter54"
|
||||
name = "firefighter poster"
|
||||
desc = "This is a poster of a particularly stern looking firefighter. The caption reads, \"Only you can prevent space fires.\""
|
||||
|
||||
/datum/poster/nanotrasen/bay_57
|
||||
icon_state="bsposter57"
|
||||
name = "space carp warning poster"
|
||||
desc = "This poster tells of the dangers of space carp infestations."
|
||||
|
||||
/datum/poster/nanotrasen/bay_58
|
||||
icon_state="bsposter58"
|
||||
name = "space carp information poster"
|
||||
desc = "This poster showcases an old spacer saying on the dangers of migrant space carp."
|
||||
|
||||
/datum/poster/nanotrasen/nt_1
|
||||
icon_state = "ntposter01"
|
||||
name = "Security recruitment"
|
||||
desc = "This poster showcases an NT security guard in an excited pose, with a small blurb about the importance of Security."
|
||||
|
||||
/datum/poster/nanotrasen/nt_2
|
||||
icon_state = "ntposter02"
|
||||
name = "Security recruitment"
|
||||
desc = "This poster showcases an NT security guard in an excited pose, with a small blurb about Security Employee benefits."
|
||||
|
||||
/datum/poster/nanotrasen/nt_3
|
||||
icon_state = "ntposter03"
|
||||
name = "Mechatronic Safety"
|
||||
desc = "This poster displays three cutting-edge gygaxes standing in line in front of a man in plain clothes.\
|
||||
The poster's captions explain the importance of knowing how to operate a mechatronic vehicle safely, especially near other personnel.\
|
||||
The image seems important."
|
||||
|
||||
/datum/poster/nanotrasen/nt_4
|
||||
icon_state = "ntposter04"
|
||||
name = "Beware Aetotheans"
|
||||
desc = "This poster displays a distinctly hostile-looking red Promethean in a black coat. The fine-print around the edges warns the reader about the dangers posed by Almachi Prometheans."
|
||||
|
||||
/datum/poster/nanotrasen/nt_5
|
||||
icon_state = "ntposter05"
|
||||
name = "Promethean"
|
||||
desc = "This poster displays a friendly-looking green Promethean in a labcoat. The fine-print around the edges talks about the benefits Prometheans give in laboratories."
|
||||
|
||||
/datum/poster/nanotrasen/nt_6
|
||||
icon_state = "ntposter06"
|
||||
name = "NanoTrasen"
|
||||
desc = "This poster showcases an NT emblem. There is writing in the ring around the inner points, probably some sort of slogan no one bothers to memorize."
|
||||
|
||||
/datum/poster/nanotrasen/nt_7
|
||||
icon_state = "ntposter07"
|
||||
name = "SolGov"
|
||||
desc = "This poster showcases an SCG emblem. The outer ring reads,\
|
||||
\"<font face='times new roman ms'>NIL MORTALIBUS ARDUI EST</font>\".\
|
||||
Solar Confederate Government."
|
||||
|
||||
/datum/poster/nanotrasen/nt_8
|
||||
icon_state = "ntposter08"
|
||||
name = "wildlife hazard"
|
||||
desc = "This poster warns against attempting to kill a fully grown giant spider or other hostile life-form alone."
|
||||
|
||||
/datum/poster/nanotrasen/nt_9
|
||||
icon_state = "ntposter09"
|
||||
name = "Regulations and You"
|
||||
desc = "This poster showcases an NT security guard reading from her PDA. The blurb advocates for the reader to keep corporate regulations in mind at all times, as an emergency can occur at any time."
|
||||
|
||||
@@ -134,6 +134,8 @@
|
||||
var/travelling_in_vent = 0
|
||||
var/list/grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/nurse, /mob/living/simple_mob/animal/giant_spider/hunter)
|
||||
|
||||
var/stunted = FALSE
|
||||
|
||||
/obj/effect/spider/spiderling/frost
|
||||
grow_as = list(/mob/living/simple_mob/animal/giant_spider/frost)
|
||||
|
||||
@@ -261,9 +263,17 @@
|
||||
break
|
||||
if(amount_grown >= 100)
|
||||
var/spawn_type = pick(grow_as)
|
||||
new spawn_type(src.loc, src)
|
||||
var/mob/living/simple_mob/animal/giant_spider/GS = new spawn_type(src.loc, src)
|
||||
if(stunted)
|
||||
spawn(2)
|
||||
GS.make_spiderling()
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/spider/spiderling/stunted
|
||||
stunted = TRUE
|
||||
|
||||
grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/hunter)
|
||||
|
||||
/obj/effect/decal/cleanable/spiderling_remains
|
||||
name = "spiderling remains"
|
||||
desc = "Green squishy mess."
|
||||
|
||||
@@ -243,6 +243,13 @@
|
||||
electric_cost_coefficent = 41.66 // Twice as efficent, out of pity.
|
||||
toolspeed = 0.5 // Twice as fast, since borg versions typically have this.
|
||||
|
||||
/obj/item/weapon/rcd/electric/mounted/borg/swarm
|
||||
can_remove_rwalls = FALSE
|
||||
name = "Rapid Assimilation Device"
|
||||
ranged = TRUE
|
||||
toolspeed = 0.7
|
||||
material_to_use = MAT_STEELHULL
|
||||
|
||||
/obj/item/weapon/rcd/electric/mounted/borg/lesser
|
||||
can_remove_rwalls = FALSE
|
||||
|
||||
|
||||
@@ -197,6 +197,9 @@ var/last_chew = 0
|
||||
breakouttime = 200
|
||||
cuff_type = "duct tape"
|
||||
|
||||
/obj/item/weapon/handcuffs/cable/tape/cyborg
|
||||
dispenser = TRUE
|
||||
|
||||
//Legcuffs. Not /really/ handcuffs, but its close enough.
|
||||
/obj/item/weapon/handcuffs/legcuffs
|
||||
name = "legcuffs"
|
||||
|
||||
@@ -368,6 +368,13 @@
|
||||
target.taunt(user)
|
||||
target.adjustFireLoss(force * 6) // 30 Burn, for 50 total.
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/ionic_rapier/lance
|
||||
name = "zero-point lance"
|
||||
desc = "Designed specifically for disrupting electronics at relatively close range, however it is still capable of dealing some damage to living beings."
|
||||
active_force = 20
|
||||
armor_penetration = 15
|
||||
reach = 2
|
||||
|
||||
/*
|
||||
* Charge blade. Uses a cell, and costs energy per strike.
|
||||
*/
|
||||
|
||||
@@ -373,3 +373,17 @@
|
||||
max_w_class = ITEMSIZE_NORMAL
|
||||
w_class = ITEMSIZE_SMALL
|
||||
can_hold = list(/obj/item/weapon/reagent_containers/food/snacks,/obj/item/weapon/reagent_containers/food/condiment)
|
||||
|
||||
// -----------------------------
|
||||
// Evidence Bag
|
||||
// -----------------------------
|
||||
/obj/item/weapon/storage/bag/detective
|
||||
name = "secure satchel"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "detbag"
|
||||
desc = "A bag for storing investigation things. You know, securely."
|
||||
max_storage_space = ITEMSIZE_COST_NORMAL * 15
|
||||
max_w_class = ITEMSIZE_NORMAL
|
||||
w_class = ITEMSIZE_SMALL
|
||||
can_hold = list(/obj/item/weapon/forensics/swab,/obj/item/weapon/sample/print,/obj/item/weapon/sample/fibers,/obj/item/weapon/evidencebag)
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
/obj/item/weapon/storage/belt/security,
|
||||
/obj/item/device/flash,
|
||||
/obj/item/weapon/melee/baton/loaded,
|
||||
/obj/item/weapon/gun/energy/gun,
|
||||
/obj/item/weapon/gun/magnetic/railgun/heater/pistol/hos,
|
||||
/obj/item/weapon/cell/device/weapon,
|
||||
/obj/item/clothing/accessory/holster/waist,
|
||||
/obj/item/weapon/melee/telebaton,
|
||||
@@ -223,6 +223,8 @@
|
||||
starts_with += /obj/item/weapon/storage/backpack/satchel/sec
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack/dufflebag/sec
|
||||
if(prob(30))
|
||||
starts_with += /obj/item/weapon/contraband/poster/nanotrasen
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/security/cargo/Initialize()
|
||||
@@ -271,6 +273,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/drinks/flask/detflask,
|
||||
/obj/item/weapon/storage/briefcase/crimekit,
|
||||
/obj/item/device/taperecorder,
|
||||
/obj/item/weapon/storage/bag/detective,
|
||||
/obj/item/device/tape/random = 3)
|
||||
|
||||
/obj/structure/closet/secure_closet/detective/update_icon()
|
||||
@@ -305,6 +308,17 @@ GLOBAL_LIST_BOILERPLATE(all_brig_closets, /obj/structure/closet/secure_closet/br
|
||||
/obj/item/clothing/under/color/prison,
|
||||
/obj/item/clothing/shoes/orange)
|
||||
|
||||
/obj/structure/closet/secure_closet/posters
|
||||
name = "morale storage"
|
||||
req_access = list(access_security)
|
||||
anchored = 1
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/weapon/contraband/poster/nanotrasen,
|
||||
/obj/item/weapon/contraband/poster/nanotrasen,
|
||||
/obj/item/weapon/contraband/poster/nanotrasen,
|
||||
/obj/item/weapon/contraband/poster/nanotrasen,
|
||||
/obj/item/weapon/contraband/poster/nanotrasen)
|
||||
|
||||
/obj/structure/closet/secure_closet/courtroom
|
||||
name = "courtroom locker"
|
||||
|
||||
@@ -83,4 +83,13 @@
|
||||
to_chat(user, "<span class='warning'>Another spirit appears to have gotten to \the [src] before you. Sorry.</span>")
|
||||
return
|
||||
|
||||
create_occupant(user)
|
||||
var/choice = input(user, "Are you certain you wish to activate this pod?", "Control Pod") as null|anything in list("Yes", "No")
|
||||
|
||||
if(!choice || choice == "No")
|
||||
return
|
||||
|
||||
else if(used)
|
||||
to_chat(user, "<span class='warning'>Another spirit appears to have gotten to \the [src] before you. Sorry.</span>")
|
||||
return
|
||||
|
||||
create_occupant(user)
|
||||
|
||||
246
code/game/objects/structures/ghost_pods/human.dm
Normal file
@@ -0,0 +1,246 @@
|
||||
// Ghost variant.
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/human
|
||||
name = "mysterious cryopod"
|
||||
desc = "This is a pod which appears to contain a body."
|
||||
description_info = "This contains a body, which may wake at any time. The external controls\
|
||||
seem to be malfunctioning."
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper_1"
|
||||
icon_state_opened = "sleeper_0"
|
||||
density = TRUE
|
||||
ghost_query_type = /datum/ghost_query/stowaway
|
||||
anchored = FALSE
|
||||
|
||||
var/occupant_type = "stowaway"
|
||||
|
||||
var/allow_appearance_change = TRUE
|
||||
|
||||
var/make_antag = MODE_STOWAWAY
|
||||
|
||||
var/start_injured = FALSE
|
||||
var/spawn_with_emag = TRUE
|
||||
|
||||
var/list/clothing_possibilities
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/human/Initialize()
|
||||
..()
|
||||
|
||||
handle_clothing_setup()
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/human/proc/handle_clothing_setup()
|
||||
clothing_possibilities = list()
|
||||
|
||||
clothing_possibilities |= subtypesof(/obj/item/clothing/under/color)
|
||||
clothing_possibilities |= subtypesof(/obj/item/clothing/head/soft)
|
||||
clothing_possibilities |= /obj/item/clothing/shoes/black
|
||||
clothing_possibilities |= /obj/item/device/radio/headset
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/human/create_occupant(var/mob/M)
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/mob/living/carbon/human/H = new(src)
|
||||
|
||||
H.adjustCloneLoss(rand(1,5))
|
||||
if(M.mind)
|
||||
M.mind.transfer_to(H)
|
||||
to_chat(M, "<span class='notice'>You are a [occupant_type]!</span>")
|
||||
if(make_antag)
|
||||
to_chat(M, "<span class='warning'>Your intent may not be completely beneficial.</span>")
|
||||
H.ckey = M.ckey
|
||||
visible_message("<span class='warning'>As \the [src] opens, the pipes on \the [src] surge, before it grows dark.</span>")
|
||||
log_and_message_admins("successfully opened \a [src] and became a [occupant_type].")
|
||||
|
||||
var/list/uniform_options
|
||||
var/list/shoe_options
|
||||
var/list/head_options
|
||||
var/list/headset_options
|
||||
|
||||
if(clothing_possibilities && clothing_possibilities.len)
|
||||
for(var/path in clothing_possibilities)
|
||||
if(ispath(path, /obj/item/clothing/under))
|
||||
if(!uniform_options)
|
||||
uniform_options = list()
|
||||
uniform_options |= path
|
||||
if(ispath(path, /obj/item/clothing/shoes))
|
||||
if(!shoe_options)
|
||||
shoe_options = list()
|
||||
shoe_options |= path
|
||||
if(ispath(path, /obj/item/clothing/head))
|
||||
if(!head_options)
|
||||
head_options = list()
|
||||
head_options |= path
|
||||
if(ispath(path, /obj/item/device/radio/headset))
|
||||
if(!headset_options)
|
||||
headset_options = list()
|
||||
headset_options |= path
|
||||
|
||||
if(uniform_options && uniform_options.len)
|
||||
var/newpath = pick(uniform_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(shoe_options && shoe_options.len)
|
||||
var/newpath = pick(shoe_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(head_options && head_options.len)
|
||||
var/newpath = pick(head_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(headset_options && headset_options.len)
|
||||
var/newpath = pick(headset_options)
|
||||
var/obj/item/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(spawn_with_emag)
|
||||
var/obj/item/weapon/card/emag/E = new(H)
|
||||
E.name = "broken card"
|
||||
E.description_antag = "This is a 'disguised' emag, to make your escape from wherever you happen to be trapped."
|
||||
H.equip_to_appropriate_slot(E)
|
||||
|
||||
var/newname = sanitize(input(H, "Your mind feels foggy, and you recall your name might be [H.real_name]. Would you like to change your name?", "Name change") as null|text, MAX_NAME_LEN)
|
||||
if (newname)
|
||||
H.real_name = newname
|
||||
|
||||
icon_state = icon_state_opened
|
||||
|
||||
H.forceMove(T)
|
||||
|
||||
if(make_antag)
|
||||
var/datum/antagonist/antag = all_antag_types[make_antag]
|
||||
if(antag)
|
||||
if(antag.add_antagonist(H.mind, 1, 1, 0, 1, 1))
|
||||
log_admin("\The [src] made [key_name(src)] into a [antag.role_text].")
|
||||
|
||||
if(start_injured) // Done 3 different times to disperse damage.
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
|
||||
if(allow_appearance_change)
|
||||
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
|
||||
|
||||
visible_message("<span class='aliem'>\The [src] [pick("gurgles", "seizes", "clangs")] before releasing \the [H]!</span>")
|
||||
|
||||
// Manual Variant
|
||||
// This one lacks the emag option due to the fact someone has to activate it, and they will probably help the person.
|
||||
/obj/structure/ghost_pod/manual/human
|
||||
name = "mysterious cryopod"
|
||||
desc = "This is a pod which appears to contain a body."
|
||||
description_info = "This contains a body, which may wake at any time. The external controls\
|
||||
seem to be functioning, though the warning lights that flash give no solace.."
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper_1"
|
||||
icon_state_opened = "sleeper_0"
|
||||
density = TRUE
|
||||
ghost_query_type = /datum/ghost_query/lost_passenger
|
||||
anchored = FALSE
|
||||
|
||||
var/occupant_type = "lost passenger"
|
||||
|
||||
var/allow_appearance_change = TRUE
|
||||
|
||||
var/make_antag = MODE_STOWAWAY
|
||||
|
||||
var/start_injured = TRUE
|
||||
|
||||
var/list/clothing_possibilities
|
||||
|
||||
/obj/structure/ghost_pod/manual/human/Initialize()
|
||||
..()
|
||||
|
||||
handle_clothing_setup()
|
||||
|
||||
/obj/structure/ghost_pod/manual/human/proc/handle_clothing_setup()
|
||||
clothing_possibilities = list()
|
||||
|
||||
clothing_possibilities |= subtypesof(/obj/item/clothing/under/utility)
|
||||
clothing_possibilities |= subtypesof(/obj/item/clothing/head/beret)
|
||||
clothing_possibilities |= /obj/item/clothing/shoes/black
|
||||
clothing_possibilities |= /obj/item/device/radio/headset
|
||||
|
||||
/obj/structure/ghost_pod/manual/human/create_occupant(var/mob/M)
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/mob/living/carbon/human/H = new(src)
|
||||
|
||||
H.adjustCloneLoss(rand(1,5))
|
||||
if(M.mind)
|
||||
M.mind.transfer_to(H)
|
||||
to_chat(M, "<span class='notice'>You are a [occupant_type]!</span>")
|
||||
if(make_antag)
|
||||
to_chat(M, "<span class='warning'>Your intent may not be completely beneficial.</span>")
|
||||
H.ckey = M.ckey
|
||||
visible_message("<span class='warning'>As \the [src] opens, the pipes on \the [src] surge, before it grows dark.</span>")
|
||||
log_and_message_admins("successfully opened \a [src] and got a [occupant_type].")
|
||||
|
||||
var/list/uniform_options
|
||||
var/list/shoe_options
|
||||
var/list/head_options
|
||||
var/list/headset_options
|
||||
|
||||
if(clothing_possibilities && clothing_possibilities.len)
|
||||
for(var/path in clothing_possibilities)
|
||||
if(ispath(path, /obj/item/clothing/under))
|
||||
if(!uniform_options)
|
||||
uniform_options = list()
|
||||
uniform_options |= path
|
||||
if(ispath(path, /obj/item/clothing/shoes))
|
||||
if(!shoe_options)
|
||||
shoe_options = list()
|
||||
shoe_options |= path
|
||||
if(ispath(path, /obj/item/clothing/head))
|
||||
if(!head_options)
|
||||
head_options = list()
|
||||
head_options |= path
|
||||
if(ispath(path, /obj/item/device/radio/headset))
|
||||
if(!headset_options)
|
||||
headset_options = list()
|
||||
headset_options |= path
|
||||
|
||||
if(uniform_options && uniform_options.len)
|
||||
var/newpath = pick(uniform_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(shoe_options && shoe_options.len)
|
||||
var/newpath = pick(shoe_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(head_options && head_options.len)
|
||||
var/newpath = pick(head_options)
|
||||
var/obj/item/clothing/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
if(headset_options && headset_options.len)
|
||||
var/newpath = pick(headset_options)
|
||||
var/obj/item/C = new newpath(H)
|
||||
H.equip_to_appropriate_slot(C)
|
||||
|
||||
var/newname = sanitize(input(H, "Your mind feels foggy, and you recall your name might be [H.real_name]. Would you like to change your name?", "Name change") as null|text, MAX_NAME_LEN)
|
||||
if (newname)
|
||||
H.real_name = newname
|
||||
|
||||
icon_state = icon_state_opened
|
||||
|
||||
H.forceMove(T)
|
||||
|
||||
if(make_antag)
|
||||
var/datum/antagonist/antag = all_antag_types[make_antag]
|
||||
if(antag)
|
||||
if(antag.add_antagonist(H.mind, 1, 1, 0, 1, 1))
|
||||
log_admin("\The [src] made [key_name(src)] into a [antag.role_text].")
|
||||
|
||||
if(start_injured) // Done 3 different times to disperse damage.
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
H.adjustBruteLoss(rand(1,20))
|
||||
|
||||
if(allow_appearance_change)
|
||||
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
|
||||
|
||||
visible_message("<span class='aliem'>\The [src] [pick("gurgles", "seizes", "clangs")] before releasing \the [H]!</span>")
|
||||
@@ -58,4 +58,50 @@
|
||||
R.ckey = M.ckey
|
||||
visible_message("<span class='warning'>As \the [src] opens, the eyes of the robot flicker as it is activated.</span>")
|
||||
R.Namepick()
|
||||
..()
|
||||
..()
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/swarm_drone
|
||||
name = "drone shell"
|
||||
desc = "A heavy metallic ball."
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "swarmer_unactivated"
|
||||
density = FALSE
|
||||
anchored = FALSE
|
||||
|
||||
var/drone_class = "general"
|
||||
var/drone_type = /mob/living/silicon/robot/drone/swarm
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/swarm_drone/create_occupant(var/mob/M)
|
||||
var/mob/living/silicon/robot/drone/swarm/R = new drone_type(get_turf(src))
|
||||
if(M.mind)
|
||||
M.mind.transfer_to(R)
|
||||
to_chat(M, "<span class='cult'>You are <b>[R]</b>, the remnant of some distant species, mechanical or flesh, living or dead.</span>")
|
||||
R.ckey = M.ckey
|
||||
visible_message("<span class='cult'>As \the [src] shudders, it glows before lifting itself with three shimmering limbs!</span>")
|
||||
spawn(3 SECONDS)
|
||||
to_chat(R,"<span class='notice'>Many of your tools are standard drone devices, however others provide you with particular benefits.</span>")
|
||||
to_chat(R,"<span class='notice'>Unlike standard drones, you are capable of utilizing 'zero point wells', found in your 'spells' tab.</span>")
|
||||
to_chat(R,"<span class='notice'>Here you will also find your replication ability(s), depending on the type of drone you are.</span>")
|
||||
to_chat(R,"<span class='notice'>Gunners have a special anti-personnel gun capable of shocking or punching through armor with low damage.</span>")
|
||||
to_chat(R,"<span class='notice'>Impalers have an energy-lance.</span>")
|
||||
to_chat(R,"<span class='notice'>General drones have the unique ability to produce one of each of these two types of shells per generation.</span>")
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/Initialize()
|
||||
..()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
say_dead_object("A <span class='notice'>[drone_class] swarm drone</span> shell is now available in \the [T.loc].", src)
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/gunner
|
||||
name = "gunner shell"
|
||||
|
||||
drone_class = "gunner"
|
||||
drone_type = /mob/living/silicon/robot/drone/swarm/gunner
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/melee
|
||||
name = "impaler shell"
|
||||
|
||||
drone_class = "impaler"
|
||||
drone_type = /mob/living/silicon/robot/drone/swarm/melee
|
||||
|
||||
150
code/game/objects/structures/props/swarm.dm
Normal file
@@ -0,0 +1,150 @@
|
||||
/obj/structure/cult/pylon/swarm
|
||||
name = "Swarm Construct"
|
||||
desc = "A small pod."
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "pod"
|
||||
light_color = "#00B2B2"
|
||||
|
||||
shatter_message = "The energetic field shatters!"
|
||||
impact_sound = 'sound/effects/Glasshit.ogg'
|
||||
shatter_sound = 'sound/effects/phasein.ogg'
|
||||
|
||||
var/list/active_beams
|
||||
|
||||
/obj/structure/cult/pylon/swarm/CanPass(atom/movable/mover, turf/target)
|
||||
if(istype(mover, /mob/living))
|
||||
var/mob/living/L = mover
|
||||
if(L.faction == "swarmer")
|
||||
return TRUE
|
||||
else if(istype(mover, /obj/item/projectile))
|
||||
var/obj/item/projectile/P = mover
|
||||
if(istype(P.firer) && P.firer.faction == "swarmer")
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/structure/cult/pylon/swarm/Initialize()
|
||||
..()
|
||||
active_beams = list()
|
||||
|
||||
/obj/structure/cult/pylon/swarm/Destroy()
|
||||
for(var/datum/beam/B in active_beams)
|
||||
QDEL_NULL(B)
|
||||
active_beams = null
|
||||
..()
|
||||
|
||||
/obj/structure/cult/pylon/swarm/pylonhit(var/damage)
|
||||
if(!isbroken)
|
||||
if(prob(1 + damage * 3))
|
||||
visible_message("<span class='danger'>[shatter_message]</span>")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
playsound(get_turf(src),shatter_sound, 75, 1)
|
||||
isbroken = 1
|
||||
density = 0
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
set_light(0)
|
||||
|
||||
/obj/structure/cult/pylon/swarm/attackpylon(mob/user as mob, var/damage)
|
||||
if(!isbroken)
|
||||
if(prob(1 + damage * 3))
|
||||
user.visible_message(
|
||||
"<span class='danger'>[user] smashed \the [src]!</span>",
|
||||
"<span class='warning'>You hit \the [src], and its crystal breaks apart!</span>",
|
||||
"You hear a tinkle of crystalline shards."
|
||||
)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
user.do_attack_animation(src)
|
||||
playsound(get_turf(src),shatter_sound, 75, 1)
|
||||
isbroken = 1
|
||||
density = 0
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
set_light(0)
|
||||
else
|
||||
to_chat(user, "You hit \the [src]!")
|
||||
playsound(get_turf(src),impact_sound, 75, 1)
|
||||
else
|
||||
if(prob(damage * 2))
|
||||
to_chat(user, "You pulverize what was left of \the [src]!")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "You hit \the [src]!")
|
||||
playsound(get_turf(src),impact_sound, 75, 1)
|
||||
|
||||
/obj/structure/cult/pylon/swarm/pylon_unique()
|
||||
. = ..()
|
||||
|
||||
return .
|
||||
|
||||
/obj/structure/cult/pylon/swarm/zp_well
|
||||
name = "Zero Point Well"
|
||||
desc = "Infinite cosmic power, itty bitty usability."
|
||||
|
||||
icon_state = "trap"
|
||||
|
||||
description_info = "An infinitely small point in space that may or may not be used to supply power to some form of advanced machine."
|
||||
|
||||
activation_cooldown = 0 // These things run constantly.
|
||||
|
||||
/obj/structure/cult/pylon/swarm/zp_well/pylon_unique()
|
||||
. = ..()
|
||||
|
||||
for(var/mob/living/silicon/robot/drone/swarm/S in view(3, src))
|
||||
var/has_beam = FALSE
|
||||
for(var/datum/beam/B in active_beams)
|
||||
if(B.target == S)
|
||||
has_beam = TRUE
|
||||
break
|
||||
|
||||
if(!has_beam)
|
||||
active_beams |= Beam(S,icon='icons/effects/beam.dmi',icon_state="holo_beam",time=3 SECONDS,maxdistance=3,beam_type = /obj/effect/ebeam,beam_sleep_time=2)
|
||||
|
||||
if(S.cell)
|
||||
S.cell.give(rand(5, 30))
|
||||
|
||||
. = TRUE
|
||||
|
||||
return .
|
||||
|
||||
/obj/structure/cult/pylon/swarm/defender
|
||||
name = "Zero Point Wall"
|
||||
desc = "Infinite cosmic power, itty bitty passability."
|
||||
|
||||
icon_state = "barricade"
|
||||
|
||||
description_info = "An infinitely small point in space spread upon infinitely many finitely-bounded points in space. Nice."
|
||||
|
||||
/obj/structure/cult/pylon/swarm/defender/pylonhit(var/damage)
|
||||
if(!isbroken)
|
||||
if(prob(1 + damage * 3) && round(damage * 0.8) >= 30)
|
||||
visible_message("<span class='danger'>[shatter_message]</span>")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
playsound(get_turf(src),shatter_sound, 75, 1)
|
||||
isbroken = 1
|
||||
density = 0
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
set_light(0)
|
||||
|
||||
/obj/structure/cult/pylon/swarm/defender/attackpylon(mob/user as mob, var/damage)
|
||||
if(!isbroken)
|
||||
if(prob(1 + damage * 3) && round(damage * 0.8) >= 25)
|
||||
user.visible_message(
|
||||
"<span class='danger'>[user] smashed \the [src]!</span>",
|
||||
"<span class='warning'>You hit \the [src], and its crystal breaks apart!</span>",
|
||||
"You hear a tinkle of crystalline shards."
|
||||
)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
user.do_attack_animation(src)
|
||||
playsound(get_turf(src),shatter_sound, 75, 1)
|
||||
isbroken = 1
|
||||
density = 0
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
set_light(0)
|
||||
else
|
||||
to_chat(user, "You hit \the [src]!")
|
||||
playsound(get_turf(src),impact_sound, 75, 1)
|
||||
else
|
||||
if(prob(damage * 2))
|
||||
to_chat(user, "You pulverize what was left of \the [src]!")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "You hit \the [src]!")
|
||||
playsound(get_turf(src),impact_sound, 75, 1)
|
||||
@@ -80,6 +80,16 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
|
||||
. = ..()
|
||||
if((. == 0) && LAZYLEN(accessories))
|
||||
for(var/obj/item/I in accessories)
|
||||
var/check = I.handle_shield(user, damage, damage_source, attacker, def_zone, attack_text)
|
||||
|
||||
if(check != 0) // Projectiles sometimes use negatives IIRC, 0 is only returned if something is not blocked.
|
||||
. = check
|
||||
break
|
||||
|
||||
/obj/item/clothing/proc/refit_for_species(var/target_species)
|
||||
if(!species_restricted)
|
||||
return //this item doesn't use the species_restricted system
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
if(H.wear_suit.body_parts_covered & ARMS)
|
||||
to_chat(H, "<span class='warning'>You can't wear \the [src] with \the [H.wear_suit], it's in the way.</span>")
|
||||
return 0
|
||||
for(var/obj/item/clothing/accessory/A in H.wear_suit)
|
||||
if(A.body_parts_covered & ARMS)
|
||||
to_chat(H, "<span class='warning'>You can't wear \the [src] with \the [H.wear_suit]'s [A], it's in the way.</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/gloves/arm_guard/laserproof
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
if(H.wear_suit.body_parts_covered & LEGS)
|
||||
H << "<span class='warning'>You can't wear \the [src] with \the [H.wear_suit], it's in the way.</span>"
|
||||
return 0
|
||||
for(var/obj/item/clothing/accessory/A in H.wear_suit)
|
||||
if(A.body_parts_covered & LEGS)
|
||||
to_chat(H, "<span class='warning'>You can't wear \the [src] with \the [H.wear_suit]'s [A], it's in the way.</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/shoes/leg_guard/laserproof
|
||||
|
||||
@@ -520,6 +520,22 @@
|
||||
|ACCESSORY_SLOT_ARMOR_M)
|
||||
blood_overlay_type = "armor"
|
||||
|
||||
/obj/item/clothing/suit/armor/pcarrier/mob_can_equip(var/mob/living/carbon/human/H, slot)
|
||||
if(..()) //This will only run if no other problems occured when equiping.
|
||||
if(H.gloves)
|
||||
if(H.gloves.body_parts_covered & ARMS)
|
||||
for(var/obj/item/clothing/accessory/A in src)
|
||||
if(A.body_parts_covered & ARMS)
|
||||
to_chat(H, "<span class='warning'>You can't wear \the [A] with \the [H.gloves], they're in the way.</span>")
|
||||
return 0
|
||||
if(H.shoes)
|
||||
if(H.shoes.body_parts_covered & LEGS)
|
||||
for(var/obj/item/clothing/accessory/A in src)
|
||||
if(A.body_parts_covered & LEGS)
|
||||
to_chat(H, "<span class='warning'>You can't wear \the [A] with \the [H.shoes], they're in the way.</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/suit/armor/pcarrier/light
|
||||
starting_accessories = list(/obj/item/clothing/accessory/armor/armorplate)
|
||||
|
||||
@@ -549,6 +565,11 @@
|
||||
desc = "A lightweight blue plate carrier vest. It can be equipped with armor plates, but provides no protection of its own."
|
||||
icon_state = "pcarrier_blue"
|
||||
|
||||
/obj/item/clothing/suit/armor/pcarrier/press
|
||||
name = "light blue plate carrier"
|
||||
desc = "A lightweight light blue plate carrier vest. It can be equipped with armor plates, but provides no protection of its own."
|
||||
icon_state = "pcarrier_press"
|
||||
|
||||
/obj/item/clothing/suit/armor/pcarrier/blue/sol
|
||||
name = "peacekeeper plate carrier"
|
||||
desc = "A lightweight plate carrier vest in SCG Peacekeeper colors. It can be equipped with armor plates, but provides no protection of its own."
|
||||
|
||||
@@ -10,6 +10,24 @@
|
||||
icon_state = "pouches"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
|
||||
/obj/item/clothing/accessory/armor/on_attached(var/obj/item/clothing/S, var/mob/user)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.wear_suit == S)
|
||||
if((body_parts_covered & ARMS) && istype(H.gloves, /obj/item/clothing))
|
||||
var/obj/item/clothing/G = H.gloves
|
||||
if(G.body_parts_covered & ARMS)
|
||||
to_chat(H, "<span class='warning'>You can't wear \the [src] with \the [G], it's in the way.</span>")
|
||||
S.accessories -= src
|
||||
return
|
||||
else if((body_parts_covered & LEGS) && istype(H.shoes, /obj/item/clothing))
|
||||
var/obj/item/clothing/Sh = H.shoes
|
||||
if(Sh.body_parts_covered & LEGS)
|
||||
to_chat(H, "<span class='warning'>You can't wear \the [src] with \the [Sh], it's in the way.</span>")
|
||||
S.accessories -= src
|
||||
return
|
||||
..()
|
||||
|
||||
///////////
|
||||
//Pouches
|
||||
///////////
|
||||
@@ -74,6 +92,13 @@
|
||||
armor = list(melee = 30, bullet = 15, laser = 40, energy = 10, bomb = 25, bio = 0, rad = 0)
|
||||
slot = ACCESSORY_SLOT_ARMOR_C
|
||||
|
||||
/obj/item/clothing/accessory/armor/armorplate/stab
|
||||
name = "mesh armor plate"
|
||||
desc = "A mesh armor plate made of steel-reinforced synthetic fibers, great for dealing with small blades. Attaches to a plate carrier."
|
||||
icon_state = "armor_stab"
|
||||
armor = list(melee = 25, bullet = 5, laser = 20, energy = 10, bomb = 15, bio = 0, rad = 0)
|
||||
armorsoak = list(melee = 7, bullet = 5, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
|
||||
/obj/item/clothing/accessory/armor/armorplate/medium
|
||||
name = "medium armor plate"
|
||||
desc = "A plasteel-reinforced synthetic armor plate, providing good protection. Attaches to a plate carrier."
|
||||
@@ -92,6 +117,56 @@
|
||||
icon_state = "armor_merc"
|
||||
armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 40, bio = 0, rad = 0)
|
||||
|
||||
/obj/item/clothing/accessory/armor/armorplate/bulletproof
|
||||
name = "ballistic armor plate"
|
||||
desc = "A woven armor plate with additional plating, providing good protection against high-velocity trauma. Attaches to a plate carrier."
|
||||
icon_state = "armor_ballistic"
|
||||
slowdown = 0.6
|
||||
armor = list(melee = 10, bullet = 70, laser = 10, energy = 10, bomb = 0, bio = 0, rad = 0)
|
||||
armorsoak = list(melee = 0, bullet = 10, laser = 0, energy = 5, bomb = 0, bio = 0, rad = 0)
|
||||
siemens_coefficient = 0.7
|
||||
|
||||
/obj/item/clothing/accessory/armor/armorplate/riot
|
||||
name = "riot armor plate"
|
||||
desc = "A thick armor plate with additional padding, providing good protection against low-velocity trauma. Attaches to a plate carrier."
|
||||
icon_state = "armor_riot"
|
||||
slowdown = 0.6
|
||||
armor = list(melee = 70, bullet = 10, laser = 10, energy = 10, bomb = 0, bio = 0, rad = 0)
|
||||
armorsoak = list(melee = 10, bullet = 0, laser = 0, energy = 5, bomb = 0, bio = 0, rad = 0)
|
||||
siemens_coefficient = 0.7
|
||||
|
||||
/obj/item/clothing/accessory/armor/armorplate/laserproof
|
||||
name = "ablative armor plate"
|
||||
desc = "A durasteel-scaled synthetic armor plate, providing good protection against lasers. Attaches to a plate carrier."
|
||||
icon_state = "armor_medium"
|
||||
slowdown = 0.6
|
||||
armor = list(melee = 10, bullet = 10, laser = 70, energy = 50, bomb = 0, bio = 0, rad = 0)
|
||||
armorsoak = list(melee = 0, bullet = 0, laser = 10, energy = 15, bomb = 0, bio = 0, rad = 0)
|
||||
siemens_coefficient = 0.1
|
||||
|
||||
/obj/item/clothing/accessory/armor/armorplate/ablative/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
|
||||
if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam))
|
||||
var/obj/item/projectile/P = damage_source
|
||||
|
||||
if(P.reflected)
|
||||
return ..()
|
||||
|
||||
var/reflectchance = 40 - round(damage/3)
|
||||
if(!(def_zone in list(BP_TORSO, BP_GROIN)))
|
||||
reflectchance /= 2
|
||||
if(P.starting && prob(reflectchance))
|
||||
visible_message("<span class='danger'>\The [user]'s [src.name] reflects [attack_text]!</span>")
|
||||
|
||||
|
||||
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
|
||||
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
|
||||
var/turf/curloc = get_turf(user)
|
||||
|
||||
P.redirect(new_x, new_y, curloc, user)
|
||||
P.reflected = 1
|
||||
|
||||
return PROJECTILE_CONTINUE
|
||||
|
||||
//////////////
|
||||
//Arm guards
|
||||
//////////////
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/closed = 0
|
||||
var/scanning = 0
|
||||
var/scanner_progress = 0
|
||||
var/scanner_rate = 2.50
|
||||
var/scanner_rate = 5
|
||||
var/last_process_worldtime = 0
|
||||
var/report_num = 0
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
user << "<span class='notice'>The microscope whirrs as you examine \the [sample].</span>"
|
||||
|
||||
if(!do_after(user, 25) || !sample)
|
||||
if(!do_after(user, 2 SECONDS) || !sample)
|
||||
user << "<span class='notice'>You stop examining \the [sample].</span>"
|
||||
return
|
||||
|
||||
@@ -71,8 +71,8 @@
|
||||
report.info += "Surface analysis has determined unique fingerprint strings:<br><br>"
|
||||
for(var/prints in card.evidence)
|
||||
report.info += "<span class='notice'>Fingerprint string: </span>"
|
||||
if(!is_complete_print(prints))
|
||||
report.info += "INCOMPLETE PRINT"
|
||||
if(!is_complete_print(card.evidence[prints]))
|
||||
report.info += "INCOMPLETE PRINT:[card.evidence[prints]]"
|
||||
else
|
||||
report.info += "[prints]"
|
||||
report.info += "<br>"
|
||||
|
||||
201
code/modules/detectivework/tools/scanner.dm
Normal file
@@ -0,0 +1,201 @@
|
||||
/obj/item/device/detective_scanner
|
||||
name = "forensic scanner"
|
||||
desc = "Used to scan objects for DNA and fingerprints."
|
||||
icon_state = "forensic"
|
||||
var/list/stored = list()
|
||||
w_class = ITEMSIZE_SMALL
|
||||
item_state = "electronic"
|
||||
flags = NOBLUDGEON
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
var/reveal_fingerprints = TRUE
|
||||
var/reveal_incompletes = FALSE
|
||||
var/reveal_blood = TRUE
|
||||
var/reveal_fibers = FALSE
|
||||
|
||||
/obj/item/device/detective_scanner/attack(mob/living/carbon/human/M as mob, mob/user as mob)
|
||||
if (!ishuman(M))
|
||||
to_chat(user, "<span class='warning'>\The [M] does not seem to be compatible with this device.</span>")
|
||||
flick("[icon_state]0",src)
|
||||
return 0
|
||||
|
||||
if(reveal_fingerprints)
|
||||
if((!( istype(M.dna, /datum/dna) ) || M.gloves))
|
||||
to_chat(user, "<span class='notice'>No fingerprints found on [M]</span>")
|
||||
flick("[icon_state]0",src)
|
||||
return 0
|
||||
else if(user.zone_sel.selecting == "r_hand" || user.zone_sel.selecting == "l_hand")
|
||||
var/obj/item/weapon/sample/print/P = new /obj/item/weapon/sample/print(user.loc)
|
||||
P.attack(M, user)
|
||||
to_chat(user,"<span class='notice'>Done printing.</span>")
|
||||
// user << "<span class='notice'>[M]'s Fingerprints: [md5(M.dna.uni_identity)]</span>"
|
||||
|
||||
if(reveal_blood && M.blood_DNA && M.blood_DNA.len)
|
||||
to_chat(user,"<span class='notice'>Blood found on [M]. Analysing...</span>")
|
||||
spawn(15)
|
||||
for(var/blood in M.blood_DNA)
|
||||
to_chat(user,"<span class='notice'>Blood type: [M.blood_DNA[blood]]\nDNA: [blood]</span>")
|
||||
return
|
||||
|
||||
/obj/item/device/detective_scanner/afterattack(atom/A as obj|turf, mob/user, proximity)
|
||||
if(!proximity) return
|
||||
if(ismob(A))
|
||||
return
|
||||
|
||||
/*
|
||||
if(istype(A,/obj/machinery/computer/forensic_scanning))
|
||||
user.visible_message("[user] takes a cord out of [src] and hooks its end into [A]" ,\
|
||||
"<span class='notice'>You download data from [src] to [A]</span>")
|
||||
var/obj/machinery/computer/forensic_scanning/F = A
|
||||
F.sync_data(stored)
|
||||
return
|
||||
*/
|
||||
|
||||
if(istype(A,/obj/item/weapon/sample/print))
|
||||
to_chat(user,"The scanner displays on the screen: \"ERROR 43: Object on Excluded Object List.\"")
|
||||
flick("[icon_state]0",src)
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if(!(do_after(user, 1 SECOND)))
|
||||
to_chat(user,"<span class='warning'>You must remain still for the device to complete its work.</span>")
|
||||
return 0
|
||||
|
||||
//General
|
||||
if ((!A.fingerprints || !A.fingerprints.len) && !A.suit_fibers && !A.blood_DNA)
|
||||
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\
|
||||
"<span class='warning'>Unable to locate any fingerprints, materials, fibers, or blood on [A]!</span>",\
|
||||
"You hear a faint hum of electrical equipment.")
|
||||
flick("[icon_state]0",src)
|
||||
return 0
|
||||
|
||||
if(add_data(A))
|
||||
to_chat(user,"<span class='notice'>Object already in internal memory. Consolidating data...</span>")
|
||||
flick("[icon_state]2",src)
|
||||
return
|
||||
|
||||
//PRINTS
|
||||
if(A.fingerprints && A.fingerprints.len)
|
||||
to_chat(user,"<span class='notice'>Isolated [A.fingerprints.len] fingerprints:</span>")
|
||||
if(!reveal_incompletes)
|
||||
to_chat(user,"<span class='warning'>Rapid Analysis Imperfect: Scan samples with H.R.F.S. equipment to determine nature of incomplete prints.</span>")
|
||||
var/list/complete_prints = list()
|
||||
var/list/incomplete_prints = list()
|
||||
for(var/i in A.fingerprints)
|
||||
var/print = A.fingerprints[i]
|
||||
if(stringpercent(print) <= FINGERPRINT_COMPLETE)
|
||||
complete_prints += print
|
||||
else
|
||||
incomplete_prints += print
|
||||
if(complete_prints.len < 1)
|
||||
to_chat(user,"<span class='notice'>No intact prints found</span>")
|
||||
else
|
||||
to_chat(user,"<span class='notice'>Found [complete_prints.len] intact prints</span>")
|
||||
if(reveal_fingerprints)
|
||||
for(var/i in complete_prints)
|
||||
to_chat(user,"<span class='notice'> [i]</span>")
|
||||
|
||||
to_chat(user,"<span class='notice'>Found [incomplete_prints.len] incomplete prints</span>")
|
||||
if(reveal_incompletes)
|
||||
for(var/i in incomplete_prints)
|
||||
to_chat(user,"<span class='notice'> [i]</span>")
|
||||
|
||||
|
||||
//FIBERS
|
||||
if(A.suit_fibers && A.suit_fibers.len)
|
||||
to_chat(user,"<span class='notice'>Fibers/Materials detected.[reveal_fibers ? " Analysing..." : " Acquisition of fibers for H.R.F.S. analysis advised."]</span>")
|
||||
flick("[icon_state]2",src)
|
||||
if(reveal_fibers && do_after(user, 5 SECONDS))
|
||||
to_chat(user,"<span class='notice'>Apparel samples scanned:</span>")
|
||||
for(var/sample in A.suit_fibers)
|
||||
to_chat(user," - <span class='notice'>[sample]</span>")
|
||||
|
||||
//Blood
|
||||
if (A.blood_DNA && A.blood_DNA.len)
|
||||
to_chat(user,"<span class='notice'>Blood detected.[reveal_blood ? " Analysing..." : " Acquisition of swab for H.R.F.S. analysis advised."]</span>")
|
||||
if(reveal_blood && do_after(user, 5 SECONDS))
|
||||
flick("[icon_state]2",src)
|
||||
for(var/blood in A.blood_DNA)
|
||||
to_chat(user,"Blood type: <span class='warning'>[A.blood_DNA[blood]]</span> DNA: <span class='warning'>[blood]</span>")
|
||||
|
||||
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\
|
||||
"<span class='notice'>You finish scanning \the [A].</span>",\
|
||||
"You hear a faint hum of electrical equipment.")
|
||||
flick("[icon_state]2",src)
|
||||
return 0
|
||||
|
||||
/obj/item/device/detective_scanner/proc/add_data(atom/A as mob|obj|turf|area)
|
||||
var/datum/data/record/forensic/old = stored["\ref [A]"]
|
||||
var/datum/data/record/forensic/fresh = new(A)
|
||||
|
||||
if(old)
|
||||
fresh.merge(old)
|
||||
. = 1
|
||||
stored["\ref [A]"] = fresh
|
||||
|
||||
/obj/item/device/detective_scanner/verb/examine_data()
|
||||
set name = "Examine Forensic Data"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
world << "usr is [usr]"
|
||||
display_data(usr)
|
||||
|
||||
/obj/item/device/detective_scanner/proc/display_data(var/mob/user)
|
||||
if(user && stored && stored.len)
|
||||
for(var/objref in stored)
|
||||
if(!do_after(user, 1 SECOND)) // So people can move and stop the spam, if they refuse to wipe data.
|
||||
break
|
||||
|
||||
var/datum/data/record/forensic/F = stored[objref]
|
||||
var/list/fprints = F.fields["fprints"]
|
||||
var/list/fibers = F.fields["fibers"]
|
||||
var/list/bloods = F.fields["blood"]
|
||||
|
||||
to_chat(user, "<span class='notice'>Data for: [F.fields["name"]]</span>")
|
||||
|
||||
if(reveal_fingerprints)
|
||||
var/list/complete_prints = list()
|
||||
var/list/incomplete_prints = list()
|
||||
for(var/i in fprints)
|
||||
var/print = fprints[i]
|
||||
if(stringpercent(print) <= FINGERPRINT_COMPLETE)
|
||||
complete_prints += print
|
||||
to_chat(user, " - <span class='notice'>[print]</span>")
|
||||
else
|
||||
incomplete_prints += print
|
||||
|
||||
if(complete_prints.len < 1)
|
||||
to_chat(user,"<span class='notice'>No intact prints found.</span>")
|
||||
|
||||
if(reveal_incompletes)
|
||||
for(var/print in incomplete_prints)
|
||||
to_chat(user, " - <span class='notice'>[print]</span>")
|
||||
|
||||
if(fibers && fibers.len)
|
||||
to_chat(user, "<span class='notice'>[fibers.len] samples of material were present.</span>")
|
||||
if(reveal_fibers)
|
||||
for(var/sample in fibers)
|
||||
to_chat(user," - <span class='notice'>[sample]</span>")
|
||||
|
||||
if(bloods && bloods.len)
|
||||
to_chat(user, "<span class='notice'>[bloods.len] samples of blood were present.</span>")
|
||||
if(reveal_blood)
|
||||
for(var/bloodsample in bloods)
|
||||
to_chat(user, " - <span class='warning'>[bloodsample]</span> Type: [bloods[bloodsample]]")
|
||||
|
||||
/obj/item/device/detective_scanner/verb/wipe()
|
||||
set name = "Wipe Forensic Data"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if (alert("Are you sure you want to wipe all data from [src]?",,"Yes","No") == "Yes")
|
||||
stored = list()
|
||||
to_chat(usr,"<span class='notice'>Forensic data erase complete.</span>")
|
||||
|
||||
/obj/item/device/detective_scanner/advanced
|
||||
name = "advanced forensic scanner"
|
||||
icon_state = "forensic_neo"
|
||||
reveal_fibers = TRUE
|
||||
reveal_incompletes = TRUE
|
||||
10
code/modules/gamemaster/actions/drill_announcement.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
/datum/gm_action/security_drill
|
||||
name = "security drills"
|
||||
departments = list(ROLE_SECURITY, ROLE_EVERYONE)
|
||||
|
||||
/datum/gm_action/security_drill/announce()
|
||||
spawn(rand(1 MINUTE, 2 MINUTES))
|
||||
command_announcement.Announce("[pick("A NanoTrasen security director", "A Vir-Gov correspondant", "Local Sif authoritiy")] has advised the enactment of [pick("a rampant wildlife", "a fire", "a hostile boarding", "a nonstandard", "a bomb", "an emergent intelligence")] drill with the personnel onboard \the [station_name()].", "Security Advisement")
|
||||
|
||||
/datum/gm_action/security_drill/get_weight()
|
||||
return max(-20, 10 + gm.staleness - (gm.danger * 2)) + (metric.count_people_in_department(ROLE_SECURITY) * 5) + (metric.count_people_in_department(ROLE_EVERYONE) * 1.5)
|
||||
@@ -14,4 +14,4 @@
|
||||
|
||||
/datum/gm_action/dust/start()
|
||||
..()
|
||||
dust_swarm("norm")
|
||||
dust_swarm("norm")
|
||||
|
||||
116
code/modules/gamemaster/actions/infestation.dm
Normal file
@@ -0,0 +1,116 @@
|
||||
#define LOC_KITCHEN 0
|
||||
#define LOC_ATMOS 1
|
||||
#define LOC_CHAPEL 2
|
||||
#define LOC_LIBRARY 3
|
||||
#define LOC_HYDRO 4
|
||||
#define LOC_VAULT 5
|
||||
#define LOC_CONSTR 6
|
||||
#define LOC_TECH 7
|
||||
#define LOC_GARDEN 8
|
||||
|
||||
#define VERM_MICE 0
|
||||
#define VERM_LIZARDS 1
|
||||
#define VERM_SPIDERS 2
|
||||
|
||||
/datum/gm_action/infestation
|
||||
name = "animal infestation"
|
||||
departments = list(ROLE_EVERYONE)
|
||||
var/location
|
||||
var/locstring
|
||||
var/vermin
|
||||
var/vermstring
|
||||
|
||||
var/list/turf/simulated/floor/turfs = list()
|
||||
|
||||
var/spawn_types
|
||||
var/max_number
|
||||
|
||||
/datum/gm_action/infestation/set_up()
|
||||
location = rand(0,8)
|
||||
turfs.Cut()
|
||||
var/spawn_area_type
|
||||
switch(location)
|
||||
if(LOC_KITCHEN)
|
||||
spawn_area_type = /area/crew_quarters/kitchen
|
||||
locstring = "the kitchen"
|
||||
if(LOC_ATMOS)
|
||||
spawn_area_type = /area/engineering/atmos
|
||||
locstring = "atmospherics"
|
||||
if(LOC_CHAPEL)
|
||||
spawn_area_type = /area/chapel/main
|
||||
locstring = "the chapel"
|
||||
if(LOC_LIBRARY)
|
||||
spawn_area_type = /area/library
|
||||
locstring = "the library"
|
||||
if(LOC_HYDRO)
|
||||
spawn_area_type = /area/hydroponics
|
||||
locstring = "hydroponics"
|
||||
if(LOC_VAULT)
|
||||
spawn_area_type = /area/security/nuke_storage
|
||||
locstring = "the vault"
|
||||
if(LOC_CONSTR)
|
||||
spawn_area_type = /area/construction
|
||||
locstring = "the construction area"
|
||||
if(LOC_TECH)
|
||||
spawn_area_type = /area/storage/tech
|
||||
locstring = "technical storage"
|
||||
if(LOC_GARDEN)
|
||||
spawn_area_type = /area/hydroponics/garden
|
||||
locstring = "the public garden"
|
||||
|
||||
for(var/areapath in typesof(spawn_area_type))
|
||||
var/area/A = locate(areapath)
|
||||
for(var/turf/simulated/floor/F in A.contents)
|
||||
if(turf_clear(F))
|
||||
turfs += F
|
||||
|
||||
spawn_types = list()
|
||||
max_number = 0
|
||||
vermin = rand(0,2)
|
||||
switch(vermin)
|
||||
if(VERM_MICE)
|
||||
spawn_types = list(/mob/living/simple_mob/animal/passive/mouse/gray, /mob/living/simple_mob/animal/passive/mouse/brown, /mob/living/simple_mob/animal/passive/mouse/white, /mob/living/simple_mob/animal/passive/mouse/rat)
|
||||
max_number = 12
|
||||
vermstring = "mice"
|
||||
if(VERM_LIZARDS)
|
||||
spawn_types = list(/mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/lizard/large, /mob/living/simple_mob/animal/passive/lizard/large/defensive)
|
||||
max_number = 6
|
||||
vermstring = "lizards"
|
||||
if(VERM_SPIDERS)
|
||||
spawn_types = list(/obj/effect/spider/spiderling)
|
||||
max_number = 3
|
||||
vermstring = "spiders"
|
||||
|
||||
/datum/gm_action/infestation/start()
|
||||
spawn()
|
||||
var/num = rand(2,max_number)
|
||||
while(turfs.len > 0 && num > 0)
|
||||
var/turf/simulated/floor/T = pick(turfs)
|
||||
turfs.Remove(T)
|
||||
num--
|
||||
|
||||
if(vermin == VERM_SPIDERS)
|
||||
var/obj/effect/spider/spiderling/S = new(T)
|
||||
S.amount_grown = -1
|
||||
else
|
||||
var/spawn_type = pick(spawn_types)
|
||||
new spawn_type(T)
|
||||
|
||||
/datum/gm_action/infestation/announce()
|
||||
command_announcement.Announce("Bioscans indicate that [vermstring] have been breeding in [locstring]. Clear them out, before this starts to affect productivity.", "Vermin infestation")
|
||||
|
||||
/datum/gm_action/infestation/get_weight()
|
||||
return 5 + (metric.count_people_in_department(ROLE_EVERYONE) * 20)
|
||||
|
||||
#undef LOC_KITCHEN
|
||||
#undef LOC_ATMOS
|
||||
#undef LOC_CHAPEL
|
||||
#undef LOC_LIBRARY
|
||||
#undef LOC_HYDRO
|
||||
#undef LOC_VAULT
|
||||
#undef LOC_TECH
|
||||
#undef LOC_GARDEN
|
||||
|
||||
#undef VERM_MICE
|
||||
#undef VERM_LIZARDS
|
||||
#undef VERM_SPIDERS
|
||||
@@ -1,4 +1,6 @@
|
||||
/datum/gm_action/ionstorm
|
||||
name = "ion storm"
|
||||
departments = list(ROLE_SYNTHETIC)
|
||||
var/botEmagChance = 0.5
|
||||
var/list/players = list()
|
||||
var/active = FALSE
|
||||
@@ -41,3 +43,8 @@
|
||||
spawn(rand(5000,8000))
|
||||
if(prob(50))
|
||||
ion_storm_announcement()
|
||||
|
||||
/datum/gm_action/ionstorm/get_weight()
|
||||
var/bots = metric.count_people_in_department(ROLE_SYNTHETIC)
|
||||
var/weight = 5 + (bots * 20)
|
||||
return weight
|
||||
|
||||
52
code/modules/gamemaster/actions/manifest_malfunction.dm
Normal file
@@ -0,0 +1,52 @@
|
||||
/datum/gm_action/manifest_malfunction
|
||||
name = "manifest malfunction"
|
||||
enabled = TRUE
|
||||
departments = list(ROLE_SECURITY, ROLE_SYNTHETIC, ROLE_EVERYONE)
|
||||
chaotic = 3
|
||||
reusable = FALSE
|
||||
length = 0
|
||||
|
||||
var/recordtype
|
||||
|
||||
/datum/gm_action/manifest_malfunction/set_up()
|
||||
severity = pickweight(EVENT_LEVEL_MUNDANE = 6,
|
||||
EVENT_LEVEL_MODERATE = 2,
|
||||
EVENT_LEVEL_MAJOR = 1
|
||||
)
|
||||
|
||||
recordtype = pickweight("medical" = 10,"security" = (severity * 15))
|
||||
|
||||
return
|
||||
|
||||
/datum/gm_action/manifest_malfunction/get_weight()
|
||||
. = -10
|
||||
|
||||
var/security = metric.count_people_in_department(ROLE_SECURITY)
|
||||
|
||||
if(security && data_core)
|
||||
. += (metric.count_people_in_department(ROLE_EVERYONE) * 5) - (metric.count_people_in_department(ROLE_SYNTHETIC) * 5)
|
||||
|
||||
return .
|
||||
|
||||
/datum/gm_action/manifest_malfunction/start()
|
||||
..()
|
||||
|
||||
var/manifest_cut_count = 1 * severity
|
||||
|
||||
for(var/I = 1 to manifest_cut_count)
|
||||
var/datum/data/record/R
|
||||
|
||||
switch(recordtype)
|
||||
if("security")
|
||||
R = pick(data_core.security)
|
||||
|
||||
if("medical")
|
||||
R = pick(data_core.medical)
|
||||
|
||||
qdel(R)
|
||||
|
||||
/datum/gm_action/manifest_malfunction/announce()
|
||||
if(prob(30 * severity))
|
||||
spawn(rand(5 MINUTES, 10 MINUTES))
|
||||
command_announcement.Announce("An ongoing mass upload of malware for [recordtype] record cores has been detected onboard [station_name()]", "Data Breach Alert")
|
||||
return
|
||||
@@ -2,18 +2,38 @@
|
||||
|
||||
/datum/gm_action/meteor_defense
|
||||
name = "meteor defense"
|
||||
departments = list(ROLE_ENGINEERING)
|
||||
departments = list(ROLE_ENGINEERING, ROLE_CARGO)
|
||||
chaotic = 50
|
||||
var/direction = null
|
||||
var/dir_text = null
|
||||
var/waves = 0
|
||||
|
||||
var/meteor_types
|
||||
|
||||
/datum/gm_action/meteor_defense/get_weight()
|
||||
var/engineers = metric.count_people_in_department(ROLE_ENGINEERING)
|
||||
var/weight = (max(engineers - 1, 0) * 25) // If only one engineer exists, no meteors for now.
|
||||
var/cargo = metric.count_people_in_department(ROLE_CARGO)
|
||||
var/bots = metric.count_people_in_department(ROLE_SYNTHETIC)
|
||||
var/weight = (max(engineers - 1, 0) * 20) // If only one engineer exists, no meteors for now.
|
||||
|
||||
if(engineers >= 2)
|
||||
weight += ((cargo - 1) * 10)
|
||||
weight += (bots * 15)
|
||||
|
||||
return weight
|
||||
|
||||
/datum/gm_action/meteor_defense/set_up()
|
||||
severity = pickweight(EVENT_LEVEL_MUNDANE = 10,
|
||||
EVENT_LEVEL_MODERATE = 3
|
||||
)
|
||||
|
||||
switch(severity)
|
||||
if(EVENT_LEVEL_MUNDANE)
|
||||
meteor_types = meteors_threatening.Copy()
|
||||
|
||||
if(EVENT_LEVEL_MODERATE)
|
||||
meteor_types = meteors_catastrophic.Copy()
|
||||
|
||||
direction = pick(cardinal) // alldirs doesn't work with current meteor code unfortunately.
|
||||
waves = rand(5, 8)
|
||||
switch(direction)
|
||||
@@ -27,17 +47,17 @@
|
||||
dir_text = "starboard"
|
||||
|
||||
/datum/gm_action/meteor_defense/announce()
|
||||
var/announcement = "Alert! Two other asteroids have collided near [station_name()]. Chunks of it are expected to approach from the [dir_text] side. ETA to arrival is \
|
||||
approximately 10 minutes."
|
||||
var/announcement = "Alert! Two asteroids have collided near [station_name()]. Chunks of it are expected to approach from the [dir_text] side. ETA to arrival is \
|
||||
approximately [round(5 * severity * 2)] minutes."
|
||||
command_announcement.Announce(announcement, "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
|
||||
|
||||
/datum/gm_action/meteor_defense/start()
|
||||
..()
|
||||
spawn(0)
|
||||
sleep(5 MINUTES)
|
||||
var/announcement = "The incoming debris are expected to approach from the [dir_text] side. ETA to arrival is approximately 5 minutes."
|
||||
sleep(round(5 * severity) MINUTES)
|
||||
var/announcement = "The incoming debris are expected to approach from the [dir_text] side. ETA to arrival is approximately [round(5 * severity)] minutes."
|
||||
command_announcement.Announce(announcement, "Meteor Alert - Update")
|
||||
sleep(5 MINUTES)
|
||||
sleep(round(5 * severity) MINUTES)
|
||||
announcement = "Incoming debris approaches from the [dir_text] side!"
|
||||
command_announcement.Announce(announcement, "Meteor Alert - Update")
|
||||
while(waves)
|
||||
@@ -46,6 +66,6 @@
|
||||
spawn_meteors(rand(8, 12), meteors_threatening, reverse_dir[direction])
|
||||
waves--
|
||||
sleep(30 SECONDS)
|
||||
announcement = "The colony has cleared the incoming debris."
|
||||
announcement = "The station has cleared the incoming debris."
|
||||
command_announcement.Announce(announcement, "Meteor Alert - Update")
|
||||
message_admins("Meteor defense event has ended.")
|
||||
message_admins("Meteor defense event has ended.")
|
||||
|
||||
49
code/modules/gamemaster/actions/security_advisement.dm
Normal file
@@ -0,0 +1,49 @@
|
||||
/datum/gm_action/security_screening
|
||||
name = "security screening"
|
||||
departments = list(ROLE_SECURITY, ROLE_EVERYONE)
|
||||
|
||||
var/list/species_weights = list(
|
||||
SPECIES_SKRELL = 9,
|
||||
SPECIES_UNATHI = 15,
|
||||
SPECIES_HUMAN_VATBORN = 6,
|
||||
SPECIES_TESHARI = 2,
|
||||
SPECIES_TAJ = 3,
|
||||
SPECIES_DIONA = 1,
|
||||
SPECIES_ZADDAT = 25,
|
||||
SPECIES_HUMAN = 3,
|
||||
SPECIES_PROMETHEAN = 30
|
||||
)
|
||||
|
||||
var/list/synth_weights = list(
|
||||
"Cybernetic" = 15,
|
||||
"Drone" = 30,
|
||||
"Positronic" = 25
|
||||
)
|
||||
|
||||
var/list/end_weights = list()
|
||||
|
||||
/datum/gm_action/security_screening/set_up()
|
||||
for(var/species_name in species_weights)
|
||||
var/giveweight = 0
|
||||
|
||||
for(var/datum/data/record/R in data_core.general)
|
||||
if(R.fields["species"] == species_name)
|
||||
giveweight += species_weights[species_name]
|
||||
|
||||
end_weights[species_name] = giveweight
|
||||
|
||||
for(var/bottype in synth_weights)
|
||||
var/giveweight = 0
|
||||
|
||||
for(var/datum/data/record/R in data_core.general)
|
||||
if(R.fields["brain_type"] == bottype)
|
||||
giveweight += synth_weights[bottype]
|
||||
|
||||
end_weights[bottype] = giveweight
|
||||
|
||||
/datum/gm_action/security_screening/announce()
|
||||
spawn(rand(1 MINUTE, 2 MINUTES))
|
||||
command_announcement.Announce("[pick("A nearby Navy vessel", "A Solar official", "A Vir-Gov official", "A NanoTrasen board director")] has requested the screening of [pick("every other", "every", "suspicious", "willing")] [pickweight(end_weights)] personnel onboard \the [station_name()].", "Security Advisement")
|
||||
|
||||
/datum/gm_action/security_screening/get_weight()
|
||||
return max(-20, 10 + round(gm.staleness * 1.5) - (gm.danger * 2)) + (metric.count_people_in_department(ROLE_SECURITY) * 10) + (metric.count_people_in_department(ROLE_EVERYONE) * 1.5)
|
||||
@@ -7,21 +7,28 @@
|
||||
|
||||
var/spawncount = 1
|
||||
|
||||
/datum/gm_action/spider_infestation/set_up()
|
||||
spawn(rand(600, 6000))
|
||||
announce()
|
||||
var/spawntype = /obj/effect/spider/spiderling
|
||||
|
||||
if(prob(40))
|
||||
severity = rand(2,3)
|
||||
else
|
||||
severity = 1
|
||||
/datum/gm_action/spider_infestation/set_up()
|
||||
severity = pickweight(EVENT_LEVEL_MUNDANE = max(1,(12 - (3 * metric.count_people_in_department(ROLE_SECURITY)))),
|
||||
EVENT_LEVEL_MODERATE = (7 + (2 * metric.count_people_in_department(ROLE_SECURITY))),
|
||||
EVENT_LEVEL_MAJOR = (1 + (2 * metric.count_people_in_department(ROLE_SECURITY)))
|
||||
)
|
||||
|
||||
switch(severity)
|
||||
if(EVENT_LEVEL_MUNDANE)
|
||||
spawntype = /obj/effect/spider/spiderling/stunted
|
||||
if(EVENT_LEVEL_MODERATE)
|
||||
spawntype = /obj/effect/spider/spiderling
|
||||
if(EVENT_LEVEL_MAJOR)
|
||||
spawntype = /obj/effect/spider/spiderling
|
||||
|
||||
spawncount = rand(4 * severity, 6 * severity)
|
||||
|
||||
/datum/gm_action/spider_infestation/announce()
|
||||
command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg')
|
||||
|
||||
if(severity >= 3)
|
||||
if(severity >= EVENT_LEVEL_MAJOR)
|
||||
spawn(rand(600, 3000))
|
||||
command_announcement.Announce("Unidentified lifesigns previously detected coming aboard [station_name()] have been classified as a swarm of arachnids. Extreme caution is advised.", "Arachnid Alert")
|
||||
|
||||
|
||||
14
code/modules/gamemaster/actions/station_fundraise.dm
Normal file
@@ -0,0 +1,14 @@
|
||||
/datum/gm_action/station_fund_raise
|
||||
name = "local funding drive"
|
||||
departments = list(ROLE_SECURITY, ROLE_CARGO, ROLE_EVERYONE)
|
||||
|
||||
/datum/gm_action/station_fund_raise/announce()
|
||||
spawn(rand(1 MINUTE, 2 MINUTES))
|
||||
command_announcement.Announce("Due to [pick("recent", "unfortunate", "possible future")] budget [pick("changes", "issues")], in-system stations are now advised to increase funding income.", "Security & Supply Advisement")
|
||||
|
||||
/datum/gm_action/station_fund_raise/get_weight()
|
||||
var/weight_modifier = 0.5
|
||||
if(station_account.money <= 80000)
|
||||
weight_modifier = 1
|
||||
|
||||
return (max(-20, 10 + gm.staleness) + ((metric.count_people_in_department(ROLE_SECURITY) + (metric.count_people_in_department(ROLE_CARGO))) * 5) + (metric.count_people_in_department(ROLE_EVERYONE) * 3)) * weight_modifier
|
||||
80
code/modules/gamemaster/actions/stowaway.dm
Normal file
@@ -0,0 +1,80 @@
|
||||
/datum/gm_action/stowaway
|
||||
name = "stowaway pod"
|
||||
departments = list(ROLE_EVERYONE, ROLE_SECURITY)
|
||||
chaotic = 10
|
||||
observers_used = TRUE
|
||||
var/area/target_area // Chosen target area
|
||||
var/area/target_turf // Chosen target turf in target_area
|
||||
var/list/area/excluded = list(
|
||||
/area/submap,
|
||||
/area/shuttle,
|
||||
/area/crew_quarters,
|
||||
/area/holodeck,
|
||||
/area/engineering/engine_room
|
||||
)
|
||||
|
||||
var/list/area/included = list(
|
||||
/area/maintenance
|
||||
)
|
||||
|
||||
/datum/gm_action/stowaway/set_up()
|
||||
severity = pickweight(EVENT_LEVEL_MUNDANE = 20,
|
||||
EVENT_LEVEL_MODERATE = 5,
|
||||
EVENT_LEVEL_MAJOR = 1
|
||||
)
|
||||
|
||||
var/list/area/grand_list_of_areas = get_station_areas(excluded)
|
||||
|
||||
for(var/area/Incl in included)
|
||||
for(var/area/A in grand_list_of_areas)
|
||||
if(!istype(A, Incl))
|
||||
grand_list_of_areas -= A
|
||||
|
||||
// Okay, now lets try and pick a target! Lets try 10 times, otherwise give up
|
||||
for(var/i in 1 to 10)
|
||||
var/area/A = pick(grand_list_of_areas)
|
||||
if(is_area_occupied(A))
|
||||
log_debug("[name] event: Rejected [A] because it is occupied.")
|
||||
continue
|
||||
// A good area, great! Lets try and pick a turf
|
||||
var/list/turfs = list()
|
||||
for(var/turf/simulated/floor/F in A)
|
||||
if(turf_clear(F))
|
||||
turfs += F
|
||||
if(turfs.len == 0)
|
||||
log_debug("[name] event: Rejected [A] because it has no clear turfs.")
|
||||
continue
|
||||
target_area = A
|
||||
target_turf = pick(turfs)
|
||||
|
||||
if(!target_area)
|
||||
log_debug("[name] event: Giving up after too many failures to pick target area")
|
||||
return
|
||||
|
||||
/datum/gm_action/stowaway/start()
|
||||
if(!target_turf)
|
||||
return
|
||||
..()
|
||||
|
||||
var/obj/structure/ghost_pod/ghost_activated/human/HP = new (target_turf)
|
||||
|
||||
if(severity == EVENT_LEVEL_MUNDANE || istype(ticker.mode, /datum/game_mode/extended))
|
||||
HP.make_antag = MODE_STOWAWAY
|
||||
|
||||
else if(severity == EVENT_LEVEL_MODERATE)
|
||||
HP.make_antag = MODE_RENEGADE
|
||||
HP.occupant_type = "renegade [HP.occupant_type]"
|
||||
|
||||
else if(severity == EVENT_LEVEL_MAJOR)
|
||||
HP.make_antag = MODE_INFILTRATOR
|
||||
HP.occupant_type = "volatile [HP.occupant_type]"
|
||||
|
||||
say_dead_object("A <span class='notice'>[HP.occupant_type]</span> pod is now available in \the [target_area].", HP)
|
||||
|
||||
/datum/gm_action/stowaway/get_weight()
|
||||
return -20 + (metric.count_people_in_department(ROLE_SECURITY) * 15 + metric.count_people_in_department(ROLE_SYNTHETIC) * 5 + metric.count_people_in_department(ROLE_EVERYONE) * 1)
|
||||
|
||||
/datum/gm_action/stowaway/announce()
|
||||
spawn(rand(15 MINUTES, 30 MINUTES))
|
||||
if(prob(20) && severity >= EVENT_LEVEL_MODERATE && atc && !atc.squelched)
|
||||
atc.msg("Attention civilian vessels in [using_map.starsys_name] shipping lanes, caution is advised as [pick("an unidentified vessel", "a known criminal's vessel", "a derelict vessel")] has been detected passing multiple local stations.")
|
||||
62
code/modules/gamemaster/actions/supply_conversion.dm
Normal file
@@ -0,0 +1,62 @@
|
||||
/datum/gm_action/nanotrasen_budget_allocation
|
||||
name = "supply point to cargo budget"
|
||||
enabled = TRUE
|
||||
departments = list(ROLE_CARGO)
|
||||
chaotic = 0
|
||||
reusable = TRUE
|
||||
|
||||
var/datum/controller/supply/SC
|
||||
var/running = FALSE
|
||||
var/last_run
|
||||
|
||||
var/thaler_earned
|
||||
|
||||
/datum/gm_action/nanotrasen_budget_allocation/set_up()
|
||||
SC = supply_controller
|
||||
running = TRUE
|
||||
return
|
||||
|
||||
/datum/gm_action/nanotrasen_budget_allocation/get_weight()
|
||||
. = round(SC.points / 15)
|
||||
|
||||
var/cargo = metric.count_people_in_department(ROLE_CARGO)
|
||||
var/personnel = metric.count_people_in_department(ROLE_EVERYONE)
|
||||
if(cargo)
|
||||
. = round(SC.points / (10 + personnel)) + cargo * 10
|
||||
|
||||
if(running || ( world.time < (last_run + 30 MINUTES)))
|
||||
. = 0
|
||||
|
||||
return .
|
||||
|
||||
/datum/gm_action/nanotrasen_budget_allocation/start()
|
||||
. = ..()
|
||||
|
||||
last_run = world.time
|
||||
|
||||
var/point_difference = SC.points
|
||||
|
||||
if(SC.points >= 1000)
|
||||
SC.points = round(SC.points / 3)
|
||||
point_difference -= SC.points
|
||||
|
||||
else if(SC.points >= 500)
|
||||
SC.points -= 100 * (rand(5, 20) / 10)
|
||||
point_difference -= SC.points
|
||||
|
||||
else
|
||||
SC.points = round(SC.points / 1.25)
|
||||
point_difference -= SC.points
|
||||
|
||||
if(point_difference > 0)
|
||||
thaler_earned = round(point_difference / SC.points_per_money)
|
||||
|
||||
/datum/gm_action/nanotrasen_budget_allocation/end()
|
||||
spawn(5 MINUTES)
|
||||
running = FALSE
|
||||
return
|
||||
|
||||
/datum/gm_action/nanotrasen_budget_allocation/announce()
|
||||
spawn(rand(1 MINUTE, 5 MINUTES))
|
||||
command_announcement.Announce("[station_name()] Supply Department has earned a converted thaler budget of [thaler_earned] due to their backlogged daily requisition tokens.", "Supply Budget Conversion")
|
||||
return
|
||||
11
code/modules/gamemaster/actions/supplyrequest.dm
Normal file
@@ -0,0 +1,11 @@
|
||||
/datum/gm_action/request
|
||||
name = "general request"
|
||||
departments = list(ROLE_CARGO)
|
||||
|
||||
/datum/gm_action/request/announce()
|
||||
spawn(rand(1 MINUTE, 2 MINUTES))
|
||||
command_announcement.Announce("[pick("A nearby vessel", "A Solar contractor", "A Skrellian contractor", "A NanoTrasen board director")] has requested the delivery of [pick("one","two","three","several")] [pick("medical","engineering","research","civilian")] supply packages. The [station_name()] has been tasked with completing this request.", "Supply Request")
|
||||
|
||||
/datum/gm_action/request/get_weight()
|
||||
return max(15, 15 + round(gm.staleness / 2) - gm.danger) + (metric.count_people_in_department(ROLE_CARGO) * 10)
|
||||
|
||||
75
code/modules/gamemaster/actions/swarmboarder.dm
Normal file
@@ -0,0 +1,75 @@
|
||||
/datum/gm_action/swarm_boarder
|
||||
name = "swarmer shell"
|
||||
departments = list(ROLE_EVERYONE, ROLE_SECURITY, ROLE_ENGINEERING)
|
||||
chaotic = 30
|
||||
observers_used = TRUE
|
||||
var/area/target_area // Chosen target area
|
||||
var/area/target_turf // Chosen target turf in target_area
|
||||
var/list/area/excluded = list(
|
||||
/area/submap,
|
||||
/area/shuttle,
|
||||
/area/crew_quarters,
|
||||
/area/holodeck,
|
||||
/area/engineering/engine_room
|
||||
)
|
||||
|
||||
var/list/area/included = list(
|
||||
/area/maintenance
|
||||
)
|
||||
|
||||
/datum/gm_action/swarm_boarder/set_up()
|
||||
severity = pickweight(EVENT_LEVEL_MUNDANE = 30,
|
||||
EVENT_LEVEL_MODERATE = 10,
|
||||
EVENT_LEVEL_MAJOR = 1
|
||||
)
|
||||
|
||||
var/list/area/grand_list_of_areas = get_station_areas(excluded)
|
||||
|
||||
for(var/area/Incl in included)
|
||||
for(var/area/A in grand_list_of_areas)
|
||||
if(!istype(A, Incl))
|
||||
grand_list_of_areas -= A
|
||||
|
||||
// Okay, now lets try and pick a target! Lets try 10 times, otherwise give up
|
||||
for(var/i in 1 to 10)
|
||||
var/area/A = pick(grand_list_of_areas)
|
||||
if(is_area_occupied(A))
|
||||
log_debug("[name] event: Rejected [A] because it is occupied.")
|
||||
continue
|
||||
// A good area, great! Lets try and pick a turf
|
||||
var/list/turfs = list()
|
||||
for(var/turf/simulated/floor/F in A)
|
||||
if(turf_clear(F))
|
||||
turfs += F
|
||||
if(turfs.len == 0)
|
||||
log_debug("[name] event: Rejected [A] because it has no clear turfs.")
|
||||
continue
|
||||
target_area = A
|
||||
target_turf = pick(turfs)
|
||||
|
||||
if(!target_area)
|
||||
log_debug("[name] event: Giving up after too many failures to pick target area")
|
||||
return
|
||||
|
||||
/datum/gm_action/swarm_boarder/start()
|
||||
if(!target_turf)
|
||||
return
|
||||
..()
|
||||
|
||||
var/swarmertype = /obj/structure/ghost_pod/ghost_activated/swarm_drone/event
|
||||
|
||||
if(severity == EVENT_LEVEL_MODERATE)
|
||||
swarmertype = /obj/structure/ghost_pod/ghost_activated/swarm_drone/event/melee
|
||||
|
||||
if(severity == EVENT_LEVEL_MAJOR)
|
||||
swarmertype = /obj/structure/ghost_pod/ghost_activated/swarm_drone/event/gunner
|
||||
|
||||
new swarmertype(target_turf)
|
||||
|
||||
/datum/gm_action/swarm_boarder/get_weight()
|
||||
return -60 + (metric.count_people_in_department(ROLE_SECURITY) * 20 + metric.count_people_in_department(ROLE_SYNTHETIC) * 5 + metric.count_people_in_department(ROLE_EVERYONE) * 1)
|
||||
|
||||
/datum/gm_action/swarm_boarder/announce()
|
||||
spawn(rand(5 MINUTES, 15 MINUTES))
|
||||
if(prob(80) && severity >= EVENT_LEVEL_MODERATE && atc && !atc.squelched)
|
||||
atc.msg("Attention civilian vessels in [using_map.starsys_name] shipping lanes, caution is advised as [pick("an unidentified vessel", "a known criminal's vessel", "a derelict vessel")] has been detected passing multiple local stations.")
|
||||
@@ -15,13 +15,22 @@
|
||||
var/next_action = 0 // Minimum amount of time of nothingness until the GM can pick something again.
|
||||
var/last_department_used = null // If an event was done for a specific department, it is written here, so it doesn't do it again.
|
||||
|
||||
|
||||
/datum/game_master/New()
|
||||
..()
|
||||
available_actions = init_subtypes(/datum/gm_action)
|
||||
for(var/datum/gm_action/action in available_actions)
|
||||
action.gm = src
|
||||
|
||||
var/config_setup_delay = TRUE
|
||||
spawn(0)
|
||||
while(config_setup_delay)
|
||||
if(config)
|
||||
config_setup_delay = FALSE
|
||||
if(config.enable_game_master)
|
||||
suspended = FALSE
|
||||
else
|
||||
sleep(30 SECONDS)
|
||||
|
||||
/datum/game_master/process()
|
||||
if(ticker && ticker.current_state == GAME_STATE_PLAYING && !suspended)
|
||||
adjust_staleness(1)
|
||||
|
||||
@@ -116,6 +116,18 @@
|
||||
|
||||
return 0
|
||||
|
||||
/datum/language/swarmbot
|
||||
name = LANGUAGE_SWARMBOT
|
||||
desc = "A confusing mechanical language spoken by some form of ancient machine."
|
||||
speech_verb = "clatters"
|
||||
ask_verb = "chatters"
|
||||
exclaim_verb = "shrieks"
|
||||
colour = "changeling"
|
||||
key = "_"
|
||||
flags = NO_STUTTER | RESTRICTED
|
||||
syllables = list("^", "v", "-", ".", "~")
|
||||
space_chance = 60
|
||||
|
||||
//for your antag purposes.
|
||||
/datum/language/minbus
|
||||
name = LANGUAGE_MINBUS
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
var/will_patrol = 0 // If set to 1, will patrol, duh
|
||||
var/patrol_speed = 1 // How many times per tick we move when patrolling
|
||||
var/target_speed = 2 // Ditto for chasing the target
|
||||
var/panic_on_alert = FALSE // Will the bot go faster when the alert level is raised?
|
||||
var/min_target_dist = 1 // How close we try to get to the target
|
||||
var/max_target_dist = 50 // How far we are willing to go
|
||||
var/max_patrol_dist = 250
|
||||
@@ -170,14 +171,20 @@
|
||||
if(!A || !A.loc || prob(1))
|
||||
ignore_list -= A
|
||||
handleRegular()
|
||||
|
||||
var/panic_speed_mod = 0
|
||||
|
||||
if(panic_on_alert)
|
||||
panic_speed_mod = handlePanic()
|
||||
|
||||
if(target && confirmTarget(target))
|
||||
if(Adjacent(target))
|
||||
handleAdjacentTarget()
|
||||
else
|
||||
handleRangedTarget()
|
||||
if(!wait_if_pulled || !pulledby)
|
||||
for(var/i = 1 to target_speed)
|
||||
sleep(20 / (target_speed + 1))
|
||||
for(var/i = 1 to (target_speed + panic_speed_mod))
|
||||
sleep(20 / (target_speed + panic_speed_mod + 1))
|
||||
stepToTarget()
|
||||
if(max_frustration && frustration > max_frustration * target_speed)
|
||||
handleFrustrated(1)
|
||||
@@ -186,7 +193,7 @@
|
||||
lookForTargets()
|
||||
if(will_patrol && !pulledby && !target)
|
||||
if(patrol_path && patrol_path.len)
|
||||
for(var/i = 1 to patrol_speed)
|
||||
for(var/i = 1 to (patrol_speed + panic_speed_mod))
|
||||
sleep(20 / (patrol_speed + 1))
|
||||
handlePatrol()
|
||||
if(max_frustration && frustration > max_frustration * patrol_speed)
|
||||
@@ -205,6 +212,32 @@
|
||||
/mob/living/bot/proc/handleRangedTarget()
|
||||
return
|
||||
|
||||
/mob/living/bot/proc/handlePanic() // Speed modification based on alert level.
|
||||
. = 0
|
||||
switch(get_security_level())
|
||||
if("green")
|
||||
. = 0
|
||||
|
||||
if("yellow")
|
||||
. = 0
|
||||
|
||||
if("violet")
|
||||
. = 0
|
||||
|
||||
if("orange")
|
||||
. = 0
|
||||
|
||||
if("blue")
|
||||
. = 1
|
||||
|
||||
if("red")
|
||||
. = 2
|
||||
|
||||
if("delta")
|
||||
. = 2
|
||||
|
||||
return .
|
||||
|
||||
/mob/living/bot/proc/stepToTarget()
|
||||
if(!target || !target.loc)
|
||||
return
|
||||
|
||||
@@ -38,6 +38,32 @@
|
||||
spawn(600)
|
||||
ignore_list -= g
|
||||
|
||||
/mob/living/bot/cleanbot/handlePanic() // Speed modification based on alert level.
|
||||
. = 0
|
||||
switch(get_security_level())
|
||||
if("green")
|
||||
. = 0
|
||||
|
||||
if("yellow")
|
||||
. = 1
|
||||
|
||||
if("violet")
|
||||
. = 1
|
||||
|
||||
if("orange")
|
||||
. = 1
|
||||
|
||||
if("blue")
|
||||
. = 2
|
||||
|
||||
if("red")
|
||||
. = 2
|
||||
|
||||
if("delta")
|
||||
. = 2
|
||||
|
||||
return .
|
||||
|
||||
/mob/living/bot/cleanbot/lookForTargets()
|
||||
for(var/obj/effect/decal/cleanable/D in view(world.view, src)) // There was some odd code to make it start with nearest decals, it's unnecessary, this works
|
||||
if(confirmTarget(D))
|
||||
|
||||
@@ -300,6 +300,32 @@
|
||||
else if(amount > maxAmount)
|
||||
amount = maxAmount
|
||||
|
||||
/mob/living/bot/floorbot/handlePanic() // Speed modification based on alert level.
|
||||
. = 0
|
||||
switch(get_security_level())
|
||||
if("green")
|
||||
. = 0
|
||||
|
||||
if("yellow")
|
||||
. = 0
|
||||
|
||||
if("violet")
|
||||
. = 0
|
||||
|
||||
if("orange")
|
||||
. = 1
|
||||
|
||||
if("blue")
|
||||
. = 1
|
||||
|
||||
if("red")
|
||||
. = 2
|
||||
|
||||
if("delta")
|
||||
. = 2
|
||||
|
||||
return .
|
||||
|
||||
/* Assembly */
|
||||
|
||||
/obj/item/weapon/storage/toolbox/mechanical/attackby(var/obj/item/stack/tile/floor/T, mob/living/user as mob)
|
||||
|
||||
@@ -49,6 +49,32 @@
|
||||
/mob/living/bot/medbot/handleAdjacentTarget()
|
||||
UnarmedAttack(target)
|
||||
|
||||
/mob/living/bot/medbot/handlePanic() // Speed modification based on alert level.
|
||||
. = 0
|
||||
switch(get_security_level())
|
||||
if("green")
|
||||
. = 0
|
||||
|
||||
if("yellow")
|
||||
. = 0
|
||||
|
||||
if("violet")
|
||||
. = 1
|
||||
|
||||
if("orange")
|
||||
. = 0
|
||||
|
||||
if("blue")
|
||||
. = 1
|
||||
|
||||
if("red")
|
||||
. = 2
|
||||
|
||||
if("delta")
|
||||
. = 2
|
||||
|
||||
return .
|
||||
|
||||
/mob/living/bot/medbot/lookForTargets()
|
||||
for(var/mob/living/carbon/human/H in view(7, src)) // Time to find a patient!
|
||||
if(confirmTarget(H))
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
patrol_speed = 2
|
||||
target_speed = 3
|
||||
|
||||
density = 1
|
||||
|
||||
var/default_icon_state = "secbot"
|
||||
var/idcheck = FALSE // If true, arrests for having weapons without authorization.
|
||||
var/check_records = FALSE // If true, arrests people without a record.
|
||||
@@ -53,6 +55,8 @@
|
||||
name = "Officer Beepsky"
|
||||
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
|
||||
will_patrol = TRUE
|
||||
maxHealth = 130
|
||||
health = 130
|
||||
|
||||
/mob/living/bot/secbot/slime
|
||||
name = "Slime Securitron"
|
||||
@@ -70,6 +74,8 @@
|
||||
/mob/living/bot/secbot/slime/slimesky
|
||||
name = "Doctor Slimesky"
|
||||
desc = "An old friend of Officer Beep O'sky. He prescribes beatings to rowdy slimes so that real doctors don't need to treat the xenobiologists."
|
||||
maxHealth = 130
|
||||
health = 130
|
||||
|
||||
/mob/living/bot/secbot/update_icons()
|
||||
if(on && busy)
|
||||
@@ -233,6 +239,32 @@
|
||||
global_announcer.autosay("[src] is [action] a level [threat] [action != "fighting" ? "suspect" : "threat"] <b>[target_name(target)]</b> in <b>[get_area(src)]</b>.", "[src]", "Security")
|
||||
UnarmedAttack(target)
|
||||
|
||||
/mob/living/bot/secbot/handlePanic() // Speed modification based on alert level.
|
||||
. = 0
|
||||
switch(get_security_level())
|
||||
if("green")
|
||||
. = 0
|
||||
|
||||
if("yellow")
|
||||
. = 0
|
||||
|
||||
if("violet")
|
||||
. = 0
|
||||
|
||||
if("orange")
|
||||
. = 0
|
||||
|
||||
if("blue")
|
||||
. = 1
|
||||
|
||||
if("red")
|
||||
. = 2
|
||||
|
||||
if("delta")
|
||||
. = 2
|
||||
|
||||
return .
|
||||
|
||||
// So Beepsky talks while beating up simple mobs.
|
||||
/mob/living/bot/secbot/proc/insult(var/mob/living/L)
|
||||
if(can_next_insult > world.time)
|
||||
|
||||
@@ -426,6 +426,10 @@
|
||||
|
||||
// Called in life() when the mob has no client.
|
||||
/datum/species/proc/handle_npc(var/mob/living/carbon/human/H)
|
||||
if(H.stat == CONSCIOUS && H.ai_holder)
|
||||
if(H.resting)
|
||||
H.resting = FALSE
|
||||
H.update_canmove()
|
||||
return
|
||||
|
||||
// Called when lying down on a water tile.
|
||||
|
||||
@@ -50,8 +50,10 @@
|
||||
if(H)
|
||||
if(H.looksSynthetic())
|
||||
return "flashing a 'system offline' light"
|
||||
else
|
||||
else if(!H.ai_holder)
|
||||
return show_ssd
|
||||
else
|
||||
return
|
||||
|
||||
/datum/species/proc/get_blood_colour(var/mob/living/carbon/human/H)
|
||||
if(H)
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
if(prob(1))
|
||||
H.emote(pick("scratch","jump","roll","tail"))
|
||||
|
||||
..()
|
||||
|
||||
/datum/species/monkey/get_random_name()
|
||||
return "[lowertext(name)] ([rand(100,999)])"
|
||||
|
||||
|
||||
@@ -60,6 +60,8 @@ var/list/mob_hat_cache = list()
|
||||
var/serial_number = 0
|
||||
var/name_override = 0
|
||||
|
||||
var/foreign_droid = FALSE
|
||||
|
||||
holder_type = /obj/item/weapon/holder/drone
|
||||
|
||||
can_be_antagged = FALSE
|
||||
@@ -117,7 +119,8 @@ var/list/mob_hat_cache = list()
|
||||
updatename()
|
||||
|
||||
/mob/living/silicon/robot/drone/init()
|
||||
aiCamera = new/obj/item/device/camera/siliconcam/drone_camera(src)
|
||||
if(!scrambledcodes && !foreign_droid)
|
||||
aiCamera = new/obj/item/device/camera/siliconcam/drone_camera(src)
|
||||
additional_law_channels["Drone"] = ":d"
|
||||
if(!laws) laws = new law_type
|
||||
if(!module) module = new module_type(src)
|
||||
@@ -252,10 +255,10 @@ var/list/mob_hat_cache = list()
|
||||
//For some goddamn reason robots have this hardcoded. Redefining it for our fragile friends here.
|
||||
/mob/living/silicon/robot/drone/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
health = 35
|
||||
health = maxHealth
|
||||
stat = CONSCIOUS
|
||||
return
|
||||
health = 35 - (getBruteLoss() + getFireLoss())
|
||||
health = maxHealth - (getBruteLoss() + getFireLoss())
|
||||
return
|
||||
|
||||
//Easiest to check this here, then check again in the robot proc.
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
for(var/mob/living/silicon/robot/drone/D in mob_list)
|
||||
if(D.z != src.z)
|
||||
continue
|
||||
if(D.foreign_droid)
|
||||
continue
|
||||
|
||||
dat += "<BR>[D.real_name] ([D.stat == 2 ? "<font color='red'>INACTIVE</FONT>" : "<font color='green'>ACTIVE</FONT>"])"
|
||||
dat += "<font dize = 9><BR>Cell charge: [D.cell.charge]/[D.cell.maxcharge]."
|
||||
dat += "<BR>Currently located in: [get_area(D)]."
|
||||
|
||||
@@ -56,6 +56,22 @@
|
||||
/obj/item/weapon/stock_parts
|
||||
)
|
||||
|
||||
/obj/item/weapon/gripper/security
|
||||
name = "security gripper"
|
||||
desc = "A simple grasping tool for corporate security work."
|
||||
icon_state = "gripper-sec"
|
||||
|
||||
can_hold = list(
|
||||
/obj/item/weapon/paper,
|
||||
/obj/item/weapon/paper_bundle,
|
||||
/obj/item/weapon/pen,
|
||||
/obj/item/weapon/sample,
|
||||
/obj/item/weapon/forensics/sample_kit,
|
||||
/obj/item/device/taperecorder,
|
||||
/obj/item/device/tape,
|
||||
/obj/item/device/uv_light
|
||||
)
|
||||
|
||||
/obj/item/weapon/gripper/paperwork
|
||||
name = "paperwork gripper"
|
||||
desc = "A simple grasping tool for clerical work."
|
||||
|
||||
98
code/modules/mob/living/silicon/robot/drone/swarm.dm
Normal file
@@ -0,0 +1,98 @@
|
||||
/mob/living/silicon/robot/drone/swarm
|
||||
name = "swarm drone"
|
||||
real_name = "drone"
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "swarmer"
|
||||
faction = "swarmer"
|
||||
maxHealth = 75
|
||||
health = 75
|
||||
cell_emp_mult = 0.5
|
||||
universal_speak = 0
|
||||
universal_understand = 1
|
||||
gender = NEUTER
|
||||
pass_flags = PASSTABLE
|
||||
braintype = "Drone"
|
||||
lawupdate = 0
|
||||
density = 1
|
||||
idcard_type = /obj/item/weapon/card/id/syndicate
|
||||
req_access = list(999)
|
||||
integrated_light_power = 3
|
||||
local_transmit = 0
|
||||
|
||||
can_pull_size = ITEMSIZE_NO_CONTAINER
|
||||
can_pull_mobs = MOB_PULL_SMALLER
|
||||
can_enter_vent_with = list(
|
||||
/obj)
|
||||
|
||||
mob_always_swap = 1
|
||||
|
||||
softfall = TRUE
|
||||
|
||||
mob_size = MOB_LARGE
|
||||
|
||||
law_type = /datum/ai_laws/swarm_drone
|
||||
module_type = /obj/item/weapon/robot_module/drone/swarm
|
||||
|
||||
hat_x_offset = 0
|
||||
hat_y_offset = -10
|
||||
|
||||
foreign_droid = TRUE
|
||||
scrambledcodes = TRUE
|
||||
|
||||
holder_type = /obj/item/weapon/holder/drone
|
||||
|
||||
can_be_antagged = TRUE
|
||||
|
||||
var/spell_setup = list(
|
||||
/spell/aoe_turf/conjure/swarmer,
|
||||
/spell/aoe_turf/conjure/forcewall/swarm,
|
||||
/spell/aoe_turf/blink/swarm,
|
||||
/spell/aoe_turf/conjure/swarmer/gunner,
|
||||
/spell/aoe_turf/conjure/swarmer/melee
|
||||
)
|
||||
|
||||
/mob/living/silicon/robot/drone/swarm/Initialize()
|
||||
..()
|
||||
|
||||
add_language(LANGUAGE_SWARMBOT, 1)
|
||||
|
||||
for(var/spell in spell_setup)
|
||||
src.add_spell(new spell, "nano_spell_ready", /obj/screen/movable/spell_master/swarm)
|
||||
|
||||
/mob/living/silicon/robot/drone/swarm/init()
|
||||
..()
|
||||
QDEL_NULL(aiCamera)
|
||||
flavor_text = "Some form of ancient machine."
|
||||
|
||||
/mob/living/silicon/robot/drone/swarm/gunner
|
||||
name = "swarm gunner"
|
||||
real_name = "drone"
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "swarmer_ranged"
|
||||
faction = "swarmer"
|
||||
|
||||
law_type = /datum/ai_laws/swarm_drone/soldier
|
||||
module_type = /obj/item/weapon/robot_module/drone/swarm/ranged
|
||||
|
||||
spell_setup = list(
|
||||
/spell/aoe_turf/conjure/swarmer,
|
||||
/spell/aoe_turf/conjure/forcewall/swarm,
|
||||
/spell/aoe_turf/blink/swarm
|
||||
)
|
||||
|
||||
/mob/living/silicon/robot/drone/swarm/melee
|
||||
name = "swarm melee"
|
||||
real_name = "drone"
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "swarmer_melee"
|
||||
faction = "swarmer"
|
||||
|
||||
law_type = /datum/ai_laws/swarm_drone/soldier
|
||||
module_type = /obj/item/weapon/robot_module/drone/swarm/melee
|
||||
|
||||
spell_setup = list(
|
||||
/spell/aoe_turf/conjure/swarmer,
|
||||
/spell/aoe_turf/conjure/forcewall/swarm,
|
||||
/spell/aoe_turf/blink/swarm
|
||||
)
|
||||
|
||||
117
code/modules/mob/living/silicon/robot/drone/swarm_abilities.dm
Normal file
@@ -0,0 +1,117 @@
|
||||
|
||||
/spell/aoe_turf/conjure/swarmer
|
||||
name = "Self Replication"
|
||||
desc = "This ability constructs a standard swarmer shell that may activate at some point."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120 SECONDS
|
||||
spell_flags = 0
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/ghost_pod/ghost_activated/swarm_drone/event)
|
||||
|
||||
hud_state = "swarm_replicate"
|
||||
|
||||
/spell/aoe_turf/conjure/swarmer/conjure_animation(var/atom/movable/overlay/animation, var/turf/target)
|
||||
animation.icon_state = "deflect_static"
|
||||
flick("shield2",animation)
|
||||
spawn(1 SECOND)
|
||||
qdel(animation)
|
||||
|
||||
/spell/aoe_turf/conjure/forcewall/swarm
|
||||
name = "Null-Field"
|
||||
desc = "Create a bubble of null-point energy."
|
||||
summon_type = list(/obj/effect/forcefield/swarm)
|
||||
duration = 30 SECONDS
|
||||
charge_max = 60 SECONDS
|
||||
|
||||
school = "conjuration"
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
hud_state = "wiz_shield"
|
||||
|
||||
/obj/effect/forcefield/swarm
|
||||
desc = "A pocket of strange energy."
|
||||
name = "Null-Field"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "shield-old"
|
||||
invisibility = 0
|
||||
|
||||
/spell/aoe_turf/conjure/zeropointwell
|
||||
name = "Zero-Point Well"
|
||||
desc = "This ability constructs a standard zero-point energy well, capable of charging nearby swarmers."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120 SECONDS
|
||||
spell_flags = 0
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/cult/pylon/swarm/zp_well)
|
||||
|
||||
hud_state = "swarm_zeropoint"
|
||||
|
||||
/spell/aoe_turf/conjure/zeropointbarricade
|
||||
name = "Zero-Point Barricade"
|
||||
desc = "This ability constructs a standard zero-point energy wall, used to create a secure passageway for allies, and a bastion for defense."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120 SECONDS
|
||||
spell_flags = 0
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/cult/pylon/swarm/defender)
|
||||
|
||||
hud_state = "swarm_barricade"
|
||||
|
||||
/spell/aoe_turf/blink/swarm
|
||||
name = "Warp"
|
||||
desc = "Your null-point drive jaunts you to a new location."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 5 MINUTES
|
||||
spell_flags = Z2NOCAST | IGNOREDENSE
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 10
|
||||
inner_radius = 5
|
||||
hud_state = "swarm_warp"
|
||||
|
||||
/spell/aoe_turf/conjure/swarmer/gunner
|
||||
name = "Generate Gunner"
|
||||
desc = "This spell constructs a gunner swarmer shell that may activate at some point."
|
||||
|
||||
school = "conjuration"
|
||||
charge_type = Sp_CHARGES
|
||||
charge_max = 1
|
||||
spell_flags = 0
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/gunner)
|
||||
|
||||
hud_state = "swarm_replicate"
|
||||
|
||||
/spell/aoe_turf/conjure/swarmer/melee
|
||||
name = "Generate Impaler"
|
||||
desc = "This spell constructs an impaler swarmer shell that may activate at some point."
|
||||
|
||||
school = "conjuration"
|
||||
charge_type = Sp_CHARGES
|
||||
charge_max = 1
|
||||
spell_flags = 0
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/melee)
|
||||
|
||||
hud_state = "swarm_replicate"
|
||||
162
code/modules/mob/living/silicon/robot/drone/swarm_items.dm
Normal file
@@ -0,0 +1,162 @@
|
||||
|
||||
//Swarm Assimilator / Breacher
|
||||
/obj/item/weapon/matter_decompiler/swarm
|
||||
name = "matter assimilator"
|
||||
desc = "Used to eat some forms of simple machinery; and large, wall-shaped blocks of metal with energetic fields."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "decompiler_swarm"
|
||||
|
||||
var/field_cooldown = 1 MINUTE
|
||||
var/last_field = 0
|
||||
|
||||
/obj/item/weapon/matter_decompiler/swarm/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
|
||||
|
||||
if(!proximity) return //Not adjacent.
|
||||
|
||||
//We only want to deal with using this on turfs. Specific items aren't important.
|
||||
var/turf/T = get_turf(target)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
//Used to give the right message.
|
||||
var/grabbed_something = FALSE
|
||||
|
||||
for(var/mob/M in T)
|
||||
if(istype(M,/mob/living/simple_mob/animal/passive/lizard) || istype(M,/mob/living/simple_mob/animal/passive/mouse))
|
||||
src.loc.visible_message("<span class='danger'>[src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.</span>","<span class='danger'>It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.</span>")
|
||||
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
|
||||
qdel(M)
|
||||
if(wood)
|
||||
wood.add_charge(2000)
|
||||
if(plastic)
|
||||
plastic.add_charge(2000)
|
||||
return
|
||||
|
||||
else if(istype(M,/mob/living/silicon/robot/drone) && !M.client)
|
||||
|
||||
var/mob/living/silicon/robot/D = src.loc
|
||||
|
||||
if(!istype(D))
|
||||
return
|
||||
|
||||
to_chat(D, "<span class='danger'>You begin decompiling [M].</span>")
|
||||
|
||||
if(!do_after(D,50))
|
||||
to_chat(D, "<span class='danger'>You need to remain still while decompiling such a large object.</span>")
|
||||
return
|
||||
|
||||
if(!M || !D) return
|
||||
|
||||
to_chat(D, "<span class='danger'>You carefully and thoroughly decompile [M], storing as much of its resources as you can within yourself.</span>")
|
||||
qdel(M)
|
||||
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
|
||||
|
||||
if(metal)
|
||||
metal.add_charge(15000)
|
||||
if(glass)
|
||||
glass.add_charge(15000)
|
||||
if(wood)
|
||||
wood.add_charge(2000)
|
||||
if(plastic)
|
||||
plastic.add_charge(1000)
|
||||
return
|
||||
else
|
||||
continue
|
||||
|
||||
for(var/obj/W in T)
|
||||
//Different classes of items give different commodities.
|
||||
if(istype(W,/obj/structure/girder))
|
||||
if(metal)
|
||||
metal.add_charge(500)
|
||||
else if(istype(W,/obj/machinery/power/emitter))
|
||||
if(metal)
|
||||
metal.add_charge(3000)
|
||||
if(plastic)
|
||||
plastic.add_charge(1000)
|
||||
else if(istype(W,/obj/machinery/space_heater))
|
||||
if(metal)
|
||||
metal.add_charge(1500)
|
||||
if(plastic)
|
||||
plastic.add_charge(750)
|
||||
else if(istype(W,/obj/structure/closet))
|
||||
var/obj/structure/closet/C = W
|
||||
if(!C.opened)
|
||||
continue
|
||||
if(istype(W,/obj/structure/closet/coffin))
|
||||
if(wood)
|
||||
wood.add_charge(1000)
|
||||
else if(istype(W,/obj/structure/closet/crate/plastic))
|
||||
if(plastic)
|
||||
plastic.add_charge(750)
|
||||
else
|
||||
if(metal)
|
||||
metal.add_charge(1000)
|
||||
else
|
||||
continue
|
||||
|
||||
qdel(W)
|
||||
grabbed_something = TRUE
|
||||
|
||||
if(istype(T,/turf/simulated/wall) && (last_field < world.time + field_cooldown))
|
||||
if(!(locate(/obj/effect/temporary_effect/pulse/disintegrate)))
|
||||
last_field = world.time
|
||||
to_chat(user, "<span class='alien'>You deploy an energetic field through \the [T], beginning its deconstruction.</span>")
|
||||
to_chat(user, "<span class='warning'>You should stand back.</span>")
|
||||
new /obj/effect/temporary_effect/pulse/disintegrate(T)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There is already a disintigration field affecting \the [T].</span>")
|
||||
|
||||
if(grabbed_something)
|
||||
to_chat(user, "<span class='notice'>You deploy your decompiler and clear out the contents of \the [T].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Nothing on \the [T] is useful to you.</span>")
|
||||
return
|
||||
|
||||
/obj/effect/temporary_effect/pulse/disintegrate
|
||||
name = "molecular debonding field"
|
||||
desc = "This is something you do not want to near."
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "disintegrate_pulse"
|
||||
light_range = 4
|
||||
light_power = 5
|
||||
light_color = "#00B4D9"
|
||||
pulses_remaining = 5
|
||||
pulse_delay = 2 SECONDS
|
||||
|
||||
/obj/effect/temporary_effect/pulse/disintegrate/emp_act()
|
||||
visible_message("<span class='warning'>\The [src] flickers, before dispersing energetically.</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/temporary_effect/pulse/disintegrate/on_pulse()
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T,/turf/simulated/wall))
|
||||
explosion(get_turf(src), -1, -1, 1, 3, adminlog = 0)
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/temporary_effect/pulse/disintegrate/Destroy()
|
||||
if(istype(get_turf(src), /turf/simulated/wall))
|
||||
explosion(get_turf(src), -1, 1, 2, 5, adminlog = 1)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/xray/swarm
|
||||
name = "spectral projector"
|
||||
desc = "A high-power laser gun capable of expelling concentrated gamma blasts, which are able to penetrate matter easier than \
|
||||
standard xray beams, resulting in an effective 'anti-everything' energy weapon."
|
||||
icon_state = "xray"
|
||||
item_state = "xray"
|
||||
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 3, TECH_MAGNET = 2)
|
||||
projectile_type = /obj/item/projectile/beam/shock
|
||||
charge_cost = 175
|
||||
|
||||
self_recharge = TRUE
|
||||
use_external_power = TRUE
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="kill", projectile_type=/obj/item/projectile/beam/gamma, charge_cost = 300),
|
||||
list(mode_name="deter", projectile_type=/obj/item/projectile/beam/shock, charge_cost = 175),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/energy/xray/swarm/Initialize()
|
||||
..()
|
||||
adjust_scale(-1, 1)
|
||||
@@ -526,6 +526,7 @@ var/global/list/robot_modules = list(
|
||||
// src.modules += new /obj/item/weapon/gun/energy/taser/xeno/sec/robot(src) // VOREStation Edit - We don't need these
|
||||
src.modules += new /obj/item/taperoll/police(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/spray/pepper(src)
|
||||
src.modules += new /obj/item/weapon/gripper/security(src)
|
||||
src.emag = new /obj/item/weapon/gun/energy/laser/mounted(src)
|
||||
|
||||
/obj/item/weapon/robot_module/robot/security/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
|
||||
29
code/modules/mob/living/silicon/robot/robot_modules/swarm.dm
Normal file
@@ -0,0 +1,29 @@
|
||||
/obj/item/weapon/robot_module/drone/swarm
|
||||
name = "swarm drone module"
|
||||
var/id
|
||||
|
||||
/obj/item/weapon/robot_module/drone/swarm/New(var/mob/living/silicon/robot/robot)
|
||||
..()
|
||||
|
||||
id = robot.idcard
|
||||
src.modules += id
|
||||
|
||||
src.modules += new /obj/item/weapon/rcd/electric/mounted/borg/swarm(src)
|
||||
src.modules += new /obj/item/device/flash/robot(src)
|
||||
src.modules += new /obj/item/weapon/handcuffs/cable/tape/cyborg(src)
|
||||
src.modules += new /obj/item/weapon/melee/baton/robot(src)
|
||||
src.modules += new /obj/item/weapon/gun/energy/taser/mounted/cyborg/swarm(src)
|
||||
src.modules += new /obj/item/weapon/matter_decompiler/swarm(src)
|
||||
|
||||
/obj/item/weapon/robot_module/drone/swarm/ranged
|
||||
name = "swarm gunner module"
|
||||
|
||||
/obj/item/weapon/robot_module/drone/swarm/ranged/New(var/mob/living/silicon/robot/robot)
|
||||
..()
|
||||
|
||||
src.modules += new /obj/item/weapon/gun/energy/xray/swarm(src)
|
||||
|
||||
/obj/item/weapon/robot_module/drone/swarm/melee/New(var/mob/living/silicon/robot/robot)
|
||||
..()
|
||||
|
||||
src.modules += new /obj/item/weapon/melee/energy/sword/ionic_rapier/lance(src)
|
||||
@@ -117,3 +117,17 @@
|
||||
if(prob(poison_chance))
|
||||
to_chat(L, "<span class='warning'>You feel a tiny prick.</span>")
|
||||
L.reagents.add_reagent(poison_type, poison_per_bite)
|
||||
|
||||
/mob/living/simple_mob/animal/giant_spider/proc/make_spiderling()
|
||||
adjust_scale(icon_scale_x * 0.7, icon_scale_y * 0.7)
|
||||
maxHealth = round(maxHealth * 0.5)
|
||||
health = round(health * 0.5)
|
||||
melee_damage_lower *= 0.7
|
||||
melee_damage_upper *= 0.7
|
||||
|
||||
response_harm = "kicks"
|
||||
|
||||
see_in_dark = max(2, round(see_in_dark * 0.6))
|
||||
|
||||
if(poison_per_bite)
|
||||
poison_per_bite *= 1.3
|
||||
|
||||
@@ -22,3 +22,23 @@
|
||||
speak_emote = list("hisses")
|
||||
|
||||
say_list_type = /datum/say_list/lizard
|
||||
|
||||
/mob/living/simple_mob/animal/passive/lizard/large
|
||||
desc = "A cute, big lizard."
|
||||
maxHealth = 20
|
||||
health = 20
|
||||
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 15
|
||||
|
||||
attack_sharp = TRUE
|
||||
|
||||
/mob/living/simple_mob/animal/passive/lizard/large/Initialize()
|
||||
..()
|
||||
adjust_scale(rand(12, 20) / 10)
|
||||
|
||||
/mob/living/simple_mob/animal/passive/lizard/large/defensive
|
||||
maxHealth = 30
|
||||
health = 30
|
||||
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/retaliate/cooperative
|
||||
|
||||
@@ -103,6 +103,17 @@
|
||||
body_color = "brown"
|
||||
icon_state = "mouse_brown"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/mouse/rat
|
||||
name = "rat"
|
||||
maxHealth = 20
|
||||
health = 20
|
||||
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive
|
||||
|
||||
/mob/living/simple_mob/animal/passive/mouse/rat/Initialize()
|
||||
..()
|
||||
adjust_scale(1.2)
|
||||
|
||||
//TOM IS ALIVE! SQUEEEEEEEE~K :)
|
||||
/mob/living/simple_mob/animal/passive/mouse/brown/Tom
|
||||
name = "Tom"
|
||||
|
||||
@@ -425,6 +425,20 @@ proc/is_blind(A)
|
||||
lname = "<span class='name'>[lname]</span> "
|
||||
M << "<span class='deadsay'>" + create_text_tag("dead", "DEAD:", M.client) + " [lname][follow][message]</span>"
|
||||
|
||||
/proc/say_dead_object(var/message, var/obj/subject = null)
|
||||
for(var/mob/M in player_list)
|
||||
if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || (M.client.holder && M.client.holder.rights)) && M.is_preference_enabled(/datum/client_preference/show_dsay))
|
||||
var/follow
|
||||
var/lname = "Game Master"
|
||||
if(M.forbid_seeing_deadchat && !M.client.holder)
|
||||
continue
|
||||
|
||||
if(subject)
|
||||
lname = "[subject.name] ([subject.x],[subject.y],[subject.z])"
|
||||
|
||||
lname = "<span class='name'>[lname]</span> "
|
||||
M << "<span class='deadsay'>" + create_text_tag("event_dead", "EVENT:", M.client) + " [lname][follow][message]</span>"
|
||||
|
||||
//Announces that a ghost has joined/left, mainly for use with wizards
|
||||
/proc/announce_ghost_joinleave(O, var/joined_ghosts = 1, var/message = "")
|
||||
var/client/C
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
charge_cost = 400
|
||||
recharge_time = 7 //Time it takes for shots to recharge (in ticks)
|
||||
|
||||
/obj/item/weapon/gun/energy/taser/mounted/cyborg/swarm
|
||||
name = "disabler"
|
||||
desc = "An archaic device which attacks the target's nervous-system or control circuits."
|
||||
projectile_type = /obj/item/projectile/beam/stun/disabler
|
||||
charge_cost = 200
|
||||
recharge_time = 0.5 SECONDS
|
||||
|
||||
/obj/item/weapon/gun/energy/stunrevolver
|
||||
name = "stun revolver"
|
||||
@@ -32,7 +38,6 @@
|
||||
projectile_type = /obj/item/projectile/energy/electrode/strong
|
||||
charge_cost = 300
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/crossbow
|
||||
name = "mini energy-crossbow"
|
||||
desc = "A weapon favored by many mercenary stealth specialists."
|
||||
|
||||
@@ -108,3 +108,89 @@
|
||||
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_handed_penalty=15, burst_accuracy=null, dispersion=null),
|
||||
list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_handed_penalty=30, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0)),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/magnetic/railgun/heater
|
||||
name = "coil rifle"
|
||||
desc = "A large rifle designed and produced after the Grey Hour."
|
||||
description_info = "The MI-51B is a Martian weapon designed in the days after the Grey Hour, in preparation for the need for updated equipment by Solar forces.<br>\
|
||||
The design is based upon a larger rail-type weapon design."
|
||||
icon_state = "railgun_sec"
|
||||
item_state = "cshotgun"
|
||||
|
||||
removable_components = TRUE
|
||||
|
||||
initial_cell_type = /obj/item/weapon/cell/high
|
||||
initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor
|
||||
|
||||
fire_delay = 8
|
||||
|
||||
slot_flags = SLOT_BACK
|
||||
|
||||
slowdown = 0
|
||||
slowdown_held = 0
|
||||
slowdown_worn = 0
|
||||
|
||||
power_cost = 400
|
||||
projectile_type = /obj/item/projectile/bullet/magnetic/heated
|
||||
loaded = null
|
||||
empty_sound = 'sound/weapons/smg_empty_alarm.ogg'
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="high power", power_cost = 400, projectile_type = /obj/item/projectile/bullet/magnetic/heated, burst=1, fire_delay=8, move_delay=null, one_handed_penalty=15),
|
||||
list(mode_name="low power", power_cost = 150, projectile_type = /obj/item/projectile/bullet/magnetic/heated/weak, burst=1, fire_delay=5, move_delay=null, one_handed_penalty=15),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/magnetic/railgun/heater/pistol
|
||||
name = "coil pistol"
|
||||
desc = "A large pistol designed and produced after the Grey Hour."
|
||||
description_info = "The MI-60D `Peacemaker` is a Martian weapon designed in the days after the Grey Hour, in preparation for the need for updated equipment by Solar forces.<br>\
|
||||
The design is based upon a larger rail-type hybrid weapon design, though much smaller in scale."
|
||||
icon_state = "peacemaker"
|
||||
item_state = "revolver"
|
||||
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
|
||||
initial_cell_type = /obj/item/weapon/cell/high
|
||||
initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor
|
||||
|
||||
slot_flags = SLOT_BELT|SLOT_HOLSTER
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="lethal", power_cost = 2000, projectile_type = /obj/item/projectile/bullet/magnetic/heated, burst=1, fire_delay=8, move_delay=null, one_handed_penalty=0),
|
||||
list(mode_name="stun", power_cost = 1500, projectile_type = /obj/item/projectile/energy/electrode/stunshot, burst=1, fire_delay=5, move_delay=null, one_handed_penalty=0),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/magnetic/railgun/heater/pistol/hos
|
||||
name = "prototype peacemaker"
|
||||
|
||||
dna_lock = TRUE
|
||||
|
||||
description_antag = "This weapon starts with a DNA locking chip attached. Using an EMAG on the weapon will disarm it, and allow you to use the chip as your own."
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="lethal", power_cost = 1500, projectile_type = /obj/item/projectile/bullet/magnetic/heated, burst=1, fire_delay=8, move_delay=null, one_handed_penalty=0),
|
||||
list(mode_name="stun", power_cost = 1200, projectile_type = /obj/item/projectile/energy/electrode/stunshot, burst=1, fire_delay=5, move_delay=null, one_handed_penalty=0),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/magnetic/railgun/flechette/sif
|
||||
name = "shredder rifle"
|
||||
desc = "The MI-12B Kaldr is a burst fire capable coilgun that fires modified slugs intended for damaging soft targets."
|
||||
description_fluff = "The Kaldr is a weapon recently deployed to various outposts on Sif, as well as local hunting guilds for the rapid dispatching of invasive wildlife."
|
||||
icon_state = "railgun_sifguard"
|
||||
item_state = "z8carbine"
|
||||
|
||||
initial_cell_type = /obj/item/weapon/cell/high
|
||||
initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor/adv
|
||||
|
||||
slot_flags = SLOT_BACK
|
||||
|
||||
slowdown = 0.3
|
||||
|
||||
power_cost = 200
|
||||
projectile_type = /obj/item/projectile/bullet/magnetic/flechette/hunting
|
||||
empty_sound = 'sound/weapons/smg_empty_alarm.ogg'
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_handed_penalty=15, burst_accuracy=null, dispersion=null),
|
||||
list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_handed_penalty=30, burst_accuracy=list(0,-15,-15), dispersion=list(0.0, 0.6, 1.0)),
|
||||
)
|
||||
|
||||
@@ -86,6 +86,19 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/xray
|
||||
impact_type = /obj/effect/projectile/impact/xray
|
||||
|
||||
/obj/item/projectile/beam/gamma
|
||||
name = "gamma beam"
|
||||
icon_state = "xray"
|
||||
fire_sound = 'sound/weapons/eluger.ogg'
|
||||
damage = 10
|
||||
armor_penetration = 90
|
||||
irradiate = 20
|
||||
light_color = "#00CC33"
|
||||
|
||||
muzzle_type = /obj/effect/projectile/muzzle/xray
|
||||
tracer_type = /obj/effect/projectile/tracer/xray
|
||||
impact_type = /obj/effect/projectile/impact/xray
|
||||
|
||||
/obj/item/projectile/beam/cyan
|
||||
name = "cyan beam"
|
||||
icon_state = "cyan"
|
||||
@@ -215,6 +228,23 @@
|
||||
icon_state = "stun"
|
||||
agony = 30
|
||||
|
||||
/obj/item/projectile/beam/stun/disabler
|
||||
muzzle_type = /obj/effect/projectile/muzzle/laser_omni
|
||||
tracer_type = /obj/effect/projectile/tracer/laser_omni
|
||||
impact_type = /obj/effect/projectile/impact/laser_omni
|
||||
|
||||
/obj/item/projectile/beam/stun/disabler/on_hit(atom/target, blocked = 0, def_zone)
|
||||
. = ..(target, blocked, def_zone)
|
||||
|
||||
if(. && istype(target, /mob/living/silicon/robot) && prob(agony))
|
||||
var/mob/living/silicon/robot/R = target
|
||||
var/drainamt = agony * (rand(5, 15) / 10)
|
||||
R.drain_power(0, 0, drainamt)
|
||||
if(istype(firer, /mob/living/silicon/robot)) // Mischevious sappers, the swarm drones are.
|
||||
var/mob/living/silicon/robot/A = firer
|
||||
if(A.cell)
|
||||
A.cell.give(drainamt * 2)
|
||||
|
||||
/obj/item/projectile/beam/shock
|
||||
name = "shock beam"
|
||||
icon_state = "lightning"
|
||||
|
||||
@@ -22,6 +22,28 @@
|
||||
damage = 20
|
||||
armor_penetration = 100
|
||||
|
||||
/obj/item/projectile/bullet/magnetic/flechette/hunting
|
||||
name = "shredder slug"
|
||||
armor_penetration = 30
|
||||
SA_bonus_damage = 40
|
||||
SA_vulnerability = SA_ANIMAL
|
||||
|
||||
/obj/item/projectile/bullet/magnetic/heated
|
||||
name = "slug"
|
||||
icon_state = "gauss"
|
||||
weaken = 0
|
||||
stun = 0
|
||||
damage = 30
|
||||
damage_type = SEARING
|
||||
embed_chance = 0
|
||||
|
||||
/obj/item/projectile/bullet/magnetic/heated/weak
|
||||
icon_state = "gauss_silenced"
|
||||
damage = 15
|
||||
agony = 5
|
||||
embed_chance = 0
|
||||
armor_penetration = 50
|
||||
|
||||
/obj/item/projectile/bullet/magnetic/fuelrod
|
||||
name = "fuel rod"
|
||||
icon_state = "fuel-deuterium"
|
||||
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 73 KiB |
BIN
icons/mob/swarmbot.dmi
Normal file
|
After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
@@ -483,6 +483,7 @@
|
||||
#include "code\game\antagonist\station\renegade.dm"
|
||||
#include "code\game\antagonist\station\revolutionary.dm"
|
||||
#include "code\game\antagonist\station\rogue_ai.dm"
|
||||
#include "code\game\antagonist\station\stowaway.dm"
|
||||
#include "code\game\antagonist\station\thug.dm"
|
||||
#include "code\game\antagonist\station\traitor.dm"
|
||||
#include "code\game\area\ai_monitored.dm"
|
||||
@@ -1308,6 +1309,7 @@
|
||||
#include "code\game\objects\structures\flora\grass.dm"
|
||||
#include "code\game\objects\structures\flora\trees.dm"
|
||||
#include "code\game\objects\structures\ghost_pods\ghost_pods.dm"
|
||||
#include "code\game\objects\structures\ghost_pods\human.dm"
|
||||
#include "code\game\objects\structures\ghost_pods\mysterious.dm"
|
||||
#include "code\game\objects\structures\ghost_pods\silicon.dm"
|
||||
#include "code\game\objects\structures\ghost_pods\silicon_vr.dm"
|
||||
@@ -1319,6 +1321,7 @@
|
||||
#include "code\game\objects\structures\props\projectile_lock.dm"
|
||||
#include "code\game\objects\structures\props\prop.dm"
|
||||
#include "code\game\objects\structures\props\puzzledoor.dm"
|
||||
#include "code\game\objects\structures\props\swarm.dm"
|
||||
#include "code\game\objects\structures\props\transmitter.dm"
|
||||
#include "code\game\objects\structures\stool_bed_chair_nest\alien_nests.dm"
|
||||
#include "code\game\objects\structures\stool_bed_chair_nest\bed.dm"
|
||||
@@ -1770,6 +1773,7 @@
|
||||
#include "code\modules\detectivework\tools\luminol.dm"
|
||||
#include "code\modules\detectivework\tools\rag.dm"
|
||||
#include "code\modules\detectivework\tools\sample_kits.dm"
|
||||
#include "code\modules\detectivework\tools\scanner.dm"
|
||||
#include "code\modules\detectivework\tools\storage.dm"
|
||||
#include "code\modules\detectivework\tools\swabs.dm"
|
||||
#include "code\modules\detectivework\tools\uvlight.dm"
|
||||
@@ -1913,12 +1917,15 @@
|
||||
#include "code\modules\gamemaster\actions\carp_migration.dm"
|
||||
#include "code\modules\gamemaster\actions\carp_migration_vr.dm"
|
||||
#include "code\modules\gamemaster\actions\comms_blackout.dm"
|
||||
#include "code\modules\gamemaster\actions\drill_announcement.dm"
|
||||
#include "code\modules\gamemaster\actions\dust.dm"
|
||||
#include "code\modules\gamemaster\actions\electrical_storm.dm"
|
||||
#include "code\modules\gamemaster\actions\electrified_door.dm"
|
||||
#include "code\modules\gamemaster\actions\gravity.dm"
|
||||
#include "code\modules\gamemaster\actions\grid_check.dm"
|
||||
#include "code\modules\gamemaster\actions\infestation.dm"
|
||||
#include "code\modules\gamemaster\actions\ion_storm.dm"
|
||||
#include "code\modules\gamemaster\actions\manifest_malfunction.dm"
|
||||
#include "code\modules\gamemaster\actions\meteor_defense.dm"
|
||||
#include "code\modules\gamemaster\actions\money_hacker.dm"
|
||||
#include "code\modules\gamemaster\actions\money_lotto.dm"
|
||||
@@ -1928,13 +1935,19 @@
|
||||
#include "code\modules\gamemaster\actions\radiation_storm.dm"
|
||||
#include "code\modules\gamemaster\actions\random_antagonist.dm"
|
||||
#include "code\modules\gamemaster\actions\rogue_drones.dm"
|
||||
#include "code\modules\gamemaster\actions\security_advisement.dm"
|
||||
#include "code\modules\gamemaster\actions\shipping_error.dm"
|
||||
#include "code\modules\gamemaster\actions\solar_storm.dm"
|
||||
#include "code\modules\gamemaster\actions\spacevine.dm"
|
||||
#include "code\modules\gamemaster\actions\spider_infestation.dm"
|
||||
#include "code\modules\gamemaster\actions\spontaneous_appendicitis.dm"
|
||||
#include "code\modules\gamemaster\actions\station_fundraise.dm"
|
||||
#include "code\modules\gamemaster\actions\stowaway.dm"
|
||||
#include "code\modules\gamemaster\actions\supply_conversion.dm"
|
||||
#include "code\modules\gamemaster\actions\supplyrequest.dm"
|
||||
#include "code\modules\gamemaster\actions\surprise_carp_attack.dm"
|
||||
#include "code\modules\gamemaster\actions\surprise_meteor.dm"
|
||||
#include "code\modules\gamemaster\actions\swarmboarder.dm"
|
||||
#include "code\modules\gamemaster\actions\viral_infection.dm"
|
||||
#include "code\modules\gamemaster\actions\viral_outbreak.dm"
|
||||
#include "code\modules\gamemaster\actions\wallrot.dm"
|
||||
@@ -2379,11 +2392,21 @@
|
||||
#include "code\modules\mob\living\silicon\robot\drone\drone_items.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\drone\drone_manufacturer.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\drone\drone_say.dm"
|
||||
<<<<<<< HEAD:vorestation.dme
|
||||
#include "code\modules\mob\living\silicon\robot\drone\drone_vr.dm"
|
||||
=======
|
||||
#include "code\modules\mob\living\silicon\robot\drone\swarm.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\drone\swarm_abilities.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\drone\swarm_items.dm"
|
||||
>>>>>>> 7ecdcb4... Security / PseudoCargo Expansion (#6482):polaris.dme
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules\event.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules\event_vr.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules\station.dm"
|
||||
<<<<<<< HEAD:vorestation.dme
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules\station_vr.dm"
|
||||
=======
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules\swarm.dm"
|
||||
>>>>>>> 7ecdcb4... Security / PseudoCargo Expansion (#6482):polaris.dme
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules\syndicate.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\subtypes\gravekeeper.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\subtypes\lost_drone.dm"
|
||||
|
||||