Merge remote-tracking branch 'refs/remotes/PolarisSS13/master' into jukebox-v2

This commit is contained in:
Spades
2016-10-04 16:06:18 -04:00
72 changed files with 776 additions and 284 deletions

View File

@@ -0,0 +1,6 @@
/datum/controller/process/game_master/setup()
name = "\improper GM controller"
schedule_interval = 600 // every 60 seconds
/datum/controller/process/game_master/doWork()
game_master.process()

View File

@@ -34,7 +34,7 @@ var/list/all_supply_groups = list("Atmospherics",
var/access = null
var/hidden = 0
var/contraband = 0
var/group = "Operations"
var/group = "Miscellaneous"
/datum/supply_packs/New()
manifest += "<ul>"

View File

@@ -203,6 +203,11 @@
name = "warning cone"
icon_state = "cone"
/obj/item/weapon/caution/cone/candy
desc = "This cone is trying to warn you of something! It has been painted to look like candy corn."
name = "candy cone"
icon_state = "candycone"
/*/obj/item/weapon/syndicate_uplink
name = "station bounced radio"
desc = "Remain silent about this..."

View File

@@ -10,3 +10,4 @@
auto_recall_shuttle = 0
antag_tags = list(MODE_MALFUNCTION)
disabled_jobs = list("AI")
votable = 0

View File

@@ -1,5 +1,5 @@
/datum/game_mode/conflux
name = "Technomancer & Cult"
name = "Technomancers & Cult"
round_description = "A space wizard and a cult have invaded the station!"
extended_round_description = "Cultists and wizards spawn during this round."
config_tag = "conflux"
@@ -9,4 +9,4 @@
end_on_antag_death = 1
antag_tags = list(MODE_TECHNOMANCER, MODE_CULTIST)
require_all_templates = 1
votable = 0
votable = 1

View File

@@ -1,5 +1,5 @@
/datum/game_mode/lizard
name = "Technomancer & Changelings"
name = "Technomancers & Changelings"
round_description = "A space wizard and changelings have invaded the station!"
extended_round_description = "Changelings and a wizard spawn during this round."
config_tag = "lizard"
@@ -9,4 +9,4 @@
end_on_antag_death = 0
antag_tags = list(MODE_TECHNOMANCER, MODE_CHANGELING)
require_all_templates = 1
votable = 0
votable = 1

View File

@@ -1,5 +1,5 @@
/datum/game_mode/visitors
name = "Technomancer & Ninja"
name = "Technomancers & Ninja"
round_description = "A space wizard and a ninja have invaded the station!"
extended_round_description = "A ninja and wizard spawn during this round."
config_tag = "visitors"
@@ -9,4 +9,4 @@
end_on_antag_death = 0
antag_tags = list(MODE_TECHNOMANCER, MODE_NINJA)
require_all_templates = 1
votable = 0
votable = 1

View File

@@ -13,4 +13,5 @@
required_players_secret = 5
required_enemies = 1
end_on_antag_death = 0
antag_tags = list(MODE_NINJA)
antag_tags = list(MODE_NINJA)
votable = 0

View File

@@ -60,6 +60,7 @@
"Nymph Chirping" = 'sound/misc/nymphchirp.ogg',
"Sad Trombone" = 'sound/misc/sadtrombone.ogg',
"Honk" = 'sound/items/bikehorn.ogg',
"Bone Fracture" = "fracture",
)
var/selected_sound = null

View File

@@ -6,7 +6,7 @@
fear and excitement. Ultimately, their purpose is unknown. However, it is up to you and your crew to decide if \
their powers can be used for good or if their arrival foreshadows the destruction of the entire colony, or worse."
config_tag = "technomancer"
votable = 0
votable = 1
required_players = 5
required_players_secret = 5
required_enemies = 1

View File

@@ -231,7 +231,7 @@
idtype = /obj/item/weapon/card/id/civilian
access = list(access_library, access_maint_tunnels)
minimal_access = list(access_library)
alt_titles = list("Journalist", "Professor", "Historian")
alt_titles = list("Journalist", "Professor", "Historian", "Writer")
equip(var/mob/living/carbon/human/H)

View File

@@ -17,9 +17,9 @@
..()
new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src)
new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src)
new /obj/item/weapon/spacecash(src)
new /obj/item/weapon/spacecash(src)
new /obj/item/weapon/spacecash(src)
new /obj/item/weapon/spacecash/c100(src)
new /obj/item/weapon/spacecash/c100(src)
new /obj/item/weapon/spacecash/c100(src)
/obj/item/weapon/storage/bible/afterattack(atom/A, mob/user as mob, proximity)
if(!proximity) return

View File

@@ -200,3 +200,9 @@
/obj/structure/flora/ausbushes/fullgrass/New()
..()
icon_state = "fullgrass_[rand(1, 3)]"
/obj/structure/flora/skeleton
name = "hanging skeleton model"
icon = 'icons/obj/plants.dmi'
icon_state = "hangskele"
desc = "It's an anatomical model of a human skeletal system made of plaster."

View File

@@ -45,6 +45,7 @@ var/list/clown_sound = list('sound/effects/clownstep1.ogg','sound/effects/clowns
var/list/swing_hit_sound = list('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')
var/list/hiss_sound = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
var/list/page_sound = list('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg')
var/list/fracture_sound = list('sound/effects/bonebreak1.ogg','sound/effects/bonebreak2.ogg','sound/effects/bonebreak3.ogg','sound/effects/bonebreak4.ogg')
//var/list/gun_sound = list('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg')
/proc/playsound(var/atom/source, soundin, vol as num, vary, extrarange as num, falloff, var/is_global, var/frequency)
@@ -175,5 +176,6 @@ var/const/FALLOFF_SOUNDS = 0.5
if ("swing_hit") soundin = pick(swing_hit_sound)
if ("hiss") soundin = pick(hiss_sound)
if ("pageturn") soundin = pick(page_sound)
if ("fracture") soundin = pick(fracture_sound)
//if ("gunshot") soundin = pick(gun_sound)
return soundin
return soundin

View File

@@ -0,0 +1,16 @@
// This is used to have vacuums inside the asteroid be more present.
/turf/space/cracked_asteroid
icon = 'icons/turf/flooring/asteroid.dmi'
name = "cracked sand"
desc = "Rough sand with a huge crack. It probably leads out into the void."
icon_state = "asteroid_cracked"
dynamic_lighting = TRUE
/turf/space/cracked_asteroid/is_space() // So people don't start floating when standing on it.
return FALSE
/turf/space/cracked_asteroid/New()
..()
spawn(2 SECONDS)
overlays.Cut()

View File

@@ -9,7 +9,7 @@
// heat_capacity = 700000 No.
/turf/space/New()
if(!istype(src, /turf/space/transit))
if(!istype(src, /turf/space/transit) && !istype(src, /turf/space/cracked_asteroid))
icon_state = "[((x + y) ^ ~(x * y) + z) % 25]"
update_starlight()
..()

View File

@@ -118,6 +118,7 @@ var/join_motd = null
var/datum/nanomanager/nanomanager = new() // NanoManager, the manager for Nano UIs.
var/datum/event_manager/event_manager = new() // Event Manager, the manager for events.
var/datum/game_master/game_master = new() // Game Master, an AI for choosing events.
var/list/awaydestinations = list() // Away missions. A list of landmarks that the warpgate can take you to.

View File

@@ -197,7 +197,8 @@ var/list/admin_verbs_debug = list(
/client/proc/dsay,
/client/proc/toggle_debug_logs,
/client/proc/admin_ghost, //allows us to ghost/reenter body at will,
/datum/admins/proc/view_runtimes
/datum/admins/proc/view_runtimes,
/client/proc/show_gm_status
)
var/list/admin_verbs_paranoid_debug = list(

View File

@@ -24,6 +24,10 @@
display_name = "armband, medical"
path = /obj/item/clothing/accessory/armband/med
/datum/gear/accessory/medical/cross
display_name = "armband, medic"
path = /obj/item/clothing/accessory/armband/med/cross
/datum/gear/accessory/science
display_name = "armband, science"
path = /obj/item/clothing/accessory/armband/science

View File

@@ -267,6 +267,7 @@ BLIND // can't see anything
toggleable = 1
action_button_name = "Toggle Goggles"
vision_flags = SEE_MOBS
see_invisible = INVISIBILITY_LEVEL_TWO
emp_act(severity)
if(istype(src.loc, /mob/living/carbon/human))

View File

@@ -394,14 +394,14 @@
/obj/item/clothing/suit/armor/heavy
name = "heavy armor"
desc = "A heavily armored suit that protects against moderate damage."
desc = "An old military-grade suit of armor. Incredibly robust against brute force damage! However, it offers little protection from energy-based weapons, which, combined with its bulk, makes it woefully obsolete."
icon_state = "heavy"
item_state_slots = list(slot_r_hand_str = "swat", slot_l_hand_str = "swat")
armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 40, bio = 0, rad = 0)
w_class = ITEMSIZE_LARGE//bulky item
armor = list(melee = 90, bullet = 80, laser = 10, energy = 10, bomb = 80, bio = 0, rad = 0)
w_class = ITEMSIZE_HUGE // Very bulky, very heavy.
gas_transfer_coefficient = 0.90
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
slowdown = 3
slowdown = 5 // If you're a tank you're gonna move like a tank.
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
siemens_coefficient = 0

View File

@@ -180,6 +180,71 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO
flags_inv = HIDEJUMPSUIT
/obj/item/clothing/suit/skeleton
name = "skeleton costume"
desc = "A body-tight costume with the human skeleton lined out on it."
icon_state = "skelecost"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|FEET|HANDS|EYES|HEAD|FACE
flags_inv = HIDEJUMPSUIT|HIDESHOES|HIDEGLOVES
item_state_slots = list(slot_r_hand_str = "judge", slot_l_hand_str = "judge")
/obj/item/clothing/suit/engicost
name = "sexy engineering voidsuit costume"
desc = "It's supposed to look like an engineering voidsuit... It doesn't look like it could protect from much radiation."
icon_state = "engicost"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|FEET
flags_inv = HIDEJUMPSUIT|HIDESHOES
item_state_slots = list(slot_r_hand_str = "eng_voidsuit", slot_l_hand_str = "eng_voidsuit")
/obj/item/clothing/suit/maxman
name = "doctor maxman costume"
desc = "A costume made to look like Dr. Maxman, the famous male-enhancement salesman. Complete with red do-rag and sleeveless labcoat."
icon_state = "maxman"
body_parts_covered = LOWER_TORSO|FEET|LEGS|HEAD
flags_inv = HIDEJUMPSUIT|HIDESHOES
item_state_slots = list(slot_r_hand_str = "leather_jacket", slot_l_hand_str = "leather_jacket")
/obj/item/clothing/suit/iasexy
name = "sexy internal affairs suit"
desc = "Now where's your pen?~..."
icon_state = "iacost"
body_parts_covered = UPPER_TORSO|FEET|LOWER_TORSO|EYES
flags_inv = HIDEJUMPSUIT|HIDESHOES
item_state_slots = list(slot_r_hand_str = "suit_black", slot_l_hand_str = "suit_black")
/obj/item/clothing/suit/sexyminer
name = "sexy miner costume"
desc = "For when you need to get your rocks off."
icon_state = "sexyminer"
body_parts_covered = FEET|LOWER_TORSO|HEAD
flags_inv = HIDEJUMPSUIT|HIDESHOES
item_state_slots = list(slot_r_hand_str = "miner", slot_l_hand_str = "miner")
/obj/item/clothing/suit/sumo
name = "inflatable sumo wrestler costume"
desc = "An inflated sumo wrestler costume. It's quite hot."
icon_state = "sumo"
body_parts_covered = FEET|LOWER_TORSO|UPPER_TORSO|LEGS|ARMS
flags_inv = HIDESHOES
item_state_slots = list(slot_r_hand_str = "classicponcho", slot_l_hand_str = "classicponcho")
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
/obj/item/clothing/suit/hackercost
name = "classic hacker costume"
desc = "You would feel insanely cool wearing this."
icon_state = "hackercost"
body_parts_covered = FEET|LOWER_TORSO|UPPER_TORSO|LEGS|ARMS|EYES
flags_inv = HIDESHOES
item_state_slots = list(slot_r_hand_str = "leather_coat", slot_l_hand_str = "leather_coat")
/obj/item/clothing/suit/lumber
name = "sexy lumberjack costume"
desc = "Smells of dusky pine. Includes chest hair and beard."
icon_state = "sexylumber"
body_parts_covered = FEET|LOWER_TORSO|FEET
flags_inv = HIDESHOES|HIDEJUMPSUIT
item_state_slots = list(slot_r_hand_str = "red_labcoat", slot_l_hand_str = "red_labcoat")
/*
* Misc
*/
@@ -816,4 +881,4 @@
icon_open = "suitjacket_green_open"
icon_closed = "suitjacket_green"
blood_overlay_type = "coat"
body_parts_covered = UPPER_TORSO|ARMS
body_parts_covered = UPPER_TORSO|ARMS

View File

@@ -29,6 +29,11 @@
desc = "An armband, worn by the crew to display which department they're assigned to. This one is white."
icon_state = "med"
/obj/item/clothing/accessory/armband/med/cross
name = "medic armband"
desc = "A white armband with a red cross on it. Typically used by people in the Medical department."
icon_state = "medicband"
/obj/item/clothing/accessory/armband/med/color
name = "armband"
desc = "A fancy armband."

View File

@@ -127,16 +127,16 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
available_events = list(
// Severity level, event name, even type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 100),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "APC Damage", /datum/event/apc_damage, 20, list(ASSIGNMENT_ENGINEER = 10)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "APC Damage", /datum/event/apc_damage, 20, list(ASSIGNMENT_ENGINEER = 20)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Brand Intelligence",/datum/event/brand_intelligence,20, list(ASSIGNMENT_JANITOR = 25), 1),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Camera Damage", /datum/event/camera_damage, 20, list(ASSIGNMENT_ENGINEER = 10)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Camera Damage", /datum/event/camera_damage, 20, list(ASSIGNMENT_ENGINEER = 20)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Economic News", /datum/event/economic_event, 300),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lost Carp", /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Hacker", /datum/event/money_hacker, 0, list(ASSIGNMENT_ANY = 4), 1, 10, 25),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 25, 50),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Space Dust", /datum/event/dust , 30, list(ASSIGNMENT_ENGINEER = 5), 0, 0, 50),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Space Dust", /datum/event/dust , 60, list(ASSIGNMENT_ENGINEER = 20), 0, 0, 50),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)),
@@ -145,22 +145,22 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
/datum/event_container/moderate
severity = EVENT_LEVEL_MODERATE
available_events = list(
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Nothing", /datum/event/nothing, 1230),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Appendicitis", /datum/event/spontaneous_appendicitis, 0, list(ASSIGNMENT_MEDICAL = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School", /datum/event/carp_migration, 100, list(ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_SECURITY = 20), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Nothing", /datum/event/nothing, 800),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Appendicitis", /datum/event/spontaneous_appendicitis, 0, list(ASSIGNMENT_MEDICAL = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School", /datum/event/carp_migration, 100, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_SECURITY = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 500, list(ASSIGNMENT_AI = 150, ASSIGNMENT_SECURITY = 120)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 250, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_JANITOR = 150)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravity Failure", /datum/event/gravity, 75, list(ASSIGNMENT_ENGINEER = 60)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_SCIENTIST = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 20)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 0, list(ASSIGNMENT_MEDICAL = 50), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 80, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_wave, 30, list(ASSIGNMENT_ENGINEER = 20)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 10, list(ASSIGNMENT_SECURITY = 100)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 50, list(ASSIGNMENT_MEDICAL = 50), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Random Antagonist", /datum/event/random_antag, 2.5, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 20, list(ASSIGNMENT_SECURITY = 20)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Solar Storm", /datum/event/solar_storm, 10, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_SECURITY = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 30, list(ASSIGNMENT_ENGINEER = 5)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 20, list(ASSIGNMENT_SECURITY = 60)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Solar Storm", /datum/event/solar_storm, 30, list(ASSIGNMENT_ENGINEER = 40, ASSIGNMENT_SECURITY = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 80, list(ASSIGNMENT_ENGINEER = 30)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 40), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Virology Breach", /datum/event/prison_break/virology, 0, list(ASSIGNMENT_MEDICAL = 100)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Xenobiology Breach", /datum/event/prison_break/xenobiology, 0, list(ASSIGNMENT_SCIENCE = 100)),
)
@@ -168,12 +168,12 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
/datum/event_container/major
severity = EVENT_LEVEL_MAJOR
available_events = list(
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 60), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 900),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 10, list(ASSIGNMENT_ENGINEER = 60), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 10, list(ASSIGNMENT_SECURITY = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station,0,list(ASSIGNMENT_ANY = 5)),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Vines", /datum/event/spacevine, 0, list(ASSIGNMENT_ENGINEER = 15), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 30, list(ASSIGNMENT_ENGINEER = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Vines", /datum/event/spacevine, 20, list(ASSIGNMENT_ENGINEER = 15), 1),
)

