Revert "Merge branch 'punishesarchie' of https://github.com/MalricB/Hyper-Station-13 into punishesarchie"

This reverts commit 1945c166b4, reversing
changes made to c8d20ea83c.
This commit is contained in:
CygnusB
2021-01-19 06:40:28 -03:00
parent 1945c166b4
commit 8cda8bbd16
1465 changed files with 202589 additions and 377073 deletions
-6
View File
@@ -70,14 +70,9 @@
#define ADMIN_PUNISHMENT_FIREBALL "Fireball"
#define ADMIN_PUNISHMENT_CLUWNE "Floor Cluwne"
#define ADMIN_PUNISHMENT_ROD "Immovable Rod"
#define ADMIN_PUNISHMENT_SUPPLYPOD_QUICK "Supply Pod (Quick)"
#define ADMIN_PUNISHMENT_SUPPLYPOD "Supply Pod"
#define ADMIN_PUNISHMENT_MAZING "Puzzle"
#define ADMIN_PUNISHMENT_PIE "Cream Pie"
#define ADMIN_PUNISHMENT_TABLETIDESTATIONWIDE "Tabletide Stationwide"
#define ADMIN_PUNISHMENT_FAKEBWOINK "Fake Bwoink"
#define ADMIN_PUNISHMENT_NUGGET "Nugget"
#define ADMIN_PUNISHMENT_BREADIFY ":b:read"
#define AHELP_ACTIVE 1
#define AHELP_CLOSED 2
@@ -94,4 +89,3 @@
#define MAX_KEYPRESS_AUTOKICK 100
///Length of held key rolling buffer
#define HELD_KEY_BUFFER_LENGTH 15
-17
View File
@@ -40,20 +40,3 @@
#define NOT_DOMINATING -1
#define MAX_LEADERS_GANG 3
#define INITIAL_DOM_ATTEMPTS 3
//Bloodsucker defines
// Bloodsucker related antag datums
#define ANTAG_DATUM_BLOODSUCKER /datum/antagonist/bloodsucker
#define ANTAG_DATUM_VASSAL /datum/antagonist/vassal
//#define ANTAG_DATUM_HUNTER /datum/antagonist/vamphunter Disabled for now
// BLOODSUCKER
#define BLOODSUCKER_LEVEL_TO_EMBRACE 3
#define BLOODSUCKER_FRENZY_TIME 25 // How long the vamp stays in frenzy.
#define BLOODSUCKER_FRENZY_OUT_TIME 300 // How long the vamp goes back into frenzy.
#define BLOODSUCKER_STARVE_VOLUME 5 // Amount of blood, below which a Vamp is at risk of frenzy.
#define CAT_STRUCTURE "Structures"
#define MARTIALART_HUNTER "hunter-fu"
+298 -316
View File
@@ -1,316 +1,298 @@
//LISTMOS
//indices of values in gas lists.
#define META_GAS_SPECIFIC_HEAT 1
#define META_GAS_NAME 2
#define META_GAS_MOLES_VISIBLE 3
#define META_GAS_OVERLAY 4
#define META_GAS_DANGER 5
#define META_GAS_ID 6
#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
#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
//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
#define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION (T20C+10)
#define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION (T20C+200)
//HEAT TRANSFER COEFFICIENTS
//Must be between 0 and 1. Values closer to 1 equalize temperature faster
//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
//FIRE
#define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD (150+T0C)
#define FIRE_MINIMUM_TEMPERATURE_TO_EXIST (100+T0C)
#define FIRE_SPREAD_RADIOSITY_SCALE 0.85
#define FIRE_GROWTH_RATE 40000 //For small fires
#define PLASMA_MINIMUM_BURN_TEMPERATURE (100+T0C)
#define PLASMA_UPPER_TEMPERATURE (1370+T0C)
#define PLASMA_OXYGEN_FULLBURN 10
//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
#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
//REACTIONS
//return values for reactions (bitflags)
#define NO_REACTION 0
#define REACTING 1
#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)
#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.
#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.
#define BODYTEMP_HEAT_DAMAGE_LIMIT (BODYTEMP_NORMAL + 20) // The limit the human body can take before it starts taking damage from heat. //CITADEL EDIT to 20
#define BODYTEMP_COLD_DAMAGE_LIMIT (BODYTEMP_NORMAL - 50) // The limit the human body can take before it starts taking damage from coldness.
#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.
#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)
#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.
#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
#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
#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
#define MAX_HIGH_PRESSURE_DAMAGE 16 // CITADEL CHANGES Max to 16, low to 8.
#define LOW_PRESSURE_DAMAGE 8 //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 COLD_SLOWDOWN_FACTOR 20 //Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this
//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.05 //5% of an overclocked volume pump leaks into the air
#define VOLUME_PUMP_THRESHOLD_LEAK_AMOUNT 0.10 //10% of an overclocked volume pump leaks into the air if it goes beyond normal threshold
//used for device_type vars
#define UNARY 1
#define BINARY 2
#define TRINARY 3
#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
#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3)
#define TANK_MIN_RELEASE_PRESSURE 0
#define TANK_DEFAULT_RELEASE_PRESSURE 16
//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
#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,15degC telecommunications. also used for xenobiology slime killrooms
#define AIRLESS_ATMOS "TEMP=2.7" //space
#define FROZEN_ATMOS "o2=22;n2=82;TEMP=180" //-93.15degC snow and ice turfs
#define BURNMIX_ATMOS "o2=2500;plasma=5000;TEMP=370" //used in the holodeck burn test program
//ATMOSPHERICS DEPARTMENT GAS TANK TURFS
#define ATMOS_TANK_N2O "n2o=6000;TEMP=293.15"
#define ATMOS_TANK_CO2 "co2=50000;TEMP=293.15"
#define ATMOS_TANK_PLASMA "plasma=70000;TEMP=293.15"
#define ATMOS_TANK_O2 "o2=100000;TEMP=293.15"
#define ATMOS_TANK_N2 "n2=100000;TEMP=293.15"
#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
#define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300"
//ATMOSIA GAS MONITOR TAGS
#define ATMOS_GAS_MONITOR_INPUT_O2 "o2_in"
#define ATMOS_GAS_MONITOR_OUTPUT_O2 "o2_out"
#define ATMOS_GAS_MONITOR_SENSOR_O2 "o2_sensor"
#define ATMOS_GAS_MONITOR_INPUT_TOX "tox_in"
#define ATMOS_GAS_MONITOR_OUTPUT_TOX "tox_out"
#define ATMOS_GAS_MONITOR_SENSOR_TOX "tox_sensor"
#define ATMOS_GAS_MONITOR_INPUT_AIR "air_in"
#define ATMOS_GAS_MONITOR_OUTPUT_AIR "air_out"
#define ATMOS_GAS_MONITOR_SENSOR_AIR "air_sensor"
#define ATMOS_GAS_MONITOR_INPUT_MIX "mix_in"
#define ATMOS_GAS_MONITOR_OUTPUT_MIX "mix_out"
#define ATMOS_GAS_MONITOR_SENSOR_MIX "mix_sensor"
#define ATMOS_GAS_MONITOR_INPUT_N2O "n2o_in"
#define ATMOS_GAS_MONITOR_OUTPUT_N2O "n2o_out"
#define ATMOS_GAS_MONITOR_SENSOR_N2O "n2o_sensor"
#define ATMOS_GAS_MONITOR_INPUT_N2 "n2_in"
#define ATMOS_GAS_MONITOR_OUTPUT_N2 "n2_out"
#define ATMOS_GAS_MONITOR_SENSOR_N2 "n2_sensor"
#define ATMOS_GAS_MONITOR_INPUT_CO2 "co2_in"
#define ATMOS_GAS_MONITOR_OUTPUT_CO2 "co2_out"
#define ATMOS_GAS_MONITOR_SENSOR_CO2 "co2_sensor"
#define ATMOS_GAS_MONITOR_INPUT_INCINERATOR "incinerator_in"
#define ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR "incinerator_out"
#define ATMOS_GAS_MONITOR_SENSOR_INCINERATOR "incinerator_sensor"
#define ATMOS_GAS_MONITOR_INPUT_TOXINS_LAB "toxinslab_in"
#define ATMOS_GAS_MONITOR_OUTPUT_TOXINS_LAB "toxinslab_out"
#define ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB "toxinslab_sensor"
#define ATMOS_GAS_MONITOR_LOOP_DISTRIBUTION "distro-loop_meter"
#define ATMOS_GAS_MONITOR_LOOP_ATMOS_WASTE "atmos-waste_loop_meter"
#define ATMOS_GAS_MONITOR_WASTE_ENGINE "engine-waste_out"
#define ATMOS_GAS_MONITOR_WASTE_ATMOS "atmos-waste_out"
//AIRLOCK CONTROLLER TAGS
//RnD toxins burn chamber
#define INCINERATOR_TOXMIX_IGNITER "toxmix_igniter"
#define INCINERATOR_TOXMIX_VENT "toxmix_vent"
#define INCINERATOR_TOXMIX_DP_VENTPUMP "toxmix_airlock_pump"
#define INCINERATOR_TOXMIX_AIRLOCK_SENSOR "toxmix_airlock_sensor"
#define INCINERATOR_TOXMIX_AIRLOCK_CONTROLLER "toxmix_airlock_controller"
#define INCINERATOR_TOXMIX_AIRLOCK_INTERIOR "toxmix_airlock_interior"
#define INCINERATOR_TOXMIX_AIRLOCK_EXTERIOR "toxmix_airlock_exterior"
//Atmospherics/maintenance incinerator
#define INCINERATOR_ATMOS_IGNITER "atmos_incinerator_igniter"
#define INCINERATOR_ATMOS_MAINVENT "atmos_incinerator_mainvent"
#define INCINERATOR_ATMOS_AUXVENT "atmos_incinerator_auxvent"
#define INCINERATOR_ATMOS_DP_VENTPUMP "atmos_incinerator_airlock_pump"
#define INCINERATOR_ATMOS_AIRLOCK_SENSOR "atmos_incinerator_airlock_sensor"
#define INCINERATOR_ATMOS_AIRLOCK_CONTROLLER "atmos_incinerator_airlock_controller"
#define INCINERATOR_ATMOS_AIRLOCK_INTERIOR "atmos_incinerator_airlock_interior"
#define INCINERATOR_ATMOS_AIRLOCK_EXTERIOR "atmos_incinerator_airlock_exterior"
//Syndicate lavaland base incinerator (lavaland_surface_syndicate_base1.dmm)
#define INCINERATOR_SYNDICATELAVA_IGNITER "syndicatelava_igniter"
#define INCINERATOR_SYNDICATELAVA_MAINVENT "syndicatelava_mainvent"
#define INCINERATOR_SYNDICATELAVA_AUXVENT "syndicatelava_auxvent"
#define INCINERATOR_SYNDICATELAVA_DP_VENTPUMP "syndicatelava_airlock_pump"
#define INCINERATOR_SYNDICATELAVA_AIRLOCK_SENSOR "syndicatelava_airlock_sensor"
#define INCINERATOR_SYNDICATELAVA_AIRLOCK_CONTROLLER "syndicatelava_airlock_controller"
#define INCINERATOR_SYNDICATELAVA_AIRLOCK_INTERIOR "syndicatelava_airlock_interior"
#define INCINERATOR_SYNDICATELAVA_AIRLOCK_EXTERIOR "syndicatelava_airlock_exterior"
//MULTIPIPES
//IF YOU EVER CHANGE THESE CHANGE SPRITES TO MATCH.
#define PIPING_LAYER_MIN 1
#define PIPING_LAYER_MAX 3
#define PIPING_LAYER_DEFAULT 2
#define PIPING_LAYER_P_X 5
#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.
//HELPERS
#define PIPING_LAYER_SHIFT(T, PipingLayer) \
if(T.dir & NORTH || T.dir & SOUTH) { \
T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\
} \
if(T.dir & WEST || T.dir & EAST) { \
T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;\
}
#define PIPING_LAYER_DOUBLE_SHIFT(T, PipingLayer) \
T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\
T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
//prefer this to gas_mixture/total_moles in performance critical areas
#define TOTAL_MOLES(cached_gases, out_var)\
out_var = 0;\
for(var/total_moles_id in cached_gases){\
out_var += cached_gases[total_moles_id];\
}
#ifdef TESTING
GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
#define CALCULATE_ADJACENT_TURFS(T) if (SSadjacent_air.queue[T]) { GLOB.atmos_adjacent_savings[1] += 1 } else { GLOB.atmos_adjacent_savings[2] += 1; SSadjacent_air.queue[T] = 1 }
#else
#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
#endif
//Unomos - So for whatever reason, garbage collection actually drastically decreases the cost of atmos later in the round. Turning this into a define yields massively improved performance.
#define GAS_GARBAGE_COLLECT(GASGASGAS)\
var/list/CACHE_GAS = GASGASGAS;\
for(var/id in CACHE_GAS){\
if(QUANTIZE(CACHE_GAS[id]) <= 0)\
CACHE_GAS -= id;\
}
#define ARCHIVE_TEMPERATURE(gas) gas.temperature_archived = gas.temperature
GLOBAL_LIST_INIT(pipe_paint_colors, list(
"amethyst" = rgb(130,43,255), //supplymain
"blue" = rgb(0,0,255),
"brown" = rgb(178,100,56),
"cyan" = rgb(0,255,249),
"dark" = rgb(69,69,69),
"green" = rgb(30,255,0),
"grey" = rgb(255,255,255),
"orange" = rgb(255,129,25),
"purple" = rgb(128,0,182),
"red" = rgb(255,0,0),
"violet" = rgb(64,0,128),
"yellow" = rgb(255,198,0)
))
#define MIASMA_CORPSE_MOLES 0.02
#define MIASMA_GIBS_MOLES 0.005
//LISTMOS
//indices of values in gas lists.
#define META_GAS_SPECIFIC_HEAT 1
#define META_GAS_NAME 2
#define META_GAS_MOLES_VISIBLE 3
#define META_GAS_OVERLAY 4
#define META_GAS_DANGER 5
#define META_GAS_ID 6
#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
#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
//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
#define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION (T20C+10)
#define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION (T20C+200)
//HEAT TRANSFER COEFFICIENTS
//Must be between 0 and 1. Values closer to 1 equalize temperature faster
//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
//FIRE
#define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD (150+T0C)
#define FIRE_MINIMUM_TEMPERATURE_TO_EXIST (100+T0C)
#define FIRE_SPREAD_RADIOSITY_SCALE 0.85
#define FIRE_GROWTH_RATE 40000 //For small fires
#define PLASMA_MINIMUM_BURN_TEMPERATURE (100+T0C)
#define PLASMA_UPPER_TEMPERATURE (1370+T0C)
#define PLASMA_OXYGEN_FULLBURN 10
//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
#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
//REACTIONS
//return values for reactions (bitflags)
#define NO_REACTION 0
#define REACTING 1
#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)
#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.
#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.
#define BODYTEMP_HEAT_DAMAGE_LIMIT (BODYTEMP_NORMAL + 20) // The limit the human body can take before it starts taking damage from heat. //CITADEL EDIT to 20
#define BODYTEMP_COLD_DAMAGE_LIMIT (BODYTEMP_NORMAL - 50) // The limit the human body can take before it starts taking damage from coldness.
#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.
#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)
#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.
#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
#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
#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
#define MAX_HIGH_PRESSURE_DAMAGE 16 // CITADEL CHANGES Max to 16, low to 8.
#define LOW_PRESSURE_DAMAGE 8 //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 COLD_SLOWDOWN_FACTOR 20 //Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this
//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.05 //5% of an overclocked volume pump leaks into the air
#define VOLUME_PUMP_THRESHOLD_LEAK_AMOUNT 0.10 //10% of an overclocked volume pump leaks into the air if it goes beyond normal threshold
//used for device_type vars
#define UNARY 1
#define BINARY 2
#define TRINARY 3
#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
#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3)
#define TANK_MIN_RELEASE_PRESSURE 0
#define TANK_DEFAULT_RELEASE_PRESSURE 16
//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
#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 ) )
//LAVALAND
#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
#define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300"
//ATMOSIA GAS MONITOR TAGS
#define ATMOS_GAS_MONITOR_INPUT_O2 "o2_in"
#define ATMOS_GAS_MONITOR_OUTPUT_O2 "o2_out"
#define ATMOS_GAS_MONITOR_SENSOR_O2 "o2_sensor"
#define ATMOS_GAS_MONITOR_INPUT_TOX "tox_in"
#define ATMOS_GAS_MONITOR_OUTPUT_TOX "tox_out"
#define ATMOS_GAS_MONITOR_SENSOR_TOX "tox_sensor"
#define ATMOS_GAS_MONITOR_INPUT_AIR "air_in"
#define ATMOS_GAS_MONITOR_OUTPUT_AIR "air_out"
#define ATMOS_GAS_MONITOR_SENSOR_AIR "air_sensor"
#define ATMOS_GAS_MONITOR_INPUT_MIX "mix_in"
#define ATMOS_GAS_MONITOR_OUTPUT_MIX "mix_out"
#define ATMOS_GAS_MONITOR_SENSOR_MIX "mix_sensor"
#define ATMOS_GAS_MONITOR_INPUT_N2O "n2o_in"
#define ATMOS_GAS_MONITOR_OUTPUT_N2O "n2o_out"
#define ATMOS_GAS_MONITOR_SENSOR_N2O "n2o_sensor"
#define ATMOS_GAS_MONITOR_INPUT_N2 "n2_in"
#define ATMOS_GAS_MONITOR_OUTPUT_N2 "n2_out"
#define ATMOS_GAS_MONITOR_SENSOR_N2 "n2_sensor"
#define ATMOS_GAS_MONITOR_INPUT_CO2 "co2_in"
#define ATMOS_GAS_MONITOR_OUTPUT_CO2 "co2_out"
#define ATMOS_GAS_MONITOR_SENSOR_CO2 "co2_sensor"
#define ATMOS_GAS_MONITOR_INPUT_INCINERATOR "incinerator_in"
#define ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR "incinerator_out"
#define ATMOS_GAS_MONITOR_SENSOR_INCINERATOR "incinerator_sensor"
#define ATMOS_GAS_MONITOR_INPUT_TOXINS_LAB "toxinslab_in"
#define ATMOS_GAS_MONITOR_OUTPUT_TOXINS_LAB "toxinslab_out"
#define ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB "toxinslab_sensor"
#define ATMOS_GAS_MONITOR_LOOP_DISTRIBUTION "distro-loop_meter"
#define ATMOS_GAS_MONITOR_LOOP_ATMOS_WASTE "atmos-waste_loop_meter"
#define ATMOS_GAS_MONITOR_WASTE_ENGINE "engine-waste_out"
#define ATMOS_GAS_MONITOR_WASTE_ATMOS "atmos-waste_out"
//AIRLOCK CONTROLLER TAGS
//RnD toxins burn chamber
#define INCINERATOR_TOXMIX_IGNITER "toxmix_igniter"
#define INCINERATOR_TOXMIX_VENT "toxmix_vent"
#define INCINERATOR_TOXMIX_DP_VENTPUMP "toxmix_airlock_pump"
#define INCINERATOR_TOXMIX_AIRLOCK_SENSOR "toxmix_airlock_sensor"
#define INCINERATOR_TOXMIX_AIRLOCK_CONTROLLER "toxmix_airlock_controller"
#define INCINERATOR_TOXMIX_AIRLOCK_INTERIOR "toxmix_airlock_interior"
#define INCINERATOR_TOXMIX_AIRLOCK_EXTERIOR "toxmix_airlock_exterior"
//Atmospherics/maintenance incinerator
#define INCINERATOR_ATMOS_IGNITER "atmos_incinerator_igniter"
#define INCINERATOR_ATMOS_MAINVENT "atmos_incinerator_mainvent"
#define INCINERATOR_ATMOS_AUXVENT "atmos_incinerator_auxvent"
#define INCINERATOR_ATMOS_DP_VENTPUMP "atmos_incinerator_airlock_pump"
#define INCINERATOR_ATMOS_AIRLOCK_SENSOR "atmos_incinerator_airlock_sensor"
#define INCINERATOR_ATMOS_AIRLOCK_CONTROLLER "atmos_incinerator_airlock_controller"
#define INCINERATOR_ATMOS_AIRLOCK_INTERIOR "atmos_incinerator_airlock_interior"
#define INCINERATOR_ATMOS_AIRLOCK_EXTERIOR "atmos_incinerator_airlock_exterior"
//Syndicate lavaland base incinerator (lavaland_surface_syndicate_base1.dmm)
#define INCINERATOR_SYNDICATELAVA_IGNITER "syndicatelava_igniter"
#define INCINERATOR_SYNDICATELAVA_MAINVENT "syndicatelava_mainvent"
#define INCINERATOR_SYNDICATELAVA_AUXVENT "syndicatelava_auxvent"
#define INCINERATOR_SYNDICATELAVA_DP_VENTPUMP "syndicatelava_airlock_pump"
#define INCINERATOR_SYNDICATELAVA_AIRLOCK_SENSOR "syndicatelava_airlock_sensor"
#define INCINERATOR_SYNDICATELAVA_AIRLOCK_CONTROLLER "syndicatelava_airlock_controller"
#define INCINERATOR_SYNDICATELAVA_AIRLOCK_INTERIOR "syndicatelava_airlock_interior"
#define INCINERATOR_SYNDICATELAVA_AIRLOCK_EXTERIOR "syndicatelava_airlock_exterior"
//MULTIPIPES
//IF YOU EVER CHANGE THESE CHANGE SPRITES TO MATCH.
#define PIPING_LAYER_MIN 1
#define PIPING_LAYER_MAX 3
#define PIPING_LAYER_DEFAULT 2
#define PIPING_LAYER_P_X 5
#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.
//HELPERS
#define PIPING_LAYER_SHIFT(T, PipingLayer) \
if(T.dir & NORTH || T.dir & SOUTH) { \
T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\
} \
if(T.dir & WEST || T.dir & EAST) { \
T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;\
}
#define PIPING_LAYER_DOUBLE_SHIFT(T, PipingLayer) \
T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\
T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
//prefer this to gas_mixture/total_moles in performance critical areas
#define TOTAL_MOLES(cached_gases, out_var)\
out_var = 0;\
for(var/total_moles_id in cached_gases){\
out_var += cached_gases[total_moles_id];\
}
#ifdef TESTING
GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
#define CALCULATE_ADJACENT_TURFS(T) if (SSadjacent_air.queue[T]) { GLOB.atmos_adjacent_savings[1] += 1 } else { GLOB.atmos_adjacent_savings[2] += 1; SSadjacent_air.queue[T] = 1 }
#else
#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
#endif
//Unomos - So for whatever reason, garbage collection actually drastically decreases the cost of atmos later in the round. Turning this into a define yields massively improved performance.
#define GAS_GARBAGE_COLLECT(GASGASGAS)\
var/list/CACHE_GAS = GASGASGAS;\
for(var/id in CACHE_GAS){\
if(QUANTIZE(CACHE_GAS[id]) <= 0)\
CACHE_GAS -= id;\
}
#define ARCHIVE_TEMPERATURE(gas) gas.temperature_archived = gas.temperature
GLOBAL_LIST_INIT(pipe_paint_colors, list(
"amethyst" = rgb(130,43,255), //supplymain
"blue" = rgb(0,0,255),
"brown" = rgb(178,100,56),
"cyan" = rgb(0,255,249),
"dark" = rgb(69,69,69),
"green" = rgb(30,255,0),
"grey" = rgb(255,255,255),
"orange" = rgb(255,129,25),
"purple" = rgb(128,0,182),
"red" = rgb(255,0,0),
"violet" = rgb(64,0,128),
"yellow" = rgb(255,198,0)
))
-1
View File
@@ -57,7 +57,6 @@
#define ANTAG_HUD_SOULLESS 21
#define ANTAG_HUD_CLOCKWORK 22
#define ANTAG_HUD_BROTHER 23
#define ANTAG_HUD_BLOODSUCKER 24
// Notification action types
#define NOTIFY_JUMP "jump"
+6 -8
View File
@@ -11,25 +11,23 @@
#define STYLE_FRUIT 11
#define STYLE_INVISIBLE 12
#define STYLE_GONDOLA 13
#define STYLE_SEETHROUGH 14
#define POD_ICON_STATE 1
#define POD_NAME 2
#define POD_DESC 3
#define POD_STYLES list(\
list("supplypod", "supply pod", "A Kinaris supply drop pod."),\
list("bluespacepod", "bluespace supply pod" , "A Kinaris Bluespace supply pod. Teleports back to CentCom after delivery."),\
list("centcompod", "\improper Centcom supply pod", "A Kinaris supply pod, this one has been marked with Central Command's designations. Teleports back to Centcom after delivery."),\
list("supplypod", "supply pod", "A Nanotrasen supply drop pod."),\
list("bluespacepod", "bluespace supply pod" , "A Nanotrasen Bluespace supply pod. Teleports back to CentCom after delivery."),\
list("centcompod", "\improper Centcom supply pod", "A Nanotrasen supply pod, this one has been marked with Central Command's designations. Teleports back to Centcom after delivery."),\
list("syndiepod", "blood-red supply pod", "A dark, intimidating supply pod, covered in the blood-red markings of the Syndicate. It's probably best to stand back from this."),\
list("squadpod", "\improper MK. II supply pod", "A Kinaris supply pod. This one has been marked the markings of some sort of elite strike team."),\
list("cultpod", "bloody supply pod", "A Kinaris supply pod covered in scratch-marks, blood, and strange runes."),\
list("squadpod", "\improper MK. II supply pod", "A Nanotrasen supply pod. This one has been marked the markings of some sort of elite strike team."),\
list("cultpod", "bloody supply pod", "A Nanotrasen supply pod covered in scratch-marks, blood, and strange runes."),\
list("missilepod", "cruise missile", "A big ass missile that didn't seem to fully detonate. It was likely launched from some far-off deep space missile silo. There appears to be an auxillery payload hatch on the side, though manually opening it is likely impossible."),\
list("smissilepod", "\improper Syndicate cruise missile", "A big ass, blood-red missile that didn't seem to fully detonate. It was likely launched from some deep space Syndicate missile silo. There appears to be an auxillery payload hatch on the side, though manually opening it is likely impossible."),\
list("boxpod", "\improper Aussec supply crate", "An incredibly sturdy supply crate, designed to withstand orbital re-entry. Has 'Aussec Armory - 2532' engraved on the side."),\
list("honkpod", "\improper HONK pod", "A brightly-colored supply pod. It likely originated from the Clown Federation."),\
list("fruitpod", "\improper Orange", "An angry orange."),\
list("", "\improper S.T.E.A.L.T.H. pod MKVII", "A supply pod that, under normal circumstances, is completely invisible to conventional methods of detection. How are you even seeing this?"),\
list("gondolapod", "gondola", "The silent walker. This one seems to be part of a delivery agency."),\
list("", "", "")\
list("gondolapod", "gondola", "The silent walker. This one seems to be part of a delivery agency.")\
)
+1 -1
View File
@@ -15,7 +15,7 @@
#define ui_boxvore "EAST-5:22,SOUTH+1:6"
//Filters
#define CIT_FILTER_STAMINACRIT filter(type="drop_shadow", x=0, y=0, size=-3, color="#04080F")
#define CIT_FILTER_STAMINACRIT filter(type="drop_shadow", x=0, y=0, size=-3, border=0, color="#04080F")
//organ defines
#define COCK_SIZE_MIN 1
+204 -205
View File
@@ -1,205 +1,204 @@
/*ALL DEFINES RELATED TO COMBAT GO HERE*/
//Damage and status effect defines
//Damage defines //TODO: merge these down to reduce on defines
#define BRUTE "brute"
#define BURN "fire"
#define TOX "tox"
#define OXY "oxy"
#define CLONE "clone"
#define STAMINA "stamina"
#define BRAIN "brain"
//bitflag damage defines used for suicide_act
#define BRUTELOSS (1<<0)
#define FIRELOSS (1<<1)
#define TOXLOSS (1<<2)
#define OXYLOSS (1<<3)
#define SHAME (1<<4)
#define MANUAL_SUICIDE (1<<5) //suicide_act will do the actual killing.
#define EFFECT_STUN "stun"
#define EFFECT_KNOCKDOWN "knockdown"
#define EFFECT_UNCONSCIOUS "unconscious"
#define EFFECT_IRRADIATE "irradiate"
#define EFFECT_STUTTER "stutter"
#define EFFECT_SLUR "slur"
#define EFFECT_EYE_BLUR "eye_blur"
#define EFFECT_DROWSY "drowsy"
#define EFFECT_JITTER "jitter"
//Bitflags defining which status effects could be or are inflicted on a mob
#define CANSTUN (1<<0)
#define CANKNOCKDOWN (1<<1)
#define CANUNCONSCIOUS (1<<2)
#define CANPUSH (1<<3)
#define GODMODE (1<<4)
//Health Defines
#define HEALTH_THRESHOLD_CRIT 0
#define HEALTH_THRESHOLD_FULLCRIT -30
#define HEALTH_THRESHOLD_DEAD -100
//Actual combat defines
//click cooldowns, in tenths of a second, used for various combat actions
#define CLICK_CD_MELEE 8
#define CLICK_CD_RANGE 4
#define CLICK_CD_RAPID 2
#define CLICK_CD_CLICK_ABILITY 6
#define CLICK_CD_BREAKOUT 100
#define CLICK_CD_HANDCUFFED 10
#define CLICK_CD_RESIST 20
#define CLICK_CD_GRABBING 10
//Cuff resist speeds
#define FAST_CUFFBREAK 1
#define INSTANT_CUFFBREAK 2
//Grab levels
#define GRAB_PASSIVE 0
#define GRAB_AGGRESSIVE 1
#define GRAB_NECK 2
#define GRAB_KILL 3
//slowdown when in softcrit
#define SOFTCRIT_ADD_SLOWDOWN 6
//Attack types for checking shields/hit reactions
#define MELEE_ATTACK 1
#define UNARMED_ATTACK 2
#define PROJECTILE_ATTACK 3
#define THROWN_PROJECTILE_ATTACK 4
#define LEAP_ATTACK 5
//attack visual effects
#define ATTACK_EFFECT_PUNCH "punch"
#define ATTACK_EFFECT_KICK "kick"
#define ATTACK_EFFECT_SMASH "smash"
#define ATTACK_EFFECT_CLAW "claw"
#define ATTACK_EFFECT_DISARM "disarm"
#define ATTACK_EFFECT_ASS_SLAP "ass_slap"
#define ATTACK_EFFECT_FACE_SLAP "face_slap"
#define ATTACK_EFFECT_BITE "bite"
#define ATTACK_EFFECT_MECHFIRE "mech_fire"
#define ATTACK_EFFECT_MECHTOXIN "mech_toxin"
#define ATTACK_EFFECT_BOOP "boop" //Honk
//intent defines
#define INTENT_HELP "help"
#define INTENT_GRAB "grab"
#define INTENT_DISARM "disarm"
#define INTENT_HARM "harm"
//NOTE: INTENT_HOTKEY_* defines are not actual intents!
//they are here to support hotkeys
#define INTENT_HOTKEY_LEFT "left"
#define INTENT_HOTKEY_RIGHT "right"
//the define for visible message range in combat
#define COMBAT_MESSAGE_RANGE 3
#define DEFAULT_MESSAGE_RANGE 7
//Shove knockdown lengths (deciseconds)
#define SHOVE_KNOCKDOWN_SOLID 30
#define SHOVE_KNOCKDOWN_HUMAN 30
#define SHOVE_KNOCKDOWN_TABLE 30
#define SHOVE_KNOCKDOWN_COLLATERAL 10
//Shove slowdown
#define SHOVE_SLOWDOWN_ID "shove_slowdown"
#define SHOVE_SLOWDOWN_LENGTH 30
#define SHOVE_SLOWDOWN_STRENGTH 0.85 //multiplier
//Shove disarming item list
GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
/obj/item/gun)))
//Combat object defines
//Embedded objects
#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user)
#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object)
#define EMBED_CHANCE 45 //Chance for an object to embed into somebody when thrown (if it's sharp)
#define EMBEDDED_PAIN_MULTIPLIER 2 //Coefficient of multiplication for the damage the item does while embedded (this*item.w_class)
#define EMBEDDED_FALL_PAIN_MULTIPLIER 5 //Coefficient of multiplication for the damage the item does when it falls out (this*item.w_class)
#define EMBEDDED_IMPACT_PAIN_MULTIPLIER 4 //Coefficient of multiplication for the damage the item does when it first embeds (this*item.w_class)
#define EMBED_THROWSPEED_THRESHOLD 4 //The minimum value of an item's throw_speed for it to embed (Unless it has embedded_ignore_throwspeed_threshold set to 1)
#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class)
#define EMBEDDED_UNSAFE_REMOVAL_TIME 150 //A Time in ticks, total removal time = (this/item.w_class)
//Gun weapon weight
#define WEAPON_LIGHT 1
#define WEAPON_MEDIUM 2
#define WEAPON_HEAVY 3
//Gun trigger guards
#define TRIGGER_GUARD_ALLOW_ALL -1
#define TRIGGER_GUARD_NONE 0
#define TRIGGER_GUARD_NORMAL 1
//E-gun self-recharge values
#define EGUN_NO_SELFCHARGE 0
#define EGUN_SELFCHARGE 1
#define EGUN_SELFCHARGE_BORG 2
//Object/Item sharpness
#define IS_BLUNT 0
#define IS_SHARP 1
#define IS_SHARP_ACCURATE 2
//His Grace.
#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep.
#define HIS_GRACE_PECKISH 20 //Slightly hungry.
#define HIS_GRACE_HUNGRY 60 //Getting closer. Increases damage up to a minimum of 20.
#define HIS_GRACE_FAMISHED 100 //Dangerous. Increases damage up to a minimum of 25 and cannot be dropped.
#define HIS_GRACE_STARVING 120 //Incredibly close to breaking loose. Increases damage up to a minimum of 30.
#define HIS_GRACE_CONSUME_OWNER 140 //His Grace consumes His owner at this point and becomes aggressive.
#define HIS_GRACE_FALL_ASLEEP 160 //If it reaches this point, He falls asleep and resets.
#define HIS_GRACE_FORCE_BONUS 4 //How much force is gained per kill.
#define EXPLODE_NONE 0 //Don't even ask me why we need this.
#define EXPLODE_DEVASTATE 1
#define EXPLODE_HEAVY 2
#define EXPLODE_LIGHT 3
#define EMP_HEAVY 1
#define EMP_LIGHT 2
#define GRENADE_CLUMSY_FUMBLE 1
#define GRENADE_NONCLUMSY_FUMBLE 2
#define GRENADE_NO_FUMBLE 3
#define BODY_ZONE_HEAD "head"
#define BODY_ZONE_CHEST "chest"
#define BODY_ZONE_L_ARM "l_arm"
#define BODY_ZONE_R_ARM "r_arm"
#define BODY_ZONE_L_LEG "l_leg"
#define BODY_ZONE_R_LEG "r_leg"
#define BODY_ZONE_PRECISE_EYES "eyes"
#define BODY_ZONE_PRECISE_MOUTH "mouth"
#define BODY_ZONE_PRECISE_GROIN "groin"
#define BODY_ZONE_PRECISE_L_HAND "l_hand"
#define BODY_ZONE_PRECISE_R_HAND "r_hand"
#define BODY_ZONE_PRECISE_L_FOOT "l_foot"
#define BODY_ZONE_PRECISE_R_FOOT "r_foot"
//We will round to this value in damage calculations.
#define DAMAGE_PRECISION 0.1
//bullet_act() return values
#define BULLET_ACT_HIT "HIT" //It's a successful hit, whatever that means in the context of the thing it's hitting.
#define BULLET_ACT_BLOCK "BLOCK" //It's a blocked hit, whatever that means in the context of the thing it's hitting.
#define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default.
#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.
//items total mass, used to calculate their attacks' stamina costs. If not defined, the cost will be (w_class * 1.25)
#define TOTAL_MASS_TINY_ITEM 1.25
#define TOTAL_MASS_SMALL_ITEM 2.5
#define TOTAL_MASS_NORMAL_ITEM 3.75
#define TOTAL_MASS_BULKY_ITEM 5
#define TOTAL_MASS_HUGE_ITEM 6.25
#define TOTAL_MASS_GIGANTIC_ITEM 7.5
#define TOTAL_MASS_HAND_REPLACEMENT 5 //standard punching stamina cost. most hand replacements are huge items anyway.
#define TOTAL_MASS_MEDIEVAL_WEAPON 3.6 //very, very generic average sword/warpick/etc. weight in pounds.
#define TOTAL_MASS_TOY_SWORD 1.5
/*ALL DEFINES RELATED TO COMBAT GO HERE*/
//Damage and status effect defines
//Damage defines //TODO: merge these down to reduce on defines
#define BRUTE "brute"
#define BURN "fire"
#define TOX "tox"
#define OXY "oxy"
#define CLONE "clone"
#define STAMINA "stamina"
#define BRAIN "brain"
//bitflag damage defines used for suicide_act
#define BRUTELOSS (1<<0)
#define FIRELOSS (1<<1)
#define TOXLOSS (1<<2)
#define OXYLOSS (1<<3)
#define SHAME (1<<4)
#define MANUAL_SUICIDE (1<<5) //suicide_act will do the actual killing.
#define EFFECT_STUN "stun"
#define EFFECT_KNOCKDOWN "knockdown"
#define EFFECT_UNCONSCIOUS "unconscious"
#define EFFECT_IRRADIATE "irradiate"
#define EFFECT_STUTTER "stutter"
#define EFFECT_SLUR "slur"
#define EFFECT_EYE_BLUR "eye_blur"
#define EFFECT_DROWSY "drowsy"
#define EFFECT_JITTER "jitter"
//Bitflags defining which status effects could be or are inflicted on a mob
#define CANSTUN (1<<0)
#define CANKNOCKDOWN (1<<1)
#define CANUNCONSCIOUS (1<<2)
#define CANPUSH (1<<3)
#define GODMODE (1<<4)
//Health Defines
#define HEALTH_THRESHOLD_CRIT 0
#define HEALTH_THRESHOLD_FULLCRIT -30
#define HEALTH_THRESHOLD_DEAD -100
//Actual combat defines
//click cooldowns, in tenths of a second, used for various combat actions
#define CLICK_CD_MELEE 8
#define CLICK_CD_RANGE 4
#define CLICK_CD_RAPID 2
#define CLICK_CD_CLICK_ABILITY 6
#define CLICK_CD_BREAKOUT 100
#define CLICK_CD_HANDCUFFED 10
#define CLICK_CD_RESIST 20
#define CLICK_CD_GRABBING 10
//Cuff resist speeds
#define FAST_CUFFBREAK 1
#define INSTANT_CUFFBREAK 2
//Grab levels
#define GRAB_PASSIVE 0
#define GRAB_AGGRESSIVE 1
#define GRAB_NECK 2
#define GRAB_KILL 3
//slowdown when in softcrit
#define SOFTCRIT_ADD_SLOWDOWN 6
//Attack types for checking shields/hit reactions
#define MELEE_ATTACK 1
#define UNARMED_ATTACK 2
#define PROJECTILE_ATTACK 3
#define THROWN_PROJECTILE_ATTACK 4
#define LEAP_ATTACK 5
//attack visual effects
#define ATTACK_EFFECT_PUNCH "punch"
#define ATTACK_EFFECT_KICK "kick"
#define ATTACK_EFFECT_SMASH "smash"
#define ATTACK_EFFECT_CLAW "claw"
#define ATTACK_EFFECT_DISARM "disarm"
#define ATTACK_EFFECT_ASS_SLAP "ass_slap"
#define ATTACK_EFFECT_FACE_SLAP "face_slap"
#define ATTACK_EFFECT_BITE "bite"
#define ATTACK_EFFECT_MECHFIRE "mech_fire"
#define ATTACK_EFFECT_MECHTOXIN "mech_toxin"
#define ATTACK_EFFECT_BOOP "boop" //Honk
//intent defines
#define INTENT_HELP "help"
#define INTENT_GRAB "grab"
#define INTENT_DISARM "disarm"
#define INTENT_HARM "harm"
//NOTE: INTENT_HOTKEY_* defines are not actual intents!
//they are here to support hotkeys
#define INTENT_HOTKEY_LEFT "left"
#define INTENT_HOTKEY_RIGHT "right"
//the define for visible message range in combat
#define COMBAT_MESSAGE_RANGE 3
//Shove knockdown lengths (deciseconds)
#define SHOVE_KNOCKDOWN_SOLID 30
#define SHOVE_KNOCKDOWN_HUMAN 30
#define SHOVE_KNOCKDOWN_TABLE 30
#define SHOVE_KNOCKDOWN_COLLATERAL 10
//Shove slowdown
#define SHOVE_SLOWDOWN_ID "shove_slowdown"
#define SHOVE_SLOWDOWN_LENGTH 30
#define SHOVE_SLOWDOWN_STRENGTH 0.85 //multiplier
//Shove disarming item list
GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
/obj/item/gun)))
//Combat object defines
//Embedded objects
#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user)
#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object)
#define EMBED_CHANCE 45 //Chance for an object to embed into somebody when thrown (if it's sharp)
#define EMBEDDED_PAIN_MULTIPLIER 2 //Coefficient of multiplication for the damage the item does while embedded (this*item.w_class)
#define EMBEDDED_FALL_PAIN_MULTIPLIER 5 //Coefficient of multiplication for the damage the item does when it falls out (this*item.w_class)
#define EMBEDDED_IMPACT_PAIN_MULTIPLIER 4 //Coefficient of multiplication for the damage the item does when it first embeds (this*item.w_class)
#define EMBED_THROWSPEED_THRESHOLD 4 //The minimum value of an item's throw_speed for it to embed (Unless it has embedded_ignore_throwspeed_threshold set to 1)
#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class)
#define EMBEDDED_UNSAFE_REMOVAL_TIME 150 //A Time in ticks, total removal time = (this/item.w_class)
//Gun weapon weight
#define WEAPON_LIGHT 1
#define WEAPON_MEDIUM 2
#define WEAPON_HEAVY 3
//Gun trigger guards
#define TRIGGER_GUARD_ALLOW_ALL -1
#define TRIGGER_GUARD_NONE 0
#define TRIGGER_GUARD_NORMAL 1
//E-gun self-recharge values
#define EGUN_NO_SELFCHARGE 0
#define EGUN_SELFCHARGE 1
#define EGUN_SELFCHARGE_BORG 2
//Object/Item sharpness
#define IS_BLUNT 0
#define IS_SHARP 1
#define IS_SHARP_ACCURATE 2
//His Grace.
#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep.
#define HIS_GRACE_PECKISH 20 //Slightly hungry.
#define HIS_GRACE_HUNGRY 60 //Getting closer. Increases damage up to a minimum of 20.
#define HIS_GRACE_FAMISHED 100 //Dangerous. Increases damage up to a minimum of 25 and cannot be dropped.
#define HIS_GRACE_STARVING 120 //Incredibly close to breaking loose. Increases damage up to a minimum of 30.
#define HIS_GRACE_CONSUME_OWNER 140 //His Grace consumes His owner at this point and becomes aggressive.
#define HIS_GRACE_FALL_ASLEEP 160 //If it reaches this point, He falls asleep and resets.
#define HIS_GRACE_FORCE_BONUS 4 //How much force is gained per kill.
#define EXPLODE_NONE 0 //Don't even ask me why we need this.
#define EXPLODE_DEVASTATE 1
#define EXPLODE_HEAVY 2
#define EXPLODE_LIGHT 3
#define EMP_HEAVY 1
#define EMP_LIGHT 2
#define GRENADE_CLUMSY_FUMBLE 1
#define GRENADE_NONCLUMSY_FUMBLE 2
#define GRENADE_NO_FUMBLE 3
#define BODY_ZONE_HEAD "head"
#define BODY_ZONE_CHEST "chest"
#define BODY_ZONE_L_ARM "l_arm"
#define BODY_ZONE_R_ARM "r_arm"
#define BODY_ZONE_L_LEG "l_leg"
#define BODY_ZONE_R_LEG "r_leg"
#define BODY_ZONE_PRECISE_EYES "eyes"
#define BODY_ZONE_PRECISE_MOUTH "mouth"
#define BODY_ZONE_PRECISE_GROIN "groin"
#define BODY_ZONE_PRECISE_L_HAND "l_hand"
#define BODY_ZONE_PRECISE_R_HAND "r_hand"
#define BODY_ZONE_PRECISE_L_FOOT "l_foot"
#define BODY_ZONE_PRECISE_R_FOOT "r_foot"
//We will round to this value in damage calculations.
#define DAMAGE_PRECISION 0.1
//bullet_act() return values
#define BULLET_ACT_HIT "HIT" //It's a successful hit, whatever that means in the context of the thing it's hitting.
#define BULLET_ACT_BLOCK "BLOCK" //It's a blocked hit, whatever that means in the context of the thing it's hitting.
#define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default.
#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.
//items total mass, used to calculate their attacks' stamina costs. If not defined, the cost will be (w_class * 1.25)
#define TOTAL_MASS_TINY_ITEM 1.25
#define TOTAL_MASS_SMALL_ITEM 2.5
#define TOTAL_MASS_NORMAL_ITEM 3.75
#define TOTAL_MASS_BULKY_ITEM 5
#define TOTAL_MASS_HUGE_ITEM 6.25
#define TOTAL_MASS_GIGANTIC_ITEM 7.5
#define TOTAL_MASS_HAND_REPLACEMENT 5 //standard punching stamina cost. most hand replacements are huge items anyway.
#define TOTAL_MASS_MEDIEVAL_WEAPON 3.6 //very, very generic average sword/warpick/etc. weight in pounds.
#define TOTAL_MASS_TOY_SWORD 1.5
+104 -104
View File
@@ -1,104 +1,104 @@
#define SEND_SIGNAL(target, sigtype, arguments...) ( !target.comp_lookup || !target.comp_lookup[sigtype] ? NONE : target._SendSignal(sigtype, list(target, ##arguments)) )
#define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) )
#define COMPONENT_INCOMPATIBLE 1
#define COMPONENT_NOTRANSFER 2
// 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
// All signals. Format:
// When the signal is called: (signal arguments)
// All signals send the source datum of the signal as the first argument
// 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
//////////////////////////////////////////////////////////////////
// /datum signals
// /atom signals
//Positions for overrides list
//End positions
#define COMSIG_ATOM_RATVAR_ACT "atom_ratvar_act" //from base of atom/ratvar_act(): ()
/////////////////
// /area signals
// /turf signals
// /atom/movable signals
// /mob/living signals
// /mob/living/carbon signals
// /obj signals
#define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag)
// /obj/item signals
// /obj/item/clothing signals
// /obj/item/implant signals
//This uses all return values of COMSIG_IMPLANT_OTHER
// /obj/item/pda signals
// /obj/item/radio signals
// /obj/item/pen signals
// /mob/living/carbon/human signals
// /datum/species signals
/*******Component Specific Signals*******/
//Janitor
//Food
//Mood
#define COMSIG_INCREASE_SANITY "decrease_sanity" //Called when you want to increase sanity from anywhere in the code.
#define COMSIG_DECREASE_SANITY "increase_sanity" //Same as above but to decrease sanity instead.
//NTnet
//Nanites
// /datum/component/storage signals
// /datum/action signals
/*******Non-Signal Component Related Defines*******/
//Redirection component init flags
#define REDIRECT_TRANSFER_WITH_TURF 1
//Arch
#define ARCH_PROB "probability" //Probability for each item
#define ARCH_MAXDROP "max_drop_amount" //each item's max drop amount
//Ouch my toes!
#define CALTROP_BYPASS_SHOES 1
#define CALTROP_IGNORE_WALKERS 2
#define ELEMENT_INCOMPATIBLE 1 // Return value to cancel attaching
// /datum/element flags
/// Causes the detach proc to be called when the host object is being deleted
#define ELEMENT_DETACH (1 << 0)
/**
* Only elements created with the same arguments given after `id_arg_index` share an element instance
* The arguments are the same when the text and number values are the same and all other values have the same ref
*/
#define ELEMENT_BESPOKE (1 << 1)
#define COMSIG_MOVABLE_UPDATE_GLIDE_SIZE "movable_glide_size" //Called when the movable's glide size is updated: (new_glide_size)
#define COMSIG_LIVING_FULLY_HEAL "living_fully_healed" //from base of /mob/living/fully_heal(): (admin_revive)
#define SEND_SIGNAL(target, sigtype, arguments...) ( !target.comp_lookup || !target.comp_lookup[sigtype] ? NONE : target._SendSignal(sigtype, list(target, ##arguments)) )
#define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) )
#define COMPONENT_INCOMPATIBLE 1
#define COMPONENT_NOTRANSFER 2
// 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
// All signals. Format:
// When the signal is called: (signal arguments)
// All signals send the source datum of the signal as the first argument
// 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
//////////////////////////////////////////////////////////////////
// /datum signals
// /atom signals
//Positions for overrides list
//End positions
#define COMSIG_ATOM_RATVAR_ACT "atom_ratvar_act" //from base of atom/ratvar_act(): ()
/////////////////
// /area signals
// /turf signals
// /atom/movable signals
// /mob/living signals
// /mob/living/carbon signals
// /obj signals
#define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag)
// /obj/item signals
// /obj/item/clothing signals
// /obj/item/implant signals
//This uses all return values of COMSIG_IMPLANT_OTHER
// /obj/item/pda signals
// /obj/item/radio signals
// /obj/item/pen signals
// /mob/living/carbon/human signals
// /datum/species signals
/*******Component Specific Signals*******/
//Janitor
//Food
//Mood
#define COMSIG_INCREASE_SANITY "decrease_sanity" //Called when you want to increase sanity from anywhere in the code.
#define COMSIG_DECREASE_SANITY "increase_sanity" //Same as above but to decrease sanity instead.
//NTnet
//Nanites
// /datum/component/storage signals
// /datum/action signals
/*******Non-Signal Component Related Defines*******/
//Redirection component init flags
#define REDIRECT_TRANSFER_WITH_TURF 1
//Arch
#define ARCH_PROB "probability" //Probability for each item
#define ARCH_MAXDROP "max_drop_amount" //each item's max drop amount
//Ouch my toes!
#define CALTROP_BYPASS_SHOES 1
#define CALTROP_IGNORE_WALKERS 2
#define ELEMENT_INCOMPATIBLE 1 // Return value to cancel attaching
// /datum/element flags
/// Causes the detach proc to be called when the host object is being deleted
#define ELEMENT_DETACH (1 << 0)
/**
* Only elements created with the same arguments given after `id_arg_index` share an element instance
* The arguments are the same when the text and number values are the same and all other values have the same ref
*/
#define ELEMENT_BESPOKE (1 << 1)
#define COMSIG_MOVABLE_UPDATE_GLIDE_SIZE "movable_glide_size" //Called when the movable's glide size is updated: (new_glide_size)
#define COMSIG_LIVING_FULLY_HEAL "living_fully_healed" //from base of /mob/living/fully_heal(): (admin_revive)
-1
View File
@@ -87,7 +87,6 @@
#define CAT_ROBOT "Robots"
#define CAT_MISC "Misc"
#define CAT_PRIMAL "Tribal"
//#define CAT_CARPENTRY "Carpentry" need to get this to work
#define CAT_CLOTHING "Clothing"
#define CAT_FOOD "Foods"
#define CAT_BREAD "Breads"
+21 -19
View File
@@ -152,15 +152,18 @@
#define COMPONENT_BLOCK_TELEPORT (1<<0)
///called when an atom is added to the hearers on get_hearers_in_view(): (list/processing_list, list/hearers)
#define COMSIG_ATOM_HEARER_IN_VIEW "atom_hearer_in_view"
///called when an atom starts orbiting another atom: (atom)
#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin"
///called when an atom stops orbiting another atom: (atom)
#define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop"
/////////////////
#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost)
#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user)
#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" //from base of atom/attack_paw(): (mob/user)
#define COMPONENT_NO_ATTACK_HAND 1 //works on all 3.
/////////////////
///from base of atom/attack_ghost(): (mob/dead/observer/ghost)
#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost"
///from base of atom/attack_hand(): (mob/user)
#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand"
///from base of atom/attack_paw(): (mob/user)
#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw"
#define COMPONENT_NO_ATTACK_HAND (1<<0) //works on all 3.
//This signal return value bitflags can be found in __DEFINES/misc.dm
///called for each movable in a turf contents on /turf/zImpact(): (atom/movable/A, levels)
@@ -171,10 +174,6 @@
#define COMSIG_LIVING_START_PULL "living_start_pull"
/////////////////
/// Called from orbit component: (atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin"
/// Called from orbit component: (atom/movable/orbiter, refreshing)
#define COMSIG_ATOM_ORBIT_END "atom_orbit_end"
///from base of area/Entered(): (/area)
#define COMSIG_ENTER_AREA "enter_area"
@@ -709,13 +708,16 @@
#define COMPONENT_ACTION_BLOCK_TRIGGER (1<<0)
//Xenobio hotkeys
#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl" //from slime CtrlClickOn(): (/mob)
#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt" //from slime AltClickOn(): (/mob)
#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob)
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
// twitch plays
/// Returns direction: (wipe_votes)
#define COMSIG_TWITCH_PLAYS_MOVEMENT_DATA "twitch_plays_movement_data"
///from slime CtrlClickOn(): (/mob)
#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl"
///from slime AltClickOn(): (/mob)
#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt"
///from slime ShiftClickOn(): (/mob)
#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift"
///from turf ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift"
///from turf AltClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt"
///from monkey CtrlClickOn(): (/mob)
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl"
-2
View File
@@ -32,7 +32,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#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.
#define PREVENT_CONTENTS_EXPLOSION_1 (1<<16) /// should not get harmed if this gets caught by an explosion?
//turf-only flags
#define NOJAUNT_1 (1<<0)
@@ -92,4 +91,3 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
// radiation
#define RAD_PROTECT_CONTENTS (1<<0)
#define RAD_NO_CONTAMINATE (1<<1)
-3
View File
@@ -81,7 +81,6 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
// Citadel specific species
#define isipcperson(A) (is_species(A, /datum/species/ipc))
#define issynthliz(A) (is_species(A, /datum/species/synthliz))
#define ismammal(A) (is_species(A, /datum/species/mammal))
#define isavian(A) (is_species(A, /datum/species/avian))
#define isaquatic(A) (is_species(A, /datum/species/aquatic))
@@ -234,8 +233,6 @@ GLOBAL_LIST_INIT(heavyfootmob, typecacheof(list(
#define isorgan(A) (istype(A, /obj/item/organ))
#define isclothing(A) (istype(A, /obj/item/clothing))
GLOBAL_LIST_INIT(pointed_types, typecacheof(list(
/obj/item/pen,
/obj/item/screwdriver,
+1 -11
View File
@@ -96,22 +96,12 @@
#define NUKESTATE_CORE_EXPOSED 1
#define NUKESTATE_CORE_REMOVED 0
#define NUKEUI_AWAIT_DISK 0
#define NUKEUI_AWAIT_CODE 1
#define NUKEUI_AWAIT_TIMER 2
#define NUKEUI_AWAIT_ARM 3
#define NUKEUI_TIMING 4
#define NUKEUI_EXPLODED 5
#define NUKE_OFF_LOCKED 0
#define NUKE_OFF_UNLOCKED 1
#define NUKE_ON_TIMING 2
#define NUKE_ON_EXPLODING 3
#define MACHINE_NOT_ELECTRIFIED 0
#define MACHINE_ELECTRIFIED_PERMANENT -1
#define MACHINE_DEFAULT_ELECTRIFY_TIME 30
//these flags are used to tell the DNA modifier if a plant gene cannot be extracted or modified.
#define PLANT_GENE_REMOVABLE (1<<0)
#define PLANT_GENE_EXTRACTABLE (1<<1)
+2 -3
View File
@@ -39,6 +39,8 @@ require only minor tweaks.
#define ZTRAIT_LAVA_RUINS "Lava Ruins"
#define ZTRAIT_LAVA_UNDERGROUND "Lava Underground"
#define ZTRAIT_ISOLATED_RUINS "Isolated Ruins" //Placing ruins on z levels with this trait will use turf reservation instead of usual placement.
// prevents certain turfs from being stripped by a singularity
#define ZTRAIT_PLANET "Planet"
// number - bombcap is multiplied by this before being applied to bombs
#define ZTRAIT_BOMBCAP_MULTIPLIER "Bombcap Multiplier"
@@ -59,9 +61,6 @@ require only minor tweaks.
// CROSSLINKED - mixed in with the cross-linked space pool
#define CROSSLINKED "Cross"
// string - type path of the z-level's baseturf (defaults to space)
#define ZTRAIT_BASETURF "Baseturf"
// default trait definitions, used by SSmapping
#define ZTRAITS_CENTCOM list(ZTRAIT_CENTCOM = TRUE)
#define ZTRAITS_STATION list(ZTRAIT_LINKAGE = CROSSLINKED, ZTRAIT_STATION = TRUE)
-5
View File
@@ -478,11 +478,6 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define AREASELECT_CORNERA "corner A"
#define AREASELECT_CORNERB "corner B"
#define VARSET_FROM_LIST(L, V) if(L && L[#V]) V = L[#V]
#define VARSET_FROM_LIST_IF(L, V, C...) if(L && L[#V] && (C)) V = L[#V]
#define VARSET_TO_LIST(L, V) if(L) L[#V] = V
#define VARSET_TO_LIST_IF(L, V, C...) if(L && (C)) L[#V] = V
#define PREF_SAVELOAD_COOLDOWN 5
#define VOMIT_TOXIC 1
+1 -1
View File
@@ -39,7 +39,6 @@
#define MOB_ORGANIC "organic"
#define MOB_INORGANIC "inorganic"
#define MOB_ROBOTIC "robotic"
#define MOB_SILICON "silicon"
#define MOB_UNDEAD "undead"
#define MOB_HUMANOID "humanoid"
#define MOB_BUG "bug"
@@ -121,6 +120,7 @@
#define BIOWARE_NERVES "nerves"
#define BIOWARE_CIRCULATION "circulation"
#define BIOWARE_LIGAMENTS "ligaments"
#define BIOWARE_DISSECTION "dissected"
//Health hud screws for carbon mobs
#define SCREWYHUD_NONE 0
-2
View File
@@ -37,7 +37,5 @@
#define MOVESPEED_ID_PRONE_DRAGGING "PRONE_DRAG"
#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
#define MOVESPEED_ID_SILICON_VTEC "SILICON_VTEC"
#define MOVESPEED_ID_SHRUNK "SHRINK_SPEED_MODIFIER"
#define MOVESPEED_ID_GROW "GROWTH_SPEED_MODIFIER"
+6 -8
View File
@@ -34,14 +34,12 @@
#define LAVAPROTECT (1<<0)
#define STOPSPRESSUREDAMAGE (1<<1) //SUIT and HEAD items which stop pressure damage. To stop you taking all pressure damage you must have both a suit and head item with this flag.
#define BLOCK_GAS_SMOKE_EFFECT (1<<2) //blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
#define ALLOWINTERNALS (1<<3) //mask allows internals
#define NOSLIP (1<<4) //prevents from slipping on wet floors, in space etc
#define THICKMATERIAL (1<<5) //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body.
#define VOICEBOX_TOGGLABLE (1<<6) //The voicebox in this clothing can be toggled.
#define VOICEBOX_DISABLED (1<<7) //The voicebox is currently turned off.
#define IGNORE_HAT_TOSS (1<<8) //Hats with negative effects when worn (i.e the tinfoil hat).
#define SCAN_REAGENTS (1<<9) // Allows helmets and glasses to scan reagents.
#define BLOCK_GAS_SMOKE_EFFECT (1<<2) // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
#define ALLOWINTERNALS (1<<3) // mask allows internals
#define NOSLIP (1<<4) //prevents from slipping on wet floors, in space etc
#define THICKMATERIAL (1<<5) //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body.
#define VOICEBOX_TOGGLABLE (1<<6) // The voicebox in this clothing can be toggled.
#define VOICEBOX_DISABLED (1<<7) // The voicebox is currently turned off.
// Flags for the organ_flags var on /obj/item/organ
+1 -3
View File
@@ -35,8 +35,6 @@
#define ADD_REAGENT 2 // reagent added
#define REM_REAGENT 3 // reagent removed (may still exist)
#define THRESHOLD_UNHUSK 40 // health threshold for synthflesh/rezadone to unhusk someone
//reagent bitflags, used for altering how they works
#define REAGENT_DEAD_PROCESS (1<<0) //calls on_mob_dead() if present in a dead body
#define REAGENT_DONOTSPLIT (1<<1) //Do not split the chem at all during processing
@@ -49,4 +47,4 @@
//Chemical reaction flags, for determining reaction specialties
#define REACTION_CLEAR_IMPURE (1<<0) //Convert into impure/pure on reaction completion
#define REACTION_CLEAR_INVERSE (1<<1) //Convert into inverse on reaction completion when purity is low enough
#define REACTION_CLEAR_INVERSE (1<<1) //Convert into inverse on reaction completion when purity is low enough
+1 -4
View File
@@ -35,7 +35,6 @@
#define ROLE_LAVALAND "lavaland"
#define ROLE_INTERNAL_AFFAIRS "internal affairs agent"
#define ROLE_GANG "gangster"
#define ROLE_BLOODSUCKER "bloodsucker"
//Hyper
#define ROLE_LEWD_TRAITOR "lewd traitor"
@@ -63,9 +62,7 @@ GLOBAL_LIST_INIT(special_roles, list(
ROLE_OVERTHROW = /datum/game_mode/overthrow,
ROLE_INTERNAL_AFFAIRS = /datum/game_mode/traitor/internal_affairs,
ROLE_SENTIENCE,
ROLE_GANG = /datum/game_mode/gang,
ROLE_BLOODSUCKER = /datum/game_mode/bloodsucker
//ROLE_MONSTERHUNTER Disabled for now
ROLE_GANG = /datum/game_mode/gang
))
//Job defines for what happens when you fail to qualify for any job during job selection
-6
View File
@@ -23,8 +23,6 @@
#define MODE_WHISPER "whisper"
#define MODE_WHISPER_CRIT "whispercrit"
#define MODE_CUSTOM_SAY "custom_say"
#define MODE_DEPARTMENT "department"
#define MODE_KEY_DEPARTMENT "h"
#define MODE_TOKEN_DEPARTMENT ":h"
@@ -83,7 +81,3 @@
#define MAX_NAME_LEN 42
#define MAX_BROADCAST_LEN 512
#define MAX_CHARTER_LEN 80
// Audio/Visual Flags. Used to determine what sense are required to notice a message.
#define MSG_VISUAL (1<<0)
#define MSG_AUDIBLE (1<<1)
+1 -9
View File
@@ -7,8 +7,6 @@
#define STATUS_EFFECT_REPLACE 2 //if it allows only one, but new instances replace
#define STATUS_EFFECT_REFRESH 3 // if it only allows one, and new instances just instead refresh the timer
///////////
// BUFFS //
///////////
@@ -46,7 +44,7 @@
#define STATUS_EFFECT_SLEEPING /datum/status_effect/incapacitating/sleeping //the affected is asleep
#define STATUS_EFFECT_TASED /datum/status_effect/no_combat_mode/electrode/ //the affected has been tased, preventing fine muscle control
#define STATUS_EFFECT_TASED /datum/status_effect/electrode //the affected has been tased, preventing fine muscle control
#define STATUS_EFFECT_PACIFY /datum/status_effect/pacify //the affected is pacified, preventing direct hostile actions
@@ -58,8 +56,6 @@
#define MAX_MANIA_SEVERITY 100 //how high the mania severity can go
#define MANIA_DAMAGE_TO_CONVERT 90 //how much damage is required before it'll convert affected targets
#define STATUS_EFFECT_CHOKINGSTRAND /datum/status_effect/strandling //Choking Strand
#define STATUS_EFFECT_HISWRATH /datum/status_effect/his_wrath //His Wrath.
#define STATUS_EFFECT_SUMMONEDGHOST /datum/status_effect/cultghost //is a cult ghost and can't use manifest runes
@@ -79,10 +75,6 @@
#define STATUS_EFFECT_ICHORIAL_STAIN /datum/status_effect/ichorial_stain //Prevents a servant from being revived by vitality matrices for one minute.
#define STATUS_EFFECT_STASIS /datum/status_effect/incapacitating/stasis //Halts biological functions like bleeding, chemical processing, blood regeneration, walking, etc
#define STATUS_EFFECT_SPASMS /datum/status_effect/spasms //causes random muscle spasms
#define STATUS_EFFECT_NO_COMBAT_MODE /datum/status_effect/no_combat_mode //Wont allow combat mode and will disable it
#define STATUS_EFFECT_MESMERIZE /datum/status_effect/no_combat_mode/mesmerize //Just reskinned no_combat_mode
/////////////
// NEUTRAL //
/////////////
+15 -21
View File
@@ -1,21 +1,15 @@
// Tool types
#define TOOL_CROWBAR "crowbar"
#define TOOL_MULTITOOL "multitool"
#define TOOL_SCREWDRIVER "screwdriver"
#define TOOL_WIRECUTTER "wirecutter"
#define TOOL_WRENCH "wrench"
#define TOOL_WELDER "welder"
#define TOOL_ANALYZER "analyzer"
#define TOOL_MINING "mining"
#define TOOL_SHOVEL "shovel"
#define TOOL_RETRACTOR "retractor"
#define TOOL_HEMOSTAT "hemostat"
#define TOOL_CAUTERY "cautery"
#define TOOL_DRILL "drill"
#define TOOL_SCALPEL "scalpel"
#define TOOL_SAW "saw"
// If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY,
// tool sound is only played when op is started. If not, it's played twice.
#define MIN_TOOL_SOUND_DELAY 20
// Tool types
#define TOOL_CROWBAR "crowbar"
#define TOOL_MULTITOOL "multitool"
#define TOOL_SCREWDRIVER "screwdriver"
#define TOOL_WIRECUTTER "wirecutter"
#define TOOL_WRENCH "wrench"
#define TOOL_WELDER "welder"
#define TOOL_ANALYZER "analyzer"
#define TOOL_MINING "mining"
#define TOOL_SHOVEL "shovel"
// If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY,
// tool sound is only played when op is started. If not, it's played twice.
#define MIN_TOOL_SOUND_DELAY 20
+2 -18
View File
@@ -81,7 +81,6 @@
#define TRAIT_PUSHIMMUNE "push_immunity"
#define TRAIT_SHOCKIMMUNE "shock_immunity"
#define TRAIT_STABLEHEART "stable_heart"
#define TRAIT_STABLELIVER "stable_liver"
#define TRAIT_RESISTHEAT "resist_heat"
#define TRAIT_RESISTHEATHANDS "resist_heat_handsonly" //For when you want to be able to touch hot things, but still want fire to be an issue.
#define TRAIT_RESISTCOLD "resist_cold"
@@ -112,35 +111,22 @@
#define TRAIT_NOHARDCRIT "nohardcrit"
#define TRAIT_NOSOFTCRIT "nosoftcrit"
#define TRAIT_MINDSHIELD "mindshield"
#define TRAIT_SIXTHSENSE "sixthsense"
#define TRAIT_DISSECTED "dissected"
#define TRAIT_FEARLESS "fearless"
#define TRAIT_UNSTABLE "unstable"
#define TRAIT_PARALYSIS_L_ARM "para-l-arm" //These are used for brain-based paralysis, where replacing the limb won't fix it
#define TRAIT_PARALYSIS_R_ARM "para-r-arm"
#define TRAIT_PARALYSIS_L_LEG "para-l-leg"
#define TRAIT_PARALYSIS_R_LEG "para-r-leg"
#define TRAIT_DISK_VERIFIER "disk-verifier"
#define TRAIT_UNINTELLIGIBLE_SPEECH "unintelligible-speech"
#define TRAIT_SOOTHED_THROAT "soothed-throat"
#define TRAIT_LAW_ENFORCEMENT_METABOLISM "law-enforcement-metabolism"
#define TRAIT_STRONG_GRABBER "strong_grabber"
#define TRAIT_CALCIUM_HEALER "calcium_healer"
#define TRAIT_MAGIC_CHOKE "magic_choke"
#define TRAIT_ALCOHOL_LIGHTWEIGHT "alcohol_lightweight" //Skyrat port
#define TRAIT_CURSED_BLOOD "cursed_blood" //Yo dawg I heard you like bloodborne references so I put a
#define TRAIT_HEAT_DETECT "heat_detect"
#define TRAIT_HEAT "heat"
#define TRAIT_RADRESONANCE "radioactive_resonance" //Hyperstation edit
#define TRAIT_SWIMMING "swimming" //only applied by /datum/element/swimming, for checking
#define TRAIT_CAPTAIN_METABOLISM "captain-metabolism"
#define TRAIT_ABDUCTOR_TRAINING "abductor-training"
#define TRAIT_ABDUCTOR_SCIENTIST_TRAINING "abductor-scientist-training"
#define TRAIT_SURGEON "surgeon"
#define TRAIT_NONATURALHEAL "nonaturalheal" // Only Admins can heal you. NOTHING else does it unless it's given the god tag.
#define TRAIT_NORUNNING "norunning" // You walk!
#define TRAIT_NOMARROW "nomarrow" // You don't make blood, with chemicals or nanites.
#define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat.
//non-mob traits
#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it
@@ -209,12 +195,10 @@
#define CULT_TRAIT "cult"
#define CURSED_ITEM_TRAIT "cursed-item" // The item is magically cursed
#define ABSTRACT_ITEM_TRAIT "abstract-item"
#define STATUS_EFFECT_TRAIT "status-effect"
#define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention
// unique trait sources, still defines
#define STATUE_MUTE "statue"
#define CLONING_POD_TRAIT "cloning-pod"
#define CHANGELING_DRAIN "drain"
#define CHANGELING_HIVEMIND_MUTE "ling_mute"
#define ABYSSAL_GAZE_BLIND "abyssal_gaze"
@@ -243,9 +227,9 @@
#define LOCKED_HELMET_TRAIT "locked-helmet"
#define NINJA_SUIT_TRAIT "ninja-suit"
#define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant"
#define ABDUCTOR_ANTAGONIST "abductor-antagonist"
#define SLEEPING_CARP_TRAIT "sleeping_carp"
#define RISING_BASS_TRAIT "rising_bass"
#define ABDUCTOR_ANTAGONIST "abductor-antagonist"
#define NUKEOP_ANTAGONIST "nukeop-antagonist"
#define MADE_UNCLONEABLE "made-uncloneable"
#define NUKEOP_TRAIT "nuke-op"
+1 -1
View File
@@ -2,7 +2,7 @@
#define TYPEID_NULL "0"
#define TYPEID_NORMAL_LIST "f"
//helper macros
#define GET_TYPEID(ref) ( ( (length(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, -7) ) )
#define GET_TYPEID(ref) ( ( (length(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, length(ref)-6) ) )
#define IS_NORMAL_LIST(L) (GET_TYPEID("\ref[L]") == TYPEID_NORMAL_LIST)
+2 -2
View File
@@ -68,8 +68,8 @@ GLOBAL_LIST_EMPTY(breasts_shapes_icons)
GLOBAL_LIST_EMPTY(vagina_shapes_list)
GLOBAL_LIST_INIT(cum_into_containers_list, list(/obj/item/reagent_containers/food/snacks/pie)) //Yer fuggin snowflake name list jfc
GLOBAL_LIST_INIT(dick_nouns, list("dick","cock","member","shaft"))
GLOBAL_LIST_INIT(cum_id_list, /datum/reagent/consumable/semen)
GLOBAL_LIST_INIT(milk_id_list, /datum/reagent/consumable/milk)
GLOBAL_LIST_INIT(cum_id_list,"semen")
GLOBAL_LIST_INIT(milk_id_list,"milk")
GLOBAL_LIST_INIT(dildo_shapes, list(
"Human" = "human",
-6
View File
@@ -573,9 +573,3 @@
L1[key] += other_value
else
L1[key] = other_value
/proc/assoc_list_strip_value(list/input)
var/list/ret = list()
for(var/key in input)
ret += key
return ret
-7
View File
@@ -160,18 +160,11 @@
WRITE_LOG(GLOB.config_error_log, text)
SEND_TEXT(world.log, text)
/proc/log_mapping(text)
WRITE_LOG(GLOB.world_map_error_log, text)
/* For logging round startup. */
/proc/start_log(log)
WRITE_LOG(log, "Starting up round ID [GLOB.round_id].\n-------------------------")
/* ui logging */
/proc/log_tgui(text)
WRITE_LOG(GLOB.tgui_log, text)
/* Close open log handles. This should be called as late as possible, and no logging should hapen after. */
/proc/shutdown_logging()
rustg_log_close_all()
+1 -7
View File
@@ -82,17 +82,11 @@ GLOBAL_VAR_INIT(cmp_field, "name")
/proc/cmp_advdisease_resistance_asc(datum/disease/advance/A, datum/disease/advance/B)
return A.totalResistance() - B.totalResistance()
/proc/cmp_numbered_displays_name_dsc(datum/numbered_display/A, datum/numbered_display/B)
return sorttext(B.sample_object.name, A.sample_object.name)
/proc/cmp_reagents_asc(datum/reagent/a, datum/reagent/b)
return sorttext(initial(b.name),initial(a.name))
/proc/cmp_quirk_asc(datum/quirk/A, datum/quirk/B)
var/a_sign = num2sign(initial(A.value) * -1)
var/b_sign = num2sign(initial(B.value) * -1)
// Neutral traits go last.
// Neutral traits go last
if(a_sign == 0)
a_sign = 2
if(b_sign == 0)
+2 -2
View File
@@ -3,7 +3,7 @@
for(var/file in args)
src << browse_rsc(file)
/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list("txt","log","htm", "html", "md"))
/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list("txt","log","htm", "html"))
var/path = root
for(var/i=0, i<max_iterations, i++)
@@ -20,7 +20,7 @@
continue
path += choice
if(copytext_char(path, -1) != "/") //didn't choose a directory, no need to iterate again
if(copytext(path,-1,0) != "/") //didn't choose a directory, no need to iterate again
break
var/extensions
for(var/i in valid_extensions)
+1 -1
View File
@@ -55,7 +55,7 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list)
GLOB.breasts_size_list = list ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing.
GLOB.genital_fluids_list = list ("Milk", "Water", "Semen", "Femcum", "Honey")
GLOB.genital_fluids_list = list ("milk", "water", "semen", "femcum")
GLOB.gentlemans_organ_names = list("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ", "cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret", "baloney pony", "schlanger")
for(var/K in GLOB.breasts_shapes_list)
var/datum/sprite_accessory/breasts/value = GLOB.breasts_shapes_list[K]
+2 -60
View File
@@ -977,7 +977,7 @@ world
var/icon/atom_icon = new(A.icon, A.icon_state)
if(!letter)
letter = A.name[1]
letter = copytext(A.name, 1, 2)
if(uppercase == 1)
letter = uppertext(letter)
else if(uppercase == -1)
@@ -1105,7 +1105,7 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
WRITE_FILE(GLOB.iconCache[iconKey], icon)
var/iconData = GLOB.iconCache.ExportText(iconKey)
var/list/partial = splittext(iconData, "{")
return replacetext(copytext_char(partial[2], 3, -5), "\n", "")
return replacetext(copytext(partial[2], 3, -5), "\n", "")
/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE)
if (!thing)
@@ -1201,61 +1201,3 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
var/icon/I = getFlatIcon(thing)
return icon2html(I, target)
GLOBAL_LIST_EMPTY(transformation_animation_objects)
/*
* Creates animation that turns current icon into result appearance from top down.
*
* result_appearance - End result appearance/atom/image
* time - Animation duration
* transform_overlay - Appearance/atom/image of effect that moves along the animation - should be horizonatally centered
* reset_after - If FALSE, filters won't be reset and helper vis_objects will not be removed after animation duration expires. Cleanup must be handled by the caller!
*/
/atom/movable/proc/transformation_animation(result_appearance,time = 3 SECONDS,transform_overlay,reset_after=TRUE)
var/list/transformation_objects = GLOB.transformation_animation_objects[src] || list()
//Disappearing part
var/top_part_filter = filter(type="alpha",icon=icon('icons/effects/alphacolors.dmi',"white"),y=0)
filters += top_part_filter
var/filter_index = length(filters)
animate(filters[filter_index],y=-32,time=time)
//Appearing part
var/obj/effect/overlay/appearing_part = new
appearing_part.appearance = result_appearance
appearing_part.appearance_flags |= KEEP_TOGETHER | KEEP_APART
appearing_part.vis_flags = VIS_INHERIT_ID
appearing_part.filters = filter(type="alpha",icon=icon('icons/effects/alphacolors.dmi',"white"),y=0,flags=MASK_INVERSE)
animate(appearing_part.filters[1],y=-32,time=time)
transformation_objects += appearing_part
//Transform effect thing - todo make appearance passed in
if(transform_overlay)
var/obj/transform_effect = new
transform_effect.appearance = transform_overlay
transform_effect.vis_flags = VIS_INHERIT_ID
transform_effect.pixel_y = 16
transform_effect.alpha = 255
transformation_objects += transform_effect
animate(transform_effect,pixel_y=-16,time=time)
animate(alpha=0)
GLOB.transformation_animation_objects[src] = transformation_objects
for(var/A in transformation_objects)
vis_contents += A
if(reset_after)
addtimer(CALLBACK(src,.proc/_reset_transformation_animation,filter_index),time)
/*
* Resets filters and removes transformation animations helper objects from vis contents.
*/
/atom/movable/proc/_reset_transformation_animation(filter_index)
var/list/transformation_objects = GLOB.transformation_animation_objects[src]
for(var/A in transformation_objects)
vis_contents -= A
qdel(A)
transformation_objects.Cut()
GLOB.transformation_animation_objects -= src
if(filters && length(filters) >= filter_index)
filters -= filters[filter_index]
//else
// filters = null
+3
View File
@@ -12,3 +12,6 @@
#define is_reserved_level(z) SSmapping.level_trait(z, ZTRAIT_RESERVED)
#define is_away_level(z) SSmapping.level_trait(z, ZTRAIT_AWAY)
// If true, the singularity cannot strip away asteroid turf on this Z
#define is_planet_level(z) SSmapping.level_trait(z, ZTRAIT_PLANET)
+598 -600
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -28,10 +28,10 @@
. = "does"
/datum/proc/p_theyve(capitalized, temp_gender)
. = p_they(capitalized, temp_gender) + "'" + copytext_char(p_have(temp_gender), 3)
. = p_they(capitalized, temp_gender) + "'" + copytext(p_have(temp_gender), 3)
/datum/proc/p_theyre(capitalized, temp_gender)
. = p_they(capitalized, temp_gender) + "'" + copytext_char(p_are(temp_gender), 2)
. = p_they(capitalized, temp_gender) + "'" + copytext(p_are(temp_gender), 2)
/datum/proc/p_s(temp_gender) //is this a descriptive proc name, or what?
. = "s"
+1 -1
View File
@@ -1,6 +1,6 @@
// Ensure the frequency is within bounds of what it should be sending/receiving at
/proc/sanitize_frequency(frequency, free = FALSE)
frequency = round(frequency)
. = round(frequency)
if(free)
. = CLAMP(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ)
else
+5 -5
View File
@@ -200,7 +200,7 @@
send_news_report()
//tell the nice people on discord what went on before the salt cannon happens.
world.TgsTargetedChatBroadcast("The current round has ended. Please standby for your shift interlude Kinaris News Network's report!", FALSE)
world.TgsTargetedChatBroadcast("The current round has ended. Please standby for your shift interlude Nanotrasen News Network's report!", FALSE)
world.TgsTargetedChatBroadcast(send_news_report(),FALSE)
CHECK_TICK
@@ -383,7 +383,7 @@
for (var/i in GLOB.ai_list)
var/mob/living/silicon/ai/aiPlayer = i
if(aiPlayer.mind)
parts += "<b>[aiPlayer.name]'s</b> laws [aiPlayer.stat != DEAD ? "at the end of the round" : "when it was <span class='redtext'>deactivated</span>"] were:"
parts += "<b>[aiPlayer.name]</b> (Played by: <b>[aiPlayer.mind.key]</b>)'s laws [aiPlayer.stat != DEAD ? "at the end of the round" : "when it was <span class='redtext'>deactivated</span>"] were:"
parts += aiPlayer.laws.get_law_list(include_zeroth=TRUE)
parts += "<b>Total law changes: [aiPlayer.law_change_counter]</b>"
@@ -394,14 +394,14 @@
for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots)
borg_num--
if(robo.mind)
robolist += "<b>[robo.name]</b> [robo.stat == DEAD ? " <span class='redtext'>(Deactivated)</span>" : ""][borg_num ?", ":""]<br>"
robolist += "<b>[robo.name]</b> (Played by: <b>[robo.mind.key]</b>)[robo.stat == DEAD ? " <span class='redtext'>(Deactivated)</span>" : ""][borg_num ?", ":""]<br>"
parts += "[robolist]"
if(!borg_spacer)
borg_spacer = TRUE
for (var/mob/living/silicon/robot/robo in GLOB.silicon_mobs)
if (!robo.connected_ai && robo.mind)
parts += "[borg_spacer?"<br>":""]<b>[robo.name]</b> [(robo.stat != DEAD)? "<span class='greentext'>survived</span> as an AI-less borg!" : "was <span class='redtext'>unable to survive</span> the rigors of being a cyborg without an AI."] Its laws were:"
parts += "[borg_spacer?"<br>":""]<b>[robo.name]</b> (Played by: <b>[robo.mind.key]</b>) [(robo.stat != DEAD)? "<span class='greentext'>survived</span> as an AI-less borg!" : "was <span class='redtext'>unable to survive</span> the rigors of being a cyborg without an AI."] Its laws were:"
if(robo) //How the hell do we lose robo between here and the world messages directly above this?
parts += robo.laws.get_law_list(include_zeroth=TRUE)
@@ -510,7 +510,7 @@
var/jobtext = ""
if(ply.assigned_role)
jobtext = " the <b>[ply.assigned_role]</b>"
var/text = "<b>[ply.hide_ckey ? "<b>[ply.name]</b>[jobtext] " : "[ply.key]</b> was <b>[ply.name]</b>[jobtext] and "]"
var/text = "<b>[ply.key]</b> was <b>[ply.name]</b>[jobtext] and"
if(ply.current)
if(ply.current.stat == DEAD)
text += " <span class='redtext'>died</span>"
+14 -22
View File
@@ -43,30 +43,24 @@
if(!istext(color))
color = ""
var/start = 1 + (text2ascii(color, 1) == 35)
var/start = 1 + (text2ascii(color,1)==35)
var/len = length(color)
var/char = ""
// RRGGBB -> RGB but awful
var/convert_to_shorthand = desired_format == 3 && length_char(color) > 3
var/step_size = 1 + ((len+1)-start != desired_format)
. = ""
var/i = start
while(i <= len)
char = color[i]
switch(text2ascii(char))
if(48 to 57) //numbers 0 to 9
. += char
if(97 to 102) //letters a to f
. += char
if(65 to 70) //letters A to F
. += lowertext(char)
for(var/i=start, i<=len, i+=step_size)
var/ascii = text2ascii(color,i)
switch(ascii)
if(48 to 57)
. += ascii2text(ascii) //numbers 0 to 9
if(97 to 102)
. += ascii2text(ascii) //letters a to f
if(65 to 70)
. += ascii2text(ascii+32) //letters A to F - translates to lowercase
else
break
i += length(char)
if(convert_to_shorthand && i <= len) //skip next one
i += length(color[i])
if(length_char(.) != desired_format)
if(length(.) != desired_format)
if(default)
return default
return crunch + repeat_string(desired_format, "0")
@@ -74,9 +68,7 @@
return crunch + .
/proc/sanitize_ooccolor(color)
if(length(color) != length_char(color))
CRASH("Invalid characters in color '[color]'")
var/list/HSL = rgb2hsl(hex2num(copytext(color, 2, 4)), hex2num(copytext(color, 4, 6)), hex2num(copytext(color, 6, 8)))
var/list/HSL = rgb2hsl(hex2num(copytext(color,2,4)),hex2num(copytext(color,4,6)),hex2num(copytext(color,6,8)))
HSL[3] = min(HSL[3],0.4)
var/list/RGB = hsl2rgb(arglist(HSL))
return "#[num2hex(RGB[1],2)][num2hex(RGB[2],2)][num2hex(RGB[3],2)]"
return "#[num2hex(RGB[1],2)][num2hex(RGB[2],2)][num2hex(RGB[3],2)]"
+1 -1
View File
@@ -52,6 +52,6 @@
if(bad_chars)
bad_match = url_encode(bad_chars_regex.match)
scrubbed_url += bad_match
last_good = bad_chars + length(bad_chars_regex.match)
last_good = bad_chars + length(bad_match)
while(bad_chars)
. = scrubbed_url
+234 -221
View File
@@ -40,16 +40,10 @@
for(var/char in repl_chars)
var/index = findtext(t, char)
while(index)
t = copytext(t, 1, index) + repl_chars[char] + copytext(t, index + length(char))
index = findtext(t, char, index + length(char))
t = copytext(t, 1, index) + repl_chars[char] + copytext(t, index+1)
index = findtext(t, char, index+1)
return t
/proc/sanitize_name(t,list/repl_chars = null)
if(t == "space" || t == "floor" || t == "wall" || t == "r-wall" || t == "monkey" || t == "unknown" || t == "inactive ai") //prevents these common metagamey names
alert("Invalid name.")
return ""
return sanitize(t)
/proc/sanitize_filename(t)
return sanitize_simple(t, list("\n"="", "\t"="", "/"="", "\\"="", "?"="", "%"="", "*"="", ":"="", "|"="", "\""="", "<"="", ">"=""))
@@ -69,28 +63,22 @@
//Returns null if there is any bad text in the string
/proc/reject_bad_text(text, max_length = 512, ascii_only = TRUE)
var/char_count = 0
var/non_whitespace = FALSE
var/lenbytes = length(text)
var/char = ""
for(var/i = 1, i <= lenbytes, i += length(char))
char = text[i]
char_count++
if(char_count > max_length)
return
switch(text2ascii(char))
if(62,60,92,47) // <, >, \, /
return
/proc/reject_bad_text(text, max_length=512)
if(length(text) > max_length)
return //message too long
var/non_whitespace = 0
for(var/i=1, i<=length(text), i++)
switch(text2ascii(text,i))
if(62,60,92,47)
return //rejects the text if it contains these bad characters: <, >, \ or /
if(127 to 255)
return //rejects weird letters like
if(0 to 31)
return
return //more weird stuff
if(32)
continue //whitespace
if(127 to INFINITY)
if(ascii_only)
return
else
non_whitespace = TRUE
non_whitespace = 1
if(non_whitespace)
return text //only accepts the text if it has some non-spaces
@@ -113,84 +101,74 @@
else
return trim(html_encode(name), max_length)
#define NO_CHARS_DETECTED 0
#define SPACES_DETECTED 1
#define SYMBOLS_DETECTED 2
#define NUMBERS_DETECTED 3
#define LETTERS_DETECTED 4
//Filters out undesirable characters from names
/proc/reject_bad_name(t_in, allow_numbers = FALSE, max_length = MAX_NAME_LEN, ascii_only = TRUE)
if(!t_in)
return //Rejects the input if it is null
/proc/reject_bad_name(t_in, allow_numbers=0, max_length=MAX_NAME_LEN)
if(!t_in || length(t_in) > max_length)
return //Rejects the input if it is null or if it is longer then the max length allowed
var/number_of_alphanumeric = 0
var/last_char_group = NO_CHARS_DETECTED
var/number_of_alphanumeric = 0
var/last_char_group = 0
var/t_out = ""
var/t_len = length(t_in)
var/charcount = 0
var/char = ""
for(var/i = 1, i <= t_len, i += length(char))
char = t_in[i]
switch(text2ascii(char))
for(var/i=1, i<=length(t_in), i++)
var/ascii_char = text2ascii(t_in,i)
switch(ascii_char)
// A .. Z
if(65 to 90) //Uppercase Letters
t_out += ascii2text(ascii_char)
number_of_alphanumeric++
last_char_group = LETTERS_DETECTED
last_char_group = 4
// a .. z
if(97 to 122) //Lowercase Letters
if(last_char_group == NO_CHARS_DETECTED || last_char_group == SPACES_DETECTED || last_char_group == SYMBOLS_DETECTED) //start of a word
char = uppertext(char)
if(last_char_group<2)
t_out += ascii2text(ascii_char-32) //Force uppercase first character
else
t_out += ascii2text(ascii_char)
number_of_alphanumeric++
last_char_group = LETTERS_DETECTED
last_char_group = 4
// 0 .. 9
if(48 to 57) //Numbers
if(last_char_group == NO_CHARS_DETECTED || !allow_numbers) //suppress at start of string
if(!last_char_group)
continue //suppress at start of string
if(!allow_numbers)
continue
t_out += ascii2text(ascii_char)
number_of_alphanumeric++
last_char_group = NUMBERS_DETECTED
last_char_group = 3
// ' - .
if(39,45,46) //Common name punctuation
if(last_char_group == NO_CHARS_DETECTED)
if(!last_char_group)
continue
last_char_group = SYMBOLS_DETECTED
t_out += ascii2text(ascii_char)
last_char_group = 2
// ~ | @ : # $ % & * +
if(126,124,64,58,35,36,37,38,42,43) //Other symbols that we'll allow (mainly for AI)
if(last_char_group == NO_CHARS_DETECTED || !allow_numbers) //suppress at start of string
if(!last_char_group)
continue //suppress at start of string
if(!allow_numbers)
continue
last_char_group = SYMBOLS_DETECTED
t_out += ascii2text(ascii_char)
last_char_group = 2
//Space
if(32)
if(last_char_group == NO_CHARS_DETECTED || last_char_group == SPACES_DETECTED) //suppress double-spaces and spaces at start of string
continue
last_char_group = SPACES_DETECTED
if(127 to INFINITY)
if(ascii_only)
continue
last_char_group = SYMBOLS_DETECTED //for now, we'll treat all non-ascii characters like symbols even though most are letters
if(last_char_group <= 1)
continue //suppress double-spaces and spaces at start of string
t_out += ascii2text(ascii_char)
last_char_group = 1
else
continue
t_out += char
charcount++
if(charcount >= max_length)
break
return
if(number_of_alphanumeric < 2)
return //protects against tiny names like "A" and also names like "' ' ' ' ' ' ' '"
if(last_char_group == SPACES_DETECTED)
t_out = copytext_char(t_out, 1, -1) //removes the last character (in this case a space)
if(last_char_group == 1)
t_out = copytext(t_out,1,length(t_out)) //removes the last character (in this case a space)
for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai")) //prevents these common metagamey names
if(cmptext(t_out,bad_name))
@@ -198,11 +176,6 @@
return t_out
#undef NO_CHARS_DETECTED
#undef SPACES_DETECTED
#undef NUMBERS_DETECTED
#undef LETTERS_DETECTED
//html_encode helper proc that returns the smallest non null of two numbers
//or 0 if they're both null (needed because of findtext returning 0 when a value is not present)
/proc/non_zero_min(a, b)
@@ -212,6 +185,39 @@
return a
return (a < b ? a : b)
/*
* Text searches
*/
//Checks the beginning of a string for a specified sub-string
//Returns the position of the substring or 0 if it was not found
/proc/dd_hasprefix(text, prefix)
var/start = 1
var/end = length(prefix) + 1
return findtext(text, prefix, start, end)
//Checks the beginning of a string for a specified sub-string. This proc is case sensitive
//Returns the position of the substring or 0 if it was not found
/proc/dd_hasprefix_case(text, prefix)
var/start = 1
var/end = length(prefix) + 1
return findtextEx(text, prefix, start, end)
//Checks the end of a string for a specified substring.
//Returns the position of the substring or 0 if it was not found
/proc/dd_hassuffix(text, suffix)
var/start = length(text) - length(suffix)
if(start)
return findtext(text, suffix, start, null)
return
//Checks the end of a string for a specified substring. This proc is case sensitive
//Returns the position of the substring or 0 if it was not found
/proc/dd_hassuffix_case(text, suffix)
var/start = length(text) - length(suffix)
if(start)
return findtextEx(text, suffix, start, null)
//Checks if any of a given list of needles is in the haystack
/proc/text_in_list(haystack, list/needle_list, start=1, end=0)
for(var/needle in needle_list)
@@ -226,19 +232,23 @@
return 1
return 0
//Adds 'char' ahead of 'text' until there are 'count' characters total
/proc/add_leading(text, count, char = " ")
text = "[text]"
var/charcount = count - length_char(text)
var/list/chars_to_add[max(charcount + 1, 0)]
return jointext(chars_to_add, char) + text
//Adds 'u' number of zeros ahead of the text 't'
/proc/add_zero(t, u)
while (length(t) < u)
t = "0[t]"
return t
//Adds 'char' behind 'text' until there are 'count' characters total
/proc/add_trailing(text, count, char = " ")
text = "[text]"
var/charcount = count - length_char(text)
var/list/chars_to_add[max(charcount + 1, 0)]
return text + jointext(chars_to_add, char)
//Adds 'u' number of spaces ahead of the text 't'
/proc/add_lspace(t, u)
while(length(t) < u)
t = " [t]"
return t
//Adds 'u' number of spaces behind the text 't'
/proc/add_tspace(t, u)
while(length(t) < u)
t = "[t] "
return t
//Returns a string with reserved characters and spaces before the first letter removed
/proc/trim_left(text)
@@ -258,41 +268,57 @@
//Returns a string with reserved characters and spaces before the first word and after the last word removed.
/proc/trim(text, max_length)
if(max_length)
text = copytext_char(text, 1, max_length)
text = copytext(text, 1, max_length)
return trim_left(trim_right(text))
//Returns a string with the first element of the string capitalized.
/proc/capitalize(t as text)
. = t
if(t)
. = t[1]
return uppertext(.) + copytext(t, 1 + length(.))
return uppertext(copytext(t, 1, 2)) + copytext(t, 2)
//Centers text by adding spaces to either side of the string.
/proc/dd_centertext(message, length)
var/new_message = message
var/size = length(message)
var/delta = length - size
if(size == length)
return new_message
if(size > length)
return copytext(new_message, 1, length + 1)
if(delta == 1)
return new_message + " "
if(delta % 2)
new_message = " " + new_message
delta--
var/spaces = add_lspace("",delta/2-1)
return spaces + new_message + spaces
//Limits the length of the text. Note: MAX_MESSAGE_LEN and MAX_NAME_LEN are widely used for this purpose
/proc/dd_limittext(message, length)
var/size = length(message)
if(size <= length)
return message
return copytext(message, 1, length + 1)
/proc/stringmerge(text,compare,replace = "*")
//This proc fills in all spaces with the "replace" var (* by default) with whatever
//is in the other string at the same spot (assuming it is not a replace char).
//This is used for fingerprints
var/newtext = text
var/text_it = 1 //iterators
var/comp_it = 1
var/newtext_it = 1
var/text_length = length(text)
var/comp_length = length(compare)
while(comp_it <= comp_length && text_it <= text_length)
var/a = text[text_it]
var/b = compare[comp_it]
if(length(text) != length(compare))
return 0
for(var/i = 1, i < length(text), i++)
var/a = copytext(text,i,i+1)
var/b = copytext(compare,i,i+1)
//if it isn't both the same letter, or if they are both the replacement character
//(no way to know what it was supposed to be)
if(a != b)
if(a == replace) //if A is the replacement char
newtext = copytext(newtext, 1, newtext_it) + b + copytext(newtext, newtext_it + length(newtext[newtext_it]))
newtext = copytext(newtext,1,i) + b + copytext(newtext, i+1)
else if(b == replace) //if B is the replacement char
newtext = copytext(newtext, 1, newtext_it) + a + copytext(newtext, newtext_it + length(newtext[newtext_it]))
newtext = copytext(newtext,1,i) + a + copytext(newtext, i+1)
else //The lists disagree, Uh-oh!
return 0
text_it += length(a)
comp_it += length(b)
newtext_it += length(newtext[newtext_it])
return newtext
/proc/stringpercent(text,character = "*")
@@ -301,21 +327,16 @@
if(!text || !character)
return 0
var/count = 0
var/lentext = length(text)
var/a = ""
for(var/i = 1, i <= lentext, i += length(a))
a = text[i]
for(var/i = 1, i <= length(text), i++)
var/a = copytext(text,i,i+1)
if(a == character)
count++
return count
/proc/reverse_text(text = "")
var/new_text = ""
var/lentext = length(text)
var/letter = ""
for(var/i = 1, i <= lentext, i += length(letter))
letter = text[i]
new_text = letter + new_text
for(var/i = length(text); i > 0; i--)
new_text += copytext(text, i, i+1)
return new_text
GLOBAL_LIST_INIT(zero_character_only, list("0"))
@@ -338,6 +359,15 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
/proc/random_color()
return random_string(6, GLOB.hex_characters)
/proc/add_zero2(t, u)
var/temp1
while (length(t) < u)
t = "0[t]"
temp1 = t
if (length(t) > u)
temp1 = copytext(t,2,u+1)
return temp1
//merges non-null characters (3rd argument) from "from" into "into". Returns result
//e.g. into = "Hello World"
// from = "Seeya______"
@@ -350,48 +380,41 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
into = ""
if(!istext(from))
from = ""
var/null_ascii = istext(null_char) ? text2ascii(null_char, 1) : null_char
var/copying_into = FALSE
var/char = ""
var/start = 1
var/end_from = length(from)
var/end_into = length(into)
var/into_it = 1
var/from_it = 1
while(from_it <= end_from && into_it <= end_into)
char = from[from_it]
if(text2ascii(char) == null_ascii)
if(!copying_into)
. += copytext(from, start, from_it)
start = into_it
copying_into = TRUE
else
if(copying_into)
. += copytext(into, start, into_it)
start = from_it
copying_into = FALSE
into_it += length(into[into_it])
from_it += length(char)
var/null_ascii = istext(null_char) ? text2ascii(null_char,1) : null_char
if(copying_into)
. += copytext(into, start)
var/previous = 0
var/start = 1
var/end = length(into) + 1
for(var/i=1, i<end, i++)
var/ascii = text2ascii(from, i)
if(ascii == null_ascii)
if(previous != 1)
. += copytext(from, start, i)
start = i
previous = 1
else
if(previous != 0)
. += copytext(into, start, i)
start = i
previous = 0
if(previous == 0)
. += copytext(from, start, end)
else
. += copytext(from, start, from_it)
if(into_it <= end_into)
. += copytext(into, into_it)
. += copytext(into, start, end)
//finds the first occurrence of one of the characters from needles argument inside haystack
//it may appear this can be optimised, but it really can't. findtext() is so much faster than anything you can do in byondcode.
//stupid byond :(
/proc/findchar(haystack, needles, start=1, end=0)
var/char = ""
var/temp
var/len = length(needles)
for(var/i = 1, i <= len, i += length(char))
char = needles[i]
. = findtextEx(haystack, char, start, end)
if(.)
return
return 0
for(var/i=1, i<=len, i++)
temp = findtextEx(haystack, ascii2text(text2ascii(needles,i)), start, end) //Note: ascii2text(text2ascii) is faster than copytext()
if(temp)
end = temp
return end
/proc/parsemarkdown_basic_step1(t, limited=FALSE)
if(length(t) <= 0)
@@ -549,28 +572,23 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
return t
/proc/text2charlist(text)
var/char = ""
var/lentext = length(text)
. = list()
for(var/i = 1, i <= lentext, i += length(char))
char = text[i]
. += char
#define string2charlist(string) (splittext(string, regex("(.)")) - splittext(string, ""))
/proc/rot13(text = "")
var/lentext = length(text)
var/char = ""
var/ascii = 0
. = ""
for(var/i = 1, i <= lentext, i += length(char))
char = text[i]
ascii = text2ascii(char)
switch(ascii)
if(65 to 77, 97 to 109) //A to M, a to m
ascii += 13
if(78 to 90, 110 to 122) //N to Z, n to z
ascii -= 13
. += ascii2text(ascii)
var/list/textlist = string2charlist(text)
var/list/result = list()
for(var/c in textlist)
var/ca = text2ascii(c)
if(ca >= text2ascii("a") && ca <= text2ascii("m"))
ca += 13
else if(ca >= text2ascii("n") && ca <= text2ascii("z"))
ca -= 13
else if(ca >= text2ascii("A") && ca <= text2ascii("M"))
ca += 13
else if(ca >= text2ascii("N") && ca <= text2ascii("Z"))
ca -= 13
result += ascii2text(ca)
return jointext(result, "")
//Takes a list of values, sanitizes it down for readability and character count,
//then exports it as a json file at data/npc_saves/[filename].json.
@@ -582,8 +600,7 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
return
//Regular expressions are, as usual, absolute magic
//Any characters outside of 32 (space) to 126 (~) because treating things you don't understand as "magic" is really stupid
var/regex/all_invalid_symbols = new(@"[^ -~]{1}")
var/regex/all_invalid_symbols = new("\[^ -~]+")
var/list/accepted = list()
for(var/string in proposed)
@@ -591,44 +608,34 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
continue
var/buffer = ""
var/early_culling = TRUE
var/lentext = length(string)
var/let = ""
for(var/pos = 1, pos <= lentext, pos += length(let))
let = string[pos]
if(!findtext(let, GLOB.is_alphanumeric))
for(var/pos = 1, pos <= length(string), pos++)
var/let = copytext(string, pos, (pos + 1) % length(string))
if(early_culling && !findtext(let,GLOB.is_alphanumeric))
continue
early_culling = FALSE
buffer = copytext(string, pos)
break
if(early_culling) //Never found any letters! Bail!
buffer += let
if(!findtext(buffer,GLOB.is_alphanumeric))
continue
var/punctbuffer = ""
var/cutoff = 0
lentext = length_char(buffer)
for(var/pos = 1, pos <= lentext, pos++)
let = copytext_char(buffer, -pos, -pos + 1)
if(!findtext(let, GLOB.is_punctuation)) //This won't handle things like Nyaaaa!~ but that's fine
var/cutoff = length(buffer)
for(var/pos = length(buffer), pos >= 0, pos--)
var/let = copytext(buffer, pos, (pos + 1) % length(buffer))
if(findtext(let,GLOB.is_alphanumeric))
break
punctbuffer += let
cutoff += length(let)
if(findtext(let,GLOB.is_punctuation))
punctbuffer = let + punctbuffer //Note this isn't the same thing as using +=
cutoff = pos
if(punctbuffer) //We clip down excessive punctuation to get the letter count lower and reduce repeats. It's not perfect but it helps.
var/exclaim = FALSE
var/question = FALSE
var/periods = 0
lentext = length(punctbuffer)
for(var/pos = 1, pos <= lentext, pos += length(let))
let = punctbuffer[pos]
if(!exclaim && findtext(let, "!"))
for(var/pos = length(punctbuffer), pos >= 0, pos--)
var/punct = copytext(punctbuffer, pos, (pos + 1) % length(punctbuffer))
if(!exclaim && findtext(punct,"!"))
exclaim = TRUE
if(question)
break
if(!question && findtext(let, "?"))
if(!question && findtext(punct,"?"))
question = TRUE
if(exclaim)
break
if(!exclaim && !question && findtext(let, ".")) //? and ! take priority over periods
if(!exclaim && !question && findtext(punct,"."))
periods += 1
if(exclaim)
if(question)
@@ -637,13 +644,15 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
punctbuffer = "!"
else if(question)
punctbuffer = "?"
else if(periods > 1)
punctbuffer = "..."
else
punctbuffer = "" //Grammer nazis be damned
buffer = copytext(buffer, 1, -cutoff) + punctbuffer
lentext = length_char(buffer)
if(!buffer || lentext > 280 || lentext <= cullshort || (buffer in accepted))
else if(periods)
if(periods > 1)
punctbuffer = "..."
else
punctbuffer = "" //Grammer nazis be damned
buffer = copytext(buffer, 1, cutoff) + punctbuffer
if(!findtext(buffer,GLOB.is_alphanumeric))
continue
if(!buffer || length(buffer) > 280 || length(buffer) <= cullshort || buffer in accepted)
continue
accepted += buffer
@@ -680,7 +689,7 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
var/leng = length(string)
var/next_space = findtext(string, " ", next_backslash + length(string[next_backslash]))
var/next_space = findtext(string, " ", next_backslash + 1)
if(!next_space)
next_space = leng - next_backslash
@@ -688,8 +697,8 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
return string
var/base = next_backslash == 1 ? "" : copytext(string, 1, next_backslash)
var/macro = lowertext(copytext(string, next_backslash + length(string[next_space]), next_space))
var/rest = next_backslash > leng ? "" : copytext(string, next_space + length(string[next_space]))
var/macro = lowertext(copytext(string, next_backslash + 1, next_space))
var/rest = next_backslash > leng ? "" : copytext(string, next_space + 1)
//See https://secure.byond.com/docs/ref/info.html#/DM/text/macros
switch(macro)
@@ -761,24 +770,28 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
return "[number]\th"
/proc/unintelligize(message)
var/regex/word_boundaries = regex(@"\b[\S]+\b", "g")
var/prefix = message[1]
var/prefix=copytext(message,1,2)
if(prefix == ";")
message = copytext(message, 1 + length(prefix))
else if(prefix in list(":", "#"))
prefix += message[1 + length(prefix)]
message = copytext(message, length(prefix))
message = copytext(message,2)
else if(prefix in list(":","#"))
prefix += copytext(message,2,3)
message = copytext(message,3)
else
prefix = ""
prefix=""
var/list/words = splittext(message," ")
var/list/rearranged = list()
while(word_boundaries.Find(message))
var/cword = word_boundaries.match
for(var/i=1;i<=words.len;i++)
var/cword = pick(words)
words.Remove(cword)
var/suffix = copytext(cword,length(cword)-1,length(cword))
while(length(cword)>0 && suffix in list(".",",",";","!",":","?"))
cword = copytext(cword,1 ,length(cword)-1)
suffix = copytext(cword,length(cword)-1,length(cword) )
if(length(cword))
rearranged += cword
shuffle_inplace(rearranged)
return "[prefix][jointext(rearranged, " ")]"
message = "[prefix][jointext(rearranged," ")]"
. = message
#define is_alpha(X) ((text2ascii(X) <= 122) && (text2ascii(X) >= 97))
#define is_digit(X) ((length(X) == 1) && (length(text2num(X)) == 1))
#define is_digit(X) ((length(X) == 1) && (length(text2num(X)) == 1))
+4 -5
View File
@@ -8,15 +8,14 @@
index = findtext(t, char)
return t
/proc/TextPreview(string, len = 40)
var/char_len = length_char(string)
if(char_len <= len)
if(char_len)
proc/TextPreview(var/string,var/len=40)
if(length(string) <= len)
if(!length(string))
return "\[...\]"
else
return string
else
return "[copytext_char(string, 1, 37)]..."
return "[copytext(string, 1, 37)]..."
GLOBAL_LIST_EMPTY(mentorlog)
GLOBAL_PROTECT(mentorlog)
+5 -5
View File
@@ -532,17 +532,17 @@
//assumes format #RRGGBB #rrggbb
/proc/color_hex2num(A)
if(!A || length(A) != length_char(A))
if(!A)
return 0
var/R = hex2num(copytext(A, 2, 4))
var/G = hex2num(copytext(A, 4, 6))
var/B = hex2num(copytext(A, 6, 0))
var/R = hex2num(copytext(A,2,4))
var/G = hex2num(copytext(A,4,6))
var/B = hex2num(copytext(A,6,0))
return R+G+B
//word of warning: using a matrix like this as a color value will simplify it back to a string after being set
/proc/color_hex2color_matrix(string)
var/length = length(string)
if((length != 7 && length != 9) || length != length_char(string))
if(length != 7 && length != 9)
return color_matrix_identity()
var/r = hex2num(copytext(string, 2, 4))/255
var/g = hex2num(copytext(string, 4, 6))/255
+20 -61
View File
@@ -6,18 +6,25 @@
//Inverts the colour of an HTML string
/proc/invertHTML(HTMLstring)
if(!istext(HTMLstring))
if (!( istext(HTMLstring) ))
CRASH("Given non-text argument!")
return
else if(length(HTMLstring) != 7)
CRASH("Given non-HTML argument!")
return
else if(length_char(HTMLstring) != 7)
CRASH("Given non-hex symbols in argument!")
else
if (length(HTMLstring) != 7)
CRASH("Given non-HTML argument!")
return
var/textr = copytext(HTMLstring, 2, 4)
var/textg = copytext(HTMLstring, 4, 6)
var/textb = copytext(HTMLstring, 6, 8)
return rgb(255 - hex2num(textr), 255 - hex2num(textg), 255 - hex2num(textb))
var/r = hex2num(textr)
var/g = hex2num(textg)
var/b = hex2num(textb)
textr = num2hex(255 - r, 2)
textg = num2hex(255 - g, 2)
textb = num2hex(255 - b, 2)
return text("#[][][]", textr, textg, textb)
return
/proc/Get_Angle(atom/movable/start,atom/movable/end)//For beams.
if(!start || !end)
@@ -177,15 +184,15 @@ Turf and target are separate in case you want to teleport some distance from a t
//Returns whether or not a player is a guest using their ckey as an input
/proc/IsGuestKey(key)
if (findtext(key, "Guest-", 1, 7) != 1) //was findtextEx
return FALSE
return 0
var/i, ch, len = length(key)
for (i = 7, i <= len, ++i) //we know the first 6 chars are Guest-
for (i = 7, i <= len, ++i)
ch = text2ascii(key, i)
if (ch < 48 || ch > 57) //0-9
return FALSE
return TRUE
if (ch < 48 || ch > 57)
return 0
return 1
//Generalised helper proc for letting mobs rename themselves. Used to be clname() and ainame()
/mob/proc/apply_pref_name(role, client/C)
@@ -1414,7 +1421,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
/proc/GUID()
var/const/GUID_VERSION = "b"
var/const/GUID_VARIANT = "d"
var/node_id = copytext_char(md5("[rand()*rand(1,9999999)][world.name][world.hub][world.hub_password][world.internet_address][world.address][world.contents.len][world.status][world.port][rand()*rand(1,9999999)]"), 1, 13)
var/node_id = copytext(md5("[rand()*rand(1,9999999)][world.name][world.hub][world.hub_password][world.internet_address][world.address][world.contents.len][world.status][world.port][rand()*rand(1,9999999)]"), 1, 13)
var/time_high = "[num2hex(text2num(time2text(world.realtime,"YYYY")), 2)][num2hex(world.realtime, 6)]"
@@ -1558,10 +1565,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
if(condition.Invoke(i))
. |= i
/proc/CallAsync(datum/source, proctype, list/arguments)
set waitfor = FALSE
return call(source, proctype)(arglist(arguments))
/proc/num2sign(numeric)
if(numeric > 0)
return 1
@@ -1569,47 +1572,3 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
return -1
else
return 0
// Converts browser keycodes to BYOND keycodes.
/proc/browser_keycode_to_byond(keycode)
keycode = text2num(keycode)
switch(keycode)
// letters and numbers
if(65 to 90, 48 to 57)
return ascii2text(keycode)
if(17)
return "Ctrl"
if(18)
return "Alt"
if(16)
return "Shift"
if(37)
return "West"
if(38)
return "North"
if(39)
return "East"
if(40)
return "South"
if(45)
return "Insert"
if(46)
return "Delete"
if(36)
return "Northwest"
if(35)
return "Southwest"
if(33)
return "Northeast"
if(34)
return "Southeast"
if(112 to 123)
return "F[keycode-111]"
if(96 to 105)
return "Numpad[keycode-96]"
if(188)
return ","
if(190)
return "."
if(189)
return "-"
-20
View File
@@ -39,26 +39,6 @@
#error You need version 512 or higher
#endif
//Compatability -- These procs were added in 513.1493, not 513.1490
//Which really shoulda bumped us up to 514 right then and there but instead Lummox is a dumb dumb
#if DM_BUILD < 1493
#define length_char(args...) length(args)
#define text2ascii_char(args...) text2ascii(args)
#define copytext_char(args...) copytext(args)
#define splittext_char(args...) splittext(args)
#define spantext_char(args...) spantext(args)
#define nonspantext_char(args...) nonspantext(args)
#define findtext_char(args...) findtext(args)
#define findtextEx_char(args...) findtextEx(args)
#define findlasttext_char(args...) findlasttext(args)
#define findlasttextEx_char(args...) findlasttextEx(args)
#define replacetext_char(args...) replacetext(args)
#define replacetextEx_char(args...) replacetextEx(args)
// /regex procs
#define Find_char(args...) Find(args)
#define Replace_char(args...) Replace(args)
#endif
//Additional code for the above flags.
#ifdef TESTING
#warn compiling in TESTING mode. testing() debug messages will be visible.
+2 -2
View File
@@ -144,8 +144,6 @@ GLOBAL_LIST_INIT(bitfields, list(
"THICKMATERIAL" = THICKMATERIAL,
"VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE,
"VOICEBOX_DISABLED" = VOICEBOX_DISABLED,
"IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS,
"SCAN_REAGENTS" = SCAN_REAGENTS
),
"tesla_flags" = list(
"TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE,
@@ -182,6 +180,7 @@ GLOBAL_LIST_INIT(bitfields, list(
"CAN_CARRY" = CAN_CARRY,
"CAN_RESIST" = CAN_RESIST
),
"chemical_flags" = list(
"REAGENT_DEAD_PROCESS" = REAGENT_DEAD_PROCESS,
"REAGENT_DONOTSPLIT" = REAGENT_DONOTSPLIT,
@@ -196,6 +195,7 @@ GLOBAL_LIST_INIT(bitfields, list(
"REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE,
"REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE
),
"organ_flags" = list(
"ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC,
"ORGAN_FROZEN" = ORGAN_FROZEN,
-4
View File
@@ -198,7 +198,3 @@ GLOBAL_LIST_INIT(numbers_as_words, world.file2list("strings/numbers_as_words.txt
GLOBAL_LIST_INIT(station_numerals, greek_letters + phonetic_alphabet + numbers_as_words + generate_number_strings())
GLOBAL_LIST_INIT(admiral_messages, list("Do you know how expensive these stations are?","Stop wasting my time.","I was sleeping, thanks a lot.","Stand and fight you cowards!","You knew the risks coming in.","Stop being paranoid.","Whatever's broken just build a new one.","No.", "<i>null</i>","<i>Error: No comment given.</i>", "It's a good day to die!"))
GLOBAL_LIST_INIT(speech_verbs, list("default", "says", "gibbers", "gekkers", "states", "chitters", "declares", "bellows", "buzzes" ,"beeps", "chirps" ,"hisses" ,"poofs" ,"rattles", "mewls", "barks", "blorbles", "squeaks", "squawks", "flutters", "mrowls"))
GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc, "kitty tongue" = /obj/item/organ/tongue/kitty))
@@ -120,21 +120,3 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/autosurgeon/womb = 1,
/obj/item/toy/plush/random = 1
))
GLOBAL_LIST_INIT(ratking_trash, list(//Garbage: used by the regal rat mob when spawning garbage.
/obj/item/cigbutt,
/obj/item/trash/cheesie,
/obj/item/trash/candy,
/obj/item/trash/chips,
/obj/item/trash/pistachios,
/obj/item/trash/plate,
/obj/item/trash/popcorn,
/obj/item/trash/raisins,
/obj/item/trash/sosjerky,
/obj/item/trash/syndi_cakes))
GLOBAL_LIST_INIT(ratking_coins, list(//Coins: Used by the regal rat mob when spawning coins.
/obj/item/coin/iron,
/obj/item/coin/silver,
/obj/item/coin/gold,
/obj/item/coin/plasma))
+8 -3
View File
@@ -109,7 +109,12 @@ GLOBAL_LIST_INIT(all_types_bloods,list(
"BUG"
))
GLOBAL_LIST_INIT(blood_reagent_types, list(
/datum/reagent/blood,
/datum/reagent/blood/jellyblood
GLOBAL_LIST_INIT(blood_types, list(
"blood",
"jellyblood"
))
GLOBAL_LIST_INIT(blood_id_types, list(
"blood" = /datum/reagent/blood,
"jellyblood" = /datum/reagent/blood/jellyblood
))
-4
View File
@@ -13,8 +13,6 @@
#define POLL_IGNORE_GOLEM "golem"
#define POLL_IGNORE_SWARMER "swarmer"
#define POLL_IGNORE_DRONE "drone"
#define POLL_IGNORE_IMAGINARYFRIEND "imaginary_friend"
#define POLL_IGNORE_SPLITPERSONALITY "split_personality"
#define POLL_IGNORE_DEMON "demon"
#define POLL_IGNORE_WIZARD "wizard"
@@ -32,8 +30,6 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list(
POLL_IGNORE_GOLEM = "Golems",
POLL_IGNORE_SWARMER = "Swarmer shells",
POLL_IGNORE_DRONE = "Drone shells",
POLL_IGNORE_IMAGINARYFRIEND = "Imaginary Friend",
POLL_IGNORE_SPLITPERSONALITY = "Split Personality",
POLL_IGNORE_DEMON = "Demons",
POLL_IGNORE_WIZARD = "Wizards",
))
-5
View File
@@ -28,8 +28,6 @@ GLOBAL_VAR(world_job_debug_log)
GLOBAL_PROTECT(world_job_debug_log)
GLOBAL_VAR(world_virus_log)
GLOBAL_PROTECT(world_virus_log)
GLOBAL_VAR(world_map_error_log)
GLOBAL_PROTECT(world_map_error_log)
GLOBAL_LIST_EMPTY(bombers)
GLOBAL_PROTECT(bombers)
@@ -40,9 +38,6 @@ GLOBAL_PROTECT(lastsignalers)
GLOBAL_LIST_EMPTY(lawchanges) //Stores who uploaded laws to which silicon-based lifeform, and what the law was
GLOBAL_PROTECT(lawchanges)
GLOBAL_VAR(tgui_log)
GLOBAL_PROTECT(tgui_log)
GLOBAL_LIST_EMPTY(combatlog)
GLOBAL_PROTECT(combatlog)
GLOBAL_LIST_EMPTY(IClog)
+11 -10
View File
@@ -114,8 +114,7 @@
/mob/living/silicon/ai/CtrlClickOn(var/atom/A)
A.AICtrlClick(src)
/mob/living/silicon/ai/AltClickOn(var/atom/A)
if(!A.AIAltClick(src))
altclick_listed_turf(A)
A.AIAltClick(src)
/*
The following criminally helpful code is just the previous code cleaned up;
@@ -126,10 +125,9 @@
/* Atom Procs */
/atom/proc/AICtrlClick()
return
/atom/proc/AIAltClick(mob/living/silicon/ai/user)
return AltClick(user)
AltClick(user)
return
/atom/proc/AIShiftClick()
return
/atom/proc/AICtrlShiftClick()
@@ -140,7 +138,10 @@
if(obj_flags & EMAGGED)
return
toggle_bolt(usr)
if(locked)
bolt_raise(usr)
else
bolt_drop(usr)
/obj/machinery/door/airlock/AIAltClick() // Eletrifies doors.
if(obj_flags & EMAGGED)
@@ -150,7 +151,6 @@
shock_perm(usr)
else
shock_restore(usr)
return TRUE
/obj/machinery/door/airlock/AIShiftClick() // Opens and closes doors!
if(obj_flags & EMAGGED)
@@ -162,7 +162,10 @@
if(obj_flags & EMAGGED)
return
toggle_emergency(usr)
if(!emergency)
emergency_on(usr)
else
emergency_off(usr)
/* APC */
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
@@ -182,12 +185,10 @@
return
toggle_on()
add_fingerprint(usr)
return TRUE
/* Holopads */
/obj/machinery/holopad/AIAltClick(mob/living/silicon/ai/user)
hangup_all_calls()
return TRUE
//
// Override TurfAdjacent for AltClicking
+520 -518
View File
File diff suppressed because it is too large Load Diff
+176 -185
View File
@@ -1,185 +1,176 @@
/*
Cyborg ClickOn()
Cyborgs have no range restriction on attack_robot(), because it is basically an AI click.
However, they do have a range restriction on item use, so they cannot do without the
adjacency code.
*/
/mob/living/silicon/robot/ClickOn(var/atom/A, var/params)
if(world.time <= next_click)
return
next_click = world.time + 1
if(check_click_intercept(params,A))
return
if(stat || lockcharge || IsKnockdown() || IsStun() || IsUnconscious())
return
var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A)
return
if(modifiers["shift"] && modifiers["middle"])
ShiftMiddleClickOn(A)
return
if(modifiers["middle"])
MiddleClickOn(A)
return
if(modifiers["shift"])
ShiftClickOn(A)
return
if(modifiers["alt"]) // alt and alt-gr (rightalt)
AltClickOn(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
if(next_move >= world.time)
return
face_atom(A) // change direction to face what you clicked on
/*
cyborg restrained() currently does nothing
if(restrained())
RestrainedClickOn(A)
return
*/
if(aicamera.in_camera_mode) //Cyborg picture taking
aicamera.camera_mode_off()
aicamera.captureimage(A, usr)
return
var/obj/item/W = get_active_held_item()
if(!W && A.Adjacent(src) && (isobj(A) || ismob(A)))
var/atom/movable/C = A
if(C.can_buckle && C.has_buckled_mobs())
if(C.buckled_mobs.len > 1)
var/unbuckled = input(src, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in C.buckled_mobs
if(C.user_unbuckle_mob(unbuckled,src))
return
else
if(C.user_unbuckle_mob(C.buckled_mobs[1],src))
return
if(!W && get_dist(src,A) <= interaction_range)
A.attack_robot(src)
return
if(W)
// buckled cannot prevent machine interlinking but stops arm movement
if( buckled || incapacitated())
return
if(W == A)
W.attack_self(src)
return
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents)
if(A == loc || (A in loc) || (A in contents))
W.melee_attack_chain(src, A, params)
return
if(!isturf(loc))
return
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc))
if(isturf(A) || isturf(A.loc))
if(A.Adjacent(src)) // see adjacent.dm
W.melee_attack_chain(src, A, params)
return
else
W.afterattack(A, src, 0, params)
return
//Middle click cycles through selected modules.
/mob/living/silicon/robot/MiddleClickOn(atom/A)
cycle_modules()
return
//Give cyborgs hotkey clicks without breaking existing uses of hotkey clicks
// for non-doors/apcs
/mob/living/silicon/robot/CtrlShiftClickOn(atom/A)
A.BorgCtrlShiftClick(src)
/mob/living/silicon/robot/ShiftClickOn(atom/A)
A.BorgShiftClick(src)
/mob/living/silicon/robot/CtrlClickOn(atom/A)
A.BorgCtrlClick(src)
/mob/living/silicon/robot/AltClickOn(atom/A)
if(!A.BorgAltClick(src))
altclick_listed_turf(A)
/atom/proc/BorgCtrlShiftClick(mob/living/silicon/robot/user) //forward to human click if not overridden
CtrlShiftClick(user)
/obj/machinery/door/airlock/BorgCtrlShiftClick(mob/living/silicon/robot/user) // Sets/Unsets Emergency Access Override Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AICtrlShiftClick()
else
..()
/atom/proc/BorgShiftClick(mob/living/silicon/robot/user) //forward to human click if not overridden
ShiftClick(user)
/obj/machinery/door/airlock/BorgShiftClick(mob/living/silicon/robot/user) // Opens and closes doors! Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AIShiftClick()
else
..()
/atom/proc/BorgCtrlClick(mob/living/silicon/robot/user) //forward to human click if not overridden
CtrlClick(user)
/obj/machinery/door/airlock/BorgCtrlClick(mob/living/silicon/robot/user) // Bolts doors. Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AICtrlClick()
else
..()
/obj/machinery/power/apc/BorgCtrlClick(mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AICtrlClick()
else
..()
/obj/machinery/turretid/BorgCtrlClick(mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AICtrlClick()
else
..()
/atom/proc/BorgAltClick(mob/living/silicon/robot/user)
return AltClick(user)
/obj/machinery/door/airlock/BorgAltClick(mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
return AIAltClick()
return ..()
/obj/machinery/turretid/BorgAltClick(mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
return AIAltClick()
return ..()
/*
As with AI, these are not used in click code,
because the code for robots is specific, not generic.
If you would like to add advanced features to robot
clicks, you can do so here, but you will have to
change attack_robot() above to the proper function
*/
/mob/living/silicon/robot/UnarmedAttack(atom/A)
A.attack_robot(src)
/mob/living/silicon/robot/RangedAttack(atom/A)
A.attack_robot(src)
/atom/proc/attack_robot(mob/user)
attack_ai(user)
return
/*
Cyborg ClickOn()
Cyborgs have no range restriction on attack_robot(), because it is basically an AI click.
However, they do have a range restriction on item use, so they cannot do without the
adjacency code.
*/
/mob/living/silicon/robot/ClickOn(var/atom/A, var/params)
if(world.time <= next_click)
return
next_click = world.time + 1
if(check_click_intercept(params,A))
return
if(stat || lockcharge || IsKnockdown() || IsStun() || IsUnconscious())
return
var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A)
return
if(modifiers["shift"] && modifiers["middle"])
ShiftMiddleClickOn(A)
return
if(modifiers["middle"])
MiddleClickOn(A)
return
if(modifiers["shift"])
ShiftClickOn(A)
return
if(modifiers["alt"]) // alt and alt-gr (rightalt)
AltClickOn(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
if(next_move >= world.time)
return
face_atom(A) // change direction to face what you clicked on
/*
cyborg restrained() currently does nothing
if(restrained())
RestrainedClickOn(A)
return
*/
if(aicamera.in_camera_mode) //Cyborg picture taking
aicamera.camera_mode_off()
aicamera.captureimage(A, usr)
return
var/obj/item/W = get_active_held_item()
if(!W && get_dist(src,A) <= interaction_range)
A.attack_robot(src)
return
if(W)
// buckled cannot prevent machine interlinking but stops arm movement
if( buckled || incapacitated())
return
if(W == A)
W.attack_self(src)
return
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents)
if(A == loc || (A in loc) || (A in contents))
W.melee_attack_chain(src, A, params)
return
if(!isturf(loc))
return
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc))
if(isturf(A) || isturf(A.loc))
if(A.Adjacent(src)) // see adjacent.dm
W.melee_attack_chain(src, A, params)
return
else
W.afterattack(A, src, 0, params)
return
//Middle click cycles through selected modules.
/mob/living/silicon/robot/MiddleClickOn(atom/A)
cycle_modules()
return
//Give cyborgs hotkey clicks without breaking existing uses of hotkey clicks
// for non-doors/apcs
/mob/living/silicon/robot/CtrlShiftClickOn(atom/A)
A.BorgCtrlShiftClick(src)
/mob/living/silicon/robot/ShiftClickOn(atom/A)
A.BorgShiftClick(src)
/mob/living/silicon/robot/CtrlClickOn(atom/A)
A.BorgCtrlClick(src)
/mob/living/silicon/robot/AltClickOn(atom/A)
A.BorgAltClick(src)
/atom/proc/BorgCtrlShiftClick(mob/living/silicon/robot/user) //forward to human click if not overridden
CtrlShiftClick(user)
/obj/machinery/door/airlock/BorgCtrlShiftClick(mob/living/silicon/robot/user) // Sets/Unsets Emergency Access Override Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AICtrlShiftClick()
else
..()
/atom/proc/BorgShiftClick(mob/living/silicon/robot/user) //forward to human click if not overridden
ShiftClick(user)
/obj/machinery/door/airlock/BorgShiftClick(mob/living/silicon/robot/user) // Opens and closes doors! Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AIShiftClick()
else
..()
/atom/proc/BorgCtrlClick(mob/living/silicon/robot/user) //forward to human click if not overridden
CtrlClick(user)
/obj/machinery/door/airlock/BorgCtrlClick(mob/living/silicon/robot/user) // Bolts doors. Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AICtrlClick()
else
..()
/obj/machinery/power/apc/BorgCtrlClick(mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AICtrlClick()
else
..()
/obj/machinery/turretid/BorgCtrlClick(mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AICtrlClick()
else
..()
/atom/proc/BorgAltClick(mob/living/silicon/robot/user)
AltClick(user)
return
/obj/machinery/door/airlock/BorgAltClick(mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AIAltClick()
else
..()
/obj/machinery/turretid/BorgAltClick(mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code.
if(get_dist(src,user) <= user.interaction_range)
AIAltClick()
else
..()
/*
As with AI, these are not used in click code,
because the code for robots is specific, not generic.
If you would like to add advanced features to robot
clicks, you can do so here, but you will have to
change attack_robot() above to the proper function
*/
/mob/living/silicon/robot/UnarmedAttack(atom/A)
A.attack_robot(src)
/mob/living/silicon/robot/RangedAttack(atom/A)
A.attack_robot(src)
/atom/proc/attack_robot(mob/user)
attack_ai(user)
return
-1
View File
@@ -125,7 +125,6 @@
moved = FALSE
user.update_action_buttons(TRUE)
to_chat(user, "<span class='notice'>Action button positions have been reset.</span>")
return TRUE
/obj/screen/movable/action_button/hide_toggle/proc/InitialiseIcon(datum/hud/owner_hud)
-6
View File
@@ -213,12 +213,6 @@ or something covering your eyes."
desc = "Whoa man, you're tripping balls! Careful you don't get addicted... if you aren't already."
icon_state = "high"
/obj/screen/alert/hypnosis
name = "Hypnosis"
desc = "Something's hypnotizing you, but you're not really sure about what."
icon_state = "hypnosis"
var/phrase
/obj/screen/alert/drunk //Not implemented
name = "Drunk"
desc = "All that alcohol you've been drinking is impairing your speech, motor skills, and mental cognition. Make sure to act like it."
-7
View File
@@ -349,13 +349,6 @@
devilsouldisplay = new /obj/screen/devil/soul_counter
infodisplay += devilsouldisplay
blood_display = new /obj/screen/bloodsucker/blood_counter // Blood Volume
infodisplay += blood_display
vamprank_display = new /obj/screen/bloodsucker/rank_counter // Vampire Rank
infodisplay += vamprank_display
sunlight_display = new /obj/screen/bloodsucker/sunlight_counter // Sunlight
infodisplay += sunlight_display
zone_select = new /obj/screen/zone_sel()
zone_select.icon = ui_style
zone_select.update_icon(mymob)
+2 -1
View File
@@ -122,7 +122,7 @@
send_item_attack_message(I, user)
if(I.force)
apply_damage(totitemdamage, I.damtype) //CIT CHANGE - replaces I.force with totitemdamage
if(I.damtype == BRUTE && !HAS_TRAIT(src, TRAIT_NOMARROW))
if(I.damtype == BRUTE)
if(prob(33))
I.add_mob_blood(src)
var/turf/location = get_turf(src)
@@ -175,3 +175,4 @@
/obj/item/proc/getweight()
return total_mass || w_class * 1.25
+83 -83
View File
@@ -1,83 +1,83 @@
/mob/dead/observer/DblClickOn(var/atom/A, var/params)
if(can_reenter_corpse && mind && mind.current)
if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it
reenter_corpse() // (cloning scanner, body bag, closet, mech, etc)
return // seems legit.
// Things you might plausibly want to follow
if(ismovableatom(A))
ManualFollow(A)
// Otherwise jump
else if(A.loc)
forceMove(get_turf(A))
update_parallax_contents()
/mob/dead/observer/ClickOn(var/atom/A, var/params)
if(check_click_intercept(params,A))
return
var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["middle"])
ShiftMiddleClickOn(A)
return
if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A)
return
if(modifiers["middle"])
MiddleClickOn(A)
return
if(modifiers["shift"])
ShiftClickOn(A)
return
if(modifiers["alt"])
altclick_listed_turf(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
if(world.time <= next_move)
return
// You are responsible for checking config.ghost_interaction when you override this function
// Not all of them require checking, see below
A.attack_ghost(src)
// Oh by the way this didn't work with old click code which is why clicking shit didn't spam you
/atom/proc/attack_ghost(mob/dead/observer/user)
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_GHOST, user) & COMPONENT_NO_ATTACK_HAND)
return TRUE
if(user.client)
if(IsAdminGhost(user))
attack_ai(user)
else if(user.client.prefs.inquisitive_ghost)
user.examinate(src)
return FALSE
/mob/living/attack_ghost(mob/dead/observer/user)
if(user.client && user.health_scan)
healthscan(user, src, 1, TRUE)
return ..()
// ---------------------------------------
// And here are some good things for free:
// Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu
/obj/machinery/gateway/centerstation/attack_ghost(mob/user)
if(awaygate)
user.forceMove(awaygate.loc)
else
to_chat(user, "[src] has no destination.")
return ..()
/obj/machinery/gateway/centeraway/attack_ghost(mob/user)
if(stationgate)
user.forceMove(stationgate.loc)
else
to_chat(user, "[src] has no destination.")
return ..()
/obj/machinery/teleport/hub/attack_ghost(mob/user)
if(power_station && power_station.engaged && power_station.teleporter_console && power_station.teleporter_console.target)
user.forceMove(get_turf(power_station.teleporter_console.target))
return ..()
/mob/dead/observer/DblClickOn(var/atom/A, var/params)
if(can_reenter_corpse && mind && mind.current)
if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it
reenter_corpse() // (cloning scanner, body bag, closet, mech, etc)
return // seems legit.
// Things you might plausibly want to follow
if(ismovableatom(A))
ManualFollow(A)
// Otherwise jump
else if(A.loc)
forceMove(get_turf(A))
update_parallax_contents()
/mob/dead/observer/ClickOn(var/atom/A, var/params)
if(check_click_intercept(params,A))
return
var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["middle"])
ShiftMiddleClickOn(A)
return
if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A)
return
if(modifiers["middle"])
MiddleClickOn(A)
return
if(modifiers["shift"])
ShiftClickOn(A)
return
if(modifiers["alt"])
AltClickNoInteract(src, A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
if(world.time <= next_move)
return
// You are responsible for checking config.ghost_interaction when you override this function
// Not all of them require checking, see below
A.attack_ghost(src)
// Oh by the way this didn't work with old click code which is why clicking shit didn't spam you
/atom/proc/attack_ghost(mob/dead/observer/user)
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_GHOST, user) & COMPONENT_NO_ATTACK_HAND)
return TRUE
if(user.client)
if(IsAdminGhost(user))
attack_ai(user)
else if(user.client.prefs.inquisitive_ghost)
user.examinate(src)
return FALSE
/mob/living/attack_ghost(mob/dead/observer/user)
if(user.client && user.health_scan)
healthscan(user, src, 1, TRUE)
return ..()
// ---------------------------------------
// And here are some good things for free:
// Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu
/obj/machinery/gateway/centerstation/attack_ghost(mob/user)
if(awaygate)
user.forceMove(awaygate.loc)
else
to_chat(user, "[src] has no destination.")
return ..()
/obj/machinery/gateway/centeraway/attack_ghost(mob/user)
if(stationgate)
user.forceMove(stationgate.loc)
else
to_chat(user, "[src] has no destination.")
return ..()
/obj/machinery/teleport/hub/attack_ghost(mob/user)
if(power_station && power_station.engaged && power_station.teleporter_console && power_station.teleporter_console.target)
user.forceMove(get_turf(power_station.teleporter_console.target))
return ..()
@@ -166,8 +166,7 @@
key_name = copytext(str_val, 1, key_pos)
if(lowercase)
key_name = lowertext(key_name)
if(key_pos)
key_value = copytext(str_val, key_pos + length(str_val[key_pos]))
key_value = copytext(str_val, key_pos + 1)
var/new_key
var/new_value
var/continue_check_value
@@ -106,13 +106,13 @@
if(!L)
continue
var/firstchar = L[1]
var/firstchar = copytext(L, 1, 2)
if(firstchar == "#")
continue
var/lockthis = firstchar == "@"
if(lockthis)
L = copytext(L, length(firstchar) + 1)
L = copytext(L, 2)
var/pos = findtext(L, " ")
var/entry = null
@@ -120,7 +120,7 @@
if(pos)
entry = lowertext(copytext(L, 1, pos))
value = copytext(L, pos + length(L[pos]))
value = copytext(L, pos + 1)
else
entry = lowertext(L)
@@ -256,7 +256,7 @@
t = trim(t)
if(length(t) == 0)
continue
else if(t[1] == "#")
else if(copytext(t, 1, 2) == "#")
continue
var/pos = findtext(t, " ")
@@ -265,7 +265,7 @@
if(pos)
command = lowertext(copytext(t, 1, pos))
data = copytext(t, pos + length(t[pos]))
data = copytext(t, pos + 1)
else
command = lowertext(t)
@@ -367,10 +367,6 @@
config_entry_value = 64
min_val = 0
/datum/config_entry/number/ratcap
config_entry_value = 64
min_val = 0
/datum/config_entry/flag/disable_stambuffer
/datum/config_entry/keyed_list/box_random_engine
+7 -5
View File
@@ -257,8 +257,9 @@ SUBSYSTEM_DEF(air)
#ifdef VISUALIZE_ACTIVE_TURFS
T.add_atom_colour("#00ff00", TEMPORARY_COLOUR_PRIORITY)
#endif
T.excited = TRUE
active_turfs[T] = SSair_turfs.currentrun[T] = TRUE
T.excited = 1
active_turfs |= T
SSair_turfs.currentrun |= T
if(blockchanges && T.excited_group)
T.excited_group.garbage_collect()
add_to_react_queue(T)
@@ -274,9 +275,10 @@ SUBSYSTEM_DEF(air)
/datum/controller/subsystem/air/proc/add_to_react_queue(turf/open/T)
if(istype(T) && T.air)
turf_react_queue[T] = TRUE
turf_react_queue |= T
if(currentpart == SSAIR_REACTQUEUE)
currentrun[T] = TRUE
currentrun |= T
return
/datum/controller/subsystem/air/proc/remove_from_react_queue(turf/open/T)
turf_react_queue -= T
@@ -313,7 +315,7 @@ SUBSYSTEM_DEF(air)
var/starting_ats = active_turfs.len
sleep(world.tick_lag)
var/timer = world.timeofday
log_mapping("There are [starting_ats] active turfs at roundstart caused by a difference of the air between the adjacent turfs. You can see its coordinates using \"Mapping -> Show roundstart AT list\" verb (debug verbs required).")
warning("There are [starting_ats] active turfs at roundstart, this is a mapping error caused by a difference of the air between the adjacent turfs. You can see its coordinates using \"Mapping -> Show roundstart AT list\" verb (debug verbs required)")
for(var/turf/T in active_turfs)
GLOB.active_turfs_startlist += T
-1
View File
@@ -8,7 +8,6 @@ SUBSYSTEM_DEF(mobs)
var/static/list/clients_by_zlevel[][]
var/static/list/dead_players_by_zlevel[][] = list(list()) // Needs to support zlevel 1 here, MaxZChanged only happens when z2 is created and new_players can login before that.
var/static/list/cubemonkeys = list()
var/static/list/cheeserats = list()
/datum/controller/subsystem/mobs/stat_entry()
..("P:[GLOB.mob_living_list.len]")
+13 -13
View File
@@ -8,7 +8,7 @@ SUBSYSTEM_DEF(pai)
var/spam_delay = 100
var/list/pai_card_list = list()
/datum/controller/subsystem/pai/Topic(href, href_list)
/datum/controller/subsystem/pai/Topic(href, href_list[])
if(href_list["download"])
var/datum/paiCandidate/candidate = locate(href_list["candidate"]) in candidates
var/obj/item/paicard/card = locate(href_list["device"]) in pai_card_list
@@ -39,34 +39,34 @@ SUBSYSTEM_DEF(pai)
switch(option)
if("name")
t = reject_bad_name(stripped_input(usr, "Enter a name for your pAI", "pAI Name", candidate.name, MAX_NAME_LEN), TRUE)
t = input("Enter a name for your pAI", "pAI Name", candidate.name) as text
if(t)
candidate.name = t
candidate.name = copytext(sanitize(t),1,MAX_NAME_LEN)
if("desc")
t = stripped_multiline_input(usr, "Enter a description for your pAI", "pAI Description", candidate.description, MAX_MESSAGE_LEN)
t = input("Enter a description for your pAI", "pAI Description", candidate.description) as message
if(t)
candidate.description = t
candidate.description = copytext(sanitize(t),1,MAX_MESSAGE_LEN)
if("role")
t = stripped_input(usr, "Enter a role for your pAI", "pAI Role", candidate.role, MAX_MESSAGE_LEN)
t = input("Enter a role for your pAI", "pAI Role", candidate.role) as text
if(t)
candidate.role = t
candidate.role = copytext(sanitize(t),1,MAX_MESSAGE_LEN)
if("ooc")
t = stripped_multiline_input(usr, "Enter any OOC comments", "pAI OOC Comments", candidate.comments, MAX_MESSAGE_LEN)
t = input("Enter any OOC comments", "pAI OOC Comments", candidate.comments) as message
if(t)
candidate.comments = t
candidate.comments = copytext(sanitize(t),1,MAX_MESSAGE_LEN)
if("save")
candidate.savefile_save(usr)
if("load")
candidate.savefile_load(usr)
//In case people have saved unsanitized stuff.
if(candidate.name)
candidate.name = copytext_char(sanitize(candidate.name),1,MAX_NAME_LEN)
candidate.name = copytext(sanitize(candidate.name),1,MAX_NAME_LEN)
if(candidate.description)
candidate.description = copytext_char(sanitize(candidate.description),1,MAX_MESSAGE_LEN)
candidate.description = copytext(sanitize(candidate.description),1,MAX_MESSAGE_LEN)
if(candidate.role)
candidate.role = copytext_char(sanitize(candidate.role),1,MAX_MESSAGE_LEN)
candidate.role = copytext(sanitize(candidate.role),1,MAX_MESSAGE_LEN)
if(candidate.comments)
candidate.comments = copytext_char(sanitize(candidate.comments),1,MAX_MESSAGE_LEN)
candidate.comments = copytext(sanitize(candidate.comments),1,MAX_MESSAGE_LEN)
if("submit")
if(candidate)
@@ -46,6 +46,6 @@ PROCESSING_SUBSYSTEM_DEF(networks)
var/hex = md5(string)
if(!hex)
return //errored
. = "[copytext_char(hex, 1, 9)]" //16 ^ 8 possibilities I think.
. = "[copytext(hex, 1, 9)]" //16 ^ 8 possibilities I think.
if(interfaces_by_id[.])
return resolve_collisions? make_address("[num2text(rand(HID_RESTRICTED_END, 999999999), 12)]"):null
+21 -23
View File
@@ -17,7 +17,8 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
/datum/controller/subsystem/processing/quirks/Initialize(timeofday)
if(!quirks.len)
SetupQuirks()
quirk_blacklist = list(list("Blind","Nearsighted"),list("Jolly","Depression","Hypersensitive"),list("Ageusia","Vegetarian","Deviant Tastes"),list("Ananas Affinity","Ananas Aversion"),list("Alcohol Tolerance","Light Drinker"),list("Prosthetic Limb (Left Arm)","Prosthetic Limb (Right Arm)","Prosthetic Limb (Left Leg)","Prosthetic Limb (Right Leg)","Prosthetic Limb"),list("Social Anxiety","Mute"))
quirk_blacklist = list(list("Blind","Nearsighted"),list("Jolly","Depression","Apathetic","Hypersensitive"),list("Ageusia","Vegetarian","Deviant Tastes"),list("Ananas Affinity","Ananas Aversion"),list("Alcohol Tolerance","Light Drinker"),list("Prosthetic Limb (Left Arm)","Prosthetic Limb (Right Arm)","Prosthetic Limb (Left Leg)","Prosthetic Limb (Right Leg)","Prosthetic Limb"),list("Social Anxiety","Mute"))
return ..()
/datum/controller/subsystem/processing/quirks/proc/SetupQuirks()
@@ -31,21 +32,13 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
quirk_names_by_path[T] = initial(T.name)
/datum/controller/subsystem/processing/quirks/proc/AssignQuirks(mob/living/user, client/cli, spawn_effects, roundstart = FALSE, datum/job/job, silent = FALSE, mob/to_chat_target)
var/badquirk = FALSE
var/list/my_quirks = cli.prefs.all_quirks.Copy()
GenerateQuirks(cli)
var/list/quirks = cli.prefs.character_quirks.Copy()
var/list/cut
if(job?.blacklisted_quirks)
cut = filter_quirks(my_quirks, job)
for(var/V in my_quirks)
if(V in quirks)
var/datum/quirk/Q = quirks[V]
user.add_quirk(Q, spawn_effects)
else
log_admin("Invalid quirk \"[V]\" in client [cli.ckey] preferences")
cli.prefs.all_quirks -= V
badquirk = TRUE
if(badquirk)
cli.prefs.save_character()
if(job && job.blacklisted_quirks)
cut = filter_quirks(quirks, job)
for(var/V in quirks)
user.add_quirk(V, spawn_effects)
if(!silent && LAZYLEN(cut))
to_chat(to_chat_target || user, "<span class='boldwarning'>All of your non-neutral character quirks have been cut due to these quirks conflicting with your job assignment: [english_list(cut)].</span>")
@@ -63,28 +56,28 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
for(var/i in quirk_names)
. += quirk_points_by_name(i)
/datum/controller/subsystem/processing/quirks/proc/filter_quirks(list/our_quirks, datum/job/job)
/datum/controller/subsystem/processing/quirks/proc/filter_quirks(list/quirks, datum/job/job)
var/list/cut = list()
var/list/banned_names = list()
for(var/i in job.blacklisted_quirks)
var/name = quirk_name_by_path(i)
if(name)
banned_names += name
var/list/blacklisted = our_quirks & banned_names
var/list/blacklisted = quirks & banned_names
if(length(blacklisted))
for(var/i in blacklisted)
our_quirks -= i
quirks -= i
cut += i
/* //Code to automatically reduce positive quirks until balance is even.
var/points_used = total_points(our_quirks)
var/points_used = total_points(quirks)
if(points_used > 0)
//they owe us points, let's collect.
for(var/i in our_quirks)
for(var/i in quirks)
var/points = quirk_points_by_name(i)
if(points > 0)
cut += i
our_quirks -= i
quirks -= i
points_used -= points
if(points_used <= 0)
break
@@ -92,9 +85,14 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
//Nah, let's null all non-neutrals out.
if(cut.len)
for(var/i in our_quirks)
for(var/i in quirks)
if(quirk_points_by_name(i) != 0)
//cut += i -- Commented out: Only show the ones that triggered the quirk purge.
our_quirks -= i
quirks -= i
return cut
/datum/controller/subsystem/processing/quirks/proc/GenerateQuirks(client/user)
if(user.prefs.character_quirks.len)
return
user.prefs.character_quirks = user.prefs.all_quirks
+11 -205
View File
@@ -1,34 +1,27 @@
SUBSYSTEM_DEF(research)
name = "Research"
priority = FIRE_PRIORITY_RESEARCH
wait = 10
init_order = INIT_ORDER_RESEARCH
//TECHWEB STATIC
var/list/techweb_nodes = list() //associative id = node datum
var/list/techweb_designs = list() //associative id = node datum
var/list/datum/techweb/techwebs = list()
var/datum/techweb/science/science_tech
var/datum/techweb/admin/admin_tech
var/datum/techweb_node/error_node/error_node //These two are what you get if a node/design is deleted and somehow still stored in a console.
var/datum/design/error_design/error_design
//ERROR LOGGING
var/list/invalid_design_ids = list() //associative id = number of times
var/list/invalid_node_ids = list() //associative id = number of times
var/list/invalid_node_boost = list() //associative id = error message
var/list/obj/machinery/rnd/server/servers = list()
var/list/techweb_nodes_starting = list() //associative id = TRUE
var/list/techweb_categories = list() //category name = list(node.id = TRUE)
var/datum/techweb/science/science_tech
var/datum/techweb/admin/admin_tech
var/list/techweb_nodes = list() //associative id = node datum
var/list/techweb_categories = list() //category name = list(node.id = node)
var/list/techweb_designs = list() //associative id = node datum
var/list/techweb_nodes_starting = list() //associative id = node datum
var/list/techweb_boost_items = list() //associative double-layer path = list(id = list(point_type = point_discount))
var/list/techweb_nodes_hidden = list() //Node ids that should be hidden by default.
var/list/techweb_nodes_hidden = list() //Nodes that should be hidden by default.
var/list/techweb_point_items = list( //path = list(point type = value)
/obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 2500),
/obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 5000), // Cit three more anomalys anomalys
/obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 7500),
/obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 10000),
// - Slime Extracts! -
// - Slime Extracts! -
/obj/item/slime_extract/grey = list(TECHWEB_POINT_TYPE_GENERIC = 500), // Adds in slime core deconing
/obj/item/slime_extract/metal = list(TECHWEB_POINT_TYPE_GENERIC = 750),
/obj/item/slime_extract/purple = list(TECHWEB_POINT_TYPE_GENERIC = 750),
@@ -301,8 +294,6 @@ SUBSYSTEM_DEF(research)
science_tech = new /datum/techweb/science
admin_tech = new /datum/techweb/admin
autosort_categories()
error_design = new
error_node = new
return ..()
/datum/controller/subsystem/research/fire()
@@ -339,191 +330,6 @@ SUBSYSTEM_DEF(research)
for(var/i in techweb_nodes)
var/datum/techweb_node/I = techweb_nodes[i]
if(techweb_categories[I.category])
techweb_categories[I.category][I.id] = TRUE
techweb_categories[I.category][I.id] = I
else
techweb_categories[I.category] = list(I.id = TRUE)
/datum/controller/subsystem/research/proc/techweb_node_by_id(id)
return techweb_nodes[id] || error_node
/datum/controller/subsystem/research/proc/techweb_design_by_id(id)
return techweb_designs[id] || error_design
/datum/controller/subsystem/research/proc/on_design_deletion(datum/design/D)
for(var/i in techweb_nodes)
var/datum/techweb_node/TN = techwebs[i]
TN.on_design_deletion(TN)
for(var/i in techwebs)
var/datum/techweb/T = i
T.recalculate_nodes(TRUE)
/datum/controller/subsystem/research/proc/on_node_deletion(datum/techweb_node/TN)
for(var/i in techweb_nodes)
var/datum/techweb_node/TN2 = techwebs[i]
TN2.on_node_deletion(TN)
for(var/i in techwebs)
var/datum/techweb/T = i
T.recalculate_nodes(TRUE)
/datum/controller/subsystem/research/proc/initialize_all_techweb_nodes(clearall = FALSE)
if(islist(techweb_nodes) && clearall)
QDEL_LIST(techweb_nodes)
if(islist(techweb_nodes_starting && clearall))
techweb_nodes_starting.Cut()
var/list/returned = list()
for(var/path in subtypesof(/datum/techweb_node))
var/datum/techweb_node/TN = path
if(isnull(initial(TN.id)))
continue
TN = new path
if(returned[initial(TN.id)])
stack_trace("WARNING: Techweb node ID clash with ID [initial(TN.id)] detected! Path: [path]")
errored_datums[TN] = initial(TN.id)
continue
returned[initial(TN.id)] = TN
if(TN.starting_node)
techweb_nodes_starting[TN.id] = TRUE
for(var/id in techweb_nodes)
var/datum/techweb_node/TN = techweb_nodes[id]
TN.Initialize()
techweb_nodes = returned
if (!verify_techweb_nodes()) //Verify all nodes have ids and such.
stack_trace("Invalid techweb nodes detected")
calculate_techweb_nodes()
calculate_techweb_boost_list()
if (!verify_techweb_nodes()) //Verify nodes and designs have been crosslinked properly.
CRASH("Invalid techweb nodes detected")
/datum/controller/subsystem/research/proc/initialize_all_techweb_designs(clearall = FALSE)
if(islist(techweb_designs) && clearall)
QDEL_LIST(techweb_designs)
var/list/returned = list()
for(var/path in subtypesof(/datum/design))
var/datum/design/DN = path
if(isnull(initial(DN.id)))
stack_trace("WARNING: Design with null ID detected. Build path: [initial(DN.build_path)]")
continue
else if(initial(DN.id) == DESIGN_ID_IGNORE)
continue
DN = new path
if(returned[initial(DN.id)])
stack_trace("WARNING: Design ID clash with ID [initial(DN.id)] detected! Path: [path]")
errored_datums[DN] = initial(DN.id)
continue
returned[initial(DN.id)] = DN
techweb_designs = returned
verify_techweb_designs()
/datum/controller/subsystem/research/proc/verify_techweb_nodes()
. = TRUE
for(var/n in techweb_nodes)
var/datum/techweb_node/N = techweb_nodes[n]
if(!istype(N))
WARNING("Invalid research node with ID [n] detected and removed.")
techweb_nodes -= n
research_node_id_error(n)
. = FALSE
for(var/p in N.prereq_ids)
var/datum/techweb_node/P = techweb_nodes[p]
if(!istype(P))
WARNING("Invalid research prerequisite node with ID [p] detected in node [N.display_name]\[[N.id]\] removed.")
N.prereq_ids -= p
research_node_id_error(p)
. = FALSE
for(var/d in N.design_ids)
var/datum/design/D = techweb_designs[d]
if(!istype(D))
WARNING("Invalid research design with ID [d] detected in node [N.display_name]\[[N.id]\] removed.")
N.design_ids -= d
design_id_error(d)
. = FALSE
for(var/u in N.unlock_ids)
var/datum/techweb_node/U = techweb_nodes[u]
if(!istype(U))
WARNING("Invalid research unlock node with ID [u] detected in node [N.display_name]\[[N.id]\] removed.")
N.unlock_ids -= u
research_node_id_error(u)
. = FALSE
for(var/p in N.boost_item_paths)
if(!ispath(p))
N.boost_item_paths -= p
WARNING("[p] is not a valid path.")
node_boost_error(N.id, "[p] is not a valid path.")
. = FALSE
var/list/points = N.boost_item_paths[p]
if(islist(points))
for(var/i in points)
if(!isnum(points[i]))
WARNING("[points[i]] is not a valid number.")
node_boost_error(N.id, "[points[i]] is not a valid number.")
. = FALSE
else if(!point_types[i])
WARNING("[i] is not a valid point type.")
node_boost_error(N.id, "[i] is not a valid point type.")
. = FALSE
else if(!isnull(points))
N.boost_item_paths -= p
node_boost_error(N.id, "No valid list.")
WARNING("No valid list.")
. = FALSE
CHECK_TICK
/datum/controller/subsystem/research/proc/verify_techweb_designs()
for(var/d in techweb_designs)
var/datum/design/D = techweb_designs[d]
if(!istype(D))
stack_trace("WARNING: Invalid research design with ID [d] detected and removed.")
techweb_designs -= d
CHECK_TICK
/datum/controller/subsystem/research/proc/research_node_id_error(id)
if(invalid_node_ids[id])
invalid_node_ids[id]++
else
invalid_node_ids[id] = 1
/datum/controller/subsystem/research/proc/design_id_error(id)
if(invalid_design_ids[id])
invalid_design_ids[id]++
else
invalid_design_ids[id] = 1
/datum/controller/subsystem/research/proc/calculate_techweb_nodes()
for(var/design_id in techweb_designs)
var/datum/design/D = techweb_designs[design_id]
D.unlocked_by.Cut()
for(var/node_id in techweb_nodes)
var/datum/techweb_node/node = techweb_nodes[node_id]
node.unlock_ids = list()
for(var/i in node.design_ids)
var/datum/design/D = techweb_designs[i]
node.design_ids[i] = TRUE
D.unlocked_by += node.id
if(node.hidden)
techweb_nodes_hidden[node.id] = TRUE
CHECK_TICK
generate_techweb_unlock_linking()
/datum/controller/subsystem/research/proc/generate_techweb_unlock_linking()
for(var/node_id in techweb_nodes) //Clear all unlock links to avoid duplication.
var/datum/techweb_node/node = techweb_nodes[node_id]
node.unlock_ids = list()
for(var/node_id in techweb_nodes)
var/datum/techweb_node/node = techweb_nodes[node_id]
for(var/prereq_id in node.prereq_ids)
var/datum/techweb_node/prereq_node = techweb_node_by_id(prereq_id)
prereq_node.unlock_ids[node.id] = node
/datum/controller/subsystem/research/proc/calculate_techweb_boost_list(clearall = FALSE)
if(clearall)
techweb_boost_items = list()
for(var/node_id in techweb_nodes)
var/datum/techweb_node/node = techweb_nodes[node_id]
for(var/path in node.boost_item_paths)
if(!ispath(path))
continue
if(length(techweb_boost_items[path]))
techweb_boost_items[path][node.id] = node.boost_item_paths[path]
else
techweb_boost_items[path] = list(node.id = node.boost_item_paths[path])
CHECK_TICK
techweb_categories[I.category] = list(I.id = I)
+1 -1
View File
@@ -251,7 +251,7 @@ SUBSYSTEM_DEF(shuttle)
if(!admiral_message)
admiral_message = pick(GLOB.admiral_messages)
var/intercepttext = "<font size = 3><b>Kinaris Update</b>: Request For Shuttle.</font><hr>\
var/intercepttext = "<font size = 3><b>Nanotrasen Update</b>: Request For Shuttle.</font><hr>\
To whom it may concern:<br><br>\
We have taken note of the situation upon [station_name()] and have come to the \
conclusion that it does not warrant the abandonment of the station.<br>\
+1 -1
View File
@@ -11,7 +11,7 @@ SUBSYSTEM_DEF(tgui)
var/basehtml // The HTML base used for all UIs.
/datum/controller/subsystem/tgui/PreInit()
basehtml = file2text('tgui-next/packages/tgui/public/tgui-main.html')
basehtml = file2text('tgui/tgui.html')
/datum/controller/subsystem/tgui/Shutdown()
close_all_uis()
+3 -3
View File
@@ -383,8 +383,8 @@ SUBSYSTEM_DEF(ticker)
captainless=0
if(player.mind.assigned_role != player.mind.special_role)
SSjob.EquipRank(N, player.mind.assigned_role, 0)
if(CONFIG_GET(flag/roundstart_traits) && ishuman(N.new_character))
SSquirks.AssignQuirks(N.new_character, N.client, TRUE, TRUE, SSjob.GetJob(player.mind.assigned_role), FALSE, N)
if(CONFIG_GET(flag/roundstart_traits) && ishuman(N.new_character))
SSquirks.AssignQuirks(N.new_character, N.client, TRUE, TRUE, SSjob.GetJob(player.mind.assigned_role), FALSE, N)
CHECK_TICK
if(captainless)
for(var/mob/dead/new_player/N in GLOB.player_list)
@@ -534,7 +534,7 @@ SUBSYSTEM_DEF(ticker)
/datum/controller/subsystem/ticker/proc/send_news_report()
var/news_message
var/news_source = "Kinaris News Network"
var/news_source = "Nanotrasen News Network"
switch(news_report)
if(NUKE_SYNDICATE_BASE)
news_message = "In a daring raid, the heroic crew of [station_name()] detonated a nuclear device in the heart of a terrorist base."
+5 -20
View File
@@ -1,12 +1,10 @@
//Brain Traumas are the new actual brain damage. Brain damage itself acts as a way to acquire traumas: every time brain damage is dealt, there's a chance of receiving a trauma.
//This chance gets higher the higher the mob's brainloss is. Removing traumas is a separate thing from removing brain damage: you can get restored to full brain operativity,
// but keep the quirks, until repaired by neurine, surgery, lobotomy or magic; depending on the resilience
// of the trauma.
//but keep the quirks, until repaired by mannitol (for mild/special ones) or brain surgery (for severe ones).
/datum/brain_trauma
var/name = "Brain Trauma"
var/desc = "A trauma caused by brain damage, which causes issues to the patient."
var/scan_desc = "generic brain trauma" //description when detected by a health scanner
var/scan_desc = "a generic brain trauma" //description when detected by a health scanner
var/mob/living/carbon/owner //the poor bastard
var/obj/item/organ/brain/brain //the poor bastard's brain
var/gain_text = "<span class='notice'>You feel traumatized.</span>"
@@ -14,21 +12,15 @@
var/can_gain = TRUE
var/random_gain = TRUE //can this be gained through random traumas?
var/resilience = TRAUMA_RESILIENCE_BASIC //how hard is this to cure?
var/clonable = TRUE // will this transfer if the brain is cloned?
/datum/brain_trauma/Destroy()
if(brain && brain.traumas)
brain.traumas -= src
brain.traumas -= src
if(owner)
on_lose()
brain = null
owner = null
return ..()
/datum/brain_trauma/proc/on_clone()
if(clonable)
return new type
//Called on life ticks
/datum/brain_trauma/proc/on_life()
return
@@ -41,24 +33,17 @@
/datum/brain_trauma/proc/on_gain()
to_chat(owner, gain_text)
RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech)
RegisterSignal(owner, COMSIG_MOVABLE_HEAR, .proc/handle_hearing)
//Called when removed from a mob
/datum/brain_trauma/proc/on_lose(silent)
if(!silent)
to_chat(owner, lose_text)
UnregisterSignal(owner, COMSIG_MOB_SAY)
UnregisterSignal(owner, COMSIG_MOVABLE_HEAR)
//Called when hearing a spoken message
/datum/brain_trauma/proc/handle_hearing(datum/source, list/hearing_args)
UnregisterSignal(owner, COMSIG_MOVABLE_HEAR)
/datum/brain_trauma/proc/on_hear(message, speaker, message_language, raw_message, radio_freq)
return message
//Called when speaking
/datum/brain_trauma/proc/handle_speech(datum/source, list/speech_args)
UnregisterSignal(owner, COMSIG_MOB_SAY)
//Called when hugging. expand into generally interacting, where future coders could switch the intent?
/datum/brain_trauma/proc/on_hug(mob/living/hugger, mob/living/hugged)
return
+9 -8
View File
@@ -5,7 +5,6 @@
gain_text = ""
lose_text = ""
resilience = TRAUMA_RESILIENCE_SURGERY
var/hypnotic_phrase = ""
var/regex/target_phrase
@@ -45,17 +44,18 @@
"You feel a part of your mind repeating this over and over. You need to follow these words.",\
"Something about this sounds... right, for some reason. You feel like you should follow these words.",\
"These words keep echoing in your mind. You find yourself completely fascinated by them.")]</span>")
to_chat(owner, "<span class='boldwarning'>You've been hypnotized by this sentence. You must follow these words. If it isn't a clear order, you can freely interpret how to do so,\
if(!HAS_TRAIT(owner, "hypnotherapy"))
to_chat(owner, "<span class='boldwarning'>You've been hypnotized by this sentence. You must follow these words. If it isn't a clear order, you can freely interpret how to do so,\
as long as you act like the words are your highest priority.</span>")
var/obj/screen/alert/hypnosis/hypno_alert = owner.throw_alert("hypnosis", /obj/screen/alert/hypnosis)
hypno_alert.desc = "\"[hypnotic_phrase]\"... your mind seems to be fixated on this concept."
else
to_chat(owner, "<span class='boldwarning'>You've been hypnotized by this sentence. You feel an incredible desire to follow these words, but are able to resist it somewhat. If it isn't a clear order, you can freely interpret how to do so,\
however this does not take precedence over your other objectives.</span>")
..()
/datum/brain_trauma/hypnosis/on_lose()
message_admins("[ADMIN_LOOKUPFLW(owner)] is no longer hypnotized with the phrase '[hypnotic_phrase]'.")
log_game("[key_name(owner)] is no longer hypnotized with the phrase '[hypnotic_phrase]'.")
to_chat(owner, "<span class='userdanger'>You suddenly snap out of your hypnosis. The phrase '[hypnotic_phrase]' no longer feels important to you.</span>")
owner.clear_alert("hypnosis")
to_chat(owner, "<span class='userdanger'>You suddenly snap out of your fixation. The phrase '[hypnotic_phrase]' no longer feels important to you.</span>")
..()
/datum/brain_trauma/hypnosis/on_life()
@@ -67,5 +67,6 @@
if(2)
new /datum/hallucination/chat(owner, TRUE, FALSE, "<span class='hypnophrase'>[hypnotic_phrase]</span>")
/datum/brain_trauma/hypnosis/handle_hearing(datum/source, list/hearing_args)
hearing_args[HEARING_MESSAGE] = target_phrase.Replace(hearing_args[HEARING_MESSAGE], "<span class='hypnophrase'>$1</span>")
/datum/brain_trauma/hypnosis/on_hear(message, speaker, message_language, raw_message, radio_freq)
message = target_phrase.Replace(message, "<span class='hypnophrase'>$1</span>")
return message
+13 -63
View File
@@ -8,10 +8,6 @@
var/friend_initialized = FALSE
/datum/brain_trauma/special/imaginary_friend/on_gain()
var/mob/living/M = owner
if(M.stat == DEAD || !M.client)
qdel(src)
return
..()
make_friend()
get_ghost()
@@ -47,7 +43,7 @@
/datum/brain_trauma/special/imaginary_friend/proc/get_ghost()
set waitfor = FALSE
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s imaginary friend?", ROLE_PAI, null, null, 75, friend, POLL_IGNORE_IMAGINARYFRIEND)
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s imaginary friend?", ROLE_PAI, null, null, 75, friend)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
friend.key = C.key
@@ -78,34 +74,26 @@
/mob/camera/imaginary_friend/Login()
..()
greet()
to_chat(src, "<span class='notice'><b>You are the imaginary friend of [owner]!</b></span>")
to_chat(src, "<span class='notice'>You are absolutely loyal to your friend, no matter what.</span>")
to_chat(src, "<span class='notice'>You cannot directly influence the world around you, but you can see what [owner] cannot.</span>")
Show()
/mob/camera/imaginary_friend/proc/greet()
to_chat(src, "<span class='notice'><b>You are the imaginary friend of [owner]!</b></span>")
to_chat(src, "<span class='notice'>You are absolutely loyal to your friend, no matter what.</span>")
to_chat(src, "<span class='notice'>You cannot directly influence the world around you, but you can see what [owner] cannot.</span>")
/mob/camera/imaginary_friend/Initialize(mapload, _trauma)
. = ..()
var/gender = pick(MALE, FEMALE)
real_name = random_unique_name(gender)
name = real_name
trauma = _trauma
owner = trauma.owner
copy_known_languages_from(owner, TRUE)
setup_friend()
human_image = get_flat_human_icon(null, pick(SSjob.occupations))
join = new
join.Grant(src)
hide = new
hide.Grant(src)
/mob/camera/imaginary_friend/proc/setup_friend()
var/gender = pick(MALE, FEMALE)
real_name = random_unique_name(gender)
name = real_name
human_image = get_flat_human_icon(null, pick(SSjob.occupations))
/mob/camera/imaginary_friend/proc/Show()
if(!client) //nobody home
return
@@ -144,18 +132,18 @@
if(client.prefs.muted & MUTE_IC)
to_chat(src, "You cannot send IC messages (muted).")
return
if (!(ignore_spam || forced) && src.client.handle_spam_prevention(message,MUTE_IC))
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
friend_talk(message)
/mob/camera/imaginary_friend/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
/mob/camera/imaginary_friend/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker)))
create_chat_message(speaker, message_language, raw_message, spans, message_mode)
to_chat(src, compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode, FALSE, source))
to_chat(src, compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode))
/mob/camera/imaginary_friend/proc/friend_talk(message)
message = capitalize(trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)))
message = capitalize(trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)))
if(!message)
return
@@ -232,42 +220,4 @@
var/mob/camera/imaginary_friend/I = owner
I.hidden = !I.hidden
I.Show()
update_status()
//down here is the trapped mind
//like imaginary friend but a lot less imagination and more like mind prison//
/datum/brain_trauma/special/imaginary_friend/trapped_owner
name = "Trapped Victim"
desc = "Patient appears to be targeted by an invisible entity."
gain_text = ""
lose_text = ""
random_gain = FALSE
/datum/brain_trauma/special/imaginary_friend/trapped_owner/make_friend()
friend = new /mob/camera/imaginary_friend/trapped(get_turf(owner), src)
/datum/brain_trauma/special/imaginary_friend/trapped_owner/reroll_friend() //no rerolling- it's just the last owner's hell
if(friend.client) //reconnected
return
friend_initialized = FALSE
QDEL_NULL(friend)
qdel(src)
/datum/brain_trauma/special/imaginary_friend/trapped_owner/get_ghost() //no randoms
return
/mob/camera/imaginary_friend/trapped
name = "figment of imagination?"
real_name = "figment of imagination?"
desc = "The previous host of this body."
/mob/camera/imaginary_friend/trapped/greet()
to_chat(src, "<span class='notice'><b>You have managed to hold on as a figment of the new host's imagination!</b></span>")
to_chat(src, "<span class='notice'>All hope is lost for you, but at least you may interact with your host. You do not have to be loyal to them.</span>")
to_chat(src, "<span class='notice'>You cannot directly influence the world around you, but you can see what the host cannot.</span>")
/mob/camera/imaginary_friend/trapped/setup_friend()
real_name = "[owner.real_name]?"
name = real_name
human_image = icon('icons/mob/lavaland/lavaland_monsters.dmi', icon_state = "curseblob")
update_status()
+55 -111
View File
@@ -64,21 +64,21 @@
name = "Speech Impediment"
desc = "Patient is unable to form coherent sentences."
scan_desc = "communication disorder"
gain_text = "<span class='danger'>You can't seem to form any coherent thoughts!</span>"
lose_text = "<span class='danger'>Your mind feels more clear.</span>"
gain_text = "" //mutation will handle the text
lose_text = ""
/datum/brain_trauma/mild/speech_impediment/on_gain()
ADD_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, TRAUMA_TRAIT)
..()
. = ..()
/datum/brain_trauma/mild/speech_impediment/on_lose()
REMOVE_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, TRAUMA_TRAIT)
..()
. = ..()
/datum/brain_trauma/mild/concussion
name = "Concussion"
desc = "Patient's brain is concussed."
scan_desc = "concussion"
scan_desc = "a concussion"
gain_text = "<span class='warning'>Your head hurts!</span>"
lose_text = "<span class='notice'>The pressure inside your head starts fading.</span>"
@@ -157,110 +157,54 @@
gain_text = "<span class='warning'>Your muscles feel oddly faint.</span>"
lose_text = "<span class='notice'>You feel in control of your muscles again.</span>"
/datum/brain_trauma/mild/muscle_spasms/on_gain()
owner.apply_status_effect(STATUS_EFFECT_SPASMS)
/datum/brain_trauma/mild/muscle_spasms/on_life()
if(prob(7))
switch(rand(1,5))
if(1)
if(owner.canmove && !isspaceturf(owner.loc))
to_chat(owner, "<span class='warning'>Your leg spasms!</span>")
step(owner, pick(GLOB.cardinals))
if(2)
if(owner.incapacitated())
return
var/obj/item/I = owner.get_active_held_item()
if(I)
to_chat(owner, "<span class='warning'>Your fingers spasm!</span>")
owner.log_message("used [I] due to a Muscle Spasm", LOG_ATTACK)
I.attack_self(owner)
if(3)
var/prev_intent = owner.a_intent
owner.a_intent = INTENT_HARM
var/range = 1
if(istype(owner.get_active_held_item(), /obj/item/gun)) //get targets to shoot at
range = 7
var/list/mob/living/targets = list()
for(var/mob/M in oview(owner, range))
if(isliving(M))
targets += M
if(LAZYLEN(targets))
to_chat(owner, "<span class='warning'>Your arm spasms!</span>")
owner.log_message(" attacked someone due to a Muscle Spasm") //the following attack will log itself
owner.ClickOn(pick(targets))
owner.a_intent = prev_intent
if(4)
var/prev_intent = owner.a_intent
owner.a_intent = INTENT_HARM
to_chat(owner, "<span class='warning'>Your arm spasms!</span>")
owner.log_message("attacked [owner.p_them()]self to a Muscle Spasm", LOG_ATTACK)
owner.ClickOn(owner)
owner.a_intent = prev_intent
if(5)
if(owner.incapacitated())
return
var/obj/item/I = owner.get_active_held_item()
var/list/turf/targets = list()
for(var/turf/T in oview(owner, 3))
targets += T
if(LAZYLEN(targets) && I)
to_chat(owner, "<span class='warning'>Your arm spasms!</span>")
owner.log_message("threw [I] due to a Muscle Spasm", LOG_ATTACK)
owner.throw_item(pick(targets))
..()
/datum/brain_trauma/mild/muscle_spasms/on_lose()
owner.remove_status_effect(STATUS_EFFECT_SPASMS)
..()
/datum/brain_trauma/mild/nervous_cough
name = "Nervous Cough"
desc = "Patient feels a constant need to cough."
scan_desc = "nervous cough"
gain_text = "<span class='warning'>Your throat itches incessantly...</span>"
lose_text = "<span class='notice'>Your throat stops itching.</span>"
/datum/brain_trauma/mild/nervous_cough/on_life()
if(prob(12) && !HAS_TRAIT(owner, TRAIT_SOOTHED_THROAT))
if(prob(5))
to_chat(owner, "<span notice='warning'>[pick("You have a coughing fit!", "You can't stop coughing!")]</span>")
owner.Stun(20)
owner.emote("cough")
addtimer(CALLBACK(owner, /mob/.proc/emote, "cough"), 6)
addtimer(CALLBACK(owner, /mob/.proc/emote, "cough"), 12)
owner.emote("cough")
..()
/datum/brain_trauma/mild/expressive_aphasia
name = "Expressive Aphasia"
desc = "Patient is affected by partial loss of speech leading to a reduced vocabulary."
scan_desc = "inability to form complex sentences"
gain_text = "<span class='warning'>You lose your grasp on complex words.</span>"
lose_text = "<span class='notice'>You feel your vocabulary returning to normal again.</span>"
var/static/list/common_words = world.file2list("strings/1000_most_common.txt")
/datum/brain_trauma/mild/expressive_aphasia/handle_speech(datum/source, list/speech_args)
var/message = speech_args[SPEECH_MESSAGE]
if(message)
var/list/message_split = splittext(message, " ")
var/list/new_message = list()
for(var/word in message_split)
var/suffix = ""
var/suffix_foundon = 0
for(var/potential_suffix in list("." , "," , ";" , "!" , ":" , "?"))
suffix_foundon = findtext(word, potential_suffix, -length(potential_suffix))
if(suffix_foundon)
suffix = potential_suffix
break
if(suffix_foundon)
word = copytext(word, 1, suffix_foundon)
word = html_decode(word)
if(lowertext(word) in common_words)
new_message += word + suffix
else
if(prob(30) && message_split.len > 2)
new_message += pick("uh","erm")
break
else
var/list/charlist = text2charlist(word)
shuffle_inplace(charlist)
new_message += jointext(charlist, "") + suffix
message = jointext(new_message, " ")
speech_args[SPEECH_MESSAGE] = trim(message)
/datum/brain_trauma/mild/mind_echo
name = "Mind Echo"
desc = "Patient's language neurons do not terminate properly, causing previous speech patterns to occasionally resurface spontaneously."
scan_desc = "looping neural pattern"
gain_text = "<span class='warning'>You feel a faint echo of your thoughts...</span>"
lose_text = "<span class='notice'>The faint echo fades away.</span>"
var/list/hear_dejavu = list()
var/list/speak_dejavu = list()
/datum/brain_trauma/mild/mind_echo/handle_hearing(datum/source, list/hearing_args)
if(owner == hearing_args[HEARING_SPEAKER])
return
if(hear_dejavu.len >= 5)
if(prob(25))
var/deja_vu = pick_n_take(hear_dejavu)
var/static/regex/quoted_spoken_message = regex("\".+\"", "gi")
hearing_args[HEARING_MESSAGE] = quoted_spoken_message.Replace(hearing_args[HEARING_MESSAGE], "\"[deja_vu]\"") //Quotes included to avoid cases where someone says part of their name
return
if(hear_dejavu.len >= 15)
if(prob(50))
popleft(hear_dejavu) //Remove the oldest
hear_dejavu += hearing_args[HEARING_RAW_MESSAGE]
else
hear_dejavu += hearing_args[HEARING_RAW_MESSAGE]
/datum/brain_trauma/mild/mind_echo/handle_speech(datum/source, list/speech_args)
if(speak_dejavu.len >= 5)
if(prob(25))
var/deja_vu = pick_n_take(speak_dejavu)
speech_args[SPEECH_MESSAGE] = deja_vu
return
if(speak_dejavu.len >= 15)
if(prob(50))
popleft(speak_dejavu) //Remove the oldest
speak_dejavu += speech_args[SPEECH_MESSAGE]
else
speak_dejavu += speech_args[SPEECH_MESSAGE]
+20 -99
View File
@@ -2,8 +2,8 @@
name = "Phobia"
desc = "Patient is unreasonably afraid of something."
scan_desc = "phobia"
gain_text = "<span class='warning'>You start finding default values very unnerving...</span>"
lose_text = "<span class='notice'>You no longer feel afraid of default values.</span>"
gain_text = ""
lose_text = ""
var/phobia_type
var/next_check = 0
var/next_scare = 0
@@ -14,10 +14,8 @@
var/list/trigger_turfs
var/list/trigger_species
/datum/brain_trauma/mild/phobia/New(new_phobia_type)
if(new_phobia_type)
phobia_type = new_phobia_type
/datum/brain_trauma/mild/phobia/New(specific_type)
phobia_type = specific_type
if(!phobia_type)
phobia_type = pick(SStraumas.phobia_types)
@@ -31,11 +29,6 @@
trigger_species = SStraumas.phobia_species[phobia_type]
..()
/datum/brain_trauma/mild/phobia/on_clone()
if(clonable)
return new type(phobia_type)
/datum/brain_trauma/mild/phobia/on_life()
..()
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
@@ -51,12 +44,6 @@
if(is_type_in_typecache(O, trigger_objs))
freak_out(O)
return
for(var/mob/living/carbon/human/HU in seen_atoms) //check equipment for trigger items
for(var/X in HU.get_all_slots() | HU.held_items)
var/obj/I = X
if(!QDELETED(I) && is_type_in_typecache(I, trigger_objs))
freak_out(I)
return
if(LAZYLEN(trigger_turfs))
for(var/turf/T in seen_atoms)
@@ -64,41 +51,45 @@
freak_out(T)
return
seen_atoms -= owner //make sure they aren't afraid of themselves.
if(LAZYLEN(trigger_mobs) || LAZYLEN(trigger_species))
if(LAZYLEN(trigger_mobs) || LAZYLEN(trigger_objs))
for(var/mob/M in seen_atoms)
if(is_type_in_typecache(M, trigger_mobs))
freak_out(M)
return
else if(ishuman(M)) //check their species
else if(ishuman(M)) //check their equipment for trigger items
var/mob/living/carbon/human/H = M
if(LAZYLEN(trigger_species) && H.dna && H.dna.species && is_type_in_typecache(H.dna.species, trigger_species))
freak_out(H)
return
/datum/brain_trauma/mild/phobia/handle_hearing(datum/source, list/hearing_args)
for(var/X in H.get_all_slots() | H.held_items)
var/obj/I = X
if(!QDELETED(I) && is_type_in_typecache(I, trigger_objs))
freak_out(I)
return
/datum/brain_trauma/mild/phobia/on_hear(message, speaker, message_language, raw_message, radio_freq)
if(!owner.can_hear() || world.time < next_scare) //words can't trigger you if you can't hear them *taps head*
return
return message
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
return
return message
for(var/word in trigger_words)
var/regex/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i")
var/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i")
if(findtext(hearing_args[HEARING_RAW_MESSAGE], reg))
if(findtext(raw_message, reg))
addtimer(CALLBACK(src, .proc/freak_out, null, word), 10) //to react AFTER the chat message
hearing_args[HEARING_MESSAGE] = reg.Replace(hearing_args[HEARING_MESSAGE], "<span class='phobia'>$1</span>")
break
return message
/datum/brain_trauma/mild/phobia/handle_speech(datum/source, list/speech_args)
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
return
for(var/word in trigger_words)
var/regex/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i")
var/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i")
if(findtext(speech_args[SPEECH_MESSAGE], reg))
to_chat(owner, "<span class='warning'>You can't bring yourself to say the word \"<span class='phobia'>[word]</span>\"!</span>")
to_chat(owner, "<span class='warning'>You can't bring yourself to say the word \"[word]\"!</span>")
speech_args[SPEECH_MESSAGE] = ""
/datum/brain_trauma/mild/phobia/proc/freak_out(atom/reason, trigger_word)
@@ -134,76 +125,6 @@
owner.Jitter(10)
owner.stuttering += 10
// Defined phobia types for badminry, not included in the RNG trauma pool to avoid diluting.
/datum/brain_trauma/mild/phobia/spiders
phobia_type = "spiders"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/space
phobia_type = "space"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/security
phobia_type = "security"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/clowns
phobia_type = "clowns"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/greytide
phobia_type = "greytide"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/lizards
phobia_type = "lizards"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/skeletons
phobia_type = "skeletons"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/snakes
phobia_type = "snakes"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/robots
phobia_type = "robots"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/doctors
phobia_type = "doctors"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/authority
phobia_type = "authority"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/supernatural
phobia_type = "the supernatural"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/aliens
phobia_type = "aliens"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/strangers
phobia_type = "strangers"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/birds
phobia_type = "birds"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/falling
phobia_type = "falling"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/anime
phobia_type = "anime"
random_gain = FALSE
/datum/brain_trauma/mild/phobia/conspiracies
phobia_type = "conspiracies"
random_gain = FALSE
+3 -3
View File
@@ -119,7 +119,7 @@
owner.update_disabled_bodyparts()
/datum/brain_trauma/severe/paralysis/paraplegic
random_gain = FALSE
//can_gain = FALSE maybe breaks.
paralysis_type = "legs"
resilience = TRAUMA_RESILIENCE_ABSOLUTE
@@ -149,7 +149,7 @@
/datum/brain_trauma/severe/monophobia
name = "Monophobia"
desc = "Patient feels sick and distressed when not around other people, leading to potentially lethal levels of stress."
scan_desc = "monophobia"
scan_desc = "severe monophobia"
gain_text = ""
lose_text = "<span class='notice'>You feel like you could be safe on your own.</span>"
var/stress = 0
@@ -168,7 +168,7 @@
if(stress > 10 && (prob(5)))
stress_reaction()
else
stress = max(stress - 4, 0)
stress -= 4
/datum/brain_trauma/severe/monophobia/proc/check_alone()
if(HAS_TRAIT(owner, TRAIT_BLIND))
+3 -106
View File
@@ -22,14 +22,6 @@
else
speak("neutral", prob(25))
/datum/brain_trauma/special/godwoken/on_gain()
ADD_TRAIT(owner, TRAIT_HOLY, TRAUMA_TRAIT)
..()
/datum/brain_trauma/special/godwoken/on_lose()
REMOVE_TRAIT(owner, TRAIT_HOLY, TRAUMA_TRAIT)
..()
/datum/brain_trauma/special/godwoken/proc/speak(type, include_owner = FALSE)
var/message
switch(type)
@@ -44,7 +36,7 @@
else
message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_neutral")
playsound(get_turf(owner), 'sound/magic/clockwork/invoke_general.ogg', 200, TRUE, 5)
playsound(get_turf(owner), 'sound/magic/clockwork/invoke_general.ogg', 200, 1, 5)
voice_of_god(message, owner, list("colossus","yell"), 2.5, include_owner, FALSE)
/datum/brain_trauma/special/bluespace_prophet
@@ -142,101 +134,7 @@
/datum/brain_trauma/special/psychotic_brawling/bath_salts
name = "Chemical Violent Psychosis"
clonable = FALSE
/datum/brain_trauma/special/tenacity
name = "Tenacity"
desc = "Patient is psychologically unaffected by pain and injuries, and can remain standing far longer than a normal person."
scan_desc = "traumatic neuropathy"
gain_text = "<span class='warning'>You suddenly stop feeling pain.</span>"
lose_text = "<span class='warning'>You realize you can feel pain again.</span>"
/datum/brain_trauma/special/tenacity/on_gain()
ADD_TRAIT(owner, TRAIT_NOSOFTCRIT, TRAUMA_TRAIT)
ADD_TRAIT(owner, TRAIT_NOHARDCRIT, TRAUMA_TRAIT)
..()
/datum/brain_trauma/special/tenacity/on_lose()
REMOVE_TRAIT(owner, TRAIT_NOSOFTCRIT, TRAUMA_TRAIT)
REMOVE_TRAIT(owner, TRAIT_NOHARDCRIT, TRAUMA_TRAIT)
..()
/datum/brain_trauma/special/death_whispers
name = "Functional Cerebral Necrosis"
desc = "Patient's brain is stuck in a functional near-death state, causing occasional moments of lucid hallucinations, which are often interpreted as the voices of the dead."
scan_desc = "chronic functional necrosis"
gain_text = "<span class='warning'>You feel dead inside.</span>"
lose_text = "<span class='notice'>You feel alive again.</span>"
var/active = FALSE
/datum/brain_trauma/special/death_whispers/on_life()
..()
if(!active && prob(2))
whispering()
/datum/brain_trauma/special/death_whispers/on_lose()
if(active)
cease_whispering()
..()
/datum/brain_trauma/special/death_whispers/proc/whispering()
ADD_TRAIT(owner, TRAIT_SIXTHSENSE, TRAUMA_TRAIT)
active = TRUE
addtimer(CALLBACK(src, .proc/cease_whispering), rand(50, 300))
/datum/brain_trauma/special/death_whispers/proc/cease_whispering()
REMOVE_TRAIT(owner, TRAIT_SIXTHSENSE, TRAUMA_TRAIT)
active = FALSE
/datum/brain_trauma/special/existential_crisis
name = "Existential Crisis"
desc = "Patient's hold on reality becomes faint, causing occasional bouts of non-existence."
scan_desc = "existential crisis"
gain_text = "<span class='notice'>You feel less real.</span>"
lose_text = "<span class='warning'>You feel more substantial again.</span>"
var/obj/effect/abstract/sync_holder/veil/veil
var/next_crisis = 0
/datum/brain_trauma/special/existential_crisis/on_life()
..()
if(!veil && world.time > next_crisis && prob(3))
if(isturf(owner.loc))
fade_out()
/datum/brain_trauma/special/existential_crisis/on_lose()
if(veil)
fade_in()
..()
/datum/brain_trauma/special/existential_crisis/proc/fade_out()
if(veil)
return
var/duration = rand(50, 450)
veil = new(owner.drop_location())
to_chat(owner, "<span class='warning'>[pick("You stop thinking for a moment. Therefore you are not.",\
"To be or not to be...",\
"Why exist?",\
"You stop keeping it real.",\
"Your grip on existence slips.",\
"Do you even exist?",\
"You simply fade away.")]</span>")
owner.forceMove(veil)
SEND_SIGNAL(owner, COMSIG_MOVABLE_SECLUDED_LOCATION)
for(var/thing in owner)
var/atom/movable/AM = thing
SEND_SIGNAL(AM, COMSIG_MOVABLE_SECLUDED_LOCATION)
next_crisis = world.time + 600
addtimer(CALLBACK(src, .proc/fade_in), duration)
/datum/brain_trauma/special/existential_crisis/proc/fade_in()
QDEL_NULL(veil)
to_chat(owner, "<span class='notice'>You fade back into reality.</span>")
next_crisis = world.time + 600
//base sync holder is in desynchronizer.dm
/obj/effect/abstract/sync_holder/veil
name = "non-existence"
desc = "Existence is just a state of mind."
random_gain = FALSE
/datum/brain_trauma/special/beepsky
name = "Criminal"
@@ -244,7 +142,6 @@
scan_desc = "criminal mind"
gain_text = "<span class='warning'>Justice is coming for you.</span>"
lose_text = "<span class='notice'>You were absolved for your crimes.</span>"
clonable = FALSE
random_gain = FALSE
var/obj/effect/hallucination/simple/securitron/beepsky
@@ -304,4 +201,4 @@
/obj/effect/hallucination/simple/securitron/Destroy()
STOP_PROCESSING(SSfastprocess,src)
return ..()
return ..()
+6 -10
View File
@@ -13,10 +13,6 @@
var/mob/living/split_personality/owner_backseat
/datum/brain_trauma/severe/split_personality/on_gain()
var/mob/living/M = owner
if(M.stat == DEAD) //No use assigning people to a corpse
qdel(src)
return
..()
make_backseats()
get_ghost()
@@ -27,7 +23,7 @@
/datum/brain_trauma/severe/split_personality/proc/get_ghost()
set waitfor = FALSE
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s split personality?", ROLE_PAI, null, null, 75, stranger_backseat, POLL_IGNORE_SPLITPERSONALITY)
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s split personality?", ROLE_PAI, null, null, 75, stranger_backseat)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
stranger_backseat.key = C.key
@@ -195,13 +191,13 @@
/datum/brain_trauma/severe/split_personality/brainwashing/on_life()
return //no random switching
/datum/brain_trauma/severe/split_personality/brainwashing/handle_hearing(datum/source, list/hearing_args)
if(HAS_TRAIT(owner, TRAIT_DEAF) || owner == hearing_args[HEARING_SPEAKER])
return
var/message = hearing_args[HEARING_MESSAGE]
/datum/brain_trauma/severe/split_personality/brainwashing/on_hear(message, speaker, message_language, raw_message, radio_freq)
if(HAS_TRAIT(owner, TRAIT_DEAF) || owner == speaker)
return message
if(findtext(message, codeword))
hearing_args[HEARING_MESSAGE] = replacetext(message, codeword, "<span class='warning'>[codeword]</span>")
message = replacetext(message, codeword, "<span class='warning'>[codeword]</span>")
addtimer(CALLBACK(src, /datum/brain_trauma/severe/split_personality.proc/switch_personalities), 10)
return message
/datum/brain_trauma/severe/split_personality/brainwashing/handle_speech(datum/source, list/speech_args)
if(findtext(speech_args[SPEECH_MESSAGE], codeword))
+6 -6
View File
@@ -39,12 +39,12 @@
//title_image = ntitle_image
/datum/browser/proc/add_stylesheet(name, file)
if(istype(name, /datum/asset/spritesheet))
var/datum/asset/spritesheet/sheet = name
stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]"
else
stylesheets["[ckey(name)].css"] = file
register_asset("[ckey(name)].css", file)
stylesheets["[ckey(name)].css"] = file
register_asset("[ckey(name)].css", file)
/datum/browser/proc/add_script(name, file)
scripts["[ckey(name)].js"] = file
register_asset("[ckey(name)].js", file)
/datum/browser/proc/set_content(ncontent)
content = ncontent
+9
View File
@@ -158,6 +158,15 @@
else
owner.crit_threshold -= (holdmyinsanityeffect - insanity_effect)
if(HAS_TRAIT(owner, TRAIT_DEPRESSION))
if(prob(0.05))
add_event(null, "depression", /datum/mood_event/depression)
clear_event(null, "jolly")
if(HAS_TRAIT(owner, TRAIT_JOLLY))
if(prob(0.05))
add_event(null, "jolly", /datum/mood_event/jolly)
clear_event(null, "depression")
holdmyinsanityeffect = insanity_effect
HandleNutrition(owner)
+8 -2
View File
@@ -24,7 +24,7 @@
if(isliving(parent))
host_mob = parent
if(MOB_SILICON in host_mob.mob_biotypes) //Shouldn't happen, but this avoids HUD runtimes in case a silicon gets them somehow.
if(!(MOB_ORGANIC in host_mob.mob_biotypes) && !(MOB_UNDEAD in host_mob.mob_biotypes)) //Shouldn't happen, but this avoids HUD runtimes in case a silicon gets them somehow.
return COMPONENT_INCOMPATIBLE
host_mob.hud_set_nanite_indicator()
@@ -53,6 +53,7 @@
RegisterSignal(parent, COMSIG_MOB_ALLOWED, .proc/check_access)
RegisterSignal(parent, COMSIG_LIVING_ELECTROCUTE_ACT, .proc/on_shock)
RegisterSignal(parent, COMSIG_LIVING_MINOR_SHOCK, .proc/on_minor_shock)
RegisterSignal(parent, COMSIG_MOVABLE_HEAR, .proc/on_hear)
RegisterSignal(parent, COMSIG_SPECIES_GAIN, .proc/check_viable_biotype)
RegisterSignal(parent, COMSIG_NANITE_SIGNAL, .proc/receive_signal)
@@ -190,13 +191,18 @@
var/datum/nanite_program/NP = X
NP.on_death(gibbed)
/datum/component/nanites/proc/on_hear(datum/source, message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
/datum/component/nanites/proc/receive_signal(datum/source, code, source = "an unidentified source")
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.receive_signal(code, source)
/datum/component/nanites/proc/check_viable_biotype()
if((MOB_SILICON in host_mob.mob_biotypes))
if(!(MOB_ORGANIC in host_mob.mob_biotypes) && !(MOB_UNDEAD in host_mob.mob_biotypes))
qdel(src) //bodytype no longer sustains nanites
/datum/component/nanites/proc/check_access(datum/source, obj/O)
-2
View File
@@ -60,7 +60,6 @@
move_react()
/datum/component/orbiter/proc/begin_orbit(atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
SEND_SIGNAL(parent, COMSIG_ATOM_ORBIT_BEGIN, orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
if(orbiter.orbiting)
if(orbiter.orbiting == src)
orbiter.orbiting.end_orbit(orbiter, TRUE)
@@ -100,7 +99,6 @@
/datum/component/orbiter/proc/end_orbit(atom/movable/orbiter, refreshing=FALSE)
if(!orbiters[orbiter])
return
SEND_SIGNAL(parent, COMSIG_ATOM_ORBIT_END, orbiter, refreshing)
UnregisterSignal(orbiter, COMSIG_MOVABLE_MOVED)
orbiter.SpinAnimation(0, 0)
orbiters -= orbiter
+2 -2
View File
@@ -130,7 +130,7 @@
//KEYS
/datum/component/riding/proc/keycheck(mob/user)
return !keytype || user?.is_holding_item_of_type(keytype)
return !keytype || user.is_holding_item_of_type(keytype)
//BUCKLE HOOKS
/datum/component/riding/proc/restore_position(mob/living/buckled_mob)
@@ -150,7 +150,7 @@
/datum/component/riding/proc/handle_ride(mob/user, direction)
var/atom/movable/AM = parent
if(user && user.incapacitated())
if(user.incapacitated())
Unbuckle(user)
return
-1
View File
@@ -106,7 +106,6 @@
if(!can_be_rotated.Invoke(user, rotation) || !can_user_rotate.Invoke(user, rotation))
return
BaseRot(user, rotation)
return TRUE
/datum/component/simple_rotation/proc/WrenchRot(datum/source, obj/item/I, mob/living/user)
if(!can_be_rotated.Invoke(user,default_rotation_direction) || !can_user_rotate.Invoke(user,default_rotation_direction))
+1 -2
View File
@@ -8,7 +8,6 @@
if(!ismovableatom(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, list(COMSIG_MOVABLE_Z_CHANGED), .proc/check_in_bounds)
RegisterSignal(parent, list(COMSIG_MOVABLE_SECLUDED_LOCATION), .proc/relocate)
RegisterSignal(parent, list(COMSIG_PARENT_PREQDELETED), .proc/check_deletion)
RegisterSignal(parent, list(COMSIG_ITEM_IMBUE_SOUL), .proc/check_soul_imbue)
src.inform_admins = inform_admins
@@ -33,7 +32,6 @@
var/atom/movable/AM = parent
AM.forceMove(targetturf)
to_chat(get(parent, /mob), "<span class='danger'>You can't help but feel that you just lost something back there...</span>")
// move the disc, so ghosts remain orbiting it even if it's "destroyed"
return targetturf
@@ -42,6 +40,7 @@
return
else
var/turf/currentturf = get_turf(src)
to_chat(get(parent, /mob), "<span class='danger'>You can't help but feel that you just lost something back there...</span>")
var/turf/targetturf = relocate()
log_game("[parent] has been moved out of bounds in [loc_name(currentturf)]. Moving it to [loc_name(targetturf)].")
if(inform_admins)
@@ -43,26 +43,6 @@
/datum/component/storage/concrete/pockets/small/detective
attack_hand_interact = TRUE // so the detectives would discover pockets in their hats
/datum/component/storage/concrete/pockets/chefhat
attack_hand_interact = TRUE
max_items = 1
max_w_class = WEIGHT_CLASS_NORMAL
/datum/component/storage/concrete/pockets/chefhat/Initialize()
. = ..()
can_hold = typecacheof(list(
/obj/item/clothing/head/mob_holder,
/obj/item/reagent_containers/food/snacks/deadmouse
))
/datum/component/storage/concrete/pockets/chefhat/can_be_inserted(obj/item/I, stop_messages, mob/M)
. = ..()
if(istype(I,/obj/item/clothing/head/mob_holder))
var/obj/item/clothing/head/mob_holder/mausholder = I
if(locate(/mob/living/simple_animal/mouse) in mausholder.contents)
return
return FALSE
/datum/component/storage/concrete/pockets/shoes
attack_hand_interact = FALSE
quickdraw = TRUE
File diff suppressed because it is too large Load Diff
-104
View File
@@ -1,104 +0,0 @@
/**
* Observers voting on things through orbiting
*/
/datum/component/twitch_plays
/// Observers
var/list/mob/players = list()
/datum/component/twitch_plays/Initialize(...)
. = ..()
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, COMSIG_ATOM_ORBIT_BEGIN, .proc/on_start_orbit)
RegisterSignal(parent, COMSIG_ATOM_ORBIT_END, .proc/on_end_orbit)
/datum/component/twitch_plays/Destroy(force, silent)
for(var/i in players)
DetachPlayer(i)
return ..()
/datum/component/twitch_plays/proc/on_start_orbit(datum/source, atom/movable/orbiter)
if(!isobserver(orbiter))
return
AttachPlayer(orbiter)
/datum/component/twitch_plays/proc/on_end_orbit(datum/source, atom/movable/orbiter)
if(!(orbiter in players))
return
DetachPlayer(orbiter)
/datum/component/twitch_plays/proc/AttachPlayer(mob/dead/observer)
players |= observer
RegisterSignal(observer, COMSIG_PARENT_QDELETING, .proc/on_end_orbit)
/datum/component/twitch_plays/proc/DetachPlayer(mob/dead/observer)
players -= observer
UnregisterSignal(observer, COMSIG_PARENT_QDELETING)
/// Simple movement one
/datum/component/twitch_plays/simple_movement
/// Movement votes by observer
var/list/votes = list()
/// Allow diagonals
var/allow_diagonal = FALSE
/datum/component/twitch_plays/simple_movement/Initialize(...)
. = ..()
if(. & COMPONENT_INCOMPATIBLE)
return
RegisterSignal(parent, COMSIG_TWITCH_PLAYS_MOVEMENT_DATA, .proc/fetch_data)
/datum/component/twitch_plays/simple_movement/AttachPlayer(mob/dead/observer)
. = ..()
RegisterSignal(observer, COMSIG_MOVABLE_PRE_MOVE, .proc/pre_move)
/datum/component/twitch_plays/simple_movement/DetachPlayer(mob/dead/observer)
. = ..()
UnregisterSignal(observer, COMSIG_MOVABLE_PRE_MOVE)
/datum/component/twitch_plays/simple_movement/proc/pre_move(datum/source, turf/newLoc)
if(get_dist(newLoc, parent) > 1) // they're trying to escape orbit
return
. = COMPONENT_MOVABLE_BLOCK_PRE_MOVE
var/dir = get_dir(parent, newLoc)
if(!dir)
return
if(allow_diagonal || !((dir - 1) & dir))
votes[source] = dir
else // pick one or the other
votes[source] = prob(50)? (dir & ~(dir - 1)) : (dir & (dir - 1))
/datum/component/twitch_plays/simple_movement/proc/fetch_data(datum/source, wipe_votes)
if(!votes.len)
return
var/list/total = list(TEXT_NORTH, TEXT_SOUTH, TEXT_EAST, TEXT_WEST)
for(var/i in votes)
total[num2text(votes[i])] += 1
. = text2num(pickweight(total, 0))
if(wipe_votes)
votes.len = 0
/datum/component/twitch_plays/simple_movement/auto
var/move_delay = 2
var/last_move = 0
/datum/component/twitch_plays/simple_movement/auto/Initialize(...)
if(!ismovable(parent))
return COMPONENT_INCOMPATIBLE
. = ..()
if(. & COMPONENT_INCOMPATIBLE)
return
START_PROCESSING(SSfastprocess, src)
/datum/component/twitch_plays/simple_movement/auto/Destroy(force, silent)
STOP_PROCESSING(SSfastprocess, src)
return ..()
/datum/component/twitch_plays/simple_movement/auto/process()
var/dir = fetch_data(null, TRUE)
if(!dir)
return
if(world.time < (last_move + move_delay))
return
last_move = world.time
step(parent, dir)
+15 -25
View File
@@ -25,8 +25,6 @@ GLOBAL_LIST_EMPTY(uplinks)
var/unlock_code
var/failsafe_code
var/datum/ui_state/checkstate
var/compact_mode = FALSE
var/debug = FALSE
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20, datum/ui_state/_checkstate)
if(!isitem(parent))
@@ -123,7 +121,7 @@ GLOBAL_LIST_EMPTY(uplinks)
active = TRUE
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "uplink", name, 620, 580, master_ui, state)
ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state)
ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input.
ui.set_style("syndicate")
ui.open()
@@ -140,35 +138,29 @@ GLOBAL_LIST_EMPTY(uplinks)
var/list/data = list()
data["telecrystals"] = telecrystals
data["lockable"] = lockable
data["compact_mode"] = compact_mode
return data
/datum/component/uplink/ui_static_data(mob/user)
var/list/data = list()
data["categories"] = list()
for(var/category in uplink_items)
var/list/cat = list(
"name" = category,
"items" = (category == selected_cat ? list() : null))
for(var/item in uplink_items[category])
var/datum/uplink_item/I = uplink_items[category][item]
if(I.limited_stock == 0)
continue
if(I.restricted_roles.len)
var/is_inaccessible = TRUE
for(var/R in I.restricted_roles)
if(R == user.mind.assigned_role || debug)
is_inaccessible = FALSE
if(is_inaccessible)
if(category == selected_cat)
for(var/item in uplink_items[category])
var/datum/uplink_item/I = uplink_items[category][item]
if(I.limited_stock == 0)
continue
if(I.restricted_roles.len)
var/is_inaccessible = 1
for(var/R in I.restricted_roles)
if(R == user.mind.assigned_role)
is_inaccessible = 0
if(is_inaccessible)
continue
cat["items"] += list(list(
"name" = I.name,
"cost" = I.cost,
"desc" = I.desc,
))
cat["items"] += list(list(
"name" = I.name,
"cost" = I.cost,
"desc" = I.desc,
))
data["categories"] += list(cat)
return data
@@ -196,8 +188,6 @@ GLOBAL_LIST_EMPTY(uplinks)
SStgui.close_uis(src)
if("select")
selected_cat = params["category"]
if("compact_toggle")
compact_mode = !compact_mode
return TRUE
/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U)
+1400 -1430
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -103,7 +103,7 @@
if(!(spread_flags & DISEASE_SPREAD_AIRBORNE) && !force_spread)
return
if(affected_mob.reagents.has_reagent(/datum/reagent/medicine/spaceacillin) || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10)))
if(affected_mob.reagents.has_reagent("spaceacillin") || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10)))
return
var/spread_range = 2
+488 -492
View File
@@ -1,492 +1,488 @@
/*
Advance Disease is a system for Virologist to Engineer their own disease with symptoms that have effects and properties
which add onto the overall disease.
If you need help with creating new symptoms or expanding the advance disease, ask for Giacom on #coderbus.
*/
/*
PROPERTIES
*/
/datum/disease/advance
name = "Unknown" // We will always let our Virologist name our disease.
desc = "An engineered disease which can contain a multitude of symptoms."
form = "Advance Disease" // Will let med-scanners know that this disease was engineered.
agent = "advance microbes"
max_stages = 5
spread_text = "Unknown"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
// NEW VARS
var/list/properties = list()
var/list/symptoms = list() // The symptoms of the disease.
var/id = ""
var/processing = FALSE
var/mutable = TRUE //set to FALSE to prevent most in-game methods of altering the disease via virology
var/oldres //To prevent setting new cures unless resistance changes.
// The order goes from easy to cure to hard to cure. Keep in mind that sentient diseases pick two cures from tier 6 and up, ensure they wont react away in bodies.
var/static/list/advance_cures = list(
list( // level 1
/datum/reagent/copper, /datum/reagent/silver, /datum/reagent/iodine, /datum/reagent/iron, /datum/reagent/carbon
),
list( // level 2
/datum/reagent/potassium, /datum/reagent/consumable/ethanol, /datum/reagent/lithium,
/datum/reagent/silicon, /datum/reagent/bromine
),
list( // level 3
/datum/reagent/consumable/sodiumchloride, /datum/reagent/consumable/sugar, /datum/reagent/consumable/orangejuice,
/datum/reagent/consumable/tomatojuice, /datum/reagent/consumable/milk
),
list( //level 4
/datum/reagent/medicine/spaceacillin, /datum/reagent/medicine/salglu_solution,
/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/charcoal
),
list( //level 5
/datum/reagent/oil, /datum/reagent/medicine/synaptizine, /datum/reagent/medicine/mannitol,
/datum/reagent/drug/space_drugs, /datum/reagent/cryptobiolin
),
list( // level 6
/datum/reagent/phenol, /datum/reagent/medicine/inacusiate, /datum/reagent/medicine/oculine, /datum/reagent/medicine/antihol
),
list( // level 7
/datum/reagent/medicine/leporazine, /datum/reagent/toxin/mindbreaker, /datum/reagent/medicine/corazone
),
list( // level 8
/datum/reagent/pax, /datum/reagent/drug/happiness, /datum/reagent/medicine/ephedrine
),
list( // level 9
/datum/reagent/toxin/lipolicide, /datum/reagent/medicine/sal_acid
),
list( // level 10
/datum/reagent/medicine/haloperidol, /datum/reagent/drug/aranesp, /datum/reagent/medicine/diphenhydramine
),
list( //level 11
/datum/reagent/medicine/modafinil, /datum/reagent/toxin/anacea
)
)
/*
OLD PROCS
*/
/datum/disease/advance/New()
Refresh()
/datum/disease/advance/Destroy()
if(processing)
for(var/datum/symptom/S in symptoms)
S.End(src)
return ..()
/datum/disease/advance/try_infect(var/mob/living/infectee, make_copy = TRUE)
//see if we are more transmittable than enough diseases to replace them
//diseases replaced in this way do not confer immunity
var/list/advance_diseases = list()
for(var/datum/disease/advance/P in infectee.diseases)
advance_diseases += P
var/replace_num = advance_diseases.len + 1 - DISEASE_LIMIT //amount of diseases that need to be removed to fit this one
if(replace_num > 0)
sortTim(advance_diseases, /proc/cmp_advdisease_resistance_asc)
for(var/i in 1 to replace_num)
var/datum/disease/advance/competition = advance_diseases[i]
if(totalTransmittable() > competition.totalResistance())
competition.cure(FALSE)
else
return FALSE //we are not strong enough to bully our way in
infect(infectee, make_copy)
return TRUE
// Randomly pick a symptom to activate.
/datum/disease/advance/stage_act()
..()
if(carrier)
return
if(symptoms && symptoms.len)
if(!processing)
processing = TRUE
for(var/datum/symptom/S in symptoms)
if(S.Start(src)) //this will return FALSE if the symptom is neutered
S.next_activation = world.time + rand(S.symptom_delay_min * 10, S.symptom_delay_max * 10)
S.on_stage_change(src)
for(var/datum/symptom/S in symptoms)
S.Activate(src)
// Tell symptoms stage changed
/datum/disease/advance/update_stage(new_stage)
..()
for(var/datum/symptom/S in symptoms)
S.on_stage_change(src)
// Compares type then ID.
/datum/disease/advance/IsSame(datum/disease/advance/D)
if(!(istype(D, /datum/disease/advance)))
return 0
if(GetDiseaseID() != D.GetDiseaseID())
return 0
return 1
// Returns the advance disease with a different reference memory.
/datum/disease/advance/Copy()
var/datum/disease/advance/A = ..()
QDEL_LIST(A.symptoms)
for(var/datum/symptom/S in symptoms)
A.symptoms += S.Copy()
A.properties = properties.Copy()
A.id = id
A.oldres = oldres
//this is a new disease starting over at stage 1, so processing is not copied
return A
//Describe this disease to an admin in detail (for logging)
/datum/disease/advance/admin_details()
var/list/name_symptoms = list()
for(var/datum/symptom/S in symptoms)
name_symptoms += S.name
return "[name] sym:[english_list(name_symptoms)] r:[totalResistance()] s:[totalStealth()] ss:[totalStageSpeed()] t:[totalTransmittable()]"
/*
NEW PROCS
*/
// Mix the symptoms of two diseases (the src and the argument)
/datum/disease/advance/proc/Mix(datum/disease/advance/D)
if(!(IsSame(D)))
var/list/possible_symptoms = shuffle(D.symptoms)
for(var/datum/symptom/S in possible_symptoms)
AddSymptom(S.Copy())
/datum/disease/advance/proc/HasSymptom(datum/symptom/S)
for(var/datum/symptom/symp in symptoms)
if(symp.type == S.type)
return 1
return 0
// Will generate new unique symptoms, use this if there are none. Returns a list of symptoms that were generated.
/datum/disease/advance/proc/GenerateSymptoms(level_min, level_max, amount_get = 0)
var/list/generated = list() // Symptoms we generated.
// Generate symptoms. By default, we only choose non-deadly symptoms.
var/list/possible_symptoms = list()
for(var/symp in SSdisease.list_symptoms)
var/datum/symptom/S = new symp
if(S.naturally_occuring && S.level >= level_min && S.level <= level_max)
if(!HasSymptom(S))
possible_symptoms += S
if(!possible_symptoms.len)
return generated
// Random chance to get more than one symptom
var/number_of = amount_get
if(!amount_get)
number_of = 1
while(prob(20))
number_of += 1
for(var/i = 1; number_of >= i && possible_symptoms.len; i++)
generated += pick_n_take(possible_symptoms)
return generated
/datum/disease/advance/proc/Refresh(new_name = FALSE)
GenerateProperties()
AssignProperties()
if(processing && symptoms && symptoms.len)
for(var/datum/symptom/S in symptoms)
S.Start(src)
S.on_stage_change(src)
id = null
var/the_id = GetDiseaseID()
if(!SSdisease.archive_diseases[the_id])
SSdisease.archive_diseases[the_id] = src // So we don't infinite loop
SSdisease.archive_diseases[the_id] = Copy()
if(new_name)
AssignName()
//Generate disease properties based on the effects. Returns an associated list.
/datum/disease/advance/proc/GenerateProperties()
properties = list("resistance" = 0, "stealth" = 0, "stage_rate" = 0, "transmittable" = 0, "severity" = 0)
for(var/datum/symptom/S in symptoms)
properties["resistance"] += S.resistance
properties["stealth"] += S.stealth
properties["stage_rate"] += S.stage_speed
properties["transmittable"] += S.transmittable
if(!S.neutered)
properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity non-neutered symptom
// Assign the properties that are in the list.
/datum/disease/advance/proc/AssignProperties()
if(properties && properties.len)
if(properties["stealth"] >= 2)
visibility_flags |= HIDDEN_SCANNER
else
visibility_flags &= ~HIDDEN_SCANNER
SetSpread(CLAMP(2 ** (properties["transmittable"] - symptoms.len), DISEASE_SPREAD_BLOOD, DISEASE_SPREAD_AIRBORNE))
permeability_mod = max(CEILING(0.4 * properties["transmittable"], 1), 1)
cure_chance = 15 - CLAMP(properties["resistance"], -5, 5) // can be between 10 and 20
stage_prob = max(properties["stage_rate"], 2)
SetSeverity(properties["severity"])
GenerateCure(properties)
else
CRASH("Our properties were empty or null!")
// Assign the spread type and give it the correct description.
/datum/disease/advance/proc/SetSpread(spread_id)
switch(spread_id)
if(DISEASE_SPREAD_NON_CONTAGIOUS)
spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
spread_text = "None"
if(DISEASE_SPREAD_SPECIAL)
spread_flags = DISEASE_SPREAD_SPECIAL
spread_text = "None"
if(DISEASE_SPREAD_BLOOD)
spread_flags = DISEASE_SPREAD_BLOOD
spread_text = "Blood"
if(DISEASE_SPREAD_CONTACT_FLUIDS)
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS
spread_text = "Fluids"
if(DISEASE_SPREAD_CONTACT_SKIN)
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN
spread_text = "On contact"
if(DISEASE_SPREAD_AIRBORNE)
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_AIRBORNE
spread_text = "Airborne"
/datum/disease/advance/proc/SetSeverity(level_sev)
switch(level_sev)
if(-INFINITY to 0)
severity = DISEASE_SEVERITY_POSITIVE
if(1)
severity = DISEASE_SEVERITY_NONTHREAT
if(2)
severity = DISEASE_SEVERITY_MINOR
if(3)
severity = DISEASE_SEVERITY_MEDIUM
if(4)
severity = DISEASE_SEVERITY_HARMFUL
if(5)
severity = DISEASE_SEVERITY_DANGEROUS
if(6 to INFINITY)
severity = DISEASE_SEVERITY_BIOHAZARD
else
severity = "Unknown"
// Will generate a random cure, the less resistance the symptoms have, the harder the cure.
/datum/disease/advance/proc/GenerateCure()
if(properties && properties.len)
var/res = CLAMP(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len)
if(res == oldres)
return
cures = list(pick(advance_cures[res]))
oldres = res
// Get the cure name from the cure_id
var/datum/reagent/D = GLOB.chemical_reagents_list[cures[1]]
cure_text = D.name
// Randomly generate a symptom, has a chance to lose or gain a symptom.
/datum/disease/advance/proc/Evolve(min_level, max_level, ignore_mutable = FALSE)
if(!mutable && !ignore_mutable)
return
var/s = safepick(GenerateSymptoms(min_level, max_level, 1))
if(s)
AddSymptom(s)
Refresh(TRUE)
return
// Randomly remove a symptom.
/datum/disease/advance/proc/Devolve(ignore_mutable = FALSE)
if(!mutable && !ignore_mutable)
return
if(symptoms.len > 1)
var/s = safepick(symptoms)
if(s)
RemoveSymptom(s)
Refresh(TRUE)
// Randomly neuter a symptom.
/datum/disease/advance/proc/Neuter(ignore_mutable = FALSE)
if(!mutable && !ignore_mutable)
return
if(symptoms.len)
var/s = safepick(symptoms)
if(s)
NeuterSymptom(s)
Refresh(TRUE)
// Name the disease.
/datum/disease/advance/proc/AssignName(name = "Unknown")
Refresh()
var/datum/disease/advance/A = SSdisease.archive_diseases[GetDiseaseID()]
A.name = name
for(var/datum/disease/advance/AD in SSdisease.active_diseases)
AD.Refresh()
// Return a unique ID of the disease.
/datum/disease/advance/GetDiseaseID()
if(!id)
var/list/L = list()
for(var/datum/symptom/S in symptoms)
if(S.neutered)
L += "[S.id]N"
else
L += S.id
L = sortList(L) // Sort the list so it doesn't matter which order the symptoms are in.
var/result = jointext(L, ":")
id = result
return id
// Add a symptom, if it is over the limit we take a random symptom away and add the new one.
/datum/disease/advance/proc/AddSymptom(datum/symptom/S)
if(HasSymptom(S))
return
if(!(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1)))
RemoveSymptom(pick(symptoms))
symptoms += S
S.OnAdd(src)
// Simply removes the symptom.
/datum/disease/advance/proc/RemoveSymptom(datum/symptom/S)
symptoms -= S
S.OnRemove(src)
// Neuter a symptom, so it will only affect stats
/datum/disease/advance/proc/NeuterSymptom(datum/symptom/S)
if(!S.neutered)
S.neutered = TRUE
S.name += " (neutered)"
S.OnRemove(src)
/*
Static Procs
*/
// Mix a list of advance diseases and return the mixed result.
/proc/Advance_Mix(var/list/D_list)
var/list/diseases = list()
for(var/datum/disease/advance/A in D_list)
diseases += A.Copy()
if(!diseases.len)
return null
if(diseases.len <= 1)
return pick(diseases) // Just return the only entry.
var/i = 0
// Mix our diseases until we are left with only one result.
while(i < 20 && diseases.len > 1)
i++
var/datum/disease/advance/D1 = pick(diseases)
diseases -= D1
var/datum/disease/advance/D2 = pick(diseases)
D2.Mix(D1)
// Should be only 1 entry left, but if not let's only return a single entry
var/datum/disease/advance/to_return = pick(diseases)
to_return.Refresh(1)
return to_return
/proc/SetViruses(datum/reagent/R, list/data)
if(data)
var/list/preserve = list()
if(istype(data) && data["viruses"])
for(var/datum/disease/A in data["viruses"])
preserve += A.Copy()
R.data = data.Copy()
if(preserve.len)
R.data["viruses"] = preserve
/proc/AdminCreateVirus(client/user)
if(!user)
return
var/i = VIRUS_SYMPTOM_LIMIT
var/datum/disease/advance/D = new()
D.symptoms = list()
var/list/symptoms = list()
symptoms += "Done"
symptoms += SSdisease.list_symptoms.Copy()
do
if(user)
var/symptom = input(user, "Choose a symptom to add ([i] remaining)", "Choose a Symptom") in symptoms
if(isnull(symptom))
return
else if(istext(symptom))
i = 0
else if(ispath(symptom))
var/datum/symptom/S = new symptom
if(!D.HasSymptom(S))
D.symptoms += S
i -= 1
while(i > 0)
if(D.symptoms.len > 0)
var/new_name = stripped_input(user, "Name your new disease.", "New Name")
if(!new_name)
return
D.AssignName(new_name)
D.Refresh()
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
if(!is_station_level(H.z))
continue
if(!H.HasDisease(D))
H.ForceContractDisease(D)
break
var/list/name_symptoms = list()
for(var/datum/symptom/S in D.symptoms)
name_symptoms += S.name
message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.admin_details()]")
log_virus("[key_name(user)] has triggered a custom virus outbreak of [D.admin_details()]!")
/datum/disease/advance/proc/totalStageSpeed()
return properties["stage_rate"]
/datum/disease/advance/proc/totalStealth()
return properties["stealth"]
/datum/disease/advance/proc/totalResistance()
return properties["resistance"]
/datum/disease/advance/proc/totalTransmittable()
return properties["transmittable"]
/*
Advance Disease is a system for Virologist to Engineer their own disease with symptoms that have effects and properties
which add onto the overall disease.
If you need help with creating new symptoms or expanding the advance disease, ask for Giacom on #coderbus.
*/
/*
PROPERTIES
*/
/datum/disease/advance
name = "Unknown" // We will always let our Virologist name our disease.
desc = "An engineered disease which can contain a multitude of symptoms."
form = "Advance Disease" // Will let med-scanners know that this disease was engineered.
agent = "advance microbes"
max_stages = 5
spread_text = "Unknown"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
// NEW VARS
var/list/properties = list()
var/list/symptoms = list() // The symptoms of the disease.
var/id = ""
var/processing = FALSE
var/mutable = TRUE //set to FALSE to prevent most in-game methods of altering the disease via virology
var/oldres //To prevent setting new cures unless resistance changes.
// The order goes from easy to cure to hard to cure. Keep in mind that sentient diseases pick two cures from tier 6 and up, ensure they wont react away in bodies.
var/static/list/advance_cures = list(
list( // level 1
"copper", "silver", "iodine", "iron", "carbon"
),
list( // level 2
"potassium", "ethanol", "lithium", "silicon", "bromine"
),
list( // level 3
"sodiumchloride", "sugar", "orangejuice", "tomatojuice", "milk"
),
list( //level 4
"spaceacillin", "salglu_solution", "epinephrine", "charcoal"
),
list( //level 5
"oil", "synaptizine", "mannitol", "space_drugs", "cryptobiolin"
),
list( // level 6
"phenol", "inacusiate", "oculine", "antihol"
),
list( // level 7
"leporazine", "mindbreaker", "corazone"
),
list( // level 8
"pax", "happiness", "ephedrine"
),
list( // level 9
"lipolicide", "sal_acid"
),
list( // level 10
"haloperidol", "aranesp", "diphenhydramine"
),
list( //level 11
"modafinil", "anacea"
)
)
/*
OLD PROCS
*/
/datum/disease/advance/New()
Refresh()
/datum/disease/advance/Destroy()
if(processing)
for(var/datum/symptom/S in symptoms)
S.End(src)
return ..()
/datum/disease/advance/try_infect(var/mob/living/infectee, make_copy = TRUE)
//see if we are more transmittable than enough diseases to replace them
//diseases replaced in this way do not confer immunity
var/list/advance_diseases = list()
for(var/datum/disease/advance/P in infectee.diseases)
advance_diseases += P
var/replace_num = advance_diseases.len + 1 - DISEASE_LIMIT //amount of diseases that need to be removed to fit this one
if(replace_num > 0)
sortTim(advance_diseases, /proc/cmp_advdisease_resistance_asc)
for(var/i in 1 to replace_num)
var/datum/disease/advance/competition = advance_diseases[i]
if(totalTransmittable() > competition.totalResistance())
competition.cure(FALSE)
else
return FALSE //we are not strong enough to bully our way in
infect(infectee, make_copy)
return TRUE
// Randomly pick a symptom to activate.
/datum/disease/advance/stage_act()
..()
if(carrier)
return
if(symptoms && symptoms.len)
if(!processing)
processing = TRUE
for(var/datum/symptom/S in symptoms)
if(S.Start(src)) //this will return FALSE if the symptom is neutered
S.next_activation = world.time + rand(S.symptom_delay_min * 10, S.symptom_delay_max * 10)
S.on_stage_change(src)
for(var/datum/symptom/S in symptoms)
S.Activate(src)
// Tell symptoms stage changed
/datum/disease/advance/update_stage(new_stage)
..()
for(var/datum/symptom/S in symptoms)
S.on_stage_change(src)
// Compares type then ID.
/datum/disease/advance/IsSame(datum/disease/advance/D)
if(!(istype(D, /datum/disease/advance)))
return 0
if(GetDiseaseID() != D.GetDiseaseID())
return 0
return 1
// Returns the advance disease with a different reference memory.
/datum/disease/advance/Copy()
var/datum/disease/advance/A = ..()
QDEL_LIST(A.symptoms)
for(var/datum/symptom/S in symptoms)
A.symptoms += S.Copy()
A.properties = properties.Copy()
A.id = id
A.oldres = oldres
//this is a new disease starting over at stage 1, so processing is not copied
return A
//Describe this disease to an admin in detail (for logging)
/datum/disease/advance/admin_details()
var/list/name_symptoms = list()
for(var/datum/symptom/S in symptoms)
name_symptoms += S.name
return "[name] sym:[english_list(name_symptoms)] r:[totalResistance()] s:[totalStealth()] ss:[totalStageSpeed()] t:[totalTransmittable()]"
/*
NEW PROCS
*/
// Mix the symptoms of two diseases (the src and the argument)
/datum/disease/advance/proc/Mix(datum/disease/advance/D)
if(!(IsSame(D)))
var/list/possible_symptoms = shuffle(D.symptoms)
for(var/datum/symptom/S in possible_symptoms)
AddSymptom(S.Copy())
/datum/disease/advance/proc/HasSymptom(datum/symptom/S)
for(var/datum/symptom/symp in symptoms)
if(symp.type == S.type)
return 1
return 0
// Will generate new unique symptoms, use this if there are none. Returns a list of symptoms that were generated.
/datum/disease/advance/proc/GenerateSymptoms(level_min, level_max, amount_get = 0)
var/list/generated = list() // Symptoms we generated.
// Generate symptoms. By default, we only choose non-deadly symptoms.
var/list/possible_symptoms = list()
for(var/symp in SSdisease.list_symptoms)
var/datum/symptom/S = new symp
if(S.naturally_occuring && S.level >= level_min && S.level <= level_max)
if(!HasSymptom(S))
possible_symptoms += S
if(!possible_symptoms.len)
return generated
// Random chance to get more than one symptom
var/number_of = amount_get
if(!amount_get)
number_of = 1
while(prob(20))
number_of += 1
for(var/i = 1; number_of >= i && possible_symptoms.len; i++)
generated += pick_n_take(possible_symptoms)
return generated
/datum/disease/advance/proc/Refresh(new_name = FALSE)
GenerateProperties()
AssignProperties()
if(processing && symptoms && symptoms.len)
for(var/datum/symptom/S in symptoms)
S.Start(src)
S.on_stage_change(src)
id = null
var/the_id = GetDiseaseID()
if(!SSdisease.archive_diseases[the_id])
SSdisease.archive_diseases[the_id] = src // So we don't infinite loop
SSdisease.archive_diseases[the_id] = Copy()
if(new_name)
AssignName()
//Generate disease properties based on the effects. Returns an associated list.
/datum/disease/advance/proc/GenerateProperties()
properties = list("resistance" = 0, "stealth" = 0, "stage_rate" = 0, "transmittable" = 0, "severity" = 0)
for(var/datum/symptom/S in symptoms)
properties["resistance"] += S.resistance
properties["stealth"] += S.stealth
properties["stage_rate"] += S.stage_speed
properties["transmittable"] += S.transmittable
if(!S.neutered)
properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity non-neutered symptom
// Assign the properties that are in the list.
/datum/disease/advance/proc/AssignProperties()
if(properties && properties.len)
if(properties["stealth"] >= 2)
visibility_flags |= HIDDEN_SCANNER
else
visibility_flags &= ~HIDDEN_SCANNER
SetSpread(CLAMP(2 ** (properties["transmittable"] - symptoms.len), DISEASE_SPREAD_BLOOD, DISEASE_SPREAD_AIRBORNE))
permeability_mod = max(CEILING(0.4 * properties["transmittable"], 1), 1)
cure_chance = 15 - CLAMP(properties["resistance"], -5, 5) // can be between 10 and 20
stage_prob = max(properties["stage_rate"], 2)
SetSeverity(properties["severity"])
GenerateCure(properties)
else
CRASH("Our properties were empty or null!")
// Assign the spread type and give it the correct description.
/datum/disease/advance/proc/SetSpread(spread_id)
switch(spread_id)
if(DISEASE_SPREAD_NON_CONTAGIOUS)
spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
spread_text = "None"
if(DISEASE_SPREAD_SPECIAL)
spread_flags = DISEASE_SPREAD_SPECIAL
spread_text = "None"
if(DISEASE_SPREAD_BLOOD)
spread_flags = DISEASE_SPREAD_BLOOD
spread_text = "Blood"
if(DISEASE_SPREAD_CONTACT_FLUIDS)
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS
spread_text = "Fluids"
if(DISEASE_SPREAD_CONTACT_SKIN)
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN
spread_text = "On contact"
if(DISEASE_SPREAD_AIRBORNE)
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_AIRBORNE
spread_text = "Airborne"
/datum/disease/advance/proc/SetSeverity(level_sev)
switch(level_sev)
if(-INFINITY to 0)
severity = DISEASE_SEVERITY_POSITIVE
if(1)
severity = DISEASE_SEVERITY_NONTHREAT
if(2)
severity = DISEASE_SEVERITY_MINOR
if(3)
severity = DISEASE_SEVERITY_MEDIUM
if(4)
severity = DISEASE_SEVERITY_HARMFUL
if(5)
severity = DISEASE_SEVERITY_DANGEROUS
if(6 to INFINITY)
severity = DISEASE_SEVERITY_BIOHAZARD
else
severity = "Unknown"
// Will generate a random cure, the less resistance the symptoms have, the harder the cure.
/datum/disease/advance/proc/GenerateCure()
if(properties && properties.len)
var/res = CLAMP(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len)
if(res == oldres)
return
cures = list(pick(advance_cures[res]))
oldres = res
// Get the cure name from the cure_id
var/datum/reagent/D = GLOB.chemical_reagents_list[cures[1]]
cure_text = D.name
// Randomly generate a symptom, has a chance to lose or gain a symptom.
/datum/disease/advance/proc/Evolve(min_level, max_level, ignore_mutable = FALSE)
if(!mutable && !ignore_mutable)
return
var/s = safepick(GenerateSymptoms(min_level, max_level, 1))
if(s)
AddSymptom(s)
Refresh(TRUE)
return
// Randomly remove a symptom.
/datum/disease/advance/proc/Devolve(ignore_mutable = FALSE)
if(!mutable && !ignore_mutable)
return
if(symptoms.len > 1)
var/s = safepick(symptoms)
if(s)
RemoveSymptom(s)
Refresh(TRUE)
// Randomly neuter a symptom.
/datum/disease/advance/proc/Neuter(ignore_mutable = FALSE)
if(!mutable && !ignore_mutable)
return
if(symptoms.len)
var/s = safepick(symptoms)
if(s)
NeuterSymptom(s)
Refresh(TRUE)
// Name the disease.
/datum/disease/advance/proc/AssignName(name = "Unknown")
Refresh()
var/datum/disease/advance/A = SSdisease.archive_diseases[GetDiseaseID()]
A.name = name
for(var/datum/disease/advance/AD in SSdisease.active_diseases)
AD.Refresh()
// Return a unique ID of the disease.
/datum/disease/advance/GetDiseaseID()
if(!id)
var/list/L = list()
for(var/datum/symptom/S in symptoms)
if(S.neutered)
L += "[S.id]N"
else
L += S.id
L = sortList(L) // Sort the list so it doesn't matter which order the symptoms are in.
var/result = jointext(L, ":")
id = result
return id
// Add a symptom, if it is over the limit we take a random symptom away and add the new one.
/datum/disease/advance/proc/AddSymptom(datum/symptom/S)
if(HasSymptom(S))
return
if(!(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1)))
RemoveSymptom(pick(symptoms))
symptoms += S
S.OnAdd(src)
// Simply removes the symptom.
/datum/disease/advance/proc/RemoveSymptom(datum/symptom/S)
symptoms -= S
S.OnRemove(src)
// Neuter a symptom, so it will only affect stats
/datum/disease/advance/proc/NeuterSymptom(datum/symptom/S)
if(!S.neutered)
S.neutered = TRUE
S.name += " (neutered)"
S.OnRemove(src)
/*
Static Procs
*/
// Mix a list of advance diseases and return the mixed result.
/proc/Advance_Mix(var/list/D_list)
var/list/diseases = list()
for(var/datum/disease/advance/A in D_list)
diseases += A.Copy()
if(!diseases.len)
return null
if(diseases.len <= 1)
return pick(diseases) // Just return the only entry.
var/i = 0
// Mix our diseases until we are left with only one result.
while(i < 20 && diseases.len > 1)
i++
var/datum/disease/advance/D1 = pick(diseases)
diseases -= D1
var/datum/disease/advance/D2 = pick(diseases)
D2.Mix(D1)
// Should be only 1 entry left, but if not let's only return a single entry
var/datum/disease/advance/to_return = pick(diseases)
to_return.Refresh(1)
return to_return
/proc/SetViruses(datum/reagent/R, list/data)
if(data)
var/list/preserve = list()
if(istype(data) && data["viruses"])
for(var/datum/disease/A in data["viruses"])
preserve += A.Copy()
R.data = data.Copy()
if(preserve.len)
R.data["viruses"] = preserve
/proc/AdminCreateVirus(client/user)
if(!user)
return
var/i = VIRUS_SYMPTOM_LIMIT
var/datum/disease/advance/D = new()
D.symptoms = list()
var/list/symptoms = list()
symptoms += "Done"
symptoms += SSdisease.list_symptoms.Copy()
do
if(user)
var/symptom = input(user, "Choose a symptom to add ([i] remaining)", "Choose a Symptom") in symptoms
if(isnull(symptom))
return
else if(istext(symptom))
i = 0
else if(ispath(symptom))
var/datum/symptom/S = new symptom
if(!D.HasSymptom(S))
D.symptoms += S
i -= 1
while(i > 0)
if(D.symptoms.len > 0)
var/new_name = stripped_input(user, "Name your new disease.", "New Name")
if(!new_name)
return
D.AssignName(new_name)
D.Refresh()
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
if(!is_station_level(H.z))
continue
if(!H.HasDisease(D))
H.ForceContractDisease(D)
break
var/list/name_symptoms = list()
for(var/datum/symptom/S in D.symptoms)
name_symptoms += S.name
message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.admin_details()]")
log_virus("[key_name(user)] has triggered a custom virus outbreak of [D.admin_details()]!")
/datum/disease/advance/proc/totalStageSpeed()
return properties["stage_rate"]
/datum/disease/advance/proc/totalStealth()
return properties["stealth"]
/datum/disease/advance/proc/totalResistance()
return properties["resistance"]
/datum/disease/advance/proc/totalTransmittable()
return properties["transmittable"]
@@ -25,10 +25,8 @@ Bonus
base_message_chance = 15
symptom_delay_min = 10
symptom_delay_max = 30
threshold_desc = list(
"Stage Speed 8" = "Causes choking more frequently.",
"Stealth 4" = "The symptom remains hidden until active."
)
threshold_desc = "<b>Stage Speed 8:</b> Causes choking more frequently.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/choking/Start(datum/disease/advance/A)
if(!..())
@@ -98,10 +96,8 @@ Bonus
symptom_delay_min = 14
symptom_delay_max = 30
var/paralysis = FALSE
threshold_desc = list(
"Stage Speed 8" = "Additionally synthesizes pancuronium and sodium thiopental inside the host.",
"Transmission 8" = "Doubles the damage caused by the symptom."
)
threshold_desc = "<b>Stage Speed 8:</b> Additionally synthesizes pancuronium and sodium thiopental inside the host.<br>\
<b>Transmission 8:</b> Doubles the damage caused by the symptom."
/datum/symptom/asphyxiation/Start(datum/disease/advance/A)
@@ -139,7 +135,7 @@ Bonus
var/get_damage = rand(15,21) * power
M.adjustOxyLoss(get_damage)
if(paralysis)
M.reagents.add_reagent_list(list(/datum/reagent/toxin/pancuronium = 3, /datum/reagent/toxin/sodium_thiopental = 3))
M.reagents.add_reagent_list(list("pancuronium" = 3, "sodium_thiopental" = 3))
return 1
/datum/symptom/asphyxiation/proc/Asphyxiate_death(mob/living/M, datum/disease/advance/A)
@@ -29,11 +29,9 @@ Bonus
symptom_delay_min = 10
symptom_delay_max = 30
var/brain_damage = FALSE
threshold_desc = list(
"Resistance 6" = "Causes brain damage over time.",
"Transmission 6" = "Increases confusion duration and strength.",
"Stealth 4" = "The symptom remains hidden until active.",
)
threshold_desc = "<b>Resistance 6:</b> Causes brain damage over time.<br>\
<b>Transmission 6:</b> Increases confusion duration.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/confusion/Start(datum/disease/advance/A)
if(!..())
@@ -29,13 +29,12 @@ BONUS
symptom_delay_min = 2
symptom_delay_max = 15
var/infective = FALSE
threshold_desc = list(
"Resistance 11" = "The host will drop small items when coughing.",
"Resistance 15" = "Occasionally causes coughing fits that stun the host. The extra coughs do not spread the virus.",
"Stage Speed 6" = "Increases cough frequency.",
"Transmission 7" = "Coughing will now infect bystanders up to 2 tiles away.",
"Stealth 4" = "The symptom remains hidden until active.",
)
threshold_desc = "<b>Resistance 3:</b> Host will drop small items when coughing.<br>\
<b>Resistance 10:</b> Occasionally causes coughing fits that stun the host.<br>\
<b>Stage Speed 6:</b> Increases cough frequency.<br>\
<b>If Airborne:</b> Coughing will infect bystanders.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/cough/Start(datum/disease/advance/A)
if(!..())
return
@@ -28,10 +28,8 @@ Bonus
base_message_chance = 100
symptom_delay_min = 25
symptom_delay_max = 80
threshold_desc = list(
"Resistance 9" = "Causes permanent deafness, instead of intermittent.",
"Stealth 4" = "The symptom remains hidden until active.",
)
threshold_desc = "<b>Resistance 9:</b> Causes permanent deafness, instead of intermittent.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/deafness/Start(datum/disease/advance/A)
if(!..())
@@ -27,10 +27,8 @@ Bonus
base_message_chance = 50
symptom_delay_min = 15
symptom_delay_max = 40
threshold_desc = list(
"Transmission 6" = "Also causes druggy vision.",
"Stealth 4" = "The symptom remains hidden until active.",
)
threshold_desc = "<b>Transmission 6:</b> Also causes druggy vision.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/dizzy/Start(datum/disease/advance/A)
if(!..())
@@ -28,10 +28,9 @@ Bonus
symptom_delay_min = 10
symptom_delay_max = 30
var/unsafe = FALSE //over the heat threshold
threshold_desc = list(
"Resistance 5" = "Increases fever intensity, fever can overheat and harm the host.",
"Resistance 10" = "Further increases fever intensity.",
)
threshold_desc = "<b>Resistance 5:</b> Increases fever intensity, fever can overheat and harm the host.<br>\
<b>Resistance 10:</b> Further increases fever intensity."
/datum/symptom/fever/Start(datum/disease/advance/A)
if(!..())
return
@@ -29,12 +29,11 @@ Bonus
symptom_delay_min = 20
symptom_delay_max = 75
var/infective = FALSE
threshold_desc = list(
"Stage Speed 4" = "Increases the intensity of the flames.",
"Stage Speed 8" = "Further increases flame intensity.",
"Transmission 8" = "Host will spread the virus through skin flakes when bursting into flame.",
"Stealth 4" = "The symptom remains hidden until active.",
)
threshold_desc = "<b>Stage Speed 4:</b> Increases the intensity of the flames.<br>\
<b>Stage Speed 8:</b> Further increases flame intensity.<br>\
<b>Transmission 8:</b> Host will spread the virus through skin flakes when bursting into flame.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/fire/Start(datum/disease/advance/A)
if(!..())
return
@@ -156,7 +155,7 @@ Bonus
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks/2)
if(chems)
M.reagents.add_reagent(/datum/reagent/clf3, 2 * power)
M.reagents.add_reagent("clf3", 2 * power)
return 1
/datum/symptom/alkali/proc/Alkali_fire_stage_5(mob/living/M, datum/disease/advance/A)
@@ -164,5 +163,5 @@ Bonus
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks)
if(chems)
M.reagents.add_reagent_list(list(/datum/reagent/napalm = 4 * power, /datum/reagent/clf3 = 4 * power))
M.reagents.add_reagent_list(list("napalm" = 4 * power, "clf3" = 4 * power))
return 1
@@ -1,136 +1,130 @@
/*
//////////////////////////////////////
Necrotizing Fasciitis (AKA Flesh-Eating Disease)
Very very noticable.
Lowers resistance tremendously.
No changes to stage speed.
Decreases transmittablity temrendously.
Fatal Level.
Bonus
Deals brute damage over time.
//////////////////////////////////////
*/
/datum/symptom/flesh_eating
name = "Necrotizing Fasciitis"
desc = "The virus aggressively attacks body cells, necrotizing tissues and organs."
stealth = -3
resistance = -4
stage_speed = 0
transmittable = -4
level = 6
severity = 5
base_message_chance = 50
symptom_delay_min = 15
symptom_delay_max = 60
var/bleed = FALSE
var/pain = FALSE
threshold_desc = list(
"Resistance 9" = "Doubles the intensity of the immolation effect, but reduces the frequency of all of this symptom's effects.",
"Stage Speed 8" = "Increases explosion radius and explosion damage to the host when the host is wet.",
"Transmission 8" = "Additionally synthesizes chlorine trifluoride and napalm inside the host. More chemicals are synthesized if the resistance 9 threshold has been met."
)
/datum/symptom/flesh_eating/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["resistance"] >= 7) //extra bleeding
bleed = TRUE
if(A.properties["transmittable"] >= 8) //extra stamina damage
pain = TRUE
/datum/symptom/flesh_eating/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(prob(base_message_chance))
to_chat(M, "<span class='warning'>[pick("You feel a sudden pain across your body.", "Drops of blood appear suddenly on your skin.")]</span>")
if(4,5)
to_chat(M, "<span class='userdanger'>[pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")]</span>")
Flesheat(M, A)
/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(15,25) * power
M.adjustBruteLoss(get_damage)
if(pain)
M.adjustStaminaLoss(get_damage)
if(bleed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.bleed_rate += 5 * power
return 1
/*
//////////////////////////////////////
Autophagocytosis (AKA Programmed mass cell death)
Very noticable.
Lowers resistance.
Fast stage speed.
Decreases transmittablity.
Fatal Level.
Bonus
Deals brute damage over time.
//////////////////////////////////////
*/
/datum/symptom/flesh_death
name = "Autophagocytosis Necrosis"
desc = "The virus rapidly consumes infected cells, leading to heavy and widespread damage."
stealth = -2
resistance = -2
stage_speed = 1
transmittable = -2
level = 7
severity = 6
base_message_chance = 50
symptom_delay_min = 3
symptom_delay_max = 6
var/chems = FALSE
var/zombie = FALSE
threshold_desc = list(
"Stage Speed 7" = "Synthesizes Heparin and Lipolicide inside the host, causing increased bleeding and hunger.",
"Stealth 5" = "The symptom remains hidden until active.",
)
/datum/symptom/flesh_death/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stealth"] >= 5)
suppress_warning = TRUE
if(A.properties["stage_rate"] >= 7) //bleeding and hunger
chems = TRUE
/datum/symptom/flesh_death/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You feel your body break apart.", "Your skin rubs off like dust.")]</span>")
if(4,5)
if(prob(base_message_chance / 2)) //reduce spam
to_chat(M, "<span class='userdanger'>[pick("You feel your muscles weakening.", "Some of your skin detaches itself.", "You feel sandy.")]</span>")
Flesh_death(M, A)
/datum/symptom/flesh_death/proc/Flesh_death(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(6,10)
M.adjustBruteLoss(get_damage)
if(chems)
M.reagents.add_reagent_list(list(/datum/reagent/toxin/heparin = 2, /datum/reagent/toxin/lipolicide = 2))
if(zombie)
M.reagents.add_reagent(/datum/reagent/romerol, 1)
return 1
/*
//////////////////////////////////////
Necrotizing Fasciitis (AKA Flesh-Eating Disease)
Very very noticable.
Lowers resistance tremendously.
No changes to stage speed.
Decreases transmittablity temrendously.
Fatal Level.
Bonus
Deals brute damage over time.
//////////////////////////////////////
*/
/datum/symptom/flesh_eating
name = "Necrotizing Fasciitis"
desc = "The virus aggressively attacks body cells, necrotizing tissues and organs."
stealth = -3
resistance = -4
stage_speed = 0
transmittable = -4
level = 6
severity = 5
base_message_chance = 50
symptom_delay_min = 15
symptom_delay_max = 60
var/bleed = FALSE
var/pain = FALSE
threshold_desc = "<b>Resistance 7:</b> Host will bleed profusely during necrosis.<br>\
<b>Transmission 8:</b> Causes extreme pain to the host, weakening it."
/datum/symptom/flesh_eating/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["resistance"] >= 7) //extra bleeding
bleed = TRUE
if(A.properties["transmittable"] >= 8) //extra stamina damage
pain = TRUE
/datum/symptom/flesh_eating/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(prob(base_message_chance))
to_chat(M, "<span class='warning'>[pick("You feel a sudden pain across your body.", "Drops of blood appear suddenly on your skin.")]</span>")
if(4,5)
to_chat(M, "<span class='userdanger'>[pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")]</span>")
Flesheat(M, A)
/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(15,25) * power
M.adjustBruteLoss(get_damage)
if(pain)
M.adjustStaminaLoss(get_damage)
if(bleed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.bleed_rate += 5 * power
return 1
/*
//////////////////////////////////////
Autophagocytosis (AKA Programmed mass cell death)
Very noticable.
Lowers resistance.
Fast stage speed.
Decreases transmittablity.
Fatal Level.
Bonus
Deals brute damage over time.
//////////////////////////////////////
*/
/datum/symptom/flesh_death
name = "Autophagocytosis Necrosis"
desc = "The virus rapidly consumes infected cells, leading to heavy and widespread damage."
stealth = -2
resistance = -2
stage_speed = 1
transmittable = -2
level = 7
severity = 6
base_message_chance = 50
symptom_delay_min = 3
symptom_delay_max = 6
var/chems = FALSE
var/zombie = FALSE
threshold_desc = "<b>Stage Speed 7:</b> Synthesizes Heparin and Lipolicide inside the host, causing increased bleeding and hunger.<br>\
<b>Stealth 5:</b> The symptom remains hidden until active."
/datum/symptom/flesh_death/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stealth"] >= 5)
suppress_warning = TRUE
if(A.properties["stage_rate"] >= 7) //bleeding and hunger
chems = TRUE
/datum/symptom/flesh_death/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You feel your body break apart.", "Your skin rubs off like dust.")]</span>")
if(4,5)
if(prob(base_message_chance / 2)) //reduce spam
to_chat(M, "<span class='userdanger'>[pick("You feel your muscles weakening.", "Some of your skin detaches itself.", "You feel sandy.")]</span>")
Flesh_death(M, A)
/datum/symptom/flesh_death/proc/Flesh_death(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(6,10)
M.adjustBruteLoss(get_damage)
if(chems)
M.reagents.add_reagent_list(list("heparin" = 2, "lipolicide" = 2))
if(zombie)
M.reagents.add_reagent("romerol", 1)
return 1

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