Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into atomwalkers
This commit is contained in:
+67
-33
@@ -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
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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))
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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"
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
))
|
||||
@@ -0,0 +1,3 @@
|
||||
#define SOLAR_TRACK_OFF 0
|
||||
#define SOLAR_TRACK_TIMED 1
|
||||
#define SOLAR_TRACK_AUTO 2
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,\
|
||||
))
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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))
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
)
|
||||
))
|
||||
|
||||
@@ -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)
|
||||
@@ -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?" ))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
@@ -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")
|
||||
@@ -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
|
||||
|
||||
+7
-16
@@ -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
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -59,4 +59,4 @@
|
||||
"<span class='userdanger'>You slide on [A]!</span>")
|
||||
|
||||
cooldown = world.time
|
||||
H.Knockdown(60)
|
||||
H.DefaultCombatKnockdown(60)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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>")
|
||||
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user