View File

@@ -0,0 +1,29 @@
/datum/gm_action
var/name = "no name" // Simple name, for organization.
var/enabled = TRUE // If not enabled, this action is never taken.
var/departments = list() // What kinds of departments are affected by this action. Multiple departments can be listed.
var/chaotic = 0 // A number showing how chaotic the action may be. If danger is high, the GM will avoid it.
var/reusable = FALSE // If true, the event does not become disabled upon being used. Should be used sparingly.
var/observers_used = FALSE // Determines if the GM should check if ghosts are available before using this.
var/datum/game_master/gm = null
/datum/gm_action/New(var/datum/game_master/new_gm)
..()
gm = new_gm
/datum/gm_action/proc/set_up()
return
/datum/gm_action/proc/get_weight()
return
/datum/gm_action/proc/start()
if(!reusable)
enabled = FALSE
return
/datum/gm_action/proc/end()
return
/datum/gm_action/proc/announce()
return

View File

@@ -0,0 +1,6 @@
// Comms blackout is, just like grid check, mostly the same as always, yet engineering has an option to get it back sooner.
/datum/gm_action/comms_blackout
name = "communications blackout"
departments = list(ROLE_ENGINEERING, ROLE_EVERYONE)
chaotic = 35

View File

@@ -0,0 +1,9 @@
// New grid check event:
// Very similar to the old one, power goes out in most of the colony, however the new feature is the ability for engineering to
// get power back on sooner, if they are able to reach a special machine and initiate a manual reboot. If no one is able to do so,
// it will reboot itself after a few minutes, just like the old one.
/datum/gm_action/grid_check
name = "grid check"
departments = list(ROLE_ENGINEERING, ROLE_EVERYONE)
chaotic = 20

