mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Documents 61 files (#9306)
* Document the world (#46495) * Document drone verbs.dm * Document the outfit datum with autodoc (#45415) * Uncurse take_damage and document obj_defense.dm (#45146) The original take_damage proc defined vars for no good reason had some duplicate code and wasn't very readable. If you are wondering why it calls obj_break every time it takes damage while below integrity_failure, that's the way it used to be. Most (if not all) stuff that takes advantage of this functionality already accounts for this. * Convert some code docs into the auto doc format (#45101) * Commit Message * Fixes * e * Documents browserOutput.dm (#51439) * Add autodoc to the callback datum (#45463) * Autodoc the vending machine (#45468) * Autodoc the vending machine * Update code/modules/vending/_vending.dm Co-Authored-By: Tad Hardesty <tad@platymuus.com> * autodoc organ helpers (#45464) * timer proc autodocs (#46530) * bunch of define autodocs * ballistic guns autodoc (#45578) * ballistic guns autodoc * fixes * client vars autodoc (#46446) About The Pull Request Autodocs client vars * Autodoc for XB and Research * shuttle docking autodoc (#48677) * Add autodocs for reagents (#49478) * Fix Co-authored-by: oranges <email@oranges.net.nz> Co-authored-by: Jonathan (JJRcop) Rubenstein <jrubcop@gmail.com> Co-authored-by: nemvar <47324920+nemvar@users.noreply.github.com> Co-authored-by: alexkar598 <> Co-authored-by: Tad Hardesty <tad@platymuus.com> Co-authored-by: spookydonut <github@spooksoftware.com> Co-authored-by: actioninja <actioninja@gmail.com>
This commit is contained in:
@@ -91,9 +91,11 @@
|
||||
#define TR_KEEPITEMS (1<<0)
|
||||
#define TR_KEEPVIRUS (1<<1)
|
||||
#define TR_KEEPDAMAGE (1<<2)
|
||||
#define TR_HASHNAME (1<<3) // hashing names (e.g. monkey(e34f)) (only in monkeyize)
|
||||
/// hashing names (e.g. monkey(e34f)) (only in monkeyize)
|
||||
#define TR_HASHNAME (1<<3)
|
||||
#define TR_KEEPIMPLANTS (1<<4)
|
||||
#define TR_KEEPSE (1<<5) // changelings shouldn't edit the DNA's SE when turning into a monkey
|
||||
/// changelings shouldn't edit the DNA's SE when turning into a monkey
|
||||
#define TR_KEEPSE (1<<5)
|
||||
#define TR_DEFAULTMSG (1<<6)
|
||||
#define TR_KEEPORGANS (1<<8)
|
||||
#define TR_KEEPSTUNS (1<<9)
|
||||
@@ -111,18 +113,22 @@
|
||||
#define LIPS 5
|
||||
#define NOBLOOD 6
|
||||
#define NOTRANSSTING 7
|
||||
#define MUTCOLORS_PARTSONLY 8 //Used if we want the mutant colour to be only used by mutant bodyparts. Don't combine this with MUTCOLORS, or it will be useless.
|
||||
/// Used if we want the mutant colour to be only used by mutant bodyparts. Don't combine this with MUTCOLORS, or it will be useless.
|
||||
#define MUTCOLORS_PARTSONLY 8
|
||||
#define NOZOMBIE 9
|
||||
#define DIGITIGRADE 10 //Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi)
|
||||
/// Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi)
|
||||
#define DIGITIGRADE 10
|
||||
#define NO_UNDERWEAR 11
|
||||
#define NOLIVER 12
|
||||
#define NOSTOMACH 13
|
||||
#define NO_DNA_COPY 14
|
||||
#define DRINKSBLOOD 15
|
||||
#define NOFLASH 16
|
||||
#define DYNCOLORS 17 //Use this if you want to change the race's color without the player being able to pick their own color. AKA special color shifting
|
||||
/// Use this if you want to change the race's color without the player being able to pick their own color. AKA special color shifting
|
||||
#define DYNCOLORS 17
|
||||
#define AGENDER 18
|
||||
#define NOEYESPRITES 19 //Do not draw eyes or eyeless overlay
|
||||
/// Do not draw eyes or eyeless overlay
|
||||
#define NOEYESPRITES 19
|
||||
|
||||
//organ slots
|
||||
#define ORGAN_SLOT_BRAIN "brain"
|
||||
@@ -152,7 +158,8 @@
|
||||
//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
|
||||
/// designed to fail organs when left to decay for ~15 minutes
|
||||
#define STANDARD_ORGAN_DECAY 0.00222
|
||||
|
||||
//used for the can_chromosome var on mutations
|
||||
#define CHROMOSOME_NEVER 0
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
//See also controllers/globals.dm
|
||||
|
||||
//Creates a global initializer with a given InitValue expression, do not use
|
||||
/// Creates a global initializer with a given InitValue expression, do not use
|
||||
#define GLOBAL_MANAGED(X, InitValue)\
|
||||
/datum/controller/global_vars/proc/InitGlobal##X(){\
|
||||
##X = ##InitValue;\
|
||||
gvars_datum_init_order += #X;\
|
||||
}
|
||||
//Creates an empty global initializer, do not use
|
||||
/// Creates an empty global initializer, do not use
|
||||
#define GLOBAL_UNMANAGED(X) /datum/controller/global_vars/proc/InitGlobal##X() { return; }
|
||||
|
||||
//Prevents a given global from being VV'd
|
||||
/// Prevents a given global from being VV'd
|
||||
#ifndef TESTING
|
||||
#define GLOBAL_PROTECT(X)\
|
||||
/datum/controller/global_vars/InitGlobal##X(){\
|
||||
@@ -20,41 +20,41 @@
|
||||
#define GLOBAL_PROTECT(X)
|
||||
#endif
|
||||
|
||||
//Standard BYOND global, do not use
|
||||
/// Standard BYOND global, do not use
|
||||
#define GLOBAL_REAL_VAR(X) var/global/##X
|
||||
|
||||
//Standard typed BYOND global, do not use
|
||||
/// Standard typed BYOND global, do not use
|
||||
#define GLOBAL_REAL(X, Typepath) var/global##Typepath/##X
|
||||
|
||||
//Defines a global var on the controller, do not use
|
||||
/// Defines a global var on the controller, do not use
|
||||
#define GLOBAL_RAW(X) /datum/controller/global_vars/var/global##X
|
||||
|
||||
//Create an untyped global with an initializer expression
|
||||
/// Create an untyped global with an initializer expression
|
||||
#define GLOBAL_VAR_INIT(X, InitValue) GLOBAL_RAW(/##X); GLOBAL_MANAGED(X, InitValue)
|
||||
|
||||
//Create a global const var, do not use
|
||||
/// Create a global const var, do not use
|
||||
#define GLOBAL_VAR_CONST(X, InitValue) GLOBAL_RAW(/const/##X) = InitValue; GLOBAL_UNMANAGED(X)
|
||||
|
||||
//Create a list global with an initializer expression
|
||||
/// Create a list global with an initializer expression
|
||||
#define GLOBAL_LIST_INIT(X, InitValue) GLOBAL_RAW(/list/##X); GLOBAL_MANAGED(X, InitValue)
|
||||
|
||||
//Create a list global that is initialized as an empty list
|
||||
/// Create a list global that is initialized as an empty list
|
||||
#define GLOBAL_LIST_EMPTY(X) GLOBAL_LIST_INIT(X, list())
|
||||
|
||||
// Create a typed list global with an initializer expression
|
||||
/// Create a typed list global with an initializer expression
|
||||
#define GLOBAL_LIST_INIT_TYPED(X, Typepath, InitValue) GLOBAL_RAW(/list##Typepath/X); GLOBAL_MANAGED(X, InitValue)
|
||||
|
||||
// Create a typed list global that is initialized as an empty list
|
||||
/// Create a typed list global that is initialized as an empty list
|
||||
#define GLOBAL_LIST_EMPTY_TYPED(X, Typepath) GLOBAL_LIST_INIT_TYPED(X, Typepath, list())
|
||||
|
||||
//Create a typed global with an initializer expression
|
||||
/// Create a typed global with an initializer expression
|
||||
#define GLOBAL_DATUM_INIT(X, Typepath, InitValue) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, InitValue)
|
||||
|
||||
//Create an untyped null global
|
||||
/// Create an untyped null global
|
||||
#define GLOBAL_VAR(X) GLOBAL_RAW(/##X); GLOBAL_UNMANAGED(X)
|
||||
|
||||
//Create a null global list
|
||||
/// Create a null global list
|
||||
#define GLOBAL_LIST(X) GLOBAL_RAW(/list/##X); GLOBAL_UNMANAGED(X)
|
||||
|
||||
//Create an typed null global
|
||||
/// Create an typed null global
|
||||
#define GLOBAL_DATUM(X, Typepath) GLOBAL_RAW(Typepath/##X); GLOBAL_UNMANAGED(X)
|
||||
@@ -1,3 +1,4 @@
|
||||
///Protects a datum from being VV'd
|
||||
#define GENERAL_PROTECT_DATUM(Path)\
|
||||
##Path/can_vv_get(var_name){\
|
||||
return FALSE;\
|
||||
@@ -7,4 +8,4 @@
|
||||
}\
|
||||
##Path/CanProcCall(procname){\
|
||||
return FALSE;\
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
/// Tick limit while running normally
|
||||
#define TICK_LIMIT_RUNNING 80
|
||||
/// Tick limit used to resume things in stoplag
|
||||
#define TICK_LIMIT_TO_RUN 70
|
||||
/// Tick limit for MC while running
|
||||
#define TICK_LIMIT_MC 70
|
||||
/// Tick limit while initializing
|
||||
#define TICK_LIMIT_MC_INIT_DEFAULT 98
|
||||
|
||||
#define TICK_USAGE world.tick_usage //for general usage
|
||||
#define TICK_USAGE_REAL world.tick_usage //to be used where the result isn't checked
|
||||
/// for general usage of tick_usage
|
||||
#define TICK_USAGE world.tick_usage
|
||||
/// to be used where the result isn't checked
|
||||
#define TICK_USAGE_REAL world.tick_usage
|
||||
|
||||
/// Returns true if tick_usage is above the limit
|
||||
#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit )
|
||||
/// runs stoplag if tick_usage is above the limit
|
||||
#define CHECK_TICK ( TICK_CHECK ? stoplag() : 0 )
|
||||
|
||||
/// Returns true if tick usage is above 95, for high priority usage
|
||||
#define TICK_CHECK_HIGH_PRIORITY ( TICK_USAGE > 95 )
|
||||
/// runs stoplag if tick_usage is above 95, for high priority usage
|
||||
#define CHECK_TICK_HIGH_PRIORITY ( TICK_CHECK_HIGH_PRIORITY? stoplag() : 0 )
|
||||
|
||||
@@ -1,21 +1,33 @@
|
||||
#define ACCESS_SECURITY 1 // Security equipment, security records, gulag item storage, secbots
|
||||
#define ACCESS_BRIG 2 // Brig cells+timers, permabrig, gulag+gulag shuttle, prisoner management console
|
||||
#define ACCESS_ARMORY 3 // Armory, gulag teleporter, execution chamber
|
||||
#define ACCESS_FORENSICS_LOCKERS 4 //Detective's office, forensics lockers, security+medical records
|
||||
// Security equipment, security records, gulag item storage, secbots
|
||||
#define ACCESS_SECURITY 1
|
||||
/// Brig cells+timers, permabrig, gulag+gulag shuttle, prisoner management console
|
||||
#define ACCESS_BRIG 2
|
||||
/// Armory, gulag teleporter, execution chamber
|
||||
#define ACCESS_ARMORY 3
|
||||
///Detective's office, forensics lockers, security+medical records
|
||||
#define ACCESS_FORENSICS_LOCKERS 4
|
||||
/// Medical general access
|
||||
#define ACCESS_MEDICAL 5
|
||||
/// Morgue access
|
||||
#define ACCESS_MORGUE 6
|
||||
#define ACCESS_TOX 7 //R&D department, R&D console, burn chamber on some maps
|
||||
#define ACCESS_TOX_STORAGE 8 //Toxins storage, burn chamber on some maps
|
||||
/// R&D department, R&D console, burn chamber on some maps
|
||||
#define ACCESS_TOX 7
|
||||
/// Toxins storage, burn chamber on some maps
|
||||
#define ACCESS_TOX_STORAGE 8
|
||||
/// Genetics access
|
||||
#define ACCESS_GENETICS 9
|
||||
#define ACCESS_ENGINE 10 //Engineering area, power monitor, power flow control console
|
||||
#define ACCESS_ENGINE_EQUIP 11 //APCs, EngiVend/YouTool, engineering equipment lockers
|
||||
/// Engineering area, power monitor, power flow control console
|
||||
#define ACCESS_ENGINE 10
|
||||
///APCs, EngiVend/YouTool, engineering equipment lockers
|
||||
#define ACCESS_ENGINE_EQUIP 11
|
||||
#define ACCESS_MAINT_TUNNELS 12
|
||||
#define ACCESS_EXTERNAL_AIRLOCKS 13
|
||||
#define ACCESS_CHANGE_IDS 15
|
||||
#define ACCESS_AI_UPLOAD 16
|
||||
#define ACCESS_TELEPORTER 17
|
||||
#define ACCESS_EVA 18
|
||||
#define ACCESS_HEADS 19 //Bridge, EVA storage windoors, gateway shutters, AI integrity restorer, clone record deletion, comms console
|
||||
/// Bridge, EVA storage windoors, gateway shutters, AI integrity restorer, clone record deletion, comms console
|
||||
#define ACCESS_HEADS 19
|
||||
#define ACCESS_CAPTAIN 20
|
||||
#define ACCESS_ALL_PERSONAL_LOCKERS 21
|
||||
#define ACCESS_CHAPEL_OFFICE 22
|
||||
@@ -49,47 +61,74 @@
|
||||
#define ACCESS_CE 56
|
||||
#define ACCESS_HOP 57
|
||||
#define ACCESS_HOS 58
|
||||
#define ACCESS_RC_ANNOUNCE 59 //Request console announcements
|
||||
#define ACCESS_KEYCARD_AUTH 60 //Used for events which require at least two people to confirm them
|
||||
#define ACCESS_TCOMSAT 61 // has access to the entire telecomms satellite / machinery
|
||||
/// Request console announcements
|
||||
#define ACCESS_RC_ANNOUNCE 59
|
||||
/// Used for events which require at least two people to confirm them
|
||||
#define ACCESS_KEYCARD_AUTH 60
|
||||
/// has access to the entire telecomms satellite / machinery
|
||||
#define ACCESS_TCOMSAT 61
|
||||
#define ACCESS_GATEWAY 62
|
||||
#define ACCESS_SEC_DOORS 63 // Outer brig doors, department security posts
|
||||
#define ACCESS_MINERAL_STOREROOM 64 //For releasing minerals from the ORM
|
||||
/// Outer brig doors, department security posts
|
||||
#define ACCESS_SEC_DOORS 63
|
||||
/// For releasing minerals from the ORM
|
||||
#define ACCESS_MINERAL_STOREROOM 64
|
||||
#define ACCESS_MINISAT 65
|
||||
#define ACCESS_WEAPONS 66 //Weapon authorization for secbots
|
||||
#define ACCESS_NETWORK 67 //NTnet diagnostics/monitoring software
|
||||
#define ACCESS_CLONING 68 //Cloning room and clone pod ejection
|
||||
#define ACCESS_PARAMEDIC 69 //Paramedic Office
|
||||
#define ACCESS_TCOM_ADMIN 70 // Access to the Signal Tech monitoring room
|
||||
/// Weapon authorization for secbots
|
||||
#define ACCESS_WEAPONS 66
|
||||
/// NTnet diagnostics/monitoring software
|
||||
#define ACCESS_NETWORK 67
|
||||
///Cloning room and clone pod ejection
|
||||
#define ACCESS_CLONING 68
|
||||
///Paramedic Office
|
||||
#define ACCESS_PARAMEDIC 69
|
||||
///Access to the Signal Tech monitoring room
|
||||
#define ACCESS_TCOM_ADMIN 70
|
||||
#define ACCESS_FREEMINER 71
|
||||
#define ACCESS_FREEMINER_CAPTAIN 72
|
||||
|
||||
//BEGIN CENTCOM ACCESS
|
||||
/*Should leave plenty of room if we need to add more access levels.
|
||||
Mostly for admin fun times.*/
|
||||
#define ACCESS_CENT_GENERAL 101//General facilities. CentCom ferry.
|
||||
#define ACCESS_CENT_THUNDER 102//Thunderdome.
|
||||
#define ACCESS_CENT_SPECOPS 103//Special Ops. Captain's display case, Marauder and Seraph mechs.
|
||||
#define ACCESS_CENT_MEDICAL 104//Medical/Research
|
||||
#define ACCESS_CENT_LIVING 105//Living quarters.
|
||||
#define ACCESS_CENT_STORAGE 106//Generic storage areas.
|
||||
#define ACCESS_CENT_TELEPORTER 107//Teleporter.
|
||||
#define ACCESS_CENT_CAPTAIN 109//Captain's office/ID comp/AI.
|
||||
#define ACCESS_CENT_BAR 110 // The non-existent CentCom Bar
|
||||
/// General facilities. CentCom ferry.
|
||||
#define ACCESS_CENT_GENERAL 101
|
||||
/// Thunderdome.
|
||||
#define ACCESS_CENT_THUNDER 102
|
||||
/// Special Ops. Captain's display case, Marauder and Seraph mechs.
|
||||
#define ACCESS_CENT_SPECOPS 103
|
||||
/// Medical/Research
|
||||
#define ACCESS_CENT_MEDICAL 104
|
||||
/// Living quarters.
|
||||
#define ACCESS_CENT_LIVING 105
|
||||
/// Generic storage areas.
|
||||
#define ACCESS_CENT_STORAGE 106
|
||||
/// Teleporter.
|
||||
#define ACCESS_CENT_TELEPORTER 107
|
||||
/// Captain's office/ID comp/AI.
|
||||
#define ACCESS_CENT_CAPTAIN 109
|
||||
/// The non-existent CentCom Bar
|
||||
#define ACCESS_CENT_BAR 110
|
||||
|
||||
//The Syndicate
|
||||
#define ACCESS_SYNDICATE 150//General Syndicate Access. Includes Syndicate mechs and ruins.
|
||||
#define ACCESS_SYNDICATE_LEADER 151//Nuke Op Leader Access
|
||||
/// General Syndicate Access. Includes Syndicate mechs and ruins.
|
||||
#define ACCESS_SYNDICATE 150
|
||||
/// Nuke Op Leader Access
|
||||
#define ACCESS_SYNDICATE_LEADER 151
|
||||
|
||||
//Away Missions or Ruins
|
||||
/*For generic away-mission/ruin access. Why would normal crew have access to a long-abandoned derelict
|
||||
or a 2000 year-old temple? */
|
||||
#define ACCESS_AWAY_GENERAL 200//General facilities.
|
||||
#define ACCESS_AWAY_MAINT 201//Away maintenance
|
||||
#define ACCESS_AWAY_MED 202//Away medical
|
||||
#define ACCESS_AWAY_SEC 203//Away security
|
||||
#define ACCESS_AWAY_ENGINE 204//Away engineering
|
||||
#define ACCESS_AWAY_GENERIC1 205//Away generic access
|
||||
/// Away general facilities.
|
||||
#define ACCESS_AWAY_GENERAL 200
|
||||
/// Away maintenance
|
||||
#define ACCESS_AWAY_MAINT 201
|
||||
/// Away medical
|
||||
#define ACCESS_AWAY_MED 202
|
||||
/// Away security
|
||||
#define ACCESS_AWAY_SEC 203
|
||||
/// Away engineering
|
||||
#define ACCESS_AWAY_ENGINE 204
|
||||
///Away generic access
|
||||
#define ACCESS_AWAY_GENERIC1 205
|
||||
#define ACCESS_AWAY_GENERIC2 206
|
||||
#define ACCESS_AWAY_GENERIC3 207
|
||||
#define ACCESS_AWAY_GENERIC4 208
|
||||
|
||||
@@ -13,11 +13,13 @@
|
||||
#define BANTYPE_TEMP 2
|
||||
#define BANTYPE_JOB_PERMA 3
|
||||
#define BANTYPE_JOB_TEMP 4
|
||||
#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban.
|
||||
/// used to locate stuff to unban.
|
||||
#define BANTYPE_ANY_FULLBAN 5
|
||||
|
||||
#define BANTYPE_ADMIN_PERMA 7
|
||||
#define BANTYPE_ADMIN_TEMP 8
|
||||
#define BANTYPE_ANY_JOB 9 //used to remove jobbans
|
||||
/// used to remove jobbans
|
||||
#define BANTYPE_ANY_JOB 9
|
||||
|
||||
//Admin Permissions
|
||||
#define R_BUILDMODE (1<<0)
|
||||
@@ -78,14 +80,19 @@
|
||||
#define AHELP_CLOSED 2
|
||||
#define AHELP_RESOLVED 3
|
||||
|
||||
#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued.
|
||||
/// Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued.
|
||||
#define ROUNDSTART_LOGOUT_REPORT_TIME 6000
|
||||
|
||||
#define SPAM_TRIGGER_WARNING 5 //Number of identical messages required before the spam-prevention will warn you to stfu
|
||||
#define SPAM_TRIGGER_AUTOMUTE 10 //Number of identical messages required before the spam-prevention will automute you
|
||||
/// Number of identical messages required before the spam-prevention will warn you to stfu
|
||||
#define SPAM_TRIGGER_WARNING 5
|
||||
/// Number of identical messages required before the spam-prevention will automute you
|
||||
#define SPAM_TRIGGER_AUTOMUTE 10
|
||||
|
||||
#define STICKYBAN_DB_CACHE_TIME 10 SECONDS
|
||||
#define STICKYBAN_ROGUE_CHECK_TIME 5
|
||||
|
||||
|
||||
#define POLICY_POLYMORPH "polymorph" //Shown to vicitm of staff of change and related effects.
|
||||
#define POLICY_VERB_HEADER "policy_verb_header" //Shown on top of policy verb window
|
||||
/// Shown to vicitm of staff of change and related effects.
|
||||
#define POLICY_POLYMORPH "polymorph"
|
||||
/// Shown on top of policy verb window
|
||||
#define POLICY_VERB_HEADER "policy_verb_header"
|
||||
@@ -26,10 +26,12 @@
|
||||
|
||||
|
||||
//Blob
|
||||
#define BLOB_REROLL_TIME 2400 //blob gets a free reroll every X time
|
||||
/// blob gets a free reroll every X time
|
||||
#define BLOB_REROLL_TIME 2400
|
||||
#define BLOB_SPREAD_COST 4
|
||||
#define BLOB_ATTACK_REFUND 2 //blob refunds this much if it attacks and doesn't spread
|
||||
#define BLOB_REFLECTOR_COST 0 //yogs - reflectors are free
|
||||
/// blob refunds this much if it attacks and doesn't spread
|
||||
#define BLOB_ATTACK_REFUND 2
|
||||
#define BLOB_REFLECTOR_COST 15
|
||||
|
||||
|
||||
//ERT Types
|
||||
@@ -47,11 +49,14 @@
|
||||
#define DEATHSQUAD_LEADER "ds_leader"
|
||||
|
||||
//Shuttle hijacking
|
||||
#define HIJACK_NEUTRAL 0 //Does not stop hijacking but itself won't hijack
|
||||
#define HIJACK_HIJACKER 1 //Needs to be present for shuttle to be hijacked
|
||||
#define HIJACK_PREVENT 2 //Prevents hijacking same way as non-antags
|
||||
/// Does not stop hijacking but itself won't hijack
|
||||
#define HIJACK_NEUTRAL 0
|
||||
/// Needs to be present for shuttle to be hijacked
|
||||
#define HIJACK_HIJACKER 1
|
||||
/// Prevents hijacking same way as non-antags
|
||||
#define HIJACK_PREVENT 2
|
||||
|
||||
//Overthrow time to update heads obj
|
||||
///Overthrow time to update heads obj
|
||||
#define OBJECTIVE_UPDATING_TIME 300
|
||||
|
||||
//Assimilation
|
||||
|
||||
@@ -12,33 +12,57 @@
|
||||
#define META_GAS_FUSION_POWER 7
|
||||
//ATMOS
|
||||
//stuff you should probably leave well alone!
|
||||
#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol)
|
||||
#define ONE_ATMOSPHERE 101.325 //kPa
|
||||
#define TCMB 2.7 // -270.3degC
|
||||
#define TCRYO 225 // -48.15degC
|
||||
#define T0C 273.15 // 0degC
|
||||
#define T20C 293.15 // 20degC
|
||||
/// kPa*L/(K*mol)
|
||||
#define R_IDEAL_GAS_EQUATION 8.31
|
||||
/// kPa
|
||||
#define ONE_ATMOSPHERE 101.325
|
||||
/// -270.3degC
|
||||
#define TCMB 2.7
|
||||
/// -48.15degC
|
||||
#define TCRYO 225
|
||||
/// 0degC
|
||||
#define T0C 273.15
|
||||
/// 20degC
|
||||
#define T20C 293.15
|
||||
|
||||
#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) //moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC
|
||||
#define M_CELL_WITH_RATIO (MOLES_CELLSTANDARD * 0.005) //compared against for superconductivity
|
||||
#define O2STANDARD 0.21 //percentage of oxygen in a normal mixture of air
|
||||
#define N2STANDARD 0.79 //same but for nitrogen
|
||||
#define MOLES_O2STANDARD (MOLES_CELLSTANDARD*O2STANDARD) // O2 standard value (21%)
|
||||
#define MOLES_N2STANDARD (MOLES_CELLSTANDARD*N2STANDARD) // N2 standard value (79%)
|
||||
#define CELL_VOLUME 2500 //liters in a cell
|
||||
#define BREATH_VOLUME 0.5 //liters in a normal breath
|
||||
#define BREATH_PERCENTAGE (BREATH_VOLUME/CELL_VOLUME) //Amount of air to take a from a tile
|
||||
///moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC
|
||||
#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION))
|
||||
///compared against for superconductivity
|
||||
#define M_CELL_WITH_RATIO (MOLES_CELLSTANDARD * 0.005)
|
||||
/// percentage of oxygen in a normal mixture of air
|
||||
#define O2STANDARD 0.21
|
||||
/// same but for nitrogen
|
||||
#define N2STANDARD 0.79
|
||||
/// O2 standard value (21%)
|
||||
#define MOLES_O2STANDARD (MOLES_CELLSTANDARD*O2STANDARD)
|
||||
/// N2 standard value (79%)
|
||||
#define MOLES_N2STANDARD (MOLES_CELLSTANDARD*N2STANDARD)
|
||||
/// liters in a cell
|
||||
#define CELL_VOLUME 2500
|
||||
/// liters in a normal breath
|
||||
#define BREATH_VOLUME 0.5
|
||||
/// Amount of air to take a from a tile
|
||||
#define BREATH_PERCENTAGE (BREATH_VOLUME/CELL_VOLUME)
|
||||
|
||||
//EXCITED GROUPS
|
||||
#define EXCITED_GROUP_BREAKDOWN_CYCLES 4 //number of FULL air controller ticks before an excited group breaks down (averages gas contents across turfs)
|
||||
#define EXCITED_GROUP_DISMANTLE_CYCLES 16 //number of FULL air controller ticks before an excited group dismantles and removes its turfs from active
|
||||
#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.1 //Ratio of air that must move to/from a tile to reset group processing
|
||||
#define MINIMUM_AIR_RATIO_TO_MOVE 0.001 //Minimum ratio of air that must move to/from a tile
|
||||
#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND) //Minimum amount of air that has to move before a group processing can be suspended
|
||||
#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_MOVE) //Either this must be active
|
||||
#define MINIMUM_TEMPERATURE_TO_MOVE (T20C+100) //or this (or both, obviously)
|
||||
#define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4 //Minimum temperature difference before group processing is suspended
|
||||
#define MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER 0.5 //Minimum temperature difference before the gas temperatures are just set to be equal
|
||||
/// number of FULL air controller ticks before an excited group breaks down (averages gas contents across turfs)
|
||||
#define EXCITED_GROUP_BREAKDOWN_CYCLES 4
|
||||
/// number of FULL air controller ticks before an excited group dismantles and removes its turfs from active
|
||||
#define EXCITED_GROUP_DISMANTLE_CYCLES 16
|
||||
/// Ratio of air that must move to/from a tile to reset group processing
|
||||
#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.1
|
||||
/// Minimum ratio of air that must move to/from a tile
|
||||
#define MINIMUM_AIR_RATIO_TO_MOVE 0.001
|
||||
/// Minimum amount of air that has to move before a group processing can be suspended
|
||||
#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND)
|
||||
/// Either this must be active
|
||||
#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_MOVE)
|
||||
/// or this (or both, obviously)
|
||||
#define MINIMUM_TEMPERATURE_TO_MOVE (T20C+100)
|
||||
/// Minimum temperature difference before group processing is suspended
|
||||
#define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4
|
||||
/// Minimum temperature difference before the gas temperatures are just set to be equal
|
||||
#define MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER 0.5
|
||||
#define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION (T20C+10)
|
||||
#define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION (T20C+200)
|
||||
|
||||
@@ -47,8 +71,10 @@
|
||||
//Should not exceed 0.4 else strange heat flow occur
|
||||
#define WALL_HEAT_TRANSFER_COEFFICIENT 0.0
|
||||
#define OPEN_HEAT_TRANSFER_COEFFICIENT 0.4
|
||||
#define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.1 //a hack for now
|
||||
#define HEAT_CAPACITY_VACUUM 7000 //a hack to help make vacuums "cold", sacrificing realism for gameplay
|
||||
/// a hack for now
|
||||
#define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.1
|
||||
/// a hack to help make vacuums "cold", sacrificing realism for gameplay
|
||||
#define HEAT_CAPACITY_VACUUM 7000
|
||||
|
||||
//FIRE
|
||||
#define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD (150+T0C)
|
||||
@@ -62,10 +88,13 @@
|
||||
//GASES
|
||||
#define MIN_TOXIC_GAS_DAMAGE 1
|
||||
#define MAX_TOXIC_GAS_DAMAGE 10
|
||||
#define MOLES_GAS_VISIBLE 0.25 //Moles in a standard cell after which gases are visible
|
||||
/// Moles in a standard cell after which gases are visible
|
||||
#define MOLES_GAS_VISIBLE 0.25
|
||||
|
||||
#define FACTOR_GAS_VISIBLE_MAX 20 //moles_visible * FACTOR_GAS_VISIBLE_MAX = Moles after which gas is at maximum visibility
|
||||
#define MOLES_GAS_VISIBLE_STEP 0.25 //Mole step for alpha updates. This means alpha can update at 0.25, 0.5, 0.75 and so on
|
||||
/// moles_visible * FACTOR_GAS_VISIBLE_MAX = Moles after which gas is at maximum visibility
|
||||
#define FACTOR_GAS_VISIBLE_MAX 20
|
||||
/// Mole step for alpha updates. This means alpha can update at 0.25, 0.5, 0.75 and so on
|
||||
#define MOLES_GAS_VISIBLE_STEP 0.25
|
||||
|
||||
//REACTIONS
|
||||
//return values for reactions (bitflags)
|
||||
@@ -74,58 +103,94 @@
|
||||
#define STOP_REACTIONS 2
|
||||
|
||||
// Pressure limits.
|
||||
#define HAZARD_HIGH_PRESSURE 550 //This determins at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant)
|
||||
#define WARNING_HIGH_PRESSURE 325 //This determins when the orange pressure icon is displayed (it is 0.7 * HAZARD_HIGH_PRESSURE)
|
||||
#define WARNING_LOW_PRESSURE 50 //This is when the gray low pressure icon is displayed. (it is 2.5 * HAZARD_LOW_PRESSURE)
|
||||
#define HAZARD_LOW_PRESSURE 20 //This is when the black ultra-low pressure icon is displayed. (This one is set as a constant)
|
||||
/// This determins at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant)
|
||||
#define HAZARD_HIGH_PRESSURE 550
|
||||
/// This determins when the orange pressure icon is displayed (it is 0.7 * HAZARD_HIGH_PRESSURE)
|
||||
#define WARNING_HIGH_PRESSURE 325
|
||||
/// This is when the gray low pressure icon is displayed. (it is 2.5 * HAZARD_LOW_PRESSURE)
|
||||
#define WARNING_LOW_PRESSURE 50
|
||||
/// This is when the black ultra-low pressure icon is displayed. (This one is set as a constant)
|
||||
#define HAZARD_LOW_PRESSURE 20
|
||||
|
||||
#define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 //This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount.
|
||||
/// This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount.
|
||||
#define TEMPERATURE_DAMAGE_COEFFICIENT 1.5
|
||||
|
||||
#define BODYTEMP_NORMAL 310.15 //The natural temperature for a body
|
||||
#define BODYTEMP_AUTORECOVERY_DIVISOR 11 //This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive.
|
||||
#define BODYTEMP_AUTORECOVERY_MINIMUM 12 //Minimum amount of kelvin moved toward 310K per tick. So long as abs(310.15 - bodytemp) is more than 50.
|
||||
#define BODYTEMP_COLD_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster.
|
||||
#define BODYTEMP_HEAT_DIVISOR 15 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster.
|
||||
#define BODYTEMP_COOLING_MAX -100 //The maximum number of degrees that your body can cool in 1 tick, due to the environment, when in a cold area.
|
||||
#define BODYTEMP_HEATING_MAX 30 //The maximum number of degrees that your body can heat up in 1 tick, due to the environment, when in a hot area.
|
||||
/// The natural temperature for a body
|
||||
#define BODYTEMP_NORMAL 310.15
|
||||
/// This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive.
|
||||
#define BODYTEMP_AUTORECOVERY_DIVISOR 11
|
||||
/// Minimum amount of kelvin moved toward 310K per tick. So long as abs(310.15 - bodytemp) is more than 50.
|
||||
#define BODYTEMP_AUTORECOVERY_MINIMUM 12
|
||||
///Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster.
|
||||
#define BODYTEMP_COLD_DIVISOR 6
|
||||
/// Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster.
|
||||
#define BODYTEMP_HEAT_DIVISOR 15
|
||||
/// The maximum number of degrees that your body can cool in 1 tick, due to the environment, when in a cold area.
|
||||
#define BODYTEMP_COOLING_MAX -100
|
||||
/// The maximum number of degrees that your body can heat up in 1 tick, due to the environment, when in a hot area.
|
||||
#define BODYTEMP_HEATING_MAX 30
|
||||
|
||||
#define BODYTEMP_HEAT_DAMAGE_LIMIT (BODYTEMP_NORMAL + 50) // The limit the human body can take before it starts taking damage from heat.
|
||||
#define BODYTEMP_COLD_DAMAGE_LIMIT (BODYTEMP_NORMAL - 50) // The limit the human body can take before it starts taking damage from coldness.
|
||||
/// The limit the human body can take before it starts taking damage from heat.
|
||||
#define BODYTEMP_HEAT_DAMAGE_LIMIT (BODYTEMP_NORMAL + 50)
|
||||
/// The limit the human body can take before it starts taking damage from coldness.
|
||||
#define BODYTEMP_COLD_DAMAGE_LIMIT (BODYTEMP_NORMAL - 50)
|
||||
|
||||
|
||||
#define SPACE_HELM_MIN_TEMP_PROTECT 2.0 //what min_cold_protection_temperature is set to for space-helmet quality headwear. MUST NOT BE 0.
|
||||
#define SPACE_HELM_MAX_TEMP_PROTECT 1500 //Thermal insulation works both ways /Malkevin
|
||||
#define SPACE_SUIT_MIN_TEMP_PROTECT 2.0 //what min_cold_protection_temperature is set to for space-suit quality jumpsuits or suits. MUST NOT BE 0.
|
||||
/// what min_cold_protection_temperature is set to for space-helmet quality headwear. MUST NOT BE 0.
|
||||
#define SPACE_HELM_MIN_TEMP_PROTECT 2.0
|
||||
/// Thermal insulation works both ways /Malkevin
|
||||
#define SPACE_HELM_MAX_TEMP_PROTECT 1500
|
||||
/// what min_cold_protection_temperature is set to for space-suit quality jumpsuits or suits. MUST NOT BE 0.
|
||||
#define SPACE_SUIT_MIN_TEMP_PROTECT 2.0
|
||||
#define SPACE_SUIT_MAX_TEMP_PROTECT 1500
|
||||
|
||||
#define FIRE_SUIT_MIN_TEMP_PROTECT 60 //Cold protection for firesuits
|
||||
#define FIRE_SUIT_MAX_TEMP_PROTECT 30000 //what max_heat_protection_temperature is set to for firesuit quality suits. MUST NOT BE 0.
|
||||
#define FIRE_HELM_MIN_TEMP_PROTECT 60 //Cold protection for fire helmets
|
||||
#define FIRE_HELM_MAX_TEMP_PROTECT 30000 //for fire helmet quality items (red and white hardhats)
|
||||
/// Cold protection for firesuits
|
||||
#define FIRE_SUIT_MIN_TEMP_PROTECT 60
|
||||
/// what max_heat_protection_temperature is set to for firesuit quality suits. MUST NOT BE 0.
|
||||
#define FIRE_SUIT_MAX_TEMP_PROTECT 30000
|
||||
/// Cold protection for fire helmets
|
||||
#define FIRE_HELM_MIN_TEMP_PROTECT 60
|
||||
/// for fire helmet quality items (red and white hardhats)
|
||||
#define FIRE_HELM_MAX_TEMP_PROTECT 30000
|
||||
|
||||
#define FIRE_IMMUNITY_MAX_TEMP_PROTECT 35000 //what max_heat_protection_temperature is set to for firesuit quality suits and helmets. MUST NOT BE 0.
|
||||
/// what max_heat_protection_temperature is set to for firesuit quality suits and helmets. MUST NOT BE 0.
|
||||
#define FIRE_IMMUNITY_MAX_TEMP_PROTECT 35000
|
||||
|
||||
#define HELMET_MIN_TEMP_PROTECT 160 //For normal helmets
|
||||
#define HELMET_MAX_TEMP_PROTECT 600 //For normal helmets
|
||||
#define ARMOR_MIN_TEMP_PROTECT 160 //For armor
|
||||
#define ARMOR_MAX_TEMP_PROTECT 600 //For armor
|
||||
/// For normal helmets
|
||||
#define HELMET_MIN_TEMP_PROTECT 160
|
||||
/// For normal helmets
|
||||
#define HELMET_MAX_TEMP_PROTECT 600
|
||||
/// For armor
|
||||
#define ARMOR_MIN_TEMP_PROTECT 160
|
||||
/// For armor
|
||||
#define ARMOR_MAX_TEMP_PROTECT 600
|
||||
|
||||
#define GLOVES_MIN_TEMP_PROTECT 2.0 //For some gloves (black and)
|
||||
#define GLOVES_MAX_TEMP_PROTECT 1500 //For some gloves
|
||||
#define SHOES_MIN_TEMP_PROTECT 2.0 //For gloves
|
||||
#define SHOES_MAX_TEMP_PROTECT 1500 //For gloves
|
||||
/// For some gloves (black and)
|
||||
#define GLOVES_MIN_TEMP_PROTECT 2.0
|
||||
/// For some gloves
|
||||
#define GLOVES_MAX_TEMP_PROTECT 1500
|
||||
/// For gloves
|
||||
#define SHOES_MIN_TEMP_PROTECT 2.0
|
||||
/// For gloves
|
||||
#define SHOES_MAX_TEMP_PROTECT 1500
|
||||
|
||||
#define PRESSURE_DAMAGE_COEFFICIENT 4 //The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE
|
||||
/// The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE
|
||||
#define PRESSURE_DAMAGE_COEFFICIENT 4
|
||||
#define MAX_HIGH_PRESSURE_DAMAGE 4
|
||||
#define LOW_PRESSURE_DAMAGE 4 //The amount of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value).
|
||||
/// The amount of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value).
|
||||
#define LOW_PRESSURE_DAMAGE 4
|
||||
|
||||
#define COLD_SLOWDOWN_FACTOR 20 //Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this
|
||||
/// Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this
|
||||
#define COLD_SLOWDOWN_FACTOR 20
|
||||
|
||||
//PIPES
|
||||
//Atmos pipe limits
|
||||
#define MAX_OUTPUT_PRESSURE 4500 // (kPa) What pressure pumps and powered equipment max out at.
|
||||
#define MAX_TRANSFER_RATE 200 // (L/s) Maximum speed powered equipment can work at.
|
||||
#define VOLUME_PUMP_LEAK_AMOUNT 0.1 //10% of an overclocked volume pump leaks into the air
|
||||
/// (kPa) What pressure pumps and powered equipment max out at.
|
||||
#define MAX_OUTPUT_PRESSURE 4500
|
||||
/// (L/s) Maximum speed powered equipment can work at.
|
||||
#define MAX_TRANSFER_RATE 200
|
||||
/// 10% of an overclocked volume pump leaks into the air
|
||||
#define VOLUME_PUMP_LEAK_AMOUNT 0.1
|
||||
//used for device_type vars
|
||||
#define UNARY 1
|
||||
#define BINARY 2
|
||||
@@ -133,11 +198,16 @@
|
||||
#define QUATERNARY 4
|
||||
|
||||
//TANKS
|
||||
#define TANK_MELT_TEMPERATURE 1000000 //temperature in kelvins at which a tank will start to melt
|
||||
#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) //Tank starts leaking
|
||||
#define TANK_RUPTURE_PRESSURE (35.*ONE_ATMOSPHERE) //Tank spills all contents into atmosphere
|
||||
#define TANK_FRAGMENT_PRESSURE (40.*ONE_ATMOSPHERE) //Boom 3x3 base explosion
|
||||
#define TANK_FRAGMENT_SCALE (6.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold
|
||||
/// temperature in kelvins at which a tank will start to melt
|
||||
#define TANK_MELT_TEMPERATURE 1000000
|
||||
/// Tank starts leaking
|
||||
#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE)
|
||||
/// Tank spills all contents into atmosphere
|
||||
#define TANK_RUPTURE_PRESSURE (35.*ONE_ATMOSPHERE)
|
||||
/// Boom 3x3 base explosion
|
||||
#define TANK_FRAGMENT_PRESSURE (40.*ONE_ATMOSPHERE)
|
||||
/// +1 for each SCALE kPa aboe threshold
|
||||
#define TANK_FRAGMENT_SCALE (6.*ONE_ATMOSPHERE)
|
||||
#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3)
|
||||
#define TANK_MIN_RELEASE_PRESSURE 0
|
||||
#define TANK_DEFAULT_RELEASE_PRESSURE 17
|
||||
@@ -145,19 +215,27 @@
|
||||
//CANATMOSPASS
|
||||
#define ATMOS_PASS_YES 1
|
||||
#define ATMOS_PASS_NO 0
|
||||
#define ATMOS_PASS_PROC -1 //ask CanAtmosPass()
|
||||
#define ATMOS_PASS_DENSITY -2 //just check density
|
||||
/// ask CanAtmosPass()
|
||||
#define ATMOS_PASS_PROC -1
|
||||
/// just check density
|
||||
#define ATMOS_PASS_DENSITY -2
|
||||
|
||||
#define CANATMOSPASS(A, O) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) )
|
||||
#define CANVERTICALATMOSPASS(A, O) ( A.CanAtmosPassVertical == ATMOS_PASS_PROC ? A.CanAtmosPass(O, TRUE) : ( A.CanAtmosPassVertical == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPassVertical ) )
|
||||
|
||||
//OPEN TURF ATMOS
|
||||
#define OPENTURF_DEFAULT_ATMOS "o2=22;n2=82;TEMP=293.15" //the default air mix that open turfs spawn
|
||||
#define TCOMMS_ATMOS "n2=100;TEMP=80" //-193,15°C telecommunications. also used for xenobiology slime killrooms
|
||||
#define AIRLESS_ATMOS "TEMP=2.7" //space
|
||||
#define FROZEN_ATMOS "o2=22;n2=82;TEMP=180" //-93.15°C snow and ice turfs
|
||||
#define KITCHEN_COLDROOM_ATMOS "o2=33;n2=124;TEMP=193.15" //-80°C kitchen coldroom; higher amount of mol to reach about 101.3 kpA
|
||||
#define BURNMIX_ATMOS "o2=100;plasma=200;TEMP=370" //used in the holodeck burn test program
|
||||
/// the default air mix that open turfs spawn
|
||||
#define OPENTURF_DEFAULT_ATMOS "o2=22;n2=82;TEMP=293.15"
|
||||
/// -193,15°C telecommunications. also used for xenobiology slime killrooms
|
||||
#define TCOMMS_ATMOS "n2=100;TEMP=80"
|
||||
/// space
|
||||
#define AIRLESS_ATMOS "TEMP=2.7"
|
||||
/// -93.15°C snow and ice turfs
|
||||
#define FROZEN_ATMOS "o2=22;n2=82;TEMP=180"
|
||||
/// -80°C kitchen coldroom; higher amount of mol to reach about 101.3 kpA
|
||||
#define KITCHEN_COLDROOM_ATMOS "o2=33;n2=124;TEMP=193.15"
|
||||
/// used in the holodeck burn test program
|
||||
#define BURNMIX_ATMOS "o2=2500;plasma=5000;TEMP=370"
|
||||
|
||||
//ATMOSPHERICS DEPARTMENT GAS TANK TURFS
|
||||
#define ATMOS_TANK_N2O "n2o=6000;TEMP=293.15"
|
||||
@@ -168,7 +246,8 @@
|
||||
#define ATMOS_TANK_AIRMIX "o2=2644;n2=10580;TEMP=293.15"
|
||||
|
||||
//LAVALAND
|
||||
#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
|
||||
/// what pressure you have to be under to increase the effect of equipment meant for lavaland
|
||||
#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50
|
||||
|
||||
//PLANETARY ATMOS MIXES
|
||||
#define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300"
|
||||
@@ -257,10 +336,14 @@
|
||||
#define PIPING_LAYER_P_Y 5
|
||||
#define PIPING_LAYER_LCHANGE 0.05
|
||||
|
||||
#define PIPING_ALL_LAYER (1<<0) //intended to connect with all layers, check for all instead of just one.
|
||||
#define PIPING_ONE_PER_TURF (1<<1) //can only be built if nothing else with this flag is on the tile already.
|
||||
#define PIPING_DEFAULT_LAYER_ONLY (1<<2) //can only exist at PIPING_LAYER_DEFAULT
|
||||
#define PIPING_CARDINAL_AUTONORMALIZE (1<<3) //north/south east/west doesn't matter, auto normalize on build.
|
||||
/// intended to connect with all layers, check for all instead of just one.
|
||||
#define PIPING_ALL_LAYER (1<<0)
|
||||
/// can only be built if nothing else with this flag is on the tile already.
|
||||
#define PIPING_ONE_PER_TURF (1<<1)
|
||||
/// can only exist at PIPING_LAYER_DEFAULT
|
||||
#define PIPING_DEFAULT_LAYER_ONLY (1<<2)
|
||||
/// north/south east/west doesn't matter, auto normalize on build.
|
||||
#define PIPING_CARDINAL_AUTONORMALIZE (1<<3)
|
||||
|
||||
//HELPERS
|
||||
#define PIPING_LAYER_SHIFT(T, PipingLayer) \
|
||||
|
||||
@@ -2,28 +2,46 @@
|
||||
// note: if you add more HUDs, even for non-human atoms, make sure to use unique numbers for the defines!
|
||||
// /datum/atom_hud expects these to be unique
|
||||
// these need to be strings in order to make them associative lists
|
||||
#define HEALTH_HUD "1" // dead, alive, sick, health status
|
||||
#define STATUS_HUD "2" // a simple line rounding the mob's number health
|
||||
#define ID_HUD "3" // the job asigned to your ID
|
||||
#define WANTED_HUD "4" // wanted, released, parroled, security status
|
||||
#define IMPLOYAL_HUD "5" // loyality implant
|
||||
#define IMPCHEM_HUD "6" // chemical implant
|
||||
#define IMPTRACK_HUD "7" // tracking implant
|
||||
#define DIAG_STAT_HUD "8" // Silicon/Mech/Circuit Status
|
||||
#define DIAG_HUD "9" // Silicon health bar
|
||||
#define DIAG_BATT_HUD "10"// Borg/Mech/Circutry power meter
|
||||
#define DIAG_MECH_HUD "11"// Mech health bar
|
||||
#define DIAG_BOT_HUD "12"// Bot HUDs
|
||||
#define DIAG_CIRCUIT_HUD "13"// Circuit assembly health bar
|
||||
#define DIAG_TRACK_HUD "14"// Mech/Silicon tracking beacon, Circutry long range icon
|
||||
#define DIAG_AIRLOCK_HUD "15"//Airlock shock overlay
|
||||
#define DIAG_PATH_HUD "16"//Bot path indicators
|
||||
#define GLAND_HUD "17"//Gland indicators for abductors
|
||||
/// dead, alive, sick, health status
|
||||
#define HEALTH_HUD "1"
|
||||
/// a simple line rounding the mob's number health
|
||||
#define STATUS_HUD "2"
|
||||
/// the job asigned to your ID
|
||||
#define ID_HUD "3"
|
||||
/// wanted, released, parroled, security status
|
||||
#define WANTED_HUD "4"
|
||||
/// loyality implant
|
||||
#define IMPLOYAL_HUD "5"
|
||||
/// chemical implant
|
||||
#define IMPCHEM_HUD "6"
|
||||
/// tracking implant
|
||||
#define IMPTRACK_HUD "7"
|
||||
/// Silicon/Mech/Circuit Status
|
||||
#define DIAG_STAT_HUD "8"
|
||||
/// Silicon health bar
|
||||
#define DIAG_HUD "9"
|
||||
/// Borg/Mech/Circutry power meter
|
||||
#define DIAG_BATT_HUD "10"
|
||||
/// Mech health bar
|
||||
#define DIAG_MECH_HUD "11"
|
||||
/// Bot HUDs
|
||||
#define DIAG_BOT_HUD "12"
|
||||
/// Circuit assembly health bar
|
||||
#define DIAG_CIRCUIT_HUD "13"
|
||||
/// Mech/Silicon tracking beacon, Circutry long range icon
|
||||
#define DIAG_TRACK_HUD "14"
|
||||
/// Airlock shock overlay
|
||||
#define DIAG_AIRLOCK_HUD "15"
|
||||
/// Bot path indicators
|
||||
#define DIAG_PATH_HUD "16"
|
||||
/// Gland indicators for abductors
|
||||
#define GLAND_HUD "17"
|
||||
#define SENTIENT_DISEASE_HUD "18"
|
||||
#define AI_DETECT_HUD "19"
|
||||
#define NANITE_HUD "20"
|
||||
#define DIAG_NANITE_FULL_HUD "21"
|
||||
#define DIAG_LAUNCHPAD_HUD "22" //Displays launchpads' targeting reticle
|
||||
/// Displays launchpads' targeting reticle
|
||||
#define DIAG_LAUNCHPAD_HUD "22"
|
||||
//for antag huds. these are used at the /mob level
|
||||
#define ANTAG_HUD "23"
|
||||
|
||||
@@ -69,4 +87,5 @@
|
||||
#define NOTIFY_ATTACK "attack"
|
||||
#define NOTIFY_ORBIT "orbit"
|
||||
|
||||
#define ADD_HUD_TO_COOLDOWN 20 //cooldown for being shown the images for any particular data hud
|
||||
/// cooldown for being shown the images for any particular data hud
|
||||
#define ADD_HUD_TO_COOLDOWN 20
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#define GLOBAL_PROC "some_magic_bullshit"
|
||||
|
||||
/// A shorthand for the callback datum, [documented here](datum/callback.html)
|
||||
#define CALLBACK new /datum/callback
|
||||
#define INVOKE_ASYNC world.ImmediateInvokeAsync
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
//Cleaning tool strength
|
||||
// 1 is also a valid cleaning strength but completely unused so left undefined
|
||||
#define CLEAN_WEAK 2
|
||||
#define CLEAN_MEDIUM 3 // Acceptable tools
|
||||
#define CLEAN_STRONG 4 // Industrial strength
|
||||
#define CLEAN_IMPRESSIVE 5 // Cleaning strong enough your granny would be proud
|
||||
#define CLEAN_GOD 6 // Cleans things spotless down to the atomic structure
|
||||
/// Acceptable tools
|
||||
#define CLEAN_MEDIUM 3
|
||||
/// Industrial strength
|
||||
#define CLEAN_STRONG 4
|
||||
/// Cleaning strong enough your granny would be proud
|
||||
#define CLEAN_IMPRESSIVE 5
|
||||
/// Cleans things spotless down to the atomic structure
|
||||
#define CLEAN_GOD 6
|
||||
|
||||
//How strong things have to be to wipe forensic evidence...
|
||||
#define CLEAN_STRENGTH_FINGERPRINTS CLEAN_IMPRESSIVE
|
||||
|
||||
@@ -1,25 +1,41 @@
|
||||
//component id defines; sometimes these may not make sense in regards to their use in scripture but important ones are bright
|
||||
#define BELLIGERENT_EYE "belligerent_eye" //Use this for offensive and damaging scripture!
|
||||
#define VANGUARD_COGWHEEL "vanguard_cogwheel" //Use this for defensive and healing scripture!
|
||||
#define GEIS_CAPACITOR "geis_capacitor" //Use this for niche scripture!
|
||||
/// Use this for offensive and damaging scripture!
|
||||
#define BELLIGERENT_EYE "belligerent_eye"
|
||||
/// Use this for defensive and healing scripture!
|
||||
#define VANGUARD_COGWHEEL "vanguard_cogwheel"
|
||||
/// Use this for niche scripture!
|
||||
#define GEIS_CAPACITOR "geis_capacitor"
|
||||
#define REPLICANT_ALLOY "replicant_alloy"
|
||||
#define HIEROPHANT_ANSIBLE "hierophant_ansible" //Use this for construction-related scripture!
|
||||
/// Use this for construction-related scripture!
|
||||
#define HIEROPHANT_ANSIBLE "hierophant_ansible"
|
||||
|
||||
GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult
|
||||
GLOBAL_VAR_INIT(clockwork_vitality, 0) //How much Vitality is stored, total
|
||||
GLOBAL_VAR_INIT(clockwork_power, 0) //How many joules of power are globally available to the clockwork cult
|
||||
/// The total value of all structures built by the clockwork cult
|
||||
GLOBAL_VAR_INIT(clockwork_construction_value, 0)
|
||||
///How many joules of power are globally available to the clockwork cult
|
||||
GLOBAL_VAR_INIT(clockwork_power, 0)
|
||||
/// How much Vitality is stored, total
|
||||
GLOBAL_VAR_INIT(clockwork_vitality, 0)
|
||||
|
||||
GLOBAL_LIST_EMPTY(all_clockwork_objects) //All clockwork items, structures, and effects in existence
|
||||
GLOBAL_LIST_EMPTY(all_clockwork_mobs) //All clockwork SERVANTS (not creatures) in existence
|
||||
/// All clockwork items, structures, and effects in existence
|
||||
GLOBAL_LIST_EMPTY(all_clockwork_objects)
|
||||
/// All clockwork SERVANTS (not creatures) in existence
|
||||
GLOBAL_LIST_EMPTY(all_clockwork_mobs)
|
||||
|
||||
GLOBAL_VAR_INIT(ratvar_approaches, 0) //The servants can choose to "herald" Ratvar, permanently buffing them but announcing their presence to the crew.
|
||||
GLOBAL_VAR_INIT(ratvar_awakens, 0) //If Ratvar has been summoned; not a boolean, for proper handling of multiple Ratvars
|
||||
GLOBAL_VAR_INIT(ark_of_the_clockwork_justiciar, FALSE) //The Ark on the Reebe z-level
|
||||
/// The servants can choose to "herald" Ratvar, permanently buffing them but announcing their presence to the crew.
|
||||
GLOBAL_VAR_INIT(ratvar_approaches, 0)
|
||||
/// If Ratvar has been summoned; not a boolean, for proper handling of multiple Ratvars
|
||||
GLOBAL_VAR_INIT(ratvar_awakens, 0)
|
||||
/// The Ark on the Reebe z-level
|
||||
GLOBAL_VAR_INIT(ark_of_the_clockwork_justiciar, FALSE)
|
||||
|
||||
GLOBAL_VAR_INIT(clockwork_gateway_activated, FALSE) //if a gateway to the celestial derelict has ever been successfully activated
|
||||
GLOBAL_VAR_INIT(script_scripture_unlocked, FALSE) //If script scripture is available, through converting at least one crewmember
|
||||
GLOBAL_VAR_INIT(application_scripture_unlocked, FALSE) //If script scripture is available
|
||||
GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not used to track existing scripture
|
||||
/// if a gateway to the celestial derelict has ever been successfully activated
|
||||
GLOBAL_VAR_INIT(clockwork_gateway_activated, FALSE)
|
||||
/// If script scripture is available, through converting at least one crewmember
|
||||
GLOBAL_VAR_INIT(script_scripture_unlocked, FALSE)
|
||||
/// If script scripture is available
|
||||
GLOBAL_VAR_INIT(application_scripture_unlocked, FALSE)
|
||||
/// a list containing scripture instances; not used to track existing scripture
|
||||
GLOBAL_LIST_EMPTY(all_scripture)
|
||||
|
||||
//Scripture tiers and requirements; peripherals should never be used
|
||||
#define SCRIPTURE_PERIPHERAL "Peripheral"
|
||||
@@ -28,64 +44,91 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
|
||||
#define SCRIPTURE_APPLICATION "Application"
|
||||
|
||||
//Various costs related to power.
|
||||
#define MAX_CLOCKWORK_POWER 50000 //The max power in J that the cult can stockpile
|
||||
#define SCRIPT_UNLOCK_THRESHOLD 25000 //Scripts will unlock if the total power reaches this amount
|
||||
#define APPLICATION_UNLOCK_THRESHOLD 40000 //Applications will unlock if the total powre reaches this amount
|
||||
///The max power in W that the cult can stockpile
|
||||
#define MAX_CLOCKWORK_POWER 50000
|
||||
/// Scripts will unlock if the total power reaches this amount
|
||||
#define SCRIPT_UNLOCK_THRESHOLD 25000
|
||||
/// Applications will unlock if the total powre reaches this amount
|
||||
#define APPLICATION_UNLOCK_THRESHOLD 40000
|
||||
|
||||
#define ABSCOND_ABDUCTION_COST 95
|
||||
|
||||
//clockcult power defines
|
||||
#define MIN_CLOCKCULT_POWER 25 //the minimum amount of power clockcult machines will handle gracefully
|
||||
/// the minimum amount of power clockcult machines will handle gracefully
|
||||
#define MIN_CLOCKCULT_POWER 25
|
||||
|
||||
#define CLOCKCULT_POWER_UNIT (MIN_CLOCKCULT_POWER*100) //standard power amount for replica fabricator costs
|
||||
/// standard power amount for replica fabricator costs
|
||||
#define CLOCKCULT_POWER_UNIT (MIN_CLOCKCULT_POWER*100)
|
||||
|
||||
#define POWER_STANDARD (CLOCKCULT_POWER_UNIT*0.2) //how much power is in anything else; doesn't matter as much as the following
|
||||
/// how much power is in anything else; doesn't matter as much as the following
|
||||
#define POWER_STANDARD (CLOCKCULT_POWER_UNIT*0.2)
|
||||
|
||||
#define POWER_FLOOR (CLOCKCULT_POWER_UNIT*0.1) //how much power is in a clockwork floor, determines the cost of clockwork floor production
|
||||
/// how much power is in a clockwork floor, determines the cost of clockwork floor production
|
||||
#define POWER_FLOOR (CLOCKCULT_POWER_UNIT*0.1)
|
||||
|
||||
#define POWER_WALL_MINUS_FLOOR (CLOCKCULT_POWER_UNIT*0.4) //how much power is in a clockwork wall, determines the cost of clockwork wall production
|
||||
/// how much power is in a clockwork wall, determines the cost of clockwork wall production
|
||||
#define POWER_WALL_MINUS_FLOOR (CLOCKCULT_POWER_UNIT*0.4)
|
||||
|
||||
#define POWER_GEAR (CLOCKCULT_POWER_UNIT*0.3) //how much power is in a wall gear, minus the brass from the wall
|
||||
/// how much power is in a wall gear, minus the brass from the wall
|
||||
#define POWER_GEAR (CLOCKCULT_POWER_UNIT*0.3)
|
||||
|
||||
#define POWER_WALL_TOTAL (POWER_WALL_MINUS_FLOOR+POWER_FLOOR) //how much power is in a clockwork wall and the floor under it
|
||||
/// how much power is in a clockwork wall and the floor under it
|
||||
#define POWER_WALL_TOTAL (POWER_WALL_MINUS_FLOOR+POWER_FLOOR)
|
||||
|
||||
#define POWER_ROD (CLOCKCULT_POWER_UNIT*0.01) //how much power is in one rod
|
||||
/// how much power is in one rod
|
||||
#define POWER_ROD (CLOCKCULT_POWER_UNIT*0.01)
|
||||
|
||||
#define POWER_METAL (CLOCKCULT_POWER_UNIT*0.02) //how much power is in one sheet of metal
|
||||
/// how much power is in one sheet of metal
|
||||
#define POWER_METAL (CLOCKCULT_POWER_UNIT*0.02)
|
||||
|
||||
#define POWER_PLASTEEL (CLOCKCULT_POWER_UNIT*0.05) //how much power is in one sheet of plasteel
|
||||
/// how much power is in one sheet of plasteel
|
||||
#define POWER_PLASTEEL (CLOCKCULT_POWER_UNIT*0.05)
|
||||
|
||||
//Ark defines
|
||||
#define GATEWAY_SUMMON_RATE 1 //the time amount the Gateway to the Celestial Derelict gets each process tick; defaults to 1 per tick
|
||||
/// the time amount the Gateway to the Celestial Derelict gets each process tick; defaults to 1 per tick
|
||||
#define GATEWAY_SUMMON_RATE 1
|
||||
|
||||
#define GATEWAY_REEBE_FOUND 240 //when progress is at or above this, the gateway finds reebe and begins drawing power
|
||||
/// when progress is at or above this, the gateway finds reebe and begins drawing power
|
||||
#define GATEWAY_REEBE_FOUND 240
|
||||
|
||||
#define GATEWAY_RATVAR_COMING 480 //when progress is at or above this, ratvar has entered and is coming through the gateway
|
||||
/// when progress is at or above this, ratvar has entered and is coming through the gateway
|
||||
#define GATEWAY_RATVAR_COMING 480
|
||||
|
||||
#define GATEWAY_RATVAR_ARRIVAL 600 //when progress is at or above this, game over ratvar's here everybody go home
|
||||
/// when progress is at or above this, game over ratvar's here everybody go home
|
||||
#define GATEWAY_RATVAR_ARRIVAL 600
|
||||
|
||||
//Objective text define
|
||||
///Objective text define
|
||||
#define CLOCKCULT_OBJECTIVE "Construct the Ark of the Clockwork Justicar and free Ratvar."
|
||||
|
||||
//Eminence defines
|
||||
#define SUPERHEATED_CLOCKWORK_WALL_LIMIT 20 //How many walls can be superheated at once
|
||||
/// How many walls can be superheated at once
|
||||
#define SUPERHEATED_CLOCKWORK_WALL_LIMIT 20
|
||||
|
||||
//misc clockcult stuff
|
||||
|
||||
#define SIGIL_ACCESS_RANGE 2 //range at which transmission sigils can access power
|
||||
/// range at which transmission sigils can access power
|
||||
#define SIGIL_ACCESS_RANGE 2
|
||||
|
||||
#define FABRICATOR_REPAIR_PER_TICK 4 //how much a fabricator repairs each tick, and also how many deciseconds each tick is
|
||||
/// how much a fabricator repairs each tick, and also how many deciseconds each tick is
|
||||
#define FABRICATOR_REPAIR_PER_TICK 4
|
||||
|
||||
#define OCULAR_WARDEN_EXCLUSION_RANGE 3 //the range at which ocular wardens cannot be placed near other ocular wardens
|
||||
/// the range at which ocular wardens cannot be placed near other ocular wardens
|
||||
#define OCULAR_WARDEN_EXCLUSION_RANGE 3
|
||||
|
||||
#define CLOCKWORK_ARMOR_COOLDOWN 1800 //The cooldown period between summoning suits of clockwork armor
|
||||
/// The cooldown period between summoning suits of clockwork armor
|
||||
#define CLOCKWORK_ARMOR_COOLDOWN 1800
|
||||
|
||||
#define RATVARIAN_SPEAR_COOLDOWN 300 //The cooldown period between summoning another Ratvarian spear
|
||||
/// The cooldown period between summoning another Ratvarian spear
|
||||
#define RATVARIAN_SPEAR_COOLDOWN 300
|
||||
|
||||
#define MARAUDER_SCRIPTURE_SCALING_THRESHOLD 600 //The amount of deciseconds that must pass before marauder scripture will not gain a recital penalty
|
||||
/// The amount of deciseconds that must pass before marauder scripture will not gain a recital penalty
|
||||
#define MARAUDER_SCRIPTURE_SCALING_THRESHOLD 600
|
||||
|
||||
#define MARAUDER_SCRIPTURE_SCALING_TIME 20 //The amount of extra deciseconds tacked on to the marauder scripture recital time per recent marauder
|
||||
/// The amount of extra deciseconds tacked on to the marauder scripture recital time per recent marauder
|
||||
#define MARAUDER_SCRIPTURE_SCALING_TIME 20
|
||||
|
||||
#define MARAUDER_SCRIPTURE_SCALING_MAX 300 //The maximum extra time applied to the marauder scripture
|
||||
/// The maximum extra time applied to the marauder scripture
|
||||
#define MARAUDER_SCRIPTURE_SCALING_MAX 300
|
||||
|
||||
#define ARK_SCREAM_COOLDOWN 600 //This much time has to pass between instances of the Ark taking damage before it will "scream" again
|
||||
/// This much time has to pass between instances of the Ark taking damage before it will "scream" again
|
||||
#define ARK_SCREAM_COOLDOWN 600
|
||||
|
||||
@@ -130,14 +130,32 @@
|
||||
#define TRIGGER_GUARD_NONE 0
|
||||
#define TRIGGER_GUARD_NORMAL 1
|
||||
//Gun bolt types
|
||||
///Gun has a bolt, it stays closed while not cycling. The gun must be racked to have a bullet chambered when a mag is inserted.
|
||||
/// Example: c20, shotguns, m90
|
||||
#define BOLT_TYPE_STANDARD 1
|
||||
///Gun has a bolt, it is open when ready to fire. The gun can never have a chambered bullet with no magazine, but the bolt stays ready when a mag is removed.
|
||||
/// Example: Some SMGs, the L6
|
||||
#define BOLT_TYPE_OPEN 2
|
||||
///Gun has no moving bolt mechanism, it cannot be racked. Also dumps the entire contents when emptied instead of a magazine.
|
||||
/// Example: Break action shotguns, revolvers
|
||||
#define BOLT_TYPE_NO_BOLT 3
|
||||
///Gun has a bolt, it locks back when empty. It can be released to chamber a round if a magazine is in.
|
||||
/// Example: Pistols with a slide lock, some SMGs
|
||||
#define BOLT_TYPE_LOCKING 4
|
||||
//Sawn off nerfs
|
||||
///accuracy penalty of sawn off guns
|
||||
#define SAWN_OFF_ACC_PENALTY 25
|
||||
///added recoil of sawn off guns
|
||||
#define SAWN_OFF_RECOIL 1
|
||||
|
||||
//ammo box sprite defines
|
||||
///ammo box will always use provided icon state
|
||||
#define AMMO_BOX_ONE_SPRITE 0
|
||||
///ammo box will have a different state for each bullet; <icon_state>-<bullets left>
|
||||
#define AMMO_BOX_PER_BULLET 1
|
||||
///ammo box will have a different state for full and empty; <icon_state>-max_ammo and <icon_state>-0
|
||||
#define AMMO_BOX_FULL_EMPTY 2
|
||||
|
||||
//Projectile Reflect
|
||||
#define REFLECT_NORMAL (1<<0)
|
||||
#define REFLECT_FAKEPROJECTILE (1<<1)
|
||||
|
||||
@@ -5,17 +5,21 @@
|
||||
#define COMPONENT_INCOMPATIBLE 1
|
||||
#define COMPONENT_NOTRANSFER 2
|
||||
|
||||
#define ELEMENT_INCOMPATIBLE 1 // Return value to cancel attaching
|
||||
/// Return value to cancel attaching
|
||||
#define ELEMENT_INCOMPATIBLE 1
|
||||
|
||||
// /datum/element flags
|
||||
/// /datum/element flags
|
||||
#define ELEMENT_DETACH (1 << 0)
|
||||
|
||||
// How multiple components of the exact same type are handled in the same datum
|
||||
|
||||
#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default)
|
||||
#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
|
||||
#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted
|
||||
#define COMPONENT_DUPE_UNIQUE_PASSARGS 4 //old component is given the initialization args of the new
|
||||
/// old component is deleted (default)
|
||||
#define COMPONENT_DUPE_HIGHLANDER 0
|
||||
/// duplicates allowed
|
||||
#define COMPONENT_DUPE_ALLOWED 1
|
||||
/// new component is deleted
|
||||
#define COMPONENT_DUPE_UNIQUE 2
|
||||
/// old component is given the initialization args of the new
|
||||
#define COMPONENT_DUPE_UNIQUE_PASSARGS 4
|
||||
|
||||
// All signals. Format:
|
||||
// When the signal is called: (signal arguments)
|
||||
@@ -24,11 +28,16 @@
|
||||
// global signals
|
||||
// These are signals which can be listened to by any component on any parent
|
||||
// start global signals with "!", this used to be necessary but now it's just a formatting choice
|
||||
#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_MOB_CREATED "!mob_created" //mob was created somewhere : (mob)
|
||||
#define COMSIG_GLOB_MOB_DEATH "!mob_death" //mob died somewhere : (mob , gibbed)
|
||||
#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message)
|
||||
/// from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
|
||||
#define COMSIG_GLOB_NEW_Z "!new_z"
|
||||
/// called after a successful var edit somewhere in the world: (list/args)
|
||||
#define COMSIG_GLOB_VAR_EDIT "!var_edit"
|
||||
/// mob was created somewhere : (mob)
|
||||
#define COMSIG_GLOB_MOB_CREATED "!mob_created"
|
||||
/// mob died somewhere : (mob , gibbed)
|
||||
#define COMSIG_GLOB_MOB_DEATH "!mob_death"
|
||||
/// global living say plug - use sparingly: (mob/speaker , message)
|
||||
#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special"
|
||||
|
||||
// signals from globally accessible objects
|
||||
/// from SSsun when the sun changes position : (azimuth)
|
||||
@@ -37,11 +46,16 @@
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// /datum signals
|
||||
#define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (/datum/component)
|
||||
#define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (/datum/component)
|
||||
#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
|
||||
#define COMSIG_TOPIC "handle_topic" //generic topic handler (usr, href_list)
|
||||
/// when a component is added to a datum: (/datum/component)
|
||||
#define COMSIG_COMPONENT_ADDED "component_added"
|
||||
/// before a component is removed from a datum because of RemoveComponent: (/datum/component)
|
||||
#define COMSIG_COMPONENT_REMOVING "component_removing"
|
||||
/// before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation
|
||||
#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted"
|
||||
/// 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
|
||||
#define COMSIG_PARENT_QDELETING "parent_qdeleting"
|
||||
/// generic topic handler (usr, href_list)
|
||||
#define COMSIG_TOPIC "handle_topic"
|
||||
|
||||
// /atom signals
|
||||
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
|
||||
|
||||
@@ -5,5 +5,7 @@
|
||||
#define CONFIG_MAPS_FILE "maps.txt"
|
||||
|
||||
//flags
|
||||
#define CONFIG_ENTRY_LOCKED 1 //can't edit
|
||||
#define CONFIG_ENTRY_HIDDEN 2 //can't see value
|
||||
/// can't edit
|
||||
#define CONFIG_ENTRY_LOCKED 1
|
||||
/// can't see value
|
||||
#define CONFIG_ENTRY_HIDDEN 2
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
//blood magic
|
||||
#define MAX_BLOODCHARGE 4
|
||||
#define RUNELESS_MAX_BLOODCHARGE 1
|
||||
#define CULT_RISEN 0.2 //percent before rise
|
||||
#define CULT_ASCENDENT 0.4 //percent before ascend
|
||||
/// percent before rise
|
||||
#define CULT_RISEN 0.2
|
||||
/// percent before ascend
|
||||
#define CULT_ASCENDENT 0.4
|
||||
#define BLOOD_SPEAR_COST 150
|
||||
#define BLOOD_BARRAGE_COST 300
|
||||
#define BLOOD_BEAM_COST 500
|
||||
@@ -24,4 +26,4 @@
|
||||
#define DEFAULT_TOOLTIP "6:-29,5:-2"
|
||||
//misc
|
||||
#define SOULS_TO_REVIVE 3
|
||||
#define BLOODCULT_EYE "f00"
|
||||
#define BLOODCULT_EYE "f00"
|
||||
|
||||
@@ -20,10 +20,17 @@
|
||||
#define DISEASE_SPREAD_AIRBORNE (1<<5)
|
||||
|
||||
//Severity Defines
|
||||
#define DISEASE_SEVERITY_POSITIVE "Positive" //Diseases that buff, heal, or at least do nothing at all
|
||||
#define DISEASE_SEVERITY_NONTHREAT "Harmless" //Diseases that may have annoying effects, but nothing disruptive (sneezing)
|
||||
#define DISEASE_SEVERITY_MINOR "Minor" //Diseases that can annoy in concrete ways (dizziness)
|
||||
#define DISEASE_SEVERITY_MEDIUM "Medium" //Diseases that can do minor harm, or severe annoyance (vomit)
|
||||
#define DISEASE_SEVERITY_HARMFUL "Harmful" //Diseases that can do significant harm, or severe disruption (brainrot)
|
||||
#define DISEASE_SEVERITY_DANGEROUS "Dangerous" //Diseases that can kill or maim if left untreated (flesh eating, blindness)
|
||||
#define DISEASE_SEVERITY_BIOHAZARD "BIOHAZARD" //Diseases that can quickly kill an unprepared victim (fungal tb, gbs)
|
||||
/// Diseases that buff, heal, or at least do nothing at all
|
||||
#define DISEASE_SEVERITY_POSITIVE "Positive"
|
||||
/// Diseases that may have annoying effects, but nothing disruptive (sneezing)
|
||||
#define DISEASE_SEVERITY_NONTHREAT "Harmless"
|
||||
/// Diseases that can annoy in concrete ways (dizziness)
|
||||
#define DISEASE_SEVERITY_MINOR "Minor"
|
||||
/// Diseases that can do minor harm, or severe annoyance (vomit)
|
||||
#define DISEASE_SEVERITY_MEDIUM "Medium"
|
||||
/// Diseases that can do significant harm, or severe disruption (brainrot)
|
||||
#define DISEASE_SEVERITY_HARMFUL "Harmful"
|
||||
/// Diseases that can kill or maim if left untreated (flesh eating, blindness)
|
||||
#define DISEASE_SEVERITY_DANGEROUS "Dangerous"
|
||||
/// Diseases that can quickly kill an unprepared victim (fungal tb, gbs)
|
||||
#define DISEASE_SEVERITY_BIOHAZARD "BIOHAZARD"
|
||||
|
||||
@@ -22,24 +22,37 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
|
||||
//FLAGS BITMASK
|
||||
|
||||
#define HEAR_1 (1<<3) // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not.
|
||||
#define CHECK_RICOCHET_1 (1<<4) // Projectiels will check ricochet on things impacted that have this.
|
||||
#define CONDUCT_1 (1<<5) // conducts electricity (metal etc.)
|
||||
#define NODECONSTRUCT_1 (1<<7) // For machines and structures that should not break into parts, eg, holodeck stuff
|
||||
#define OVERLAY_QUEUED_1 (1<<8) // atom queued to SSoverlay
|
||||
#define ON_BORDER_1 (1<<9) // item has priority to check when entering or leaving
|
||||
#define PREVENT_CLICK_UNDER_1 (1<<11) //Prevent clicking things below it on the same turf eg. doors/ fulltile windows
|
||||
/// This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not.
|
||||
#define HEAR_1 (1<<3)
|
||||
/// Projectiels will check ricochet on things impacted that have this.
|
||||
#define CHECK_RICOCHET_1 (1<<4)
|
||||
/// conducts electricity (metal etc.)
|
||||
#define CONDUCT_1 (1<<5)
|
||||
/// For machines and structures that should not break into parts, eg, holodeck stuff
|
||||
#define NODECONSTRUCT_1 (1<<7)
|
||||
/// atom queued to SSoverlay
|
||||
#define OVERLAY_QUEUED_1 (1<<8)
|
||||
/// item has priority to check when entering or leaving
|
||||
#define ON_BORDER_1 (1<<9)
|
||||
/// Prevent clicking things below it on the same turf eg. doors/ fulltile windows
|
||||
#define PREVENT_CLICK_UNDER_1 (1<<11)
|
||||
#define HOLOGRAM_1 (1<<12)
|
||||
#define TESLA_IGNORE_1 (1<<13) // TESLA_IGNORE grants immunity from being targeted by tesla-style electricity
|
||||
#define INITIALIZED_1 (1<<14) //Whether /atom/Initialize() has already run for the object
|
||||
#define ADMIN_SPAWNED_1 (1<<15) //was this spawned by an admin? used for stat tracking stuff.
|
||||
/// TESLA_IGNORE grants immunity from being targeted by tesla-style electricity
|
||||
#define TESLA_IGNORE_1 (1<<13)
|
||||
///Whether /atom/Initialize() has already run for the object
|
||||
#define INITIALIZED_1 (1<<14)
|
||||
/// was this spawned by an admin? used for stat tracking stuff.
|
||||
#define ADMIN_SPAWNED_1 (1<<15)
|
||||
|
||||
//turf-only flags
|
||||
#define NOJAUNT_1 (1<<0)
|
||||
#define UNUSED_RESERVATION_TURF_1 (1<<1)
|
||||
#define CAN_BE_DIRTY_1 (1<<2) // If a turf can be made dirty at roundstart. This is also used in areas.
|
||||
#define NO_LAVA_GEN_1 (1<<6) //Blocks lava rivers being generated on the turf
|
||||
#define NO_RUINS_1 (1<<10) //Blocks ruins spawning on the turf
|
||||
/// If a turf can be made dirty at roundstart. This is also used in areas.
|
||||
#define CAN_BE_DIRTY_1 (1<<2)
|
||||
/// Blocks lava rivers being generated on the turf
|
||||
#define NO_LAVA_GEN_1 (1<<6)
|
||||
/// Blocks ruins spawning on the turf
|
||||
#define NO_RUINS_1 (1<<10)
|
||||
|
||||
/*
|
||||
These defines are used specifically with the atom/pass_flags bitmask
|
||||
@@ -61,17 +74,23 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
#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.
|
||||
/// When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
|
||||
#define UNSTOPPABLE (1<<4)
|
||||
|
||||
//Fire and Acid stuff, for resistance_flags
|
||||
#define LAVA_PROOF (1<<0)
|
||||
#define FIRE_PROOF (1<<1) //100% immune to fire damage (but not necessarily to lava or heat)
|
||||
/// 100% immune to fire damage (but not necessarily to lava or heat)
|
||||
#define FIRE_PROOF (1<<1)
|
||||
#define FLAMMABLE (1<<2)
|
||||
#define ON_FIRE (1<<3)
|
||||
#define UNACIDABLE (1<<4) //acid can't even appear on it, let alone melt it.
|
||||
#define ACID_PROOF (1<<5) //acid stuck on it doesn't melt it.
|
||||
#define INDESTRUCTIBLE (1<<6) //doesn't take damage
|
||||
#define FREEZE_PROOF (1<<7) //can't be frozen
|
||||
/// acid can't even appear on it, let alone melt it.
|
||||
#define UNACIDABLE (1<<4)
|
||||
/// acid stuck on it doesn't melt it.
|
||||
#define ACID_PROOF (1<<5)
|
||||
/// doesn't take damage
|
||||
#define INDESTRUCTIBLE (1<<6)
|
||||
/// can't be frozen
|
||||
#define FREEZE_PROOF (1<<7)
|
||||
|
||||
//tesla_zap
|
||||
#define TESLA_MACHINE_EXPLOSIVE (1<<0)
|
||||
@@ -89,13 +108,20 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
#define EMP_PROTECT_WIRES (1<<2)
|
||||
|
||||
//Mob mobility var flags
|
||||
#define MOBILITY_MOVE (1<<0) //can move
|
||||
#define MOBILITY_STAND (1<<1) //can, and is, standing up
|
||||
#define MOBILITY_PICKUP (1<<2) //can pickup items
|
||||
#define MOBILITY_USE (1<<3) //can hold and use items
|
||||
#define MOBILITY_UI (1<<4) //can use interfaces like machinery
|
||||
#define MOBILITY_STORAGE (1<<5) //can use storage item
|
||||
#define MOBILITY_PULL (1<<6) //can pull things
|
||||
/// 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 hold and use items
|
||||
#define MOBILITY_USE (1<<3)
|
||||
/// can use interfaces like machinery
|
||||
#define MOBILITY_UI (1<<4)
|
||||
/// can use storage item
|
||||
#define MOBILITY_STORAGE (1<<5)
|
||||
/// can pull things
|
||||
#define MOBILITY_PULL (1<<6)
|
||||
|
||||
#define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL)
|
||||
#define MOBILITY_FLAGS_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE)
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
//HUD styles. Index order defines how they are cycled in F12.
|
||||
#define HUD_STYLE_STANDARD 1 //Standard hud
|
||||
#define HUD_STYLE_REDUCED 2 //Reduced hud (just hands and intent switcher)
|
||||
#define HUD_STYLE_NOHUD 3 //No hud (for screenshots)
|
||||
/// Standard hud
|
||||
#define HUD_STYLE_STANDARD 1
|
||||
/// Reduced hud (just hands and intent switcher)
|
||||
#define HUD_STYLE_REDUCED 2
|
||||
/// No hud (for screenshots)
|
||||
#define HUD_STYLE_NOHUD 3
|
||||
|
||||
#define HUD_VERSIONS 3 //Used in show_hud(); Please ensure this is the same as the maximum index.
|
||||
/// Used in show_hud(); Please ensure this is the same as the maximum index.
|
||||
#define HUD_VERSIONS 3
|
||||
|
||||
//1:1 HUD layout stuff
|
||||
#define UI_BOXCRAFT "EAST-4:22,SOUTH+1:6"
|
||||
|
||||
@@ -1,22 +1,38 @@
|
||||
/// whether can_interact() checks for anchored. only works on movables.
|
||||
#define INTERACT_ATOM_REQUIRES_ANCHORED (1<<0)
|
||||
/// calls try_interact() on attack_hand() and returns that.
|
||||
#define INTERACT_ATOM_ATTACK_HAND (1<<1)
|
||||
/// automatically calls and returns ui_interact() on interact().
|
||||
#define INTERACT_ATOM_UI_INTERACT (1<<2)
|
||||
/// user must be dextrous
|
||||
#define INTERACT_ATOM_REQUIRES_DEXTERITY (1<<3)
|
||||
/// ignores incapacitated check
|
||||
#define INTERACT_ATOM_IGNORE_INCAPACITATED (1<<4)
|
||||
/// incapacitated check ignores restrained
|
||||
#define INTERACT_ATOM_IGNORE_RESTRAINED (1<<5)
|
||||
/// incapacitated check checks grab
|
||||
#define INTERACT_ATOM_CHECK_GRAB (1<<6)
|
||||
/// prevents leaving fingerprints automatically on attack_hand
|
||||
#define INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND (1<<7)
|
||||
/// adds hiddenprints instead of fingerprints on interact
|
||||
#define INTERACT_ATOM_NO_FINGERPRINT_INTERACT (1<<8)
|
||||
|
||||
#define INTERACT_ATOM_REQUIRES_ANCHORED (1<<0) //whether can_interact() checks for anchored. only works on movables.
|
||||
#define INTERACT_ATOM_ATTACK_HAND (1<<1) //calls try_interact() on attack_hand() and returns that.
|
||||
#define INTERACT_ATOM_UI_INTERACT (1<<2) //automatically calls and returns ui_interact() on interact().
|
||||
#define INTERACT_ATOM_REQUIRES_DEXTERITY (1<<3) //user must be dextrous
|
||||
#define INTERACT_ATOM_IGNORE_INCAPACITATED (1<<4) //ignores incapacitated check
|
||||
#define INTERACT_ATOM_IGNORE_RESTRAINED (1<<5) //incapacitated check ignores restrained
|
||||
#define INTERACT_ATOM_CHECK_GRAB (1<<6) //incapacitated check checks grab
|
||||
#define INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND (1<<7) //prevents leaving fingerprints automatically on attack_hand
|
||||
#define INTERACT_ATOM_NO_FINGERPRINT_INTERACT (1<<8) //adds hiddenprints instead of fingerprints on interact
|
||||
/// attempt pickup on attack_hand for items
|
||||
#define INTERACT_ITEM_ATTACK_HAND_PICKUP (1<<0)
|
||||
|
||||
#define INTERACT_ITEM_ATTACK_HAND_PICKUP (1<<0) //attempt pickup on attack_hand for items
|
||||
|
||||
#define INTERACT_MACHINE_OPEN (1<<0) //can_interact() while open
|
||||
#define INTERACT_MACHINE_OFFLINE (1<<1) //can_interact() while offline
|
||||
#define INTERACT_MACHINE_WIRES_IF_OPEN (1<<2) //try to interact with wires if open
|
||||
#define INTERACT_MACHINE_ALLOW_SILICON (1<<3) //let silicons interact
|
||||
#define INTERACT_MACHINE_OPEN_SILICON (1<<4) //let silicons interact while open
|
||||
#define INTERACT_MACHINE_REQUIRES_SILICON (1<<5) //must be silicon to interact
|
||||
#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!!
|
||||
/// can_interact() while open
|
||||
#define INTERACT_MACHINE_OPEN (1<<0)
|
||||
/// can_interact() while offline
|
||||
#define INTERACT_MACHINE_OFFLINE (1<<1)
|
||||
/// try to interact with wires if open
|
||||
#define INTERACT_MACHINE_WIRES_IF_OPEN (1<<2)
|
||||
/// let silicons interact
|
||||
#define INTERACT_MACHINE_ALLOW_SILICON (1<<3)
|
||||
/// let silicons interact while open
|
||||
#define INTERACT_MACHINE_OPEN_SILICON (1<<4)
|
||||
/// must be silicon to interact
|
||||
#define INTERACT_MACHINE_REQUIRES_SILICON (1<<5)
|
||||
/// 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_MACHINE_SET_MACHINE (1<<6)
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
/*ALL DEFINES RELATED TO INVENTORY OBJECTS, MANAGEMENT, ETC, GO HERE*/
|
||||
|
||||
//ITEM INVENTORY WEIGHT, FOR w_class
|
||||
#define WEIGHT_CLASS_TINY 1 //Usually items smaller then a human hand, (e.g. playing cards, lighter, scalpel, coins/holochips)
|
||||
#define WEIGHT_CLASS_SMALL 2 //Pockets can hold small and tiny items, (e.g. flashlight, multitool, grenades, GPS device)
|
||||
#define WEIGHT_CLASS_NORMAL 3 //Standard backpacks can carry tiny, small & normal items, (e.g. fire extinguisher, stun baton, gas mask, metal sheets)
|
||||
#define WEIGHT_CLASS_BULKY 4 //Items that can be weilded or equipped but not stored in an inventory, (e.g. defibrillator, backpack, space suits)
|
||||
#define WEIGHT_CLASS_HUGE 5 //Usually represents objects that require two hands to operate, (e.g. shotgun, two-handed melee weapons)
|
||||
#define WEIGHT_CLASS_GIGANTIC 6 //Essentially means it cannot be picked up or placed in an inventory, (e.g. mech parts, safe)
|
||||
/// Usually items smaller then a human hand, (e.g. playing cards, lighter, scalpel, coins/holochips)
|
||||
#define WEIGHT_CLASS_TINY 1
|
||||
/// Pockets can hold small and tiny items, (e.g. flashlight, multitool, grenades, GPS device)
|
||||
#define WEIGHT_CLASS_SMALL 2
|
||||
/// Standard backpacks can carry tiny, small & normal items, (e.g. fire extinguisher, stun baton, gas mask, metal sheets)
|
||||
#define WEIGHT_CLASS_NORMAL 3
|
||||
/// Items that can be weilded or equipped but not stored in an inventory, (e.g. defibrillator, backpack, space suits)
|
||||
#define WEIGHT_CLASS_BULKY 4
|
||||
/// Usually represents objects that require two hands to operate, (e.g. shotgun, two-handed melee weapons)
|
||||
#define WEIGHT_CLASS_HUGE 5
|
||||
/// Essentially means it cannot be picked up or placed in an inventory, (e.g. mech parts, safe)
|
||||
#define WEIGHT_CLASS_GIGANTIC 6
|
||||
|
||||
//Inventory depth: limits how many nested storage items you can access directly.
|
||||
//1: stuff in mob, 2: stuff in backpack, 3: stuff in box in backpack, etc
|
||||
@@ -25,8 +31,10 @@
|
||||
#define ITEM_SLOT_ID (1<<8)
|
||||
#define ITEM_SLOT_BELT (1<<9)
|
||||
#define ITEM_SLOT_BACK (1<<10)
|
||||
#define ITEM_SLOT_POCKET (1<<11) // this is to allow items with a w_class of WEIGHT_CLASS_NORMAL or WEIGHT_CLASS_BULKY to fit in pockets.
|
||||
#define ITEM_SLOT_DENYPOCKET (1<<12) // this is to deny items with a w_class of WEIGHT_CLASS_SMALL or WEIGHT_CLASS_TINY to fit in pockets.
|
||||
/// this is to allow items with a w_class of WEIGHT_CLASS_NORMAL or WEIGHT_CLASS_BULKY to fit in pockets.
|
||||
#define ITEM_SLOT_POCKET (1<<11)
|
||||
/// this is to deny items with a w_class of WEIGHT_CLASS_SMALL or WEIGHT_CLASS_TINY to fit in pockets.
|
||||
#define ITEM_SLOT_DENYPOCKET (1<<12)
|
||||
#define ITEM_SLOT_NECK (1<<13)
|
||||
#define ITEM_SLOT_HANDS (1<<14)
|
||||
#define ITEM_SLOT_BACKPACK (1<<15)
|
||||
@@ -36,8 +44,9 @@
|
||||
#define SLOT_BACK 1
|
||||
#define SLOT_WEAR_MASK 2
|
||||
#define SLOT_HANDCUFFED 3
|
||||
#define SLOT_HANDS 4 //wherever you provide a slot for hands you provide SLOT_HANDS
|
||||
//SLOT_HANDS as a slot will pick ANY available hand
|
||||
/// wherever you provide a slot for hands you provide SLOT_HANDS.
|
||||
/// SLOT_HANDS as a slot will pick ANY available hand
|
||||
#define SLOT_HANDS 4
|
||||
#define SLOT_BELT 5
|
||||
#define SLOT_WEAR_ID 6
|
||||
#define SLOT_EARS 7
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
//Bay lighting engine shit, not in /code/modules/lighting because BYOND is being shit about it
|
||||
#define LIGHTING_INTERVAL 5 // frequency, in 1/10ths of a second, of the lighting process
|
||||
/// frequency, in 1/10ths of a second, of the lighting process
|
||||
#define LIGHTING_INTERVAL 5
|
||||
|
||||
#define MINIMUM_USEFUL_LIGHT_RANGE 1.4
|
||||
|
||||
#define LIGHTING_FALLOFF 1 // type of falloff to use for lighting; 1 for circular, 2 for square
|
||||
#define LIGHTING_LAMBERTIAN 0 // use lambertian shading for light sources
|
||||
#define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone
|
||||
#define LIGHTING_ROUND_VALUE (1 / 64) //Value used to round lumcounts, values smaller than 1/129 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY.
|
||||
/// type of falloff to use for lighting; 1 for circular, 2 for square
|
||||
#define LIGHTING_FALLOFF 1
|
||||
/// use lambertian shading for light sources
|
||||
#define LIGHTING_LAMBERTIAN 0
|
||||
/// height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone
|
||||
#define LIGHTING_HEIGHT 1
|
||||
/// Value used to round lumcounts, values smaller than 1/129 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY.
|
||||
#define LIGHTING_ROUND_VALUE (1 / 64)
|
||||
|
||||
#define LIGHTING_ICON 'icons/effects/lighting_object.dmi' // icon used for lighting shading effects
|
||||
/// icon used for lighting shading effects
|
||||
#define LIGHTING_ICON 'icons/effects/lighting_object.dmi'
|
||||
|
||||
// If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting objects.
|
||||
// Set to zero to disable soft lighting. Luminosity changes then work if it's lit at all.
|
||||
/// If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting objects.
|
||||
/// Set to zero to disable soft lighting. Luminosity changes then work if it's lit at all.
|
||||
#define LIGHTING_SOFT_THRESHOLD 0
|
||||
|
||||
// If I were you I'd leave this alone.
|
||||
/// If I were you I'd leave this alone.
|
||||
#define LIGHTING_BASE_MATRIX \
|
||||
list \
|
||||
( \
|
||||
@@ -29,45 +35,71 @@
|
||||
//Some defines to generalise colours used in lighting.
|
||||
//Important note on colors. Colors can end up significantly different from the basic html picture, especially when saturated
|
||||
#define LIGHT_COLOR_WHITE "#FFFFFF"
|
||||
#define LIGHT_COLOR_RED "#FA8282" //Warm but extremely diluted red. rgb(250, 130, 130)
|
||||
#define LIGHT_COLOR_GREEN "#64C864" //Bright but quickly dissipating neon green. rgb(100, 200, 100)
|
||||
#define LIGHT_COLOR_BLUE "#6496FA" //Cold, diluted blue. rgb(100, 150, 250)
|
||||
/// Warm but extremely diluted red. rgb(250, 130, 130)
|
||||
#define LIGHT_COLOR_RED "#FA8282"
|
||||
/// Bright but quickly dissipating neon green. rgb(100, 200, 100)
|
||||
#define LIGHT_COLOR_GREEN "#64C864"
|
||||
/// Cold, diluted blue. rgb(100, 150, 250)
|
||||
#define LIGHT_COLOR_BLUE "#6496FA"
|
||||
/// Light blueish green. rgb(125, 225, 175)
|
||||
#define LIGHT_COLOR_BLUEGREEN "#7DE1AF"
|
||||
/// Diluted cyan. rgb(125, 225, 225)
|
||||
#define LIGHT_COLOR_CYAN "#7DE1E1"
|
||||
/// More-saturated cyan. rgb(64, 206, 255)
|
||||
#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF"
|
||||
/// Saturated blue. rgb(51, 117, 248)
|
||||
#define LIGHT_COLOR_DARK_BLUE "#6496FA"
|
||||
/// Diluted, mid-warmth pink. rgb(225, 125, 225)
|
||||
#define LIGHT_COLOR_PINK "#E17DE1"
|
||||
/// Dimmed yellow, leaning kaki. rgb(225, 225, 125)
|
||||
#define LIGHT_COLOR_YELLOW "#E1E17D"
|
||||
/// Clear brown, mostly dim. rgb(150, 100, 50)
|
||||
#define LIGHT_COLOR_BROWN "#966432"
|
||||
/// Mostly pure orange. rgb(250, 150, 50)
|
||||
#define LIGHT_COLOR_ORANGE "#FA9632"
|
||||
/// Light Purple. rgb(149, 44, 244)
|
||||
#define LIGHT_COLOR_PURPLE "#952CF4"
|
||||
/// Less-saturated light purple. rgb(155, 81, 255)
|
||||
#define LIGHT_COLOR_LAVENDER "#9B51FF"
|
||||
|
||||
#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" //Light blueish green. rgb(125, 225, 175)
|
||||
#define LIGHT_COLOR_CYAN "#7DE1E1" //Diluted cyan. rgb(125, 225, 225)
|
||||
#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" //More-saturated cyan. rgb(64, 206, 255)
|
||||
#define LIGHT_COLOR_DARK_BLUE "#6496FA" //Saturated blue. rgb(51, 117, 248)
|
||||
#define LIGHT_COLOR_PINK "#E17DE1" //Diluted, mid-warmth pink. rgb(225, 125, 225)
|
||||
#define LIGHT_COLOR_YELLOW "#E1E17D" //Dimmed yellow, leaning kaki. rgb(225, 225, 125)
|
||||
#define LIGHT_COLOR_BROWN "#966432" //Clear brown, mostly dim. rgb(150, 100, 50)
|
||||
#define LIGHT_COLOR_ORANGE "#FA9632" //Mostly pure orange. rgb(250, 150, 50)
|
||||
#define LIGHT_COLOR_PURPLE "#952CF4" //Light Purple. rgb(149, 44, 244)
|
||||
#define LIGHT_COLOR_LAVENDER "#9B51FF" //Less-saturated light purple. rgb(155, 81, 255)
|
||||
|
||||
#define LIGHT_COLOR_HOLY_MAGIC "#FFF743" //slightly desaturated bright yellow.
|
||||
#define LIGHT_COLOR_BLOOD_MAGIC "#D00000" //deep crimson
|
||||
///slightly desaturated bright yellow.
|
||||
#define LIGHT_COLOR_HOLY_MAGIC "#FFF743"
|
||||
/// deep crimson
|
||||
#define LIGHT_COLOR_BLOOD_MAGIC "#D00000"
|
||||
|
||||
//These ones aren't a direct colour like the ones above, because nothing would fit
|
||||
#define LIGHT_COLOR_FIRE "#FAA019" //Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25)
|
||||
#define LIGHT_COLOR_LAVA "#C48A18" //Very warm yellow, leaning slightly towards orange. rgb(196, 138, 24)
|
||||
#define LIGHT_COLOR_FLARE "#FA644B" //Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75)
|
||||
#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" //Weird color, between yellow and green, very slimy. rgb(175, 200, 75)
|
||||
#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175)
|
||||
#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250)
|
||||
/// Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25)
|
||||
#define LIGHT_COLOR_FIRE "#FAA019"
|
||||
/// Very warm yellow, leaning slightly towards orange. rgb(196, 138, 24)
|
||||
#define LIGHT_COLOR_LAVA "#C48A18"
|
||||
/// Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75)
|
||||
#define LIGHT_COLOR_FLARE "#FA644B"
|
||||
/// Weird color, between yellow and green, very slimy. rgb(175, 200, 75)
|
||||
#define LIGHT_COLOR_SLIME_LAMP "#AFC84B"
|
||||
/// Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175)
|
||||
#define LIGHT_COLOR_TUNGSTEN "#FAE1AF"
|
||||
/// Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250)
|
||||
#define LIGHT_COLOR_HALOGEN "#F0FAFA"
|
||||
|
||||
#define LIGHT_RANGE_FIRE 3 //How many tiles standard fires glow.
|
||||
///How many tiles standard fires glow.
|
||||
#define LIGHT_RANGE_FIRE 3
|
||||
|
||||
#define LIGHTING_PLANE_ALPHA_VISIBLE 255
|
||||
#define LIGHTING_PLANE_ALPHA_NV_TRAIT 245
|
||||
#define LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE 192
|
||||
#define LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 128 //For lighting alpha, small amounts lead to big changes. even at 128 its hard to figure out what is dark and what is light, at 64 you almost can't even tell.
|
||||
/// For lighting alpha, small amounts lead to big changes. even at 128 its hard to figure out what is dark and what is light, at 64 you almost can't even tell.
|
||||
#define LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 128
|
||||
#define LIGHTING_PLANE_ALPHA_INVISIBLE 0
|
||||
|
||||
//lighting area defines
|
||||
#define DYNAMIC_LIGHTING_DISABLED 0 //dynamic lighting disabled (area stays at full brightness)
|
||||
#define DYNAMIC_LIGHTING_ENABLED 1 //dynamic lighting enabled
|
||||
#define DYNAMIC_LIGHTING_FORCED 2 //dynamic lighting enabled even if the area doesn't require power
|
||||
#define DYNAMIC_LIGHTING_IFSTARLIGHT 3 //dynamic lighting enabled only if starlight is.
|
||||
/// dynamic lighting disabled (area stays at full brightness)
|
||||
#define DYNAMIC_LIGHTING_DISABLED 0
|
||||
/// dynamic lighting enabled
|
||||
#define DYNAMIC_LIGHTING_ENABLED 1
|
||||
/// dynamic lighting enabled even if the area doesn't require power
|
||||
#define DYNAMIC_LIGHTING_FORCED 2
|
||||
/// dynamic lighting enabled only if starlight is.
|
||||
#define DYNAMIC_LIGHTING_IFSTARLIGHT 3
|
||||
#define IS_DYNAMIC_LIGHTING(A) A.dynamic_lighting
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
|
||||
///Defines for the R&D console, see: [/modules/research/rdconsole][rdconsole]
|
||||
#define RDCONSOLE_UI_MODE_NORMAL 1
|
||||
#define RDCONSOLE_UI_MODE_EXPERT 2
|
||||
#define RDCONSOLE_UI_MODE_LIST 3
|
||||
|
||||
//RDSCREEN screens
|
||||
#define RDSCREEN_MENU 0
|
||||
#define RDSCREEN_TECHDISK 1
|
||||
#define RDSCREEN_DESIGNDISK 20
|
||||
@@ -27,6 +26,7 @@
|
||||
|
||||
#define RDSCREEN_NOBREAK "<NO_HTML_BREAK>"
|
||||
|
||||
///Sanity check defines for when these devices aren't connected or no disk is inserted
|
||||
#define RDSCREEN_TEXT_NO_PROTOLATHE "<div><h3>No Protolathe Linked!</h3></div><br>"
|
||||
#define RDSCREEN_TEXT_NO_IMPRINTER "<div><h3>No Circuit Imprinter Linked!</h3></div><br>"
|
||||
#define RDSCREEN_TEXT_NO_DECONSTRUCT "<div><h3>No Destructive Analyzer Linked!</h3></div><br>"
|
||||
@@ -43,12 +43,14 @@
|
||||
#define RDSCREEN_UI_SNODE_CHECK if(!selected_node) { return RDSCREEN_TEXT_NO_SNODE }
|
||||
#define RDSCREEN_UI_SDESIGN_CHECK if(!selected_design) { return RDSCREEN_TEXT_NO_SDESIGN }
|
||||
|
||||
///Defines for the Protolathe screens, see: [/modules/research/machinery/protolathe][Protolathe]
|
||||
#define RESEARCH_FABRICATOR_SCREEN_MAIN 1
|
||||
#define RESEARCH_FABRICATOR_SCREEN_CHEMICALS 2
|
||||
#define RESEARCH_FABRICATOR_SCREEN_MATERIALS 3
|
||||
#define RESEARCH_FABRICATOR_SCREEN_SEARCH 4
|
||||
#define RESEARCH_FABRICATOR_SCREEN_CATEGORYVIEW 5
|
||||
|
||||
///Department flags for techwebs. Defines which department can print what from each protolathe so Cargo can't print guns, etc.
|
||||
#define DEPARTMENTAL_FLAG_SECURITY (1<<0)
|
||||
#define DEPARTMENTAL_FLAG_MEDICAL (1<<1)
|
||||
#define DEPARTMENTAL_FLAG_CARGO (1<<2)
|
||||
@@ -56,22 +58,25 @@
|
||||
#define DEPARTMENTAL_FLAG_ENGINEERING (1<<4)
|
||||
#define DEPARTMENTAL_FLAG_SERVICE (1<<5)
|
||||
#define DEPARTMENTAL_FLAG_ALL (1<<6) //NO THIS DOESN'T ALLOW YOU TO PRINT EVERYTHING, IT'S FOR ALL DEPARTMENTS!
|
||||
//#define DEPARTMENTAL_FLAG_MINING (1<<7)
|
||||
//#define DEPARTMENTAL_FLAG_MINING (1<<7) //I swear I'm actually going to use this eventually leave it here
|
||||
|
||||
#define DESIGN_ID_IGNORE "IGNORE_THIS_DESIGN"
|
||||
#define DESIGN_ID_IGNORE "IGNORE_THIS_DESIGN" ///For instances where we don't want a design showing up due to it being for debug/sanity purposes
|
||||
|
||||
#define RESEARCH_MATERIAL_RECLAMATION_ID "__materials"
|
||||
|
||||
//When adding new types, update the list below!
|
||||
///Techweb names for new point types. Can be used to define specific point values for specific types of research (science, security, engineering, etc.)
|
||||
#define TECHWEB_POINT_TYPE_GENERIC "General Research"
|
||||
|
||||
#define TECHWEB_POINT_TYPE_DEFAULT TECHWEB_POINT_TYPE_GENERIC
|
||||
|
||||
//defined here so people don't forget to change this!
|
||||
///Associative names for techweb point values, see: [/modules/research/techweb/all_nodes][all_nodes]
|
||||
#define TECHWEB_POINT_TYPE_LIST_ASSOCIATIVE_NAMES list(\
|
||||
TECHWEB_POINT_TYPE_GENERIC = "General Research"\
|
||||
)
|
||||
|
||||
|
||||
#define TOXINS_RESEARCH_MAX 70000 // This is the maximum amount of research points a toxins bomb can get.
|
||||
#define TOXINS_RESEARCH_LAMBDA 3940 // This determines how easy it is for a toxins bomb to reach the max research cap.
|
||||
///This is the maximum amount of research points a toxins bomb can get.
|
||||
#define TOXINS_RESEARCH_MAX 70000
|
||||
|
||||
///This determines how easy it is for a toxins bomb to reach the max research cap.
|
||||
#define TOXINS_RESEARCH_LAMBDA 3940
|
||||
|
||||
@@ -1,39 +1,91 @@
|
||||
//Update this whenever the db schema changes
|
||||
//make sure you add an update to the schema_version stable in the db changelog
|
||||
//! Defines for subsystems and overlays
|
||||
//!
|
||||
//! Lots of important stuff in here, make sure you have your brain switched on
|
||||
//! when editing this file
|
||||
|
||||
//! ## DB defines
|
||||
/**
|
||||
* DB major schema version
|
||||
*
|
||||
* Update this whenever the db schema changes
|
||||
*
|
||||
* make sure you add an update to the schema_version stable in the db changelog
|
||||
*/
|
||||
#define DB_MAJOR_VERSION 5
|
||||
|
||||
/**
|
||||
* DB minor schema version
|
||||
*
|
||||
* Update this whenever the db schema changes
|
||||
*
|
||||
* make sure you add an update to the schema_version stable in the db changelog
|
||||
*/
|
||||
#define DB_MINOR_VERSION 4
|
||||
|
||||
|
||||
//Timing subsystem
|
||||
//Don't run if there is an identical unique timer active
|
||||
//if the arguments to addtimer are the same as an existing timer, it doesn't create a new timer, and returns the id of the existing timer
|
||||
//! ## Timing subsystem
|
||||
/**
|
||||
* Don't run if there is an identical unique timer active
|
||||
*
|
||||
* if the arguments to addtimer are the same as an existing timer, it doesn't create a new timer,
|
||||
* and returns the id of the existing timer
|
||||
*/
|
||||
#define TIMER_UNIQUE (1<<0)
|
||||
//For unique timers: Replace the old timer rather then not start this one
|
||||
|
||||
///For unique timers: Replace the old timer rather then not start this one
|
||||
#define TIMER_OVERRIDE (1<<1)
|
||||
//Timing should be based on how timing progresses on clients, not the sever.
|
||||
// tracking this is more expensive,
|
||||
// should only be used in conjuction with things that have to progress client side, such as animate() or sound()
|
||||
|
||||
/**
|
||||
* Timing should be based on how timing progresses on clients, not the server.
|
||||
*
|
||||
* Tracking this is more expensive,
|
||||
* should only be used in conjuction with things that have to progress client side, such as
|
||||
* animate() or sound()
|
||||
*/
|
||||
#define TIMER_CLIENT_TIME (1<<2)
|
||||
//Timer can be stopped using deltimer()
|
||||
|
||||
///Timer can be stopped using deltimer()
|
||||
#define TIMER_STOPPABLE (1<<3)
|
||||
//To be used with TIMER_UNIQUE
|
||||
//prevents distinguishing identical timers with the wait variable
|
||||
|
||||
///prevents distinguishing identical timers with the wait variable
|
||||
///
|
||||
///To be used with TIMER_UNIQUE
|
||||
#define TIMER_NO_HASH_WAIT (1<<4)
|
||||
//Loops the timer repeatedly until qdeleted
|
||||
//In most cases you want a subsystem instead
|
||||
|
||||
///Loops the timer repeatedly until qdeleted
|
||||
///
|
||||
///In most cases you want a subsystem instead, so don't use this unless you have a good reason
|
||||
#define TIMER_LOOP (1<<5)
|
||||
|
||||
///Empty ID define
|
||||
#define TIMER_ID_NULL -1
|
||||
|
||||
#define INITIALIZATION_INSSATOMS 0 //New should not call Initialize
|
||||
#define INITIALIZATION_INNEW_MAPLOAD 2 //New should call Initialize(TRUE)
|
||||
#define INITIALIZATION_INNEW_REGULAR 1 //New should call Initialize(FALSE)
|
||||
//! ## Initialization subsystem
|
||||
|
||||
#define INITIALIZE_HINT_NORMAL 0 //Nothing happens
|
||||
#define INITIALIZE_HINT_LATELOAD 1 //Call LateInitialize
|
||||
#define INITIALIZE_HINT_QDEL 2 //Call qdel on the atom
|
||||
///New should not call Initialize
|
||||
#define INITIALIZATION_INSSATOMS 0
|
||||
///New should call Initialize(TRUE)
|
||||
#define INITIALIZATION_INNEW_MAPLOAD 2
|
||||
///New should call Initialize(FALSE)
|
||||
#define INITIALIZATION_INNEW_REGULAR 1
|
||||
|
||||
//type and all subtypes should always call Initialize in New()
|
||||
//! ### Initialization hints
|
||||
|
||||
///Nothing happens
|
||||
#define INITIALIZE_HINT_NORMAL 0
|
||||
/**
|
||||
* call LateInitialize at the end of all atom Initalization
|
||||
*
|
||||
* The item will be added to the late_loaders list, this is iterated over after
|
||||
* initalization of subsystems is complete and calls LateInitalize on the atom
|
||||
* see [this file for the LateIntialize proc](atom.html#proc/LateInitialize)
|
||||
*/
|
||||
#define INITIALIZE_HINT_LATELOAD 1
|
||||
|
||||
///Call qdel on the atom after intialization
|
||||
#define INITIALIZE_HINT_QDEL 2
|
||||
|
||||
///type and all subtypes should always immediately call Initialize in New()
|
||||
#define INITIALIZE_IMMEDIATE(X) ##X/New(loc, ...){\
|
||||
..();\
|
||||
if(!(flags_1 & INITIALIZED_1)) {\
|
||||
@@ -127,7 +179,9 @@
|
||||
|
||||
|
||||
// Truly disgusting, TG. Truly disgusting.
|
||||
//! ## Overlays subsystem
|
||||
|
||||
///Compile all the overlays for an atom from the cache lists
|
||||
#define COMPILE_OVERLAYS(A)\
|
||||
if (TRUE) {\
|
||||
var/list/ad = A.add_overlays;\
|
||||
|
||||
@@ -1095,14 +1095,19 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
|
||||
obj_flags &= ~FROZEN
|
||||
|
||||
|
||||
//Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
|
||||
// exporting it as text, and then parsing the base64 from that.
|
||||
// (This relies on byond automatically storing icons in savefiles as base64)
|
||||
/proc/icon2base64(icon/icon, iconKey = "misc")
|
||||
/// Save file used in icon2base64. Used for converting icons to base64.
|
||||
GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of icons for the browser output
|
||||
|
||||
/**
|
||||
* Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
|
||||
* exporting it as text, and then parsing the base64 from that.
|
||||
* (This relies on byond automatically storing icons in savefiles as base64)
|
||||
*/
|
||||
/proc/icon2base64(icon/icon)
|
||||
if (!isicon(icon))
|
||||
return FALSE
|
||||
WRITE_FILE(GLOB.iconCache[iconKey], icon)
|
||||
var/iconData = GLOB.iconCache.ExportText(iconKey)
|
||||
WRITE_FILE(GLOB.dummySave["dummy"], icon)
|
||||
var/iconData = GLOB.dummySave.ExportText("dummy")
|
||||
var/list/partial = splittext(iconData, "{")
|
||||
return replacetext(copytext_char(partial[2], 3, -5), "\n", "")
|
||||
|
||||
@@ -1188,7 +1193,7 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
|
||||
I = icon()
|
||||
I.Insert(temp, dir = SOUTH)
|
||||
|
||||
bicon_cache[key] = icon2base64(I, key)
|
||||
bicon_cache[key] = icon2base64(I)
|
||||
|
||||
return "<img class='icon icon-[A.icon_state]' src='data:image/png;base64,[bicon_cache[key]]'>"
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
**/
|
||||
|
||||
//This is the ABSOLUTE ONLY THING that should init globally like this
|
||||
//2019 update: the failsafe,config and Global controllers also do it
|
||||
GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
|
||||
//THIS IS THE INIT ORDER
|
||||
|
||||
@@ -447,6 +447,7 @@ SUBSYSTEM_DEF(timer)
|
||||
next.prev = src
|
||||
prev.next = src
|
||||
|
||||
///Returns a string of the type of the callback for this timer
|
||||
/datum/timedevent/proc/getcallingtype()
|
||||
. = "ERROR"
|
||||
if (callBack.object == GLOBAL_PROC)
|
||||
@@ -454,6 +455,14 @@ SUBSYSTEM_DEF(timer)
|
||||
else
|
||||
. = "[callBack.object.type]"
|
||||
|
||||
/**
|
||||
* Create a new timer and insert it in the queue
|
||||
*
|
||||
* Arguments:
|
||||
* * callback the callback to call on timer finish
|
||||
* * wait deciseconds to run the timer for
|
||||
* * flags flags for this timer, see: code\__DEFINES\subsystems.dm
|
||||
*/
|
||||
/proc/addtimer(datum/callback/callback, wait = 0, flags = 0)
|
||||
if (!callback)
|
||||
CRASH("addtimer called without a callback")
|
||||
@@ -498,6 +507,12 @@ SUBSYSTEM_DEF(timer)
|
||||
var/datum/timedevent/timer = new(callback, wait, flags, hash)
|
||||
return timer.id
|
||||
|
||||
/**
|
||||
* Delete a timer
|
||||
*
|
||||
* Arguments:
|
||||
* * id a timerid or a /datum/timedevent
|
||||
*/
|
||||
/proc/deltimer(id)
|
||||
if (!id)
|
||||
return FALSE
|
||||
@@ -514,6 +529,26 @@ SUBSYSTEM_DEF(timer)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Get the remaining deciseconds on a timer
|
||||
*
|
||||
* Arguments:
|
||||
* * id a timerid or a /datum/timedevent
|
||||
*/
|
||||
/proc/timeleft(id)
|
||||
if (!id)
|
||||
return null
|
||||
if (id == TIMER_ID_NULL)
|
||||
CRASH("Tried to get timeleft of a null timerid. Use TIMER_STOPPABLE flag")
|
||||
if (!istext(id))
|
||||
if (istype(id, /datum/timedevent))
|
||||
var/datum/timedevent/timer = id
|
||||
return timer.timeToRun - world.time
|
||||
//id is string
|
||||
var/datum/timedevent/timer = SStimer.timer_id_dict[id]
|
||||
if (timer && !timer.spent)
|
||||
return timer.timeToRun - world.time
|
||||
return null
|
||||
|
||||
#undef BUCKET_LEN
|
||||
#undef BUCKET_POS
|
||||
|
||||
@@ -1,55 +1,72 @@
|
||||
/*
|
||||
USAGE:
|
||||
|
||||
var/datum/callback/C = new(object|null, /proc/type/path|"procstring", arg1, arg2, ... argn)
|
||||
var/timerid = addtimer(C, time, timertype)
|
||||
OR
|
||||
var/timerid = addtimer(CALLBACK(object|null, /proc/type/path|procstring, arg1, arg2, ... argn), time, timertype)
|
||||
|
||||
Note: proc strings can only be given for datum proc calls, global procs must be proc paths
|
||||
Also proc strings are strongly advised against because they don't compile error if the proc stops existing
|
||||
See the note on proc typepath shortcuts
|
||||
|
||||
INVOKING THE CALLBACK:
|
||||
var/result = C.Invoke(args, to, add) //additional args are added after the ones given when the callback was created
|
||||
OR
|
||||
var/result = C.InvokeAsync(args, to, add) //Sleeps will not block, returns . on the first sleep (then continues on in the "background" after the sleep/block ends), otherwise operates normally.
|
||||
OR
|
||||
INVOKE_ASYNC(<CALLBACK args>) to immediately create and call InvokeAsync
|
||||
|
||||
PROC TYPEPATH SHORTCUTS (these operate on paths, not types, so to these shortcuts, datum is NOT a parent of atom, etc...)
|
||||
|
||||
global proc while in another global proc:
|
||||
.procname
|
||||
Example:
|
||||
CALLBACK(GLOBAL_PROC, .some_proc_here)
|
||||
|
||||
proc defined on current(src) object (when in a /proc/ and not an override) OR overridden at src or any of it's parents:
|
||||
.procname
|
||||
Example:
|
||||
CALLBACK(src, .some_proc_here)
|
||||
|
||||
|
||||
when the above doesn't apply:
|
||||
.proc/procname
|
||||
Example:
|
||||
CALLBACK(src, .proc/some_proc_here)
|
||||
|
||||
proc defined on a parent of a some type:
|
||||
/some/type/.proc/some_proc_here
|
||||
|
||||
|
||||
|
||||
Other wise you will have to do the full typepath of the proc (/type/of/thing/proc/procname)
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
*# Callback Datums
|
||||
*A datum that holds a proc to be called on another object, used to track proccalls to other objects
|
||||
*
|
||||
* ## USAGE
|
||||
*
|
||||
* ```
|
||||
* var/datum/callback/C = new(object|null, /proc/type/path|"procstring", arg1, arg2, ... argn)
|
||||
* var/timerid = addtimer(C, time, timertype)
|
||||
* you can also use the compiler define shorthand
|
||||
* var/timerid = addtimer(CALLBACK(object|null, /proc/type/path|procstring, arg1, arg2, ... argn), time, timertype)
|
||||
* ```
|
||||
*
|
||||
* Note: proc strings can only be given for datum proc calls, global procs must be proc paths
|
||||
*
|
||||
* Also proc strings are strongly advised against because they don't compile error if the proc stops existing
|
||||
*
|
||||
* In some cases you can provide a shortform of the procname, see the proc typepath shortcuts documentation below
|
||||
*
|
||||
* ## INVOKING THE CALLBACK
|
||||
*`var/result = C.Invoke(args, to, add)` additional args are added after the ones given when the callback was created
|
||||
*
|
||||
* `var/result = C.InvokeAsync(args, to, add)` Asyncronous - returns . on the first sleep then continues on in the background
|
||||
* after the sleep/block ends, otherwise operates normally.
|
||||
*
|
||||
* ## PROC TYPEPATH SHORTCUTS
|
||||
* (these operate on paths, not types, so to these shortcuts, datum is NOT a parent of atom, etc...)
|
||||
*
|
||||
* ### global proc while in another global proc:
|
||||
* .procname
|
||||
*
|
||||
* `CALLBACK(GLOBAL_PROC, .some_proc_here)`
|
||||
*
|
||||
* ### proc defined on current(src) object (when in a /proc/ and not an override) OR overridden at src or any of it's parents:
|
||||
* .procname
|
||||
*
|
||||
* `CALLBACK(src, .some_proc_here)`
|
||||
*
|
||||
* ### when the above doesn't apply:
|
||||
*.proc/procname
|
||||
*
|
||||
* `CALLBACK(src, .proc/some_proc_here)`
|
||||
*
|
||||
*
|
||||
* proc defined on a parent of a some type
|
||||
*
|
||||
* `/some/type/.proc/some_proc_here`
|
||||
*
|
||||
* Otherwise you must always provide the full typepath of the proc (/type/of/thing/proc/procname)
|
||||
*/
|
||||
/datum/callback
|
||||
|
||||
///The object we will be calling the proc on
|
||||
var/datum/object = GLOBAL_PROC
|
||||
///The proc we will be calling on the object
|
||||
var/delegate
|
||||
///A list of arguments to pass into the proc
|
||||
var/list/arguments
|
||||
///A weak reference to the user who triggered this callback
|
||||
var/datum/weakref/user
|
||||
|
||||
/**
|
||||
* Create a new callback datum
|
||||
*
|
||||
* Arguments
|
||||
* * thingtocall the object to call the proc on
|
||||
* * proctocall the proc to call on the target object
|
||||
* * ... an optional list of extra arguments to pass to the proc
|
||||
*/
|
||||
/datum/callback/New(thingtocall, proctocall, ...)
|
||||
if (thingtocall)
|
||||
object = thingtocall
|
||||
@@ -58,7 +75,14 @@
|
||||
arguments = args.Copy(3)
|
||||
if(usr)
|
||||
user = WEAKREF(usr)
|
||||
|
||||
/**
|
||||
* Immediately Invoke proctocall on thingtocall, with waitfor set to false
|
||||
*
|
||||
* Arguments:
|
||||
* * thingtocall Object to call on
|
||||
* * proctocall Proc to call on that object
|
||||
* * ... optional list of arguments to pass as arguments to the proc being called
|
||||
*/
|
||||
/world/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...)
|
||||
set waitfor = FALSE
|
||||
|
||||
@@ -72,6 +96,14 @@
|
||||
else
|
||||
call(thingtocall, proctocall)(arglist(calling_arguments))
|
||||
|
||||
/**
|
||||
* Invoke this callback
|
||||
*
|
||||
* Calls the registered proc on the registered object, if the user ref
|
||||
* can be resolved it also inclues that as an arg
|
||||
*
|
||||
* If the datum being called on is varedited, the call is wrapped via WrapAdminProcCall
|
||||
*/
|
||||
/datum/callback/proc/Invoke(...)
|
||||
if(!usr)
|
||||
var/datum/weakref/W = user
|
||||
@@ -97,7 +129,14 @@
|
||||
return call(delegate)(arglist(calling_arguments))
|
||||
return call(object, delegate)(arglist(calling_arguments))
|
||||
|
||||
//copy and pasted because fuck proc overhead
|
||||
/**
|
||||
* Invoke this callback async (waitfor=false)
|
||||
*
|
||||
* Calls the registered proc on the registered object, if the user ref
|
||||
* can be resolved it also inclues that as an arg
|
||||
*
|
||||
* If the datum being called on is varedited, the call is wrapped via WrapAdminProcCall
|
||||
*/
|
||||
/datum/callback/proc/InvokeAsync(...)
|
||||
set waitfor = FALSE
|
||||
|
||||
@@ -125,7 +164,9 @@
|
||||
return call(delegate)(arglist(calling_arguments))
|
||||
return call(object, delegate)(arglist(calling_arguments))
|
||||
|
||||
|
||||
/**
|
||||
Helper datum for the select callbacks proc
|
||||
*/
|
||||
/datum/callback_select
|
||||
var/list/finished
|
||||
var/pendingcount
|
||||
@@ -150,15 +191,17 @@
|
||||
if (savereturn)
|
||||
finished[index] = rtn
|
||||
|
||||
|
||||
|
||||
|
||||
//runs a list of callbacks asynchronously, returning once all of them return.
|
||||
//callbacks can be repeated.
|
||||
//callbacks-args is an optional list of argument lists, in the same order as the callbacks,
|
||||
// the inner lists will be sent to the callbacks when invoked() as additional args.
|
||||
//can optionly save and return a list of return values, in the same order as the original list of callbacks
|
||||
//resolution is the number of byond ticks between checks.
|
||||
/**
|
||||
* Runs a list of callbacks asyncronously, returning only when all have finished
|
||||
*
|
||||
* Callbacks can be repeated, to call it multiple times
|
||||
*
|
||||
* Arguments:
|
||||
* * list/callbacks the list of callbacks to be called
|
||||
* * list/callback_args the list of lists of arguments to pass into each callback
|
||||
* * savereturns Optionally save and return the list of returned values from each of the callbacks
|
||||
* * resolution The number of byond ticks between each time you check if all callbacks are complete
|
||||
*/
|
||||
/proc/callback_select(list/callbacks, list/callback_args, savereturns = TRUE, resolution = 1)
|
||||
if (!callbacks)
|
||||
return
|
||||
|
||||
@@ -1,12 +1,38 @@
|
||||
/**
|
||||
* The absolute base class for everything
|
||||
*
|
||||
* A datum instantiated has no physical world prescence, use an atom if you want something
|
||||
* that actually lives in the world
|
||||
*
|
||||
* Be very mindful about adding variables to this class, they are inherited by every single
|
||||
* thing in the entire game, and so you can easily cause memory usage to rise a lot with careless
|
||||
* use of variables at this level
|
||||
*/
|
||||
/datum
|
||||
var/gc_destroyed //Time when this object was destroyed.
|
||||
var/list/active_timers //for SStimer
|
||||
var/list/datum_components //for /datum/components
|
||||
/**
|
||||
* Tick count time when this object was destroyed.
|
||||
*
|
||||
* If this is non zero then the object has been garbage collected and is awaiting either
|
||||
* a hard del by the GC subsystme, or to be autocollected (if it has no references)
|
||||
*/
|
||||
var/gc_destroyed
|
||||
|
||||
/// Active timers with this datum as the target
|
||||
var/list/active_timers
|
||||
/// Components attached to this datum
|
||||
var/list/datum_components
|
||||
/// Status traits attached to this datum
|
||||
var/list/status_traits
|
||||
var/list/comp_lookup //it used to be for looking up components which had registered a signal but now anything can register
|
||||
/// Any datum registered to receive signals from this datum is in this list
|
||||
var/list/comp_lookup
|
||||
/// List of callbacks for signal procs
|
||||
var/list/list/datum/callback/signal_procs
|
||||
/// Is this datum capable of sending signals?
|
||||
var/signal_enabled = FALSE
|
||||
/// Datum level flags
|
||||
var/datum_flags = NONE
|
||||
|
||||
/// A weak reference to another datum
|
||||
var/datum/weakref/weak_reference
|
||||
|
||||
#ifdef TESTING
|
||||
@@ -18,13 +44,31 @@
|
||||
var/list/cached_vars
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Called when a href for this datum is clicked
|
||||
*
|
||||
* Sends a COMSIG_TOPIC signal
|
||||
*/
|
||||
/datum/Topic(href, href_list[])
|
||||
..()
|
||||
SEND_SIGNAL(src, COMSIG_TOPIC, usr, href_list)
|
||||
|
||||
// Default implementation of clean-up code.
|
||||
// This should be overridden to remove all references pointing to the object being destroyed.
|
||||
// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE.
|
||||
/**
|
||||
* Default implementation of clean-up code.
|
||||
*
|
||||
* This should be overridden to remove all references pointing to the object being destroyed, if
|
||||
* you do override it, make sure to call the parent and return it's return value by default
|
||||
*
|
||||
* Return an appropriate QDEL_HINT to modify handling of your deletion;
|
||||
* in most cases this is QDEL_HINT_QUEUE.
|
||||
*
|
||||
* The base case is responsible for doing the following
|
||||
* * Erasing timers pointing to this datum
|
||||
* * Erasing compenents on this datum
|
||||
* * Notifying datums listening to signals from this datum that we are going away
|
||||
*
|
||||
* Returns QDEL_HINT_QUEUE
|
||||
*/
|
||||
/datum/proc/Destroy(force=FALSE, ...)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
tag = null
|
||||
@@ -100,15 +144,15 @@
|
||||
to_chat(target, txt_changed_vars())
|
||||
#endif
|
||||
|
||||
//Return a LIST for serialize_datum to encode! Not the actual json!
|
||||
///Return a LIST for serialize_datum to encode! Not the actual json!
|
||||
/datum/proc/serialize_list(list/options)
|
||||
CRASH("Attempted to serialize datum [src] of type [type] without serialize_list being implemented!")
|
||||
|
||||
//Accepts a LIST from deserialize_datum. Should return src or another datum.
|
||||
///Accepts a LIST from deserialize_datum. Should return src or another datum.
|
||||
/datum/proc/deserialize_list(json, list/options)
|
||||
CRASH("Attempted to deserialize datum [src] of type [type] without deserialize_list being implemented!")
|
||||
|
||||
//Serializes into JSON. Does not encode type.
|
||||
///Serializes into JSON. Does not encode type.
|
||||
/datum/proc/serialize_json(list/options)
|
||||
. = serialize_list(options)
|
||||
if(!islist(.))
|
||||
@@ -116,13 +160,14 @@
|
||||
else
|
||||
. = json_encode(.)
|
||||
|
||||
//Deserializes from JSON. Does not parse type.
|
||||
///Deserializes from JSON. Does not parse type.
|
||||
/datum/proc/deserialize_json(list/input, list/options)
|
||||
var/list/jsonlist = json_decode(input)
|
||||
. = deserialize_list(jsonlist)
|
||||
if(!istype(., /datum))
|
||||
. = null
|
||||
|
||||
///Convert a datum into a json blob
|
||||
/proc/json_serialize_datum(datum/D, list/options)
|
||||
if(!istype(D))
|
||||
return
|
||||
@@ -131,6 +176,7 @@
|
||||
jsonlist["DATUM_TYPE"] = D.type
|
||||
return json_encode(jsonlist)
|
||||
|
||||
/// Convert a list of json to datum
|
||||
/proc/json_deserialize_datum(list/jsonlist, list/options, target_type, strict_target_type = FALSE)
|
||||
if(!islist(jsonlist))
|
||||
if(!istext(jsonlist))
|
||||
|
||||
@@ -1,41 +1,153 @@
|
||||
/**
|
||||
* # Outfit datums
|
||||
*
|
||||
* This is a clean system of applying outfits to mobs, if you need to equip someone in a uniform
|
||||
* this is the way to do it cleanly and properly.
|
||||
*
|
||||
* You can also specify an outfit datum on a job to have it auto equipped to the mob on join
|
||||
*
|
||||
* /mob/living/carbon/human/proc/equipOutfit(outfit) is the mob level proc to equip an outfit
|
||||
* and you pass it the relevant datum outfit
|
||||
*
|
||||
* outfits can also be saved as json blobs downloadable by a client and then can be uploaded
|
||||
* by that user to recreate the outfit, this is used by admins to allow for custom event outfits
|
||||
* that can be restored at a later date
|
||||
*/
|
||||
/datum/outfit
|
||||
///Name of the outfit (shows up in the equip admin verb)
|
||||
var/name = "Naked"
|
||||
|
||||
/// Type path of item to go in uniform slot
|
||||
var/uniform = null
|
||||
|
||||
/// Type path of item to go in suit slot
|
||||
var/suit = null
|
||||
var/toggle_helmet = TRUE
|
||||
|
||||
/// Type path of item to go in back slot
|
||||
var/back = null
|
||||
|
||||
/// Type path of item to go in belt slot
|
||||
var/belt = null
|
||||
|
||||
/// Type path of item to go in gloves slot
|
||||
var/gloves = null
|
||||
|
||||
/// Type path of item to go in shoes slot
|
||||
var/shoes = null
|
||||
|
||||
/// Type path of item to go in head slot
|
||||
var/head = null
|
||||
|
||||
/// Type path of item to go in mask slot
|
||||
var/mask = null
|
||||
|
||||
/// Type path of item to go in neck slot
|
||||
var/neck = null
|
||||
|
||||
/// Type path of item to go in ears slot
|
||||
var/ears = null
|
||||
|
||||
/// Type path of item to go in the glasses slot
|
||||
var/glasses = null
|
||||
|
||||
/// Type path of item to go in the idcard slot
|
||||
var/id = null
|
||||
|
||||
/// Type path of item for left pocket slot
|
||||
var/l_pocket = null
|
||||
|
||||
/// Type path of item for right pocket slot
|
||||
var/r_pocket = null
|
||||
|
||||
/**
|
||||
* Type path of item to go in suit storage slot
|
||||
*
|
||||
* (make sure it's valid for that suit)
|
||||
*/
|
||||
var/suit_store = null
|
||||
|
||||
///Type path of item to go in the right hand
|
||||
var/r_hand = null
|
||||
|
||||
//Type path of item to go in left hand
|
||||
var/l_hand = null
|
||||
var/internals_slot = null //ID of slot containing a gas tank
|
||||
var/list/backpack_contents = null // In the list(path=count,otherpath=count) format
|
||||
var/box // Internals box. Will be inserted at the start of backpack_contents
|
||||
|
||||
/// Should the toggle helmet proc be called on the helmet during equip
|
||||
var/toggle_helmet = TRUE
|
||||
|
||||
///ID of the slot containing a gas tank
|
||||
var/internals_slot = null
|
||||
|
||||
/**
|
||||
* list of items that should go in the backpack of the user
|
||||
*
|
||||
* Format of this list should be: list(path=count,otherpath=count)
|
||||
*/
|
||||
var/list/backpack_contents = null
|
||||
|
||||
/// Internals box. Will be inserted at the start of backpack_contents
|
||||
var/box
|
||||
|
||||
/**
|
||||
* Any implants the mob should start implanted with
|
||||
*
|
||||
* Format of this list is (typepath, typepath, typepath)
|
||||
*/
|
||||
var/list/implants = null
|
||||
|
||||
/// Any clothing accessory item
|
||||
var/accessory = null
|
||||
|
||||
var/can_be_admin_equipped = TRUE // Set to FALSE if your outfit requires runtime parameters
|
||||
var/list/chameleon_extras //extra types for chameleon outfit changes, mostly guns
|
||||
/// Set to FALSE if your outfit requires runtime parameters
|
||||
var/can_be_admin_equipped = TRUE
|
||||
|
||||
/**
|
||||
* extra types for chameleon outfit changes, mostly guns
|
||||
*
|
||||
* Format of this list is (typepath, typepath, typepath)
|
||||
*
|
||||
* These are all added and returns in the list for get_chamelon_diguise_info proc
|
||||
*/
|
||||
var/list/chameleon_extras
|
||||
|
||||
/**
|
||||
* Called at the start of the equip proc
|
||||
*
|
||||
* Override to change the value of the slots depending on client prefs, species and
|
||||
* other such sources of change
|
||||
*
|
||||
* Extra Arguments
|
||||
* * visualsOnly true if this is only for display (in the character setup screen)
|
||||
*
|
||||
* If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
|
||||
*/
|
||||
/datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
//to be overridden for customization depending on client prefs,species etc
|
||||
return
|
||||
|
||||
/**
|
||||
* Called after the equip proc has finished
|
||||
*
|
||||
* All items are on the mob at this point, use this proc to toggle internals
|
||||
* fiddle with id bindings and accesses etc
|
||||
*
|
||||
* Extra Arguments
|
||||
* * visualsOnly true if this is only for display (in the character setup screen)
|
||||
*
|
||||
* If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
|
||||
*/
|
||||
/datum/outfit/proc/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
//to be overridden for toggling internals, id binding, access etc
|
||||
return
|
||||
|
||||
/**
|
||||
* Equips all defined types and paths to the mob passed in
|
||||
*
|
||||
* Extra Arguments
|
||||
* * visualsOnly true if this is only for display (in the character setup screen)
|
||||
*
|
||||
* If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
|
||||
*/
|
||||
/datum/outfit/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
pre_equip(H, visualsOnly)
|
||||
|
||||
@@ -118,6 +230,13 @@
|
||||
H.update_body()
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Apply a fingerprint from the passed in human to all items in the outfit
|
||||
*
|
||||
* Used for forensics setup when the mob is first equipped at roundstart
|
||||
* essentially calls add_fingerprint to every defined item on the human
|
||||
*
|
||||
*/
|
||||
/datum/outfit/proc/apply_fingerprints(mob/living/carbon/human/H)
|
||||
if(!istype(H))
|
||||
return
|
||||
@@ -159,12 +278,14 @@
|
||||
I.add_fingerprint(H,1)
|
||||
return 1
|
||||
|
||||
/// Return a list of all the types that are required to disguise as this outfit type
|
||||
/datum/outfit/proc/get_chameleon_disguise_info()
|
||||
var/list/types = list(uniform, suit, back, belt, gloves, shoes, head, mask, neck, ears, glasses, id, l_pocket, r_pocket, suit_store, r_hand, l_hand)
|
||||
types += chameleon_extras
|
||||
listclearnulls(types)
|
||||
return types
|
||||
|
||||
/// Return a json list of this outfit
|
||||
/datum/outfit/proc/get_json_data()
|
||||
. = list()
|
||||
.["outfit_type"] = type
|
||||
@@ -193,6 +314,7 @@
|
||||
.["implants"] = implants
|
||||
.["accessory"] = accessory
|
||||
|
||||
/// Prompt the passed in mob client to download this outfit as a json blob
|
||||
/datum/outfit/proc/save_to_file(mob/admin)
|
||||
var/stored_data = get_json_data()
|
||||
var/json = json_encode(stored_data)
|
||||
@@ -202,6 +324,7 @@
|
||||
WRITE_FILE(f,json)
|
||||
admin << ftp(f,"[name].json")
|
||||
|
||||
/// Create an outfit datum from a list of json data
|
||||
/datum/outfit/proc/load_from(list/outfit_data)
|
||||
//This could probably use more strict validation
|
||||
name = outfit_data["name"]
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
// Areas.dm
|
||||
|
||||
|
||||
/**
|
||||
* # area
|
||||
*
|
||||
* A grouping of tiles into a logical space, mostly used by map editors
|
||||
*/
|
||||
/area
|
||||
level = null
|
||||
name = "Space"
|
||||
icon = 'icons/turf/areas.dmi'
|
||||
icon_state = "unknown"
|
||||
layer = AREA_LAYER
|
||||
plane = BLACKNESS_PLANE //Keeping this on the default plane, GAME_PLANE, will make area overlays fail to render on FLOOR_PLANE.
|
||||
//Keeping this on the default plane, GAME_PLANE, will make area overlays fail to render on FLOOR_PLANE.
|
||||
plane = BLACKNESS_PLANE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
|
||||
@@ -37,9 +40,9 @@
|
||||
|
||||
var/areasize = 0 //Size of the area in open turfs, only calculated for indoors areas.
|
||||
|
||||
//Bonus mood from being in this area
|
||||
/// Bonus mood for being in this area
|
||||
var/mood_bonus = 0
|
||||
//Mood message for being here, only shows up if mood_bonus != 0
|
||||
/// Mood message for being here, only shows up if mood_bonus != 0
|
||||
var/mood_message = "<span class='nicegreen'>This area is pretty nice!\n</span>"
|
||||
|
||||
var/power_equip = TRUE
|
||||
@@ -53,9 +56,12 @@
|
||||
var/static_environ
|
||||
|
||||
var/has_gravity = 0
|
||||
var/noteleport = FALSE //Are you forbidden from teleporting to the area? (centcom, mobs, wizard, hand teleporter)
|
||||
var/hidden = FALSE //Hides area from player Teleport function.
|
||||
var/safe = FALSE //Is the area teleport-safe: no space / radiation / aggresive mobs / other dangers
|
||||
///Are you forbidden from teleporting to the area? (centcom, mobs, wizard, hand teleporter)
|
||||
var/noteleport = FALSE
|
||||
///Hides area from player Teleport function.
|
||||
var/hidden = FALSE
|
||||
///Is the area teleport-safe: no space / radiation / aggresive mobs / other dangers
|
||||
var/safe = FALSE
|
||||
/// If false, loading multiple maps with this area type will create multiple instances.
|
||||
var/unique = TRUE
|
||||
|
||||
@@ -72,15 +78,30 @@
|
||||
var/list/cameras
|
||||
var/list/firealarms
|
||||
var/firedoors_last_closed_on = 0
|
||||
var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default?
|
||||
var/list/canSmoothWithAreas //typecache to limit the areas that atoms in this area can smooth with
|
||||
/// Can the Xenobio management console transverse this area by default?
|
||||
var/xenobiology_compatible = FALSE
|
||||
/// typecache to limit the areas that atoms in this area can smooth with, used for shuttles IIRC
|
||||
var/list/canSmoothWithAreas
|
||||
|
||||
var/minimap_color = null // if null, chooses random one
|
||||
|
||||
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
|
||||
/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/
|
||||
/**
|
||||
* A list of teleport locations
|
||||
*
|
||||
* Adding a wizard area teleport list because motherfucking lag -- Urist
|
||||
* I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game
|
||||
*/
|
||||
GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
|
||||
/**
|
||||
* Generate a list of turfs you can teleport to from the areas list
|
||||
*
|
||||
* Includes areas if they're not a shuttle or not not teleport or have no contents
|
||||
*
|
||||
* The chosen turf is the first item in the areas contents that is a station level
|
||||
*
|
||||
* The returned list of turfs is sorted by name
|
||||
*/
|
||||
/proc/process_teleport_locs()
|
||||
for(var/V in GLOB.sortedAreas)
|
||||
var/area/AR = V
|
||||
@@ -96,8 +117,11 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
|
||||
sortTim(GLOB.teleportlocs, /proc/cmp_text_dsc)
|
||||
|
||||
// ===
|
||||
|
||||
/**
|
||||
* Called when an area loads
|
||||
*
|
||||
* Adds the item to the GLOB.areas_by_type list based on area type
|
||||
*/
|
||||
/area/New()
|
||||
if(!minimap_color) // goes in New() because otherwise it doesn't fucking work
|
||||
// generate one using the icon_state
|
||||
@@ -114,6 +138,14 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
GLOB.areas_by_type[type] = src
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Initalize this area
|
||||
*
|
||||
* intializes the dynamic area lighting and also registers the area with the z level via
|
||||
* reg_in_areas_in_z
|
||||
*
|
||||
* returns INITIALIZE_HINT_LATELOAD
|
||||
*/
|
||||
/area/Initialize()
|
||||
icon_state = ""
|
||||
layer = AREA_LAYER
|
||||
@@ -147,9 +179,21 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/**
|
||||
* Sets machine power levels in the area
|
||||
*/
|
||||
/area/LateInitialize()
|
||||
power_change() // all machines set to current power level, also updates icon
|
||||
|
||||
/**
|
||||
* Register this area as belonging to a z level
|
||||
*
|
||||
* Ensures the item is added to the SSmapping.areas_in_z list for this z
|
||||
*
|
||||
* It also goes through every item in this areas contents and sets the area level z to it
|
||||
* breaking the exat first time it does this, this seems crazy but what would I know, maybe
|
||||
* areas don't have a valid z themself or something
|
||||
*/
|
||||
/area/proc/reg_in_areas_in_z()
|
||||
if(contents.len)
|
||||
var/list/areas_in_z = SSmapping.areas_in_z
|
||||
@@ -168,12 +212,25 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
areas_in_z["[z]"] = list()
|
||||
areas_in_z["[z]"] += src
|
||||
|
||||
/**
|
||||
* Destroy an area and clean it up
|
||||
*
|
||||
* Removes the area from GLOB.areas_by_type and also stops it processing on SSobj
|
||||
*
|
||||
* This is despite the fact that no code appears to put it on SSobj, but
|
||||
* who am I to argue with old coders
|
||||
*/
|
||||
/area/Destroy()
|
||||
if(GLOB.areas_by_type[type] == src)
|
||||
GLOB.areas_by_type[type] = null
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Generate a power alert for this area
|
||||
*
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*/
|
||||
/area/proc/poweralert(state, obj/source)
|
||||
if (state != poweralm)
|
||||
poweralm = state
|
||||
@@ -205,6 +262,11 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
else
|
||||
p.triggerAlarm("Power", src, cameras, source)
|
||||
|
||||
/**
|
||||
* Generate an atmospheric alert for this area
|
||||
*
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*/
|
||||
/area/proc/atmosalert(danger_level, obj/source)
|
||||
if(danger_level != atmosalm)
|
||||
if (danger_level==2)
|
||||
@@ -240,6 +302,9 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/**
|
||||
* Try to close all the firedoors in the area
|
||||
*/
|
||||
/area/proc/ModifyFiredoors(opening)
|
||||
if(firedoors)
|
||||
firedoors_last_closed_on = world.time
|
||||
@@ -258,6 +323,13 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
else if(!(D.density ^ opening))
|
||||
INVOKE_ASYNC(D, (opening ? /obj/machinery/door/firedoor.proc/open : /obj/machinery/door/firedoor.proc/close))
|
||||
|
||||
/**
|
||||
* Generate an firealarm alert for this area
|
||||
*
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*
|
||||
* Also starts the area processing on SSobj
|
||||
*/
|
||||
/area/proc/firealert(obj/source)
|
||||
if(always_unpowered == 1) //no fire alarms in space/asteroid
|
||||
return
|
||||
@@ -284,6 +356,14 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/**
|
||||
* Reset the firealarm alert for this area
|
||||
*
|
||||
* resets the alert sent to all ai players, alert consoles, drones and alarm monitor programs
|
||||
* in the world
|
||||
*
|
||||
* Also cycles the icons of all firealarms and deregisters the area from processing on SSOBJ
|
||||
*/
|
||||
/area/proc/firereset(obj/source)
|
||||
if (fire)
|
||||
unset_fire_alarm_effects()
|
||||
@@ -307,16 +387,31 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/**
|
||||
* If 100 ticks has elapsed, toggle all the firedoors closed again
|
||||
*/
|
||||
/area/process()
|
||||
if(firedoors_last_closed_on + 100 < world.time) //every 10 seconds
|
||||
ModifyFiredoors(FALSE)
|
||||
|
||||
/**
|
||||
* Close and lock a door passed into this proc
|
||||
*
|
||||
* Does this need to exist on area? probably not
|
||||
*/
|
||||
/area/proc/close_and_lock_door(obj/machinery/door/DOOR)
|
||||
set waitfor = FALSE
|
||||
DOOR.close()
|
||||
if(DOOR.density)
|
||||
DOOR.lock()
|
||||
|
||||
/**
|
||||
* Raise a burglar alert for this area
|
||||
*
|
||||
* Close and locks all doors in the area and alerts silicon mobs of a break in
|
||||
*
|
||||
* Alarm auto resets after 600 ticks
|
||||
*/
|
||||
/area/proc/burglaralert(obj/trigger)
|
||||
if(always_unpowered) //no burglar alarms in space/asteroid
|
||||
return
|
||||
@@ -333,6 +428,11 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
//Cancel silicon alert after 1 minute
|
||||
addtimer(CALLBACK(SILICON, /mob/living/silicon.proc/cancelAlarm,"Burglar",src,trigger), 600)
|
||||
|
||||
/**
|
||||
* Trigger the fire alarm visual affects in an area
|
||||
*
|
||||
* Updates the fire light on fire alarms in the area and sets all lights to emergency mode
|
||||
*/
|
||||
/area/proc/set_fire_alarm_effect()
|
||||
fire = TRUE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
@@ -342,6 +442,11 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
for(var/obj/machinery/light/L in src)
|
||||
L.update()
|
||||
|
||||
/**
|
||||
* unset the fire alarm visual affects in an area
|
||||
*
|
||||
* Updates the fire light on fire alarms in the area and sets all lights to emergency mode
|
||||
*/
|
||||
/area/proc/unset_fire_alarm_effects()
|
||||
fire = FALSE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
@@ -363,6 +468,12 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
for(var/obj/machinery/light/L in src)
|
||||
L.update()
|
||||
|
||||
/**
|
||||
* Update the icon of the area
|
||||
*
|
||||
* Im not sure what the heck this does, somethign to do with weather being able to set icon
|
||||
* states on areas?? where the heck would that even display?
|
||||
*/
|
||||
/area/proc/update_icon()
|
||||
var/weather_icon
|
||||
for(var/V in SSweather.processing)
|
||||
@@ -373,15 +484,19 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
if(!weather_icon)
|
||||
icon_state = null
|
||||
|
||||
/**
|
||||
* Update the icon of the area (overridden to always be null for space
|
||||
*/
|
||||
/area/space/update_icon()
|
||||
icon_state = null
|
||||
|
||||
/*
|
||||
#define EQUIP 1
|
||||
#define LIGHT 2
|
||||
#define ENVIRON 3
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns int 1 or 0 if the area has power for the given channel
|
||||
*
|
||||
* evalutes a mixture of variables mappers can set, requires_power, always_unpowered and then
|
||||
* per channel power_equip, power_light, power_environ
|
||||
*/
|
||||
/area/proc/powered(chan) // return true if the area has power to given channel
|
||||
|
||||
if(!requires_power)
|
||||
@@ -398,16 +513,25 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
|
||||
return 0
|
||||
|
||||
/**
|
||||
* Space is not powered ever, so this returns 0
|
||||
*/
|
||||
/area/space/powered(chan) //Nope.avi
|
||||
return 0
|
||||
|
||||
// called when power status changes
|
||||
|
||||
/**
|
||||
* Called when the area power status changes
|
||||
*
|
||||
* Updates the area icon and calls power change on all machinees in the area
|
||||
*/
|
||||
/area/proc/power_change()
|
||||
for(var/obj/machinery/M in src) // for each machine in the area
|
||||
M.power_change() // reverify power status (to update icons etc.)
|
||||
update_icon()
|
||||
|
||||
/**
|
||||
* Return the usage of power per channel
|
||||
*/
|
||||
/area/proc/usage(chan)
|
||||
var/used = 0
|
||||
switch(chan)
|
||||
@@ -427,6 +551,14 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
used += static_environ
|
||||
return used
|
||||
|
||||
/**
|
||||
* Add a static amount of power load to an area
|
||||
*
|
||||
* Possible channels
|
||||
* *STATIC_EQUIP
|
||||
* *STATIC_LIGHT
|
||||
* *STATIC_ENVIRON
|
||||
*/
|
||||
/area/proc/addStaticPower(value, powerchannel)
|
||||
switch(powerchannel)
|
||||
if(STATIC_EQUIP)
|
||||
@@ -436,11 +568,19 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
if(STATIC_ENVIRON)
|
||||
static_environ += value
|
||||
|
||||
/**
|
||||
* Clear all power usage in area
|
||||
*
|
||||
* Clears all power used for equipment, light and environment channels
|
||||
*/
|
||||
/area/proc/clear_usage()
|
||||
used_equip = 0
|
||||
used_light = 0
|
||||
used_environ = 0
|
||||
|
||||
/**
|
||||
* Add a power value amount to the stored used_x variables
|
||||
*/
|
||||
/area/proc/use_power(amount, chan)
|
||||
|
||||
switch(chan)
|
||||
@@ -451,7 +591,13 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
if(ENVIRON)
|
||||
used_environ += amount
|
||||
|
||||
|
||||
/**
|
||||
* Call back when an atom enters an area
|
||||
*
|
||||
* Sends signals COMSIG_AREA_ENTERED and COMSIG_ENTER_AREA (to the atom)
|
||||
*
|
||||
* If the area has ambience, then it plays some ambience music to the ambience channel
|
||||
*/
|
||||
/area/Entered(atom/movable/M)
|
||||
set waitfor = FALSE
|
||||
SEND_SIGNAL(src, COMSIG_AREA_ENTERED, M)
|
||||
@@ -479,13 +625,35 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
L.client.played = TRUE
|
||||
addtimer(CALLBACK(L.client, /client/proc/ResetAmbiencePlayed), 600)
|
||||
|
||||
/**
|
||||
* Called when an atom exits an area
|
||||
*
|
||||
* Sends signals COMSIG_AREA_EXITED and COMSIG_EXIT_AREA (to the atom)
|
||||
*/
|
||||
/area/Exited(atom/movable/M)
|
||||
SEND_SIGNAL(src, COMSIG_AREA_EXITED, M)
|
||||
SEND_SIGNAL(M, COMSIG_EXIT_AREA, src) //The atom that exits the area
|
||||
|
||||
/**
|
||||
* Reset the played var to false on the client
|
||||
*/
|
||||
/client/proc/ResetAmbiencePlayed()
|
||||
played = FALSE
|
||||
|
||||
/**
|
||||
* Returns true if this atom has gravity for the passed in turf
|
||||
*
|
||||
* Sends signals COMSIG_ATOM_HAS_GRAVITY and COMSIG_TURF_HAS_GRAVITY, both can force gravity with
|
||||
* the forced gravity var
|
||||
*
|
||||
* Gravity situations:
|
||||
* * No gravity if you're not in a turf
|
||||
* * No gravity if this atom is in is a space turf
|
||||
* * Gravity if the area it's in always has gravity
|
||||
* * Gravity if there's a gravity generator on the z level
|
||||
* * Gravity if the Z level has an SSMappingTrait for ZTRAIT_GRAVITY
|
||||
* * otherwise no gravity
|
||||
*/
|
||||
/atom/proc/has_gravity(turf/T)
|
||||
if(!T || !isturf(T))
|
||||
T = get_turf(src)
|
||||
@@ -517,7 +685,11 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
max_grav = max(G.setting,max_grav)
|
||||
return max_grav
|
||||
return SSmapping.level_trait(T.z, ZTRAIT_GRAVITY)
|
||||
|
||||
/**
|
||||
* Setup an area (with the given name)
|
||||
*
|
||||
* Sets the area name, sets all status var's to false and adds the area to the sorted area list
|
||||
*/
|
||||
/area/proc/setup(a_name)
|
||||
name = a_name
|
||||
power_equip = FALSE
|
||||
@@ -527,7 +699,12 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
valid_territory = FALSE
|
||||
blob_allowed = FALSE
|
||||
addSorted()
|
||||
|
||||
/**
|
||||
* Set the area size of the area
|
||||
*
|
||||
* This is the number of open turfs in the area contents, or FALSE if the outdoors var is set
|
||||
*
|
||||
*/
|
||||
/area/proc/update_areasize()
|
||||
if(outdoors)
|
||||
return FALSE
|
||||
@@ -535,12 +712,18 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
for(var/turf/open/T in contents)
|
||||
areasize++
|
||||
|
||||
/**
|
||||
* Causes a runtime error
|
||||
*/
|
||||
/area/AllowDrop()
|
||||
CRASH("Bad op: area/AllowDrop() called")
|
||||
|
||||
/**
|
||||
* Causes a runtime error
|
||||
*/
|
||||
/area/drop_location()
|
||||
CRASH("Bad op: area/drop_location() called")
|
||||
|
||||
// A hook so areas can modify the incoming args
|
||||
/// A hook so areas can modify the incoming args (of what??)
|
||||
/area/proc/PlaceOnTopReact(list/new_baseturfs, turf/fake_turf_type, flags)
|
||||
return flags
|
||||
|
||||
@@ -1,43 +1,72 @@
|
||||
/**
|
||||
* The base type for nearly all physical objects in SS13
|
||||
|
||||
* Lots and lots of functionality lives here, although in general we are striving to move
|
||||
* as much as possible to the components/elements system
|
||||
*/
|
||||
/atom
|
||||
layer = TURF_LAYER
|
||||
plane = GAME_PLANE
|
||||
var/level = 2
|
||||
var/article // If non-null, overrides a/an/some in all cases
|
||||
|
||||
///If non-null, overrides a/an/some in all cases
|
||||
var/article
|
||||
|
||||
///First atom flags var
|
||||
var/flags_1 = NONE
|
||||
///Intearaction flags
|
||||
var/interaction_flags_atom = NONE
|
||||
|
||||
///Reagents holder
|
||||
var/datum/reagents/reagents = null
|
||||
|
||||
//This atom's HUD (med/sec, etc) images. Associative list.
|
||||
///This atom's HUD (med/sec, etc) images. Associative list.
|
||||
var/list/image/hud_list = null
|
||||
//HUD images that this atom can provide.
|
||||
///HUD images that this atom can provide.
|
||||
var/list/hud_possible
|
||||
|
||||
//Value used to increment ex_act() if reactionary_explosions is on
|
||||
///Value used to increment ex_act() if reactionary_explosions is on
|
||||
var/explosion_block = 0
|
||||
|
||||
var/list/atom_colours //used to store the different colors on an atom
|
||||
//its inherent color, the colored paint applied on it, special color effect etc...
|
||||
/**
|
||||
* used to store the different colors on an atom
|
||||
*
|
||||
* its inherent color, the colored paint applied on it, special color effect etc...
|
||||
*/
|
||||
var/list/atom_colours
|
||||
|
||||
var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
|
||||
var/list/remove_overlays // a very temporary list of overlays to remove
|
||||
var/list/add_overlays // a very temporary list of overlays to add
|
||||
|
||||
var/list/managed_vis_overlays //vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays
|
||||
///overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
|
||||
var/list/priority_overlays
|
||||
/// a very temporary list of overlays to remove
|
||||
var/list/remove_overlays
|
||||
/// a very temporary list of overlays to add
|
||||
var/list/add_overlays
|
||||
|
||||
///vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays
|
||||
var/list/managed_vis_overlays
|
||||
|
||||
///Proximity monitor associated with this atom
|
||||
var/datum/proximity_monitor/proximity_monitor
|
||||
///Cooldown tick timer for buckle messages
|
||||
var/buckle_message_cooldown = 0
|
||||
///Last fingerprints to touch this atom
|
||||
var/fingerprintslast
|
||||
|
||||
var/list/filter_data //For handling persistent filters
|
||||
|
||||
///Economy cost of item
|
||||
var/custom_price
|
||||
///Economy cost of item in premium vendor
|
||||
var/custom_premium_price
|
||||
///Whether spessmen with an ID with an age below AGE_MINOR (21 by default) can buy this item
|
||||
var/age_restricted = FALSE
|
||||
//List of datums orbiting this atom
|
||||
var/datum/component/orbiter/orbiters
|
||||
|
||||
var/rad_flags = NONE // Will move to flags_1 when i can be arsed to
|
||||
/// Will move to flags_1 when i can be arsed to (2019, has not done so)
|
||||
var/rad_flags = NONE
|
||||
/// Radiation insulation types
|
||||
var/rad_insulation = RAD_NO_INSULATION
|
||||
|
||||
var/chat_color_name // Last name used to calculate a color for the chatmessage overlays
|
||||
@@ -47,6 +76,16 @@
|
||||
var/chat_color_darkened // A luminescence-shifted value of the last color calculated for chatmessage overlays
|
||||
|
||||
|
||||
/**
|
||||
* Called when an atom is created in byond (built in engine proc)
|
||||
*
|
||||
* Not a lot happens here in SS13 code, as we offload most of the work to the
|
||||
* [Intialization](atom.html#proc/Initialize) proc, mostly we run the preloader
|
||||
* if the preloader is being used and then call InitAtom of which the ultimate
|
||||
* result is that the Intialize proc is called.
|
||||
*
|
||||
* We also generate a tag here if the DF_USE_TAG flag is set on the atom
|
||||
*/
|
||||
/atom/New(loc, ...)
|
||||
//atom creation method that preloads variables at creation
|
||||
if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
||||
@@ -63,17 +102,40 @@
|
||||
return
|
||||
SSdemo.mark_new(src)
|
||||
|
||||
//Called after New if the map is being loaded. mapload = TRUE
|
||||
//Called from base of New if the map is not being loaded. mapload = FALSE
|
||||
//This base must be called or derivatives must set initialized to TRUE
|
||||
//must not sleep
|
||||
//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE
|
||||
//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm
|
||||
|
||||
//Note: the following functions don't call the base for optimization and must copypasta:
|
||||
// /turf/Initialize
|
||||
// /turf/open/space/Initialize
|
||||
|
||||
/**
|
||||
* The primary method that objects are setup in SS13 with
|
||||
*
|
||||
* we don't use New as we have better control over when this is called and we can choose
|
||||
* to delay calls or hook other logic in and so forth
|
||||
*
|
||||
* During roundstart map parsing, atoms are queued for intialization in the base atom/New(),
|
||||
* After the map has loaded, then Initalize is called on all atoms one by one. NB: this
|
||||
* is also true for loading map templates as well, so they don't Initalize until all objects
|
||||
* in the map file are parsed and present in the world
|
||||
*
|
||||
* If you're creating an object at any point after SSInit has run then this proc will be
|
||||
* immediately be called from New.
|
||||
*
|
||||
* mapload: This parameter is true if the atom being loaded is either being intialized during
|
||||
* the Atom subsystem intialization, or if the atom is being loaded from the map template.
|
||||
* If the item is being created at runtime any time after the Atom subsystem is intialized then
|
||||
* it's false.
|
||||
*
|
||||
* You must always call the parent of this proc, otherwise failures will occur as the item
|
||||
* will not be seen as initalized (this can lead to all sorts of strange behaviour, like
|
||||
* the item being completely unclickable)
|
||||
*
|
||||
* You must not sleep in this proc, or any subprocs
|
||||
*
|
||||
* Any parameters from new are passed through (excluding loc), naturally if you're loading from a map
|
||||
* there are no other arguments
|
||||
*
|
||||
* Must return an [initialization hint](code/__DEFINES/subsystems.html) or a runtime will occur.
|
||||
*
|
||||
* Note: the following functions don't call the base for optimization and must copypasta handling:
|
||||
* * /turf/Initialize
|
||||
* * /turf/open/space/Initialize
|
||||
*/
|
||||
/atom/proc/Initialize(mapload, ...)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(flags_1 & INITIALIZED_1)
|
||||
@@ -98,14 +160,35 @@
|
||||
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
//called if Initialize returns INITIALIZE_HINT_LATELOAD
|
||||
/**
|
||||
* Late Intialization, for code that should run after all atoms have run Intialization
|
||||
*
|
||||
* To have your LateIntialize proc be called, your atoms [Initalization](atom.html#proc/Initialize)
|
||||
* proc must return the hint
|
||||
* [INITIALIZE_HINT_LATELOAD](code/__DEFINES/subsystems.html#define/INITIALIZE_HINT_LATELOAD)
|
||||
* otherwise you will never be called.
|
||||
*
|
||||
* useful for doing things like finding other machines on GLOB.machines because you can guarantee
|
||||
* that all atoms will actually exist in the "WORLD" at this time and that all their Intialization
|
||||
* code has been run
|
||||
*/
|
||||
/atom/proc/LateInitialize()
|
||||
return
|
||||
|
||||
// Put your AddComponent() calls here
|
||||
/// Put your AddComponent() calls here
|
||||
/atom/proc/ComponentInitialize()
|
||||
return
|
||||
|
||||
/**
|
||||
* Top level of the destroy chain for most atoms
|
||||
*
|
||||
* Cleans up the following:
|
||||
* * Removes alternate apperances from huds that see them
|
||||
* * qdels the reagent holder from atoms if it exists
|
||||
* * clears the orbiters list
|
||||
* * clears overlays and priority overlays
|
||||
* * clears the light object
|
||||
*/
|
||||
/atom/Destroy()
|
||||
if(alternate_appearances)
|
||||
for(var/K in alternate_appearances)
|
||||
@@ -127,6 +210,7 @@
|
||||
/atom/proc/handle_ricochet(obj/item/projectile/P)
|
||||
return
|
||||
|
||||
///Can the mover object pass this atom, while heading for the target turf
|
||||
/atom/proc/CanPass(atom/movable/mover, turf/target)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
@@ -143,6 +227,16 @@
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
return !density
|
||||
|
||||
/**
|
||||
* Is this atom currently located on centcom
|
||||
*
|
||||
* Specifically, is it on the z level and within the centcom areas
|
||||
*
|
||||
* You can also be in a shuttleshuttle during endgame transit
|
||||
*
|
||||
* Used in gamemode to identify mobs who have escaped and for some other areas of the code
|
||||
* who don't want atoms where they shouldn't be
|
||||
*/
|
||||
/atom/proc/onCentCom()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
@@ -173,6 +267,13 @@
|
||||
if(T in shuttle_area)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Is the atom in any of the centcom syndicate areas
|
||||
*
|
||||
* Either in the syndie base on centcom, or any of their shuttles
|
||||
*
|
||||
* Also used in gamemode code for win conditions
|
||||
*/
|
||||
/atom/proc/onSyndieBase()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
@@ -186,6 +287,7 @@
|
||||
|
||||
return FALSE
|
||||
|
||||
///This atom has been hit by a hulkified mob in hulk mode (user)
|
||||
/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user)
|
||||
if(does_attack_animation)
|
||||
@@ -193,6 +295,18 @@
|
||||
log_combat(user, src, "punched", "hulk powers")
|
||||
user.do_attack_animation(src, ATTACK_EFFECT_SMASH)
|
||||
|
||||
/**
|
||||
* Ensure a list of atoms/reagents exists inside this atom
|
||||
*
|
||||
* Goes throught he list of passed in parts, if they're reagents, adds them to our reagent holder
|
||||
* creating the reagent holder if it exists.
|
||||
*
|
||||
* If the part is a moveable atom and the previous location of the item was a mob/living,
|
||||
* it calls the inventory handler transferItemToLoc for that mob/living and transfers the part
|
||||
* to this atom
|
||||
*
|
||||
* Otherwise it simply forceMoves the atom into this atom
|
||||
*/
|
||||
/atom/proc/CheckParts(list/parts_list)
|
||||
for(var/A in parts_list)
|
||||
if(istype(A, /datum/reagent))
|
||||
@@ -208,65 +322,91 @@
|
||||
else
|
||||
M.forceMove(src)
|
||||
|
||||
//common name
|
||||
///Hook for multiz???
|
||||
/atom/proc/update_multiz(prune_on_fail = FALSE)
|
||||
return FALSE
|
||||
|
||||
///Take air from the passed in gas mixture datum
|
||||
/atom/proc/assume_air(datum/gas_mixture/giver)
|
||||
qdel(giver)
|
||||
return null
|
||||
|
||||
///Remove air from this atom
|
||||
/atom/proc/remove_air(amount)
|
||||
return null
|
||||
|
||||
///Return the current air environment in this atom
|
||||
/atom/proc/return_air()
|
||||
if(loc)
|
||||
return loc.return_air()
|
||||
else
|
||||
return null
|
||||
|
||||
///Return the air if we can analyze it
|
||||
///Check if this atoms eye is still alive (probably)
|
||||
/atom/proc/check_eye(mob/user)
|
||||
return
|
||||
|
||||
/atom/proc/Bumped(atom/movable/AM)
|
||||
set waitfor = FALSE
|
||||
|
||||
// Convenience procs to see if a container is open for chemistry handling
|
||||
/// Convenience proc to see if a container is open for chemistry handling
|
||||
/atom/proc/is_open_container()
|
||||
return is_refillable() && is_drainable()
|
||||
|
||||
/// Is this atom injectable into other atoms
|
||||
/atom/proc/is_injectable(mob/user, allowmobs = TRUE)
|
||||
return reagents && (reagents.flags & (INJECTABLE | REFILLABLE))
|
||||
|
||||
/// Can we draw from this atom with an injectable atom
|
||||
/atom/proc/is_drawable(mob/user, allowmobs = TRUE)
|
||||
return reagents && (reagents.flags & (DRAWABLE | DRAINABLE))
|
||||
|
||||
/// Can this atoms reagents be refilled
|
||||
/atom/proc/is_refillable()
|
||||
return reagents && (reagents.flags & REFILLABLE)
|
||||
|
||||
/// Is this atom drainable of reagents
|
||||
/atom/proc/is_drainable()
|
||||
return reagents && (reagents.flags & DRAINABLE)
|
||||
|
||||
|
||||
/// Are you allowed to drop this atom
|
||||
/atom/proc/AllowDrop()
|
||||
return FALSE
|
||||
|
||||
/atom/proc/CheckExit()
|
||||
return 1
|
||||
|
||||
///Is this atom within 1 tile of another atom
|
||||
/atom/proc/HasProximity(atom/movable/AM as mob|obj)
|
||||
return
|
||||
|
||||
/**
|
||||
* React to an EMP of the given severity
|
||||
*
|
||||
* Default behaviour is to send the COMSIG_ATOM_EMP_ACT signal
|
||||
*
|
||||
* If the signal does not return protection, and there are attached wires then we call
|
||||
* emp_pulse() on the wires
|
||||
*
|
||||
* We then return the protection value
|
||||
*/
|
||||
/atom/proc/emp_act(severity)
|
||||
var/protection = SEND_SIGNAL(src, COMSIG_ATOM_EMP_ACT, severity)
|
||||
if(!(protection & EMP_PROTECT_WIRES) && istype(wires))
|
||||
wires.emp_pulse()
|
||||
return protection // Pass the protection value collected here upwards
|
||||
|
||||
/**
|
||||
* React to a hit by a projectile object
|
||||
*
|
||||
* Default behaviour is to send the COMSIG_ATOM_BULLET_ACT and then call on_hit() on the projectile
|
||||
*/
|
||||
/atom/proc/bullet_act(obj/item/projectile/P, def_zone)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, P, def_zone)
|
||||
. = P.on_hit(src, 0, def_zone)
|
||||
|
||||
///Return true if we're inside the passed in atom
|
||||
/atom/proc/in_contents_of(container)//can take class or object instance as argument
|
||||
if(ispath(container))
|
||||
if(istype(src.loc, container))
|
||||
@@ -275,6 +415,12 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Get the name of this object for examine
|
||||
*
|
||||
* You can override what is returned from this proc by registering to listen for the
|
||||
* COMSIG_ATOM_GET_EXAMINE_NAME signal
|
||||
*/
|
||||
/atom/proc/get_examine_name(mob/user)
|
||||
. = "\a [src]"
|
||||
var/list/override = list(gender == PLURAL ? "some" : "a", " ", "[name]")
|
||||
@@ -284,9 +430,18 @@
|
||||
if(SEND_SIGNAL(src, COMSIG_ATOM_GET_EXAMINE_NAME, user, override) & COMPONENT_EXNAME_CHANGED)
|
||||
. = override.Join("")
|
||||
|
||||
///Generate the full examine string of this atom (including icon for goonchat)
|
||||
/atom/proc/get_examine_string(mob/user, thats = FALSE)
|
||||
return "[icon2html(src, user)] [thats? "That's ":""][get_examine_name(user)]"
|
||||
|
||||
/**
|
||||
* Called when a mob examines (shift click or verb) this atom
|
||||
*
|
||||
* Default behaviour is to get the name and icon of the object and it's reagents where
|
||||
* the TRANSPARENT flag is set on the reagents holder
|
||||
*
|
||||
* Produces a signal COMSIG_PARENT_EXAMINE
|
||||
*/
|
||||
/atom/proc/examine(mob/user)
|
||||
. = list("[get_examine_string(user, TRUE)].")
|
||||
|
||||
@@ -315,23 +470,41 @@
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
|
||||
|
||||
/**
|
||||
* An atom we are buckled or is contained within us has tried to move
|
||||
*
|
||||
* Default behaviour is to send a warning that the user can't move while buckled as long
|
||||
* as the buckle_message_cooldown has expired (50 ticks)
|
||||
*/
|
||||
/atom/proc/relaymove(mob/user)
|
||||
if(buckle_message_cooldown <= world.time)
|
||||
buckle_message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>You can't move while buckled to [src]!</span>")
|
||||
return
|
||||
|
||||
/// Return true if this atoms contents should not have ex_act called on ex_act
|
||||
/atom/proc/prevent_content_explosion()
|
||||
return FALSE
|
||||
|
||||
/// Handle what happens when your contents are exploded by a bomb
|
||||
/atom/proc/contents_explosion(severity, target)
|
||||
return //For handling the effects of explosions on contents that would not normally be effected
|
||||
|
||||
/**
|
||||
* React to being hit by an explosion
|
||||
*
|
||||
* Default behaviour is to call contents_explosion() and send the COMSIG_ATOM_EX_ACT signal
|
||||
*/
|
||||
/atom/proc/ex_act(severity, target)
|
||||
set waitfor = FALSE
|
||||
contents_explosion(severity, target)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_EX_ACT, severity, target)
|
||||
|
||||
/**
|
||||
* React to a hit by a blob objecd
|
||||
*
|
||||
* default behaviour is to send the COMSIG_ATOM_BLOB_ACT signal
|
||||
*/
|
||||
/atom/proc/blob_act(obj/structure/blob/B)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_BLOB_ACT, B)
|
||||
return
|
||||
@@ -340,23 +513,40 @@
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_FIRE_ACT, exposed_temperature, exposed_volume)
|
||||
return
|
||||
|
||||
/**
|
||||
* React to being hit by a thrown object
|
||||
*
|
||||
* Default behaviour is to call hitby_react() on ourselves after 2 seconds if we are dense
|
||||
* and under normal gravity.
|
||||
*
|
||||
* Im not sure why this the case, maybe to prevent lots of hitby's if the thrown object is
|
||||
* deleted shortly after hitting something (during explosions or other massive events that
|
||||
* throw lots of items around - singularity being a notable example)
|
||||
*/
|
||||
/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
||||
if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...).
|
||||
addtimer(CALLBACK(src, .proc/hitby_react, AM), 2)
|
||||
|
||||
/**
|
||||
* We have have actually hit the passed in atom
|
||||
*
|
||||
* Default behaviour is to move back from the item that hit us
|
||||
*/
|
||||
/atom/proc/hitby_react(atom/movable/AM)
|
||||
if(AM && isturf(AM.loc))
|
||||
step(AM, turn(AM.dir, 180))
|
||||
|
||||
///Handle the atom being slipped over
|
||||
/atom/proc/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube, paralyze, force_drop)
|
||||
return
|
||||
|
||||
//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list
|
||||
///returns the mob's dna info as a list, to be inserted in an object's blood_DNA list
|
||||
/mob/living/proc/get_blood_dna_list()
|
||||
if(get_blood_id() != /datum/reagent/blood)
|
||||
return
|
||||
return list("ANIMAL DNA" = "Y-")
|
||||
|
||||
///Get the mobs dna list
|
||||
/mob/living/carbon/get_blood_dna_list()
|
||||
if(get_blood_id() != /datum/reagent/blood)
|
||||
return
|
||||
@@ -373,7 +563,7 @@
|
||||
/mob/living/silicon/get_blood_dna_list()
|
||||
return list("MOTOR OIL" = "SAE 5W-30") //just a little flavor text.
|
||||
|
||||
//to add a mob's dna info into an object's blood_DNA list.
|
||||
///to add a mob's dna info into an object's blood_dna list.
|
||||
/atom/proc/transfer_mob_blood_dna(mob/living/L)
|
||||
// Returns 0 if we have that blood already
|
||||
var/new_blood_dna = L.get_blood_dna_list()
|
||||
@@ -385,58 +575,120 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//to add blood from a mob onto something, and transfer their dna info
|
||||
///to add blood from a mob onto something, and transfer their dna info
|
||||
/atom/proc/add_mob_blood(mob/living/M)
|
||||
var/list/blood_dna = M.get_blood_dna_list()
|
||||
if(!blood_dna)
|
||||
return FALSE
|
||||
return add_blood_DNA(blood_dna)
|
||||
|
||||
///wash cream off this object
|
||||
///
|
||||
///(for the love of space jesus please make this a component)
|
||||
/atom/proc/wash_cream()
|
||||
return TRUE
|
||||
|
||||
///Is this atom in space
|
||||
/atom/proc/isinspace()
|
||||
if(isspaceturf(get_turf(src)))
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
///Called when gravity returns after floating I think
|
||||
/atom/proc/handle_fall()
|
||||
return
|
||||
|
||||
///Respond to the singularity eating this atom
|
||||
/atom/proc/singularity_act()
|
||||
return
|
||||
|
||||
/**
|
||||
* Respond to the singularity pulling on us
|
||||
*
|
||||
* Default behaviour is to send COMSIG_ATOM_SING_PULL and return
|
||||
*/
|
||||
/atom/proc/singularity_pull(obj/singularity/S, current_size)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_SING_PULL, S, current_size)
|
||||
|
||||
|
||||
/**
|
||||
* Respond to acid being used on our atom
|
||||
*
|
||||
* Default behaviour is to send COMSIG_ATOM_ACID_ACT and return
|
||||
*/
|
||||
/atom/proc/acid_act(acidpwr, acid_volume)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_ACID_ACT, acidpwr, acid_volume)
|
||||
|
||||
/**
|
||||
* Respond to an emag being used on our atom
|
||||
*
|
||||
* Default behaviour is to send COMSIG_ATOM_EMAG_ACT and return
|
||||
*/
|
||||
/atom/proc/emag_act()
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT)
|
||||
|
||||
/**
|
||||
* Respond to a radioactive wave hitting this atom
|
||||
*
|
||||
* Default behaviour is to send COMSIG_ATOM_RAD_ACT and return
|
||||
*/
|
||||
/atom/proc/rad_act(strength)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_RAD_ACT, strength)
|
||||
|
||||
/**
|
||||
* Respond to narsie eating our atom
|
||||
*
|
||||
* Default behaviour is to send COMSIG_ATOM_NARSIE_ACT and return
|
||||
*/
|
||||
/atom/proc/narsie_act()
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_NARSIE_ACT)
|
||||
|
||||
/**
|
||||
* Respond to ratvar eating our atom
|
||||
*
|
||||
* Default behaviour is to send COMSIG_ATOM_RATVAR_ACT and return
|
||||
*/
|
||||
/atom/proc/ratvar_act()
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_RATVAR_ACT)
|
||||
|
||||
///Return the values you get when an RCD eats you?
|
||||
/atom/proc/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
||||
return FALSE
|
||||
|
||||
|
||||
/**
|
||||
* Respond to an RCD acting on our item
|
||||
*
|
||||
* Default behaviour is to send COMSIG_ATOM_RCD_ACT and return FALSE
|
||||
*/
|
||||
/atom/proc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_RCD_ACT, user, the_rcd, passed_mode)
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Implement the behaviour for when a user click drags a storage object to your atom
|
||||
*
|
||||
* This behaviour is usually to mass transfer, but this is no longer a used proc as it just
|
||||
* calls the underyling /datum/component/storage dump act if a component exists
|
||||
*
|
||||
* TODO these should be purely component items that intercept the atom clicks higher in the
|
||||
* call chain
|
||||
*/
|
||||
/atom/proc/storage_contents_dump_act(obj/item/storage/src_object, mob/user)
|
||||
if(GetComponent(/datum/component/storage))
|
||||
return component_storage_contents_dump_act(src_object, user)
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Implement the behaviour for when a user click drags another storage item to you
|
||||
*
|
||||
* In this case we get as many of the tiems from the target items compoent storage and then
|
||||
* put everything into ourselves (or our storage component)
|
||||
*
|
||||
* TODO these should be purely component items that intercept the atom clicks higher in the
|
||||
* call chain
|
||||
*/
|
||||
/atom/proc/component_storage_contents_dump_act(datum/component/storage/src_object, mob/user)
|
||||
var/list/things = src_object.contents()
|
||||
var/datum/progressbar/progress = new(user, things.len, src)
|
||||
@@ -457,38 +709,64 @@
|
||||
user.active_storage.show_to(user)
|
||||
return TRUE
|
||||
|
||||
///Get the best place to dump the items contained in the source storage item?
|
||||
/atom/proc/get_dumping_location(obj/item/storage/source,mob/user)
|
||||
return null
|
||||
|
||||
//This proc is called on the location of an atom when the atom is Destroy()'d
|
||||
/**
|
||||
* This proc is called when an atom in our contents has it's Destroy() called
|
||||
*
|
||||
* Default behaviour is to simply send COMSIG_ATOM_CONTENTS_DEL
|
||||
*/
|
||||
/atom/proc/handle_atom_del(atom/A)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_CONTENTS_DEL, A)
|
||||
|
||||
//called when the turf the atom resides on is ChangeTurfed
|
||||
/**
|
||||
* called when the turf the atom resides on is ChangeTurfed
|
||||
*
|
||||
* Default behaviour is to loop through atom contents and call their HandleTurfChange() proc
|
||||
*/
|
||||
/atom/proc/HandleTurfChange(turf/T)
|
||||
for(var/a in src)
|
||||
var/atom/A = a
|
||||
A.HandleTurfChange(T)
|
||||
|
||||
//the vision impairment to give to the mob whose perspective is set to that atom (e.g. an unfocused camera giving you an impaired vision when looking through it)
|
||||
/**
|
||||
* the vision impairment to give to the mob whose perspective is set to that atom
|
||||
*
|
||||
* (e.g. an unfocused camera giving you an impaired vision when looking through it)
|
||||
*/
|
||||
/atom/proc/get_remote_view_fullscreens(mob/user)
|
||||
return
|
||||
|
||||
//the sight changes to give to the mob whose perspective is set to that atom (e.g. A mob with nightvision loses its nightvision while looking through a normal camera)
|
||||
/**
|
||||
* the sight changes to give to the mob whose perspective is set to that atom
|
||||
*
|
||||
* (e.g. A mob with nightvision loses its nightvision while looking through a normal camera)
|
||||
*/
|
||||
/atom/proc/update_remote_sight(mob/living/user)
|
||||
return
|
||||
|
||||
|
||||
//Hook for running code when a dir change occurs
|
||||
/**
|
||||
* Hook for running code when a dir change occurs
|
||||
*
|
||||
* Not recommended to use, listen for the COMSIG_ATOM_DIR_CHANGE signal instead (sent by this proc)
|
||||
*/
|
||||
/atom/proc/setDir(newdir)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_DIR_CHANGE, dir, newdir)
|
||||
dir = newdir
|
||||
|
||||
///Handle melee attack by a mech
|
||||
/atom/proc/mech_melee_attack(obj/mecha/M)
|
||||
return
|
||||
|
||||
//If a mob logouts/logins in side of an object you can use this proc
|
||||
/**
|
||||
* Called when the atom log's in or out
|
||||
*
|
||||
* Default behaviour is to call on_log on the location this atom is in
|
||||
*/
|
||||
/atom/proc/on_log(login)
|
||||
if(loc)
|
||||
loc.on_log(login)
|
||||
@@ -502,9 +780,7 @@
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Adds an instance of colour_type to the atom's atom_colours list
|
||||
*/
|
||||
///Adds an instance of colour_type to the atom's atom_colours list
|
||||
/atom/proc/add_atom_colour(coloration, colour_priority)
|
||||
if(!atom_colours || !atom_colours.len)
|
||||
atom_colours = list()
|
||||
@@ -517,9 +793,7 @@
|
||||
update_atom_colour()
|
||||
|
||||
|
||||
/*
|
||||
Removes an instance of colour_type from the atom's atom_colours list
|
||||
*/
|
||||
///Removes an instance of colour_type from the atom's atom_colours list
|
||||
/atom/proc/remove_atom_colour(colour_priority, coloration)
|
||||
if(!atom_colours)
|
||||
atom_colours = list()
|
||||
@@ -532,10 +806,7 @@
|
||||
update_atom_colour()
|
||||
|
||||
|
||||
/*
|
||||
Resets the atom's color to null, and then sets it to the highest priority
|
||||
colour available
|
||||
*/
|
||||
///Resets the atom's color to null, and then sets it to the highest priority colour available
|
||||
/atom/proc/update_atom_colour()
|
||||
if(!atom_colours)
|
||||
atom_colours = list()
|
||||
@@ -551,6 +822,17 @@
|
||||
color = C
|
||||
return
|
||||
|
||||
/**
|
||||
* call back when a var is edited on this atom
|
||||
*
|
||||
* Can be used to implement special handling of vars
|
||||
*
|
||||
* At the atom level, if you edit a var named "color" it will add the atom colour with
|
||||
* admin level priority to the atom colours list
|
||||
*
|
||||
* Also, if GLOB.Debug2 is FALSE, it sets the ADMIN_SPAWNED_1 flag on flags_1, which signifies
|
||||
* the object has been admin edited
|
||||
*/
|
||||
/atom/vv_edit_var(var_name, var_value)
|
||||
if(!GLOB.Debug2)
|
||||
flags_1 |= ADMIN_SPAWNED_1
|
||||
@@ -559,6 +841,11 @@
|
||||
if("color")
|
||||
add_atom_colour(color, ADMIN_COLOUR_PRIORITY)
|
||||
|
||||
/**
|
||||
* Return the markup to for the dropdown list for the VV panel for this atom
|
||||
*
|
||||
* Override in subtypes to add custom VV handling in the VV panel
|
||||
*/
|
||||
/atom/vv_get_dropdown()
|
||||
. = ..()
|
||||
. += "---"
|
||||
@@ -570,29 +857,53 @@
|
||||
.["Trigger EM pulse"] = "?_src_=vars;[HrefToken()];emp=[REF(src)]"
|
||||
.["Trigger explosion"] = "?_src_=vars;[HrefToken()];explode=[REF(src)]"
|
||||
|
||||
///Where atoms should drop if taken from this atom
|
||||
/atom/proc/drop_location()
|
||||
var/atom/L = loc
|
||||
if(!L)
|
||||
return null
|
||||
return L.AllowDrop() ? L : L.drop_location()
|
||||
|
||||
/**
|
||||
* An atom has entered this atom's contents
|
||||
*
|
||||
* Default behaviour is to send the COMSIG_ATOM_ENTERED
|
||||
*/
|
||||
/atom/Entered(atom/movable/AM, atom/oldLoc)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_ENTERED, AM, oldLoc)
|
||||
|
||||
/**
|
||||
* An atom is attempting to exit this atom's contents
|
||||
*
|
||||
* Default behaviour is to send the COMSIG_ATOM_EXIT
|
||||
*
|
||||
* Return value should be set to FALSE if the moving atom is unable to leave,
|
||||
* otherwise leave value the result of the parent call
|
||||
*/
|
||||
/atom/Exit(atom/movable/AM, atom/newLoc)
|
||||
. = ..()
|
||||
if(SEND_SIGNAL(src, COMSIG_ATOM_EXIT, AM, newLoc) & COMPONENT_ATOM_BLOCK_EXIT)
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* An atom has exited this atom's contents
|
||||
*
|
||||
* Default behaviour is to send the COMSIG_ATOM_EXITED
|
||||
*/
|
||||
/atom/Exited(atom/movable/AM, atom/newLoc)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_EXITED, AM, newLoc)
|
||||
|
||||
///Return atom temperature
|
||||
/atom/proc/return_temperature()
|
||||
return
|
||||
|
||||
// Tool behavior procedure. Redirects to tool-specific procs by default.
|
||||
// You can override it to catch all tool interactions, for use in complex deconstruction procs.
|
||||
// Just don't forget to return ..() in the end.
|
||||
/**
|
||||
*Tool behavior procedure. Redirects to tool-specific procs by default.
|
||||
*
|
||||
* You can override it to catch all tool interactions, for use in complex deconstruction procs.
|
||||
*
|
||||
* Must return parent proc ..() in the end if overridden
|
||||
*/
|
||||
/atom/proc/tool_act(mob/living/user, obj/item/I, tool_type)
|
||||
switch(tool_type)
|
||||
if(TOOL_CROWBAR)
|
||||
@@ -610,13 +921,18 @@
|
||||
if(TOOL_ANALYZER)
|
||||
return analyzer_act(user, I)
|
||||
|
||||
// Tool-specific behavior procs. To be overridden in subtypes.
|
||||
//! Tool-specific behavior procs. To be overridden in subtypes.
|
||||
///
|
||||
|
||||
///Crowbar act
|
||||
/atom/proc/crowbar_act(mob/living/user, obj/item/I)
|
||||
return
|
||||
|
||||
///Multitool act
|
||||
/atom/proc/multitool_act(mob/living/user, obj/item/I)
|
||||
return
|
||||
|
||||
///Check if the multitool has an item in it's data buffer
|
||||
/atom/proc/multitool_check_buffer(user, obj/item/I, silent = FALSE)
|
||||
if(!istype(I, /obj/item/multitool))
|
||||
if(user && !silent)
|
||||
@@ -624,29 +940,35 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
///Screwdriver act
|
||||
/atom/proc/screwdriver_act(mob/living/user, obj/item/I)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_SCREWDRIVER_ACT, user, I)
|
||||
|
||||
///Wrench act
|
||||
/atom/proc/wrench_act(mob/living/user, obj/item/I)
|
||||
return
|
||||
|
||||
///Wirecutter act
|
||||
/atom/proc/wirecutter_act(mob/living/user, obj/item/I)
|
||||
return
|
||||
|
||||
///Welder act
|
||||
/atom/proc/welder_act(mob/living/user, obj/item/I)
|
||||
return
|
||||
|
||||
///Analyzer act
|
||||
/atom/proc/analyzer_act(mob/living/user, obj/item/I)
|
||||
return
|
||||
|
||||
///Generate a tag for this atom
|
||||
/atom/proc/GenerateTag()
|
||||
return
|
||||
|
||||
///Connect this atom to a shuttle
|
||||
/atom/proc/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
|
||||
return
|
||||
|
||||
// Generic logging helper
|
||||
/// Generic logging helper
|
||||
/atom/proc/log_message(message, message_type, color=null, log_globally=TRUE)
|
||||
if(!log_globally)
|
||||
return
|
||||
@@ -693,13 +1015,13 @@
|
||||
stack_trace("Invalid individual logging type: [message_type]. Defaulting to [LOG_GAME] (LOG_GAME).")
|
||||
log_game(log_text)
|
||||
|
||||
// Helper for logging chat messages or other logs with arbitrary inputs (e.g. announcements)
|
||||
/// Helper for logging chat messages or other logs with arbitrary inputs (e.g. announcements)
|
||||
/atom/proc/log_talk(message, message_type, tag=null, log_globally=TRUE, forced_by=null)
|
||||
var/prefix = tag ? "([tag]) " : ""
|
||||
var/suffix = forced_by ? " FORCED by [forced_by]" : ""
|
||||
log_message("[prefix]\"[message]\"[suffix]", message_type, log_globally=log_globally)
|
||||
|
||||
// Helper for logging of messages with only one sender and receiver
|
||||
/// Helper for logging of messages with only one sender and receiver
|
||||
/proc/log_directed_talk(atom/source, atom/target, message, message_type, tag)
|
||||
if(!tag)
|
||||
stack_trace("Unspecified tag for private message")
|
||||
@@ -709,15 +1031,15 @@
|
||||
if(source != target)
|
||||
target.log_talk(message, message_type, tag="[tag] from [key_name(source)]", log_globally=FALSE)
|
||||
|
||||
/*
|
||||
Proc for attack log creation, because really why not
|
||||
1 argument is the actor performing the action
|
||||
2 argument is the target of the action
|
||||
3 is a verb describing the action (e.g. punched, throwed, kicked, etc.)
|
||||
4 is a tool with which the action was made (usually an item)
|
||||
5 is any additional text, which will be appended to the rest of the log line
|
||||
*/
|
||||
|
||||
/**
|
||||
* Log a combat message in the attack log
|
||||
*
|
||||
* 1 argument is the actor performing the action
|
||||
* 2 argument is the target of the action
|
||||
* 3 is a verb describing the action (e.g. punched, throwed, kicked, etc.)
|
||||
* 4 is a tool with which the action was made (usually an item)
|
||||
* 5 is any additional text, which will be appended to the rest of the log line
|
||||
*/
|
||||
/proc/log_combat(atom/user, atom/target, what_done, atom/object=null, addition=null)
|
||||
var/ssource = key_name(user)
|
||||
var/starget = key_name(target)
|
||||
@@ -741,7 +1063,6 @@ Proc for attack log creation, because really why not
|
||||
var/reverse_message = "has been [what_done] by [ssource][postfix]"
|
||||
target.log_message(reverse_message, LOG_ATTACK, color="orange", log_globally=FALSE)
|
||||
|
||||
// Filter stuff
|
||||
/atom/movable/proc/add_filter(name,priority,list/params)
|
||||
if(!filter_data)
|
||||
filter_data = list()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
//the essential proc to call when an obj must receive damage of any kind.
|
||||
/obj/proc/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, armour_penetration = 0)
|
||||
///the essential proc to call when an obj must receive damage of any kind.
|
||||
/obj/proc/take_damage(damage_amount, damage_type = BRUTE, damage_flag = "", sound_effect = TRUE, attack_dir, armour_penetration = 0)
|
||||
if(QDELETED(src))
|
||||
stack_trace("[src] taking damage after deletion")
|
||||
return
|
||||
@@ -21,7 +21,7 @@
|
||||
if(obj_integrity <= integrity_failure)
|
||||
obj_break(damage_flag)
|
||||
|
||||
//returns the damage value of the attack after processing the obj's various armor protections
|
||||
///returns the damage value of the attack after processing the obj's various armor protections
|
||||
/obj/proc/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir, armour_penetration = 0)
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
@@ -35,7 +35,7 @@
|
||||
armor_protection = clamp(armor_protection - armour_penetration, min(armor_protection, 0), 100)
|
||||
return round(damage_amount * (100 - armor_protection)*0.01, DAMAGE_PRECISION)
|
||||
|
||||
//the sound played when the obj is damaged.
|
||||
///the sound played when the obj is damaged.
|
||||
/obj/proc/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
@@ -80,6 +80,7 @@
|
||||
if(!QDELETED(src)) //Bullet on_hit effect might have already destroyed this object
|
||||
take_damage(P.damage, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration)
|
||||
|
||||
///Called to get the damage that hulks will deal to the obj.
|
||||
/obj/proc/hulk_damage()
|
||||
return 150 //the damage hulks do on punches to this object, is affected by melee armor
|
||||
|
||||
@@ -175,7 +176,7 @@
|
||||
|
||||
GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/effects/effects.dmi', "acid"))
|
||||
|
||||
//the obj's reaction when touched by acid
|
||||
///the obj's reaction when touched by acid
|
||||
/obj/acid_act(acidpwr, acid_volume)
|
||||
if(!(resistance_flags & UNACIDABLE) && acid_volume)
|
||||
|
||||
@@ -187,7 +188,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
acid_level = min(acid_level + acidpwr * acid_volume, acid_cap)
|
||||
return 1
|
||||
|
||||
//the proc called by the acid subsystem to process the acid that's on the obj
|
||||
///the proc called by the acid subsystem to process the acid that's on the obj
|
||||
/obj/proc/acid_processing()
|
||||
. = 1
|
||||
if(!(resistance_flags & ACID_PROOF))
|
||||
@@ -202,13 +203,14 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
if(!acid_level)
|
||||
return 0
|
||||
|
||||
//called when the obj is destroyed by acid.
|
||||
///called when the obj is destroyed by acid.
|
||||
/obj/proc/acid_melt()
|
||||
SSacid.processing -= src
|
||||
deconstruct(FALSE)
|
||||
|
||||
//// FIRE
|
||||
|
||||
///Called when the obj is exposed to fire.
|
||||
/obj/fire_act(exposed_temperature, exposed_volume)
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
@@ -222,18 +224,20 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
add_overlay(GLOB.fire_overlay, TRUE)
|
||||
return 1
|
||||
|
||||
//called when the obj is destroyed by fire
|
||||
///called when the obj is destroyed by fire
|
||||
/obj/proc/burn()
|
||||
if(resistance_flags & ON_FIRE)
|
||||
SSfire_burning.processing -= src
|
||||
deconstruct(FALSE)
|
||||
|
||||
///Called when the obj is no longer on fire.
|
||||
/obj/proc/extinguish()
|
||||
if(resistance_flags & ON_FIRE)
|
||||
resistance_flags &= ~ON_FIRE
|
||||
cut_overlay(GLOB.fire_overlay, TRUE)
|
||||
SSfire_burning.processing -= src
|
||||
|
||||
///Called when the obj is hit by a tesla bolt.
|
||||
/obj/proc/tesla_act(power, tesla_flags, shocked_targets)
|
||||
obj_flags |= BEING_SHOCKED
|
||||
var/power_bounced = power / 2
|
||||
@@ -241,7 +245,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
addtimer(CALLBACK(src, .proc/reset_shocked), 10)
|
||||
|
||||
//The surgeon general warns that being buckled to certain objects receiving powerful shocks is greatly hazardous to your health
|
||||
//Only tesla coils and grounding rods currently call this because mobs are already targeted over all other objects, but this might be useful for more things later.
|
||||
///Only tesla coils and grounding rods currently call this because mobs are already targeted over all other objects, but this might be useful for more things later.
|
||||
/obj/proc/tesla_buckle_check(var/strength)
|
||||
if(has_buckled_mobs())
|
||||
for(var/m in buckled_mobs)
|
||||
@@ -251,16 +255,16 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
/obj/proc/reset_shocked()
|
||||
obj_flags &= ~BEING_SHOCKED
|
||||
|
||||
//the obj is deconstructed into pieces, whether through careful disassembly or when destroyed.
|
||||
///the obj is deconstructed into pieces, whether through careful disassembly or when destroyed.
|
||||
/obj/proc/deconstruct(disassembled = TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_OBJ_DECONSTRUCT, disassembled)
|
||||
qdel(src)
|
||||
|
||||
//what happens when the obj's health is below integrity_failure level.
|
||||
///called after the obj takes damage and integrity is below integrity_failure level
|
||||
/obj/proc/obj_break(damage_flag)
|
||||
return
|
||||
|
||||
//what happens when the obj's integrity reaches zero.
|
||||
///what happens when the obj's integrity reaches zero.
|
||||
/obj/proc/obj_destruction(damage_flag)
|
||||
if(damage_flag == "acid")
|
||||
acid_melt()
|
||||
@@ -269,8 +273,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
else
|
||||
deconstruct(FALSE)
|
||||
|
||||
//changes max_integrity while retaining current health percentage
|
||||
//returns TRUE if the obj broke, FALSE otherwise
|
||||
///changes max_integrity while retaining current health percentage, returns TRUE if the obj got broken.
|
||||
/obj/proc/modify_max_integrity(new_max, can_break = TRUE, damage_type = BRUTE, new_failure_integrity = null)
|
||||
var/current_integrity = obj_integrity
|
||||
var/current_max = max_integrity
|
||||
@@ -290,6 +293,6 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//returns how much the object blocks an explosion
|
||||
///returns how much the object blocks an explosion. Used by subtypes.
|
||||
/obj/proc/GetExplosionBlock()
|
||||
CRASH("Unimplemented GetExplosionBlock()")
|
||||
|
||||
@@ -7,8 +7,22 @@ GLOBAL_VAR(restart_counter)
|
||||
if (dll)
|
||||
call(dll, "debug_initialize")()
|
||||
|
||||
//This happens after the Master subsystem new(s) (it's a global datum)
|
||||
//So subsystems globals exist, but are not initialised
|
||||
/**
|
||||
* World creation
|
||||
*
|
||||
* Here is where a round itself is actually begun and setup, lots of important config changes happen here
|
||||
* * db connection setup
|
||||
* * config loaded from files
|
||||
* * loads admins
|
||||
* * Sets up the dynamic menu system
|
||||
* * and most importantly, calls initialize on the master subsystem, starting the game loop that causes the rest of the game to begin processing and setting up
|
||||
*
|
||||
* Note this happens after the Master subsystem is created (as that is a global datum), this means all the subsystems exist,
|
||||
* but they have not been Initialized at this point, only their New proc has run
|
||||
*
|
||||
* Nothing happens until something moves. ~Albert Einstein
|
||||
*
|
||||
*/
|
||||
/world/New()
|
||||
enable_debugger() //This does nothing if you aren't trying to debug
|
||||
log_world("World loaded at [time_stamp()]!")
|
||||
|
||||
@@ -6,13 +6,20 @@
|
||||
////////////////
|
||||
//ADMIN THINGS//
|
||||
////////////////
|
||||
///Contains admin info. Null if client is not an admin.
|
||||
var/datum/admins/holder = null
|
||||
var/datum/click_intercept = null // Needs to implement InterceptClickOn(user,params,atom) proc
|
||||
var/AI_Interact = 0
|
||||
///Needs to implement InterceptClickOn(user,params,atom) proc
|
||||
var/datum/click_intercept = null
|
||||
///Used for admin AI interaction
|
||||
var/AI_Interact = FALSE
|
||||
|
||||
var/ban_cache = null //Used to cache this client's bans to save on DB queries
|
||||
var/last_message = "" //Contains the last message sent by this client - used to protect against copy-paste spamming.
|
||||
var/last_message_count = 0 //contins a number of how many times a message identical to last_message was sent.
|
||||
///Used to cache this client's bans to save on DB queries
|
||||
var/ban_cache = null
|
||||
///Contains the last message sent by this client - used to protect against copy-paste spamming.
|
||||
var/last_message = ""
|
||||
///contins a number of how many times a message identical to last_message was sent.
|
||||
var/last_message_count = 0
|
||||
///Internal counter for clients sending irc relay messages via ahelp to prevent spamming. Set to a number every time an admin reply is sent, decremented for every client send.
|
||||
var/ircreplyamount = 0
|
||||
|
||||
var/total_message_count = 0 //How many messages sent in the last 10 seconds
|
||||
@@ -21,10 +28,14 @@
|
||||
/////////
|
||||
//OTHER//
|
||||
/////////
|
||||
///Player preferences datum for the client
|
||||
var/datum/preferences/prefs = null
|
||||
///last turn of the controlled mob, I think this is only used by mechs?
|
||||
var/last_turn = 0
|
||||
///Move delay of controlled mob, related to input handling
|
||||
var/move_delay = 0
|
||||
var/area = null
|
||||
///Current area of the controlled mob
|
||||
var/area = null
|
||||
var/cryo_warned = -3000 //when was the last time we warned them about not cryoing without an ahelp, set to -5 minutes so that rounstart cryo still warns
|
||||
|
||||
/////////
|
||||
@@ -34,8 +45,10 @@
|
||||
///////////////
|
||||
//SOUND STUFF//
|
||||
///////////////
|
||||
var/ambience_playing= null
|
||||
var/played = 0
|
||||
///Currently playing ambience sound
|
||||
var/ambience_playing = null
|
||||
///Whether an ambience sound has been played and one shouldn't be played again, unset by a callback
|
||||
var/played = FALSE
|
||||
////////////
|
||||
//SECURITY//
|
||||
////////////
|
||||
@@ -45,49 +58,73 @@
|
||||
////////////////////////////////////
|
||||
//things that require the database//
|
||||
////////////////////////////////////
|
||||
var/player_age = -1 //Used to determine how old the account is - in days.
|
||||
var/player_join_date = null //Date that this account was first seen in the server
|
||||
var/related_accounts_ip = "Requires database" //So admins know why it isn't working - Used to determine what other accounts previously logged in from this ip
|
||||
var/related_accounts_cid = "Requires database" //So admins know why it isn't working - Used to determine what other accounts previously logged in from this computer id
|
||||
var/account_join_date = null //Date of byond account creation in ISO 8601 format
|
||||
var/account_age = -1 //Age of byond account in days
|
||||
///Used to determine how old the account is - in days.
|
||||
var/player_age = -1
|
||||
///Date that this account was first seen in the server
|
||||
var/player_join_date = null
|
||||
///So admins know why it isn't working - Used to determine what other accounts previously logged in from this ip
|
||||
var/related_accounts_ip = "Requires database"
|
||||
///So admins know why it isn't working - Used to determine what other accounts previously logged in from this computer id
|
||||
var/related_accounts_cid = "Requires database"
|
||||
///Date of byond account creation in ISO 8601 format
|
||||
var/account_join_date = null
|
||||
///Age of byond account in days
|
||||
var/account_age = -1
|
||||
|
||||
preload_rsc = PRELOAD_RSC
|
||||
|
||||
var/obj/screen/click_catcher/void
|
||||
|
||||
//These two vars are used to make a special mouse cursor, with a unique icon for clicking
|
||||
///used to make a special mouse cursor, this one for mouse up icon
|
||||
var/mouse_up_icon = null
|
||||
///used to make a special mouse cursor, this one for mouse up icon
|
||||
var/mouse_down_icon = null
|
||||
|
||||
///Used for ip intel checking to identify evaders, disabled because of issues with traffic
|
||||
var/ip_intel = "Disabled"
|
||||
|
||||
//datum that controls the displaying and hiding of tooltips
|
||||
///datum that controls the displaying and hiding of tooltips
|
||||
var/datum/tooltip/tooltips
|
||||
|
||||
///Last ping of the client
|
||||
var/lastping = 0
|
||||
///Average ping of the client
|
||||
var/avgping = 0
|
||||
var/connection_time //world.time they connected
|
||||
var/connection_realtime //world.realtime they connected
|
||||
var/connection_timeofday //world.timeofday they connected
|
||||
///world.time they connected
|
||||
var/connection_time
|
||||
///world.realtime they connected
|
||||
var/connection_realtime
|
||||
///world.timeofday they connected
|
||||
var/connection_timeofday
|
||||
|
||||
///If the client is currently in player preferences
|
||||
var/inprefs = FALSE
|
||||
///Used for limiting the rate of topic sends by the client to avoid abuse
|
||||
var/list/topiclimiter
|
||||
///Used for limiting the rate of clicks sends by the client to avoid abuse
|
||||
var/list/clicklimiter
|
||||
|
||||
///goonchat chatoutput of the client
|
||||
var/datum/chatOutput/chatOutput
|
||||
|
||||
var/list/credits //lazy list of all credit object bound to this client
|
||||
///lazy list of all credit object bound to this client
|
||||
var/list/credits
|
||||
|
||||
var/datum/player_details/player_details //these persist between logins/logouts during the same round.
|
||||
///these persist between logins/logouts during the same round.
|
||||
var/datum/player_details/player_details
|
||||
|
||||
var/list/char_render_holders //Should only be a key-value list of north/south/east/west = obj/screen.
|
||||
///Should only be a key-value list of north/south/east/west = obj/screen.
|
||||
var/list/char_render_holders
|
||||
|
||||
///LibVG encoding
|
||||
var/encoding = "1252"
|
||||
|
||||
var/encoding = "1252" // yogs - LibVG
|
||||
|
||||
var/list/seen_messages // Messages currently seen by this client
|
||||
///Messages currently seen by this client
|
||||
var/list/seen_messages
|
||||
|
||||
var/list/spell_tabs = list()
|
||||
|
||||
//rate limiting for the crew manifest
|
||||
///rate limiting for the crew manifest
|
||||
var/crew_manifest_delay
|
||||
|
||||
var/datum/viewData/view_size
|
||||
@@ -5,13 +5,26 @@ For the main html chat area
|
||||
//Precaching a bunch of shit
|
||||
GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of icons for the browser output
|
||||
|
||||
//On client, created on login
|
||||
/// Should match the value set in the browser js
|
||||
#define MAX_COOKIE_LENGTH 5
|
||||
|
||||
/**
|
||||
* The chatOutput datum exists to handle the goonchat browser.
|
||||
* On client, created on Client/New()
|
||||
*/
|
||||
/datum/chatOutput
|
||||
var/client/owner //client ref
|
||||
var/loaded = FALSE // Has the client loaded the browser output area?
|
||||
var/list/messageQueue //If they haven't loaded chat, this is where messages will go until they do
|
||||
var/cookieSent = FALSE // Has the client sent a cookie for analysis
|
||||
var/broken = FALSE
|
||||
/// The client that owns us.
|
||||
var/client/owner
|
||||
/// How many times client data has been checked
|
||||
var/total_checks = 0
|
||||
/// When to next clear the client data checks counter
|
||||
var/next_time_to_clear = 0
|
||||
/// Has the client loaded the browser output area?
|
||||
var/loaded = FALSE
|
||||
/// If they haven't loaded chat, this is where messages will go until they do
|
||||
var/list/messageQueue
|
||||
var/cookieSent = FALSE // Has the client sent a cookie for analysis
|
||||
var/broken = FALSE
|
||||
var/list/connectionHistory //Contains the connection history passed from chat cookie
|
||||
var/adminMusicVolume = 25 //This is for the Play Global Sound verb
|
||||
|
||||
@@ -20,13 +33,18 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
messageQueue = list()
|
||||
connectionHistory = list()
|
||||
|
||||
/**
|
||||
* start: Tries to load the chat browser
|
||||
* Aborts if a problem is encountered.
|
||||
* Async because this is called from Client/New.
|
||||
*/
|
||||
/datum/chatOutput/proc/start()
|
||||
set waitfor = FALSE
|
||||
//Check for existing chat
|
||||
if(!owner)
|
||||
return FALSE
|
||||
|
||||
if(!winexists(owner, "browseroutput")) // Oh goddamnit.
|
||||
set waitfor = FALSE
|
||||
broken = TRUE
|
||||
message_admins("Couldn't start chat for [key_name_admin(owner)]!")
|
||||
. = FALSE
|
||||
@@ -41,6 +59,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
|
||||
return TRUE
|
||||
|
||||
/// Loads goonchat and sends assets.
|
||||
/datum/chatOutput/proc/load()
|
||||
set waitfor = FALSE
|
||||
if(!owner)
|
||||
@@ -51,6 +70,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
|
||||
owner << browse(file('code/modules/goonchat/browserassets/html/browserOutput.html'), "window=browseroutput")
|
||||
|
||||
/// Interprets input from the client. Will send data back if required.
|
||||
/datum/chatOutput/Topic(href, list/href_list)
|
||||
if(usr.client != owner)
|
||||
return TRUE
|
||||
@@ -106,7 +126,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
ehjax_send(data = data)
|
||||
|
||||
|
||||
//Called on chat output done-loading by JS.
|
||||
/// Called on chat output done-loading by JS.
|
||||
/datum/chatOutput/proc/doneLoading()
|
||||
if(loaded)
|
||||
return
|
||||
@@ -126,15 +146,26 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
//do not convert to to_chat()
|
||||
SEND_TEXT(owner, "<span class=\"userdanger\">Failed to load fancy chat, reverting to old chat. Certain features won't work.</span>")
|
||||
|
||||
/// Hides the standard output and makes the browser visible.
|
||||
/datum/chatOutput/proc/showChat()
|
||||
winset(owner, "output", "is-visible=false")
|
||||
winset(owner, "browseroutput", "is-disabled=false;is-visible=true")
|
||||
|
||||
/// Sends json encoded data to the browser.
|
||||
/datum/chatOutput/proc/ehjax_send(client/C = owner, window = "browseroutput", data)
|
||||
if(islist(data))
|
||||
data = json_encode(data)
|
||||
C << output("[data]", "[window]:ehjaxCallback")
|
||||
|
||||
/**
|
||||
* Sends music data to the browser. If enabled by the browser, it will start playing.
|
||||
* Arguments:
|
||||
* music must be a https adress.
|
||||
* extra_data is a list. The keys "pitch", "start" and "end" are used.
|
||||
** "pitch" determines the playback rate
|
||||
** "start" determines the start time of the sound
|
||||
** "end" determines when the musics stops playing
|
||||
*/
|
||||
/datum/chatOutput/proc/sendMusic(music, list/extra_data)
|
||||
if(!findtext(music, GLOB.is_http_protocol))
|
||||
return
|
||||
@@ -147,14 +178,16 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
|
||||
ehjax_send(data = music_data)
|
||||
|
||||
/// Stops music playing throw the browser.
|
||||
/datum/chatOutput/proc/stopMusic()
|
||||
ehjax_send(data = "stopMusic")
|
||||
|
||||
/// Setter for adminMusicVolume. Sanitizes the value to between 0 and 100.
|
||||
/datum/chatOutput/proc/setMusicVolume(volume = "")
|
||||
if(volume)
|
||||
adminMusicVolume = clamp(text2num(volume), 0, 100)
|
||||
|
||||
//Sends client connection details to the chat to handle and save
|
||||
/// Sends client connection details to the chat to handle and save
|
||||
/datum/chatOutput/proc/sendClientData()
|
||||
//Get dem deets
|
||||
var/list/deets = list("clientData" = list())
|
||||
@@ -164,7 +197,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
var/data = json_encode(deets)
|
||||
ehjax_send(data = data)
|
||||
|
||||
//Called by client, sent data to investigate (cookie history so far)
|
||||
/// Called by client, sent data to investigate (cookie history so far)
|
||||
/datum/chatOutput/proc/analyzeClientData(cookie = "")
|
||||
if(!cookie)
|
||||
return
|
||||
@@ -190,15 +223,15 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
|
||||
cookieSent = TRUE
|
||||
|
||||
//Called by js client every 60 seconds
|
||||
/// Called by js client every 60 seconds
|
||||
/datum/chatOutput/proc/ping()
|
||||
return "pong"
|
||||
|
||||
//Called by js client on js error
|
||||
/// Called by js client on js error
|
||||
/datum/chatOutput/proc/debug(error)
|
||||
log_world("\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: [(src.owner.key ? src.owner.key : src.owner)] triggered JS error: [error]")
|
||||
|
||||
//Global chat procs
|
||||
/// Global chat proc. to_chat_immediate will circumvent SSchat and send data as soon as possible.
|
||||
/proc/to_chat_immediate(target, message, handle_whitespace = TRUE, confidential = FALSE)
|
||||
if(!target || !message)
|
||||
return
|
||||
@@ -253,14 +286,17 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
// url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
|
||||
C << output(url_encode(url_encode(message)), "browseroutput:output")
|
||||
|
||||
/// Sends a text message to the target.
|
||||
/proc/to_chat(target, message, handle_whitespace = TRUE, confidential = FALSE)
|
||||
if(Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.initialized)
|
||||
to_chat_immediate(target, message, handle_whitespace, confidential)
|
||||
return
|
||||
SSchat.queue(target, message, handle_whitespace, confidential)
|
||||
|
||||
/datum/chatOutput/proc/swaptolightmode() //Dark mode light mode stuff. Yell at KMC if this breaks! (See darkmode.dm for documentation)
|
||||
/// Dark mode light mode stuff. Yell at KMC if this breaks! (See darkmode.dm for documentation)
|
||||
/datum/chatOutput/proc/swaptolightmode()
|
||||
owner.force_white_theme()
|
||||
|
||||
/// Light mode stuff. (See darkmode.dm for documentation)
|
||||
/datum/chatOutput/proc/swaptodarkmode()
|
||||
owner.force_dark_theme()
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
///////////////
|
||||
//Drone verbs that appear in the Drone tab and on buttons
|
||||
|
||||
|
||||
/**
|
||||
* Echoes drone laws to the user
|
||||
*
|
||||
* See [/mob/living/simple_animal/drone/var/laws]
|
||||
*/
|
||||
/mob/living/simple_animal/drone/verb/check_laws()
|
||||
set category = "Drone"
|
||||
set name = "Check Laws"
|
||||
@@ -12,6 +16,17 @@
|
||||
to_chat(src, "<b>Drone Laws</b>")
|
||||
to_chat(src, laws)
|
||||
|
||||
/**
|
||||
* Creates an alert to drones in the same network
|
||||
*
|
||||
* Prompts user for alert level of:
|
||||
* * Low
|
||||
* * Medium
|
||||
* * High
|
||||
* * Critical
|
||||
*
|
||||
* Attaches area name to message
|
||||
*/
|
||||
/mob/living/simple_animal/drone/verb/drone_ping()
|
||||
set category = "Drone"
|
||||
set name = "Drone ping"
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
/**
|
||||
* Run when a client is put in this mob or reconnets to byond and their client was on this mob
|
||||
*
|
||||
* Things it does:
|
||||
* * Adds player to player_list
|
||||
* * sets lastKnownIP
|
||||
* * sets computer_id
|
||||
* * logs the login
|
||||
* * tells the world to update it's status (for player count)
|
||||
* * create mob huds for the mob if needed
|
||||
* * reset next_move to 1
|
||||
* * parent call
|
||||
* * if the client exists set the perspective to the mob loc
|
||||
* * call on_log on the loc (sigh)
|
||||
* * reload the huds for the mob
|
||||
* * reload all full screen huds attached to this mob
|
||||
* * load any global alternate apperances
|
||||
* * sync the mind datum via sync_mind()
|
||||
* * call any client login callbacks that exist
|
||||
* * grant any actions the mob has to the client
|
||||
* * calls [auto_deadmin_on_login](mob.html#proc/auto_deadmin_on_login)
|
||||
* * send signal COMSIG_MOB_CLIENT_LOGIN
|
||||
*/
|
||||
/mob/Login()
|
||||
if(!client)
|
||||
return FALSE
|
||||
@@ -58,6 +81,17 @@
|
||||
log_message("Client [key_name(src)] has taken ownership of mob [src]([src.type])", LOG_OWNERSHIP)
|
||||
SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client)
|
||||
|
||||
/**
|
||||
* Checks if the attached client is an admin and may deadmin them
|
||||
*
|
||||
* Configs:
|
||||
* * flag/auto_deadmin_players
|
||||
* * client.prefs?.toggles & DEADMIN_ALWAYS
|
||||
* * User is antag and flag/auto_deadmin_antagonists or client.prefs?.toggles & DEADMIN_ANTAGONIST
|
||||
* * or if their job demands a deadminning SSjob.handle_auto_deadmin_roles()
|
||||
*
|
||||
* Called from [login](mob.html#proc/Login)
|
||||
*/
|
||||
/mob/proc/auto_deadmin_on_login() //return true if they're not an admin at the end.
|
||||
if(!client?.holder)
|
||||
return TRUE
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
/**
|
||||
* Delete a mob
|
||||
*
|
||||
* Removes mob from the following global lists
|
||||
* * GLOB.mob_list
|
||||
* * GLOB.dead_mob_list
|
||||
* * GLOB.alive_mob_list
|
||||
* * GLOB.all_clockwork_mobs
|
||||
* * GLOB.mob_directory
|
||||
*
|
||||
* Unsets the focus var
|
||||
*
|
||||
* Clears alerts for this mob
|
||||
*
|
||||
* Resets all the observers perspectives to the tile this mob is on
|
||||
*
|
||||
* qdels any client colours in place on this mob
|
||||
*
|
||||
* Ghostizes the client attached to this mob
|
||||
*
|
||||
* Parent call
|
||||
*
|
||||
* Returns QDEL_HINT_HARDDEL (don't change this)
|
||||
*/
|
||||
/mob/Destroy()//This makes sure that mobs with clients/keys are not just deleted from the game.
|
||||
GLOB.mob_list -= src
|
||||
GLOB.dead_mob_list -= src
|
||||
@@ -19,6 +43,24 @@
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL
|
||||
|
||||
/**
|
||||
* Intialize a mob
|
||||
*
|
||||
* Sends global signal COMSIG_GLOB_MOB_CREATED
|
||||
*
|
||||
* Adds to global lists
|
||||
* * GLOB.mob_list
|
||||
* * GLOB.mob_directory (by tag)
|
||||
* * GLOB.dead_mob_list - if mob is dead
|
||||
* * GLOB.alive_mob_list - if the mob is alive
|
||||
*
|
||||
* Other stuff:
|
||||
* * Sets the mob focus to itself
|
||||
* * Generates huds
|
||||
* * If there are any global alternate apperances apply them to this mob
|
||||
* * set a random nutrition level
|
||||
* * Intialize the movespeed of the mob
|
||||
*/
|
||||
/mob/Initialize()
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_MOB_CREATED, src)
|
||||
GLOB.mob_list += src
|
||||
@@ -39,9 +81,20 @@
|
||||
update_config_movespeed()
|
||||
update_movespeed(TRUE)
|
||||
|
||||
/**
|
||||
* Generate the tag for this mob
|
||||
*
|
||||
* This is simply "mob_"+ a global incrementing counter that goes up for every mob
|
||||
*/
|
||||
/mob/GenerateTag()
|
||||
tag = "mob_[next_mob_id++]"
|
||||
|
||||
/**
|
||||
* Prepare the huds for this atom
|
||||
*
|
||||
* Goes through hud_possible list and adds the images to the hud_list variable (if not already
|
||||
* cached)
|
||||
*/
|
||||
/atom/proc/prepare_huds()
|
||||
hud_list = list()
|
||||
for(var/hud in hud_possible)
|
||||
@@ -54,6 +107,9 @@
|
||||
I.appearance_flags = RESET_COLOR|RESET_TRANSFORM
|
||||
hud_list[hud] = I
|
||||
|
||||
/**
|
||||
* Some kind of debug verb that gives atmosphere environment details
|
||||
*/
|
||||
/mob/proc/Cell()
|
||||
set category = "Admin"
|
||||
set hidden = 1
|
||||
@@ -71,9 +127,15 @@
|
||||
|
||||
to_chat(usr, t)
|
||||
|
||||
/**
|
||||
* Return the desc of this mob for a photo
|
||||
*/
|
||||
/mob/proc/get_photo_description(obj/item/camera/camera)
|
||||
return "a ... thing?"
|
||||
|
||||
/**
|
||||
* Show a message to this mob (visual)
|
||||
*/
|
||||
/mob/proc/show_message(msg, type, alt_msg, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
|
||||
|
||||
if(!client)
|
||||
@@ -104,15 +166,23 @@
|
||||
else
|
||||
to_chat(src, msg)
|
||||
|
||||
// Show a message to all player mobs who sees this atom
|
||||
// Show a message to the src mob (if the src is a mob)
|
||||
// Use for atoms performing visible actions
|
||||
// message is output to anyone who can see, e.g. "The [src] does something!"
|
||||
// self_message (optional) is what the src mob sees e.g. "You do something!"
|
||||
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
|
||||
// vision_distance (optional) define how many tiles away the message can be seen.
|
||||
// ignored_mob (optional) doesn't show any message to a given mob if TRUE.
|
||||
|
||||
/**
|
||||
* Generate a visible message from this atom
|
||||
*
|
||||
* Show a message to all player mobs who sees this atom
|
||||
*
|
||||
* Show a message to the src mob (if the src is a mob)
|
||||
*
|
||||
* Use for atoms performing visible actions
|
||||
*
|
||||
* message is output to anyone who can see, e.g. "The [src] does something!"
|
||||
*
|
||||
* Vars:
|
||||
* * self_message (optional) is what the src mob sees e.g. "You do something!"
|
||||
* * blind_message (optional) is what blind people will hear e.g. "You hear something!"
|
||||
* * vision_distance (optional) define how many tiles away the message can be seen.
|
||||
* * ignored_mob (optional) doesn't show any message to a given mob if TRUE.
|
||||
*/
|
||||
/atom/proc/visible_message(message, self_message, blind_message, vision_distance, list/ignored_mobs)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
@@ -147,13 +217,17 @@
|
||||
|
||||
M.show_message(msg,1,blind_message,2)
|
||||
|
||||
// Show a message to all mobs in earshot of this one
|
||||
// This would be for audible actions by the src mob
|
||||
// message is the message output to anyone who can hear.
|
||||
// self_message (optional) is what the src mob hears.
|
||||
// deaf_message (optional) is what deaf people will see.
|
||||
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
|
||||
/**
|
||||
* Show a message to all mobs in earshot of this one
|
||||
*
|
||||
* This would be for audible actions by the src mob
|
||||
*
|
||||
* vars:
|
||||
* * message is the message output to anyone who can hear.
|
||||
* * self_message (optional) is what the src mob hears.
|
||||
* * deaf_message (optional) is what deaf people will see.
|
||||
* * hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
*/
|
||||
/mob/audible_message(message, deaf_message, hearing_distance, self_message)
|
||||
var/range = 7
|
||||
if(hearing_distance)
|
||||
@@ -164,12 +238,16 @@
|
||||
msg = self_message
|
||||
M.show_message( msg, 2, deaf_message, 1)
|
||||
|
||||
// Show a message to all mobs in earshot of this atom
|
||||
// Use for objects performing audible actions
|
||||
// message is the message output to anyone who can hear.
|
||||
// deaf_message (optional) is what deaf people will see.
|
||||
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
|
||||
/**
|
||||
* Show a message to all mobs in earshot of this atom
|
||||
*
|
||||
* Use for objects performing audible actions
|
||||
*
|
||||
* vars:
|
||||
* * message is the message output to anyone who can hear.
|
||||
* * deaf_message (optional) is what deaf people will see.
|
||||
* * hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
*/
|
||||
/atom/proc/audible_message(message, deaf_message, hearing_distance)
|
||||
var/range = 7
|
||||
if(hearing_distance)
|
||||
@@ -177,16 +255,24 @@
|
||||
for(var/mob/M in get_hearers_in_view(range, src))
|
||||
M.show_message( message, 2, deaf_message, 1)
|
||||
|
||||
///Get the item on the mob in the storage slot identified by the id passed in
|
||||
/mob/proc/get_item_by_slot(slot_id)
|
||||
return null
|
||||
|
||||
///Is the mob restrained
|
||||
/mob/proc/restrained(ignore_grab)
|
||||
return
|
||||
|
||||
///Is the mob incapacitated
|
||||
/mob/proc/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, check_immobilized = FALSE)
|
||||
return
|
||||
|
||||
//This proc is called whenever someone clicks an inventory ui slot.
|
||||
/**
|
||||
* This proc is called whenever someone clicks an inventory ui slot.
|
||||
*
|
||||
* Mostly tries to put the item into the slot if possible, or call attack hand
|
||||
* on the item in the slot if the users active hand is empty
|
||||
*/
|
||||
/mob/proc/attack_ui(slot)
|
||||
var/obj/item/W = get_active_held_item()
|
||||
|
||||
@@ -202,10 +288,17 @@
|
||||
|
||||
return 0
|
||||
|
||||
//This is a SAFE proc. Use this instead of equip_to_slot()!
|
||||
//set qdel_on_fail to have it delete W if it fails to equip
|
||||
//set disable_warning to disable the 'you are unable to equip that' warning.
|
||||
//unset redraw_mob to prevent the mob from being redrawn at the end.
|
||||
/**
|
||||
* Try to equip an item to a slot on the mob
|
||||
*
|
||||
* This is a SAFE proc. Use this instead of equip_to_slot()!
|
||||
*
|
||||
* set qdel_on_fail to have it delete W if it fails to equip
|
||||
*
|
||||
* set disable_warning to disable the 'you are unable to equip that' warning.
|
||||
*
|
||||
* unset redraw_mob to prevent the mob icons from being redrawn at the end.
|
||||
*/
|
||||
/mob/proc/equip_to_slot_if_possible(obj/item/W, slot, qdel_on_fail = FALSE, disable_warning = FALSE, redraw_mob = TRUE, bypass_equip_delay_self = FALSE)
|
||||
if(!istype(W))
|
||||
return FALSE
|
||||
@@ -219,18 +312,35 @@
|
||||
equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail.
|
||||
return TRUE
|
||||
|
||||
//This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't equip need to be done before! Use mob_can_equip() for that task.
|
||||
//In most cases you will want to use equip_to_slot_if_possible()
|
||||
/**
|
||||
* Actually equips an item to a slot (UNSAFE)
|
||||
*
|
||||
* This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on
|
||||
* whether you can or can't equip need to be done before! Use mob_can_equip() for that task.
|
||||
*
|
||||
*In most cases you will want to use equip_to_slot_if_possible()
|
||||
*/
|
||||
/mob/proc/equip_to_slot(obj/item/W, slot)
|
||||
return
|
||||
|
||||
//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the round starts and when events happen and such.
|
||||
//Also bypasses equip delay checks, since the mob isn't actually putting it on.
|
||||
/**
|
||||
* Equip an item to the slot or delete
|
||||
*
|
||||
* This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to
|
||||
* equip people when the round starts and when events happen and such.
|
||||
*
|
||||
* Also bypasses equip delay checks, since the mob isn't actually putting it on.
|
||||
*/
|
||||
/mob/proc/equip_to_slot_or_del(obj/item/W, slot)
|
||||
return equip_to_slot_if_possible(W, slot, TRUE, TRUE, FALSE, TRUE)
|
||||
|
||||
//puts the item "W" into an appropriate slot in a human's inventory
|
||||
//returns 0 if it cannot, 1 if successful
|
||||
/**
|
||||
* Auto equip the passed in item the appropriate slot based on equipment priority
|
||||
*
|
||||
* puts the item "W" into an appropriate slot in a human's inventory
|
||||
*
|
||||
* returns 0 if it cannot, 1 if successful
|
||||
*/
|
||||
/mob/proc/equip_to_appropriate_slot(obj/item/W)
|
||||
if(!istype(W))
|
||||
return 0
|
||||
@@ -253,9 +363,12 @@
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
// reset_perspective(thing) set the eye to the thing (if it's equal to current default reset to mob perspective)
|
||||
// reset_perspective() set eye to common default : mob on turf, loc otherwise
|
||||
/**
|
||||
* Reset the attached clients perspective (viewpoint)
|
||||
*
|
||||
* reset_perspective() set eye to common default : mob on turf, loc otherwise
|
||||
* reset_perspective(thing) set the eye to the thing (if it's equal to current default reset to mob perspective)
|
||||
*/
|
||||
/mob/proc/reset_perspective(atom/A)
|
||||
if(client)
|
||||
if(A)
|
||||
@@ -287,6 +400,7 @@
|
||||
client.eye = loc
|
||||
return 1
|
||||
|
||||
/// Show the mob's inventory to another mob
|
||||
/mob/proc/show_inv(mob/user)
|
||||
return
|
||||
|
||||
@@ -300,7 +414,13 @@
|
||||
var/mob/living/carbon/C = src
|
||||
C.give()
|
||||
|
||||
//mob verbs are faster than object verbs. See https://secure.byond.com/forum/?post=1326139&page=2#comment8198716 for why this isn't atom/verb/examine()
|
||||
/**
|
||||
* Examine a mob
|
||||
*
|
||||
* mob verbs are faster than object verbs. See
|
||||
* [this byond forum post](https://secure.byond.com/forum/?post=1326139&page=2#comment8198716)
|
||||
* for why this isn't atom/verb/examine()
|
||||
*/
|
||||
/mob/verb/examinate(atom/A as mob|obj|turf in view()) //It used to be oview(12), but I can't really say why
|
||||
set name = "Examine"
|
||||
set category = "IC"
|
||||
@@ -318,10 +438,19 @@
|
||||
to_chat(src, result.Join("\n"))
|
||||
SEND_SIGNAL(src, COMSIG_MOB_EXAMINATE, A)
|
||||
|
||||
//same as above
|
||||
//note: ghosts can point, this is intended
|
||||
//visible_message will handle invisibility properly
|
||||
//overridden here and in /mob/dead/observer for different point span classes and sanity checks
|
||||
/**
|
||||
* Point at an atom
|
||||
*
|
||||
* mob verbs are faster than object verbs. See
|
||||
* [this byond forum post](https://secure.byond.com/forum/?post=1326139&page=2#comment8198716)
|
||||
* for why this isn't atom/verb/pointed()
|
||||
*
|
||||
* note: ghosts can point, this is intended
|
||||
*
|
||||
* visible_message will handle invisibility properly
|
||||
*
|
||||
* overridden here and in /mob/dead/observer for different point span classes and sanity checks
|
||||
*/
|
||||
/mob/verb/pointed(atom/A as mob|obj|turf in view())
|
||||
set name = "Point To"
|
||||
set category = "Object"
|
||||
@@ -341,9 +470,11 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
///Can this mob resist (default FALSE)
|
||||
/mob/proc/can_resist()
|
||||
return FALSE //overridden in living.dm
|
||||
|
||||
///Spin this mob around it's central axis
|
||||
/mob/proc/spin(spintime, speed)
|
||||
set waitfor = 0
|
||||
var/D = dir
|
||||
@@ -363,16 +494,23 @@
|
||||
setDir(D)
|
||||
spintime -= speed
|
||||
|
||||
///Update the pulling hud icon
|
||||
/mob/proc/update_pull_hud_icon()
|
||||
if(hud_used)
|
||||
if(hud_used.pull_icon)
|
||||
hud_used.pull_icon.update_icon(src)
|
||||
|
||||
///Update the resting hud icon
|
||||
/mob/proc/update_rest_hud_icon()
|
||||
if(hud_used)
|
||||
if(hud_used.rest_icon)
|
||||
hud_used.rest_icon.update_icon(src)
|
||||
|
||||
/**
|
||||
* Verb to activate the object in your held hand
|
||||
*
|
||||
* Calls attack self on the item and updates the inventory hud for hands
|
||||
*/
|
||||
/mob/verb/mode()
|
||||
set name = "Activate Held Object"
|
||||
set category = "Object"
|
||||
@@ -389,6 +527,11 @@
|
||||
I.attack_self(src)
|
||||
update_inv_hands()
|
||||
|
||||
/**
|
||||
* Get the notes of this mob
|
||||
*
|
||||
* This actually gets the mind datums notes
|
||||
*/
|
||||
/mob/verb/memory()
|
||||
set name = "Notes"
|
||||
set category = "IC"
|
||||
@@ -398,6 +541,9 @@
|
||||
else
|
||||
to_chat(src, "You don't have a mind datum for some reason, so you can't look at your notes, if you had any.")
|
||||
|
||||
/**
|
||||
* Add a note to the mind datum
|
||||
*/
|
||||
/mob/verb/add_memory(msg as message)
|
||||
set name = "Add Note"
|
||||
set category = "IC"
|
||||
@@ -419,6 +565,13 @@
|
||||
else
|
||||
to_chat(src, "You don't have a mind datum for some reason, so you can't add a note to it.")
|
||||
|
||||
/**
|
||||
* Allows you to respawn, abandoning your current mob
|
||||
*
|
||||
* This sends you back to the lobby creating a new dead mob
|
||||
*
|
||||
* Only works if flag/norespawn is allowed in config
|
||||
*/
|
||||
/mob/verb/abandon_mob()
|
||||
set name = "Respawn"
|
||||
set category = "OOC"
|
||||
@@ -453,7 +606,9 @@
|
||||
return
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sometimes helps if the user is stuck in another perspective or camera
|
||||
*/
|
||||
/mob/verb/cancel_camera()
|
||||
set name = "Cancel Camera View"
|
||||
set category = "OOC"
|
||||
@@ -472,7 +627,13 @@
|
||||
set hidden = TRUE
|
||||
set category = null
|
||||
return
|
||||
|
||||
/**
|
||||
* Topic call back for any mob
|
||||
*
|
||||
* * Unset machines if "mach_close" sent
|
||||
* * refresh the inventory of machines in range if "refresh" sent
|
||||
* * handles the strip panel equip and unequip as well if "item" sent
|
||||
*/
|
||||
/mob/Topic(href, href_list)
|
||||
if(href_list["mach_close"])
|
||||
var/t1 = text("window=[href_list["mach_close"]]")
|
||||
@@ -515,6 +676,9 @@
|
||||
/mob/proc/stripPanelEquip(obj/item/what, mob/who)
|
||||
return
|
||||
|
||||
/**
|
||||
* Controls if a mouse drop succeeds (return null if it doesnt)
|
||||
*/
|
||||
/mob/MouseDrop(mob/M)
|
||||
. = ..()
|
||||
if(M != usr)
|
||||
@@ -526,13 +690,25 @@
|
||||
if(isAI(M))
|
||||
return
|
||||
show_inv(usr)
|
||||
/**
|
||||
* Handle the result of a click drag onto this mob
|
||||
*
|
||||
* For mobs this just shows the inventory
|
||||
*/
|
||||
|
||||
///Is the mob muzzled (default false)
|
||||
/mob/proc/is_muzzled()
|
||||
return 0
|
||||
|
||||
/mob/proc/get_status_tab_items()
|
||||
. = list()
|
||||
|
||||
/**
|
||||
* Output an update to the stat panel for the client
|
||||
*
|
||||
* calculates client ping, round id, server time, time dilation and other data about the round
|
||||
* and puts it in the mob status panel on a regular loop
|
||||
*/
|
||||
/mob/Stat()
|
||||
..()
|
||||
|
||||
@@ -603,6 +779,11 @@
|
||||
. += add_spells_to_statpanel(mind.spell_list)
|
||||
. += add_spells_to_statpanel(mob_spell_list)
|
||||
|
||||
/**
|
||||
* Convert a list of spells into a displyable list for the statpanel
|
||||
*
|
||||
* Shows charge and other important info
|
||||
*/
|
||||
/mob/proc/add_spells_to_statpanel(list/spells)
|
||||
var/list/L = list()
|
||||
for(var/obj/effect/proc_holder/spell/S in spells)
|
||||
@@ -619,6 +800,16 @@
|
||||
#define MOB_FACE_DIRECTION_DELAY 1
|
||||
|
||||
// facing verbs
|
||||
/**
|
||||
* Returns true if a mob can turn to face things
|
||||
*
|
||||
* Conditions:
|
||||
* * client.last_turn > world.time
|
||||
* * not dead or unconcious
|
||||
* * not anchored
|
||||
* * no transform not set
|
||||
* * we are not restrained
|
||||
*/
|
||||
/mob/proc/canface()
|
||||
if(world.time < client.last_turn)
|
||||
return FALSE
|
||||
@@ -632,11 +823,13 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
///Checks mobility move as well as parent checks
|
||||
/mob/living/canface()
|
||||
if(!(mobility_flags & MOBILITY_MOVE))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
///Hidden verb to turn east
|
||||
/mob/verb/eastface()
|
||||
set hidden = TRUE
|
||||
if(!canface())
|
||||
@@ -645,6 +838,7 @@
|
||||
client.last_turn = world.time + MOB_FACE_DIRECTION_DELAY
|
||||
return TRUE
|
||||
|
||||
///Hidden verb to turn west
|
||||
/mob/verb/westface()
|
||||
set hidden = TRUE
|
||||
if(!canface())
|
||||
@@ -653,6 +847,7 @@
|
||||
client.last_turn = world.time + MOB_FACE_DIRECTION_DELAY
|
||||
return TRUE
|
||||
|
||||
///Hidden verb to turn north
|
||||
/mob/verb/northface()
|
||||
set hidden = TRUE
|
||||
if(!canface())
|
||||
@@ -661,6 +856,7 @@
|
||||
client.last_turn = world.time + MOB_FACE_DIRECTION_DELAY
|
||||
return TRUE
|
||||
|
||||
///Hidden verb to turn south
|
||||
/mob/verb/southface()
|
||||
set hidden = TRUE
|
||||
if(!canface())
|
||||
@@ -709,7 +905,8 @@
|
||||
pixel_y--
|
||||
is_shifted = TRUE
|
||||
|
||||
/mob/proc/IsAdvancedToolUser()//This might need a rename but it should replace the can this mob use things check
|
||||
///This might need a rename but it should replace the can this mob use things check
|
||||
/mob/proc/IsAdvancedToolUser()
|
||||
return FALSE
|
||||
|
||||
/mob/proc/swap_hand()
|
||||
@@ -721,24 +918,29 @@
|
||||
/mob/proc/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) //For sec bot threat assessment
|
||||
return 0
|
||||
|
||||
///Get the ghost of this mob (from the mind)
|
||||
/mob/proc/get_ghost(even_if_they_cant_reenter, ghosts_with_clients)
|
||||
if(mind)
|
||||
return mind.get_ghost(even_if_they_cant_reenter, ghosts_with_clients)
|
||||
|
||||
///Force get the ghost from the mind
|
||||
/mob/proc/grab_ghost(force)
|
||||
if(mind)
|
||||
return mind.grab_ghost(force = force)
|
||||
|
||||
///Notify a ghost that it's body is being cloned
|
||||
/mob/proc/notify_ghost_cloning(var/message = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!", var/sound = 'sound/effects/genetics.ogg', var/atom/source = null, flashwindow)
|
||||
var/mob/dead/observer/ghost = get_ghost()
|
||||
if(ghost)
|
||||
ghost.notify_cloning(message, sound, source, flashwindow)
|
||||
return ghost
|
||||
|
||||
///Add a spell to the mobs spell list
|
||||
/mob/proc/AddSpell(obj/effect/proc_holder/spell/S)
|
||||
mob_spell_list += S
|
||||
S.action?.Grant(src)
|
||||
|
||||
///Remove a spell from the mobs spell list
|
||||
/mob/proc/RemoveSpell(obj/effect/proc_holder/spell/spell)
|
||||
if(!spell)
|
||||
return
|
||||
@@ -748,6 +950,7 @@
|
||||
mob_spell_list -= S
|
||||
qdel(S)
|
||||
|
||||
///Return any anti magic atom on this mob that matches the magic type
|
||||
/mob/proc/anti_magic_check(magic = TRUE, holy = FALSE, tinfoil = FALSE, chargecost = 1, self = FALSE)
|
||||
if(!magic && !holy && !tinfoil)
|
||||
return
|
||||
@@ -760,7 +963,13 @@
|
||||
if((magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC)) || (holy && HAS_TRAIT(src, TRAIT_HOLY)))
|
||||
return src
|
||||
|
||||
//You can buckle on mobs if you're next to them since most are dense
|
||||
/**
|
||||
* Buckle to another mob
|
||||
*
|
||||
* You can buckle on mobs if you're next to them since most are dense
|
||||
*
|
||||
* Turns you to face the other mob too
|
||||
*/
|
||||
/mob/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
|
||||
if(M.buckled)
|
||||
return 0
|
||||
@@ -774,18 +983,18 @@
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
//Default buckling shift visual for mobs
|
||||
///Call back post buckle to a mob to offset your visual height
|
||||
/mob/post_buckle_mob(mob/living/M)
|
||||
var/height = M.get_mob_buckling_height(src)
|
||||
M.pixel_y = initial(M.pixel_y) + height
|
||||
if(M.layer < layer)
|
||||
M.layer = layer + 0.1
|
||||
|
||||
///Call back post unbuckle from a mob, (reset your visual height here)
|
||||
/mob/post_unbuckle_mob(mob/living/M)
|
||||
M.layer = initial(M.layer)
|
||||
M.pixel_y = initial(M.pixel_y)
|
||||
|
||||
//returns the height in pixel the mob should have when buckled to another mob.
|
||||
///returns the height in pixel the mob should have when buckled to another mob.
|
||||
/mob/proc/get_mob_buckling_height(mob/seat)
|
||||
if(isliving(seat))
|
||||
var/mob/living/L = seat
|
||||
@@ -793,25 +1002,30 @@
|
||||
return 0
|
||||
return 9
|
||||
|
||||
//can the mob be buckled to something by default?
|
||||
///can the mob be buckled to something by default?
|
||||
/mob/proc/can_buckle()
|
||||
return 1
|
||||
|
||||
//can the mob be unbuckled from something by default?
|
||||
///can the mob be unbuckled from something by default?
|
||||
/mob/proc/can_unbuckle()
|
||||
return 1
|
||||
|
||||
//Can the mob interact() with an atom?
|
||||
///Can the mob interact() with an atom?
|
||||
/mob/proc/can_interact_with(atom/A)
|
||||
return IsAdminGhost(src) || Adjacent(A)
|
||||
|
||||
//Can the mob use Topic to interact with machines
|
||||
///Can the mob use Topic to interact with machines
|
||||
/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
|
||||
return
|
||||
|
||||
///Can this mob use storage
|
||||
/mob/proc/canUseStorage()
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Check if the other mob has any factions the same as us
|
||||
*
|
||||
* If exact match is set, then all our factions must match exactly
|
||||
*/
|
||||
/mob/proc/faction_check_mob(mob/target, exact_match)
|
||||
if(exact_match) //if we need an exact match, we need to do some bullfuckery.
|
||||
var/list/faction_src = faction.Copy()
|
||||
@@ -822,7 +1036,11 @@
|
||||
faction_target -= "[REF(target)]" //same thing here.
|
||||
return faction_check(faction_src, faction_target, TRUE)
|
||||
return faction_check(faction, target.faction, FALSE)
|
||||
|
||||
/*
|
||||
* Compare two lists of factions, returning true if any match
|
||||
*
|
||||
* If exact match is passed through we only return true if both faction lists match equally
|
||||
*/
|
||||
/proc/faction_check(list/faction_A, list/faction_B, exact_match)
|
||||
var/list/match_list
|
||||
if(exact_match)
|
||||
@@ -836,8 +1054,13 @@
|
||||
return FALSE
|
||||
|
||||
|
||||
//This will update a mob's name, real_name, mind.name, GLOB.data_core records, pda, id and traitor text
|
||||
//Calling this proc without an oldname will only update the mob and skip updating the pda, id and records ~Carn
|
||||
/**
|
||||
* Fully update the name of a mob
|
||||
*
|
||||
* This will update a mob's name, real_name, mind.name, GLOB.data_core records, pda, id and traitor text
|
||||
*
|
||||
* Calling this proc without an oldname will only update the mob and skip updating the pda, id and records ~Carn
|
||||
*/
|
||||
/mob/proc/fully_replace_character_name(oldname,newname)
|
||||
log_message("[src] name changed from [oldname] to [newname]", LOG_OWNERSHIP)
|
||||
if(!newname)
|
||||
@@ -866,10 +1089,11 @@
|
||||
obj.update_explanation_text()
|
||||
return 1
|
||||
|
||||
//Updates GLOB.data_core records with new name , see mob/living/carbon/human
|
||||
///Updates GLOB.data_core records with new name , see mob/living/carbon/human
|
||||
/mob/proc/replace_records_name(oldname,newname)
|
||||
return
|
||||
|
||||
///update the ID name of this mob
|
||||
/mob/proc/replace_identification_name(oldname,newname)
|
||||
var/list/searching = GetAllContents()
|
||||
var/search_id = 1
|
||||
@@ -902,16 +1126,19 @@
|
||||
/mob/proc/update_health_hud()
|
||||
return
|
||||
|
||||
///Update the lighting plane and sight of this mob (sends COMSIG_MOB_UPDATE_SIGHT)
|
||||
/mob/proc/update_sight()
|
||||
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
|
||||
sync_lighting_plane_alpha()
|
||||
|
||||
///Set the lighting plane hud alpha to the mobs lighting_alpha var
|
||||
/mob/proc/sync_lighting_plane_alpha()
|
||||
if(hud_used)
|
||||
var/obj/screen/plane_master/lighting/L = hud_used.plane_masters["[LIGHTING_PLANE]"]
|
||||
if (L)
|
||||
L.alpha = lighting_alpha
|
||||
|
||||
///Update the mouse pointer of the attached client in this mob
|
||||
/mob/proc/update_mouse_pointer()
|
||||
if (!client)
|
||||
return
|
||||
@@ -926,10 +1153,11 @@
|
||||
client.mouse_pointer_icon = E.mouse_pointer
|
||||
|
||||
|
||||
|
||||
///This mob is abile to read books
|
||||
/mob/proc/is_literate()
|
||||
return FALSE
|
||||
|
||||
///Can this mob read (is literate and not blind)
|
||||
/mob/proc/can_read(obj/O)
|
||||
if(is_blind(src))
|
||||
to_chat(src, "<span class='warning'>As you are trying to read [O], you suddenly feel very stupid!</span>")
|
||||
@@ -939,12 +1167,17 @@
|
||||
return
|
||||
return TRUE
|
||||
|
||||
///Can this mob hold items
|
||||
/mob/proc/can_hold_items()
|
||||
return FALSE
|
||||
|
||||
///Get the id card on this mob
|
||||
/mob/proc/get_idcard(hand_first)
|
||||
return
|
||||
|
||||
/**
|
||||
* Get the mob VV dropdown extras
|
||||
*/
|
||||
/mob/vv_get_dropdown()
|
||||
. = ..()
|
||||
. += "---"
|
||||
@@ -960,12 +1193,16 @@
|
||||
.["Assume Direct Control"] = "?_src_=vars;[HrefToken()];direct_control=[REF(src)]"
|
||||
.["Offer Control to Ghosts"] = "?_src_=vars;[HrefToken()];offer_control=[REF(src)]"
|
||||
|
||||
/**
|
||||
* extra var handling for the logging var
|
||||
*/
|
||||
/mob/vv_get_var(var_name)
|
||||
switch(var_name)
|
||||
if("logging")
|
||||
return debug_variable(var_name, logging, 0, src, FALSE)
|
||||
. = ..()
|
||||
|
||||
///Show the language menu for this mob
|
||||
/mob/verb/open_language_menu()
|
||||
set name = "Open Language Menu"
|
||||
set category = "IC"
|
||||
@@ -973,12 +1210,15 @@
|
||||
var/datum/language_holder/H = get_language_holder()
|
||||
H.open_language_menu(usr)
|
||||
|
||||
///Adjust the nutrition of a mob
|
||||
/mob/proc/adjust_nutrition(var/change) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks
|
||||
nutrition = max(0, nutrition + change)
|
||||
|
||||
///Force set the mob nutrition
|
||||
/mob/proc/set_nutrition(var/change) //Seriously fuck you oldcoders.
|
||||
nutrition = max(0, change)
|
||||
|
||||
///Set the movement type of the mob and update it's movespeed
|
||||
/mob/setMovetype(newval)
|
||||
. = ..()
|
||||
update_movespeed(FALSE)
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/**
|
||||
* The mob, usually meant to be a creature of some type
|
||||
*
|
||||
* Has a client attached that is a living person (most of the time), although I have to admit
|
||||
* sometimes it's hard to tell they're sentient
|
||||
*
|
||||
* Has a lot of the creature game world logic, such as health etc
|
||||
*/
|
||||
/mob
|
||||
datum_flags = DF_USE_TAG
|
||||
density = TRUE
|
||||
@@ -13,102 +21,194 @@
|
||||
var/datum/mind/mind
|
||||
var/static/next_mob_id = 0
|
||||
|
||||
//MOVEMENT SPEED
|
||||
/// List of movement speed modifiers applying to this mob
|
||||
var/list/movespeed_modification //Lazy list, see mob_movespeed.dm
|
||||
/// The calculated mob speed slowdown based on the modifiers list
|
||||
var/cached_multiplicative_slowdown
|
||||
//ACTIONS
|
||||
/// List of action hud items the user has
|
||||
var/list/datum/action/actions = list()
|
||||
/// A special action? No idea why this lives here
|
||||
var/list/datum/action/chameleon_item_actions
|
||||
|
||||
var/stat = CONSCIOUS //Whether a mob is alive or dead. TODO: Move this to living - Nodrak
|
||||
/// Whether a mob is alive or dead. TODO: Move this to living - Nodrak (2019, still here)
|
||||
var/stat = CONSCIOUS
|
||||
|
||||
/*A bunch of this stuff really needs to go under their own defines instead of being globally attached to mob.
|
||||
/* A bunch of this stuff really needs to go under their own defines instead of being globally attached to mob.
|
||||
A variable should only be globally attached to turfs/objects/whatever, when it is in fact needed as such.
|
||||
The current method unnecessarily clusters up the variable list, especially for humans (although rearranging won't really clean it up a lot but the difference will be noticable for other mobs).
|
||||
I'll make some notes on where certain variable defines should probably go.
|
||||
Changing this around would probably require a good look-over the pre-existing code.
|
||||
*/
|
||||
|
||||
/// The zone this mob is currently targeting
|
||||
var/zone_selected = null
|
||||
|
||||
var/computer_id = null
|
||||
var/list/logging = list()
|
||||
|
||||
/// The machine the mob is interacting with (this is very bad old code btw)
|
||||
var/obj/machinery/machine = null
|
||||
|
||||
/// Tick time the mob can next move
|
||||
var/next_move = null
|
||||
|
||||
/**
|
||||
* Magic var that stops you moving and interacting with anything
|
||||
*
|
||||
* Set when you're being turned into something else and also used in a bunch of places
|
||||
* it probably shouldn't really be
|
||||
*/
|
||||
var/notransform = null //Carbon
|
||||
|
||||
/// Is the mob blind
|
||||
var/eye_blind = 0 //Carbon
|
||||
/// Does the mob have blurry sight
|
||||
var/eye_blurry = 0 //Carbon
|
||||
/// What is the mobs real name (name is overridden for disguises etc)
|
||||
var/real_name = null
|
||||
/// Is the mob pixel shifted
|
||||
var/is_shifted = FALSE
|
||||
/// can this mob move freely in space (should be a trait)
|
||||
var/spacewalk = FALSE
|
||||
|
||||
/**
|
||||
* back up of the real name during admin possession
|
||||
*
|
||||
* If an admin possesses an object it's real name is set to the admin name and this
|
||||
* stores whatever the real name was previously. When possession ends, the real name
|
||||
* is reset to this value
|
||||
*/
|
||||
var/name_archive //For admin things like possession
|
||||
|
||||
/// Default body temperature
|
||||
var/bodytemperature = BODYTEMP_NORMAL //310.15K / 98.6F
|
||||
/// Drowsyness level of the mob
|
||||
var/drowsyness = 0//Carbon
|
||||
/// Dizziness level of the mob
|
||||
var/dizziness = 0//Carbon
|
||||
/// Jitteryness level of the mob
|
||||
var/jitteriness = 0//Carbon
|
||||
/// Hunger level of the mob
|
||||
var/nutrition = NUTRITION_LEVEL_START_MIN // randomised in Initialize
|
||||
/// Satiation level of the mob
|
||||
var/satiety = 0//Carbon
|
||||
|
||||
/// How many ticks this mob has been over reating
|
||||
var/overeatduration = 0 // How long this guy is overeating //Carbon
|
||||
|
||||
/// The current intent of the mob
|
||||
var/a_intent = INTENT_HELP//Living
|
||||
/// List of possible intents a mob can have
|
||||
var/list/possible_a_intents = null//Living
|
||||
/// The movement intent of the mob (run/wal)
|
||||
var/m_intent = MOVE_INTENT_RUN//Living
|
||||
|
||||
/// The last known IP of the client who was in this mob
|
||||
var/lastKnownIP = null
|
||||
|
||||
/// movable atoms buckled to this mob
|
||||
var/atom/movable/buckled = null//Living
|
||||
/// movable atom we are buckled to
|
||||
var/atom/movable/buckling
|
||||
|
||||
//Hands
|
||||
///What hand is the active hand
|
||||
var/active_hand_index = 1
|
||||
var/list/held_items = list() //len = number of hands, eg: 2 nulls is 2 empty hands, 1 item and 1 null is 1 full hand and 1 empty hand.
|
||||
//held_items[active_hand_index] is the actively held item, but please use get_active_held_item() instead, because OOP
|
||||
/**
|
||||
* list of items held in hands
|
||||
*
|
||||
* len = number of hands, eg: 2 nulls is 2 empty hands, 1 item and 1 null is 1 full hand
|
||||
* and 1 empty hand.
|
||||
*
|
||||
* NB: contains nulls!
|
||||
*
|
||||
* held_items[active_hand_index] is the actively held item, but please use
|
||||
* get_active_held_item() instead, because OOP
|
||||
*/
|
||||
var/list/held_items = list()
|
||||
|
||||
//HUD things
|
||||
|
||||
/// Storage component (for mob inventory)
|
||||
var/datum/component/storage/active_storage
|
||||
/// Active hud
|
||||
var/datum/hud/hud_used = null
|
||||
/// I have no idea tbh
|
||||
var/research_scanner = FALSE
|
||||
|
||||
/// Is the mob throw intent on
|
||||
var/in_throw_mode = 0
|
||||
|
||||
/// What job does this mob have
|
||||
var/job = null//Living
|
||||
|
||||
var/list/faction = list("neutral") //A list of factions that this mob is currently in, for hostile mob targetting, amongst other things
|
||||
var/move_on_shuttle = 1 // Can move on the shuttle.
|
||||
/// A list of factions that this mob is currently in, for hostile mob targetting, amongst other things
|
||||
var/list/faction = list("neutral")
|
||||
|
||||
//The last mob/living/carbon to push/drag/grab this mob (mostly used by slimes friend recognition)
|
||||
/// Can this mob enter shuttles
|
||||
var/move_on_shuttle = 1
|
||||
|
||||
///The last mob/living/carbon to push/drag/grab this mob (exclusively used by slimes friend recognition)
|
||||
var/mob/living/carbon/LAssailant = null
|
||||
|
||||
var/list/mob_spell_list = list() //construct spells and mime spells. Spells that do not transfer from one mob to another and can not be lost in mindswap.
|
||||
/**
|
||||
* construct spells and mime spells.
|
||||
*
|
||||
* Spells that do not transfer from one mob to another and can not be lost in mindswap.
|
||||
* obviously do not live in the mind
|
||||
*/
|
||||
var/list/mob_spell_list = list()
|
||||
|
||||
var/status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH //bitflags defining which status effects can be inflicted (replaces canknockdown, canstun, etc)
|
||||
|
||||
/// bitflags defining which status effects can be inflicted (replaces canknockdown, canstun, etc)
|
||||
var/status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH
|
||||
|
||||
var/digitalcamo = 0 // Can they be tracked by the AI?
|
||||
var/digitalinvis = 0 //Are they ivisible to the AI?
|
||||
var/image/digitaldisguise = null //what does the AI see instead of them?
|
||||
/// Can they be tracked by the AI?
|
||||
var/digitalcamo = 0
|
||||
///Are they ivisible to the AI?
|
||||
var/digitalinvis = 0
|
||||
///what does the AI see instead of them?
|
||||
var/image/digitaldisguise = null
|
||||
|
||||
var/has_unlimited_silicon_privilege = 0 // Can they interact with station electronics
|
||||
/// Can they interact with station electronics
|
||||
var/has_unlimited_silicon_privilege = 0
|
||||
|
||||
var/obj/control_object //Used by admins to possess objects. All mobs should have this var
|
||||
var/atom/movable/remote_control //Calls relaymove() to whatever it is
|
||||
///Used by admins to possess objects. All mobs should have this var
|
||||
var/obj/control_object
|
||||
|
||||
var/deathsound //leave null for no sound. used for *deathgasp
|
||||
///Calls relay_move() to whatever this is set to when the mob tries to move
|
||||
var/atom/movable/remote_control
|
||||
|
||||
var/turf/listed_turf = null //the current turf being examined in the stat panel
|
||||
/**
|
||||
* The sound made on death
|
||||
*
|
||||
* leave null for no sound. used for *deathgasp
|
||||
*/
|
||||
var/deathsound
|
||||
|
||||
var/list/observers = null //The list of people observing this mob.
|
||||
///the current turf being examined in the stat panel
|
||||
var/turf/listed_turf = null
|
||||
|
||||
///The list of people observing this mob.
|
||||
var/list/observers = null
|
||||
|
||||
///List of progress bars this mob is currently seeing for actions
|
||||
var/list/progressbars = null //for stacking do_after bars
|
||||
|
||||
///List of datums that this has which make use of MouseMove()
|
||||
var/list/mousemove_intercept_objects
|
||||
|
||||
///Allows a datum to intercept all click calls this mob is the so
|
||||
var/datum/click_intercept
|
||||
|
||||
var/registered_z
|
||||
///THe z level this mob is currently registered in
|
||||
var/registered_z = null
|
||||
|
||||
///Size of the user's memory(IC notes)
|
||||
var/memory_amt = 0
|
||||
|
||||
var/list/emotes_used /// Used for tracking last uses of emotes for cooldown purposes
|
||||
/// Used for tracking last uses of emotes for cooldown purposes
|
||||
var/list/emotes_used
|
||||
|
||||
///Whether the mob is updating glide size when movespeed updates or not
|
||||
var/updating_glide_size = TRUE
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// see _DEFINES/is_helpers.dm for mob type checks
|
||||
|
||||
///Find the mob at the bottom of a buckle chain
|
||||
/mob/proc/lowest_buckled_mob()
|
||||
. = src
|
||||
if(buckled && ismob(buckled))
|
||||
var/mob/Buckled = buckled
|
||||
. = Buckled.lowest_buckled_mob()
|
||||
|
||||
///Convert a PRECISE ZONE into the BODY_ZONE
|
||||
/proc/check_zone(zone)
|
||||
if(!zone)
|
||||
return BODY_ZONE_CHEST
|
||||
@@ -26,7 +28,12 @@
|
||||
zone = BODY_ZONE_CHEST
|
||||
return zone
|
||||
|
||||
|
||||
/**
|
||||
* Return the zone or randomly, another valid zone
|
||||
*
|
||||
* probability controls the chance it chooses the passed in zone, or another random zone
|
||||
* defaults to 80
|
||||
*/
|
||||
/proc/ran_zone(zone, probability = 80)
|
||||
if(prob(probability))
|
||||
zone = check_zone(zone)
|
||||
@@ -34,29 +41,45 @@
|
||||
zone = pickweight(list(BODY_ZONE_HEAD = 1, BODY_ZONE_CHEST = 1, BODY_ZONE_L_ARM = 4, BODY_ZONE_R_ARM = 4, BODY_ZONE_L_LEG = 4, BODY_ZONE_R_LEG = 4))
|
||||
return zone
|
||||
|
||||
///Would this zone be above the neck
|
||||
/proc/above_neck(zone)
|
||||
var/list/zones = list(BODY_ZONE_HEAD, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_PRECISE_EYES)
|
||||
if(zones.Find(zone))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
/**
|
||||
* Convert random parts of a passed in message to stars
|
||||
*
|
||||
* * n - the string to convert
|
||||
* * pr - probability any character gets changed
|
||||
*
|
||||
* This proc is dangerously laggy, avoid it or die
|
||||
*/
|
||||
/proc/stars(n, pr)
|
||||
n = html_encode(n)
|
||||
if (pr == null)
|
||||
pr = 25
|
||||
if (pr <= 0)
|
||||
return null
|
||||
else
|
||||
if (pr >= 100)
|
||||
return n
|
||||
var/te = n
|
||||
var/t = ""
|
||||
n = length(n)
|
||||
|
||||
/proc/stars(phrase, probability = 25)
|
||||
if(probability <= 0)
|
||||
return phrase
|
||||
phrase = html_decode(phrase)
|
||||
var/leng = length(phrase)
|
||||
. = ""
|
||||
var/char = ""
|
||||
for(var/i = 1, i <= leng, i += length(char))
|
||||
char = phrase[i]
|
||||
if(char == " " || !prob(probability))
|
||||
. += char
|
||||
for(var/p = 1 to min(n,MAX_BROADCAST_LEN))
|
||||
if ((copytext(te, p, p + 1) == " " || prob(pr)))
|
||||
t = text("[][]", t, copytext(te, p, p + 1))
|
||||
else
|
||||
. += "*"
|
||||
return sanitize(.)
|
||||
|
||||
|
||||
t = text("[]*", t)
|
||||
if(n > MAX_BROADCAST_LEN)
|
||||
t += "..." //signals missing text
|
||||
return sanitize(t)
|
||||
/**
|
||||
* Makes you speak like you're drunk
|
||||
*/
|
||||
/proc/slur(phrase)
|
||||
phrase = html_decode(phrase)
|
||||
var/leng = length(phrase)
|
||||
@@ -92,7 +115,7 @@
|
||||
. += "[newletter]"
|
||||
return sanitize(.)
|
||||
|
||||
|
||||
/// Makes you talk like you got cult stunned, which is slurring but with some dark messages
|
||||
/proc/cultslur(phrase) // Inflicted on victims of a stun talisman
|
||||
phrase = html_decode(phrase)
|
||||
var/leng = length(phrase)
|
||||
@@ -135,7 +158,7 @@
|
||||
. += newletter
|
||||
return sanitize(.)
|
||||
|
||||
|
||||
///Adds stuttering to the message passed in
|
||||
/proc/stutter(phrase)
|
||||
phrase = html_decode(phrase)
|
||||
var/leng = length(phrase)
|
||||
@@ -156,6 +179,7 @@
|
||||
. += newletter
|
||||
return sanitize(.)
|
||||
|
||||
///Convert a message to derpy speak
|
||||
/proc/derpspeech(message, stuttering)
|
||||
message = replacetext(message, " am ", " ")
|
||||
message = replacetext(message, " is ", " ")
|
||||
@@ -176,7 +200,7 @@
|
||||
/**
|
||||
* Turn text into complete gibberish!
|
||||
*
|
||||
* text is the inputted message, replace_characters will cause original letters to be replaced and chance are the odds that a character gets modified.
|
||||
* text is the inputted message, and any value higher than 70 for chance will cause letters to be replaced instead of added
|
||||
*/
|
||||
/proc/Gibberish(text, replace_characters = FALSE, chance = 50)
|
||||
text = html_decode(text)
|
||||
@@ -195,6 +219,9 @@
|
||||
return sanitize(.)
|
||||
|
||||
|
||||
|
||||
|
||||
///Shake the camera of the person viewing the mob SO REAL!
|
||||
/proc/shake_camera(mob/M, duration, strength=1)
|
||||
if(!M || !M.client || duration < 1)
|
||||
return
|
||||
@@ -212,7 +239,7 @@
|
||||
animate(pixel_x=oldx, pixel_y=oldy, time=1)
|
||||
|
||||
|
||||
|
||||
///Find if the message has the real name of any user mob in the mob_list
|
||||
/proc/findname(msg)
|
||||
if(!istext(msg))
|
||||
msg = "[msg]"
|
||||
@@ -222,13 +249,18 @@
|
||||
return M
|
||||
return 0
|
||||
|
||||
///Find the first name of a mob from the real name with regex
|
||||
/mob/proc/first_name()
|
||||
var/static/regex/firstname = new("^\[^\\s-\]+") //First word before whitespace or "-"
|
||||
firstname.Find(real_name)
|
||||
return firstname.match
|
||||
|
||||
|
||||
//change a mob's act-intent. Input the intent as a string such as "help" or use "right"/"left
|
||||
/**
|
||||
* change a mob's act-intent.
|
||||
*
|
||||
* Input the intent as a string such as "help" or use "right"/"left
|
||||
*/
|
||||
/mob/verb/a_intent_change(input as text)
|
||||
set name = "a-intent"
|
||||
set hidden = 1
|
||||
@@ -261,7 +293,7 @@
|
||||
if(hud_used && hud_used.action_intent)
|
||||
hud_used.action_intent.icon_state = "[a_intent]"
|
||||
|
||||
|
||||
///Checks if passed through item is blind
|
||||
/proc/is_blind(A)
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
if(ismob(A))
|
||||
@@ -269,10 +301,19 @@
|
||||
return B.eye_blind
|
||||
return FALSE
|
||||
|
||||
///Is the mob hallucinating?
|
||||
/mob/proc/hallucinating()
|
||||
return FALSE
|
||||
|
||||
/proc/is_special_character(mob/M) // returns 1 for special characters and 2 for heroes of gamemode //moved out of admins.dm because things other than admin procs were calling this.
|
||||
|
||||
// moved out of admins.dm because things other than admin procs were calling this.
|
||||
/**
|
||||
* Is this mob special to the gamemode?
|
||||
*
|
||||
* returns 1 for special characters and 2 for heroes of gamemode
|
||||
*
|
||||
*/
|
||||
/proc/is_special_character(mob/M)
|
||||
if(!SSticker.HasRoundStarted())
|
||||
return FALSE
|
||||
if(!istype(M))
|
||||
@@ -315,9 +356,29 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/proc/reagent_check(datum/reagent/R) // utilized in the species code
|
||||
return 1
|
||||
|
||||
|
||||
/**
|
||||
* Fancy notifications for ghosts
|
||||
*
|
||||
* The kitchen sink of notification procs
|
||||
*
|
||||
* Arguments:
|
||||
* * message
|
||||
* * ghost_sound sound to play
|
||||
* * enter_link Href link to enter the ghost role being notified for
|
||||
* * source The source of the notification
|
||||
* * alert_overlay The alert overlay to show in the alert message
|
||||
* * action What action to take upon the ghost interacting with the notification, defaults to NOTIFY_JUMP
|
||||
* * flashwindow Flash the byond client window
|
||||
* * ignore_key Ignore keys if they're in the GLOB.poll_ignore list
|
||||
* * header The header of the notifiaction
|
||||
* * notify_suiciders If it should notify suiciders (who do not qualify for many ghost roles)
|
||||
* * notify_volume How loud the sound should be to spook the user
|
||||
*/
|
||||
/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/mutable_appearance/alert_overlay = null, var/action = NOTIFY_JUMP, flashwindow = TRUE, ignore_mapload = TRUE, ignore_key, header = null, notify_suiciders = TRUE, var/notify_volume = 100) //Easy notification of ghosts.
|
||||
if(ignore_mapload && SSatoms.initialized != INITIALIZATION_INNEW_REGULAR) //don't notify for objects created during a map load
|
||||
return
|
||||
@@ -351,6 +412,9 @@
|
||||
alert_overlay.plane = FLOAT_PLANE
|
||||
A.add_overlay(alert_overlay)
|
||||
|
||||
/**
|
||||
* Heal a robotic body part on a mob
|
||||
*/
|
||||
/proc/item_heal_robotic(mob/living/carbon/human/H, mob/user, brute_heal, burn_heal)
|
||||
var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected))
|
||||
if(affecting && affecting.status == BODYPART_ROBOTIC)
|
||||
@@ -368,7 +432,7 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[affecting] is already in good condition!</span>")
|
||||
|
||||
|
||||
///Is the passed in mob an admin ghost
|
||||
/proc/IsAdminGhost(var/mob/user)
|
||||
if(!user) //Are they a mob? Auto interface updates call this with a null src
|
||||
return
|
||||
@@ -382,6 +446,11 @@
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Offer control of the passed in mob to dead player
|
||||
*
|
||||
* Automatic logging and uses pollCandidatesForMob, how convenient
|
||||
*/
|
||||
/proc/offer_control(mob/M)
|
||||
to_chat(M, "Control of your mob has been offered to dead players.")
|
||||
if(usr)
|
||||
@@ -410,12 +479,14 @@
|
||||
message_admins("No ghosts were willing to take control of [ADMIN_LOOKUPFLW(M)])")
|
||||
return FALSE
|
||||
|
||||
///Is the mob a flying mob
|
||||
/mob/proc/is_flying(mob/M = src)
|
||||
if(M.movement_type & FLYING)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
///Clicks a random nearby mob with the source from this mob
|
||||
/mob/proc/click_random_mob()
|
||||
var/list/nearby_mobs = list()
|
||||
for(var/mob/living/L in range(1, src))
|
||||
@@ -425,7 +496,7 @@
|
||||
var/mob/living/T = pick(nearby_mobs)
|
||||
ClickOn(T)
|
||||
|
||||
// Logs a message in a mob's individual log, and in the global logs as well if log_globally is true
|
||||
/// Logs a message in a mob's individual log, and in the global logs as well if log_globally is true
|
||||
/mob/log_message(message, message_type, color=null, log_globally = TRUE)
|
||||
if(!LAZYLEN(message))
|
||||
stack_trace("Empty message")
|
||||
@@ -457,14 +528,25 @@
|
||||
|
||||
..()
|
||||
|
||||
///Can the mob hear
|
||||
/mob/proc/can_hear()
|
||||
. = TRUE
|
||||
|
||||
//Examine text for traits shared by multiple types. I wish examine was less copypasted.
|
||||
/**
|
||||
* Examine text for traits shared by multiple types.
|
||||
*
|
||||
* I wish examine was less copypasted. (oranges say, be the change you want to see buddy)
|
||||
*/
|
||||
/mob/proc/common_trait_examine()
|
||||
if(HAS_TRAIT(src, TRAIT_DISSECTED))
|
||||
. += "<span class='notice'>This body has been dissected and analyzed. It is no longer worth experimenting on.</span><br>"
|
||||
|
||||
/**
|
||||
* Get the list of keywords for policy config
|
||||
*
|
||||
* This gets the type, mind assigned roles and antag datums as a list, these are later used
|
||||
* to send the user relevant headadmin policy config
|
||||
*/
|
||||
/mob/proc/get_policy_keywords()
|
||||
. = list()
|
||||
. += "[type]"
|
||||
@@ -474,6 +556,6 @@
|
||||
for(var/datum/antagonist/A in mind.antag_datums)
|
||||
. += "[A.type]"
|
||||
|
||||
//Can the mob see reagents inside of containers?
|
||||
///Can the mob see reagents inside of containers?
|
||||
/mob/proc/can_see_reagents()
|
||||
return stat == DEAD || has_unlimited_silicon_privilege //Dead guys and silicons can always see reagents
|
||||
|
||||
@@ -1,14 +1,33 @@
|
||||
//DO NOT USE THIS UNLESS YOU ABSOLUTELY HAVE TO. THIS IS BEING PHASED OUT FOR THE MOVESPEED MODIFICATION SYSTEM.
|
||||
//See mob_movespeed.dm
|
||||
///Can the atom pass this mob (always true for /mob)
|
||||
/**
|
||||
* Get the current movespeed delay of the mob
|
||||
*
|
||||
* DO NOT OVERRIDE THIS UNLESS YOU ABSOLUTELY HAVE TO.
|
||||
* THIS IS BEING PHASED OUT FOR THE MOVESPEED MODIFICATION SYSTEM.
|
||||
* See mob_movespeed.dm
|
||||
*/
|
||||
/mob/proc/movement_delay() //update /living/movement_delay() if you change this
|
||||
return cached_multiplicative_slowdown
|
||||
|
||||
/**
|
||||
* If your mob is concious, drop the item in the active hand
|
||||
*
|
||||
* This is a hidden verb, likely for binding with winset for hotkeys
|
||||
*/
|
||||
/client/verb/drop_item()
|
||||
set hidden = 1
|
||||
if(!iscyborg(mob) && mob.stat == CONSCIOUS)
|
||||
mob.dropItemToGround(mob.get_active_held_item())
|
||||
return
|
||||
|
||||
/**
|
||||
* force move the control_object of your client mob
|
||||
*
|
||||
* Used in admin possession and called from the client Move proc
|
||||
* ensures the possessed object moves and not the admin mob
|
||||
*
|
||||
* Has no sanity other than checking density
|
||||
*/
|
||||
/client/proc/Move_object(direct)
|
||||
if(mob && mob.control_object)
|
||||
if(mob.control_object.density)
|
||||
@@ -26,17 +45,17 @@
|
||||
* Move a client in a direction
|
||||
*
|
||||
* Huge proc, has a lot of functionality
|
||||
*
|
||||
*
|
||||
* Mostly it will despatch to the mob that you are the owner of to actually move
|
||||
* in the physical realm
|
||||
*
|
||||
*
|
||||
* Things that stop you moving as a mob:
|
||||
* * world time being less than your next move_delay
|
||||
* * not being in a mob, or that mob not having a loc
|
||||
* * missing the n and direction parameters
|
||||
* * being in remote control of an object (calls Moveobject instead)
|
||||
* * being dead (it ghosts you instead)
|
||||
*
|
||||
*
|
||||
* Things that stop you moving as a mob living (why even have OO if you're just shoving it all
|
||||
* in the parent proc with istype checks right?):
|
||||
* * having incorporeal_move set (calls Process_Incorpmove() instead)
|
||||
@@ -56,7 +75,7 @@
|
||||
*
|
||||
* Finally if you're pulling an object and it's dense, you are turned 180 after the move
|
||||
* (if you ask me, this should be at the top of the move so you don't dance around)
|
||||
*
|
||||
*
|
||||
*/
|
||||
/client/Move(n, direct)
|
||||
if(world.time < move_delay) //do not move anything ahead of this check please
|
||||
@@ -147,9 +166,11 @@
|
||||
if(P && !ismob(P) && P.density)
|
||||
mob.setDir(turn(mob.dir, 180))
|
||||
|
||||
///Process_Grab()
|
||||
///Called by client/Move()
|
||||
///Checks to see if you are being grabbed and if so attemps to break it
|
||||
/**
|
||||
* Checks to see if you're being grabbed and if so attempts to break it
|
||||
*
|
||||
* Called by client/Move()
|
||||
*/
|
||||
/client/proc/Process_Grab()
|
||||
if(mob.pulledby)
|
||||
if((mob.pulledby == mob.pulling) && (mob.pulledby.grab_state == GRAB_PASSIVE)) //Don't autoresist passive grabs if we're grabbing them too.
|
||||
@@ -168,7 +189,7 @@
|
||||
* Allows mobs to ignore density and phase through objects
|
||||
*
|
||||
* Called by client/Move()
|
||||
*
|
||||
*
|
||||
* The behaviour depends on the incorporeal_move value of the mob
|
||||
*
|
||||
* * INCORPOREAL_MOVE_BASIC - forceMoved to the next tile with no stop
|
||||
@@ -256,9 +277,9 @@
|
||||
* Handles mob/living movement in space (or no gravity)
|
||||
*
|
||||
* Called by /client/Move()
|
||||
*
|
||||
*
|
||||
* return TRUE for movement or FALSE for none
|
||||
*
|
||||
*
|
||||
* You can move in space if you have a spacewalk ability
|
||||
*/
|
||||
/mob/Process_Spacemove(movement_dir = 0)
|
||||
@@ -272,6 +293,9 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Find movable atoms? near a mob that are viable for pushing off when moving
|
||||
*/
|
||||
/mob/get_spacemove_backup()
|
||||
for(var/A in orange(1, get_turf(src)))
|
||||
if(isarea(A))
|
||||
@@ -298,27 +322,42 @@
|
||||
continue
|
||||
. = AM
|
||||
|
||||
/**
|
||||
* Returns true if a mob has gravity
|
||||
*
|
||||
* I hate that this exists
|
||||
*/
|
||||
/mob/proc/mob_has_gravity()
|
||||
return has_gravity()
|
||||
|
||||
/**
|
||||
* Does this mob ignore gravity
|
||||
*/
|
||||
/mob/proc/mob_negates_gravity()
|
||||
return FALSE
|
||||
|
||||
|
||||
/// Called when this mob slips over, override as needed
|
||||
/mob/proc/slip(knockdown_amount, obj/O, lube, paralyze, force_drop)
|
||||
return
|
||||
|
||||
/// Update the gravity status of this mob
|
||||
/mob/proc/update_gravity()
|
||||
return
|
||||
|
||||
//bodypart selection - Cyberboss
|
||||
//8 toggles through head - eyes - mouth
|
||||
//bodypart selection verbs - Cyberboss
|
||||
//8:repeated presses toggles through head - eyes - mouth
|
||||
//4: r-arm 5: chest 6: l-arm
|
||||
//1: r-leg 2: groin 3: l-leg
|
||||
|
||||
///Validate the client's mob has a valid zone selected
|
||||
/client/proc/check_has_body_select()
|
||||
return mob && mob.hud_used && mob.hud_used.zone_select && istype(mob.hud_used.zone_select, /obj/screen/zone_sel)
|
||||
|
||||
/**
|
||||
* Hidden verb to set the target zone of a mob to the head
|
||||
*
|
||||
* (bound to 8) - repeated presses toggles through head - eyes - mouth
|
||||
*/
|
||||
/client/verb/body_toggle_head()
|
||||
set name = "body-toggle-head"
|
||||
set hidden = 1
|
||||
@@ -338,6 +377,7 @@
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(next_in_line, mob)
|
||||
|
||||
///Hidden verb to target the right arm, bound to 4
|
||||
/client/verb/body_r_arm()
|
||||
set name = "body-r-arm"
|
||||
set hidden = 1
|
||||
@@ -348,6 +388,7 @@
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_R_ARM, mob)
|
||||
|
||||
///Hidden verb to target the chest, bound to 5
|
||||
/client/verb/body_chest()
|
||||
set name = "body-chest"
|
||||
set hidden = 1
|
||||
@@ -358,6 +399,7 @@
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_CHEST, mob)
|
||||
|
||||
///Hidden verb to target the left arm, bound to 6
|
||||
/client/verb/body_l_arm()
|
||||
set name = "body-l-arm"
|
||||
set hidden = 1
|
||||
@@ -368,6 +410,7 @@
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_L_ARM, mob)
|
||||
|
||||
///Hidden verb to target the right leg, bound to 1
|
||||
/client/verb/body_r_leg()
|
||||
set name = "body-r-leg"
|
||||
set hidden = 1
|
||||
@@ -378,6 +421,7 @@
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_R_LEG, mob)
|
||||
|
||||
///Hidden verb to target the groin, bound to 2
|
||||
/client/verb/body_groin()
|
||||
set name = "body-groin"
|
||||
set hidden = 1
|
||||
@@ -388,6 +432,7 @@
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_PRECISE_GROIN, mob)
|
||||
|
||||
///Hidden verb to target the left leg, bound to 3
|
||||
/client/verb/body_l_leg()
|
||||
set name = "body-l-leg"
|
||||
set hidden = 1
|
||||
@@ -398,6 +443,7 @@
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_L_LEG, mob)
|
||||
|
||||
///Verb to toggle the walk or run status
|
||||
/client/verb/toggle_walk_run()
|
||||
set name = "toggle-walk-run"
|
||||
set hidden = TRUE
|
||||
@@ -407,7 +453,7 @@
|
||||
|
||||
/**
|
||||
* Toggle the move intent of the mob
|
||||
*
|
||||
*
|
||||
* triggers an update the move intent hud as well
|
||||
*/
|
||||
/mob/proc/toggle_move_intent(mob/user)
|
||||
@@ -419,6 +465,7 @@
|
||||
for(var/obj/screen/mov_intent/selector in hud_used.static_inventory)
|
||||
selector.update_icon(src)
|
||||
|
||||
///Moves a mob upwards in z level
|
||||
/mob/verb/up()
|
||||
set name = "Move Upwards"
|
||||
set category = "IC"
|
||||
@@ -426,6 +473,7 @@
|
||||
if(zMove(UP, TRUE))
|
||||
to_chat(src, "<span class='notice'>You move upwards.</span>")
|
||||
|
||||
///Moves a mob down a z level
|
||||
/mob/verb/down()
|
||||
set name = "Move Down"
|
||||
set category = "IC"
|
||||
@@ -433,6 +481,7 @@
|
||||
if(zMove(DOWN, TRUE))
|
||||
to_chat(src, "<span class='notice'>You move down.</span>")
|
||||
|
||||
///Move a mob between z levels, if it's valid to move z's on this turf
|
||||
/mob/proc/zMove(dir, feedback = FALSE)
|
||||
if(dir != UP && dir != DOWN)
|
||||
return FALSE
|
||||
@@ -448,5 +497,6 @@
|
||||
forceMove(target)
|
||||
return TRUE
|
||||
|
||||
/// Can this mob move between z levels
|
||||
/mob/proc/canZMove(direction, turf/target)
|
||||
return FALSE
|
||||
|
||||
@@ -1,13 +1,40 @@
|
||||
/*! How move speed for mobs works
|
||||
|
||||
/*Current movespeed modification list format: list(id = list(
|
||||
priority,
|
||||
flags,
|
||||
legacy slowdown/speedup amount,
|
||||
movetype_flags
|
||||
))
|
||||
Move speed is now calculated by using a list of movespeed modifiers, which is a list itself (to avoid datum overhead)
|
||||
|
||||
This gives us the ability to have multiple sources of movespeed, reliabily keep them applied and remove them when they should be
|
||||
|
||||
THey can have unique sources and a bunch of extra fancy flags that control behaviour
|
||||
|
||||
Previously trying to update move speed was a shot in the dark that usually meant mobs got stuck going faster or slower
|
||||
|
||||
This list takes the following format
|
||||
|
||||
```Current movespeed modification list format:
|
||||
list(
|
||||
id = list(
|
||||
priority,
|
||||
flags,
|
||||
legacy slowdown/speedup amount,
|
||||
movetype_flags
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
WHen update movespeed is called, the list of items is iterated, according to flags priority and a bunch of conditions
|
||||
this spits out a final calculated value which is used as a modifer to last_move + modifier for calculating when a mob
|
||||
can next move
|
||||
|
||||
Key procs
|
||||
* [add_movespeed_modifier](mob.html#proc/add_movespeed_modifier)
|
||||
* [remove_movespeed_modifier](mob.html#proc/remove_movespeed_modifier)
|
||||
* [has_movespeed_modifier](mob.html#proc/has_movespeed_modifier)
|
||||
* [update_movespeed](mob.html#proc/update_movespeed)
|
||||
*/
|
||||
|
||||
//ANY ADD/REMOVE DONE IN UPDATE_MOVESPEED MUST HAVE THE UPDATE ARGUMENT SET AS FALSE!
|
||||
|
||||
///Add a move speed modifier to a mob
|
||||
/mob/proc/add_movespeed_modifier(id, update=TRUE, priority=0, flags=NONE, override=FALSE, multiplicative_slowdown=0, movetypes=ALL, blacklisted_movetypes=NONE, conflict=FALSE)
|
||||
var/list/temp = list(priority, flags, multiplicative_slowdown, movetypes, blacklisted_movetypes, conflict) //build the modification list
|
||||
var/resort = TRUE
|
||||
@@ -24,6 +51,7 @@
|
||||
update_movespeed(resort)
|
||||
return TRUE
|
||||
|
||||
///Remove a move speed modifier from a mob
|
||||
/mob/proc/remove_movespeed_modifier(id, update = TRUE)
|
||||
if(!LAZYACCESS(movespeed_modification, id))
|
||||
return FALSE
|
||||
@@ -33,6 +61,7 @@
|
||||
update_movespeed(FALSE)
|
||||
return TRUE
|
||||
|
||||
///Handles the special case of editing the movement var
|
||||
/mob/vv_edit_var(var_name, var_value)
|
||||
var/slowdown_edit = (var_name == NAMEOF(src, cached_multiplicative_slowdown))
|
||||
var/diff
|
||||
@@ -43,18 +72,22 @@
|
||||
if(. && slowdown_edit && isnum(diff))
|
||||
add_movespeed_modifier(MOVESPEED_ID_ADMIN_VAREDIT, TRUE, 100, override = TRUE, multiplicative_slowdown = diff)
|
||||
|
||||
///Is there a movespeed modifier for this mob
|
||||
/mob/proc/has_movespeed_modifier(id)
|
||||
return LAZYACCESS(movespeed_modification, id)
|
||||
|
||||
///Set or update the global movespeed config on a mob
|
||||
/mob/proc/update_config_movespeed()
|
||||
add_movespeed_modifier(MOVESPEED_ID_CONFIG_SPEEDMOD, FALSE, 100, override = TRUE, multiplicative_slowdown = get_config_multiplicative_speed())
|
||||
|
||||
///Get the global config movespeed of a mob by type
|
||||
/mob/proc/get_config_multiplicative_speed()
|
||||
if(!islist(GLOB.mob_config_movespeed_type_lookup) || !GLOB.mob_config_movespeed_type_lookup[type])
|
||||
return 0
|
||||
else
|
||||
return GLOB.mob_config_movespeed_type_lookup[type]
|
||||
|
||||
///Go through the list of movespeed modifiers and calculate a final movespeed
|
||||
/mob/proc/update_movespeed(resort = TRUE)
|
||||
if(resort)
|
||||
sort_movespeed_modlist()
|
||||
@@ -78,9 +111,11 @@
|
||||
. += amt
|
||||
cached_multiplicative_slowdown = .
|
||||
|
||||
///Get the move speed modifiers list of the mob
|
||||
/mob/proc/get_movespeed_modifiers()
|
||||
return movespeed_modification
|
||||
|
||||
///Check if a movespeed modifier is identical to another
|
||||
/mob/proc/movespeed_modifier_identical_check(list/mod1, list/mod2)
|
||||
if(!islist(mod1) || !islist(mod2) || mod1.len < MOVESPEED_DATA_INDEX_MAX || mod2.len < MOVESPEED_DATA_INDEX_MAX)
|
||||
return FALSE
|
||||
@@ -89,18 +124,25 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
///Calculate the total slowdown of all movespeed modifiers
|
||||
/mob/proc/total_multiplicative_slowdown()
|
||||
. = 0
|
||||
for(var/id in get_movespeed_modifiers())
|
||||
var/list/data = movespeed_modification[id]
|
||||
. += data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN]
|
||||
|
||||
///Checks if a move speed modifier is valid and not missing any data
|
||||
/proc/movespeed_data_null_check(list/data) //Determines if a data list is not meaningful and should be discarded.
|
||||
. = TRUE
|
||||
if(data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN])
|
||||
. = FALSE
|
||||
|
||||
/mob/proc/sort_movespeed_modlist() //Verifies it too. Sorts highest priority (first applied) to lowest priority (last applied)
|
||||
/**
|
||||
* Sort the list of move speed modifiers
|
||||
*
|
||||
* Verifies it too. Sorts highest priority (first applied) to lowest priority (last applied)
|
||||
*/
|
||||
/mob/proc/sort_movespeed_modlist()
|
||||
if(!movespeed_modification)
|
||||
return
|
||||
var/list/assembled = list()
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//Speech verbs.
|
||||
|
||||
///Say verb
|
||||
/mob/verb/say_verb(message as text)
|
||||
set name = "Say"
|
||||
set category = "IC"
|
||||
@@ -18,7 +20,7 @@
|
||||
if(message)
|
||||
say(message)
|
||||
|
||||
|
||||
///Whisper verb
|
||||
/mob/verb/whisper_verb(message as text)
|
||||
set name = "Whisper"
|
||||
set category = "IC"
|
||||
@@ -36,9 +38,11 @@
|
||||
return
|
||||
whisper(message)
|
||||
|
||||
///whisper a message
|
||||
/mob/proc/whisper(message, datum/language/language=null)
|
||||
say(message, language) //only living mobs actually whisper, everything else just talks
|
||||
|
||||
///The me emote verb
|
||||
/mob/verb/me_verb(message as text)
|
||||
set name = "Me"
|
||||
set category = "IC"
|
||||
@@ -51,6 +55,7 @@
|
||||
|
||||
usr.emote("me",1,message,TRUE)
|
||||
|
||||
///Speak as a dead person (ghost etc)
|
||||
/mob/proc/say_dead(var/message)
|
||||
var/name = real_name
|
||||
var/alt_name = ""
|
||||
@@ -99,17 +104,28 @@
|
||||
log_talk(message, LOG_SAY, tag="DEAD")
|
||||
deadchat_broadcast(rendered, source, follow_target = src, speaker_key = key)
|
||||
|
||||
///Check if this message is an emote
|
||||
/mob/proc/check_emote(message, forced)
|
||||
if(message[1] == "*")
|
||||
emote(copytext(message, length(message[1]) + 1), intentional = !forced)
|
||||
return TRUE
|
||||
|
||||
///Check if the mob has a hivemind channel
|
||||
/mob/proc/hivecheck()
|
||||
return 0
|
||||
|
||||
///Check if the mob has a ling hivemind
|
||||
/mob/proc/lingcheck()
|
||||
return LINGHIVE_NONE
|
||||
|
||||
/**
|
||||
* Get the mode of a message
|
||||
*
|
||||
* Result can be
|
||||
* * MODE_WHISPER (Quiet speech)
|
||||
* * MODE_HEADSET (Common radio channel)
|
||||
* * A department radio (lots of values here)
|
||||
*/
|
||||
/mob/proc/get_message_mode(message)
|
||||
var/key = message[1]
|
||||
if(key == "#")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*=============================================================
|
||||
======================MIAUW'S SAY REWRITE======================
|
||||
===============================================================
|
||||
# Say code basics
|
||||
|
||||
This document is a little dated but I believe it's accurate mostly (oranges 2019)
|
||||
# MIAUW'S SAY REWRITE
|
||||
|
||||
This is a basic explanation of how say() works. Read this if you don't understand something.
|
||||
|
||||
@@ -14,8 +15,9 @@ If you came here to see how to use saycode, all you will ever really need to cal
|
||||
To have things react when other things speak around them, add the HEAR_1 flag to their flags variable and
|
||||
override their Hear() proc.
|
||||
|
||||
=======================PROCS & VARIABLES=======================
|
||||
Here follows a list of say()-related procs and variables.
|
||||
# PROCS & VARIABLES
|
||||
Here follows a list of say()-related procs and variables.
|
||||
```
|
||||
global procs
|
||||
get_radio_span(freq)
|
||||
Returns the span class associated with that frequency.
|
||||
@@ -76,7 +78,8 @@ global procs
|
||||
Passes message_mode to say_quote.
|
||||
|
||||
say_quote(input, spans, message_mode)
|
||||
Adds a verb and quotes to a message. Also attaches span classes to a message. Verbs are determined by verb_say/verb_ask/verb_yell variables. Called on the speaker.
|
||||
Adds a verb and quotes to a message. Also attaches span classes to a message.
|
||||
Verbs are determined by verb_say/verb_ask/verb_yell variables. Called on the speaker.
|
||||
|
||||
/mob
|
||||
say_dead(message)
|
||||
@@ -145,8 +148,8 @@ global procs
|
||||
|
||||
Return 0 if no radio was spoken into.
|
||||
IMPORTANT: remember to call ..() and check for ..()'s return value properly!
|
||||
|
||||
============================RADIOS=============================
|
||||
```
|
||||
# RADIOS
|
||||
|
||||
I did not want to interfere with radios too much, but I sort of had to.
|
||||
For future generations, here is how radio code works:
|
||||
@@ -162,9 +165,10 @@ This is an associative list, and the numbers as strings are the keys. The values
|
||||
To add a radio, simply use add_radio(radio, frequency). To remove a radio, use remove_radio(radio, frequency).
|
||||
To remove a radio from ALL frequencies, use remove_radio_all(radio).
|
||||
|
||||
VIRTUAL SPEAKERS:
|
||||
## VIRTUAL SPEAKERS:
|
||||
Virtual speakers are simply atom/movables with a few extra variables.
|
||||
If radio_freq is not null, the code will rely on the fact that the speaker is virtual. This means that several procs will return something:
|
||||
```
|
||||
(all of these procs are defined at the atom/movable level and return "" at that level.)
|
||||
GetJob()
|
||||
Returns the job string variable of the virtual speaker.
|
||||
@@ -174,7 +178,7 @@ If radio_freq is not null, the code will rely on the fact that the speaker is vi
|
||||
Returns the source of the virtual speaker.
|
||||
GetRadio()
|
||||
Returns the radio that was spoken through by the source. Needed for AI tracking.
|
||||
|
||||
```
|
||||
This is fairly hacky, but it means that I can advoid using istypes. It's mainly relevant for AI tracking and AI job display.
|
||||
|
||||
That's all, folks!*/
|
||||
That's all, folks!
|
||||
@@ -5,21 +5,23 @@
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////// JITTERINESS ////////////////////////////////////
|
||||
|
||||
///Set the jitter of a mob
|
||||
/mob/proc/Jitter(amount)
|
||||
jitteriness = max(jitteriness,amount,0)
|
||||
|
||||
/////////////////////////////////// DIZZINESS ////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Set the dizzyness of a mob to a passed in amount
|
||||
*
|
||||
* Except if dizziness is already higher in which case it does nothing
|
||||
*/
|
||||
/mob/proc/Dizzy(amount)
|
||||
dizziness = max(dizziness,amount,0)
|
||||
|
||||
///FOrce set the dizzyness of a mob
|
||||
/mob/proc/set_dizziness(amount)
|
||||
dizziness = max(amount, 0)
|
||||
|
||||
/////////////////////////////////// EYE_BLIND ////////////////////////////////////
|
||||
|
||||
///Blind a mobs eyes by amount
|
||||
/mob/proc/blind_eyes(amount)
|
||||
if(amount>0)
|
||||
var/old_eye_blind = eye_blind
|
||||
@@ -29,6 +31,11 @@
|
||||
throw_alert("blind", /obj/screen/alert/blind)
|
||||
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
|
||||
|
||||
/**
|
||||
* Adjust a mobs blindness by an amount
|
||||
*
|
||||
* Will apply the blind alerts if needed
|
||||
*/
|
||||
/mob/proc/adjust_blindness(amount)
|
||||
if(amount>0)
|
||||
var/old_eye_blind = eye_blind
|
||||
@@ -49,7 +56,9 @@
|
||||
if(!eye_blind)
|
||||
clear_alert("blind")
|
||||
clear_fullscreen("blind")
|
||||
|
||||
/**
|
||||
* Force set the blindness of a mob to some level
|
||||
*/
|
||||
/mob/proc/set_blindness(amount)
|
||||
if(amount>0)
|
||||
var/old_eye_blind = eye_blind
|
||||
@@ -71,21 +80,27 @@
|
||||
clear_alert("blind")
|
||||
clear_fullscreen("blind")
|
||||
|
||||
/////////////////////////////////// EYE_BLURRY ////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Make the mobs vision blurry
|
||||
*/
|
||||
/mob/proc/blur_eyes(amount)
|
||||
if(amount>0)
|
||||
eye_blurry = max(amount, eye_blurry)
|
||||
update_eye_blur()
|
||||
|
||||
/**
|
||||
* Adjust the current blurriness of the mobs vision by amount
|
||||
*/
|
||||
/mob/proc/adjust_blurriness(amount)
|
||||
eye_blurry = max(eye_blurry+amount, 0)
|
||||
update_eye_blur()
|
||||
|
||||
///Set the mobs blurriness of vision to an amount
|
||||
/mob/proc/set_blurriness(amount)
|
||||
eye_blurry = max(amount, 0)
|
||||
update_eye_blur()
|
||||
|
||||
///Apply the blurry overlays to a mobs clients screen
|
||||
/mob/proc/update_eye_blur()
|
||||
if(!client)
|
||||
return
|
||||
@@ -94,24 +109,23 @@
|
||||
GW.backdrop(src)
|
||||
OT.backdrop(src)
|
||||
|
||||
/////////////////////////////////// DRUGGY ////////////////////////////////////
|
||||
|
||||
///Adjust the drugginess of a mob
|
||||
/mob/proc/adjust_drugginess(amount)
|
||||
return
|
||||
|
||||
///Set the drugginess of a mob
|
||||
/mob/proc/set_drugginess(amount)
|
||||
return
|
||||
|
||||
/////////////////////////////////// GROSSED OUT ////////////////////////////////////
|
||||
|
||||
///Adjust the disgust level of a mob
|
||||
/mob/proc/adjust_disgust(amount)
|
||||
return
|
||||
|
||||
///Set the disgust level of a mob
|
||||
/mob/proc/set_disgust(amount)
|
||||
return
|
||||
|
||||
/////////////////////////////////// TEMPERATURE ////////////////////////////////////
|
||||
|
||||
///Adjust the body temperature of a mob, with min/max settings
|
||||
/mob/proc/adjust_bodytemperature(amount,min_temp=0,max_temp=INFINITY)
|
||||
if(bodytemperature >= min_temp && bodytemperature <= max_temp)
|
||||
bodytemperature = clamp(bodytemperature + amount,min_temp,max_temp)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Modular computer programs
|
||||
|
||||
How module computer programs work
|
||||
|
||||
Ok. so a quick rundown on how to make a program. This is kind of a shitty documentation, but oh well I was asked to.
|
||||
|
||||
## Base setup
|
||||
|
||||
@@ -13,15 +13,24 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
///list containing the actual ammo within the magazine
|
||||
var/list/stored_ammo = list()
|
||||
///type that the magazine will be searching for, rejects if not a subtype of
|
||||
var/ammo_type = /obj/item/ammo_casing
|
||||
///maximum amount of ammo in the magazine
|
||||
var/max_ammo = 7
|
||||
var/multiple_sprites = 0
|
||||
///Controls how sprites are updated for the ammo box; see defines in combat.dm: AMMO_BOX_ONE_SPRITE; AMMO_BOX_PER_BULLET; AMMO_BOX_FULL_EMPTY
|
||||
var/multiple_sprites = AMMO_BOX_ONE_SPRITE
|
||||
///String, used for checking if ammo of different types but still fits can fit inside it; generally used for magazines
|
||||
var/caliber
|
||||
///Allows multiple bullets to be loaded in from one click of another box/magazine
|
||||
var/multiload = TRUE
|
||||
///Whether the magazine should start with nothing in it
|
||||
var/start_empty = FALSE
|
||||
///cost of all the bullets in the magazine/box
|
||||
var/list/bullet_cost
|
||||
var/list/base_cost// override this one as well if you override bullet_cost
|
||||
///cost of the materials in the magazine/box itself
|
||||
var/list/base_cost
|
||||
|
||||
/obj/item/ammo_box/Initialize()
|
||||
. = ..()
|
||||
@@ -44,6 +53,7 @@
|
||||
/obj/item/ammo_box/autolathe_crafted()
|
||||
calc_mats(force = TRUE)
|
||||
|
||||
///gets a round from the magazine, if keep is TRUE the round will stay in the gun
|
||||
/obj/item/ammo_box/proc/get_round(keep = FALSE)
|
||||
if (!stored_ammo.len)
|
||||
return null
|
||||
@@ -54,6 +64,7 @@
|
||||
stored_ammo.Insert(1,b)
|
||||
return b
|
||||
|
||||
///puts a round into the magazine
|
||||
/obj/item/ammo_box/proc/give_round(obj/item/ammo_casing/R, replace_spent = 0)
|
||||
// Boxes don't have a caliber type, magazines do. Not sure if it's intended or not, but if we fail to find a caliber, then we fall back to ammo_type.
|
||||
if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type))
|
||||
@@ -76,6 +87,7 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
///Whether or not the box can be loaded, used in overrides
|
||||
/obj/item/ammo_box/proc/can_load(mob/user)
|
||||
return TRUE
|
||||
|
||||
@@ -119,9 +131,9 @@
|
||||
/obj/item/ammo_box/update_icon()
|
||||
var/shells_left = stored_ammo.len
|
||||
switch(multiple_sprites)
|
||||
if(1)
|
||||
if(AMMO_BOX_PER_BULLET)
|
||||
icon_state = "[initial(icon_state)]-[shells_left]"
|
||||
if(2)
|
||||
if(AMMO_BOX_FULL_EMPTY)
|
||||
icon_state = "[initial(icon_state)]-[shells_left ? "[max_ammo]" : "0"]"
|
||||
desc = "[initial(desc)] There [(shells_left == 1) ? "is" : "are"] [shells_left] shell\s left!"
|
||||
for (var/material in bullet_cost)
|
||||
@@ -129,7 +141,7 @@
|
||||
material_amount = (material_amount*stored_ammo.len) + base_cost[material]
|
||||
materials[material] = material_amount
|
||||
|
||||
//Behavior for magazines
|
||||
///Count of number of bullets in the magazine
|
||||
/obj/item/ammo_box/magazine/proc/ammo_count(countempties = TRUE)
|
||||
var/boolets = 0
|
||||
for(var/obj/item/ammo_casing/bullet in stored_ammo)
|
||||
@@ -137,12 +149,14 @@
|
||||
boolets++
|
||||
return boolets
|
||||
|
||||
///list of every bullet in the magazine
|
||||
/obj/item/ammo_box/magazine/proc/ammo_list(drop_list = FALSE)
|
||||
var/list/L = stored_ammo.Copy()
|
||||
if(drop_list)
|
||||
stored_ammo.Cut()
|
||||
return L
|
||||
|
||||
///drops the entire contents of the magazine on the floor
|
||||
/obj/item/ammo_box/magazine/proc/empty_magazine()
|
||||
var/turf_mag = get_turf(src)
|
||||
for(var/obj/item/ammo in stored_ammo)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
icon_state = "357"
|
||||
ammo_type = /obj/item/ammo_casing/a357
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
multiple_sprites = AMMO_BOX_PER_BULLET
|
||||
|
||||
/obj/item/ammo_box/c38
|
||||
name = "speed loader (.38)"
|
||||
@@ -12,7 +12,7 @@
|
||||
icon_state = "38"
|
||||
ammo_type = /obj/item/ammo_casing/c38
|
||||
max_ammo = 6
|
||||
multiple_sprites = 1
|
||||
multiple_sprites = AMMO_BOX_PER_BULLET
|
||||
materials = list(MAT_METAL = 20000)
|
||||
|
||||
/obj/item/ammo_box/c38/trac
|
||||
@@ -53,7 +53,7 @@
|
||||
icon_state = "40mm"
|
||||
ammo_type = /obj/item/ammo_casing/a40mm
|
||||
max_ammo = 4
|
||||
multiple_sprites = 1
|
||||
multiple_sprites = AMMO_BOX_PER_BULLET
|
||||
|
||||
/obj/item/ammo_box/a762
|
||||
name = "stripper clip (7.62mm)"
|
||||
@@ -61,7 +61,7 @@
|
||||
icon_state = "762"
|
||||
ammo_type = /obj/item/ammo_casing/a762
|
||||
max_ammo = 5
|
||||
multiple_sprites = 1
|
||||
multiple_sprites = AMMO_BOX_PER_BULLET
|
||||
|
||||
/obj/item/ammo_box/n762
|
||||
name = "ammo box (7.62x38mmR)"
|
||||
@@ -80,4 +80,4 @@
|
||||
/obj/item/ammo_box/foambox/riot
|
||||
icon_state = "foambox_riot"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
|
||||
materials = list(MAT_METAL = 50000)
|
||||
materials = list(MAT_METAL = 50000)
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
icon_state = "75"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/a75
|
||||
caliber = "75"
|
||||
multiple_sprites = 2
|
||||
multiple_sprites = AMMO_BOX_FULL_EMPTY
|
||||
max_ammo = 8
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
ammo_type = /obj/item/ammo_casing/c10mm
|
||||
caliber = "10mm"
|
||||
max_ammo = 8
|
||||
multiple_sprites = 2
|
||||
multiple_sprites = AMMO_BOX_FULL_EMPTY
|
||||
|
||||
/obj/item/ammo_box/magazine/m10mm/fire
|
||||
name = "pistol magazine (10mm incendiary)"
|
||||
@@ -56,4 +56,4 @@
|
||||
ammo_type = /obj/item/ammo_casing/a50AE
|
||||
caliber = ".50"
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
multiple_sprites = AMMO_BOX_PER_BULLET
|
||||
|
||||
@@ -19,4 +19,4 @@
|
||||
ammo_type = /obj/item/ammo_casing/a556
|
||||
caliber = "a556"
|
||||
max_ammo = 30
|
||||
multiple_sprites = 2
|
||||
multiple_sprites = AMMO_BOX_FULL_EMPTY
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
name = "foam force pistol magazine"
|
||||
icon_state = "9x19p"
|
||||
max_ammo = 8
|
||||
multiple_sprites = 2
|
||||
multiple_sprites = AMMO_BOX_FULL_EMPTY
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/pistol/riot
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
|
||||
|
||||
@@ -1,59 +1,91 @@
|
||||
///Subtype for any kind of ballistic gun
|
||||
///This has a shitload of vars on it, and I'm sorry for that, but it does make making new subtypes really easy
|
||||
/obj/item/gun/ballistic
|
||||
desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason."
|
||||
name = "projectile gun"
|
||||
icon_state = "pistol"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
//sound info vars
|
||||
///sound when inserting magazine
|
||||
var/load_sound = "gun_insert_full_magazine"
|
||||
///sound when inserting an empty magazine
|
||||
var/load_empty_sound = "gun_insert_empty_magazine"
|
||||
///volume of loading sound
|
||||
var/load_sound_volume = 40
|
||||
///whether loading sound should vary
|
||||
var/load_sound_vary = TRUE
|
||||
///sound of racking
|
||||
var/rack_sound = "gun_slide_lock"
|
||||
///volume of racking
|
||||
var/rack_sound_volume = 60
|
||||
///whether racking sound should vary
|
||||
var/rack_sound_vary = TRUE
|
||||
///sound of when the bolt is locked back manually
|
||||
var/lock_back_sound = "sound/weapons/pistollock.ogg"
|
||||
///volume of lock back
|
||||
var/lock_back_sound_volume = 60
|
||||
///whether lock back varies
|
||||
var/lock_back_sound_vary = TRUE
|
||||
///Sound of ejecting a magazine
|
||||
var/eject_sound = "gun_remove_empty_magazine"
|
||||
///sound of ejecting an empty magazine
|
||||
var/eject_empty_sound = "gun_remove_full_magazine"
|
||||
///volume of ejecting a magazine
|
||||
var/eject_sound_volume = 40
|
||||
///whether eject sound should vary
|
||||
var/eject_sound_vary = TRUE
|
||||
///sound of dropping the bolt or releasing a slide
|
||||
var/bolt_drop_sound = 'sound/weapons/gun_chamber_round.ogg'
|
||||
///volume of bolt drop/slide release
|
||||
var/bolt_drop_sound_volume = 60
|
||||
///empty alarm sound (if enabled)
|
||||
var/empty_alarm_sound = 'sound/weapons/smg_empty_alarm.ogg'
|
||||
///empty alarm volume sound
|
||||
var/empty_alarm_volume = 70
|
||||
///whether empty alarm sound varies
|
||||
var/empty_alarm_vary = TRUE
|
||||
|
||||
///Whether the gun will spawn loaded with a magazine
|
||||
var/spawnwithmagazine = TRUE
|
||||
///Compatible magazines with the gun
|
||||
var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info
|
||||
var/mag_display = FALSE //Whether the sprite has a visible magazine or not
|
||||
var/mag_display_ammo = FALSE //Whether the sprite has a visible ammo display or not
|
||||
var/empty_indicator = FALSE //Whether the sprite has an indicator for being empty or not.
|
||||
var/empty_alarm = FALSE //Whether the gun alarms when empty or not.
|
||||
var/special_mags = FALSE //Whether the gun supports multiple special mag types
|
||||
///Whether the sprite has a visible magazine or not
|
||||
var/mag_display = FALSE
|
||||
///Whether the sprite has a visible ammo display or not
|
||||
var/mag_display_ammo = FALSE
|
||||
///Whether the sprite has a visible indicator for being empty or not.
|
||||
var/empty_indicator = FALSE
|
||||
///Whether the gun alarms when empty or not.
|
||||
var/empty_alarm = FALSE
|
||||
///Whether the gun supports multiple special mag types
|
||||
var/special_mags = FALSE
|
||||
///Whether the gun is currently alarmed to prevent it from spamming sounds
|
||||
var/alarmed = FALSE
|
||||
//Four bolt types:
|
||||
//BOLT_TYPE_STANDARD: Gun has a bolt, it stays closed while not cycling. The gun must be racked to have a bullet chambered when a mag is inserted.
|
||||
//Example: c20, shotguns, m90
|
||||
//BOLT_TYPE_OPEN: Gun has a bolt, it is open when ready to fire. The gun can never have a chambered bullet with no magazine, but the bolt stays ready when a mag is removed.
|
||||
//Example: Some SMGs, the L6
|
||||
//BOLT_TYPE_NO_BOLT: Gun has no moving bolt mechanism, it cannot be racked. Also dumps the entire contents when emptied instead of a magazine.
|
||||
//Example: Break action shotguns, revolvers
|
||||
//BOLT_TYPE_LOCKING: Gun has a bolt, it locks back when empty. It can be released to chamber a round if a magazine is in.
|
||||
//Example: Pistols with a slide lock, some SMGs
|
||||
///The bolt type of the gun, affects quite a bit of functionality, see combat.dm defines for bolt types: BOLT_TYPE_STANDARD; BOLT_TYPE_LOCKING; BOLT_TYPE_OPEN; BOLT_TYPE_NO_BOLT
|
||||
var/bolt_type = BOLT_TYPE_STANDARD
|
||||
var/bolt_locked = FALSE //Used for locking bolt and open bolt guns. Set a bit differently for the two but prevents firing when true for both.
|
||||
var/bolt_wording = "bolt" //bolt, slide, etc.
|
||||
var/semi_auto = TRUE //Whether the gun has to be racked each shot or not.
|
||||
///Used for locking bolt and open bolt guns. Set a bit differently for the two but prevents firing when true for both.
|
||||
var/bolt_locked = FALSE
|
||||
///Whether the gun has to be racked each shot or not.
|
||||
var/semi_auto = TRUE
|
||||
///Actual magazine currently contained within the gun
|
||||
var/obj/item/ammo_box/magazine/magazine
|
||||
var/casing_ejector = TRUE //whether the gun ejects the chambered casing
|
||||
var/internal_magazine = FALSE //Whether the gun has an internal magazine or a detatchable one. Overridden by BOLT_TYPE_NO_BOLT.
|
||||
///whether the gun ejects the chambered casing
|
||||
var/casing_ejector = TRUE
|
||||
///Whether the gun has an internal magazine or a detatchable one. Overridden by BOLT_TYPE_NO_BOLT.
|
||||
var/internal_magazine = FALSE
|
||||
///Phrasing of the bolt in examine and notification messages; ex: bolt, slide, etc.
|
||||
var/bolt_wording = "bolt"
|
||||
///Phrasing of the magazine in examine and notification messages; ex: magazine, box, etx
|
||||
var/magazine_wording = "magazine"
|
||||
///Phrasing of the cartridge in examine and notification messages; ex: bullet, shell, dart, etc.
|
||||
var/cartridge_wording = "bullet"
|
||||
///length between individual racks
|
||||
var/rack_delay = 5
|
||||
///time of the most recent rack, used for cooldown purposes
|
||||
var/recent_rack = 0
|
||||
///Whether the gun can be tacloaded by slapping a fresh magazine directly on it
|
||||
var/tac_reloads = TRUE //Snowflake mechanic no more.
|
||||
///Whether the gun can be sawn off by sawing tools
|
||||
var/can_be_sawn_off = FALSE
|
||||
|
||||
/obj/item/gun/ballistic/Initialize()
|
||||
@@ -121,6 +153,7 @@
|
||||
if (chamber_next_round && (magazine?.max_ammo > 1))
|
||||
chamber_round()
|
||||
|
||||
///Used to chamber a new round and eject the old one
|
||||
/obj/item/gun/ballistic/proc/chamber_round(keep_bullet = FALSE)
|
||||
if (chambered || !magazine)
|
||||
return
|
||||
@@ -129,6 +162,7 @@
|
||||
if (bolt_type != BOLT_TYPE_OPEN)
|
||||
chambered.forceMove(src)
|
||||
|
||||
///updates a bunch of racking related stuff and also handles the sound effects and the like
|
||||
/obj/item/gun/ballistic/proc/rack(mob/user = null)
|
||||
if (bolt_type == BOLT_TYPE_NO_BOLT) //If there's no bolt, nothing to rack
|
||||
return
|
||||
@@ -148,6 +182,7 @@
|
||||
playsound(src, rack_sound, rack_sound_volume, rack_sound_vary)
|
||||
update_icon()
|
||||
|
||||
///Drops the bolt from a locked position
|
||||
/obj/item/gun/ballistic/proc/drop_bolt(mob/user = null)
|
||||
playsound(src, bolt_drop_sound, bolt_drop_sound_volume, FALSE)
|
||||
if (user)
|
||||
@@ -156,6 +191,7 @@
|
||||
bolt_locked = FALSE
|
||||
update_icon()
|
||||
|
||||
///Handles all the logic needed for magazine insertion
|
||||
/obj/item/gun/ballistic/proc/insert_magazine(mob/user, obj/item/ammo_box/magazine/AM, display_message = TRUE)
|
||||
if(!istype(AM, mag_type))
|
||||
to_chat(user, "<span class='warning'>\The [AM] doesn't seem to fit into \the [src]...</span>")
|
||||
@@ -173,6 +209,7 @@
|
||||
to_chat(user, "<span class='warning'>You cannot seem to get \the [src] out of your hands!</span>")
|
||||
return FALSE
|
||||
|
||||
///Handles all the logic of magazine ejection, if tac_load is set that magazine will be tacloaded in the place of the old eject
|
||||
/obj/item/gun/ballistic/proc/eject_magazine(mob/user, display_message = TRUE, obj/item/ammo_box/magazine/tac_load = null)
|
||||
if(bolt_type == BOLT_TYPE_OPEN)
|
||||
chambered = null
|
||||
@@ -252,8 +289,8 @@
|
||||
bonus_spread += SAWN_OFF_ACC_PENALTY
|
||||
. = ..()
|
||||
|
||||
///Installs a new suppressor, assumes that the suppressor is already in the contents of src
|
||||
/obj/item/gun/ballistic/proc/install_suppressor(obj/item/suppressor/S)
|
||||
// this proc assumes that the suppressor is already inside src
|
||||
suppressed = S
|
||||
w_class += S.w_class //so pistols do not fit in pockets when suppressed
|
||||
update_icon()
|
||||
@@ -274,6 +311,7 @@
|
||||
update_icon()
|
||||
return
|
||||
|
||||
///Prefire empty checks for the bolt drop
|
||||
/obj/item/gun/ballistic/proc/prefire_empty_checks()
|
||||
if (!chambered && !get_ammo())
|
||||
if (bolt_type == BOLT_TYPE_OPEN && !bolt_locked)
|
||||
@@ -281,7 +319,7 @@
|
||||
playsound(src, bolt_drop_sound, bolt_drop_sound_volume)
|
||||
update_icon()
|
||||
|
||||
|
||||
///postfire empty checks for bolt locking and sound alarms
|
||||
/obj/item/gun/ballistic/proc/postfire_empty_checks()
|
||||
if (!chambered && !get_ammo())
|
||||
if (!alarmed && empty_alarm)
|
||||
@@ -344,6 +382,7 @@
|
||||
if (suppressed)
|
||||
. += "It has a suppressor attached that can be removed with <b>alt+click</b>."
|
||||
|
||||
///Gets the number of bullets in the gun
|
||||
/obj/item/gun/ballistic/proc/get_ammo(countchambered = TRUE)
|
||||
var/boolets = 0 //mature var names for mature people
|
||||
if (chambered && countchambered)
|
||||
@@ -352,6 +391,7 @@
|
||||
boolets += magazine.ammo_count()
|
||||
return boolets
|
||||
|
||||
///gets a list of every bullet in the gun
|
||||
/obj/item/gun/ballistic/proc/get_ammo_list(countchambered = TRUE, drop_all = FALSE)
|
||||
var/list/rounds = list()
|
||||
if(chambered && countchambered)
|
||||
@@ -397,6 +437,7 @@ GLOBAL_LIST_INIT(gun_saw_types, typecacheof(list(
|
||||
/obj/item/nullrod/chainsaw,
|
||||
/obj/item/mounted_chainsaw)))
|
||||
|
||||
///Handles all the logic of sawing off guns,
|
||||
/obj/item/gun/ballistic/proc/sawoff(mob/user, obj/item/saw)
|
||||
if(!saw.is_sharp() || !is_type_in_typecache(saw, GLOB.gun_saw_types)) //needs to be sharp. Otherwise turned off eswords can cut this.
|
||||
return
|
||||
@@ -429,7 +470,7 @@ GLOBAL_LIST_INIT(gun_saw_types, typecacheof(list(
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
// Sawing guns related proc
|
||||
///used for sawing guns, causes the gun to fire without the input of the user
|
||||
/obj/item/gun/ballistic/proc/blow_up(mob/user)
|
||||
. = FALSE
|
||||
for(var/obj/item/ammo_casing/AC in magazine.stored_ammo)
|
||||
|
||||
@@ -47,15 +47,25 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Holder for a bunch of [/datum/reagent]
|
||||
/datum/reagents
|
||||
/// The reagents being held
|
||||
var/list/datum/reagent/reagent_list = new/list()
|
||||
/// Current volume of all the reagents
|
||||
var/total_volume = 0
|
||||
/// Max volume of this holder
|
||||
var/maximum_volume = 100
|
||||
/// The atom this holder is attached to
|
||||
var/atom/my_atom = null
|
||||
/// Current temp of the holder volume
|
||||
var/chem_temp = 150
|
||||
/// unused
|
||||
var/last_tick = 1
|
||||
/// see [/datum/reagents/proc/metabolize] for usage
|
||||
var/addiction_tick = 1
|
||||
/// currently addicted reagents
|
||||
var/list/datum/reagent/addiction_list = new/list()
|
||||
/// various flags, see code\__DEFINES\reagents.dm
|
||||
var/flags
|
||||
|
||||
/datum/reagents/New(maximum=100, new_flags=0)
|
||||
@@ -81,7 +91,9 @@
|
||||
my_atom.reagents = null
|
||||
my_atom = null
|
||||
|
||||
// Used in attack logs for reagents in pills and such
|
||||
/**
|
||||
* Used in attack logs for reagents in pills and such
|
||||
*/
|
||||
/datum/reagents/proc/log_list()
|
||||
if(!length(reagent_list))
|
||||
return "no reagents"
|
||||
@@ -93,6 +105,7 @@
|
||||
//Using IDs because SOME chemicals (I'm looking at you, chlorhydrate-beer) have the same names as other chemicals.
|
||||
return english_list(data)
|
||||
|
||||
/// Remove an amount of reagents without caring about what they are
|
||||
/datum/reagents/proc/remove_any(amount = 1)
|
||||
var/list/cached_reagents = reagent_list
|
||||
var/total_transfered = 0
|
||||
@@ -119,6 +132,7 @@
|
||||
handle_reactions()
|
||||
return total_transfered
|
||||
|
||||
/// Removes all reagents from this holder
|
||||
/datum/reagents/proc/remove_all(amount = 1)
|
||||
var/list/cached_reagents = reagent_list
|
||||
if(total_volume > 0)
|
||||
@@ -131,6 +145,7 @@
|
||||
handle_reactions()
|
||||
return amount
|
||||
|
||||
/// Get the name of the reagent there is the most of in this holder
|
||||
/datum/reagents/proc/get_master_reagent_name()
|
||||
var/list/cached_reagents = reagent_list
|
||||
var/name
|
||||
@@ -143,6 +158,7 @@
|
||||
|
||||
return name
|
||||
|
||||
/// Get the id of the reagent there is the most of in this holder
|
||||
/datum/reagents/proc/get_master_reagent_id()
|
||||
var/list/cached_reagents = reagent_list
|
||||
var/max_type
|
||||
@@ -155,6 +171,7 @@
|
||||
|
||||
return max_type
|
||||
|
||||
/// Get a reference to the reagent there is the most of in this holder
|
||||
/datum/reagents/proc/get_master_reagent()
|
||||
var/list/cached_reagents = reagent_list
|
||||
var/datum/reagent/master
|
||||
@@ -167,8 +184,22 @@
|
||||
|
||||
return master
|
||||
|
||||
/**
|
||||
* Transfer some stuff from this holder to a target object
|
||||
*
|
||||
* Arguments:
|
||||
* * obj/target - Target to attempt transfer to
|
||||
* * amount - amount of reagent volume to transfer
|
||||
* * multiplier - multiplies amount of each reagent by this number
|
||||
* * preserve_data - if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
|
||||
* * no_react - passed through to [/datum/reagents/proc/add_reagent]
|
||||
* * mob/transfered_by - used for logging
|
||||
* * remove_blacklisted - skips transferring of reagents with can_synth = FALSE
|
||||
* * method - passed through to [/datum/reagents/proc/react_single] and [/datum/reagent/proc/on_transfer]
|
||||
* * show_message - passed through to [/datum/reagents/proc/react_single]
|
||||
* * round_robin - if round_robin=TRUE, so transfer 5 from 15 water, 15 sugar and 15 plasma becomes 10, 15, 15 instead of 13.3333, 13.3333 13.3333. Good if you hate floating point errors
|
||||
*/
|
||||
/datum/reagents/proc/trans_to(obj/target, amount = 1, multiplier = 1, preserve_data = TRUE, no_react = FALSE, mob/transfered_by, remove_blacklisted = FALSE)
|
||||
//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
|
||||
var/list/cached_reagents = reagent_list
|
||||
if(!target || !total_volume)
|
||||
return
|
||||
@@ -210,6 +241,7 @@
|
||||
src.handle_reactions()
|
||||
return amount
|
||||
|
||||
/// Copies the reagents to the target object
|
||||
/datum/reagents/proc/copy_to(obj/target, amount=1, multiplier=1, preserve_data=1)
|
||||
var/list/cached_reagents = reagent_list
|
||||
if(!target || !total_volume)
|
||||
@@ -241,6 +273,7 @@
|
||||
src.handle_reactions()
|
||||
return amount
|
||||
|
||||
/// Transfer a specific reagent id to the target object
|
||||
/datum/reagents/proc/trans_id_to(obj/target, reagent, amount=1, preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N
|
||||
var/list/cached_reagents = reagent_list
|
||||
if (!target)
|
||||
@@ -269,6 +302,14 @@
|
||||
R.handle_reactions()
|
||||
return amount
|
||||
|
||||
/**
|
||||
* Triggers metabolizing the reagents in this holder
|
||||
*
|
||||
* Arguments:
|
||||
* * mob/living/carbon/C - The mob to metabolize in, if null it uses [/datum/reagents/var/my_atom]
|
||||
* * can_overdose - Allows overdosing
|
||||
* * liverless - Stops reagents that aren't set as [/datum/reagent/var/self_consuming] from metabolizing
|
||||
*/
|
||||
/datum/reagents/proc/metabolize(mob/living/carbon/C, can_overdose = FALSE, liverless = FALSE)
|
||||
var/list/cached_reagents = reagent_list
|
||||
var/list/cached_addictions = addiction_list
|
||||
@@ -338,7 +379,8 @@
|
||||
C.update_stamina()
|
||||
update_total()
|
||||
|
||||
//Signals that metabolization has stopped, triggering the end of trait-based effects
|
||||
/// Removes addiction to a specific reagent on [/datum/reagents/var/my_atom]
|
||||
/// Signals that metabolization has stopped, triggering the end of trait-based effects
|
||||
/datum/reagents/proc/end_metabolization(mob/living/carbon/C, keep_liverless = TRUE)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
@@ -353,6 +395,13 @@
|
||||
R.metabolizing = FALSE
|
||||
R.on_mob_end_metabolize(C)
|
||||
|
||||
/**
|
||||
* Calls [/datum/reagent/proc/on_move] on every reagent in this holder
|
||||
*
|
||||
* Arguments:
|
||||
* * atom/A - passed to on_move
|
||||
* * Running - passed to on_move
|
||||
*/
|
||||
/datum/reagents/proc/conditional_update_move(atom/A, Running = 0)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
@@ -360,6 +409,12 @@
|
||||
R.on_move (A, Running)
|
||||
update_total()
|
||||
|
||||
/**
|
||||
* Calls [/datum/reagent/proc/on_update] on every reagent in this holder
|
||||
*
|
||||
* Arguments:
|
||||
* * atom/A - passed to on_update
|
||||
*/
|
||||
/datum/reagents/proc/conditional_update(atom/A)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
@@ -367,6 +422,7 @@
|
||||
R.on_update (A)
|
||||
update_total()
|
||||
|
||||
/// Handle any reactions possible in this holder
|
||||
/datum/reagents/proc/handle_reactions()
|
||||
if(flags & NO_REACT)
|
||||
return //Yup, no reactions here. No siree.
|
||||
@@ -486,6 +542,7 @@
|
||||
update_total()
|
||||
return 0
|
||||
|
||||
/// Remove every reagent except this one
|
||||
/datum/reagents/proc/isolate_reagent(reagent)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/_reagent in cached_reagents)
|
||||
@@ -494,6 +551,7 @@
|
||||
del_reagent(R.type)
|
||||
update_total()
|
||||
|
||||
/// Fuck this one reagent
|
||||
/datum/reagents/proc/del_reagent(reagent)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/_reagent in cached_reagents)
|
||||
@@ -512,6 +570,7 @@
|
||||
my_atom.on_reagent_change(DEL_REAGENT)
|
||||
return 1
|
||||
|
||||
/// Updates [/datum/reagents/var/total_volume]
|
||||
/datum/reagents/proc/update_total()
|
||||
var/list/cached_reagents = reagent_list
|
||||
total_volume = 0
|
||||
@@ -524,6 +583,7 @@
|
||||
|
||||
return 0
|
||||
|
||||
/// Removes all reagents
|
||||
/datum/reagents/proc/clear_reagents()
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
@@ -531,6 +591,12 @@
|
||||
del_reagent(R.type)
|
||||
return 0
|
||||
|
||||
/**
|
||||
* Applies the relevant reaction_ proc for every reagent in this holder
|
||||
* * [/datum/reagent/proc/reaction_mob]
|
||||
* * [/datum/reagent/proc/reaction_turf]
|
||||
* * [/datum/reagent/proc/reaction_obj]
|
||||
*/
|
||||
/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1)
|
||||
var/react_type
|
||||
if(isliving(A))
|
||||
@@ -559,12 +625,14 @@
|
||||
if("OBJ")
|
||||
R.reaction_obj(A, R.volume * volume_modifier, show_message)
|
||||
|
||||
/// Same as [/datum/reagents/proc/reaction] but only for one reagent
|
||||
/// Is this holder full or not
|
||||
/datum/reagents/proc/holder_full()
|
||||
if(total_volume >= maximum_volume)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//Returns the average specific heat for all reagents currently in this holder.
|
||||
/// Returns the average specific heat for all reagents currently in this holder.
|
||||
/datum/reagents/proc/specific_heat()
|
||||
. = 0
|
||||
var/cached_amount = total_volume //cache amount
|
||||
@@ -577,6 +645,16 @@
|
||||
var/S = specific_heat()
|
||||
chem_temp = clamp(chem_temp + (J / (S * total_volume)), 2.7, 1000)
|
||||
|
||||
/**
|
||||
* Adds a reagent to this holder
|
||||
*
|
||||
* Arguments:
|
||||
* * reagent - The reagent id to add
|
||||
* * amount - Amount to add
|
||||
* * list/data - Any reagent data for this reagent, used for transferring data with reagents
|
||||
* * reagtemp - Temperature of this reagent, will be equalized
|
||||
* * no_react - prevents reactions being triggered by this addition
|
||||
*/
|
||||
/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, no_react = 0)
|
||||
if(!isnum(amount) || !amount)
|
||||
return FALSE
|
||||
@@ -648,11 +726,13 @@
|
||||
handle_reactions()
|
||||
return TRUE
|
||||
|
||||
/datum/reagents/proc/add_reagent_list(list/list_reagents, list/data=null) // Like add_reagent but you can enter a list. Format it like this: list(/datum/reagent/toxin = 10, "beer" = 15)
|
||||
/// Like add_reagent but you can enter a list. Format it like this: list(/datum/reagent/toxin = 10, "beer" = 15)
|
||||
/datum/reagents/proc/add_reagent_list(list/list_reagents, list/data=null)
|
||||
for(var/r_id in list_reagents)
|
||||
var/amt = list_reagents[r_id]
|
||||
add_reagent(r_id, amt, data)
|
||||
|
||||
/// Remove a specific reagent
|
||||
/datum/reagents/proc/remove_reagent(reagent, amount, safety)//Added a safety check for the trans_id_to
|
||||
|
||||
if(isnull(amount))
|
||||
@@ -683,6 +763,7 @@
|
||||
|
||||
return FALSE
|
||||
|
||||
/// Check if this holder contains this reagent
|
||||
/datum/reagents/proc/has_reagent(reagent, amount = -1, needs_metabolizing = FALSE)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/_reagent in cached_reagents)
|
||||
@@ -702,6 +783,7 @@
|
||||
|
||||
return 0
|
||||
|
||||
/// Get the amount of this reagent
|
||||
/datum/reagents/proc/get_reagent_amount(reagent)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/_reagent in cached_reagents)
|
||||
@@ -711,6 +793,7 @@
|
||||
|
||||
return 0
|
||||
|
||||
/// Get a comma separated string of every reagent name in this holder
|
||||
/datum/reagents/proc/get_reagents()
|
||||
var/list/names = list()
|
||||
var/list/cached_reagents = reagent_list
|
||||
@@ -720,7 +803,8 @@
|
||||
|
||||
return jointext(names, ",")
|
||||
|
||||
/datum/reagents/proc/remove_all_type(reagent_type, amount, strict = 0, safety = 1) // Removes all reagent of X type. @strict set to 1 determines whether the childs of the type are included.
|
||||
/// Removes all reagent of X type. @strict set to 1 determines whether the childs of the type are included.
|
||||
/datum/reagents/proc/remove_all_type(reagent_type, amount, strict = 0, safety = 1)
|
||||
if(!isnum(amount))
|
||||
return 1
|
||||
var/list/cached_reagents = reagent_list
|
||||
@@ -743,7 +827,7 @@
|
||||
|
||||
return has_removed_reagent
|
||||
|
||||
//two helper functions to preserve data across reactions (needed for xenoarch)
|
||||
/// helper function to preserve data across reactions (needed for xenoarch)
|
||||
/datum/reagents/proc/get_data(reagent_id)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
@@ -751,6 +835,7 @@
|
||||
if(R.type == reagent_id)
|
||||
return R.data
|
||||
|
||||
/// helper function to preserve data across reactions (needed for xenoarch)
|
||||
/datum/reagents/proc/set_data(reagent_id, new_data)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
@@ -758,6 +843,7 @@
|
||||
if(R.type == reagent_id)
|
||||
R.data = new_data
|
||||
|
||||
/// Shallow copies (deep copy of viruses) data from the provided reagent into our copy of that reagent
|
||||
/datum/reagents/proc/copy_data(datum/reagent/current_reagent)
|
||||
if(!current_reagent || !current_reagent.data)
|
||||
return null
|
||||
@@ -779,12 +865,18 @@
|
||||
|
||||
return trans_data
|
||||
|
||||
/// Get a reference to the reagent if it exists
|
||||
/datum/reagents/proc/get_reagent(type)
|
||||
var/list/cached_reagents = reagent_list
|
||||
. = locate(type) in cached_reagents
|
||||
|
||||
/**
|
||||
* Returns what this holder's reagents taste like
|
||||
*
|
||||
* Arguments:
|
||||
* * minimum_percent - the lower the minimum percent, the more sensitive the message is.
|
||||
*/
|
||||
/datum/reagents/proc/generate_taste_message(minimum_percent=15)
|
||||
// the lower the minimum percent, the more sensitive the message is.
|
||||
var/list/out = list()
|
||||
var/list/tastes = list() //descriptor = strength
|
||||
if(minimum_percent <= 100)
|
||||
@@ -828,6 +920,7 @@
|
||||
|
||||
return english_list(out, "something indescribable")
|
||||
|
||||
/// Applies heat to this holder
|
||||
/datum/reagents/proc/expose_temperature(var/temperature, var/coeff=0.02)
|
||||
var/temp_delta = (temperature - chem_temp) * coeff
|
||||
if(temp_delta > 0)
|
||||
@@ -840,8 +933,13 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Convenience proc to create a reagents holder for an atom
|
||||
// Max vol is maximum volume of holder
|
||||
/**
|
||||
* Convenience proc to create a reagents holder for an atom
|
||||
*
|
||||
* Arguments:
|
||||
* * max_vol - maximum volume of holder
|
||||
* * flags - flags to pass to the holder
|
||||
*/
|
||||
/atom/proc/create_reagents(max_vol, flags)
|
||||
if(reagents)
|
||||
qdel(reagents)
|
||||
|
||||
@@ -14,37 +14,65 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
|
||||
//Toxin & acid reagents
|
||||
//Hydroponics stuff
|
||||
|
||||
/// A single reagent
|
||||
/datum/reagent
|
||||
/// datums don't have names by default
|
||||
var/name = "Reagent"
|
||||
/// nor do they have descriptions
|
||||
var/description = ""
|
||||
var/specific_heat = SPECIFIC_HEAT_DEFAULT //J/(K*mol)
|
||||
///J/(K*mol)
|
||||
var/specific_heat = SPECIFIC_HEAT_DEFAULT
|
||||
/// used by taste messages
|
||||
var/taste_description = "metaphorical salt"
|
||||
var/taste_mult = 1 //how this taste compares to others. Higher values means it is more noticable
|
||||
var/glass_name = "glass of ...what?" // use for specialty drinks.
|
||||
///how this taste compares to others. Higher values means it is more noticable
|
||||
var/taste_mult = 1
|
||||
/// use for specialty drinks.
|
||||
var/glass_name = "glass of ...what?"
|
||||
/// desc applied to glasses with this reagent
|
||||
var/glass_desc = "You can't really tell what this is."
|
||||
var/glass_icon_state = null // Otherwise just sets the icon to a normal glass with the mixture of the reagents in the glass.
|
||||
/// Otherwise just sets the icon to a normal glass with the mixture of the reagents in the glass.
|
||||
var/glass_icon_state = null
|
||||
/// used for shot glasses, mostly for alcohol
|
||||
var/shot_glass_icon_state = null
|
||||
/// reagent holder this belongs to
|
||||
var/datum/reagents/holder = null
|
||||
/// LIQUID, SOLID, GAS
|
||||
var/reagent_state = LIQUID
|
||||
/// special data associated with this like viruses etc
|
||||
var/list/data
|
||||
/// increments everytime on_mob_life is called
|
||||
var/current_cycle = 0
|
||||
var/volume = 0 //pretend this is moles
|
||||
///pretend this is moles
|
||||
var/volume = 0
|
||||
/// color it looks in containers etc
|
||||
var/color = "#000000" // rgb: 0, 0, 0
|
||||
var/can_synth = TRUE // can this reagent be synthesized? (for example: odysseus syringe gun)
|
||||
var/metabolization_rate = REAGENTS_METABOLISM //how fast the reagent is metabolized by the mob
|
||||
/// can this reagent be synthesized? (for example: odysseus syringe gun)
|
||||
var/can_synth = TRUE
|
||||
///how fast the reagent is metabolized by the mob
|
||||
var/metabolization_rate = REAGENTS_METABOLISM
|
||||
/// appears unused
|
||||
var/overrides_metab = 0
|
||||
/// above this overdoses happen
|
||||
var/overdose_threshold = 0
|
||||
/// above this amount addictions start
|
||||
var/addiction_threshold = 0
|
||||
/// increases as addiction gets worse
|
||||
var/addiction_stage = 0
|
||||
var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick.
|
||||
/// You fucked up and this is now triggering its overdose effects, purge that shit quick.
|
||||
var/overdosed = 0
|
||||
///if false stops metab in liverless mobs
|
||||
var/self_consuming = FALSE
|
||||
var/reagent_weight = 1 //affects how far it travels when sprayed
|
||||
///affects how far it travels when sprayed
|
||||
var/reagent_weight = 1
|
||||
///is it currently metabolizing
|
||||
var/metabolizing = FALSE
|
||||
/// Are we from a material? We might wanna know that for special stuff. Like metalgen. Is replaced with a ref of the material on New()
|
||||
|
||||
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
|
||||
. = ..()
|
||||
holder = null
|
||||
|
||||
/// Applies this reagent to a [/mob/living]
|
||||
/datum/reagent/proc/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
|
||||
if(!istype(M))
|
||||
return 0
|
||||
@@ -56,78 +84,90 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
|
||||
M.reagents.add_reagent(type, amount)
|
||||
return 1
|
||||
|
||||
/// Applies this reagent to an [/obj]
|
||||
/datum/reagent/proc/reaction_obj(obj/O, volume)
|
||||
return
|
||||
|
||||
/// Applies this reagent to a [/turf]
|
||||
/datum/reagent/proc/reaction_turf(turf/T, volume)
|
||||
return
|
||||
|
||||
/// Called from [/datum/reagents/proc/metabolize]
|
||||
/datum/reagent/proc/on_mob_life(mob/living/carbon/M)
|
||||
current_cycle++
|
||||
holder.remove_reagent(type, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears.
|
||||
return
|
||||
|
||||
// Called when this reagent is first added to a mob
|
||||
///Called after a reagent is transfered
|
||||
/datum/reagent/proc/on_transfer(atom/A, method=TOUCH, trans_volume)
|
||||
/// Called when this reagent is first added to a mob
|
||||
/datum/reagent/proc/on_mob_add(mob/living/L)
|
||||
return
|
||||
|
||||
// Called when this reagent is removed while inside a mob
|
||||
/// Called when this reagent is removed while inside a mob
|
||||
/datum/reagent/proc/on_mob_delete(mob/living/L)
|
||||
return
|
||||
|
||||
// Called when this reagent first starts being metabolized by a liver
|
||||
/// Called when this reagent first starts being metabolized by a liver
|
||||
/datum/reagent/proc/on_mob_metabolize(mob/living/L)
|
||||
return
|
||||
|
||||
// Called when this reagent stops being metabolized by a liver
|
||||
/// Called when this reagent stops being metabolized by a liver
|
||||
/datum/reagent/proc/on_mob_end_metabolize(mob/living/L)
|
||||
return
|
||||
|
||||
/// Called by [/datum/reagents/proc/conditional_update_move]
|
||||
/datum/reagent/proc/on_move(mob/M)
|
||||
return
|
||||
|
||||
// Called after add_reagents creates a new reagent.
|
||||
/// Called after add_reagents creates a new reagent.
|
||||
/datum/reagent/proc/on_new(data)
|
||||
return
|
||||
|
||||
// Called when two reagents of the same are mixing.
|
||||
/// Called when two reagents of the same are mixing.
|
||||
/datum/reagent/proc/on_merge(data)
|
||||
return
|
||||
|
||||
/// Called by [/datum/reagents/proc/conditional_update]
|
||||
/datum/reagent/proc/on_update(atom/A)
|
||||
return
|
||||
|
||||
// Called when the reagent container is hit by an explosion
|
||||
/// Called when the reagent container is hit by an explosion
|
||||
/datum/reagent/proc/on_ex_act(severity)
|
||||
return
|
||||
|
||||
// Called if the reagent has passed the overdose threshold and is set to be triggering overdose effects
|
||||
/// Called if the reagent has passed the overdose threshold and is set to be triggering overdose effects
|
||||
/datum/reagent/proc/overdose_process(mob/living/M)
|
||||
return
|
||||
|
||||
/// Called when an overdose starts
|
||||
/datum/reagent/proc/overdose_start(mob/living/M)
|
||||
to_chat(M, "<span class='userdanger'>You feel like you took too much of [name]!</span>")
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/overdose, name)
|
||||
return
|
||||
|
||||
/// Called when addiction hits stage1, see [/datum/reagents/proc/metabolize]
|
||||
/datum/reagent/proc/addiction_act_stage1(mob/living/M)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/withdrawal_light, name)
|
||||
if(prob(30))
|
||||
to_chat(M, "<span class='notice'>You feel like having some [name] right about now.</span>")
|
||||
return
|
||||
|
||||
/// Called when addiction hits stage2, see [/datum/reagents/proc/metabolize]
|
||||
/datum/reagent/proc/addiction_act_stage2(mob/living/M)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/withdrawal_medium, name)
|
||||
if(prob(30))
|
||||
to_chat(M, "<span class='notice'>You feel like you need [name]. You just can't get enough.</span>")
|
||||
return
|
||||
|
||||
/// Called when addiction hits stage3, see [/datum/reagents/proc/metabolize]
|
||||
/datum/reagent/proc/addiction_act_stage3(mob/living/M)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/withdrawal_severe, name)
|
||||
if(prob(30))
|
||||
to_chat(M, "<span class='danger'>You have an intense craving for [name].</span>")
|
||||
return
|
||||
|
||||
/// Called when addiction hits stage4, see [/datum/reagents/proc/metabolize]
|
||||
/datum/reagent/proc/addiction_act_stage4(mob/living/M)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/withdrawal_critical, name)
|
||||
if(prob(30))
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
throw_speed = 3
|
||||
throw_range = 6
|
||||
grind_results = list()
|
||||
var/Uses = 1 // uses before it goes inert
|
||||
var/qdel_timer = null // deletion timer, for delayed reactions
|
||||
var/effectmod
|
||||
var/list/activate_reagents = list() //Reagents required for activation
|
||||
var/Uses = 1 ///uses before it goes inert
|
||||
var/qdel_timer = null ///deletion timer, for delayed reactions
|
||||
var/effectmod ///Which type of crossbred
|
||||
var/list/activate_reagents = list() ///Reagents required for activation
|
||||
var/recurring = FALSE
|
||||
|
||||
/obj/item/slime_extract/examine(mob/user)
|
||||
@@ -44,12 +44,24 @@
|
||||
if(Uses)
|
||||
grind_results[/datum/reagent/toxin/slimejelly] = 20
|
||||
|
||||
//Effect when activated by a Luminescent. Separated into a minor and major effect. Returns cooldown in deciseconds.
|
||||
/**
|
||||
* Effect when activated by a Luminescent.
|
||||
*
|
||||
* This proc is called whenever a Luminescent consumes a slime extract. Each one is separated into major and minor effects depending on the extract. Cooldown is measured in deciseconds.
|
||||
*
|
||||
* * arg1 - The mob absorbing the slime extract.
|
||||
* * arg2 - The valid species for the absorbtion. Should always be a Luminescent unless something very major has changed.
|
||||
* * arg3 - Whether or not the activation is major or minor. Major activations have large, complex effects, minor are simple.
|
||||
*/
|
||||
/obj/item/slime_extract/proc/activate(mob/living/carbon/human/user, datum/species/jelly/luminescent/species, activation_type)
|
||||
to_chat(user, "<span class='notice'>Nothing happened... This slime extract cannot be activated this way.</span>")
|
||||
return 0
|
||||
|
||||
//Core-crossing: Feeding adult slimes extracts to obtain a much more powerful, single extract.
|
||||
/**
|
||||
* Core-crossing: Feeding adult slimes extracts to obtain a much more powerful, single extract.
|
||||
*
|
||||
* By using a valid core on a living adult slime, then feeding it nine more of the same type, you can mutate it into more useful items. Not every slime type has an implemented core cross.
|
||||
*/
|
||||
/obj/item/slime_extract/attack(mob/living/simple_animal/slime/M, mob/user)
|
||||
if(!isslime(M))
|
||||
return ..()
|
||||
@@ -608,6 +620,16 @@
|
||||
|
||||
////Slime-derived potions///
|
||||
|
||||
/**
|
||||
* #Slime potions
|
||||
*
|
||||
* Feed slimes potions either by hand or using the slime console.
|
||||
*
|
||||
* Slime potions either augment the slime's behavior, its extract output, or its intelligence. These all come either from extract effects or cross cores.
|
||||
* A few of the more powerful ones can modify someone's equipment or gender.
|
||||
* New ones should probably be accessible only through cross cores as all the normal core types already have uses. Rule of thumb is 'stronger effects go in cross cores'.
|
||||
*/
|
||||
|
||||
/obj/item/slimepotion
|
||||
name = "slime potion"
|
||||
desc = "A hard yet gelatinous capsule excreted by a slime, containing mysterious substances."
|
||||
@@ -976,6 +998,8 @@
|
||||
imp.implant(M, user)
|
||||
qdel(src)
|
||||
|
||||
///Definitions for slime products that don't have anywhere else to go (Floor tiles, blueprints).
|
||||
|
||||
/obj/item/stack/tile/bluespace
|
||||
name = "bluespace floor tile"
|
||||
singular_name = "floor tile"
|
||||
|
||||
@@ -11,17 +11,26 @@
|
||||
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
anchored = TRUE
|
||||
//
|
||||
/// The identifier of the port or ship.
|
||||
/// This will be used in numerous other places like the console,
|
||||
/// stationary ports and whatnot to tell them your ship's mobile
|
||||
/// port can be used in these places, or the docking port is compatible, etc.
|
||||
var/id
|
||||
// this should point -away- from the dockingport door, ie towards the ship
|
||||
///Common standard is for this to point -away- from the dockingport door, ie towards the ship
|
||||
dir = NORTH
|
||||
var/width = 0 //size of covered area, perpendicular to dir
|
||||
var/height = 0 //size of covered area, parallel to dir
|
||||
var/dwidth = 0 //position relative to covered area, perpendicular to dir
|
||||
var/dheight = 0 //position relative to covered area, parallel to dir
|
||||
///size of covered area, perpendicular to dir. You shouldn't modify this for mobile dockingports, set automatically.
|
||||
var/width = 0
|
||||
///size of covered area, parallel to dir. You shouldn't modify this for mobile dockingports, set automatically.
|
||||
var/height = 0
|
||||
///position relative to covered area, perpendicular to dir. You shouldn't modify this for mobile dockingports, set automatically.
|
||||
var/dwidth = 0
|
||||
///position relative to covered area, parallel to dir. You shouldn't modify this for mobile dockingports, set automatically.
|
||||
var/dheight = 0
|
||||
|
||||
var/area_type
|
||||
var/hidden = FALSE //are we invisible to shuttle navigation computers?
|
||||
///are we invisible to shuttle navigation computers?
|
||||
var/hidden = FALSE
|
||||
|
||||
|
||||
//these objects are indestructible
|
||||
/obj/docking_port/Destroy(force)
|
||||
@@ -243,18 +252,25 @@
|
||||
|
||||
var/list/shuttle_areas
|
||||
|
||||
var/timer //used as a timer (if you want time left to complete move, use timeLeft proc)
|
||||
///used as a timer (if you want time left to complete move, use timeLeft proc)
|
||||
var/timer
|
||||
var/last_timer_length
|
||||
///current shuttle mode
|
||||
var/mode = SHUTTLE_IDLE
|
||||
///time spent in transit (deciseconds). Should not be lower then 10 seconds without editing the animation of the hyperspace ripples.
|
||||
var/callTime = 100
|
||||
/// time spent "starting the engines". Also rate limits how often we try to reserve transit space if its ever full of transiting shuttles.
|
||||
var/ignitionTime = 55
|
||||
/// time spent after arrival before being able to begin ignition
|
||||
var/rechargeTime = 0
|
||||
/// time spent after transit 'landing' before actually arriving
|
||||
var/prearrivalTime = 0
|
||||
|
||||
var/mode = SHUTTLE_IDLE //current shuttle mode
|
||||
var/callTime = 100 //time spent in transit (deciseconds). Should not be lower then 10 seconds without editing the animation of the hyperspace ripples.
|
||||
var/ignitionTime = 55 // time spent "starting the engines". Also rate limits how often we try to reserve transit space if its ever full of transiting shuttles.
|
||||
var/rechargeTime = 0 // time spent after arrival before being able to begin ignition
|
||||
var/prearrivalTime = 0 // time spent after transit 'landing' before actually arriving
|
||||
|
||||
// The direction the shuttle prefers to travel in
|
||||
/// The direction the shuttle prefers to travel in, ie what direction
|
||||
/// the animation will cause it to appear to be traveling in
|
||||
var/preferred_direction = NORTH
|
||||
// And the angle from the front of the shuttle to the port
|
||||
/// relative direction of the docking port from the front of the shuttle
|
||||
/// NORTH is towards front, EAST would be starboard side, WEST port, etc.
|
||||
var/port_direction = NORTH
|
||||
|
||||
var/obj/docking_port/stationary/destination
|
||||
@@ -264,14 +280,16 @@
|
||||
|
||||
var/launch_status = NOLAUNCH
|
||||
|
||||
///Whether or not you want your ship to knock people down, and also whether it will throw them several tiles upon launching.
|
||||
var/list/movement_force = list("KNOCKDOWN" = 3, "THROW" = 0)
|
||||
|
||||
var/list/ripples = list()
|
||||
var/engine_coeff = 1 //current engine coeff
|
||||
var/current_engines = 0 //current engine power
|
||||
var/initial_engines = 0 //initial engine power
|
||||
var/engine_coeff = 1
|
||||
var/current_engines = 0
|
||||
var/initial_engines = 0
|
||||
var/list/engine_list = list()
|
||||
var/can_move_docking_ports = FALSE //if this shuttle can move docking ports other than the one it is docked at
|
||||
///if this shuttle can move docking ports other than the one it is docked at
|
||||
var/can_move_docking_ports = FALSE
|
||||
var/list/hidden_turfs = list()
|
||||
|
||||
/obj/docking_port/mobile/proc/register()
|
||||
|
||||
@@ -1,9 +1,27 @@
|
||||
/**
|
||||
* Get the organ object from the mob matching the passed in typepath
|
||||
*
|
||||
* Arguments:
|
||||
* * typepath The typepath of the organ to get
|
||||
*/
|
||||
/mob/proc/getorgan(typepath)
|
||||
return
|
||||
|
||||
/**
|
||||
* Get organ objects by zone
|
||||
*
|
||||
* This will return a list of all the organs that are relevant to the zone that is passedin
|
||||
*
|
||||
* Arguments:
|
||||
* * zone [a BODY_ZONE_X define](https://github.com/tgstation/tgstation/blob/master/code/__DEFINES/combat.dm#L187-L200)
|
||||
*/
|
||||
/mob/proc/getorganszone(zone)
|
||||
return
|
||||
|
||||
/**
|
||||
* Get an organ relating to a specific slot
|
||||
*
|
||||
* Arguments:
|
||||
* * slot Slot to get the organ from
|
||||
*/
|
||||
/mob/proc/getorganslot(slot)
|
||||
return
|
||||
|
||||
|
||||
@@ -15,17 +15,31 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
|
||||
*/
|
||||
|
||||
#define MAX_VENDING_INPUT_AMOUNT 30
|
||||
|
||||
/**
|
||||
* # vending record datum
|
||||
*
|
||||
* A datum that represents a product that is vendable
|
||||
*/
|
||||
/datum/data/vending_product
|
||||
name = "generic"
|
||||
///Typepath of the product that is created when this record "sells"
|
||||
var/product_path = null
|
||||
///How many of this product we currently have
|
||||
var/amount = 0
|
||||
///How many we can store at maximum
|
||||
var/max_amount = 0
|
||||
///Does the item have a custom price override
|
||||
var/custom_price
|
||||
///Does the item have a custom premium price override
|
||||
var/custom_premium_price
|
||||
///Whether spessmen with an ID with an age below AGE_MINOR (21 by default) can buy this item
|
||||
var/age_restricted = FALSE
|
||||
|
||||
/**
|
||||
* # vending machines
|
||||
*
|
||||
* Captalism in the year 2525, everything in a vending machine, even love
|
||||
*/
|
||||
/obj/machinery/vending
|
||||
name = "\improper Vendomat"
|
||||
desc = "A generic vending machine."
|
||||
@@ -41,56 +55,115 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
|
||||
armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70)
|
||||
circuit = /obj/item/circuitboard/machine/vendor
|
||||
payment_department = ACCOUNT_SRV
|
||||
var/active = 1 //No sales pitches if off!
|
||||
var/vend_ready = 1 //Are we ready to vend?? Is it time??
|
||||
/// Is the machine active (No sales pitches if off)!
|
||||
var/active = 1
|
||||
///Are we ready to vend?? Is it time??
|
||||
var/vend_ready = 1
|
||||
///Next world time to send a purchase message
|
||||
var/purchase_message_cooldown
|
||||
///Last mob to shop with us
|
||||
var/last_shopper
|
||||
|
||||
// To be filled out at compile time
|
||||
var/list/products = list() //For each, use the following pattern:
|
||||
var/list/contraband = list() //list(/type/path = amount, /type/path2 = amount2)
|
||||
var/list/premium = list() //No specified amount = only one in stock
|
||||
|
||||
/**
|
||||
* List of products this machine sells
|
||||
*
|
||||
* form should be list(/type/path = amount, /type/path2 = amount2)
|
||||
*/
|
||||
var/list/products = list()
|
||||
|
||||
/**
|
||||
* List of products this machine sells when you hack it
|
||||
*
|
||||
* form should be list(/type/path = amount, /type/path2 = amount2)
|
||||
*/
|
||||
var/list/contraband = list()
|
||||
|
||||
/**
|
||||
* List of premium products this machine sells
|
||||
*
|
||||
* form should be list(/type/path, /type/path2) as there is only ever one in stock
|
||||
*/
|
||||
var/list/premium = list()
|
||||
|
||||
///String of slogans separated by semicolons, optional
|
||||
var/product_slogans = ""
|
||||
///String of small ad messages in the vending screen - random chance
|
||||
var/product_ads = ""
|
||||
|
||||
var/product_slogans = "" //String of slogans separated by semicolons, optional
|
||||
var/product_ads = "" //String of small ad messages in the vending screen - random chance
|
||||
var/list/product_records = list()
|
||||
var/list/hidden_records = list()
|
||||
var/list/coin_records = list()
|
||||
var/list/slogan_list = list()
|
||||
var/list/small_ads = list() //Small ad messages in the vending screen - random chance of popping up whenever you open it
|
||||
var/vend_reply //Thank you for shopping!
|
||||
///Small ad messages in the vending screen - random chance of popping up whenever you open it
|
||||
var/list/small_ads = list()
|
||||
///Message sent post vend (Thank you for shopping!)
|
||||
var/vend_reply
|
||||
///Last world tick we sent a vent reply
|
||||
var/last_reply = 0
|
||||
var/last_slogan = 0 //When did we last pitch?
|
||||
var/slogan_delay = 6000 //How long until we can pitch again?
|
||||
var/icon_vend //Icon_state when vending!
|
||||
var/icon_deny //Icon_state when vending!
|
||||
var/seconds_electrified = MACHINE_NOT_ELECTRIFIED //Shock customers like an airlock.
|
||||
var/shoot_inventory = 0 //Fire items at customers! We're broken!
|
||||
///Last world tick we sent a slogan message out
|
||||
var/last_slogan = 0
|
||||
///How many ticks until we can send another
|
||||
var/slogan_delay = 6000
|
||||
///Icon when vending an item to the user
|
||||
var/icon_vend
|
||||
///Icon to flash when user is denied a vend
|
||||
var/icon_deny
|
||||
///World ticks the machine is electified for
|
||||
var/seconds_electrified = MACHINE_NOT_ELECTRIFIED
|
||||
///When this is TRUE, we fire items at customers! We're broken!
|
||||
var/shoot_inventory = 0
|
||||
///How likely this is to happen (prob 100)
|
||||
var/shoot_inventory_chance = 2
|
||||
var/shut_up = 0 //Stop spouting those godawful pitches!
|
||||
var/extended_inventory = 0 //can we access the hidden inventory?
|
||||
//Stop spouting those godawful pitches!
|
||||
var/shut_up = 0
|
||||
///can we access the hidden inventory?
|
||||
var/extended_inventory = 0
|
||||
///Are we checking the users ID
|
||||
var/scan_id = 1
|
||||
///Coins that we accept?
|
||||
var/obj/item/coin/coin
|
||||
///Bills we accept?
|
||||
var/obj/item/stack/spacecash/bill
|
||||
var/chef_price = 10
|
||||
///Default price of items if not overridden
|
||||
var/default_price = 25
|
||||
///Default price of premium items if not overridden
|
||||
var/extra_price = 50
|
||||
///Whether our age check is currently functional
|
||||
var/age_restrictions = TRUE
|
||||
var/onstation = TRUE //if it doesn't originate from off-station during mapload, everything is free
|
||||
/**
|
||||
* Is this item on station or not
|
||||
*
|
||||
* if it doesn't originate from off-station during mapload, everything is free
|
||||
*/
|
||||
var/onstation = TRUE
|
||||
///ID's that can load this vending machine wtih refills
|
||||
var/list/canload_access_list
|
||||
|
||||
var/list/vending_machine_input = list()
|
||||
///Display header on the input view
|
||||
var/input_display_header = "Custom Compartment"
|
||||
|
||||
var/obj/item/vending_refill/refill_canister = null //The type of refill canisters used by this machine.
|
||||
//The type of refill canisters used by this machine.
|
||||
var/obj/item/vending_refill/refill_canister = null
|
||||
|
||||
/// used for narcing on underages
|
||||
var/obj/item/radio/alertradio
|
||||
|
||||
/obj/item/circuitboard
|
||||
var/onstation = TRUE //if the circuit board originated from a vendor off station or not.
|
||||
///determines if the circuit board originated from a vendor off station or not.
|
||||
var/onstation = TRUE
|
||||
|
||||
/**
|
||||
* Initialize the vending machine
|
||||
*
|
||||
* Builds the vending machine inventory, sets up slogans and other such misc work
|
||||
*
|
||||
* This also sets the onstation var to:
|
||||
* * FALSE - if the machine was maploaded on a zlevel that doesn't pass the is_station_level check
|
||||
* * TRUE - all other cases
|
||||
*/
|
||||
/obj/machinery/vending/Initialize(mapload)
|
||||
var/build_inv = FALSE
|
||||
if(!refill_canister)
|
||||
@@ -192,7 +265,15 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
|
||||
return
|
||||
|
||||
GLOBAL_LIST_EMPTY(vending_products)
|
||||
|
||||
/**
|
||||
* Build the inventory of the vending machine from it's product and record lists
|
||||
*
|
||||
* This builds up a full set of /datum/data/vending_products from the product list of the vending machine type
|
||||
* Arguments:
|
||||
* * productlist - the list of products that need to be converted
|
||||
* * recordlist - the list containing /datum/data/vending_product datums
|
||||
* * startempty - should we set vending_product record amount from the product list (so it's prefilled at roundstart)
|
||||
*/
|
||||
/obj/machinery/vending/proc/build_inventory(list/productlist, list/recordlist, start_empty = FALSE)
|
||||
for(var/typepath in productlist)
|
||||
var/amount = productlist[typepath]
|
||||
@@ -211,7 +292,14 @@ GLOBAL_LIST_EMPTY(vending_products)
|
||||
R.custom_premium_price = initial(temp.custom_premium_price)
|
||||
R.age_restricted = initial(temp.age_restricted)
|
||||
recordlist += R
|
||||
|
||||
/**
|
||||
* Refill a vending machine from a refill canister
|
||||
*
|
||||
* This takes the products from the refill canister and then fills the products,contraband and premium product categories
|
||||
*
|
||||
* Arguments:
|
||||
* * canister - the vending canister we are refilling from
|
||||
*/
|
||||
/obj/machinery/vending/proc/restock(obj/item/vending_refill/canister)
|
||||
if (!canister.products)
|
||||
canister.products = products.Copy()
|
||||
@@ -223,7 +311,13 @@ GLOBAL_LIST_EMPTY(vending_products)
|
||||
. += refill_inventory(canister.products, product_records)
|
||||
. += refill_inventory(canister.contraband, hidden_records)
|
||||
. += refill_inventory(canister.premium, coin_records)
|
||||
|
||||
/**
|
||||
* Refill our inventory from the passed in product list into the record list
|
||||
*
|
||||
* Arguments:
|
||||
* * productlist - list of types -> amount
|
||||
* * recordlist - existing record datums
|
||||
*/
|
||||
/obj/machinery/vending/proc/refill_inventory(list/productlist, list/recordlist)
|
||||
. = 0
|
||||
for(var/R in recordlist)
|
||||
@@ -233,7 +327,11 @@ GLOBAL_LIST_EMPTY(vending_products)
|
||||
productlist[record.product_path] -= diff
|
||||
record.amount += diff
|
||||
. += diff
|
||||
|
||||
/**
|
||||
* Set up a refill canister that matches this machines products
|
||||
*
|
||||
* This is used when the machine is deconstructed, so the items aren't "lost"
|
||||
*/
|
||||
/obj/machinery/vending/proc/update_canister()
|
||||
if (!component_parts)
|
||||
return
|
||||
@@ -246,6 +344,9 @@ GLOBAL_LIST_EMPTY(vending_products)
|
||||
R.contraband = unbuild_inventory(hidden_records)
|
||||
R.premium = unbuild_inventory(coin_records)
|
||||
|
||||
/**
|
||||
* Given a record list, go through and and return a list of type -> amount
|
||||
*/
|
||||
/obj/machinery/vending/proc/unbuild_inventory(list/recordlist)
|
||||
. = list()
|
||||
for(var/R in recordlist)
|
||||
@@ -555,7 +656,14 @@ GLOBAL_LIST_EMPTY(vending_products)
|
||||
|
||||
if(shoot_inventory && prob(shoot_inventory_chance))
|
||||
throw_item()
|
||||
|
||||
/**
|
||||
* Speak the given message verbally
|
||||
*
|
||||
* Checks if the machine is powered and the message exists
|
||||
*
|
||||
* Arguments:
|
||||
* * message - the message to speak
|
||||
*/
|
||||
/obj/machinery/vending/proc/speak(message)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
@@ -577,6 +685,12 @@ GLOBAL_LIST_EMPTY(vending_products)
|
||||
update_icon()
|
||||
|
||||
//Somebody cut an important wire and now we're following a new definition of "pitch."
|
||||
/**
|
||||
* Throw an item from our internal inventory out in front of us
|
||||
*
|
||||
* This is called when we are hacked, it selects a random product from the records that has an amount > 0
|
||||
* This item is then created and tossed out in front of us with a visible message
|
||||
*/
|
||||
/obj/machinery/vending/proc/throw_item()
|
||||
var/obj/throw_item = null
|
||||
var/mob/living/target = locate() in view(7,src)
|
||||
@@ -601,10 +715,26 @@ GLOBAL_LIST_EMPTY(vending_products)
|
||||
throw_item.throw_at(target, 16, 3)
|
||||
visible_message("<span class='danger'>[src] launches [throw_item] at [target]!</span>")
|
||||
return 1
|
||||
|
||||
/**
|
||||
* A callback called before an item is tossed out
|
||||
*
|
||||
* Override this if you need to do any special case handling
|
||||
*
|
||||
* Arguments:
|
||||
* * I - obj/item being thrown
|
||||
*/
|
||||
/obj/machinery/vending/proc/pre_throw(obj/item/I)
|
||||
return
|
||||
|
||||
/**
|
||||
* Shock the passed in user
|
||||
*
|
||||
* This checks we have power and that the passed in prob is passed, then generates some sparks
|
||||
* and calls electrocute_mob on the user
|
||||
*
|
||||
* Arguments:
|
||||
* * user - the user to shock
|
||||
* * prb - probability the shock happens
|
||||
*/
|
||||
/obj/machinery/vending/proc/shock(mob/user, prb)
|
||||
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
|
||||
return FALSE
|
||||
@@ -616,10 +746,21 @@ GLOBAL_LIST_EMPTY(vending_products)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Are we able to load the item passed in
|
||||
*
|
||||
* Arguments:
|
||||
* * I - the item being loaded
|
||||
* * user - the user doing the loading
|
||||
*/
|
||||
/obj/machinery/vending/proc/canLoadItem(obj/item/I,mob/user)
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Is the passed in user allowed to load this vending machines compartments
|
||||
*
|
||||
* Arguments:
|
||||
* * user - mob that is doing the loading of the vending machine
|
||||
*/
|
||||
/obj/machinery/vending/proc/compartmentLoadAccessCheck(mob/user)
|
||||
if(!canload_access_list)
|
||||
return TRUE
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
//This file is just for the necessary /world definition
|
||||
//Try looking in game/world.dm
|
||||
|
||||
/**
|
||||
* # World
|
||||
*
|
||||
* Two possibilities exist: either we are alone in the Universe or we are not. Both are equally terrifying. ~ Arthur C. Clarke
|
||||
*
|
||||
* The byond world object stores some basic byond level config, and has a few hub specific procs for managing hub visiblity
|
||||
*
|
||||
* The world /New() is the root of where a round itself begins
|
||||
*/
|
||||
/world
|
||||
mob = /mob/dead/new_player
|
||||
turf = /turf/open/space/basic
|
||||
|
||||
Reference in New Issue
Block a user