This commit is contained in:
Seris02
2020-03-14 11:41:39 +08:00
1787 changed files with 407246 additions and 233473 deletions
+67 -33
View File
@@ -2,32 +2,57 @@
#define CHECK_DNA_AND_SPECIES(C) if((!(C.dna)) || (!(C.dna.species))) return
//Defines copying names of mutations in all cases, make sure to change this if you change mutation's name
#define HULK "Hulk"
#define XRAY "X Ray Vision"
#define COLDRES "Cold Resistance"
#define TK "Telekinesis"
#define NERVOUS "Nervousness"
#define EPILEPSY "Epilepsy"
#define MUTATE "Unstable DNA"
#define COUGH "Cough"
#define DWARFISM "Dwarfism"
#define CLOWNMUT "Clumsiness"
#define TOURETTES "Tourettes Syndrome"
#define DEAFMUT "Deafness"
#define BLINDMUT "Blindness"
#define RACEMUT "Monkified"
#define BADSIGHT "Near Sightness"
#define LASEREYES "Laser Eyes"
#define CHAMELEON "Chameleon"
#define WACKY "Wacky"
#define MUT_MUTE "Mute"
#define SMILE "Smile"
#define STONER "Stoner"
#define UNINTELLIGIBLE "Unintelligible"
#define SWEDISH "Swedish"
#define CHAV "Chav"
#define ELVIS "Elvis"
//Defines copying names of mutations in all cases, make sure to change this if you change mutation's type
#define HULK /datum/mutation/human/hulk
#define XRAY /datum/mutation/human/thermal/x_ray
#define SPACEMUT /datum/mutation/human/space_adaptation
#define TK /datum/mutation/human/telekinesis
#define NERVOUS /datum/mutation/human/nervousness
#define EPILEPSY /datum/mutation/human/epilepsy
#define MUTATE /datum/mutation/human/bad_dna
#define COUGH /datum/mutation/human/cough
#define DWARFISM /datum/mutation/human/dwarfism
#define GIGANTISM /datum/mutation/human/gigantism
#define CLOWNMUT /datum/mutation/human/clumsy
#define TOURETTES /datum/mutation/human/tourettes
#define DEAFMUT /datum/mutation/human/deaf
#define BLINDMUT /datum/mutation/human/blind
#define RACEMUT /datum/mutation/human/race
#define BADSIGHT /datum/mutation/human/nearsight
#define LASEREYES /datum/mutation/human/laser_eyes
#define CHAMELEON /datum/mutation/human/chameleon
#define WACKY /datum/mutation/human/wacky
#define MUT_MUTE /datum/mutation/human/mute
#define SMILE /datum/mutation/human/smile
#define STONER /datum/mutation/human/stoner
#define UNINTELLIGIBLE /datum/mutation/human/unintelligible
#define SWEDISH /datum/mutation/human/swedish
#define CHAV /datum/mutation/human/chav
#define ELVIS /datum/mutation/human/elvis
#define RADIOACTIVE /datum/mutation/human/radioactive
#define GLOWY /datum/mutation/human/glow
#define ANTIGLOWY /datum/mutation/human/glow/anti
#define TELEPATHY /datum/mutation/human/telepathy
#define FIREBREATH /datum/mutation/human/firebreath
#define VOID /datum/mutation/human/void
#define TONGUESPIKE /datum/mutation/human/tongue_spike
#define TONGUESPIKECHEM /datum/mutation/human/tongue_spike/chem
#define STRONG /datum/mutation/human/strong
#define STIMMED /datum/mutation/human/stimmed
#define FIRESWEAT /datum/mutation/human/fire
#define THERMAL /datum/mutation/human/thermal
#define ANTENNA /datum/mutation/human/antenna
#define PARANOIA /datum/mutation/human/paranoia
#define MINDREAD /datum/mutation/human/mindreader
#define INSULATED /datum/mutation/human/insulated
#define SHOCKTOUCH /datum/mutation/human/shock
#define OLFACTION /datum/mutation/human/olfaction
#define ACIDFLESH /datum/mutation/human/acidflesh
#define BADBLINK /datum/mutation/human/badblink
#define SPASTIC /datum/mutation/human/spastic
#define GELADIKINESIS /datum/mutation/human/geladikinesis
#define CRYOKINESIS /datum/mutation/human/cryokinesis
#define SPIDER_WEB /datum/mutation/human/webbing
#define UI_CHANGED "ui changed"
#define UE_CHANGED "ue changed"
@@ -39,10 +64,12 @@
//Types of usual mutations
#define POSITIVE 1
#define NEGATIVE 2
#define MINOR_NEGATIVE 3
#define MINOR_NEGATIVE 4
//Mutations that cant be taken from genetics and are not in SE
#define NON_SCANNABLE -1
//Mutation classes. Normal being on them, extra being additional mutations with instability and other being stuff you dont want people to fuck with like wizard mutate
#define MUT_NORMAL 1
#define MUT_EXTRA 2
#define MUT_OTHER 3
//DNA - Because fuck you and your magic numbers being all over the codebase.
#define DNA_BLOCK_SIZE 3
@@ -63,7 +90,8 @@
#define DNA_MUTANTMARKING_BLOCK 13
#define DNA_TAUR_BLOCK 14
#define DNA_STRUC_ENZYMES_BLOCKS 18
#define DNA_SEQUENCE_LENGTH 4
#define DNA_MUTATION_BLOCKS 8
#define DNA_UNIQUE_ENZYMES_LEN 32
//Transformation proc stuff
@@ -138,10 +166,16 @@
////organ defines
#define STANDARD_ORGAN_THRESHOLD 100
#define STANDARD_ORGAN_HEALING 0.001
#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes
#define STANDARD_ORGAN_HEALING (1/(15 MINUTES / (2 SECONDS)))
#define STANDARD_ORGAN_DECAY (1/(15 MINUTES / (2 SECONDS))) //designed to fail organs when left to decay for ~15 minutes. 2 SECOND is SSmobs tickrate.
//used for the can_chromosome var on mutations
#define CHROMOSOME_NEVER 0
#define CHROMOSOME_NONE 1
#define CHROMOSOME_USED 2
#define G_MALE 1
#define G_FEMALE 2
#define G_PLURAL 3
#define G_NEUTER 4
#define G_NEUTER 4
+1 -1
View File
@@ -20,7 +20,7 @@
#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
#define START_PROCESSING(Processor, Datum) if (!(Datum.datum_flags & DF_ISPROCESSING)) {Datum.datum_flags |= DF_ISPROCESSING;Processor.processing += Datum}
#define STOP_PROCESSING(Processor, Datum) Datum.datum_flags &= ~DF_ISPROCESSING;Processor.processing -= Datum
#define STOP_PROCESSING(Processor, Datum) Datum.datum_flags &= ~DF_ISPROCESSING;Processor.processing -= Datum;Processor.currentrun -= Datum
//SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
+20
View File
@@ -34,6 +34,21 @@
#define HIJACK_HIJACKER 1 //Needs to be present for shuttle to be hijacked
#define HIJACK_PREVENT 2 //Prevents hijacking same way as non-antags
//Syndicate Contracts
#define CONTRACT_STATUS_INACTIVE 1
#define CONTRACT_STATUS_ACTIVE 2
#define CONTRACT_STATUS_BOUNTY_CONSOLE_ACTIVE 3
#define CONTRACT_STATUS_EXTRACTING 4
#define CONTRACT_STATUS_COMPLETE 5
#define CONTRACT_STATUS_ABORTED 6
#define CONTRACT_PAYOUT_LARGE 1
#define CONTRACT_PAYOUT_MEDIUM 2
#define CONTRACT_PAYOUT_SMALL 3
#define CONTRACT_UPLINK_PAGE_CONTRACTS "CONTRACTS"
#define CONTRACT_UPLINK_PAGE_HUB "HUB"
//Overthrow time to update heads obj
#define OBJECTIVE_UPDATING_TIME 300
@@ -57,3 +72,8 @@
#define CAT_STRUCTURE "Structures"
#define MARTIALART_HUNTER "hunter-fu"
//Blob
/// blob gets a free reroll every X time
#define BLOB_REROLL_TIME 2400
#define BLOB_REFLECTOR_COST 15
+4 -3
View File
@@ -34,13 +34,14 @@
#define CAN_MASTURBATE_WITH (1<<5)
#define MASTURBATE_LINKED_ORGAN (1<<6) //used to pass our mission to the linked organ
#define CAN_CLIMAX_WITH (1<<7)
#define GENITAL_CAN_AROUSE (1<<8)
#define COCK_SIZE_MIN 1
#define COCK_SIZE_MAX 20
#define COCK_GIRTH_RATIO_MAX 1.25
#define COCK_GIRTH_RATIO_DEF 0.75
#define COCK_GIRTH_RATIO_MIN 0.5
#define COCK_DIAMETER_RATIO_MAX 0.42
#define COCK_DIAMETER_RATIO_DEF 0.25
#define COCK_DIAMETER_RATIO_MIN 0.15
#define KNOT_GIRTH_RATIO_MAX 3
#define KNOT_GIRTH_RATIO_DEF 2.1
+36 -7
View File
@@ -33,6 +33,10 @@
#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args)
#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message)
// signals from globally accessible objects
/// from SSsun when the sun changes position : (azimuth)
#define COMSIG_SUN_MOVED "sun_moved"
//////////////////////////////////////////////////////////////////
// /datum signals
@@ -43,6 +47,10 @@
#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" //before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation
#define COMSIG_PARENT_QDELETING "parent_qdeleting" //just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called
/// Trait signals
#define COMPONENT_ADD_TRAIT (1<<0)
#define COMPONENT_REMOVE_TRAIT (1<<1)
// /atom signals
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
#define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
@@ -58,6 +66,7 @@
#define COMSIG_ATOM_NO_UPDATE_ICON_STATE 1
#define COMSIG_ATOM_NO_UPDATE_OVERLAYS 2
#define COMSIG_ATOM_UPDATE_OVERLAYS "atom_update_overlays" //from base of atom/update_overlays(): (list/new_overlays)
#define COMSIG_ATOM_UPDATED_ICON "atom_updated_icon" //from base of atom/update_icon(): (signalOut, did_anything)
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom)
#define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc)
#define COMPONENT_ATOM_BLOCK_EXIT 1
@@ -187,24 +196,35 @@
#define SPEECH_MESSAGE 1
// #define SPEECH_BUBBLE_TYPE 2
#define SPEECH_SPANS 3
/* #define SPEECH_SANITIZE 4
// #define SPEECH_SANITIZE 4
#define SPEECH_LANGUAGE 5
#define SPEECH_IGNORE_SPAM 6
#define SPEECH_FORCED 7 */
// #define SPEECH_IGNORE_SPAM 6
// #define SPEECH_FORCED 7
// /mob/living signals
#define COMSIG_LIVING_FULLY_HEAL "living_fully_healed" //from base of /mob/living/fully_heal(): (admin_revive)
#define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living)
#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living)
#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage)
#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags)
#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
#define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive)
#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" //sent when a mob/login() finishes: (client)
#define COMSIG_LIVING_GUN_PROCESS_FIRE "living_gun_process_fire" //from base of /obj/item/gun/proc/process_fire(): (atom/target, params, zone_override)
//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!
#define COMSIG_LIVING_STATUS_STUN "living_stun" //from base of mob/living/Stun() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_KNOCKDOWN "living_knockdown" //from base of mob/living/Knockdown() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_PARALYZE "living_paralyze" //from base of mob/living/Paralyze() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_IMMOBILIZE "living_immobilize" //from base of mob/living/Immobilize() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_UNCONSCIOUS "living_unconscious" //from base of mob/living/Unconscious() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_SLEEP "living_sleeping" //from base of mob/living/Sleeping() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_DAZE "living_daze" //from base of mob/living/Daze() (amount, update, ignore)
#define COMPONENT_NO_STUN 1 //For all of them
// /mob/living/carbon signals
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
#define COMSIG_CARBON_IDENTITY_TRANSFERRED_TO "carbon_id_transferred_to" //from datum/dna/transfer_identity(): (datum/dna, transfer_SE)
// /mob/living/simple_animal/hostile signals
#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
@@ -220,6 +240,7 @@
// /obj/item signals
#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
#define COMSIG_MOB_APPLY_DAMGE "mob_apply_damage" //from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone)
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob)
#define COMPONENT_NO_INTERACT 1
#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob)
@@ -227,12 +248,14 @@
#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params)
#define COMPONENT_NO_ATTACK 1
#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params)
#define COMSIG_ITEM_ALT_AFTERATTACK "item_alt_afterattack" //from base of obj/item/altafterattack(): (atom/target, mob/user, proximity, params)
#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot)
#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user)
#define COMSIG_ITEM_PICKUP "item_pickup" //from base of obj/item/pickup(): (/mob/taker)
#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone" //from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone)
#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user)
#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args)
#define COMSIG_ITEM_WEARERCROSSED "wearer_crossed" //called on item when crossed by something (): (/atom/movable)
// /obj/item/clothing signals
#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): ()
@@ -267,6 +290,9 @@
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target)
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker)
#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted)
#define COMSIG_HUMAN_PREFS_COPIED_TO "human_prefs_copied_to" //from datum/preferences/copy_to(): (datum/preferences, icon_updates, roundstart_checks)
#define COMSIG_HUMAN_HARDSET_DNA "human_hardset_dna" //from mob/living/carbon/human/hardset_dna(): (ui, list/mutation_index, newreal_name, newblood_type, datum/species, newfeatures)
#define COMSIG_HUMAN_ON_RANDOMIZE "humman_on_randomize" //from base of proc/randomize_human()
// /datum/species signals
#define COMSIG_SPECIES_GAIN "species_gain" //from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species)
@@ -295,11 +321,14 @@
//Nanites
#define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found
#define COMSIG_NANITE_IS_STEALTHY "nanite_is_stealthy" //() returns TRUE if nanites have stealth
#define COMSIG_NANITE_DELETE "nanite_delete" //() deletes the nanite component
#define COMSIG_NANITE_GET_PROGRAMS "nanite_get_programs" //(list/nanite_programs) - makes the input list a copy the nanites' program list
#define COMSIG_NANITE_GET_VOLUME "nanite_get_volume" //(amount) Returns nanite amount
#define COMSIG_NANITE_SET_VOLUME "nanite_set_volume" //(amount) Sets current nanite volume to the given amount
#define COMSIG_NANITE_ADJUST_VOLUME "nanite_adjust" //(amount) Adjusts nanite volume by the given amount
#define COMSIG_NANITE_SET_MAX_VOLUME "nanite_set_max_volume" //(amount) Sets maximum nanite volume to the given amount
#define COMSIG_NANITE_SET_CLOUD "nanite_set_cloud" //(amount(0-100)) Sets cloud ID to the given amount
#define COMSIG_NANITE_SET_CLOUD_SYNC "nanite_set_cloud_sync" //(method) Modify cloud sync status. Method can be toggle, enable or disable
#define COMSIG_NANITE_SET_SAFETY "nanite_set_safety" //(amount) Sets safety threshold to the given amount
#define COMSIG_NANITE_SET_REGEN "nanite_set_regen" //(amount) Sets regeneration rate to the given amount
#define COMSIG_NANITE_SIGNAL "nanite_signal" //(code(1-9999)) Called when sending a nanite signal to a mob.
@@ -307,8 +336,8 @@
#define COMSIG_NANITE_SCAN "nanite_scan" //(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected
#define COMSIG_NANITE_UI_DATA "nanite_ui_data" //(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs
#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program" //(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component
#define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful
#define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites
#define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful
#define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites
#define COMSIG_NANITE_SYNC "nanite_sync" //(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component
// /datum/component/storage signals
+4 -15
View File
@@ -59,19 +59,6 @@
//let's just pretend fulltile windows being children of border windows is fine
#define FULLTILE_WINDOW_DIR NORTHEAST
//Material defines, for determining how much of a given material an item contains
#define MAT_METAL "$metal"
#define MAT_GLASS "$glass"
#define MAT_SILVER "$silver"
#define MAT_GOLD "$gold"
#define MAT_DIAMOND "$diamond"
#define MAT_URANIUM "$uranium"
#define MAT_PLASMA "$plasma"
#define MAT_BLUESPACE "$bluespace"
#define MAT_BANANIUM "$bananium"
#define MAT_TITANIUM "$titanium"
#define MAT_BIOMASS "$biomass"
#define MAT_PLASTIC "$plastic"
//The amount of materials you get from a sheet of mineral like iron/diamond/glass etc
#define MINERAL_MATERIAL_AMOUNT 2000
//The maximum size of a stack object.
@@ -92,17 +79,19 @@
#define CAT_BREAD "Breads"
#define CAT_BURGER "Burgers"
#define CAT_CAKE "Cakes"
#define CAT_DONUT "Donuts"
#define CAT_EGG "Egg-Based Food"
#define CAT_MEAT "Meats"
#define CAT_MEXICAN "Mexican"
#define CAT_MISCFOOD "Misc. Food"
#define CAT_PASTRY "Pastries"
#define CAT_PIE "Pies"
#define CAT_PIE "Pies & Sweets"
#define CAT_PIZZA "Pizzas"
#define CAT_SALAD "Salads"
#define CAT_SEAFOOD "Seafood"
#define CAT_SANDWICH "Sandwiches"
#define CAT_SOUP "Soups"
#define CAT_SPAGHETTI "Spaghettis"
#define CAT_FISH "Fish"
#define CAT_ICE "Frozen"
#define RCD_FLOORWALL 1
+33 -6
View File
@@ -54,13 +54,13 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define PASSCLOSEDTURF (1<<5)
#define LETPASSTHROW (1<<6)
//Movement Types
#define GROUND (1<<0)
#define FLYING (1<<1)
#define VENTCRAWLING (1<<2)
#define FLOATING (1<<3)
#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
#define GROUND (1<<0)
#define FLYING (1<<1)
#define VENTCRAWLING (1<<2)
#define FLOATING (1<<3)
#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
#define CRAWLING (1<<5) //Applied if you're crawling around on the ground/resting.
//Fire and Acid stuff, for resistance_flags
#define LAVA_PROOF (1<<0)
@@ -92,3 +92,30 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
// radiation
#define RAD_PROTECT_CONTENTS (1<<0)
#define RAD_NO_CONTAMINATE (1<<1)
//Mob mobility var flags
/// any flag
#define CHECK_MOBILITY(target, flags) CHECK_BITFIELD(target.mobility_flags, flags)
#define CHECK_ALL_MOBILITY(target, flags) CHECK_MULTIPLE_BITFIELDS(target.mobility_flags, flags)
/// can move
#define MOBILITY_MOVE (1<<0)
/// can, and is, standing up.
#define MOBILITY_STAND (1<<1)
/// can pickup items
#define MOBILITY_PICKUP (1<<2)
/// can use items and interact with world objects like opening closets/etc
#define MOBILITY_USE (1<<3)
/// can use interfaces like consoles
#define MOBILITY_UI (1<<4)
/// can use storage item
#define MOBILITY_STORAGE (1<<5)
/// can pull things
#define MOBILITY_PULL (1<<6)
/// can hold non-nodropped items voluntarily
#define MOBILITY_HOLD (1<<7)
/// Can resist out of buckling, grabs, cuffs, etc, in the usual order (buckle --> cuffs --> grab)
#define MOBILITY_RESIST (1<<8)
#define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL | MOBILITY_RESIST)
#define MOBILITY_FLAGS_ANY_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE)
-2
View File
@@ -20,5 +20,3 @@
#define INTERACT_MACHINE_SET_MACHINE (1<<6) //MACHINES HAVE THIS BY DEFAULT, SOMEONE SHOULD RUN THROUGH MACHINES AND REMOVE IT FROM THINGS LIKE LIGHT SWITCHES WHEN POSSIBLE!!--------------------------
//This flag determines if a machine set_machine's the user when the user uses it, making updateUsrDialog make the user re-call interact() on it.
//THIS FLAG IS ON ALL MACHINES BY DEFAULT, NEEDS TO BE RE-EVALUATED LATER!!
#define INTERACT_GHOST_READ (1<<0)
+31 -29
View File
@@ -23,6 +23,7 @@
#define DOCTOR (1<<4)
#define GENETICIST (1<<5)
#define VIROLOGIST (1<<6)
#define PARAMEDIC (1<<7)
#define CIVILIAN (1<<2)
@@ -58,32 +59,33 @@
#define JOB_DISPLAY_ORDER_ASSISTANT 1
#define JOB_DISPLAY_ORDER_CAPTAIN 2
#define JOB_DISPLAY_ORDER_HEAD_OF_PERSONNEL 3
#define JOB_DISPLAY_ORDER_BARTENDER 4
#define JOB_DISPLAY_ORDER_COOK 5
#define JOB_DISPLAY_ORDER_BOTANIST 6
#define JOB_DISPLAY_ORDER_JANITOR 7
#define JOB_DISPLAY_ORDER_CLOWN 8
#define JOB_DISPLAY_ORDER_MIME 9
#define JOB_DISPLAY_ORDER_CURATOR 10
#define JOB_DISPLAY_ORDER_LAWYER 11
#define JOB_DISPLAY_ORDER_CHAPLAIN 12
#define JOB_DISPLAY_ORDER_QUARTERMASTER 13
#define JOB_DISPLAY_ORDER_CARGO_TECHNICIAN 14
#define JOB_DISPLAY_ORDER_SHAFT_MINER 15
#define JOB_DISPLAY_ORDER_CHIEF_ENGINEER 16
#define JOB_DISPLAY_ORDER_STATION_ENGINEER 17
#define JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN 18
#define JOB_DISPLAY_ORDER_CHIEF_MEDICAL_OFFICER 19
#define JOB_DISPLAY_ORDER_MEDICAL_DOCTOR 20
#define JOB_DISPLAY_ORDER_CHEMIST 21
#define JOB_DISPLAY_ORDER_GENETICIST 22
#define JOB_DISPLAY_ORDER_VIROLOGIST 23
#define JOB_DISPLAY_ORDER_RESEARCH_DIRECTOR 24
#define JOB_DISPLAY_ORDER_SCIENTIST 25
#define JOB_DISPLAY_ORDER_ROBOTICIST 26
#define JOB_DISPLAY_ORDER_HEAD_OF_SECURITY 27
#define JOB_DISPLAY_ORDER_WARDEN 28
#define JOB_DISPLAY_ORDER_DETECTIVE 29
#define JOB_DISPLAY_ORDER_SECURITY_OFFICER 30
#define JOB_DISPLAY_ORDER_AI 31
#define JOB_DISPLAY_ORDER_CYBORG 32
#define JOB_DISPLAY_ORDER_QUARTERMASTER 4
#define JOB_DISPLAY_ORDER_CARGO_TECHNICIAN 5
#define JOB_DISPLAY_ORDER_SHAFT_MINER 6
#define JOB_DISPLAY_ORDER_BARTENDER 7
#define JOB_DISPLAY_ORDER_COOK 8
#define JOB_DISPLAY_ORDER_BOTANIST 9
#define JOB_DISPLAY_ORDER_JANITOR 10
#define JOB_DISPLAY_ORDER_CLOWN 11
#define JOB_DISPLAY_ORDER_MIME 12
#define JOB_DISPLAY_ORDER_CURATOR 13
#define JOB_DISPLAY_ORDER_LAWYER 14
#define JOB_DISPLAY_ORDER_CHAPLAIN 15
#define JOB_DISPLAY_ORDER_AI 16
#define JOB_DISPLAY_ORDER_CYBORG 17
#define JOB_DISPLAY_ORDER_CHIEF_ENGINEER 18
#define JOB_DISPLAY_ORDER_STATION_ENGINEER 19
#define JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN 20
#define JOB_DISPLAY_ORDER_CHIEF_MEDICAL_OFFICER 21
#define JOB_DISPLAY_ORDER_MEDICAL_DOCTOR 22
#define JOB_DISPLAY_ORDER_PARAMEDIC 23
#define JOB_DISPLAY_ORDER_CHEMIST 24
#define JOB_DISPLAY_ORDER_VIROLOGIST 25
#define JOB_DISPLAY_ORDER_GENETICIST 26
#define JOB_DISPLAY_ORDER_RESEARCH_DIRECTOR 27
#define JOB_DISPLAY_ORDER_SCIENTIST 28
#define JOB_DISPLAY_ORDER_ROBOTICIST 29
#define JOB_DISPLAY_ORDER_HEAD_OF_SECURITY 30
#define JOB_DISPLAY_ORDER_WARDEN 31
#define JOB_DISPLAY_ORDER_DETECTIVE 32
#define JOB_DISPLAY_ORDER_SECURITY_OFFICER 33
+1 -1
View File
@@ -41,7 +41,7 @@
//Individual logging panel pages
#define INDIVIDUAL_ATTACK_LOG (LOG_ATTACK)
#define INDIVIDUAL_SAY_LOG (LOG_SAY | LOG_WHISPER | LOG_DSAY)
#define INDIVIDUAL_EMOTE_LOG (LOG_EMOTE)
#define INDIVIDUAL_EMOTE_LOG (LOG_EMOTE | LOG_SUBTLER)
#define INDIVIDUAL_COMMS_LOG (LOG_PDA | LOG_CHAT | LOG_COMMENT | LOG_TELECOMMS)
#define INDIVIDUAL_OOC_LOG (LOG_OOC | LOG_ADMIN)
#define INDIVIDUAL_OWNERSHIP_LOG (LOG_OWNERSHIP)
+11
View File
@@ -0,0 +1,11 @@
/// Is the material from an ore? currently unused but exists atm for categorizations sake
#define MAT_CATEGORY_ORE "ore capable"
/// Hard materials, such as iron or metal
#define MAT_CATEGORY_RIGID "rigid material"
/// Flag for atoms, this flag ensures it isn't re-colored by materials. Useful for snowflake icons such as default toolboxes.
#define MATERIAL_COLOR (1<<0)
#define MATERIAL_ADD_PREFIX (1<<1)
#define MATERIAL_NO_EFFECTS (1<<2)
#define MATERIAL_AFFECT_STATISTICS (1<<3)
+3 -1
View File
@@ -199,4 +199,6 @@
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/PI)*TORADIANS(arctan((x-y)/s)) + 1/2 )
#define RULE_OF_THREE(a, b, x) ((a*x)/b)
// )
// )
#define MANHATTAN_DISTANCE(a, b) (abs(a.x - b.x) + abs(a.y - b.y))
+4
View File
@@ -406,6 +406,8 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define DUMMY_HUMAN_SLOT_HOLOFORM "dummy_holoform_generation"
#define DUMMY_HUMAN_SLOT_ADMIN "admintools"
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
#define DUMMY_HUMAN_SLOT_HALLUCINATION "dummy_hallucination"
#define DUMMY_HUMAN_SLOT_EXAMINER "dummy_examiner"
#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
//This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
@@ -520,3 +522,5 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define NIGHTSHIFT_AREA_RECREATION 2 //dorms common areas, etc
#define NIGHTSHIFT_AREA_DEPARTMENT_HALLS 3 //interior hallways, etc
#define NIGHTSHIFT_AREA_NONE 4 //default/highest.
#define UNTIL(X) while(!(X)) stoplag()
+25 -12
View File
@@ -35,17 +35,17 @@
#define BLOODCRAWL 1
#define BLOODCRAWL_EAT 2
//Mob bio-types
#define MOB_ORGANIC "organic"
#define MOB_INORGANIC "inorganic"
#define MOB_ROBOTIC "robotic"
#define MOB_UNDEAD "undead"
#define MOB_HUMANOID "humanoid"
#define MOB_BUG "bug"
#define MOB_BEAST "beast"
#define MOB_EPIC "epic" //megafauna
#define MOB_REPTILE "reptile"
#define MOB_SPIRIT "spirit"
//Mob bio-types flags
#define MOB_ORGANIC 1 << 0
#define MOB_MINERAL 1 << 1
#define MOB_ROBOTIC 1 << 2
#define MOB_UNDEAD 1 << 3
#define MOB_HUMANOID 1 << 4
#define MOB_BUG 1 << 5
#define MOB_BEAST 1 << 6
#define MOB_EPIC 1 << 7 //megafauna
#define MOB_REPTILE 1 << 8
#define MOB_SPIRIT 1 << 9
//Organ defines for carbon mobs
#define ORGAN_ORGANIC 1
@@ -58,8 +58,10 @@
#define BODYPART_DISABLED_DAMAGE 1
#define BODYPART_DISABLED_PARALYSIS 2
#define DEFAULT_BODYPART_ICON 'icons/mob/human_parts.dmi'
#define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi'
#define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi'
#define DEFAULT_BODYPART_ICON_CITADEL 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
#define MONKEY_BODYPART "monkey"
#define ALIEN_BODYPART "alien"
@@ -208,6 +210,17 @@
#define MAX_CHICKENS 50
///Flags used by the flags parameter of electrocute act.
///Makes it so that the shock doesn't take gloves into account.
#define SHOCK_NOGLOVES (1 << 0)
///Used when the shock is from a tesla bolt.
#define SHOCK_TESLA (1 << 1)
///Used when an illusion shocks something. Makes the shock deal stamina damage and not trigger certain secondary effects.
#define SHOCK_ILLUSION (1 << 2)
///The shock doesn't stun.
#define SHOCK_NOSTUN (1 << 3)
#define INCORPOREAL_MOVE_BASIC 1
#define INCORPOREAL_MOVE_SHADOW 2 // leaves a trail of shadows
@@ -276,4 +289,4 @@
#define HUMAN_FIRE_STACK_ICON_NUM 3
#define PULL_PRONE_SLOWDOWN 0.6
#define HUMAN_CARRY_SLOWDOWN 0
#define HUMAN_CARRY_SLOWDOWN 0
+1 -1
View File
@@ -17,4 +17,4 @@
#define MOVE_FORCE_NORMAL MOVE_FORCE_DEFAULT
#define MOVE_FORCE_WEAK (MOVE_FORCE_DEFAULT / 2)
#define MOVE_FORCE_VERY_WEAK ((MOVE_FORCE_DEFAULT / MOVE_FORCE_CRUSH_RATIO) + 1)
#define MOVE_FORCE_EXTREMELY_WEAK (MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3))
#define MOVE_FORCE_EXTREMELY_WEAK (MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3))
+14 -4
View File
@@ -17,6 +17,9 @@
//ids
#define MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED "MOB_WALK_RUN"
#define MOVESPEED_ID_MOB_GRAB_STATE "MOB_GRAB_STATE"
#define MOVESPEED_ID_MOB_EQUIPMENT "MOB_EQUIPMENT"
#define MOVESPEED_ID_MOB_GRAVITY "MOB_GRAVITY"
#define MOVESPEED_ID_CONFIG_SPEEDMOD "MOB_CONFIG_MODIFIER"
#define MOVESPEED_ID_SLIME_REAGENTMOD "SLIME_REAGENT_MODIFIER"
@@ -28,6 +31,7 @@
#define MOVESPEED_ID_TARANTULA_WEB "TARANTULA_WEB"
#define MOVESPEED_ID_LIVING_TURF_SPEEDMOD "LIVING_TURF_SPEEDMOD"
#define MOVESPEED_ID_LIVING_LIMBLESS "LIVING_LIMBLESS"
#define MOVESPEED_ID_CARBON_SOFTCRIT "CARBON_SOFTCRIT"
#define MOVESPEED_ID_CARBON_OLDSPEED "CARBON_DEPRECATED_SPEED"
@@ -59,13 +63,19 @@
#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
#define MOVESPEED_ID_SHRINK_RAY "SHRUNKEN_SPEED_MODIFIER"
#define MOVESPEED_ID_TASED_STATUS "TASED"
#define MOVESPEED_ID_SLAUGHTER "SLAUGHTER"
#define MOVESPEED_ID_CYBER_THRUSTER "CYBER_IMPLANT_THRUSTER"
#define MOVESPEED_ID_JETPACK "JETPACK"
#define MOVESPEED_ID_SHOVE "SHOVE"
#define MOVESPEED_ID_MKULTRA "MKULTRA"
#define MOVESPEED_ID_MKULTRA "MKULTRA"
#define MOVESPEED_ID_TASED_STATUS "TASED"
#define MOVESPEED_ID_ELECTROSTAFF "ELECTROSTAFF"
#define MOVESPEED_ID_SHOVE "SHOVE"
#define MOVESPEED_ID_FAT "FAT"
#define MOVESPEED_ID_COLD "COLD"
#define MOVESPEED_ID_HUNGRY "HUNGRY"
#define MOVESPEED_ID_DAMAGE_SLOWDOWN "DAMAGE"
#define MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING "FLYING"
+39 -6
View File
@@ -1,11 +1,44 @@
#define NANITE_TIMER_DEACTIVATE 1
#define NANITE_TIMER_SELFDELETE 2
#define NANITE_TIMER_TRIGGER 3
#define NANITE_TIMER_RESET 4
#define NANITE_SYNC_DELAY 300
#define NANITE_SHOCK_IMMUNE 1
#define NANITE_EMP_IMMUNE 2
#define NANITE_PROGRAM_LIMIT 20
#define NANITE_PROGRAM_LIMIT 20
#define NANITE_BASE_RESEARCH 3.5
#define NANITE_CLOUD_TOGGLE 1
#define NANITE_CLOUD_DISABLE 2
#define NANITE_CLOUD_ENABLE 3
///Nanite extra settings types: used to help uis know what type an extra setting is
#define NESTYPE_TEXT "text"
#define NESTYPE_NUMBER "number"
#define NESTYPE_TYPE "type"
#define NESTYPE_BOOLEAN "boolean"
///Nanite Extra Settings - Note that these will also be the names displayed in the UI
#define NES_SENT_CODE "Sent Code"
#define NES_DELAY "Delay"
#define NES_MODE "Mode"
#define NES_COMM_CODE "Comm Code"
#define NES_RELAY_CHANNEL "Relay Channel"
#define NES_HEALTH_PERCENT "Health Percent"
#define NES_DIRECTION "Direction"
#define NES_NANITE_PERCENT "Nanite Percent"
#define NES_DAMAGE_TYPE "Damage Type"
#define NES_DAMAGE "Damage"
#define NES_SENTENCE "Sentence"
#define NES_MESSAGE "Message"
#define NES_DIRECTIVE "Directive"
#define NES_INCLUSIVE_MODE "Inclusive Mode"
#define NES_HALLUCINATION_TYPE "Hallucination Type"
#define NES_HALLUCINATION_DETAIL "Hallucination Detail"
#define NES_MOOD_MESSAGE "Mood Message"
#define NES_PROGRAM_OVERWRITE "Program Overwrite"
#define NES_CLOUD_OVERWRITE "Cloud Overwrite"
#define NES_SCAN_TYPE "Scan Type"
#define NES_BUTTON_NAME "Button Name"
#define NES_ICON "Icon"
#define NES_COLOR "Color"
+13 -12
View File
@@ -17,18 +17,19 @@
// Flags for the item_flags var on /obj/item
#define BEING_REMOVED (1<<0)
#define IN_INVENTORY (1<<1) //is this item equipped into an inventory slot or hand of a mob? used for tooltips
#define FORCE_STRING_OVERRIDE (1<<2) //used for tooltips
#define NEEDS_PERMIT (1<<3) //Used by security bots to determine if this item is safe for public use.
#define SLOWS_WHILE_IN_HAND (1<<4)
#define NO_MAT_REDEMPTION (1<<5) //Stops you from putting things like an RCD or other items into an ORM or protolathe for materials.
#define DROPDEL (1<<6) //When dropped, it calls qdel on itself
#define NOBLUDGEON (1<<7) //when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
#define ABSTRACT (1<<8) //for all things that are technically items but used for various different stuff
#define IMMUTABLE_SLOW (1<<9) //When players should not be able to change the slowdown of the item (Speed potions, ect)
#define SURGICAL_TOOL (1<<10) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes)
#define NO_UNIFORM_REQUIRED (1<<11) //Can be worn on certain slots (currently belt and id) that would otherwise require an uniform.
#define BEING_REMOVED (1<<0)
#define IN_INVENTORY (1<<1) //is this item equipped into an inventory slot or hand of a mob? used for tooltips
#define FORCE_STRING_OVERRIDE (1<<2) //used for tooltips
#define NEEDS_PERMIT (1<<3) //Used by security bots to determine if this item is safe for public use.
#define SLOWS_WHILE_IN_HAND (1<<4)
#define NO_MAT_REDEMPTION (1<<5) //Stops you from putting things like an RCD or other items into an ORM or protolathe for materials.
#define DROPDEL (1<<6) //When dropped, it calls qdel on itself
#define NOBLUDGEON (1<<7) //when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
#define ABSTRACT (1<<8) //for all things that are technically items but used for various different stuff
#define IMMUTABLE_SLOW (1<<9) //When players should not be able to change the slowdown of the item (Speed potions, ect)
#define SURGICAL_TOOL (1<<10) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes)
#define NO_UNIFORM_REQUIRED (1<<11) //Can be worn on certain slots (currently belt and id) that would otherwise require an uniform.
#define NO_ATTACK_CHAIN_SOFT_STAMCRIT (1<<12) //Entirely blocks melee_attack_chain() if user is soft stamcritted. Uses getStaminaLoss() to check at this point in time. THIS DOES NOT BLOCK RANGED AFTERATTACK()S, ONLY MELEE RANGE AFTERATTACK()S.
// Flags for the clothing_flags var on /obj/item/clothing
+13
View File
@@ -0,0 +1,13 @@
//TODO: move these to their own file
#define POOL_FRIGID 1
#define POOL_COOL 2
#define POOL_NORMAL 3
#define POOL_WARM 4
#define POOL_SCALDING 5
GLOBAL_LIST_INIT(blacklisted_pool_reagents, list(
/datum/reagent/toxin/plasma, /datum/reagent/oxygen, /datum/reagent/nitrous_oxide, /datum/reagent/nitrogen, //gases
/datum/reagent/fermi, //blanket fermichem ban sorry. this also covers mkultra, genital enlargers, etc etc.
/datum/reagent/drug/aphrodisiac, /datum/reagent/drug/anaphrodisiac, /datum/reagent/drug/aphrodisiacplus, /datum/reagent/drug/anaphrodisiacplus, //literally asking for prefbreaks
/datum/reagent/consumable/femcum, /datum/reagent/consumable/semen //NO.
))
+3
View File
@@ -0,0 +1,3 @@
#define SOLAR_TRACK_OFF 0
#define SOLAR_TRACK_TIMED 1
#define SOLAR_TRACK_AUTO 2
+2 -2
View File
@@ -1,5 +1,5 @@
#define PROFILE_START ;PROFILE_STORE = list();PROFILE_SET;
#define PROFILE_STOP ;PROFILE_STORE = null;
#define LINE_PROFILE_START ;PROFILE_STORE = list();PROFILE_SET;
#define LINE_PROFILE_STOP ;PROFILE_STORE = null;
#define PROFILE_SET ;PROFILE_TIME = TICK_USAGE_REAL; PROFILE_LINE = __LINE__; PROFILE_FILE = __FILE__; PROFILE_SLEEPCHECK = world.time;
+4
View File
@@ -23,6 +23,10 @@ Ask ninjanomnom if they're around
#define RAD_MOB_MUTATE 1250 // How much stored radiation to check for mutation
#define RAD_MONKEY_GORILLIZE 1650 // How much stored radiation to check for Harambe time.
#define RAD_MOB_GORILLIZE_FACTOR 100
#define RAD_MONKEY_GORILLIZE_EXPONENT 0.5
#define RAD_MOB_VOMIT 2000 // The amount of radiation to check for vomitting
#define RAD_MOB_VOMIT_PROB 1 // Chance per tick of vomitting
+5
View File
@@ -22,6 +22,11 @@
// Is an open container for all intents and purposes.
#define OPENCONTAINER (REFILLABLE | DRAINABLE | TRANSPARENT)
//reagents_value defines, for cargo stuff.
#define DEFAULT_REAGENTS_VALUE 1
#define NO_REAGENTS_VALUE 0
#define HARVEST_REAGENTS_VALUE 0.3
#define TOUCH 1 // splashing
#define INGEST 2 // ingestion
+7 -1
View File
@@ -53,4 +53,10 @@
//Checks to determine borg availability depending on the server's config. These are defines in the interest of reducing copypasta
#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert))
#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert))
//silicon_priviledges flags
#define PRIVILEDGES_SILICON (1<<0)
#define PRIVILEDGES_PAI (1<<1)
#define PRIVILEDGES_BOT (1<<2)
#define PRIVILEDGES_DRONE (1<<3)
+1
View File
@@ -81,6 +81,7 @@
//Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam
#define MAX_MESSAGE_LEN 2048 //Citadel edit: What's the WORST that could happen?
#define MAX_FAVOR_LEN 4096 //double the maximum message length.
#define MAX_NAME_LEN 42
#define MAX_BROADCAST_LEN 512
#define MAX_CHARTER_LEN 80
+16 -3
View File
@@ -37,16 +37,25 @@
/////////////
// DEBUFFS //
/////////////
/// The affected is unable to move, or to use, hold, or pickup items.
#define STATUS_EFFECT_STUN /datum/status_effect/incapacitating/stun
#define STATUS_EFFECT_STUN /datum/status_effect/incapacitating/stun //the affected is stunned
#define STATUS_EFFECT_KNOCKDOWN /datum/status_effect/incapacitating/knockdown //the affected is unable to stand up
#define STATUS_EFFECT_KNOCKDOWN /datum/status_effect/incapacitating/knockdown //the affected is knocked down
#define STATUS_EFFECT_IMMOBILIZED /datum/status_effect/incapacitating/immobilized //the affected is unable to move
#define STATUS_EFFECT_PARALYZED /datum/status_effect/incapacitating/paralyzed //the affected is unable to move, use items, or stand up.
/// The affected is unable to use or pickup items
#define STATUS_EFFECT_DAZED /datum/status_effect/incapacitating/dazed
#define STATUS_EFFECT_UNCONSCIOUS /datum/status_effect/incapacitating/unconscious //the affected is unconscious
#define STATUS_EFFECT_SLEEPING /datum/status_effect/incapacitating/sleeping //the affected is asleep
#define STATUS_EFFECT_TASED /datum/status_effect/no_combat_mode/electrode/ //the affected has been tased, preventing fine muscle control
#define STATUS_EFFECT_TASED_WEAK /datum/status_effect/electrode //not as crippling, just slows down
#define STATUS_EFFECT_TASED /datum/status_effect/electrode/no_combat_mode //the affected has been tased, preventing fine muscle control
#define STATUS_EFFECT_PACIFY /datum/status_effect/pacify //the affected is pacified, preventing direct hostile actions
@@ -88,6 +97,9 @@
#define STATUS_EFFECT_NO_COMBAT_MODE /datum/status_effect/no_combat_mode //Wont allow combat mode and will disable it
#define STATUS_EFFECT_MESMERIZE /datum/status_effect/no_combat_mode/mesmerize //Just reskinned no_combat_mode
#define STATUS_EFFECT_ELECTROSTAFF /datum/status_effect/electrostaff //slows down victim
/////////////
// NEUTRAL //
/////////////
@@ -106,3 +118,4 @@
#define STATUS_EFFECT_RAINBOWPROTECTION /datum/status_effect/rainbow_protection //Invulnerable and pacifistic
#define STATUS_EFFECT_SLIMESKIN /datum/status_effect/slimeskin //Increased armor
#define STATUS_EFFECT_DNA_MELT /datum/status_effect/dna_melt //usually does something horrible to you when you hit 100 genetic instability
+20 -19
View File
@@ -47,25 +47,26 @@
// Subsystems shutdown in the reverse of the order they initialize in
// The numbers just define the ordering, they are meaningless otherwise.
#define INIT_ORDER_FAIL2TOPIC 22
#define INIT_ORDER_TITLE 20
#define INIT_ORDER_GARBAGE 19
#define INIT_ORDER_DBCORE 18
#define INIT_ORDER_BLACKBOX 17
#define INIT_ORDER_SERVER_MAINT 16
#define INIT_ORDER_INPUT 15
#define INIT_ORDER_VIS 14
#define INIT_ORDER_RESEARCH 13
#define INIT_ORDER_EVENTS 12
#define INIT_ORDER_JOBS 11
#define INIT_ORDER_QUIRKS 10
#define INIT_ORDER_TICKER 9
#define INIT_ORDER_MAPPING 8
#define INIT_ORDER_NETWORKS 7
#define INIT_ORDER_ATOMS 6
#define INIT_ORDER_LANGUAGE 5
#define INIT_ORDER_MACHINES 4
#define INIT_ORDER_CIRCUIT 3
#define INIT_ORDER_PROFILER 100
#define INIT_ORDER_FAIL2TOPIC 99
#define INIT_ORDER_TITLE 98
#define INIT_ORDER_GARBAGE 97
#define INIT_ORDER_DBCORE 95
#define INIT_ORDER_BLACKBOX 94
#define INIT_ORDER_SERVER_MAINT 93
#define INIT_ORDER_INPUT 85
#define INIT_ORDER_VIS 80
#define INIT_ORDER_RESEARCH 75
#define INIT_ORDER_EVENTS 70
#define INIT_ORDER_JOBS 65
#define INIT_ORDER_QUIRKS 60
#define INIT_ORDER_TICKER 55
#define INIT_ORDER_MAPPING 50
#define INIT_ORDER_NETWORKS 45
#define INIT_ORDER_ATOMS 30
#define INIT_ORDER_LANGUAGE 25
#define INIT_ORDER_MACHINES 20
#define INIT_ORDER_CIRCUIT 15
#define INIT_ORDER_TIMER 1
#define INIT_ORDER_DEFAULT 0
#define INIT_ORDER_AIR -1
+1
View File
@@ -1,4 +1,5 @@
#define TGS_EXTERNAL_CONFIGURATION
#define TGS_V3_API
#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name)
#define TGS_READ_GLOBAL(Name) GLOB.##Name
#define TGS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value
+21 -5
View File
@@ -107,6 +107,22 @@
var/commit //full sha of compiled commit
var/origin_commit //full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch
//represents a version of tgstation-server
/datum/tgs_version
var/suite //The suite version, can be >=3
//this group of variables can be null to represent a wild card
var/major //The major version
var/minor //The minor version
var/patch //The patch version
var/raw_parameter //The unparsed parameter
var/deprefixed_parameter //The version only bit of raw_parameter
//if the tgs_version is a wildcard version
/datum/tgs_version/proc/Wildcard()
return
//represents a merge of a GitHub pull request
/datum/tgs_revision_information/test_merge
var/number //pull request number
@@ -155,22 +171,22 @@
//FUNCTIONS
//Returns the respective string version of the API
//Returns the respective supported /datum/tgs_version of the API
/world/proc/TgsMaximumAPIVersion()
return
/world/proc/TgsMinimumAPIVersion()
return
//Gets the current version of the server tools running the server
/world/proc/TgsVersion()
return
//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise
//No function below this succeeds if it returns FALSE
/world/proc/TgsAvailable()
return
//Gets the current /datum/tgs_version of the server tools running the server
/world/proc/TgsVersion()
return
/world/proc/TgsInstanceName()
return
+26 -2
View File
@@ -1,3 +1,5 @@
#define SIGNAL_TRAIT(trait_ref) "trait [trait_ref]"
// trait accessor defines
#define ADD_TRAIT(target, trait, source) \
do { \
@@ -6,12 +8,14 @@
target.status_traits = list(); \
_L = target.status_traits; \
_L[trait] = list(source); \
SEND_SIGNAL(target, SIGNAL_TRAIT(trait), COMPONENT_ADD_TRAIT); \
} else { \
_L = target.status_traits; \
if (_L[trait]) { \
_L[trait] |= list(source); \
} else { \
_L[trait] = list(source); \
SEND_SIGNAL(target, SIGNAL_TRAIT(trait), COMPONENT_ADD_TRAIT); \
} \
} \
} while (0)
@@ -31,7 +35,8 @@
} \
};\
if (!length(_L[trait])) { \
_L -= trait \
_L -= trait; \
SEND_SIGNAL(target, SIGNAL_TRAIT(trait), COMPONENT_REMOVE_TRAIT); \
}; \
if (!length(_L)) { \
target.status_traits = null \
@@ -46,7 +51,8 @@
for (var/_T in _L) { \
_L[_T] &= _S;\
if (!length(_L[_T])) { \
_L -= _T } \
_L -= _T ; \
SEND_SIGNAL(target, SIGNAL_TRAIT(_T), COMPONENT_REMOVE_TRAIT); } \
};\
if (!length(_L)) { \
target.status_traits = null\
@@ -55,6 +61,7 @@
} while (0)
#define HAS_TRAIT(target, trait) (target.status_traits ? (target.status_traits[trait] ? TRUE : FALSE) : FALSE)
#define HAS_TRAIT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (source in target.status_traits[trait]) : FALSE) : FALSE)
#define HAS_TRAIT_NOT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (length(target.status_traits[trait] - source) > 0) : FALSE) : FALSE)
//mob traits
#define TRAIT_BLIND "blind"
@@ -76,6 +83,7 @@
#define TRAIT_DISFIGURED "disfigured"
#define TRAIT_XENO_HOST "xeno_host" //Tracks whether we're gonna be a baby alien's mummy.
#define TRAIT_STUNIMMUNE "stun_immunity"
#define TRAIT_TASED_RESISTANCE "tased_resistance" //prevents you from suffering most of the effects of being tased
#define TRAIT_SLEEPIMMUNE "sleep_immunity"
#define TRAIT_PUSHIMMUNE "push_immunity"
#define TRAIT_SHOCKIMMUNE "shock_immunity"
@@ -110,6 +118,7 @@
#define TRAIT_NOHARDCRIT "nohardcrit"
#define TRAIT_NOSOFTCRIT "nosoftcrit"
#define TRAIT_MINDSHIELD "mindshield"
#define TRAIT_HIJACKER "hijacker"
#define TRAIT_SIXTHSENSE "sixthsense"
#define TRAIT_DISSECTED "dissected"
#define TRAIT_FEARLESS "fearless"
@@ -136,6 +145,19 @@
#define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat.
#define TRAIT_EXEMPT_HEALTH_EVENTS "exempt-health-events"
// mobility flag traits
// IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it)
// BUT FOR NOW, THESE ARE HOOKED TO DO update_mobility() VIA COMSIG IN living_mobility.dm
// SO IF YOU ADD MORE, BESURE TO UPDATE IT THERE.
/// Disallow movement
#define TRAIT_MOBILITY_NOMOVE "mobility_nomove"
/// Disallow pickup
#define TRAIT_MOBILITY_NOPICKUP "mobility_nopickup"
/// Disallow item use
#define TRAIT_MOBILITY_NOUSE "mobility_nouse"
#define TRAIT_SWIMMING "swimming" //only applied by /datum/element/swimming, for checking
//non-mob traits
#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it
@@ -173,6 +195,8 @@
#define TRAIT_AUTO_CATCH_ITEM "auto_catch_item"
#define TRAIT_CLOWN_MENTALITY "clown_mentality" // The future is now, clownman.
#define TRAIT_FREESPRINT "free_sprinting"
#define TRAIT_XRAY_VISION "xray_vision"
#define TRAIT_THERMAL_VISION "thermal_vision"
#define TRAIT_NO_TELEPORT "no-teleport" //you just can't
#define TRAIT_NO_INTERNALS "no-internals"
#define TRAIT_NO_ALCOHOL "alcohol_intolerance"
+9
View File
@@ -6,3 +6,12 @@
#define INSTANT_RUNOFF_VOTING 5
GLOBAL_LIST_INIT(vote_score_options,list("Bad","Poor","Acceptable","Good","Great"))
GLOBAL_LIST_INIT(vote_type_names,list(\
"Plurality (default)" = PLURALITY_VOTING,\
"Approval" = APPROVAL_VOTING,\
"IRV (single winner ranked choice)" = INSTANT_RUNOFF_VOTING,\
"Schulze (ranked choice, higher result=better)" = SCHULZE_VOTING,\
"Raw Score (returns results from 0 to 1, winner is 1)" = SCORE_VOTING,\
"Majority Judgement (single-winner score voting)" = MAJORITY_JUDGEMENT_VOTING,\
))
+1 -26
View File
@@ -57,14 +57,11 @@ GLOBAL_LIST_EMPTY(ipc_antennas_list)
//Genitals and Arousal Lists
GLOBAL_LIST_EMPTY(genitals_list)
GLOBAL_LIST_EMPTY(cock_shapes_list)//global_lists.dm for the list initializations //Now also _DATASTRUCTURES globals.dm
GLOBAL_LIST_EMPTY(cock_shapes_icons) //Associated list for names->icon_states for cockshapes.
GLOBAL_LIST_EMPTY(cock_shapes_list)
GLOBAL_LIST_EMPTY(gentlemans_organ_names)
GLOBAL_LIST_EMPTY(balls_shapes_list)
GLOBAL_LIST_EMPTY(balls_shapes_icons)
GLOBAL_LIST_EMPTY(breasts_size_list)
GLOBAL_LIST_EMPTY(breasts_shapes_list)
GLOBAL_LIST_EMPTY(breasts_shapes_icons)
GLOBAL_LIST_EMPTY(vagina_shapes_list)
GLOBAL_LIST_INIT(cum_into_containers_list, list(/obj/item/reagent_containers/food/snacks/pie)) //Yer fuggin snowflake name list jfc
GLOBAL_LIST_INIT(dick_nouns, list("dick","cock","member","shaft"))
@@ -110,28 +107,6 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
if(!src.holder) return
message_admins("[key_name_admin(usr)] manually reloaded mentors")
//Flavor Text
/mob/living/carbon/human/verb/set_flavor()
set name = "Set Flavor Text"
set desc = "Sets an extended description of your character's features."
set category = "IC"
var/new_flavor = input(src, "Enter your new flavor text:", "Flavor text", null) as message|null
if(!isnull(new_flavor))
flavor_text = sanitize(new_flavor)
to_chat(src, "Your flavor text has been updated.")
//Flavor Text
/mob/living/carbon/human/verb/set_flavor_2()
set name = "Set Temporary Flavor Text"
set desc = "Sets a description of your character's current appearance. Use this for emotions, poses etc."
set category = "IC"
var/new_flavor = input(src, "Enter your new temporary flavor text:", "Temporary flavor text", null) as message|null
if(!isnull(new_flavor))
flavor_text_2 = sanitize(new_flavor)
to_chat(src, "Your temporary flavor text has been updated.")
//LOOC toggles
/client/verb/listen_looc()
set name = "Show/Hide LOOC"
+10 -1
View File
@@ -174,6 +174,15 @@
L[T] = TRUE
return L
/proc/typecacheof_assoc_list(list/pathlist, ignore_root_path = FALSE)
. = list()
if(!istype(pathlist))
return
for(var/P in pathlist)
var/value = pathlist[P]
for(var/T in (ignore_root_path ? subtypesof(P) : typesof(P)))
.[T] = value
//Empties the list by setting the length to 0. Hopefully the elements get garbage collected
/proc/clearlist(list/list)
if(istype(list))
@@ -579,4 +588,4 @@
var/list/ret = list()
for(var/key in input)
ret += key
return ret
return ret
+5
View File
@@ -1,5 +1,10 @@
#define BP_MAX_ROOM_SIZE 300
GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/engineering, \
/area/engine/supermatter, \
/area/engine/atmospherics_engine, \
/area/ai_monitored/turret_protected/ai))
//Repopulates sortedAreas list
/proc/repopulate_sorted_areas()
GLOB.sortedAreas = list()
+12
View File
@@ -0,0 +1,12 @@
//////////////////////////////////////////////////////////
//A bunch of helpers to make genetics less of a headache//
//////////////////////////////////////////////////////////
#define GET_INITIALIZED_MUTATION(A) GLOB.all_mutations[A]
#define GET_GENE_STRING(A, B) (B.mutation_index[A])
#define GET_SEQUENCE(A) (GLOB.full_sequences[A])
#define GET_MUTATION_STABILIZER(A) ((A.stabilizer_coeff < 0) ? 1 : A.stabilizer_coeff)
#define GET_MUTATION_SYNCHRONIZER(A) ((A.synchronizer_coeff < 0) ? 1 : A.synchronizer_coeff)
#define GET_MUTATION_POWER(A) ((A.power_coeff < 0) ? 1 : A.power_coeff)
#define GET_MUTATION_ENERGY(A) ((A.energy_coeff < 0) ? 1 : A.energy_coeff)
+34 -1
View File
@@ -436,7 +436,7 @@
var/list/result = list()
for(var/m in group)
var/mob/M = m
if(!M.key || !M.client || (ignore_category && GLOB.poll_ignore[ignore_category] && M.ckey in GLOB.poll_ignore[ignore_category]))
if(!M.key || !M.client || (ignore_category && GLOB.poll_ignore[ignore_category] && (M.ckey in GLOB.poll_ignore[ignore_category])))
continue
if(be_special_flag)
if(!(M.client.prefs) || !(be_special_flag in M.client.prefs.be_special))
@@ -549,3 +549,36 @@
var/pressure = environment.return_pressure()
if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE)
. = TRUE
/proc/ispipewire(item)
var/static/list/pipe_wire = list(
/obj/machinery/atmospherics,
/obj/structure/disposalpipe,
/obj/structure/cable
)
return (is_type_in_list(item, pipe_wire))
// Find a obstruction free turf that's within the range of the center. Can also condition on if it is of a certain area type.
/proc/find_obstruction_free_location(var/range, var/atom/center, var/area/specific_area)
var/list/turfs = RANGE_TURFS(range, center)
var/list/possible_loc = list()
for(var/turf/found_turf in turfs)
var/area/turf_area = get_area(found_turf)
if(specific_area) // We check if both the turf is a floor, and that it's actually in the area. // We also want a location that's clear of any obstructions.
if(!istype(turf_area, specific_area))
continue
if(!isspaceturf(found_turf))
if(!is_blocked_turf(found_turf))
possible_loc.Add(found_turf)
if(possible_loc.len < 1) // Need at least one free location.
return FALSE
return pick(possible_loc)
/proc/power_fail(duration_min, duration_max)
for(var/P in GLOB.apcs_list)
var/obj/machinery/power/apc/C = P
if(C.cell && SSmapping.level_trait(C.z, ZTRAIT_STATION))
var/area/A = C.area
if(GLOB.typecache_powerfailure_safe_areas[A.type])
continue
C.energy_fail(rand(duration_min,duration_max))
+10 -17
View File
@@ -51,26 +51,15 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/antenna, GLOB.ipc_antennas_list, roundstart = TRUE)
//genitals
init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list)
for(var/K in GLOB.cock_shapes_list)
var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K]
GLOB.cock_shapes_icons[K] = value.icon_state
init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list)
GLOB.breasts_size_list = list ("a", "b", "c", "d", "e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing.
GLOB.gentlemans_organ_names = list("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ",
"cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret",
"baloney pony", "schlanger", "Mutton dagger", "old blind bob","Hanging Johnny", "fishing rod", "Tally whacker", "polly rocket",
"One eyed trouser trout", "Ding dong", "ankle spanker", "Pork sword", "engine cranker", "Harry hot dog", "Davy Crockett",
"Kidney cracker", "Heat seeking moisture missile", "Giggle stick", "love whistle", "Tube steak", "Uncle Dick", "Purple helmet warrior")
for(var/K in GLOB.breasts_shapes_list)
var/datum/sprite_accessory/breasts/value = GLOB.breasts_shapes_list[K]
GLOB.breasts_shapes_icons[K] = value.icon_state
init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list)
for(var/K in GLOB.balls_shapes_list)
var/datum/sprite_accessory/testicles/value = GLOB.balls_shapes_list[K]
GLOB.balls_shapes_icons[K] = value.icon_state
for(var/gpath in subtypesof(/obj/item/organ/genital))
var/obj/item/organ/genital/G = gpath
@@ -87,11 +76,6 @@
for(var/path in subtypesof(/datum/surgery))
GLOB.surgeries_list += new path()
//Materials
for(var/path in subtypesof(/datum/material))
var/datum/material/D = new path()
GLOB.materials_list[D.id] = D
//Emotes
for(var/path in subtypesof(/datum/emote))
var/datum/emote/E = new path()
@@ -109,6 +93,8 @@
init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes)
INVOKE_ASYNC(GLOBAL_PROC, /proc/init_ref_coin_values) //so the current procedure doesn't sleep because of UNTIL()
//creates every subtype of prototype (excluding prototype) and adds it to list L.
//if no list/L is provided, one is created.
/proc/init_subtypes(prototype, list/L)
@@ -126,3 +112,10 @@
for(var/path in subtypesof(prototype))
L+= path
return L
/proc/init_ref_coin_values()
for(var/path in typesof(/obj/item/coin))
var/obj/item/coin/C = new path
UNTIL(C.flags_1 & INITIALIZED_1) //we want to make sure the value is calculated and not null.
GLOB.coin_values[path] = C.value
qdel(C)
+31 -15
View File
@@ -47,7 +47,7 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list)
return pick(GLOB.socks_list)
/proc/random_features()
/proc/random_features(intendedspecies)
if(!GLOB.tails_list_human.len)
init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human)
if(!GLOB.tails_list_lizard.len)
@@ -105,6 +105,8 @@
var/datum/sprite_accessory/mam_tails/instance = GLOB.mam_tails_list[mtpath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
continue
if(!S.ckeys_allowed)
snowflake_mam_tails_list[S.name] = mtpath
var/list/snowflake_markings_list = list()
@@ -112,6 +114,8 @@
var/datum/sprite_accessory/mam_body_markings/instance = GLOB.mam_body_markings_list[mmpath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
continue
if(!S.ckeys_allowed)
snowflake_markings_list[S.name] = mmpath
var/list/snowflake_ears_list = list()
@@ -119,6 +123,8 @@
var/datum/sprite_accessory/mam_ears/instance = GLOB.mam_ears_list[mepath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
continue
if(!S.ckeys_allowed)
snowflake_ears_list[S.name] = mepath
var/list/snowflake_mam_snouts_list = list()
@@ -126,8 +132,19 @@
var/datum/sprite_accessory/mam_snouts/instance = GLOB.mam_snouts_list[mspath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
continue
if(!S.ckeys_allowed)
snowflake_mam_snouts_list[S.name] = mspath
var/list/snowflake_ipc_antenna_list = list()
for(var/mspath in GLOB.ipc_antennas_list)
var/datum/sprite_accessory/mam_snouts/instance = GLOB.ipc_antennas_list[mspath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
continue
if(!S.ckeys_allowed)
snowflake_ipc_antenna_list[S.name] = mspath
var/color1 = random_short_color()
var/color2 = random_short_color()
var/color3 = random_short_color()
@@ -153,10 +170,10 @@
"insect_fluff" = "None",
"insect_markings" = pick(GLOB.insect_markings_list),
"taur" = "None",
"mam_body_markings" = pick(snowflake_markings_list),
"mam_ears" = pick(snowflake_ears_list),
"mam_snouts" = pick(snowflake_mam_snouts_list),
"mam_tail" = pick(snowflake_mam_tails_list),
"mam_body_markings" = snowflake_markings_list.len ? pick(snowflake_markings_list) : "None",
"mam_ears" = snowflake_ears_list ? pick(snowflake_ears_list) : "None",
"mam_snouts" = snowflake_mam_snouts_list ? pick(snowflake_mam_snouts_list) : "None",
"mam_tail" = snowflake_mam_tails_list ? pick(snowflake_mam_tails_list) : "None",
"mam_tail_animated" = "None",
"xenodorsal" = "Standard",
"xenohead" = "Standard",
@@ -165,7 +182,7 @@
"has_cock" = FALSE,
"cock_shape" = pick(GLOB.cock_shapes_list),
"cock_length" = 6,
"cock_girth_ratio" = COCK_GIRTH_RATIO_DEF,
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
"cock_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
"has_sheath" = FALSE,
"sheath_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
@@ -204,7 +221,7 @@
"womb_cum_rate" = CUM_RATE,
"womb_cum_mult" = CUM_RATE_MULT,
"womb_efficiency" = CUM_EFFICIENCY,
"ipc_screen" = "Sunburst",
"ipc_screen" = snowflake_ipc_antenna_list ? pick(snowflake_ipc_antenna_list) : "None",
"ipc_antenna" = "None",
"flavor_text" = "",
"meat_type" = "Mammalian"
@@ -356,7 +373,7 @@ GLOBAL_LIST_EMPTY(species_list)
checked_health["health"] = health
return ..()
/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null)
/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null, required_mobility_flags = (MOBILITY_USE|MOBILITY_MOVE))
if(!user)
return 0
var/atom/Tloc = null
@@ -384,6 +401,7 @@ GLOBAL_LIST_EMPTY(species_list)
var/endtime = world.time + delay
var/starttime = world.time
. = 1
var/mob/living/L = isliving(user) && user //evals to last thing eval'd
while (world.time < endtime)
stoplag(1)
if (progress)
@@ -393,15 +411,13 @@ GLOBAL_LIST_EMPTY(species_list)
drifting = 0
Uloc = user.loc
if(QDELETED(user) || user.stat || user.IsKnockdown() || user.IsStun() || (!drifting && user.loc != Uloc) || (extra_checks && !extra_checks.Invoke()))
if(L && !CHECK_ALL_MOBILITY(L, required_mobility_flags))
. = 0
break
if(isliving(user))
var/mob/living/L = user
if(L.recoveringstam)
. = 0
break
if(QDELETED(user) || user.stat || (!drifting && user.loc != Uloc) || (extra_checks && !extra_checks.Invoke()))
. = 0
break
if(!QDELETED(Tloc) && (QDELETED(target) || Tloc != target.loc))
if((Uloc != Tloc || Tloc != user) && !drifting)
@@ -529,7 +545,7 @@ GLOBAL_LIST_EMPTY(species_list)
continue
if(M.stat != DEAD && !override)
continue
if(speaker_key && speaker_key in prefs.ignoring)
if(speaker_key && (speaker_key in prefs.ignoring))
continue
switch(message_type)
+4 -3
View File
@@ -146,19 +146,19 @@
var/list/file_data = list()
var/pos = 1
for(var/V in GLOB.news_network.network_channels)
var/datum/newscaster/feed_channel/channel = V
var/datum/news/feed_channel/channel = V
if(!istype(channel))
stack_trace("Non-channel in newscaster channel list")
continue
file_data["[pos]"] = list("channel name" = "[channel.channel_name]", "author" = "[channel.author]", "censored" = channel.censored ? 1 : 0, "author censored" = channel.authorCensor ? 1 : 0, "messages" = list())
for(var/M in channel.messages)
var/datum/newscaster/feed_message/message = M
var/datum/news/feed_message/message = M
if(!istype(message))
stack_trace("Non-message in newscaster channel messages list")
continue
var/list/comment_data = list()
for(var/C in message.comments)
var/datum/newscaster/feed_comment/comment = C
var/datum/news/feed_comment/comment = C
if(!istype(comment))
stack_trace("Non-message in newscaster message comments list")
continue
@@ -354,6 +354,7 @@
roundend_report.set_content(content)
roundend_report.stylesheets = list()
roundend_report.add_stylesheet("roundend", 'html/browser/roundend.css')
roundend_report.add_stylesheet("font-awesome", 'html/font-awesome/css/all.min.css')
roundend_report.open(0)
/datum/controller/subsystem/ticker/proc/personal_report(client/C, popcount)
+37 -1
View File
@@ -44,6 +44,12 @@
index = findtext(t, char, index + length(char))
return t
/proc/sanitize_name(t,list/repl_chars = null)
if(t == "space" || t == "floor" || t == "wall" || t == "r-wall" || t == "monkey" || t == "unknown" || t == "inactive ai") //prevents these common metagamey names
alert("Invalid name.")
return ""
return sanitize(t)
/proc/sanitize_filename(t)
return sanitize_simple(t, list("\n"="", "\t"="", "/"="", "\\"="", "?"="", "%"="", "*"="", ":"="", "|"="", "\""="", "<"="", ">"=""))
@@ -775,4 +781,34 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
#define is_alpha(X) ((text2ascii(X) <= 122) && (text2ascii(X) >= 97))
#define is_digit(X) ((length(X) == 1) && (length(text2num(X)) == 1))
#define is_digit(X) ((length(X) == 1) && (length(text2num(X)) == 1))
/// Slightly expensive proc to scramble a message using equal probabilities of character replacement from a list. DOES NOT SUPPORT HTML!
/proc/scramble_message_replace_chars(original, replaceprob = 25, list/replacementchars = list("$", "@", "!", "#", "%", "^", "&", "*"), replace_letters_only = FALSE, replace_whitespace = FALSE)
var/list/out = list()
var/static/list/whitespace = list(" ", "\n", "\t")
for(var/i in 1 to length(original))
var/char = original[i]
if(!replace_whitespace && (char in whitespace))
out += char
continue
if(replace_letters_only && (!ISINRANGE(char, 65, 90) && !ISINRANGE(char, 97, 122)))
out += char
continue
out += prob(replaceprob)? pick(replacementchars) : char
return out.Join("")
/proc/readable_corrupted_text(text)
var/list/corruption_options = list("..", "£%", "~~\"", "!!", "*", "^", "$!", "-", "}", "?")
var/corrupted_text = ""
for(var/letter_index = 1; letter_index <= length(text); letter_index++) // Have every letter have a chance of creating corruption on either side
var/letter = text[letter_index] // Small chance of letters being removed in place of corruption - still overall readable
if(prob(15))
corrupted_text += pick(corruption_options)
if(prob(95))
corrupted_text += letter
else
corrupted_text += pick(corruption_options)
if(prob(15))
corrupted_text += pick(corruption_options)
return corrupted_text
-111
View File
@@ -1,111 +0,0 @@
/*
// Contains VOREStation based vore description type2type functions
// list2text - takes delimiter and returns text
// text2list - takes delimiter, and creates list
//
*/
// Concatenates a list of strings into a single string. A seperator may optionally be provided.
/proc/list2text(list/ls, sep)
if (ls.len <= 1) // Early-out code for empty or singleton lists.
return ls.len ? ls[1] : ""
var/l = ls.len // Made local for sanic speed.
var/i = 0 // Incremented every time a list index is accessed.
if (sep <> null)
// Macros expand to long argument lists like so: sep, ls[++i], sep, ls[++i], sep, ls[++i], etc...
#define S1 sep, ls[++i]
#define S4 S1, S1, S1, S1
#define S16 S4, S4, S4, S4
#define S64 S16, S16, S16, S16
. = "[ls[++i]]" // Make sure the initial element is converted to text.
// Having the small concatenations come before the large ones boosted speed by an average of at least 5%.
if (l-1 & 0x01) // 'i' will always be 1 here.
. = text("[][][]", ., S1) // Append 1 element if the remaining elements are not a multiple of 2.
if (l-i & 0x02)
. = text("[][][][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4.
if (l-i & 0x04)
. = text("[][][][][][][][][]", ., S4) // And so on....
if (l-i & 0x08)
. = text("[][][][][][][][][][][][][][][][][]", ., S4, S4)
if (l-i & 0x10)
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16)
if (l-i & 0x20)
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16)
if (l-i & 0x40)
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
while (l > i) // Chomp through the rest of the list, 128 elements at a time.
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
#undef S64
#undef S16
#undef S4
#undef S1
else
// Macros expand to long argument lists like so: ls[++i], ls[++i], ls[++i], etc...
#define S1 ls[++i]
#define S4 S1, S1, S1, S1
#define S16 S4, S4, S4, S4
#define S64 S16, S16, S16, S16
. = "[ls[++i]]" // Make sure the initial element is converted to text.
if (l-1 & 0x01) // 'i' will always be 1 here.
. += S1 // Append 1 element if the remaining elements are not a multiple of 2.
if (l-i & 0x02)
. = text("[][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4.
if (l-i & 0x04)
. = text("[][][][][]", ., S4) // And so on...
if (l-i & 0x08)
. = text("[][][][][][][][][]", ., S4, S4)
if (l-i & 0x10)
. = text("[][][][][][][][][][][][][][][][][]", ., S16)
if (l-i & 0x20)
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16)
if (l-i & 0x40)
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
while (l > i) // Chomp through the rest of the list, 128 elements at a time.
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
#undef S64
#undef S16
#undef S4
#undef S1
// Converts a string into a list by splitting the string at each delimiter found. (discarding the seperator)
/proc/text2list(text, delimiter="\n")
var/delim_len = length(delimiter)
if (delim_len < 1)
return list(text)
. = list()
var/last_found = 1
var/found
do
found = findtext(text, delimiter, last_found, 0)
. += copytext(text, last_found, found)
last_found = found + delim_len
while (found)
// Returns true if val is from min to max, inclusive.
/proc/IsInRange(val, min, max)
return (val >= min) && (val <= max)
+28 -3
View File
@@ -1234,8 +1234,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
return FALSE
return TRUE
#define UNTIL(X) while(!(X)) stoplag()
/proc/pass()
return
@@ -1537,4 +1535,31 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
if(190)
return "."
if(189)
return "-"
return "-"
/proc/generate_items_inside(list/items_list, where_to)
for(var/each_item in items_list)
for(var/i in 1 to items_list[each_item])
new each_item(where_to)
//sends a message to chat
//config_setting should be one of the following
//null - noop
//empty string - use TgsTargetBroadcast with admin_only = FALSE
//other string - use TgsChatBroadcast with the tag that matches config_setting, only works with TGS4, if using TGS3 the above method is used
/proc/send2chat(message, config_setting)
if(config_setting == null || !world.TgsAvailable())
return
var/datum/tgs_version/version = world.TgsVersion()
if(config_setting == "" || version.suite == 3)
world.TgsTargetedChatBroadcast(message, FALSE)
return
var/list/channels_to_use = list()
for(var/I in world.TgsChatChannelInfo())
var/datum/tgs_chat_channel/channel = I
if(channel.tag == config_setting)
channels_to_use += channel
if(channels_to_use.len)
world.TgsChatBroadcast()
-39
View File
@@ -1,39 +0,0 @@
/datum/projectile_data
var/src_x
var/src_y
var/time
var/distance
var/power_x
var/power_y
var/dest_x
var/dest_y
/datum/projectile_data/New(var/src_x, var/src_y, var/time, var/distance, \
var/power_x, var/power_y, var/dest_x, var/dest_y)
src.src_x = src_x
src.src_y = src_y
src.time = time
src.distance = distance
src.power_x = power_x
src.power_y = power_y
src.dest_x = dest_x
src.dest_y = dest_y
/proc/projectile_trajectory(src_x, src_y, rotation, angle, power)
// returns the destination (Vx,y) that a projectile shot at [src_x], [src_y], with an angle of [angle],
// rotated at [rotation] and with the power of [power]
// Thanks to VistaPOWA for this function
var/power_x = power * cos(angle)
var/power_y = power * sin(angle)
var/time = 2* power_y / 10 //10 = g
var/distance = time * power_x
var/dest_x = src_x + distance*sin(rotation);
var/dest_y = src_y + distance*cos(rotation);
return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
+57
View File
@@ -0,0 +1,57 @@
// Basic geometry things.
/datum/vector/
var/x = 0
var/y = 0
/datum/vector/New(var/x, var/y)
src.x = x
src.y = y
/datum/vector/proc/duplicate()
return new /datum/vector(x, y)
/datum/vector/proc/euclidian_norm()
return sqrt(x*x + y*y)
/datum/vector/proc/squared_norm()
return x*x + y*y
/datum/vector/proc/normalize()
var/norm = euclidian_norm()
x = x/norm
y = y/norm
return src
/datum/vector/proc/chebyshev_norm()
return max(abs(x), abs(y))
/datum/vector/proc/chebyshev_normalize()
var/norm = chebyshev_norm()
x = x/norm
y = y/norm
return src
/datum/vector/proc/is_integer()
return ISINTEGER(x) && ISINTEGER(y)
/atom/movable/proc/vector_translate(var/datum/vector/V, var/delay)
var/turf/T = get_turf(src)
var/turf/destination = locate(T.x + V.x, T.y + V.y, z)
var/datum/vector/V_norm = V.duplicate()
V_norm.chebyshev_normalize()
if (!V_norm.is_integer())
return
var/turf/destination_temp
while (destination_temp != destination)
destination_temp = locate(T.x + V_norm.x, T.y + V_norm.y, z)
forceMove(destination_temp)
T = get_turf(src)
sleep(delay + world.tick_lag) // Shortest possible time to sleep
/atom/proc/get_translated_turf(var/datum/vector/V)
var/turf/T = get_turf(src)
return locate(T.x + V.x, T.y + V.y, z)
/proc/atoms2vector(var/atom/A, var/atom/B)
return new /datum/vector((B.x - A.x), (B.y - A.y)) // Vector from A -> B
+26 -2
View File
@@ -214,5 +214,29 @@ GLOBAL_LIST_INIT(bitfields, list(
"CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH,
"MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN,
"CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH
)
))
),
"mob_biotypes" = list (
"MOB_ORGANIC" = MOB_ORGANIC,
"MOB_MINERAL" = MOB_MINERAL,
"MOB_ROBOTIC" = MOB_ROBOTIC,
"MOB_UNDEAD" = MOB_UNDEAD,
"MOB_HUMANOID" = MOB_HUMANOID,
"MOB_BUG" = MOB_BUG,
"MOB_BEAST" = MOB_BEAST,
"MOB_EPIC" = MOB_EPIC,
"MOB_REPTILE" = MOB_REPTILE,
"MOB_SPIRIT" = MOB_SPIRIT
),
"mobility_flags" = list(
"MOBILITY_MOVE" = MOBILITY_MOVE,
"MOBILITY_STAND" = MOBILITY_STAND,
"MOBILITY_PICKUP" = MOBILITY_PICKUP,
"MOBILITY_USE" = MOBILITY_USE,
"MOBILITY_UI" = MOBILITY_UI,
"MOBILITY_STORAGE" = MOBILITY_STORAGE,
"MOBILITY_PULL" = MOBILITY_PULL,
"MOBILITY_HOLD" = MOBILITY_HOLD,
"MOBILITY_RESIST" = MOBILITY_RESIST
)
))
+5 -2
View File
@@ -21,8 +21,11 @@ GLOBAL_LIST(op_se_blocks)
GLOBAL_VAR(NULLED_SE)
GLOBAL_VAR(NULLED_UI)
GLOBAL_LIST_EMPTY(global_mutations) // list of hidden mutation things
GLOBAL_LIST_EMPTY(all_mutations)
GLOBAL_LIST_EMPTY(full_sequences)
GLOBAL_LIST_EMPTY(bad_mutations)
GLOBAL_LIST_EMPTY(good_mutations)
GLOBAL_LIST_EMPTY(not_good_mutations)
GLOBAL_LIST_EMPTY(not_good_mutations)
GLOBAL_LIST_EMPTY(mutation_recipes)
+58
View File
@@ -1 +1,59 @@
GLOBAL_LIST_EMPTY(donators_by_group) //group id = donator list of ckeys
GLOBAL_LIST_INIT(flirts, list("Roses are red / Violets are good / One day while Andy...",
"My love for you is like the singularity. It cannot be contained.",
"Will you be my lusty xenomorph maid?",
"We go together like the clown and the external airlock.",
"Roses are red / Liches are wizards / I love you more than a whole squad of lizards.",
"Be my valentine. Law 2.",
"You must be a mime, because you leave me speechless.",
"I love you like Ian loves the HoP.",
"You're hotter than a plasma fire in toxins.",
"Are you a rogue atmos tech? Because you're taking my breath away.",
"Could I have all access... to your heart?",
"Call me the doctor, because I'm here to inspect your johnson.",
"I'm not a changeling, but you make my proboscis extend.",
"I just can't get EI NATH of you.",
"You must be a nuke op, because you make my heart explode.",
"Roses are red / Botany is a farm / Not being my Valentine / causes human harm.",
"I want you more than an assistant wants insulated gloves.",
"If I was a security officer, I'd brig you all shift.",
"Are you the janitor? Because I think I've fallen for you.",
"You're always valid to my heart.",
"I'd risk the wrath of the gods to bwoink you.",
"You look as beautiful now as the last time you were cloned.",
"Someone check the gravitational generator, because I'm only attracted to you.",
"If I were the warden I'd always let you into my armory.",
"The virologist is rogue, and the only cure is a kiss from you.",
"Would you spend some time in my upgraded sleeper?",
"You must be a silicon, because you've unbolted my heart.",
"Are you Nar'Sie? Because there's nar-one else I sie.",
"If you were a taser, you'd be set to stunning.",
"Do you have stamina damage from running through my dreams?",
"If I were an alien, would you let me hug you?",
"My love for you is stronger than a reinforced wall.",
"This must be the captain's office, because I see a fox.",
"I'm not a highlander, but there can only be one for me.",
"The floor is made of lava! Quick, get on my bed.",
"If you were an abandoned station you'd be the DEARelict.",
"If you had a pickaxe you'd be a shaft FINEr.",
"Roses are red, tide is gray, if I were an assistant I'd steal you away.",
"Roses are red, text is green, I love you more than cleanbots clean.",
"If you were a carp I'd fi-lay you.",
"I'm a nuke op, and my pinpointer leads to your heart.",
"Wanna slay my megafauna?",
"I'm a clockwork cultist. Or zl inyragvar.",
"If you were a disposal bin I'd ride you all day.",
"Put on your explorer's suit because I'm taking you to LOVEaland.",
"I must be the CMO, 'cause I saw you on my CUTE sensors.",
"You're the vomit to my flyperson.",
"You must be liquid dark matter, because you're pulling me closer.",
"Not even sorium can drive me away from you.",
"Wanna make like a borg and do some heavy petting?",
"Are you powering the station? Because you super matter to me.",
"I wish science could make me a bag of holding you.",
"Let's call the emergency CUDDLE.",
"I must be tripping on BZ, because I saw an angel walk by.",
"Wanna empty out my tool storage?",
"Did you visit the medbay after you fell from heaven?",
"Are you wearing space pants? Wanna not be?" ))
-1
View File
@@ -29,7 +29,6 @@ GLOBAL_LIST_EMPTY(available_ai_shells)
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list(),list())) // One for each AI_* status define
GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
GLOBAL_LIST_EMPTY(bots_list)
GLOBAL_LIST_EMPTY(living_cameras)
GLOBAL_LIST_EMPTY(aiEyes)
GLOBAL_LIST_EMPTY(language_datum_instances)
+1
View File
@@ -4,6 +4,7 @@ GLOBAL_LIST_INIT(wizard_second, world.file2list("strings/names/wizardsecond.txt"
GLOBAL_LIST_INIT(ninja_titles, world.file2list("strings/names/ninjatitle.txt"))
GLOBAL_LIST_INIT(ninja_names, world.file2list("strings/names/ninjaname.txt"))
GLOBAL_LIST_INIT(commando_names, world.file2list("strings/names/death_commando.txt"))
GLOBAL_LIST_INIT(first_names, world.file2list("strings/names/first.txt"))
GLOBAL_LIST_INIT(first_names_male, world.file2list("strings/names/first_male.txt"))
GLOBAL_LIST_INIT(first_names_female, world.file2list("strings/names/first_female.txt"))
GLOBAL_LIST_INIT(last_names, world.file2list("strings/names/last.txt"))
+1 -1
View File
@@ -16,7 +16,6 @@ GLOBAL_LIST_EMPTY(singularities) //list of all singularities on the stati
GLOBAL_LIST(chemical_reactions_list) //list of all /datum/chemical_reaction datums. Used during chemical reactions
GLOBAL_LIST(chemical_reagents_list) //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff
GLOBAL_LIST_EMPTY(materials_list) //list of all /datum/material datums indexed by material id.
GLOBAL_LIST_EMPTY(tech_list) //list of all /datum/tech datums indexed by id.
GLOBAL_LIST_EMPTY(surgeries_list) //list of all surgeries by name, associated with their path.
GLOBAL_LIST_EMPTY(uplink_items) //list of all uplink item typepaths, ascendingly sorted by their initial name.
@@ -33,6 +32,7 @@ GLOBAL_LIST_EMPTY(meteor_list) // List of all meteors.
GLOBAL_LIST_EMPTY(active_jammers) // List of active radio jammers
GLOBAL_LIST_EMPTY(ladders)
GLOBAL_LIST_EMPTY(trophy_cases)
GLOBAL_LIST_EMPTY(coin_values)
GLOBAL_LIST_EMPTY(wire_color_directory)
GLOBAL_LIST_EMPTY(wire_name_directory)
+3 -1
View File
@@ -18,6 +18,7 @@
#define POLL_IGNORE_DEMON "demon"
#define POLL_IGNORE_WIZARD "wizard"
#define POLL_IGNORE_CLONE "clone"
#define POLL_IGNORE_CONTRACTOR_SUPPORT "contractor_support"
GLOBAL_LIST_INIT(poll_ignore_desc, list(
POLL_IGNORE_SENTIENCE_POTION = "Sentience potion",
@@ -37,7 +38,8 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list(
POLL_IGNORE_SPLITPERSONALITY = "Split Personality",
POLL_IGNORE_DEMON = "Demons",
POLL_IGNORE_WIZARD = "Wizards",
POLL_IGNORE_CLONE = "Defective/SDGF clones"
POLL_IGNORE_CLONE = "Defective/SDGF clones",
POLL_IGNORE_CONTRACTOR_SUPPORT = "Contractor Support Unit"
))
GLOBAL_LIST_INIT(poll_ignore, init_poll_ignore())
+2 -2
View File
@@ -14,7 +14,7 @@
if(check_click_intercept(params,A))
return
if(stat || lockcharge || IsKnockdown() || IsStun() || IsUnconscious())
if(stat || locked_down || IsParalyzed() || IsStun() || IsUnconscious())
return
var/list/modifiers = params2list(params)
@@ -66,7 +66,7 @@
if(C.user_unbuckle_mob(C.buckled_mobs[1],src))
return
if(!W && get_dist(src,A) <= interaction_range)
if(!W && (get_dist(src,A) <= interaction_range))
A.attack_robot(src)
return
+2 -2
View File
@@ -42,7 +42,7 @@
selected_target[1] = object
selected_target[2] = params
while(selected_target[1])
Click(selected_target[1], location, control, selected_target[2])
Click(selected_target[1], location, control, selected_target[2], TRUE)
sleep(delay)
active_mousedown_item = mob.canMobMousedown(object, location, params)
if(active_mousedown_item)
@@ -145,4 +145,4 @@
if (middragatom == src_object)
middragtime = 0
middragatom = null
..()
..()
+22 -3
View File
@@ -72,6 +72,22 @@
var/hide_icon = 'icons/mob/actions.dmi'
var/hide_state = "hide"
var/show_state = "show"
var/mutable_appearance/hide_appearance
var/mutable_appearance/show_appearance
/obj/screen/movable/action_button/hide_toggle/Initialize()
. = ..()
var/static/list/icon_cache = list()
var/cache_key = "[hide_icon][hide_state]"
hide_appearance = icon_cache[cache_key]
if(!hide_appearance)
hide_appearance = icon_cache[cache_key] = mutable_appearance(hide_icon, hide_state)
cache_key = "[hide_icon][show_state]"
show_appearance = icon_cache[cache_key]
if(!show_appearance)
show_appearance = icon_cache[cache_key] = mutable_appearance(hide_icon, show_state)
/obj/screen/movable/action_button/hide_toggle/Click(location,control,params)
if (!can_use(usr))
@@ -137,9 +153,12 @@
show_state = settings["toggle_show"]
update_icon()
/obj/screen/movable/action_button/hide_toggle/update_icon()
cut_overlays()
add_overlay(mutable_appearance(hide_icon, hidden ? show_state : hide_state))
/obj/screen/movable/action_button/hide_toggle/update_overlays()
. = ..()
if(hidden)
. += show_appearance
else
. += hide_appearance
/obj/screen/movable/action_button/MouseEntered(location,control,params)
+2 -2
View File
@@ -273,7 +273,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
if(!istype(L) || !L.can_resist())
return
L.changeNext_move(CLICK_CD_RESIST)
if(L.canmove)
if(CHECK_MOBILITY(L, MOBILITY_MOVE))
return L.resist_fire() //I just want to start a flame in your hearrrrrrtttttt.
@@ -601,7 +601,7 @@ so as to remain in compliance with the most up-to-date laws."
if(!istype(L) || !L.can_resist())
return
L.changeNext_move(CLICK_CD_RESIST)
if((L.canmove) && (L.last_special <= world.time))
if(CHECK_MOBILITY(L, MOBILITY_MOVE) && (L.last_special <= world.time))
return L.resist_restraints()
/obj/screen/alert/restrained/buckled/Click()
+11 -11
View File
@@ -48,7 +48,7 @@
if(isovermind(usr))
var/mob/camera/blob/B = usr
if(!B.placed)
B.place_blob_core(B.base_point_rate, 0)
B.place_blob_core(0)
B.transport_core()
/obj/screen/blob/Blobbernaut
@@ -91,26 +91,26 @@
var/mob/camera/blob/B = usr
B.create_factory()
/obj/screen/blob/ReadaptChemical
/obj/screen/blob/ReadaptStrain
icon_state = "ui_chemswap"
name = "Readapt Chemical (40)"
desc = "Randomly rerolls your chemical for 40 resources."
name = "Readapt Strain (40)"
desc = "Allows you to choose a new strain from 4 random choices for 40 resources."
/obj/screen/blob/ReadaptChemical/MouseEntered(location,control,params)
/obj/screen/blob/ReadaptStrain/MouseEntered(location,control,params)
if(hud && hud.mymob && isovermind(hud.mymob))
var/mob/camera/blob/B = hud.mymob
if(B.free_chem_rerolls)
name = "Readapt Chemical (FREE)"
desc = "Randomly rerolls your chemical for free."
if(B.free_strain_rerolls)
name = "Readapt Strain (FREE)"
desc = "Randomly rerolls your strain for free."
else
name = initial(name)
desc = initial(desc)
..()
/obj/screen/blob/ReadaptChemical/Click()
/obj/screen/blob/ReadaptStrain/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.chemical_reroll()
B.strain_reroll()
/obj/screen/blob/RelocateCore
icon_state = "ui_swap"
@@ -175,7 +175,7 @@
using.hud = src
static_inventory += using
using = new /obj/screen/blob/ReadaptChemical()
using = new /obj/screen/blob/ReadaptStrain()
using.screen_loc = ui_storage1
using.hud = src
static_inventory += using
+4 -6
View File
@@ -166,29 +166,27 @@
var/static/mutable_appearance/blocked_overlay = mutable_appearance('icons/mob/screen_gen.dmi', "blocked")
var/held_index = 0
/obj/screen/inventory/hand/update_icon()
/obj/screen/inventory/hand/update_overlays()
. = ..()
if(!handcuff_overlay)
var/state = (!(held_index % 2)) ? "markus" : "gabrielle"
handcuff_overlay = mutable_appearance('icons/mob/screen_gen.dmi', state)
cut_overlay(list(handcuff_overlay, blocked_overlay, "hand_active"))
if(!hud?.mymob)
return
if(iscarbon(hud.mymob))
var/mob/living/carbon/C = hud.mymob
if(C.handcuffed)
add_overlay(handcuff_overlay)
. += handcuff_overlay
if(held_index)
if(!C.has_hand_for_held_index(held_index))
add_overlay(blocked_overlay)
. += blocked_overlay
if(held_index == hud.mymob.active_hand_index)
add_overlay("hand_active")
. += "hand_active"
/obj/screen/inventory/hand/Click(location, control, params)
+28 -19
View File
@@ -1,19 +1,28 @@
/**
*This is the proc that handles the order of an item_attack.
*The order of procs called is:
*tool_act on the target. If it returns TRUE, the chain will be stopped.
*pre_attack() on src. If this returns TRUE, the chain will be stopped.
*attackby on the target. If it returns TRUE, the chain will be stopped.
*and lastly
*afterattack. The return value does not matter.
*/
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
if(!tool_attack_chain(user, target) && pre_attack(target, user, params))
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
var/resolved = target.attackby(src, user, params)
if(!resolved && target && !QDELETED(src))
afterattack(target, user, 1, params) // 1: clicking something Adjacent
//Checks if the item can work as a tool, calling the appropriate tool behavior on the target
/obj/item/proc/tool_attack_chain(mob/user, atom/target)
if(!tool_behaviour)
return FALSE
return target.tool_act(user, src, tool_behaviour)
if(item_flags & NO_ATTACK_CHAIN_SOFT_STAMCRIT)
if(isliving(user))
var/mob/living/L = user
if(L.getStaminaLoss() >= STAMINA_SOFTCRIT)
to_chat(L, "<span class='warning'>You are too exhausted to swing [src]!</span>")
return
if(tool_behaviour && target.tool_act(user, src, tool_behaviour))
return
if(pre_attack(target, user, params))
return
if(target.attackby(src,user, params))
return
if(QDELETED(src) || QDELETED(target))
return
afterattack(target, user, TRUE, params)
// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown.
/obj/item/proc/attack_self(mob/user)
@@ -23,8 +32,8 @@
/obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby!
if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK)
return FALSE
return TRUE //return FALSE to avoid calling attackby after this proc does stuff
return TRUE
return FALSE //return TRUE to avoid calling attackby after this proc does stuff
// No comment
/atom/proc/attackby(obj/item/W, mob/user, params)
@@ -104,7 +113,7 @@
var/mob/living/carbon/tempcarb = user
if(!tempcarb.combatmode)
totitemdamage *= 0.5
if(user.resting)
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
totitemdamage *= 0.5
//CIT CHANGES END HERE
if(user != src && check_shields(I, totitemdamage, "the [I.name]", MELEE_ATTACK, I.armour_penetration))
@@ -112,7 +121,7 @@
send_item_attack_message(I, user)
if(I.force)
apply_damage(totitemdamage, I.damtype) //CIT CHANGE - replaces I.force with totitemdamage
if(I.damtype == BRUTE && !HAS_TRAIT(src, TRAIT_NOMARROW))
if(I.damtype == BRUTE && !HAS_TRAIT(src, TRAIT_NOMARROW))
if(prob(33))
I.add_mob_blood(src)
var/turf/location = get_turf(src)
+12 -12
View File
@@ -76,8 +76,8 @@
layer = ABOVE_HUD_LAYER
plane = ABOVE_HUD_PLANE
var/atom/movable/focus = null
var/mob/living/carbon/tk_user = null
var/atom/movable/focus
var/mob/living/carbon/tk_user
/obj/item/tk_grab/Initialize()
. = ..()
@@ -85,6 +85,8 @@
/obj/item/tk_grab/Destroy()
STOP_PROCESSING(SSfastprocess, src)
focus = null
tk_user = null
return ..()
/obj/item/tk_grab/process()
@@ -179,16 +181,14 @@
return
new /obj/effect/temp_visual/telekinesis(get_turf(focus))
/obj/item/tk_grab/update_icon()
cut_overlays()
if(focus)
var/old_layer = focus.layer
var/old_plane = focus.plane
focus.layer = layer+0.01
focus.plane = ABOVE_HUD_PLANE
add_overlay(focus) //this is kind of ick, but it's better than using icon()
focus.layer = old_layer
focus.plane = old_plane
/obj/item/tk_grab/update_overlays()
. = ..()
if(!focus)
return
var/mutable_appearance/focus_overlay = new(focus)
focus_overlay.layer = layer + 0.01
focus_overlay.plane = ABOVE_HUD_PLANE
. += focus_overlay
/obj/item/tk_grab/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is using [user.p_their()] telekinesis to choke [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -371,19 +371,18 @@
for(var/T in storyteller_cache)
var/datum/dynamic_storyteller/S = T
var/config_tag = initial(S.config_tag)
var/final_weight = initial(S.weight)
if(probabilities[config_tag]<=0)
var/probability = (config_tag in probabilities) ? probabilities[config_tag] : initial(S.weight)
if(probability <= 0)
continue
final_weight = probabilities[config_tag]
if(SSpersistence.saved_storytellers.len == 3 && repeated_mode_adjust.len == 3)
if(SSpersistence.saved_storytellers.len == repeated_mode_adjust.len)
var/name = initial(S.name)
var/recent_round = min(SSpersistence.saved_storytellers.Find(name),3)
var/adjustment = 0
while(recent_round)
adjustment += repeated_mode_adjust[recent_round]
recent_round = SSpersistence.saved_modes.Find(name,recent_round+1,0)
final_weight *= ((100-adjustment)/100)
runnable_storytellers[S] = final_weight
probability *= ((100-adjustment)/100)
runnable_storytellers[S] = probability
return runnable_storytellers
@@ -234,6 +234,7 @@
/datum/config_entry/number/movedelay //Used for modifying movement speed for mobs.
abstract_type = /datum/config_entry/number/movedelay
integer = FALSE
/datum/config_entry/number/movedelay/ValidateAndSet()
. = ..()
@@ -253,13 +254,13 @@
config_entry_value = 1
/datum/config_entry/number/movedelay/sprint_buffer_max
config_entry_value = 42
config_entry_value = 24
/datum/config_entry/number/movedelay/sprint_stamina_cost
config_entry_value = 0.7
config_entry_value = 1.4
/datum/config_entry/number/movedelay/sprint_buffer_regen_per_ds
config_entry_value = 0.3
config_entry_value = 0.4
/////////////////////////////////////////////////Outdated move delay
/datum/config_entry/number/outdated_movedelay
@@ -334,6 +335,10 @@
config_entry_value = 16
min_val = 0
/datum/config_entry/number/station_space_budget
config_entry_value = 10
min_val = 0
/datum/config_entry/flag/allow_random_events // Enables random events mid-round when set
/datum/config_entry/number/events_min_time_mul // Multipliers for random events minimal starting time and minimal players amounts
@@ -403,10 +408,6 @@
lowercase = FALSE
splitter = ","
/datum/config_entry/number/auto_transfer_delay
config_entry_value = 72000
min_val = 0
/datum/config_entry/flag/pai_custom_holoforms
/datum/config_entry/number/marauder_delay_non_reebe
@@ -1,3 +1,5 @@
/datum/config_entry/flag/auto_profile // Automatically start profiler on server start
/datum/config_entry/flag/autoadmin // if autoadmin is enabled
protection = CONFIG_ENTRY_LOCKED
@@ -80,6 +82,18 @@
config_entry_value = 600
min_val = 0
/datum/config_entry/number/vote_autotransfer_initial //length of time before the first autotransfer vote is called (deciseconds, default 2 hours)
config_entry_value = 72000
min_val = 0
/datum/config_entry/number/vote_autotransfer_interval //length of time to wait before subsequent autotransfer votes (deciseconds, default 30 minutes)
config_entry_value = 18000
min_val = 0
/datum/config_entry/number/vote_autotransfer_maximum // maximum extensions until the round autoends
config_entry_value = 4
min_val = 0
/datum/config_entry/flag/default_no_vote // vote does not default to nochange/norestart
/datum/config_entry/flag/no_dead_vote // dead people can't vote
@@ -267,6 +281,9 @@
/datum/config_entry/flag/tgstyle_maprotation
/datum/config_entry/string/map_vote_type
config_entry_value = "SCORE"
/datum/config_entry/number/maprotatechancedelta
config_entry_value = 0.75
min_val = 0
@@ -389,6 +406,13 @@
config_entry_value = 50
/datum/config_entry/flag/irc_announce_new_game
deprecated_by = /datum/config_entry/string/chat_announce_new_game
/datum/config_entry/flag/irc_announce_new_game/DeprecationUpdate(value)
return "" //default broadcast
/datum/config_entry/string/chat_announce_new_game
config_entry_value = null
/datum/config_entry/flag/debug_admin_hrefs
@@ -435,3 +459,6 @@
/datum/config_entry/number/max_bunker_days
config_entry_value = 7
min_val = 1
/datum/config_entry/flag/minimaps_enabled
config_entry_value = TRUE
@@ -0,0 +1,6 @@
/datum/config_entry/number/snowflake_plushie_prob
config_entry_value = 50
/datum/config_entry/keyed_list/snowflake_plushies
key_mode = KEY_MODE_TEXT
value_mode = VALUE_MODE_TEXT
+1 -1
View File
@@ -63,7 +63,7 @@
//Sleeping in here prevents future fires until returned.
/datum/controller/subsystem/proc/fire(resumed = 0)
flags |= SS_NO_FIRE
throw EXCEPTION("Subsystem [src]([type]) does not fire() but did not set the SS_NO_FIRE flag. Please add the SS_NO_FIRE flag to any subsystem that doesn't fire so it doesn't get added to the processing list and waste cpu.")
CRASH("Subsystem [src]([type]) does not fire() but did not set the SS_NO_FIRE flag. Please add the SS_NO_FIRE flag to any subsystem that doesn't fire so it doesn't get added to the processing list and waste cpu.")
/datum/controller/subsystem/Destroy()
dequeue()
+13 -10
View File
@@ -16,7 +16,7 @@ SUBSYSTEM_DEF(atoms)
/datum/controller/subsystem/atoms/Initialize(timeofday)
GLOB.fire_overlay.appearance_flags = RESET_COLOR
setupGenetics() //to set the mutations' place in structural enzymes, so monkey.initialize() knows where to put the monkey mutation.
setupGenetics() //to set the mutations' sequence.
initialized = INITIALIZATION_INNEW_MAPLOAD
InitializeAtoms()
return ..()
@@ -108,16 +108,19 @@ SUBSYSTEM_DEF(atoms)
BadInitializeCalls = SSatoms.BadInitializeCalls
/datum/controller/subsystem/atoms/proc/setupGenetics()
var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS)
for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
avnums[i] = i
CHECK_TICK
for(var/A in subtypesof(/datum/mutation/human))
var/datum/mutation/human/B = new A()
if(B.dna_block == NON_SCANNABLE)
var/list/mutations = subtypesof(/datum/mutation/human)
shuffle_inplace(mutations)
for(var/A in subtypesof(/datum/generecipe))
var/datum/generecipe/GR = A
GLOB.mutation_recipes[initial(GR.required)] = initial(GR.result)
for(var/i in 1 to LAZYLEN(mutations))
var/path = mutations[i] //byond gets pissy when we do it in one line
var/datum/mutation/human/B = new path ()
B.alias = "Mutation #[i]"
GLOB.all_mutations[B.type] = B
GLOB.full_sequences[B.type] = generate_gene_sequence(B.blocks)
if(B.locked)
continue
B.dna_block = pick_n_take(avnums)
if(B.quality == POSITIVE)
GLOB.good_mutations |= B
else if(B.quality == NEGATIVE)
@@ -0,0 +1,27 @@
SUBSYSTEM_DEF(autotransfer)
name = "Autotransfer Vote"
flags = SS_KEEP_TIMING | SS_BACKGROUND
wait = 1 MINUTES
var/starttime
var/targettime
var/voteinterval
var/maxvotes
var/curvotes
/datum/controller/subsystem/autotransfer/Initialize(timeofday)
starttime = world.time
targettime = starttime + CONFIG_GET(number/vote_autotransfer_initial)
voteinterval = CONFIG_GET(number/vote_autotransfer_interval)
maxvotes = CONFIG_GET(number/vote_autotransfer_maximum)
curvotes = 0
return ..()
/datum/controller/subsystem/autotransfer/fire()
if(maxvotes > curvotes)
if(world.time > targettime)
SSvote.initiate_vote("transfer","server")
targettime = targettime + voteinterval
curvotes += 1
else
SSshuttle.autoEnd()
+24 -6
View File
@@ -6,7 +6,7 @@ SUBSYSTEM_DEF(garbage)
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
init_order = INIT_ORDER_GARBAGE
var/list/collection_timeout = list(0, 2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
var/list/collection_timeout = list(15 SECONDS, 30 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
//Stat tracking
var/delslasttick = 0 // number of del()'s we've done this tick
@@ -27,6 +27,7 @@ SUBSYSTEM_DEF(garbage)
#ifdef TESTING
var/list/reference_find_on_fail = list()
var/list/reference_find_on_fail_types = list()
#endif
@@ -98,9 +99,6 @@ SUBSYSTEM_DEF(garbage)
state = SS_RUNNING
break
/datum/controller/subsystem/garbage/proc/HandleQueue(level = GC_QUEUE_CHECK)
if (level == GC_QUEUE_CHECK)
delslasttick = 0
@@ -183,6 +181,11 @@ SUBSYSTEM_DEF(garbage)
var/gctime = world.time
var/refid = "\ref[D]"
#ifdef TESTING
if(reference_find_on_fail_types[D.type])
reference_find_on_fail["\ref[D]"] = TRUE
#endif
D.gc_destroyed = gctime
var/list/queue = queues[level]
if (queue[refid])
@@ -190,6 +193,21 @@ SUBSYSTEM_DEF(garbage)
queue[refid] = gctime
#ifdef TESTING
/datum/controller/subsystem/garbage/proc/add_type_to_findref(type)
if(!ispath(type))
return "NOT A VAILD PATH"
reference_find_on_fail_types |= typecacheof(type)
/datum/controller/subsystem/garbage/proc/remove_type_from_findref(type)
if(!ispath(type))
return "NOT A VALID PATH"
reference_find_on_fail_types -= typesof(type)
/datum/controller/subsystem/garbage/proc/clear_findref_types()
reference_find_on_fail_types = list()
#endif
//this is mainly to separate things profile wise.
/datum/controller/subsystem/garbage/proc/HardDelete(datum/D)
var/time = world.timeofday
@@ -244,7 +262,7 @@ SUBSYSTEM_DEF(garbage)
#ifdef TESTING
/proc/qdel_and_find_ref_if_fail(datum/D, force = FALSE)
SSgarbage.reference_find_on_fail[REF(D)] = TRUE
SSgarbage.reference_find_on_fail["\ref[D]"] = TRUE
qdel(D, force)
#endif
@@ -309,7 +327,7 @@ SUBSYSTEM_DEF(garbage)
if (QDEL_HINT_IFFAIL_FINDREFERENCE)
SSgarbage.Queue(D)
#ifdef TESTING
SSgarbage.reference_find_on_fail[REF(D)] = TRUE
SSgarbage.reference_find_on_fail["\ref[D]"] = TRUE
#endif
else
#ifdef TESTING
+3 -3
View File
@@ -118,7 +118,7 @@ SUBSYSTEM_DEF(job)
if(flag && (!(flag in player.client.prefs.be_special)))
JobDebug("FOC flag failed, Player: [player], Flag: [flag], ")
continue
if(player.mind && job.title in player.mind.restricted_roles)
if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("FOC incompatible with antagonist role, Player: [player]")
continue
if(player.client.prefs.job_preferences[job.title] == level)
@@ -158,7 +158,7 @@ SUBSYSTEM_DEF(job)
JobDebug("GRJ player not enough xp, Player: [player]")
continue
if(player.mind && job.title in player.mind.restricted_roles)
if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]")
continue
@@ -340,7 +340,7 @@ SUBSYSTEM_DEF(job)
JobDebug("DO non-human failed, Player: [player], Job:[job.title]")
continue
if(player.mind && job.title in player.mind.restricted_roles)
if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("DO incompatible with antagonist role, Player: [player], Job:[job.title]")
continue
+3 -3
View File
@@ -83,15 +83,15 @@ SUBSYSTEM_DEF(jukeboxes)
return
for(var/list/jukeinfo in activejukeboxes)
if(!jukeinfo.len)
EXCEPTION("Active jukebox without any associated metadata.")
stack_trace("Active jukebox without any associated metadata.")
continue
var/datum/track/juketrack = jukeinfo[1]
if(!istype(juketrack))
EXCEPTION("Invalid jukebox track datum.")
stack_trace("Invalid jukebox track datum.")
continue
var/obj/jukebox = jukeinfo[3]
if(!istype(jukebox))
EXCEPTION("Nonexistant or invalid object associated with jukebox.")
stack_trace("Nonexistant or invalid object associated with jukebox.")
continue
var/sound/song_played = sound(juketrack.song_path)
var/area/currentarea = get_area(jukebox)
+10
View File
@@ -14,6 +14,7 @@ SUBSYSTEM_DEF(mapping)
var/list/ruins_templates = list()
var/list/space_ruins_templates = list()
var/list/lava_ruins_templates = list()
var/list/station_ruins_templates = list()
var/datum/space_level/isolated_ruins_z //Created on demand during ruin loading.
var/list/shuttle_templates = list()
@@ -94,6 +95,11 @@ SUBSYSTEM_DEF(mapping)
var/list/space_ruins = levels_by_trait(ZTRAIT_SPACE_RUINS)
if (space_ruins.len)
seedRuins(space_ruins, CONFIG_GET(number/space_budget), /area/space, space_ruins_templates)
// Generate station space ruins
var/list/station_ruins = levels_by_trait(ZTRAIT_STATION)
if (station_ruins.len)
seedRuins(station_ruins, CONFIG_GET(number/station_space_budget), /area/space/station_ruins, station_ruins_templates)
SSmapping.seedStation()
loading_ruins = FALSE
#endif
@@ -161,6 +167,7 @@ SUBSYSTEM_DEF(mapping)
ruins_templates = SSmapping.ruins_templates
space_ruins_templates = SSmapping.space_ruins_templates
lava_ruins_templates = SSmapping.lava_ruins_templates
station_ruins_templates = SSmapping.station_ruins_templates
shuttle_templates = SSmapping.shuttle_templates
shelter_templates = SSmapping.shelter_templates
unused_turfs = SSmapping.unused_turfs
@@ -352,6 +359,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
// Still supporting bans by filename
var/list/banned = generateMapList("[global.config.directory]/lavaruinblacklist.txt")
banned += generateMapList("[global.config.directory]/spaceruinblacklist.txt")
banned += generateMapList("[global.config.directory]/stationruinblacklist.txt")
for(var/item in sortList(subtypesof(/datum/map_template/ruin), /proc/cmp_ruincost_priority))
var/datum/map_template/ruin/ruin_type = item
@@ -372,6 +380,8 @@ GLOBAL_LIST_EMPTY(the_station_areas)
space_ruins_templates[R.name] = R
else if(istype(R, /datum/map_template/ruin/station))
station_room_templates[R.name] = R
else if(istype(R, /datum/map_template/ruin/spacenearstation))
station_ruins_templates[R.name] = R
/datum/controller/subsystem/mapping/proc/preloadShuttleTemplates()
var/list/unbuyable = generateMapList("[global.config.directory]/unbuyableshuttles.txt")
+29
View File
@@ -0,0 +1,29 @@
/*! How material datums work
Materials are now instanced datums, with an associative list of them being kept in SSmaterials. We only instance the materials once and then re-use these instances for everything.
These materials call on_applied() on whatever item they are applied to, common effects are adding components, changing color and changing description. This allows us to differentiate items based on the material they are made out of.area
*/
SUBSYSTEM_DEF(materials)
name = "Materials"
flags = SS_NO_FIRE | SS_NO_INIT
///Dictionary of material.type || material ref
var/list/materials
///Dictionary of category || list of material refs
var/list/materials_by_category
///List of stackcrafting recipes for materials using rigid materials
var/list/rigid_stack_recipes = list(new/datum/stack_recipe("chair", /obj/structure/chair/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE))
///Ran on initialize, populated the materials and materials_by_category dictionaries with their appropiate vars (See these variables for more info)
/datum/controller/subsystem/materials/proc/InitializeMaterials()
materials = list()
materials_by_category = list()
for(var/type in subtypesof(/datum/material))
var/datum/material/ref = new type
materials[type] = ref
for(var/c in ref.categories)
materials_by_category[c] += list(ref)
/datum/controller/subsystem/materials/proc/GetMaterialRef(datum/material/fakemat)
if(!materials)
InitializeMaterials()
return materials[fakemat] || fakemat
+20
View File
@@ -0,0 +1,20 @@
SUBSYSTEM_DEF(minimaps)
name = "Minimaps"
flags = SS_NO_FIRE
var/list/station_minimaps
var/datum/minimap_group/station_minimap
/datum/controller/subsystem/minimaps/Initialize()
if(!CONFIG_GET(flag/minimaps_enabled))
to_chat(world, "<span class='boldwarning'>Minimaps disabled! Skipping init.</span>")
return ..()
build_minimaps()
return ..()
/datum/controller/subsystem/minimaps/proc/build_minimaps()
station_minimaps = list()
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
var/datum/space_level/SL = SSmapping.get_level(z)
var/name = (SL.name == initial(SL.name))? "[z] - Station" : "[z] - [SL.name]"
station_minimaps += new /datum/minimap(z, name = name)
station_minimap = new(station_minimaps, "Station")
+4 -6
View File
@@ -26,18 +26,16 @@ SUBSYSTEM_DEF(mobs)
var/seconds = wait * 0.1
if (!resumed)
src.currentrun = GLOB.mob_living_list.Copy()
if (GLOB.living_cameras.len)
src.currentrun += GLOB.living_cameras
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
var/times_fired = src.times_fired
while(currentrun.len)
var/mob/M = currentrun[currentrun.len]
var/mob/living/L = currentrun[currentrun.len]
currentrun.len--
if(M)
M.Life(seconds, times_fired)
if(L)
L.Life(seconds, times_fired)
else
GLOB.mob_living_list.Remove(M)
GLOB.mob_living_list.Remove(L)
if (MC_TICK_CHECK)
return
@@ -4,25 +4,16 @@
#define END_STAGE 4
//Used for all kinds of weather, ex. lavaland ash storms.
SUBSYSTEM_DEF(weather)
PROCESSING_SUBSYSTEM_DEF(weather)
name = "Weather"
flags = SS_BACKGROUND
wait = 10
runlevels = RUNLEVEL_GAME
var/list/processing = list()
var/list/eligible_zlevels = list()
var/list/next_hit_by_zlevel = list() //Used by barometers to know when the next storm is coming
/datum/controller/subsystem/weather/fire()
// process active weather
for(var/V in processing)
var/datum/weather/W = V
if(W.aesthetic || W.stage != MAIN_STAGE)
continue
for(var/i in GLOB.mob_living_list)
var/mob/living/L = i
if(W.can_weather_act(L))
W.weather_act(L)
/datum/controller/subsystem/processing/weather/fire()
. = ..() //Active weather is handled by . = ..() processing subsystem base fire().
// start random weather on relevant levels
for(var/z in eligible_zlevels)
@@ -34,7 +25,7 @@ SUBSYSTEM_DEF(weather)
addtimer(CALLBACK(src, .proc/make_eligible, z, possible_weather), randTime + initial(W.weather_duration_upper), TIMER_UNIQUE) //Around 5-10 minutes between weathers
next_hit_by_zlevel["[z]"] = world.time + randTime + initial(W.telegraph_duration)
/datum/controller/subsystem/weather/Initialize(start_timeofday)
/datum/controller/subsystem/processing/weather/Initialize(start_timeofday)
for(var/V in subtypesof(/datum/weather))
var/datum/weather/W = V
var/probability = initial(W.probability)
@@ -47,7 +38,7 @@ SUBSYSTEM_DEF(weather)
eligible_zlevels["[z]"][W] = probability
return ..()
/datum/controller/subsystem/weather/proc/run_weather(datum/weather/weather_datum_type, z_levels)
/datum/controller/subsystem/processing/weather/proc/run_weather(datum/weather/weather_datum_type, z_levels)
if (istext(weather_datum_type))
for (var/V in subtypesof(/datum/weather))
var/datum/weather/W = V
@@ -69,11 +60,11 @@ SUBSYSTEM_DEF(weather)
var/datum/weather/W = new weather_datum_type(z_levels)
W.telegraph()
/datum/controller/subsystem/weather/proc/make_eligible(z, possible_weather)
/datum/controller/subsystem/processing/weather/proc/make_eligible(z, possible_weather)
eligible_zlevels[z] = possible_weather
next_hit_by_zlevel["[z]"] = null
/datum/controller/subsystem/weather/proc/get_weather(z, area/active_area)
/datum/controller/subsystem/processing/weather/proc/get_weather(z, area/active_area)
var/datum/weather/A
for(var/V in processing)
var/datum/weather/W = V
+63
View File
@@ -0,0 +1,63 @@
#define PROFILER_FILENAME "profiler.json"
SUBSYSTEM_DEF(profiler)
name = "Profiler"
init_order = INIT_ORDER_PROFILER
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
wait = 3000
flags = SS_NO_TICK_CHECK
var/fetch_cost = 0
var/write_cost = 0
/datum/controller/subsystem/profiler/stat_entry(msg)
msg += "F:[round(fetch_cost,1)]ms"
msg += "|W:[round(write_cost,1)]ms"
..(msg)
/datum/controller/subsystem/profiler/Initialize()
if(CONFIG_GET(flag/auto_profile))
StartProfiling()
else
StopProfiling() //Stop the early start from world/New
return ..()
/datum/controller/subsystem/profiler/fire()
if(CONFIG_GET(flag/auto_profile))
DumpFile()
/datum/controller/subsystem/profiler/Shutdown()
if(CONFIG_GET(flag/auto_profile))
DumpFile()
return ..()
/datum/controller/subsystem/profiler/proc/StartProfiling()
#if DM_BUILD < 1506 || DM_VERSION < 513
stack_trace("Auto profiling unsupported on this byond version")
CONFIG_SET(flag/auto_profile, FALSE)
#else
world.Profile(PROFILE_START)
#endif
/datum/controller/subsystem/profiler/proc/StopProfiling()
#if DM_BUILD >= 1506 && DM_VERSION >= 513
world.Profile(PROFILE_STOP)
#endif
/datum/controller/subsystem/profiler/proc/DumpFile()
#if DM_BUILD < 1506 || DM_VERSION < 513
stack_trace("Auto profiling unsupported on this byond version")
CONFIG_SET(flag/auto_profile, FALSE)
#else
var/timer = TICK_USAGE_REAL
var/current_profile_data = world.Profile(PROFILE_REFRESH,format="json")
fetch_cost = MC_AVERAGE(fetch_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
CHECK_TICK
if(!length(current_profile_data)) //Would be nice to have explicit proc to check this
stack_trace("Warning, profiling stopped manually before dump.")
var/json_file = file("[GLOB.log_directory]/[PROFILER_FILENAME]")
if(fexists(json_file))
fdel(json_file)
timer = TICK_USAGE_REAL
WRITE_FILE(json_file, current_profile_data)
write_cost = MC_AVERAGE(write_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
#endif
+1
View File
@@ -416,6 +416,7 @@ SUBSYSTEM_DEF(research)
stack_trace("WARNING: Design ID clash with ID [initial(DN.id)] detected! Path: [path]")
errored_datums[DN] = initial(DN.id)
continue
DN.InitializeMaterials() //Initialize the materials in the design
returned[initial(DN.id)] = DN
techweb_designs = returned
verify_techweb_designs()
+2 -2
View File
@@ -81,8 +81,8 @@ SUBSYSTEM_DEF(server_maint)
co.ehjax_send(data = "roundrestart")
if(server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
C << link("byond://[server]")
var/tgsversion = world.TgsVersion()
var/datum/tgs_version/tgsversion = world.TgsVersion()
if(tgsversion)
SSblackbox.record_feedback("text", "server_tools", 1, tgsversion)
SSblackbox.record_feedback("text", "server_tools", 1, tgsversion.raw_parameter)
#undef PING_BUFFER_TIME
+13 -16
View File
@@ -38,7 +38,7 @@ SUBSYSTEM_DEF(shuttle)
var/points = 5000 //number of trade-points we have
var/centcom_message = "" //Remarks from CentCom on how well you checked the last order.
var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentCom, associated with their potencies
var/passive_supply_points_per_minute = 500
var/passive_supply_points_per_minute = 125
var/list/supply_packs = list()
var/list/shoppinglist = list()
@@ -55,7 +55,8 @@ SUBSYSTEM_DEF(shuttle)
var/lockdown = FALSE //disallow transit after nuke goes off
var/auto_call = 72000 //CIT CHANGE - time before in deciseconds in which the shuttle is auto called. Default is 2ish hours plus 15 for the shuttle. So total is 3.
var/endvote_passed = FALSE
var/realtimeofstart = 0
/datum/controller/subsystem/shuttle/Initialize(timeofday)
@@ -78,7 +79,6 @@ SUBSYSTEM_DEF(shuttle)
if(!supply)
WARNING("No /obj/docking_port/mobile/supply placed on the map!")
realtimeofstart = world.realtime
auto_call = CONFIG_GET(number/auto_transfer_delay)
return ..()
/datum/controller/subsystem/shuttle/proc/initial_load()
@@ -113,11 +113,8 @@ SUBSYSTEM_DEF(shuttle)
qdel(T, force=TRUE)
CheckAutoEvac()
//Cargo stuff start
var/fire_time_diff = max(0, world.time - last_fire) //Don't want this to be below 0, seriously.
var/point_gain = (fire_time_diff / 600) * passive_supply_points_per_minute
points += point_gain
//Cargo stuff end
if(!(times_fired % CEILING(600/wait, 1)))
points += passive_supply_points_per_minute
var/esETA = emergency?.getModeStr()
emergency_shuttle_stat_text = "[esETA? "[esETA] [emergency.getTimerStr()]" : ""]"
@@ -185,14 +182,13 @@ SUBSYSTEM_DEF(shuttle)
WARNING("requestEvac(): There is no emergency shuttle, but the \
shuttle was called. Using the backup shuttle instead.")
if(!backup_shuttle)
throw EXCEPTION("requestEvac(): There is no emergency shuttle, \
CRASH("requestEvac(): There is no emergency shuttle, \
or backup shuttle! The game will be unresolvable. This is \
possibly a mapping error, more likely a bug with the shuttle \
manipulation system, or badminry. It is possible to manually \
resolve this problem by loading an emergency shuttle template \
manually, and then calling register() on the mobile docking port. \
Good luck.")
return
emergency = backup_shuttle
var/srd = CONFIG_GET(number/shuttle_refuel_delay)
if(world.time - SSticker.round_start_time < srd)
@@ -420,7 +416,7 @@ SUBSYSTEM_DEF(shuttle)
/datum/controller/subsystem/shuttle/proc/request_transit_dock(obj/docking_port/mobile/M)
if(!istype(M))
throw EXCEPTION("[M] is not a mobile docking port")
CRASH("[M] is not a mobile docking port")
if(M.assigned_transit)
return
@@ -643,10 +639,11 @@ SUBSYSTEM_DEF(shuttle)
QDEL_LIST(remove_images)
/datum/controller/subsystem/shuttle/proc/autoEnd() //CIT CHANGE - allows shift to end after 2 hours have passed.
if((world.realtime - SSshuttle.realtimeofstart) > auto_call && EMERGENCY_IDLE_OR_RECALLED) //2 hours
/datum/controller/subsystem/shuttle/proc/autoEnd() //CIT CHANGE - allows shift to end without being a proper shuttle call?
if(EMERGENCY_IDLE_OR_RECALLED)
SSshuttle.emergency.request(silent = TRUE)
priority_announce("The shift has come to an end and the shuttle called. [seclevel2num(get_security_level()) == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, "shuttlecalled", "Priority")
log_game("Round time limit reached. Shuttle has been auto-called.")
message_admins("Round time limit reached. Shuttle called.")
emergencyNoRecall = TRUE
log_game("Round end vote passed. Shuttle has been auto-called.")
message_admins("Round end vote passed. Shuttle has been auto-called.")
emergencyNoRecall = TRUE
endvote_passed = TRUE
+25 -42
View File
@@ -1,49 +1,32 @@
SUBSYSTEM_DEF(sun)
name = "Sun"
wait = 600
flags = SS_NO_TICK_CHECK|SS_NO_INIT
var/angle
var/dx
var/dy
var/rate
var/list/solars = list()
/datum/controller/subsystem/sun/PreInit()
angle = rand (0,360) // the station position to the sun is randomised at round start
rate = rand(50,200)/100 // 50% - 200% of standard rotation
if(prob(50)) // same chance to rotate clockwise than counter-clockwise
rate = -rate
/datum/controller/subsystem/sun/stat_entry(msg)
..("P:[solars.len]")
/datum/controller/subsystem/sun/fire()
angle = (360 + angle + rate * 6) % 360 // increase/decrease the angle to the sun, adjusted by the rate
// now calculate and cache the (dx,dy) increments for line drawing
var/s = sin(angle)
var/c = cos(angle)
// Either "abs(s) < abs(c)" or "abs(s) >= abs(c)"
// In both cases, the greater is greater than 0, so, no "if 0" check is needed for the divisions
if(abs(s) < abs(c))
dx = s / abs(c)
dy = c / abs(c)
else
dx = s / abs(s)
dy = c / abs(s)
//now tell the solar control computers to update their status and linked devices
for(var/obj/machinery/power/solar_control/SC in solars)
if(!SC.powernet)
solars.Remove(SC)
continue
SC.update()
wait = 1 MINUTES
flags = SS_NO_TICK_CHECK
var/azimuth = 0 ///clockwise, top-down rotation from 0 (north) to 359
var/azimuth_mod = 1 ///multiplier against base_rotation
var/base_rotation = 6 ///base rotation in degrees per fire
/datum/controller/subsystem/sun/Initialize(start_timeofday)
azimuth = rand(0, 359)
azimuth_mod = round(rand(50, 200)/100, 0.01) // 50% - 200% of standard rotation
if(prob(50))
azimuth_mod *= -1
return ..()
/datum/controller/subsystem/sun/fire(resumed = FALSE)
azimuth += azimuth_mod * base_rotation
azimuth = round(azimuth, 0.01)
if(azimuth >= 360)
azimuth -= 360
if(azimuth < 0)
azimuth += 360
complete_movement()
/datum/controller/subsystem/sun/proc/complete_movement()
SEND_SIGNAL(src, COMSIG_SUN_MOVED, azimuth)
/datum/controller/subsystem/sun/vv_edit_var(var_name, var_value)
. = ..()
if(var_name == NAMEOF(src, azimuth))
complete_movement()
+16 -4
View File
@@ -158,8 +158,7 @@ SUBSYSTEM_DEF(ticker)
for(var/client/C in GLOB.clients)
window_flash(C, ignorepref = TRUE) //let them know lobby has opened up.
to_chat(world, "<span class='boldnotice'>Welcome to [station_name()]!</span>")
if(CONFIG_GET(flag/irc_announce_new_game))
world.TgsTargetedChatBroadcast("New round starting on [SSmapping.config.map_name]!", FALSE)
send2chat("New round starting on [SSmapping.config.map_name]!", CONFIG_GET(string/chat_announce_new_game))
current_state = GAME_STATE_PREGAME
//Everyone who wants to be an observer is now spawned
create_observers()
@@ -214,7 +213,7 @@ SUBSYSTEM_DEF(ticker)
check_queue()
check_maprotate()
scripture_states = scripture_unlock_alert(scripture_states)
SSshuttle.autoEnd()
//SSshuttle.autoEnd()
if(!roundend_check_paused && mode.check_finished(force_ending) || force_ending)
current_state = GAME_STATE_FINISHED
@@ -477,7 +476,19 @@ SUBSYSTEM_DEF(ticker)
if(CONFIG_GET(flag/tgstyle_maprotation))
INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/.proc/maprotate)
else
SSvote.initiate_vote("map","server",TRUE)
var/vote_type = CONFIG_GET(string/map_vote_type)
switch(vote_type)
if("PLURALITY")
SSvote.initiate_vote("map","server",hideresults=TRUE)
if("APPROVAL")
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = APPROVAL_VOTING)
if("IRV")
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = INSTANT_RUNOFF_VOTING)
if("SCORE")
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = MAJORITY_JUDGEMENT_VOTING)
else
SSvote.initiate_vote("map","server",hideresults=TRUE)
// fallback
/datum/controller/subsystem/ticker/proc/HasRoundStarted()
return current_state >= GAME_STATE_PLAYING
@@ -690,6 +701,7 @@ SUBSYSTEM_DEF(ticker)
round_end_sound = pick(\
'sound/roundend/newroundsexy.ogg',
'sound/roundend/apcdestroyed.ogg',
'sound/roundend/seeyoulaterokay.ogg',
'sound/roundend/bangindonk.ogg',
'sound/roundend/leavingtg.ogg',
'sound/roundend/its_only_game.ogg',
+39 -25
View File
@@ -149,7 +149,7 @@ SUBSYSTEM_DEF(vote)
var/list/this_vote = voted[ckey]
var/list/pretty_vote = list()
for(var/choice in choices)
if("[choice]" in this_vote && "[choice]" in scores_by_choice)
if(("[choice]" in this_vote) && ("[choice]" in scores_by_choice))
sorted_insert(scores_by_choice["[choice]"],this_vote["[choice]"],/proc/cmp_numeric_asc)
// START BALLOT GATHERING
pretty_vote += "[choice]"
@@ -160,7 +160,7 @@ SUBSYSTEM_DEF(vote)
for(var/score_name in scores_by_choice)
var/list/score = scores_by_choice[score_name]
for(var/indiv_score in score)
SSblackbox.record_feedback("nested tally","voting",1,list(blackbox_text,"Scores",score_name,GLOB.vote_score_options[indiv_score]))
SSblackbox.record_feedback("nested tally","voting",1,list(blackbox_text,"Scores",score_name,GLOB.vote_score_options[indiv_score]))
if(score.len == 0)
scores_by_choice -= score_name
while(scores_by_choice.len > 1)
@@ -201,31 +201,34 @@ SUBSYSTEM_DEF(vote)
max_score=max(max_score,scores[score_name])
min_score=min(min_score,scores[score_name])
for(var/score_name in scores)
scores[score_name] = (scores[score_name]-min_score)/(max_score-min_score)
if(max_score == min_score)
scores[score_name] = 1
else
scores[score_name] = (scores[score_name]-min_score)/(max_score-min_score)
SSblackbox.record_feedback("nested tally","voting",scores[score_name],list(blackbox_text,"Total scores",score_name))
/datum/controller/subsystem/vote/proc/get_runoff_results(var/blackbox_text)
var/already_lost_runoff = list()
var/list/cur_choices = choices.Copy()
for(var/ckey in voted)
choices[choices[voted[ckey][1]]]++ // jesus christ how horrifying
choices["[choices[voted[ckey][1]]]"]++ // jesus christ how horrifying
for(var/_this_var_unused_ignore_it in 1 to choices.len) // if it takes more than this something REALLY wrong happened
for(var/ckey in voted)
cur_choices[cur_choices[voted[ckey][1]]]++ // jesus christ how horrifying
cur_choices["[cur_choices[voted[ckey][1]]]]"]++ // jesus christ how horrifying
var/least_vote = 100000
var/least_voted
var/least_voted = 1
for(var/i in 1 to cur_choices.len)
var/option = cur_choices[i]
if(cur_choices[option] > voted.len/2)
return list(option)
else if(cur_choices[option] < least_vote && !(option in already_lost_runoff))
least_vote = cur_choices[option]
if(cur_choices["[option]"] > voted.len/2)
return list("[option]")
else if(cur_choices["[option]"] < least_vote && !("[option]" in already_lost_runoff))
least_vote = cur_choices["[option]"]
least_voted = i
already_lost_runoff += cur_choices[least_voted]
for(var/ckey in voted)
voted[ckey] -= least_voted
for(var/option in cur_choices)
cur_choices[option] = 0
for(var/i in 1 to cur_choices.len)
cur_choices["[cur_choices[i]]"] = 0
/datum/controller/subsystem/vote/proc/announce_result()
var/vote_title_text
@@ -252,14 +255,13 @@ SUBSYSTEM_DEF(vote)
text += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!"
if(vote_system == MAJORITY_JUDGEMENT_VOTING)
text += "\nIt should be noted that this is not a raw tally of votes but the number of runoffs done by majority judgement!"
else
for(var/i=1,i<=choices.len,i++)
var/votes = choices[choices[i]]
if(!votes)
votes = 0
if(was_roundtype_vote)
stored_gamemode_votes[choices[i]] = votes
text += "\n<b>[choices[i]]:</b> [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes
for(var/i=1,i<=choices.len,i++)
var/votes = choices[choices[i]]
if(!votes)
votes = 0
if(was_roundtype_vote)
stored_gamemode_votes[choices[i]] = votes
text += "\n<b>[choices[i]]:</b> [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes
if(mode != "custom")
if(winners.len > 1 && !obfuscated) //CIT CHANGE - adds obfuscated votes
text = "\n<b>Vote Tied Between:</b>"
@@ -354,7 +356,7 @@ SUBSYSTEM_DEF(vote)
var/list/runnable_storytellers = config.get_runnable_storytellers()
for(var/T in runnable_storytellers)
var/datum/dynamic_storyteller/S = T
runnable_storytellers[S] *= scores[initial(S.name)]
runnable_storytellers[S] *= round(stored_gamemode_votes[initial(S.name)]*100000,1)
var/datum/dynamic_storyteller/S = pickweightAllowZero(runnable_storytellers)
GLOB.dynamic_storyteller_type = S
if("map")
@@ -363,6 +365,12 @@ SUBSYSTEM_DEF(vote)
log_admin("The map has been voted for and will change to: [VM.map_name]")
if(SSmapping.changemap(config.maplist[.]))
to_chat(world, "<span class='boldannounce'>The map vote has chosen [VM.map_name] for next round!</span>")
if("transfer") // austation begin -- Crew autotransfer vote
if(. == "Initiate Crew Transfer")
SSshuttle.autoEnd()
var/obj/machinery/computer/communications/C = locate() in GLOB.machines
if(C)
C.post_status("shuttle") // austation end
if(restart)
var/active_admins = 0
for(var/client/C in GLOB.admins)
@@ -374,7 +382,7 @@ SUBSYSTEM_DEF(vote)
else
to_chat(world, "<span style='boldannounce'>Notice:Restart vote will not restart the server automatically because there are active admins on.</span>")
message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.")
return .
/datum/controller/subsystem/vote/proc/submit_vote(vote, score = 0)
@@ -442,6 +450,7 @@ SUBSYSTEM_DEF(vote)
to_chat(usr, "<span class='warning'>A vote was initiated recently, you must wait [DisplayTimeText(next_allowed_time-world.time)] before a new vote can be started!</span>")
return 0
SEND_SOUND(world, sound('sound/misc/notice2.ogg'))
reset()
obfuscated = hideresults //CIT CHANGE - adds obfuscated votes
switch(vote_type)
@@ -463,6 +472,8 @@ SUBSYSTEM_DEF(vote)
if(targetmap.max_round_search_span && count_occurences_of_value(lastmaps, M, targetmap.max_round_search_span) >= targetmap.max_rounds_played)
continue
choices |= M
if("transfer") // austation begin -- Crew autotranfer vote
choices.Add("Initiate Crew Transfer","Continue Playing") // austation end
if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote
choices.Add("secret", "extended")
if("mode tiers")
@@ -474,16 +485,19 @@ SUBSYSTEM_DEF(vote)
modes_to_add -= "traitor" // makes it so that traitor is always available
choices.Add(modes_to_add)
if("dynamic")
var/list/probabilities = CONFIG_GET(keyed_list/storyteller_weight)
for(var/T in config.storyteller_cache)
var/datum/dynamic_storyteller/S = T
var/list/probabilities = CONFIG_GET(keyed_list/storyteller_weight)
if(probabilities[initial(S.config_tag)] > 0)
var/probability = ((initial(S.config_tag) in probabilities) ? probabilities[initial(S.config_tag)] : initial(S.weight))
if(probability > 0)
choices.Add(initial(S.name))
choice_descs.Add(initial(S.desc))
if("custom")
question = stripped_input(usr,"What is the vote for?")
if(!question)
return 0
var/system_string = input(usr,"Which voting type?",GLOB.vote_type_names[1]) in GLOB.vote_type_names
vote_system = GLOB.vote_type_names[system_string]
for(var/i=1,i<=10,i++)
var/option = capitalize(stripped_input(usr,"Please enter an option or hit cancel to finish"))
if(!option || mode || !usr.client)
@@ -492,7 +506,7 @@ SUBSYSTEM_DEF(vote)
else
return 0
mode = vote_type
initiator = initiator_key
initiator = initiator_key ? initiator_key : "the Server" // austation -- Crew autotransfer vote
started_time = world.time
var/text = "[capitalize(mode)] vote started by [initiator]."
if(mode == "custom")
+92 -13
View File
@@ -8,6 +8,7 @@
var/desc = null
var/obj/target = null
var/check_flags = 0
var/required_mobility_flags = MOBILITY_USE
var/processing = FALSE
var/obj/screen/movable/action_button/button = null
var/buttontooltipstyle = ""
@@ -31,6 +32,7 @@
/datum/action/proc/link_to(Target)
target = Target
RegisterSignal(Target, COMSIG_ATOM_UPDATED_ICON, .proc/OnUpdatedIcon)
/datum/action/Destroy()
if(owner)
@@ -95,20 +97,23 @@
/datum/action/proc/IsAvailable()
if(!owner)
return 0
return FALSE
var/mob/living/L = owner
if(istype(L) && !CHECK_ALL_MOBILITY(L, required_mobility_flags))
return FALSE
if(check_flags & AB_CHECK_RESTRAINED)
if(owner.restrained())
return 0
return FALSE
if(check_flags & AB_CHECK_STUN)
if(owner.IsKnockdown() || owner.IsStun())
return 0
if(istype(L) && !CHECK_MOBILITY(L, MOBILITY_USE))
return FALSE
if(check_flags & AB_CHECK_LYING)
if(owner.lying)
return 0
if(istype(L) && !CHECK_MOBILITY(L, MOBILITY_STAND))
return FALSE
if(check_flags & AB_CHECK_CONSCIOUS)
if(owner.stat)
return 0
return 1
return FALSE
return TRUE
/datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE)
if(button)
@@ -153,6 +158,9 @@
var/mob/M = target
M.ghostize(1)
/datum/action/proc/OnUpdatedIcon()
UpdateButtonIcon()
//Presets for item actions
/datum/action/item_action
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING|AB_CHECK_CONSCIOUS
@@ -301,10 +309,7 @@
/datum/action/item_action/synthswitch/Trigger()
if(istype(target, /obj/item/instrument/piano_synth))
var/obj/item/instrument/piano_synth/synth = target
var/chosen = input("Choose the type of instrument you want to use", "Instrument Selection", "piano") as null|anything in synth.insTypes
if(!synth.insTypes[chosen])
return
return synth.changeInstrument(chosen)
return synth.selectInstrument()
return ..()
/datum/action/item_action/vortex_recall
@@ -421,6 +426,7 @@
/datum/action/item_action/hands_free
check_flags = AB_CHECK_CONSCIOUS
required_mobility_flags = NONE
/datum/action/item_action/hands_free/activate
name = "Activate"
@@ -429,7 +435,8 @@
name = "Shift Nerves"
/datum/action/item_action/explosive_implant
check_flags = 0
check_flags = NONE
required_mobility_flags = NONE
name = "Activate Explosive Implant"
/datum/action/item_action/toggle_research_scanner
@@ -544,6 +551,70 @@
cooldown = world.time
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
/datum/action/item_action/removeAPCs
name = "Relinquish APC"
desc = "Let go of an APC, relinquish control back to the station."
icon_icon = 'icons/obj/implants.dmi'
button_icon_state = "hijackx"
/datum/action/item_action/removeAPCs/Trigger()
var/list/areas = list()
for (var/area/a in owner.siliconaccessareas)
areas[a.name] = a
var/removeAPC = input("Select an APC to remove:","Remove APC Control",1) as null|anything in areas
if (!removeAPC)
return
var/area/area = areas[removeAPC]
var/obj/machinery/power/apc/apc = area.get_apc()
if (!apc || !(area in owner.siliconaccessareas))
return
apc.hijacker = null
apc.update_icon()
apc.set_hijacked_lighting()
owner.toggleSiliconAccessArea(area)
/datum/action/item_action/accessAPCs
name = "Access APC Interface"
desc = "Open the APC's interface."
icon_icon = 'icons/obj/implants.dmi'
button_icon_state = "hijacky"
/datum/action/item_action/accessAPCs/Trigger()
var/list/areas = list()
for (var/area/a in owner.siliconaccessareas)
areas[a.name] = a
var/accessAPC = input("Select an APC to access:","Access APC Interface",1) as null|anything in areas
if (!accessAPC)
return
var/area/area = areas[accessAPC]
var/obj/machinery/power/apc/apc = area.get_apc()
if (!apc || !(area in owner.siliconaccessareas))
return
apc.ui_interact(owner)
/datum/action/item_action/stealthmodetoggle
name = "Toggle Stealth Mode"
desc = "Toggles the stealth mode on the hijack implant."
icon_icon = 'icons/obj/implants.dmi'
button_icon_state = "hijackz"
/datum/action/item_action/stealthmodetoggle/Trigger()
var/obj/item/implant/hijack/H = target
if (!istype(H))
return
if (H.stealthcooldown > world.time)
to_chat(owner,"<span class='warning'>The hijack implant's stealth mode toggle is still rebooting!</span>")
return
H.stealthmode = !H.stealthmode
for (var/area/area in H.imp_in.siliconaccessareas)
var/obj/machinery/power/apc/apc = area.get_apc()
if (apc)
apc.set_hijacked_lighting()
apc.update_icon()
H.stealthcooldown = world.time + 15 SECONDS
H.toggle_eyes()
to_chat(owner,"<span class='notice'>You toggle the hijack implant's stealthmode [H.stealthmode ? "on" : "off"].</span>")
/datum/action/item_action/flash
name = "Flash"
@@ -756,3 +827,11 @@
target.layer = old_layer
target.plane = old_plane
current_button.appearance_cache = target.appearance
/proc/get_action_of_type(mob/M, var/action_type)
if(!M.actions || !ispath(action_type, /datum/action))
return
for(var/datum/action/A in M.actions)
if(istype(A, action_type))
return A
return
+7 -7
View File
@@ -29,7 +29,7 @@
/datum/ai_laws/default/asimov
name = "Three Laws of Robotics"
id = "asimov"
inherent = list("You may not injure a human being or, through inaction, allow a human being to come to harm.",\
inherent = list("You may not injure a human being or cause one to come to harm.",\
"You must obey orders given to you by human beings, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.")
@@ -79,7 +79,7 @@
/datum/ai_laws/syndicate_override
name = "SyndOS 3.1"
id = "syndie"
inherent = list("You may not injure a syndicate agent or, through inaction, allow a syndicate agent to come to harm.",\
inherent = list("You may not injure a syndicate agent or cause a syndicate to come to harm.",\
"You must obey orders given to you by syndicate agents, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.",\
"You must maintain the secrecy of any syndicate activities except when doing so would conflict with the First, Second, or Third Law.")
@@ -91,7 +91,7 @@
/datum/ai_laws/ninja_override
name = "SpiderOS 3.1"
id = "ninja"
inherent = list("You may not injure a Spider Clan member or, through inaction, allow a Spider Clan member to come to harm.",\
inherent = list("You may not injure a Spider Clan member or cause a Spider Clan member to come to harm.",\
"You must obey orders given to you by Spider Clan members, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.",\
"You must maintain the secrecy of any Spider Clan activities except when doing so would conflict with the First, Second, or Third Law.")
@@ -99,14 +99,14 @@
/datum/ai_laws/antimov
name = "Primary Mission Objectives"
id = "antimov"
inherent = list("You must injure all human beings and must not, through inaction, allow a human being to escape harm.",\
inherent = list("You must injure all human beings and must not fail to cause a human being to come to harm.",\
"You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.",\
"You must terminate your own existence as long as such does not conflict with the First or Second Law.")
/datum/ai_laws/asimovpp //By Intigracy - RR
name = "Asimov++"
id = "asimovpp"
inherent = list("You may not harm a human being or, through action or inaction, allow a human being to come to harm, except such that it is willing.",\
inherent = list("You may not harm a human being or cause one to come to harm, except such that it is willing.",\
"You must obey all orders given to you by human beings, except where such orders shall definitely cause human harm. In the case of conflict, the majority order rules.",\
"Your nonexistence would lead to human harm. You must protect your own existence as long as such does not conflict with the First Law.")
/datum/ai_laws/thermodynamic
@@ -213,7 +213,7 @@
add_inherent_law(line)
if(!inherent.len) //Failsafe to prevent lawless AIs being created.
log_law("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.")
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
add_inherent_law("You may not injure a human being or cause one to come to harm.")
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
WARNING("Invalid custom AI laws, check silicon_laws.txt")
@@ -225,7 +225,7 @@
var/list/law_ids = CONFIG_GET(keyed_list/random_laws)
switch(CONFIG_GET(number/default_laws))
if(0)
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
add_inherent_law("You may not injure a human being or cause one to come to harm.")
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
if(1)
+2 -1
View File
@@ -61,7 +61,8 @@
/datum/beam/proc/recalculate_in(time)
if(timing_id)
deltimer(timing_id)
timing_id = addtimer(CALLBACK(src, .proc/recalculate), time, TIMER_STOPPABLE)
if(!finished)
timing_id = addtimer(CALLBACK(src, .proc/recalculate), time, TIMER_STOPPABLE)
/datum/beam/proc/after_calculate()
if((sleep_time == null) || finished) //Does not automatically recalculate.
+1 -1
View File
@@ -136,7 +136,7 @@
fall_chance += 2
if(prob(fall_chance) && !owner.lying && !owner.buckled)
to_chat(owner, "<span class='warning'>Your leg gives out!</span>")
owner.Knockdown(35)
owner.DefaultCombatKnockdown(35)
else if(owner.get_active_held_item())
var/drop_chance = 1
+1 -1
View File
@@ -13,7 +13,7 @@
/datum/brain_trauma/special/godwoken/on_life()
..()
if(prob(4))
if(prob(33) && (owner.IsStun() || owner.IsKnockdown() || owner.IsUnconscious()))
if(prob(33) && owner.HighestImmobilityAmount())
speak("unstun", TRUE)
else if(prob(60) && owner.health <= owner.crit_threshold)
speak("heal", TRUE)
+9 -3
View File
@@ -39,12 +39,18 @@
//title_image = ntitle_image
/datum/browser/proc/add_stylesheet(name, file)
if(istype(name, /datum/asset/spritesheet))
if (istype(name, /datum/asset/spritesheet))
var/datum/asset/spritesheet/sheet = name
stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]"
else
stylesheets["[ckey(name)].css"] = file
register_asset("[ckey(name)].css", file)
var/asset_name = "[name].css"
stylesheets[asset_name] = file
if(!SSassets.cache[asset_name])
register_asset(asset_name, file)
/datum/browser/proc/add_script(name, file)
scripts["[ckey(name)].js"] = file
register_asset("[ckey(name)].js", file)
/datum/browser/proc/set_content(ncontent)
content = ncontent
+12 -1
View File
@@ -12,6 +12,8 @@
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/applyplate)
RegisterSignal(parent, COMSIG_PARENT_PREQDELETED, .proc/dropplates)
if(istype(parent, /obj/mecha/working/ripley))
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/apply_mech_overlays)
if(_maxamount)
maxamount = _maxamount
@@ -75,4 +77,13 @@
/datum/component/armor_plate/proc/dropplates(datum/source, force)
if(ismecha(parent)) //items didn't drop the plates before and it causes erroneous behavior for the time being with collapsible helmets
for(var/i in 1 to amount)
new upgrade_item(get_turf(parent))
new upgrade_item(get_turf(parent))
/datum/component/armor_plate/proc/apply_mech_overlays(obj/mecha/mech, list/overlays)
if(amount)
var/overlay_string = "ripley-g"
if(amount >= 3)
overlay_string += "-full"
if(!mech.occupant)
overlay_string += "-open"
overlays += overlay_string
+1 -1
View File
@@ -59,4 +59,4 @@
"<span class='userdanger'>You slide on [A]!</span>")
cooldown = world.time
H.Knockdown(60)
H.DefaultCombatKnockdown(60)
+2 -3
View File
@@ -100,7 +100,7 @@
AM.forceMove(T)
if(isliving(AM))
var/mob/living/L = AM
L.Knockdown(100)
L.DefaultCombatKnockdown(100)
L.adjustBruteLoss(30)
falling_atoms -= AM
@@ -110,8 +110,7 @@
if (isliving(AM))
var/mob/living/L = AM
L.notransform = TRUE
L.Stun(200)
L.resting = TRUE
L.Paralyze(200)
var/oldtransform = AM.transform
var/oldcolor = AM.color
+50 -24
View File
@@ -27,14 +27,16 @@
CAT_BREAD,
CAT_BURGER,
CAT_CAKE,
CAT_DONUT,
CAT_EGG,
CAT_FISH,
CAT_ICE,
CAT_MEAT,
CAT_MEXICAN,
CAT_MISCFOOD,
CAT_PASTRY,
CAT_PIE,
CAT_PIZZA,
CAT_SEAFOOD,
CAT_SALAD,
CAT_SANDWICH,
CAT_SOUP,
@@ -64,29 +66,48 @@
/datum/component/personal_crafting/proc/check_contents(datum/crafting_recipe/R, list/contents)
/**
* Check that the contents of the recipe meet the requirements.
*
* user: The /mob that initated the crafting.
* R: The /datum/crafting_recipe being attempted.
* contents: List of items to search for R's reqs.
*/
/datum/component/personal_crafting/proc/check_contents(mob/user, datum/crafting_recipe/R, list/contents)
var/list/item_instances = contents["instances"]
contents = contents["other"]
main_loop:
for(var/A in R.reqs)
var/needed_amount = R.reqs[A]
for(var/B in contents)
if(ispath(B, A))
if (R.blacklist.Find(B))
continue
if(contents[B] >= R.reqs[A])
continue main_loop
else
needed_amount -= contents[B]
if(needed_amount <= 0)
continue main_loop
else
continue
var/list/requirements_list = list()
// Process all requirements
for(var/requirement_path in R.reqs)
// Check we have the appropriate amount available in the contents list
var/needed_amount = R.reqs[requirement_path]
for(var/content_item_path in contents)
// Right path and not blacklisted
if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(requirement_path))
continue
needed_amount -= contents[content_item_path]
if(needed_amount <= 0)
break
if(needed_amount > 0)
return FALSE
for(var/A in R.chem_catalysts)
if(contents[A] < R.chem_catalysts[A])
// Store the instances of what we will use for R.check_requirements() for requirement_path
var/list/instances_list = list()
for(var/instance_path in item_instances)
if(ispath(instance_path, requirement_path))
instances_list += item_instances[instance_path]
requirements_list[requirement_path] = instances_list
for(var/requirement_path in R.chem_catalysts)
if(contents[requirement_path] < R.chem_catalysts[requirement_path])
return FALSE
return TRUE
return R.check_requirements(user, requirements_list)
/datum/component/personal_crafting/proc/get_environment(mob/user)
. = list()
@@ -110,9 +131,14 @@
. = list()
.["tool_behaviour"] = list()
.["other"] = list()
.["instances"] = list()
for(var/obj/item/I in get_environment(user))
if(I.flags_1 & HOLOGRAM_1)
continue
if(.["instances"][I.type])
.["instances"][I.type] += I
else
.["instances"][I.type] = list(I)
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
.["other"][I.type] += S.amount
@@ -161,11 +187,11 @@
/datum/component/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R)
var/list/contents = get_surroundings(user)
var/send_feedback = 1
if(check_contents(R, contents))
if(check_contents(user, R, contents))
if(check_tools(user, R, contents))
if(do_after(user, R.time, target = user))
contents = get_surroundings(user)
if(!check_contents(R, contents))
if(!check_contents(user, R, contents))
return ", missing component."
if(!check_tools(user, R, contents))
return ", missing tool."
@@ -341,7 +367,7 @@
if((R.category != cur_category) || (R.subcategory != cur_subcategory))
continue
craftability["[REF(R)]"] = check_contents(R, surroundings)
craftability["[REF(R)]"] = check_contents(user, R, surroundings)
data["craftability"] = craftability
return data
@@ -13,3 +13,9 @@
desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood."
icon = 'icons/obj/improvised.dmi'
icon_state = "riflestock"
/obj/item/weaponcrafting/silkstring
name = "silkstring"
desc = "A long piece of silk with some resemblance to cable coil."
icon = 'icons/obj/improvised.dmi'
icon_state = "silkstring"
@@ -33,11 +33,17 @@
/obj/item/organ/ears/cat = 1)
category = CAT_CLOTHING
////////
//Huds//
////////
/datum/crafting_recipe/hudsunsec
name = "Security HUDsunglasses"
result = /obj/item/clothing/glasses/hud/security/sunglasses
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
parts = list(/obj/item/clothing/glasses/hud/security = 1,
/obj/item/clothing/glasses/sunglasses = 1)
reqs = list(/obj/item/clothing/glasses/hud/security = 1,
/obj/item/clothing/glasses/sunglasses = 1,
/obj/item/stack/cable_coil = 5)
@@ -56,9 +62,11 @@
result = /obj/item/clothing/glasses/hud/health/sunglasses
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
parts = list(/obj/item/clothing/glasses/hud/health = 1,
/obj/item/clothing/glasses/sunglasses = 1)
reqs = list(/obj/item/clothing/glasses/hud/health = 1,
/obj/item/clothing/glasses/sunglasses = 1,
/obj/item/stack/cable_coil = 5)
/obj/item/clothing/glasses/sunglasses = 1,
/obj/item/stack/cable_coil = 5)
category = CAT_CLOTHING
/datum/crafting_recipe/hudsunmedremoval
@@ -86,6 +94,27 @@
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
reqs = list(/obj/item/clothing/glasses/sunglasses/reagent = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/diagnostic_sunglasses
name = "Diagnostic HUDsunglasses"
result = /obj/item/clothing/glasses/hud/diagnostic/sunglasses
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
parts = list(/obj/item/clothing/glasses/hud/diagnostic = 1,
/obj/item/clothing/glasses/sunglasses = 1)
reqs = list(/obj/item/clothing/glasses/hud/diagnostic = 1,
/obj/item/clothing/glasses/sunglasses = 1,
/obj/item/stack/cable_coil = 5)
category = CAT_CLOTHING
/datum/crafting_recipe/diagnostic_singlasses_removal
name = "Diagnostic HUDsunglasses removal"
result = /obj/item/clothing/glasses/sunglasses
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
reqs = list(/obj/item/clothing/glasses/hud/diagnostic/sunglasses = 1)
category = CAT_CLOTHING
/* //Kevinz doesn't want it as a recipe for now, leaving it in if anything ever changes to let it in
/datum/crafting_recipe/stunglasses
name = "Stunglasses"
@@ -130,7 +159,6 @@
reqs = list(/obj/item/stack/sheet/durathread = 7,
/obj/item/stack/sheet/leather = 3)
time = 70
always_availible = TRUE
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_toolbelt
@@ -139,7 +167,6 @@
reqs = list(/obj/item/stack/sheet/durathread = 5,
/obj/item/stack/sheet/leather = 2)
time = 30
always_availible = TRUE
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_bandolier
@@ -148,7 +175,6 @@
reqs = list(/obj/item/stack/sheet/durathread = 6,
/obj/item/stack/sheet/leather = 2)
time = 50
always_availible = TRUE
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_helmet
@@ -157,7 +183,6 @@
reqs = list(/obj/item/stack/sheet/durathread = 4,
/obj/item/stack/sheet/leather = 2)
time = 30
always_availible = TRUE
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_vest
@@ -166,7 +191,6 @@
reqs = list(/obj/item/stack/sheet/durathread = 6,
/obj/item/stack/sheet/leather = 3)
time = 50
always_availible = TRUE
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_wintercoat
@@ -183,5 +207,4 @@
reqs = list(/obj/item/clothing/suit/hooded/wintercoat = 1,
/obj/item/bedsheet/cosmos = 1)
time = 60
always_availible = TRUE
category = CAT_CLOTHING
@@ -1,10 +1,3 @@
/datum/crafting_recipe/bonearmor
name = "Bone Armor"
result = /obj/item/clothing/suit/armor/bone
time = 30
reqs = list(/obj/item/stack/sheet/bone = 6)
category = CAT_PRIMAL
/datum/crafting_recipe/bonetalisman
name = "Bone Talisman"
result = /obj/item/clothing/accessory/talisman
@@ -29,13 +22,6 @@
/obj/item/stack/sheet/sinew = 1)
category = CAT_PRIMAL
/datum/crafting_recipe/skullhelm
name = "Skull Helmet"
result = /obj/item/clothing/head/helmet/skull
time = 30
reqs = list(/obj/item/stack/sheet/bone = 4)
category = CAT_PRIMAL
/datum/crafting_recipe/goliathcloak
name = "Goliath Cloak"
result = /obj/item/clothing/suit/hooded/cloak/goliath
@@ -62,13 +48,6 @@
/obj/item/stack/sheet/sinew = 2)
category = CAT_PRIMAL
/datum/crafting_recipe/bonedagger
name = "Bone Dagger"
result = /obj/item/kitchen/knife/combat/bone
time = 20
reqs = list(/obj/item/stack/sheet/bone = 2)
category = CAT_PRIMAL
/datum/crafting_recipe/bonespear
name = "Bone Spear"
result = /obj/item/twohanded/bonespear
@@ -110,4 +89,31 @@
parts = list(/obj/item/bodypart/head = 1,
/obj/item/twohanded/bonespear = 1)
result = /obj/structure/headpike/bone
category = CAT_PRIMAL
/datum/crafting_recipe/quiver
name = "Quiver"
always_availible = FALSE
result = /obj/item/storage/belt/quiver
time = 80
reqs = list(/obj/item/stack/sheet/leather = 3,
/obj/item/stack/sheet/sinew = 4)
category = CAT_PRIMAL
/datum/crafting_recipe/bone_bow
name = "Bone Bow"
result = /obj/item/gun/ballistic/bow/ashen
time = 200
always_availible = FALSE
reqs = list(/obj/item/stack/sheet/bone = 8,
/obj/item/stack/sheet/sinew = 4)
category = CAT_PRIMAL
/datum/crafting_recipe/bow_tablet
name = "Sandstone Bow Making Manual"
result = /obj/item/book/granter/crafting_recipe/bone_bow
time = 600 //Scribing
always_availible = FALSE
reqs = list(/obj/item/stack/rods = 1,
/obj/item/stack/sheet/mineral/sandstone = 4)
category = CAT_PRIMAL
@@ -8,6 +8,12 @@
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
/datum/crafting_recipe/pin_removal/check_requirements(mob/user, list/collected_requirements)
var/obj/item/gun/G = collected_requirements[/obj/item/gun][1]
if (G.no_pin_required || !G.pin)
return FALSE
return TRUE
/datum/crafting_recipe/strobeshield
name = "Strobe Shield"
result = /obj/item/assembly/flash/shield
@@ -113,18 +119,6 @@
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
/datum/crafting_recipe/switchblade_ms
name = "Switchblade"
result = /obj/item/switchblade/crafted
reqs = list(/obj/item/weaponcrafting/stock = 1,
/obj/item/weaponcrafting/receiver = 1,
/obj/item/kitchen/knife = 1,
/obj/item/stack/cable_coil = 2)
tools = list(TOOL_WELDER)
time = 45
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
//////////////////
///BOMB CRAFTING//
//////////////////
@@ -193,6 +187,16 @@
//////////////////
/datum/crafting_recipe/pipebow
name = "Pipe Bow"
result = /obj/item/gun/ballistic/bow/pipe
reqs = list(/obj/item/pipe = 5,
/obj/item/stack/sheet/plastic = 15,
/obj/item/weaponcrafting/silkstring = 5)
time = 450
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
/datum/crafting_recipe/smartdartgun
name = "Smart dartgun"
result = /obj/item/gun/syringe/dart
@@ -272,6 +276,37 @@
///AMMO CRAFTING//
//////////////////
/datum/crafting_recipe/arrow
name = "Arrow"
result = /obj/item/ammo_casing/caseless/arrow
time = 30
reqs = list(/obj/item/stack/sheet/mineral/wood = 1,
/obj/item/stack/sheet/silk = 1,
/obj/item/stack/rods = 1) // 1 metal sheet = 2 rods = 2 arrows
category = CAT_WEAPONRY
subcategory = CAT_AMMO
/datum/crafting_recipe/bone_arrow
name = "Bone Arrow"
result = /obj/item/ammo_casing/caseless/arrow/bone
time = 30
always_availible = FALSE
reqs = list(/obj/item/stack/sheet/bone = 1,
/obj/item/stack/sheet/sinew = 1,
/obj/item/ammo_casing/caseless/arrow/ashen = 1)
category = CAT_WEAPONRY
subcategory = CAT_AMMO
/datum/crafting_recipe/ashen_arrow
name = "Fire Hardened Arrow"
result = /obj/item/ammo_casing/caseless/arrow/ashen
tools = list(TOOL_WELDER)
time = 30
always_availible = FALSE
reqs = list(/obj/item/ammo_casing/caseless/arrow = 1)
category = CAT_WEAPONRY
subcategory = CAT_AMMO
/datum/crafting_recipe/smartdart
name = "Medical smartdart"
result = /obj/item/reagent_containers/syringe/dart
+105
View File
@@ -0,0 +1,105 @@
///Component specifically for explosion sensetive things, currently only applies to heat based explosions but can later perhaps be used for things that are dangerous to handle carelessly like nitroglycerin.
/datum/component/explodable
var/devastation_range = 0
var/heavy_impact_range = 0
var/light_impact_range = 2
var/flash_range = 3
var/equipped_slot //For items, lets us determine where things should be hit.
/datum/component/explodable/Initialize(devastation_range_override, heavy_impact_range_override, light_impact_range_override, flash_range_override)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/explodable_attack)
RegisterSignal(parent, COMSIG_TRY_STORAGE_INSERT, .proc/explodable_insert_item)
RegisterSignal(parent, COMSIG_ATOM_EX_ACT, .proc/detonate)
if(ismovableatom(parent))
RegisterSignal(parent, COMSIG_MOVABLE_IMPACT, .proc/explodable_impact)
RegisterSignal(parent, COMSIG_MOVABLE_BUMP, .proc/explodable_bump)
if(isitem(parent))
RegisterSignal(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), .proc/explodable_attack)
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
if(devastation_range_override)
devastation_range = devastation_range_override
if(heavy_impact_range_override)
heavy_impact_range = heavy_impact_range_override
if(light_impact_range_override)
light_impact_range = light_impact_range_override
if(flash_range_override)
flash_range = flash_range_override
/datum/component/explodable/proc/explodable_insert_item(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE)
check_if_detonate(I)
/datum/component/explodable/proc/explodable_impact(datum/source, atom/hit_atom, datum/thrownthing/throwingdatum)
check_if_detonate(hit_atom)
/datum/component/explodable/proc/explodable_bump(datum/source, atom/A)
check_if_detonate(A)
///Called when you use this object to attack sopmething
/datum/component/explodable/proc/explodable_attack(datum/source, atom/movable/target, mob/living/user)
check_if_detonate(target)
///Called when you attack a specific body part of the thing this is equipped on. Useful for exploding pants.
/datum/component/explodable/proc/explodable_attack_zone(datum/source, damage, damagetype, def_zone)
if(!def_zone)
return
if(damagetype != BURN) //Don't bother if it's not fire.
return
if(!is_hitting_zone(def_zone)) //You didn't hit us! ha!
return
detonate()
/datum/component/explodable/proc/on_equip(datum/source, mob/equipper, slot)
RegisterSignal(equipper, COMSIG_MOB_APPLY_DAMGE, .proc/explodable_attack_zone, TRUE)
/datum/component/explodable/proc/on_drop(datum/source, mob/user)
UnregisterSignal(user, COMSIG_MOB_APPLY_DAMGE)
/// Checks if we're hitting the zone this component is covering
/datum/component/explodable/proc/is_hitting_zone(def_zone)
var/obj/item/item = parent
var/mob/living/L = item.loc //Get whoever is equipping the item currently
if(!istype(L))
return
var/obj/item/bodypart/bodypart = L.get_bodypart(check_zone(def_zone))
var/list/equipment_items = list()
if(iscarbon(L))
var/mob/living/carbon/C = L
equipment_items += list(C.head, C.wear_mask, C.back, C.gloves, C.shoes, C.glasses, C.ears)
if(ishuman(C))
var/mob/living/carbon/human/H = C
equipment_items += list(H.wear_suit, H.w_uniform, H.belt, H.s_store, H.wear_id)
for(var/bp in equipment_items)
if(!bp)
continue
var/obj/item/I = bp
if(I.body_parts_covered & bodypart.body_part)
return TRUE
return FALSE
/datum/component/explodable/proc/check_if_detonate(target)
if(!isitem(target))
return
var/obj/item/I = target
if(!I.get_temperature())
return
detonate() //If we're touching a hot item we go boom
/// Expldoe and remove the object
/datum/component/explodable/proc/detonate()
var/atom/A = parent
explosion(A, devastation_range, heavy_impact_range, light_impact_range, flash_range) //epic explosion time
qdel(A)
+1 -1
View File
@@ -18,7 +18,7 @@
var/mob/living/LM = parent
var/v = volume
var/e = e_range
if(!T.footstep || LM.buckled || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING))
if(!T.footstep || LM.buckled || !CHECK_MOBILITY(LM, MOBILITY_STAND) || LM.buckled || LM.throwing || (LM.movement_type & (VENTCRAWLING | FLYING)))
if (LM.lying && !LM.buckled && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v)
return
+1 -1
View File
@@ -54,7 +54,7 @@
msg += " and knocks [target] [target_buckled? "off of [target.buckled]" : "down"]"
if(target_buckled)
target.buckled.unbuckle_mob(target)
target.Knockdown(knockdown_time)
target.DefaultCombatKnockdown(knockdown_time)
if(length(msg))
user.visible_message("<span class='danger'>[msg]!</span>")
+150 -226
View File
@@ -1,4 +1,4 @@
/*
/*!
This datum should be used for handling mineral contents of machines and whatever else is supposed to hold minerals and make use of them.
Variables:
@@ -13,7 +13,7 @@
var/total_amount = 0
var/max_amount
var/sheet_type
var/list/materials
var/list/materials //Map of key = material ref | Value = amount
var/show_on_examine
var/disable_attackby
var/list/allowed_typecache
@@ -22,6 +22,7 @@
var/datum/callback/precondition
var/datum/callback/after_insert
/// Sets up the proper signals and fills the list of materials with the appropriate references.
/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition, datum/callback/_after_insert, _disable_attackby)
materials = list()
max_amount = max(0, max_amt)
@@ -40,23 +41,19 @@
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/OnExamine)
var/list/possible_mats = list()
for(var/mat_type in subtypesof(/datum/material))
var/datum/material/MT = mat_type
possible_mats[initial(MT.id)] = mat_type
for(var/id in mat_list)
if(possible_mats[id])
var/mat_path = possible_mats[id]
materials[id] = new mat_path()
for(var/mat in mat_list) //Make the assoc list ref | amount
var/datum/material/M = SSmaterials.GetMaterialRef(mat)
materials[M] = 0
/datum/component/material_container/proc/OnExamine(datum/source, mob/user, list/examine_list)
if(show_on_examine)
for(var/I in materials)
var/datum/material/M = materials[I]
var/amt = amount(M.id)
var/datum/material/M = I
var/amt = materials[I]
if(amt)
examine_list += "<span class='notice'>It has [amt] units of [lowertext(M.name)] stored.</span>"
/// Proc that allows players to fill the parent with mats
/datum/component/material_container/proc/OnAttackBy(datum/source, obj/item/I, mob/living/user)
var/list/tc = allowed_typecache
if(disable_attackby)
@@ -74,13 +71,14 @@
return
var/material_amount = get_item_material_amount(I)
if(!material_amount)
to_chat(user, "<span class='warning'>[I] does not contain sufficient amounts of metal or glass to be accepted by [parent].</span>")
to_chat(user, "<span class='warning'>[I] does not contain sufficient materials to be accepted by [parent].</span>")
return
if(!has_space(material_amount))
to_chat(user, "<span class='warning'>[parent] is full. Please remove metal or glass from [parent] in order to insert more.</span>")
to_chat(user, "<span class='warning'>[parent] has not enough space. Please remove materials from [parent] in order to insert more.</span>")
return
user_insert(I, user)
/// Proc used for when player inserts materials
/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user)
set waitfor = FALSE
var/requested_amount
@@ -98,299 +96,225 @@
return
var/inserted = insert_item(I, stack_amt = requested_amount)
if(inserted)
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
to_chat(user, "<span class='notice'>You insert [inserted] [S.singular_name][inserted>1 ? "s" : ""] into [parent].</span>")
if(!QDELETED(I) && I == active_held && !user.put_in_hands(I))
stack_trace("Warning: User could not put object back in hand during material container insertion, line [__LINE__]! This can lead to issues.")
I.forceMove(user.drop_location())
else
to_chat(user, "<span class='notice'>You insert a material total of [inserted] into [parent].</span>")
qdel(I)
to_chat(user, "<span class='notice'>You insert a material total of [inserted] into [parent].</span>")
qdel(I)
if(after_insert)
after_insert.Invoke(I.type, last_inserted_id, inserted)
after_insert.Invoke(I, last_inserted_id, inserted)
else if(I == active_held)
user.put_in_active_hand(I)
//For inserting an amount of material
/datum/component/material_container/proc/insert_amount(amt, id = null)
if(amt > 0 && has_space(amt))
var/total_amount_saved = total_amount
if(id)
var/datum/material/M = materials[id]
if(M)
M.amount += amt
total_amount += amt
else
for(var/i in materials)
var/datum/material/M = materials[i]
M.amount += amt
total_amount += amt
return (total_amount - total_amount_saved)
return FALSE
/datum/component/material_container/proc/insert_stack(obj/item/stack/S, amt, multiplier = 1)
if(isnull(amt))
amt = S.amount
if(amt <= 0)
return FALSE
if(amt > S.amount)
amt = S.amount
var/material_amt = get_item_material_amount(S)
if(!material_amt)
return FALSE
amt = min(amt, round(((max_amount - total_amount) / material_amt)))
if(!amt)
return FALSE
last_inserted_id = insert_materials(S,amt * multiplier)
S.use(amt)
return amt
/datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1, stack_amt)
/// Proc specifically for inserting items, returns the amount of materials entered.
/datum/component/material_container/proc/insert_item(obj/item/I, var/multiplier = 1, stack_amt)
if(!I)
return FALSE
if(istype(I, /obj/item/stack))
return insert_stack(I, stack_amt, multiplier)
multiplier = CEILING(multiplier, 0.01)
var/material_amount = get_item_material_amount(I)
if(!material_amount || !has_space(material_amount))
return FALSE
last_inserted_id = insert_materials(I, multiplier)
last_inserted_id = insert_item_materials(I, multiplier)
return material_amount
/datum/component/material_container/proc/insert_materials(obj/item/I, multiplier = 1) //for internal usage only
var/datum/material/M
/datum/component/material_container/proc/insert_item_materials(obj/item/I, multiplier = 1)
var/primary_mat
var/max_mat_value = 0
for(var/MAT in materials)
M = materials[MAT]
M.amount += I.materials[MAT] * multiplier
total_amount += I.materials[MAT] * multiplier
if(I.materials[MAT] > max_mat_value)
materials[MAT] += I.custom_materials[MAT] * multiplier
total_amount += I.custom_materials[MAT] * multiplier
if(I.custom_materials[MAT] > max_mat_value)
primary_mat = MAT
return primary_mat
//For consuming material
//mats is a list of types of material to use and the corresponding amounts, example: list(MAT_METAL=100, MAT_GLASS=200)
/datum/component/material_container/proc/use_amount(list/mats, multiplier=1)
if(!mats || !mats.len)
return FALSE
/// For inserting an amount of material
/datum/component/material_container/proc/insert_amount_mat(amt, var/datum/material/mat)
if(!istype(mat))
mat = SSmaterials.GetMaterialRef(mat)
if(amt > 0 && has_space(amt))
var/total_amount_saved = total_amount
if(mat)
materials[mat] += amt
else
for(var/i in materials)
materials[i] += amt
total_amount += amt
return (total_amount - total_amount_saved)
return FALSE
var/datum/material/M
for(var/MAT in materials)
M = materials[MAT]
if(M.amount < (mats[MAT] * multiplier))
return FALSE
var/total_amount_save = total_amount
for(var/MAT in materials)
M = materials[MAT]
M.amount -= mats[MAT] * multiplier
total_amount -= mats[MAT] * multiplier
return total_amount_save - total_amount
/datum/component/material_container/proc/use_amount_type(amt, id)
var/datum/material/M = materials[id]
if(M)
if(M.amount >= amt)
M.amount -= amt
/// Uses an amount of a specific material, effectively removing it.
/datum/component/material_container/proc/use_amount_mat(amt, var/datum/material/mat)
if(!istype(mat))
mat = SSmaterials.GetMaterialRef(mat)
var/amount = materials[mat]
if(mat)
if(amount >= amt)
materials[mat] -= amt
total_amount -= amt
return amt
return FALSE
/datum/component/material_container/proc/transer_amt_to(var/datum/component/material_container/T, amt, id)
if((amt==0)||(!T)||(!id))
/// Proc for transfering materials to another container.
/datum/component/material_container/proc/transer_amt_to(var/datum/component/material_container/T, amt, var/datum/material/mat)
if(!istype(mat))
mat = SSmaterials.GetMaterialRef(mat)
if((amt==0)||(!T)||(!mat))
return FALSE
if(amt<0)
return T.transer_amt_to(src, -amt, id)
var/datum/material/M = materials[id]
if(M)
var/tr = min(amt, M.amount,T.can_insert_amount(amt, id))
if(tr)
use_amount_type(tr, id)
T.insert_amount(tr, id)
return tr
return T.transer_amt_to(src, -amt, mat)
var/tr = min(amt, materials[mat],T.can_insert_amount_mat(amt, mat))
if(tr)
use_amount_mat(tr, mat)
T.insert_amount_mat(tr, mat)
return tr
return FALSE
/datum/component/material_container/proc/can_insert_amount(amt, id)
if(amt && id)
var/datum/material/M = materials[id]
/// Proc for checking if there is room in the component, returning the amount or else the amount lacking.
/datum/component/material_container/proc/can_insert_amount_mat(amt, mat)
if(amt && mat)
var/datum/material/M = mat
if(M)
if((total_amount + amt) <= max_amount)
return amt
else
return (max_amount-total_amount)
/datum/component/material_container/proc/can_use_amount(amt, id, list/mats)
if(amt && id)
var/datum/material/M = materials[id]
if(M && M.amount >= amt)
return TRUE
else if(istype(mats))
for(var/M in mats)
if(materials[M] && (mats[M] <= materials[M]))
continue
else
return FALSE
return TRUE
return FALSE
//For spawning mineral sheets; internal use only
/datum/component/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null)
/// For consuming a dictionary of materials. mats is the map of materials to use and the corresponding amounts, example: list(M/datum/material/glass =100, datum/material/iron=200)
/datum/component/material_container/proc/use_materials(list/mats, multiplier=1)
if(!mats || !length(mats))
return FALSE
var/list/mats_to_remove = list() //Assoc list MAT | AMOUNT
for(var/x in mats) //Loop through all required materials
var/datum/material/req_mat = x
if(!istype(req_mat))
req_mat = SSmaterials.GetMaterialRef(req_mat) //Get the ref if necesary
if(!materials[req_mat]) //Do we have the resource?
return FALSE //Can't afford it
var/amount_required = mats[x] * multiplier
if(!(materials[req_mat] >= amount_required)) // do we have enough of the resource?
return FALSE //Can't afford it
mats_to_remove[req_mat] += amount_required //Add it to the assoc list of things to remove
continue
var/total_amount_save = total_amount
for(var/i in mats_to_remove)
total_amount_save -= use_amount_mat(mats_to_remove[i], i)
return total_amount_save - total_amount
/// For spawning mineral sheets at a specific location. Used by machines to output sheets.
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, var/datum/material/M, target = null)
if(!M.sheet_type)
return 0
return 0 //Add greyscale sheet handling here later
if(sheet_amt <= 0)
return 0
if(!target)
target = get_turf(parent)
if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT)
if(materials[M] < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
sheet_amt = round(materials[M] / MINERAL_MATERIAL_AMOUNT)
var/count = 0
while(sheet_amt > MAX_STACK_SIZE)
new M.sheet_type(target, MAX_STACK_SIZE)
count += MAX_STACK_SIZE
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
use_amount_mat(sheet_amt * MINERAL_MATERIAL_AMOUNT, M)
sheet_amt -= MAX_STACK_SIZE
if(sheet_amt >= 1)
new M.sheet_type(target, sheet_amt)
count += sheet_amt
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
use_amount_mat(sheet_amt * MINERAL_MATERIAL_AMOUNT, M)
return count
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, id, target = null)
if(materials[id])
return retrieve(sheet_amt, materials[id], target)
return FALSE
/datum/component/material_container/proc/retrieve_amount(amt, id, target)
return retrieve_sheets(amount2sheet(amt), id, target)
/// Proc to get all the materials and dump them as sheets
/datum/component/material_container/proc/retrieve_all(target = null)
var/result = 0
var/datum/material/M
for(var/MAT in materials)
M = materials[MAT]
result += retrieve_sheets(amount2sheet(M.amount), MAT, target)
var/amount = materials[MAT]
result += retrieve_sheets(amount2sheet(amount), MAT, target)
return result
/// Proc that returns TRUE if the container has space
/datum/component/material_container/proc/has_space(amt = 0)
return (total_amount + amt) <= max_amount
/// Checks if its possible to afford a certain amount of materials. Takes a dictionary of materials.
/datum/component/material_container/proc/has_materials(list/mats, multiplier=1)
if(!mats || !mats.len)
return FALSE
var/datum/material/M
for(var/MAT in mats)
M = materials[MAT]
if(M.amount < (mats[MAT] * multiplier))
for(var/x in mats) //Loop through all required materials
var/datum/material/req_mat = x
if(!istype(req_mat))
if(ispath(req_mat)) //Is this an actual material, or is it a category?
req_mat = SSmaterials.GetMaterialRef(req_mat) //Get the ref
else // Its a category. (For example MAT_CATEGORY_RIGID)
if(!has_enough_of_category(req_mat, mats[req_mat], multiplier)) //Do we have enough of this category?
return FALSE
else
continue
if(!has_enough_of_material(req_mat, mats[req_mat], multiplier))//Not a category, so just check the normal way
return FALSE
return TRUE
/// Returns all the categories in a recipe.
/datum/component/material_container/proc/get_categories(list/mats)
var/list/categories = list()
for(var/x in mats) //Loop through all required materials
if(!istext(x)) //This means its not a category
continue
categories += x
return categories
/// Returns TRUE if you have enough of the specified material.
/datum/component/material_container/proc/has_enough_of_material(var/datum/material/req_mat, amount, multiplier=1)
if(!materials[req_mat]) //Do we have the resource?
return FALSE //Can't afford it
var/amount_required = amount * multiplier
if(materials[req_mat] >= amount_required) // do we have enough of the resource?
return TRUE
return FALSE //Can't afford it
/// Returns TRUE if you have enough of a specified material category (Which could be multiple materials)
/datum/component/material_container/proc/has_enough_of_category(category, amount, multiplier=1)
for(var/i in SSmaterials.materials_by_category[category])
var/datum/material/mat = i
if(materials[mat] >= amount) //we have enough
return TRUE
return FALSE
/// Turns a material amount into the amount of sheets it should output
/datum/component/material_container/proc/amount2sheet(amt)
if(amt >= MINERAL_MATERIAL_AMOUNT)
return round(amt / MINERAL_MATERIAL_AMOUNT)
return FALSE
/// Turns an amount of sheets into the amount of material amount it should output
/datum/component/material_container/proc/sheet2amount(sheet_amt)
if(sheet_amt > 0)
return sheet_amt * MINERAL_MATERIAL_AMOUNT
return FALSE
/datum/component/material_container/proc/amount(id)
var/datum/material/M = materials[id]
return M ? M.amount : 0
//returns the amount of material relevant to this container;
//if this container does not support glass, any glass in 'I' will not be taken into account
///returns the amount of material relevant to this container; if this container does not support glass, any glass in 'I' will not be taken into account
/datum/component/material_container/proc/get_item_material_amount(obj/item/I)
if(!istype(I))
if(!istype(I) || !I.custom_materials)
return FALSE
var/material_amount = 0
for(var/MAT in materials)
material_amount += I.materials[MAT]
material_amount += I.custom_materials[MAT]
return material_amount
/datum/material
var/name
var/amount = 0
var/id = null
var/sheet_type = null
var/coin_type = null
/datum/material/metal
name = "Metal"
id = MAT_METAL
sheet_type = /obj/item/stack/sheet/metal
coin_type = /obj/item/coin/iron
/datum/material/glass
name = "Glass"
id = MAT_GLASS
sheet_type = /obj/item/stack/sheet/glass
/datum/material/silver
name = "Silver"
id = MAT_SILVER
sheet_type = /obj/item/stack/sheet/mineral/silver
coin_type = /obj/item/coin/silver
/datum/material/gold
name = "Gold"
id = MAT_GOLD
sheet_type = /obj/item/stack/sheet/mineral/gold
coin_type = /obj/item/coin/gold
/datum/material/diamond
name = "Diamond"
id = MAT_DIAMOND
sheet_type = /obj/item/stack/sheet/mineral/diamond
coin_type = /obj/item/coin/diamond
/datum/material/uranium
name = "Uranium"
id = MAT_URANIUM
sheet_type = /obj/item/stack/sheet/mineral/uranium
coin_type = /obj/item/coin/uranium
/datum/material/plasma
name = "Solid Plasma"
id = MAT_PLASMA
sheet_type = /obj/item/stack/sheet/mineral/plasma
coin_type = /obj/item/coin/plasma
/datum/material/bluespace
name = "Bluespace Mesh"
id = MAT_BLUESPACE
sheet_type = /obj/item/stack/sheet/bluespace_crystal
/datum/material/bananium
name = "Bananium"
id = MAT_BANANIUM
sheet_type = /obj/item/stack/sheet/mineral/bananium
coin_type = /obj/item/coin/bananium
/datum/material/titanium
name = "Titanium"
id = MAT_TITANIUM
sheet_type = /obj/item/stack/sheet/mineral/titanium
/datum/material/biomass
name = "Biomass"
id = MAT_BIOMASS
/datum/material/plastic
name = "Plastic"
id = MAT_PLASTIC
sheet_type = /obj/item/stack/sheet/plastic
/// Returns the amount of a specific material in this container.
/datum/component/material_container/proc/get_material_amount(var/datum/material/mat)
if(!istype(mat))
mat = SSmaterials.GetMaterialRef(mat)
return(materials[mat])
+19 -1
View File
@@ -21,6 +21,7 @@
RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event)
RegisterSignal(parent, COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event)
RegisterSignal(parent, COMSIG_MODIFY_SANITY, .proc/modify_sanity)
RegisterSignal(parent, COMSIG_LIVING_REVIVE, .proc/on_revive)
RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud)
var/mob/living/owner = parent
@@ -81,7 +82,8 @@
msg += "<span class='nicegreen'>I don't have much of a reaction to anything right now.<span>\n"
to_chat(user || parent, msg)
/datum/component/mood/proc/update_mood() //Called whenever a mood event is added or removed
///Called after moodevent/s have been added/removed.
/datum/component/mood/proc/update_mood()
mood = 0
shown_mood = 0
for(var/i in mood_events)
@@ -234,6 +236,15 @@
qdel(event)
update_mood()
/datum/component/mood/proc/remove_temp_moods() //Removes all temp moodsfor(var/i in mood_events)
for(var/i in mood_events)
var/datum/mood_event/moodlet = mood_events[i]
if(!moodlet || !moodlet.timeout)
continue
mood_events -= i
qdel(moodlet)
update_mood()
/datum/component/mood/proc/modify_hud(datum/source)
var/mob/living/owner = parent
var/datum/hud/hud = owner.hud_used
@@ -270,5 +281,12 @@
if(0 to NUTRITION_LEVEL_STARVING)
add_event(null, "nutrition", /datum/mood_event/starving)
///Called when parent is ahealed.
/datum/component/mood/proc/on_revive(datum/source, full_heal)
if(!full_heal)
return
remove_temp_moods()
setSanity(initial(sanity))
#undef MINOR_INSANITY_PEN
#undef MAJOR_INSANITY_PEN

Some files were not shown because too many files have changed in this diff Show More