View File

@@ -0,0 +1,6 @@
// A shuttle full of junk docks, and cargo is tasked with sifting through it all to find valuables, or just dispose of it.
/datum/gm_action/waste_disposal
name = "waste disposal"
departments = list(ROLE_CARGO)
chaotic = 0

View File

@@ -0,0 +1,40 @@
/client/proc/show_gm_status()
set category = "Debug"
set name = "Show GM Status"
set desc = "Shows you what the GM is thinking. If only that existed in real life..."
game_master.interact(usr)
/datum/game_master/proc/interact(var/client/user)
if(!user)
return
var/HTML = "<html><head><title>Game Master AI</title></head><body>"
HTML += "Staleness: [staleness]<br>"
HTML += "Danger: [danger]<br><br>"
HTML += "Actions available;<br>"
for(var/datum/gm_action/action in available_actions)
if(action.enabled == FALSE)
continue
HTML += "[action.name] ([english_list(action.departments)])<br>"
HTML += "<br>"
HTML += "All living mobs activity: [assess_all_living_mobs()]<br>"
HTML += "<br>"
HTML += "Departmental activity;<br>"
for(var/department in departments)
var/number_of_people = count_people_in_department(department)
HTML += " [department] : [assess_department(department)] / [number_of_people * 100]<br>"
HTML += "<br>"
HTML += "Activity of players;<br>"
for(var/mob/player in player_list)
HTML += " [player] : [assess_player_activity(player)]<br>"
HTML +="</body></html>"
user << browse(HTML, "window=log;size=400x450;border=1;can_resize=1;can_close=1;can_minimize=1")

View File

@@ -0,0 +1,10 @@
#define ROLE_COMMAND "command"
#define ROLE_SECURITY "security"
#define ROLE_ENGINEERING "engineering"
#define ROLE_MEDICAL "medical"
#define ROLE_RESEARCH "research"
#define ROLE_CARGO "cargo"
#define ROLE_CIVILIAN "civilian"
#define ROLE_SYNTHETIC "synthetic"
#define ROLE_UNKNOWN "unknown"
#define ROLE_EVERYONE "everyone"

View File

@@ -0,0 +1,207 @@
// This is a sort of successor to the various event systems created over the years. It is designed to be just a tad smarter than the
// previous ones, checking various things like player count, department size and composition, individual player activity,
// individual player (IC) skill, and such, in order to try to choose the best actions to take in order to add spice or variety to
// the round.
/datum/game_master
var/suspended = FALSE // If true, it will not do anything.
var/list/available_actions = list() // A list of 'actions' that the GM has access to, to spice up a round, such as events.
var/danger = 0 // The GM's best guess at how chaotic the round is. High danger makes it hold back.
var/staleness = -20 // Determines liklihood of the GM doing something, increases over time.
var/danger_modifier = 1 // Multiplier for how much 'danger' is accumulated.
var/staleness_modifier = 1 // Ditto. Higher numbers generally result in more events occuring in a round.
var/ticks_completed = 0 // Counts amount of ticks completed. Note that this ticks once a minute.
var/next_action = 0 // Minimum amount of time of nothingness until the GM can pick something again.
var/departments = list( // List of departments the GM considers for choosing events for.
ROLE_COMMAND,
ROLE_SECURITY,
ROLE_ENGINEERING,
ROLE_MEDICAL,
ROLE_RESEARCH,
ROLE_CARGO,
ROLE_CIVILIAN,
ROLE_SYNTHETIC
)
/datum/game_master/New()
..()
available_actions = init_subtypes(/datum/gm_action)
// var/actions = typesof(/datum/gm_actions)
// for(var/type in actions)
// available_actions.Add(new type)
/datum/game_master/proc/process()
if(ticker && ticker.current_state == GAME_STATE_PLAYING)
adjust_staleness(1)
adjust_danger(-1)
ticks_completed++
var/global_afk = assess_all_living_mobs()
global_afk -= 100
global_afk = abs(global_afk)
global_afk = round(global_afk / 100, 0.1)
adjust_staleness(global_afk) // Staleness increases faster if more people are less active.
if(world.time < next_action && prob(staleness * 2) )
log_debug("Game Master going to start something.")
start_action()
/datum/game_master/proc/assess_all_living_mobs()
var/num = 0
for(var/mob/living/L in player_list) // Ghosts being AFK isn't that much of a concern.
. += assess_player_activity(L)
num++
if(num)
. = round(. / num, 0.1)
// This is run before committing to an action/event.
/datum/game_master/proc/pre_action_checks()
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
log_debug("Game Master unable to start event: Ticker is nonexistant, or the game is not ongoing.")
return FALSE
// Last minute antagging is bad for humans to do, so the GM will respect the start and end of the round.
var/mills = round_duration_in_ticks
var/mins = round((mills % 36000) / 600)
var/hours = round(mills / 36000)
if(hours < 1 && mins <= 20) // Don't do anything for the first twenty minutes of the round.
log_debug("Game Master unable to start event: It is too early.")
return FALSE
if(hours >= 2 && mins >= 40) // Don't do anything in the last twenty minutes of the round, as well.
log_debug("Game Master unable to start event: It is too late.")
return FALSE
return TRUE
/datum/game_master/proc/start_action()
if(!pre_action_checks()) // Make sure we're not doing last minute events, or early events.
return
log_debug("Game Master now starting action decision.")
var/list/best_actions = assess_round() // Checks the whole round for active people, and returns a list of the most activie departments.
if(best_actions && best_actions.len)
var/datum/gm_action/choice = pick(best_actions)
if(choice)
// log_debug("[choice.name] was chosen by the Game Master, and is now being ran.")
// choice.set_up()
// choice.start()
// choice.annnounce()
next_action = world.time + rand(15 MINUTES, 30 MINUTES)
/datum/game_master/proc/assess_round()
var/list/activity = list()
for(var/department in departments)
activity[department] = assess_department(department)
log_debug("Assessing department [department]. They have activity of [activity[department]].")
var/list/most_active_departments = list() // List of winners.
var/highest_activity = null // Department who is leading in activity, if one exists.
var/highest_number = 0 // Activity score needed to beat to be the most active department.
for(var/i = 1, i <= 3, i++)
log_debug("Doing [i]\th round of counting.")
for(var/department in activity)
if(activity[department] > highest_number && activity[department] > 0) // More active than the current highest department?
highest_activity = department
highest_number = activity[department]
if(highest_activity) // Someone's a winner.
most_active_departments.Add(highest_activity) // Add to the list of most active.
activity.Remove(highest_activity) // Remove them from the other list so they don't win more than once.
log_debug("[highest_activity] has won the [i]\th round of activity counting.")
highest_activity = null // Now reset for the next round.
highest_number = 0
//todo: finish
var/list/best_actions = decide_best_action(most_active_departments)
return best_actions
// By now, we should have a list of departments populated. The GM will prefer events tailored to these departments.
/datum/game_master/proc/decide_best_action(var/list/most_active_departments)
if(!most_active_departments.len) // Server's empty?
log_debug("Game Master failed to find any active departments.")
return list()
var/list/best_actions = list() // List of actions which involve the most active departments.
if(most_active_departments.len >= 2)
for(var/datum/gm_action/action in available_actions)
if(!action.enabled)
continue
// Try to incorporate an action with the top two departments first.
if(most_active_departments[1] in action.departments && most_active_departments[2] in action.departments)
best_actions.Add(action)
log_debug("[action.name] is being considered because both most active departments are involved.")
if(best_actions.len) // We found something for those two, let's do it.
return best_actions
// Otherwise we probably couldn't find something for the second highest group, so let's ignore them.
for(var/datum/gm_action/action in available_actions)
if(!action.enabled)
continue
if(most_active_departments[1] in action.departments)
best_actions.Add(action)
log_debug("[action.name] is being considered because the most active department is involved.")
if(best_actions.len) // Found something for the one guy.
return best_actions
// At this point we should expand our horizons.
for(var/datum/gm_action/action in available_actions)
if(!action.enabled)
continue
if(ROLE_EVERYONE in action.departments)
best_actions.Add(action)
log_debug("[action.name] is being considered because it involves everyone.")
if(best_actions.len) // Finally, perhaps?
return best_actions
// Just give a random event if for some reason it still can't make up its mind.
for(var/datum/gm_action/action in available_actions)
if(!action.enabled)
continue
best_actions.Add(action)
log_debug("[action.name] is being considered because everything else failed.")
if(best_actions.len) // Finally, perhaps?
return best_actions
else
log_debug("Game Master failed to find a suitable event, something very wrong is going on.")
// This checks a whole department's viability to receive an event.
/datum/game_master/proc/assess_department(var/department)
if(!department)
return
var/departmental_activitiy = 0
for(var/mob/M in player_list)
if(guess_department(M) != department) // Ignore people outside the department we're assessing.
continue
departmental_activitiy += assess_player_activity(M)
return departmental_activitiy
// This checks an individual player's activity level. People who have been afk for a few minutes aren't punished as much as those
// who were afk for hours, as they're most likely gone for good.
/datum/game_master/proc/assess_player_activity(var/mob/M)
. = 100
if(!M)
. = 0
return
if(!M.mind || !M.client) // Logged out. They might come back but we can't do any meaningful assessments for now.
. = 0
return
var/afk = M.client.is_afk(1 MINUTE)
if(afk) // Deduct points based on length of AFK-ness.
switch(afk) // One minute is equal to 600, for reference.
if(1 MINUTE to 10 MINUTES) // People gone for this emough of time hopefully will come back soon.
. -= round( (afk / 200), 1)
// . -= 30
if(10 MINUTES to 30 MINUTES)
. -= round( (afk / 150), 1)
// . -= 70
if(30 MINUTES to INFINITY) // They're probably not coming back if it's been 30 minutes.
. -= 100
. = max(. , 0) // No negative numbers, or else people could drag other, non-afk players down.

View File

@@ -0,0 +1,72 @@
// Tell the game master that something dangerous happened, e.g. someone dying.
/datum/game_master/proc/adjust_danger(var/amt)
amt = amt * danger_modifier
danger = round( Clamp(danger + amt, 0, 1000), 0.1)
// Tell the game master that something interesting happened.
/datum/game_master/proc/adjust_staleness(var/amt)
amt = amt * staleness_modifier
staleness = round( Clamp(staleness + amt, -50, 200), 0.1)
// This proc tries to find the department of an arbitrary mob.
/datum/game_master/proc/guess_department(var/mob/M)
var/datum/data/record/R = find_general_record("name", M.real_name)
. = ROLE_UNKNOWN
if(R) // We found someone with a record.
var/recorded_rank = R.fields["real_rank"]
. = role_name_to_department(recorded_rank)
if(. != ROLE_UNKNOWN) // We found the correct department, so we can stop now.
return
// They have a custom title, aren't crew, or someone deleted their record, so we need a fallback method.
// Let's check the mind.
if(M.mind)
. = role_name_to_department(M.mind.assigned_role)
if(. != ROLE_UNKNOWN)
return
// At this point, they don't have a mind, or for some reason assigned_role didn't work.
if(ishuman(M))
var/mob/living/carbon/human/H = M
. = role_name_to_department(H.job)
if(. != ROLE_UNKNOWN)
return
return ROLE_UNKNOWN // Welp.
// Feed this proc the name of a job, and it will try to figure out what department they are apart of.
/datum/game_master/proc/role_name_to_department(var/role_name)
if(role_name in security_positions)
return ROLE_SECURITY
if(role_name in engineering_positions)
return ROLE_ENGINEERING
if(role_name in medical_positions)
return ROLE_MEDICAL
if(role_name in science_positions)
return ROLE_RESEARCH
if(role_name in cargo_positions)
return ROLE_CARGO
if(role_name in civilian_positions)
return ROLE_CIVILIAN
if(role_name in nonhuman_positions)
return ROLE_SYNTHETIC
if(role_name in command_positions) // We do command last, so that only the Captain and command secretaries get caught.
return ROLE_COMMAND
return ROLE_UNKNOWN
/datum/game_master/proc/count_people_in_department(var/department)
if(!department)
return
for(var/mob/M in player_list)
if(guess_department(M) != department) // Ignore people outside the department we're counting.
continue
. += 1

View File

@@ -139,7 +139,7 @@ var/list/mining_overlay_cache = list()
overlays += mining_overlay_cache["dug_overlay"]
for(var/direction in cardinal)
if(istype(get_step(src, direction), /turf/space))
if(istype(get_step(src, direction), /turf/space) && !istype(get_step(src, direction), /turf/space/cracked_asteroid))
if(!mining_overlay_cache["asteroid_edge_[direction]"])
mining_overlay_cache["asteroid_edge_[direction]"] = image('icons/turf/flooring/asteroid.dmi', "asteroid_edges", dir = direction)
overlays += mining_overlay_cache["asteroid_edge_[direction]"]

View File

@@ -105,6 +105,8 @@
"Your chilly flesh stands out in goosebumps."
)
var/metabolic_rate = 1
// HUD data vars.
var/datum/hud_data/hud
var/hud_type

View File

@@ -894,7 +894,7 @@ mob/proc/yank_out_object()
H.shock_stage+=20
affected.take_damage((selection.w_class * 3), 0, 0, 1, "Embedded object extraction")
if(prob(selection.w_class * 5) && (affected < ORGAN_ROBOT)) //I'M SO ANEMIC I COULD JUST -DIE-.
if(prob(selection.w_class * 5) && (affected.robotic < ORGAN_ROBOT)) //I'M SO ANEMIC I COULD JUST -DIE-.
var/datum/wound/internal_bleeding/I = new (min(selection.w_class * 5, 15))
affected.wounds += I
H.custom_pain("Something tears wetly in your [affected] as [selection] is pulled free!", 1)

View File

@@ -1002,6 +1002,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(!(species.flags & NO_PAIN))
owner.emote("scream")
playsound(src.loc, "fracture", 10, 1, -2)
status |= ORGAN_BROKEN
broken_description = pick("broken","fracture","hairline fracture")

View File

@@ -45,7 +45,10 @@
var/turf/simulated/mineral/T = locate((origin_x-1)+x,(origin_y-1)+y,origin_z)
if(istype(T) && !T.ignore_mapgen)
if(map[current_cell] == FLOOR_CHAR)
T.make_floor()
if(prob(90))
T.make_floor()
else
T.ChangeTurf(/turf/space/cracked_asteroid)
else
T.make_wall()
if(map[current_cell] == DOOR_CHAR)

View File

@@ -19,6 +19,7 @@
var/list/data = null
var/volume = 0
var/metabolism = REM // This would be 0.2 normally
var/mrate_static = FALSE //If the reagent should always process at the same speed, regardless of species, make this TRUE
var/ingest_met = 0
var/touch_met = 0
var/dose = 0
@@ -60,6 +61,8 @@
if(overdose && (volume > overdose) && (location != CHEM_TOUCH))
overdose(M, alien)
var/removed = metabolism
if(!mrate_static == TRUE)
removed *= M.species.metabolic_rate
if(ingest_met && (location == CHEM_INGEST))
removed = ingest_met
if(touch_met && (location == CHEM_TOUCH))

View File

@@ -4,6 +4,7 @@
id = "blood"
reagent_state = LIQUID
metabolism = REM * 5
mrate_static = TRUE
color = "#C80000"
glass_name = "tomato juice"
@@ -75,6 +76,7 @@
id = "antibodies"
reagent_state = LIQUID
color = "#0050F0"
mrate_static = TRUE
/datum/reagent/antibodies/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(src.data)
@@ -89,6 +91,7 @@
reagent_state = LIQUID
color = "#0064C877"
metabolism = REM * 10
mrate_static = TRUE
glass_name = "water"
glass_desc = "The father of all refreshments."

View File

@@ -12,6 +12,7 @@
reagent_state = SOLID
color = "#1C1300"
ingest_met = REM * 5
mrate_static = TRUE
/datum/reagent/carbon/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
@@ -66,6 +67,8 @@
var/targ_temp = 310
var/halluci = 0
mrate_static = TRUE
glass_name = "ethanol"
glass_desc = "A well-known alcohol with a variety of applications."

View File

@@ -6,6 +6,7 @@
description = "All the vitamins, minerals, and carbohydrates the body needs in pure form."
reagent_state = SOLID
metabolism = REM * 4
mrate_static = TRUE
var/nutriment_factor = 30 // Per unit
var/injectable = 0
color = "#664330"

View File

@@ -8,6 +8,7 @@
color = "#00BFFF"
overdose = REAGENTS_OVERDOSE * 2
metabolism = REM * 0.5
mrate_static = TRUE
scannable = 1
/datum/reagent/inaprovaline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
@@ -91,6 +92,7 @@
description = "Dexalin Plus is used in the treatment of oxygen deprivation. It is highly effective."
reagent_state = LIQUID
color = "#0040FF"
mrate_static = TRUE //Until it's not crazy strong, at least
overdose = REAGENTS_OVERDOSE * 0.5
scannable = 1
@@ -123,6 +125,7 @@
reagent_state = LIQUID
color = "#8080FF"
metabolism = REM * 0.5
mrate_static = TRUE
scannable = 1
/datum/reagent/cryoxadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
@@ -139,6 +142,7 @@
reagent_state = LIQUID
color = "#80BFFF"
metabolism = REM * 0.5
mrate_static = TRUE
scannable = 1
/datum/reagent/clonexadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
@@ -159,6 +163,7 @@
overdose = 60
scannable = 1
metabolism = 0.02
mrate_static = TRUE
/datum/reagent/paracetamol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.add_chemical_effect(CE_PAINKILLER, 50)
@@ -176,6 +181,7 @@
overdose = 30
scannable = 1
metabolism = 0.02
mrate_static = TRUE
/datum/reagent/tramadol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.add_chemical_effect(CE_PAINKILLER, 80)
@@ -192,6 +198,7 @@
color = "#800080"
overdose = 20
metabolism = 0.02
mrate_static = TRUE
/datum/reagent/oxycodone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.add_chemical_effect(CE_PAINKILLER, 200)
@@ -311,6 +318,7 @@
reagent_state = LIQUID
color = "#FF3300"
metabolism = REM * 0.3
mrate_static = TRUE
overdose = REAGENTS_OVERDOSE * 0.5
/datum/reagent/hyperzine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
@@ -376,6 +384,7 @@
reagent_state = LIQUID
color = "#C1C1C1"
metabolism = REM * 0.05
mrate_static = TRUE
overdose = REAGENTS_OVERDOSE
scannable = 1
@@ -430,6 +439,7 @@
reagent_state = LIQUID
color = "#BF80BF"
metabolism = 0.01
mrate_static = TRUE
data = 0
/datum/reagent/methylphenidate/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
@@ -450,6 +460,7 @@
reagent_state = LIQUID
color = "#FF80FF"
metabolism = 0.01
mrate_static = TRUE
data = 0
/datum/reagent/citalopram/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
@@ -470,6 +481,7 @@
reagent_state = LIQUID
color = "#FF80BF"
metabolism = 0.01
mrate_static = TRUE
data = 0
/datum/reagent/paroxetine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)

View File

@@ -111,6 +111,7 @@
reagent_state = LIQUID
color = "#C8A5DC"
affects_dead = 1 //This can even heal dead people.
mrate_static = TRUE //Just in case
glass_name = "liquid gold"
glass_desc = "It's magic. We don't have to explain it."
@@ -182,6 +183,7 @@
description = "Adrenaline is a hormone used as a drug to treat cardiac arrest and other cardiac dysrhythmias resulting in diminished or absent cardiac output."
reagent_state = LIQUID
color = "#C8A5DC"
mrate_static = TRUE
/datum/reagent/adrenaline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
@@ -195,6 +197,7 @@
id = "holywater"
description = "An ashen-obsidian-water mix, this solution will alter certain sections of the brain's rationality."
color = "#E0E8EF"
mrate_static = TRUE
glass_name = "holy water"
glass_desc = "An ashen-obsidian-water mix, this solution will alter certain sections of the brain's rationality."

View File

@@ -7,6 +7,7 @@
reagent_state = LIQUID
color = "#CF3600"
metabolism = REM * 0.25 // 0.05 by default. Hopefully enough to get some help, or die horribly, whatever floats your boat
mrate_static = TRUE
var/strength = 4 // How much damage it deals per unit
/datum/reagent/toxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)