Merge remote-tracking branch 'upstream/dev' into 150702-MoneyMoneyMoney

Conflicts:
	code/__defines/mobs.dm
	code/game/jobs/job/civilian.dm
	code/game/jobs/job_controller.dm
This commit is contained in:
PsiOmegaDelta
2015-08-13 08:06:11 +02:00
426 changed files with 10672 additions and 9746 deletions

View File

@@ -1,32 +1,43 @@
#pretending we're C because otherwise ruby will initialize, even with "language: dm". #pretending we're C because otherwise ruby will initialize, even with "language: dm".
language: c language: c
sudo: false
env: env:
BYOND_MAJOR="508" BYOND_MAJOR="508"
BYOND_MINOR="1287" BYOND_MINOR="1287"
MACRO_COUNT=1234
before_install: cache:
- sudo apt-get update -qq directories:
- sudo apt-get install libc6:i386 libgcc1:i386 libstdc++6:i386 -qq - $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}
- sudo apt-get install python -qq
- sudo apt-get install python-pip -qq addons:
- sudo pip install PyYaml -q apt:
- sudo pip install beautifulsoup4 -q packages:
- libc6-i386
- libgcc1:i386
- libstdc++6:i386
- python
- python-pip
install: install:
- curl "http://www.byond.com/download/build/${BYOND_MAJOR}/${BYOND_MAJOR}.${BYOND_MINOR}_byond_linux.zip" -o byond.zip - pip install --user PyYaml -q
- unzip byond.zip - pip install --user beautifulsoup4 -q
- cd byond
- sudo make install before_script:
- cd .. - chmod +x ./install-byond.sh
- ./install-byond.sh
script: script:
- shopt -s globstar - shopt -s globstar
- (! grep 'step_[xy]' maps/**/*.dmm) - (! grep 'step_[xy]' maps/**/*.dmm)
- (! find nano/templates/ -type f -exec md5sum {} + | sort | uniq -D -w 32 | grep nano) - (! find nano/templates/ -type f -exec md5sum {} + | sort | uniq -D -w 32 | grep nano)
- (num=`grep -E '\\\\(red|blue|green|black|b|i[^mc])' **/*.dm | wc -l`; [ $num -le 1355 ]) - (! grep -E "<\s*span\s+class\s*=\s*('[^'>]+|[^'>]+')\s*>" **/*.dm)
- (num=`grep -E '\\\\(red|blue|green|black|b|i[^mc])' **/*.dm | wc -l`; echo "$num escapes (expecting ${MACRO_COUNT} or less)"; [ $num -le ${MACRO_COUNT} ])
- md5sum -c - <<< "0af969f671fba6cf9696c78cd175a14a *baystation12.int" - md5sum -c - <<< "0af969f671fba6cf9696c78cd175a14a *baystation12.int"
- md5sum -c - <<< "88490b460c26947f5ec1ab1bb9fa9f17 *html/changelogs/example.yml" - md5sum -c - <<< "88490b460c26947f5ec1ab1bb9fa9f17 *html/changelogs/example.yml"
- python tools/TagMatcher/tag-matcher.py ../.. - python tools/TagMatcher/tag-matcher.py ../..
- python tools/GenerateChangelog/ss13_genchangelog.py html/changelog.html html/changelogs - python tools/GenerateChangelog/ss13_genchangelog.py html/changelog.html html/changelogs
- source $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}/byond/bin/byondsetup
- DreamMaker baystation12.dme - DreamMaker baystation12.dme

View File

@@ -16,6 +16,7 @@
#include "code\stylesheet.dm" #include "code\stylesheet.dm"
#include "code\world.dm" #include "code\world.dm"
#include "code\__defines\_compile_options.dm" #include "code\__defines\_compile_options.dm"
#include "code\__defines\_macros.dm"
#include "code\__defines\admin.dm" #include "code\__defines\admin.dm"
#include "code\__defines\atmos.dm" #include "code\__defines\atmos.dm"
#include "code\__defines\chemistry.dm" #include "code\__defines\chemistry.dm"
@@ -23,12 +24,14 @@
#include "code\__defines\dna.dm" #include "code\__defines\dna.dm"
#include "code\__defines\gamemode.dm" #include "code\__defines\gamemode.dm"
#include "code\__defines\items_clothing.dm" #include "code\__defines\items_clothing.dm"
#include "code\__defines\lighting.dm"
#include "code\__defines\machinery.dm" #include "code\__defines\machinery.dm"
#include "code\__defines\math_physics.dm" #include "code\__defines\math_physics.dm"
#include "code\__defines\misc.dm" #include "code\__defines\misc.dm"
#include "code\__defines\mobs.dm" #include "code\__defines\mobs.dm"
#include "code\__defines\research.dm" #include "code\__defines\research.dm"
#include "code\__defines\species_languages.dm" #include "code\__defines\species_languages.dm"
#include "code\_helpers\atmospherics.dm"
#include "code\_helpers\datum_pool.dm" #include "code\_helpers\datum_pool.dm"
#include "code\_helpers\files.dm" #include "code\_helpers\files.dm"
#include "code\_helpers\game.dm" #include "code\_helpers\game.dm"
@@ -143,6 +146,7 @@
#include "code\datums\ai_laws.dm" #include "code\datums\ai_laws.dm"
#include "code\datums\browser.dm" #include "code\datums\browser.dm"
#include "code\datums\computerfiles.dm" #include "code\datums\computerfiles.dm"
#include "code\datums\crew.dm"
#include "code\datums\datacore.dm" #include "code\datums\datacore.dm"
#include "code\datums\datumvars.dm" #include "code\datums\datumvars.dm"
#include "code\datums\disease.dm" #include "code\datums\disease.dm"
@@ -771,6 +775,7 @@
#include "code\game\objects\structures\watercloset.dm" #include "code\game\objects\structures\watercloset.dm"
#include "code\game\objects\structures\windoor_assembly.dm" #include "code\game\objects\structures\windoor_assembly.dm"
#include "code\game\objects\structures\window.dm" #include "code\game\objects\structures\window.dm"
#include "code\game\objects\structures\window_spawner.dm"
#include "code\game\objects\structures\crates_lockers\closets.dm" #include "code\game\objects\structures\crates_lockers\closets.dm"
#include "code\game\objects\structures\crates_lockers\crates.dm" #include "code\game\objects\structures\crates_lockers\crates.dm"
#include "code\game\objects\structures\crates_lockers\largecrate.dm" #include "code\game\objects\structures\crates_lockers\largecrate.dm"
@@ -1276,6 +1281,7 @@
#include "code\modules\mob\living\silicon\decoy\death.dm" #include "code\modules\mob\living\silicon\decoy\death.dm"
#include "code\modules\mob\living\silicon\decoy\decoy.dm" #include "code\modules\mob\living\silicon\decoy\decoy.dm"
#include "code\modules\mob\living\silicon\decoy\life.dm" #include "code\modules\mob\living\silicon\decoy\life.dm"
#include "code\modules\mob\living\silicon\pai\admin.dm"
#include "code\modules\mob\living\silicon\pai\death.dm" #include "code\modules\mob\living\silicon\pai\death.dm"
#include "code\modules\mob\living\silicon\pai\examine.dm" #include "code\modules\mob\living\silicon\pai\examine.dm"
#include "code\modules\mob\living\silicon\pai\life.dm" #include "code\modules\mob\living\silicon\pai\life.dm"
@@ -1287,6 +1293,7 @@
#include "code\modules\mob\living\silicon\pai\software_modules.dm" #include "code\modules\mob\living\silicon\pai\software_modules.dm"
#include "code\modules\mob\living\silicon\robot\analyzer.dm" #include "code\modules\mob\living\silicon\robot\analyzer.dm"
#include "code\modules\mob\living\silicon\robot\component.dm" #include "code\modules\mob\living\silicon\robot\component.dm"
#include "code\modules\mob\living\silicon\robot\custom_sprites.dm"
#include "code\modules\mob\living\silicon\robot\death.dm" #include "code\modules\mob\living\silicon\robot\death.dm"
#include "code\modules\mob\living\silicon\robot\emote.dm" #include "code\modules\mob\living\silicon\robot\emote.dm"
#include "code\modules\mob\living\silicon\robot\examine.dm" #include "code\modules\mob\living\silicon\robot\examine.dm"
@@ -1306,6 +1313,7 @@
#include "code\modules\mob\living\silicon\robot\drone\drone_damage.dm" #include "code\modules\mob\living\silicon\robot\drone\drone_damage.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_items.dm" #include "code\modules\mob\living\silicon\robot\drone\drone_items.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_manufacturer.dm" #include "code\modules\mob\living\silicon\robot\drone\drone_manufacturer.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_say.dm"
#include "code\modules\mob\living\simple_animal\bees.dm" #include "code\modules\mob\living\simple_animal\bees.dm"
#include "code\modules\mob\living\simple_animal\corpse.dm" #include "code\modules\mob\living\simple_animal\corpse.dm"
#include "code\modules\mob\living\simple_animal\parrot.dm" #include "code\modules\mob\living\simple_animal\parrot.dm"
@@ -1503,6 +1511,7 @@
#include "code\modules\random_map\noise\tundra.dm" #include "code\modules\random_map\noise\tundra.dm"
#include "code\modules\reagents\Chemistry-Colours.dm" #include "code\modules\reagents\Chemistry-Colours.dm"
#include "code\modules\reagents\Chemistry-Holder.dm" #include "code\modules\reagents\Chemistry-Holder.dm"
#include "code\modules\reagents\Chemistry-Logging.dm"
#include "code\modules\reagents\Chemistry-Machinery.dm" #include "code\modules\reagents\Chemistry-Machinery.dm"
#include "code\modules\reagents\Chemistry-Metabolism.dm" #include "code\modules\reagents\Chemistry-Metabolism.dm"
#include "code\modules\reagents\Chemistry-Readme.dm" #include "code\modules\reagents\Chemistry-Readme.dm"
@@ -1606,7 +1615,6 @@
#include "code\modules\research\xenoarchaeology\machinery\geosample_scanner.dm" #include "code\modules\research\xenoarchaeology\machinery\geosample_scanner.dm"
#include "code\modules\research\xenoarchaeology\tools\ano_device_battery.dm" #include "code\modules\research\xenoarchaeology\tools\ano_device_battery.dm"
#include "code\modules\research\xenoarchaeology\tools\anomaly_suit.dm" #include "code\modules\research\xenoarchaeology\tools\anomaly_suit.dm"
#include "code\modules\research\xenoarchaeology\tools\bunsen_burner.dm"
#include "code\modules\research\xenoarchaeology\tools\gearbelt.dm" #include "code\modules\research\xenoarchaeology\tools\gearbelt.dm"
#include "code\modules\research\xenoarchaeology\tools\suspension_generator.dm" #include "code\modules\research\xenoarchaeology\tools\suspension_generator.dm"
#include "code\modules\research\xenoarchaeology\tools\tools.dm" #include "code\modules\research\xenoarchaeology\tools\tools.dm"
@@ -1672,16 +1680,15 @@
#include "code\modules\spells\aoe_turf\conjure\forcewall.dm" #include "code\modules\spells\aoe_turf\conjure\forcewall.dm"
#include "code\modules\spells\general\area_teleport.dm" #include "code\modules\spells\general\area_teleport.dm"
#include "code\modules\spells\general\rune_write.dm" #include "code\modules\spells\general\rune_write.dm"
#include "code\modules\spells\targeted\disintegrate.dm"
#include "code\modules\spells\targeted\ethereal_jaunt.dm" #include "code\modules\spells\targeted\ethereal_jaunt.dm"
#include "code\modules\spells\targeted\flesh_to_stone.dm"
#include "code\modules\spells\targeted\genetic.dm" #include "code\modules\spells\targeted\genetic.dm"
#include "code\modules\spells\targeted\harvest.dm" #include "code\modules\spells\targeted\harvest.dm"
#include "code\modules\spells\targeted\horsemask.dm"
#include "code\modules\spells\targeted\mind_transfer.dm" #include "code\modules\spells\targeted\mind_transfer.dm"
#include "code\modules\spells\targeted\shift.dm" #include "code\modules\spells\targeted\shift.dm"
#include "code\modules\spells\targeted\subjugate.dm" #include "code\modules\spells\targeted\subjugate.dm"
#include "code\modules\spells\targeted\targeted.dm" #include "code\modules\spells\targeted\targeted.dm"
#include "code\modules\spells\targeted\equip\equip.dm"
#include "code\modules\spells\targeted\equip\horsemask.dm"
#include "code\modules\spells\targeted\projectile\dumbfire.dm" #include "code\modules\spells\targeted\projectile\dumbfire.dm"
#include "code\modules\spells\targeted\projectile\fireball.dm" #include "code\modules\spells\targeted\projectile\fireball.dm"
#include "code\modules\spells\targeted\projectile\magic_missile.dm" #include "code\modules\spells\targeted\projectile\magic_missile.dm"

View File

@@ -199,7 +199,7 @@
total_unfilterable_moles += source.gas[g] total_unfilterable_moles += source.gas[g]
var/ratio = source.gas[g]/source.total_moles //converts the specific power per mole of pure gas to specific power per mole of input gas mix var/ratio = source.gas[g]/source.total_moles //converts the specific power per mole of pure gas to specific power per mole of input gas mix
total_specific_power = specific_power_gas[g]*ratio total_specific_power += specific_power_gas[g]*ratio
//Figure out how much of each gas to filter //Figure out how much of each gas to filter
if (isnull(total_transfer_moles)) if (isnull(total_transfer_moles))
@@ -272,7 +272,7 @@
total_unfilterable_moles += source.gas[g] total_unfilterable_moles += source.gas[g]
var/ratio = source.gas[g]/source.total_moles //converts the specific power per mole of pure gas to specific power per mole of input gas mix var/ratio = source.gas[g]/source.total_moles //converts the specific power per mole of pure gas to specific power per mole of input gas mix
total_specific_power = specific_power_gas[g]*ratio total_specific_power += specific_power_gas[g]*ratio
//Figure out how much of each gas to filter //Figure out how much of each gas to filter
if (isnull(total_transfer_moles)) if (isnull(total_transfer_moles))

View File

@@ -120,14 +120,14 @@
if(pressure_delta > 0.5) if(pressure_delta > 0.5)
if(pump_direction) //internal -> external if(pump_direction) //internal -> external
if (node1 && (environment.temperature || air1.temperature)) if (node1 && (environment.temperature || air1.temperature))
var/transfer_moles = calculate_transfer_moles(air1, environment) var/transfer_moles = calculate_transfer_moles(air1, environment, pressure_delta)
power_draw = pump_gas(src, air1, environment, transfer_moles, power_rating) power_draw = pump_gas(src, air1, environment, transfer_moles, power_rating)
if(power_draw >= 0 && network1) if(power_draw >= 0 && network1)
network1.update = 1 network1.update = 1
else //external -> internal else //external -> internal
if (node2 && (environment.temperature || air2.temperature)) if (node2 && (environment.temperature || air2.temperature))
var/transfer_moles = calculate_transfer_moles(environment, air2, (network2)? network2.volume : 0) var/transfer_moles = calculate_transfer_moles(environment, air2, pressure_delta, (network2)? network2.volume : 0)
//limit flow rate from turfs //limit flow rate from turfs
transfer_moles = min(transfer_moles, environment.total_moles*air2.volume/environment.volume) //group_multiplier gets divided out here transfer_moles = min(transfer_moles, environment.total_moles*air2.volume/environment.volume) //group_multiplier gets divided out here

View File

@@ -178,10 +178,10 @@
if((environment.temperature || air_contents.temperature) && pressure_delta > 0.5) if((environment.temperature || air_contents.temperature) && pressure_delta > 0.5)
if(pump_direction) //internal -> external if(pump_direction) //internal -> external
var/transfer_moles = calculate_transfer_moles(air_contents, environment) var/transfer_moles = calculate_transfer_moles(air_contents, environment, pressure_delta)
power_draw = pump_gas(src, air_contents, environment, transfer_moles, power_rating) power_draw = pump_gas(src, air_contents, environment, transfer_moles, power_rating)
else //external -> internal else //external -> internal
var/transfer_moles = calculate_transfer_moles(environment, air_contents, (network)? network.volume : 0) var/transfer_moles = calculate_transfer_moles(environment, air_contents, pressure_delta, (network)? network.volume : 0)
//limit flow rate from turfs //limit flow rate from turfs
transfer_moles = min(transfer_moles, environment.total_moles*air_contents.volume/environment.volume) //group_multiplier gets divided out here transfer_moles = min(transfer_moles, environment.total_moles*air_contents.volume/environment.volume) //group_multiplier gets divided out here

View File

@@ -91,7 +91,7 @@
add_fingerprint(user) add_fingerprint(user)
return 1 return 1
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
user << "<span class='notice>You begin to unfasten \the [src]...</span>" user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
if (do_after(user, 40)) if (do_after(user, 40))
user.visible_message( \ user.visible_message( \
"<span class='notice'>\The [user] unfastens \the [src].</span>", \ "<span class='notice'>\The [user] unfastens \the [src].</span>", \
@@ -1120,20 +1120,8 @@
return return
if(istype(W, /obj/item/device/analyzer) && in_range(user, src)) if(istype(W, /obj/item/device/analyzer) && in_range(user, src))
for (var/mob/O in viewers(user, null)) var/obj/item/device/analyzer/A = W
O << "<span class='notice'>\The [user] has used \the [W] on \the [src] \icon[src]</span>" A.analyze_gases(src, user)
var/pressure = parent.air.return_pressure()
var/total_moles = parent.air.total_moles
user << "<span class='notice'>Results of analysis of \the [src] \icon[src]</span>"
if (total_moles>0)
user << "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>"
for(var/g in parent.air.gas)
user << "<span class='notice'>[gas_data.name[g]]: [round((parent.air.gas[g] / total_moles) * 100)]%</span>"
user << "<span class='notice'>Temperature: [round(parent.air.temperature-T0C)]&deg;C</span>"
else
user << "<span class='notice'>Tank is empty!</span>"
/obj/machinery/atmospherics/pipe/tank/air /obj/machinery/atmospherics/pipe/tank/air
name = "Pressure Tank (Air)" name = "Pressure Tank (Air)"

View File

@@ -241,7 +241,7 @@ mob/living/carbon/human/airflow_hit(atom/A)
zone/proc/movables() zone/proc/movables()
. = list() . = list()
for(var/turf/T in contents) for(var/turf/T in contents)
for(var/atom/A in T) for(var/atom/movable/A in T)
if(istype(A, /obj/effect) || istype(A, /mob/aiEye)) if(!A.simulated || A.anchored || istype(A, /obj/effect) || istype(A, /mob/aiEye))
continue continue
. += A . += A

View File

@@ -274,10 +274,10 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
//vapour fuels are extremely volatile! The reaction progress is a percentage of the total fuel (similar to old zburn).) //vapour fuels are extremely volatile! The reaction progress is a percentage of the total fuel (similar to old zburn).)
var/min_burn = 0.30*volume*group_multiplier/CELL_VOLUME //in moles - so that fires with very small gas concentrations burn out fast var/min_burn = 0.30*volume*group_multiplier/CELL_VOLUME //in moles - so that fires with very small gas concentrations burn out fast
var/gas_reaction_progress = max(min_burn, firelevel_ratio*gas_fuel)*FIRE_GAS_BURNRATE_MULT var/gas_reaction_progress = min(max(min_burn, firelevel_ratio*gas_fuel)*FIRE_GAS_BURNRATE_MULT, gas_fuel)
//liquid fuels are not as volatile, and the reaction progress depends on the size of the area that is burning. Limit the burn rate to a certain amount per area. //liquid fuels are not as volatile, and the reaction progress depends on the size of the area that is burning. Limit the burn rate to a certain amount per area.
var/liquid_reaction_progress = (firelevel_ratio*0.2 + 0.05)*fuel_area*FIRE_LIQUID_BURNRATE_MULT var/liquid_reaction_progress = min((firelevel_ratio*0.2 + 0.05)*fuel_area*FIRE_LIQUID_BURNRATE_MULT, liquid_fuel)
var/total_reaction_progress = gas_reaction_progress + liquid_reaction_progress var/total_reaction_progress = gas_reaction_progress + liquid_reaction_progress
var/used_fuel = min(total_reaction_progress, reaction_limit) var/used_fuel = min(total_reaction_progress, reaction_limit)
@@ -295,7 +295,7 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
//if the reaction is progressing too slow then it isn't self-sustaining anymore and burns out //if the reaction is progressing too slow then it isn't self-sustaining anymore and burns out
if(zone) //be less restrictive with canister and tank reactions if(zone) //be less restrictive with canister and tank reactions
if((!liquid_fuel || used_fuel <= FIRE_LIQUD_MIN_BURNRATE) && (!gas_fuel || used_fuel <= FIRE_GAS_MIN_BURNRATE*group_multiplier)) if((!liquid_fuel || used_fuel <= FIRE_LIQUD_MIN_BURNRATE) && (!gas_fuel || used_fuel <= FIRE_GAS_MIN_BURNRATE*zone.contents.len))
return 0 return 0

View File

@@ -0,0 +1,2 @@
#define Clamp(x, y, z) (x <= y ? y : (x >= z ? z : x))
#define CLAMP01(x) (Clamp(x, 0, 1))

View File

@@ -0,0 +1,6 @@
#define FOR_DVIEW(type, range, center, invis_flags) \
dview_mob.loc = center; \
dview_mob.see_invisible = invis_flags; \
for(type in view(range, dview_mob))
#define END_FOR_DVIEW dview_mob.loc = null

View File

@@ -12,7 +12,7 @@
#define INVISIBILITY_EYE 61 #define INVISIBILITY_EYE 61
#define SEE_INVISIBLE_LIVING 25 #define SEE_INVISIBLE_LIVING 25
#define SEE_INVISIBLE_OBSERVER_NOLIGHTING 15 #define SEE_INVISIBLE_NOLIGHTING 15
#define SEE_INVISIBLE_LEVEL_ONE 35 #define SEE_INVISIBLE_LEVEL_ONE 35
#define SEE_INVISIBLE_LEVEL_TWO 45 #define SEE_INVISIBLE_LEVEL_TWO 45
#define SEE_INVISIBLE_CULT 60 #define SEE_INVISIBLE_CULT 60
@@ -117,8 +117,8 @@
#define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6 #define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
#define DOOR_CLOSED_LAYER 3.1 //Above most items if closed #define DOOR_CLOSED_LAYER 3.1 //Above most items if closed
#define LIGHTING_LAYER 11 #define LIGHTING_LAYER 11
#define OBFUSCATION_LAYER 14 //Where images covering the view for eyes are put #define OBFUSCATION_LAYER 21 //Where images covering the view for eyes are put
#define SCREEN_LAYER 17 //Mob HUD/effects layer #define SCREEN_LAYER 22 //Mob HUD/effects layer
// Convoluted setup so defines can be supplied by Bay12 main server compile script. // Convoluted setup so defines can be supplied by Bay12 main server compile script.
// Should still work fine for people jamming the icons into their repo. // Should still work fine for people jamming the icons into their repo.
@@ -154,3 +154,7 @@
#define BOMBCAP_HEAVY_RADIUS (max_explosion_range/2) #define BOMBCAP_HEAVY_RADIUS (max_explosion_range/2)
#define BOMBCAP_LIGHT_RADIUS max_explosion_range #define BOMBCAP_LIGHT_RADIUS max_explosion_range
#define BOMBCAP_FLASH_RADIUS (max_explosion_range*1.5) #define BOMBCAP_FLASH_RADIUS (max_explosion_range*1.5)
// Special return values from bullet_act(). Positive return values are already used to indicate the blocked level of the projectile.
#define PROJECTILE_CONTINUE -1 //if the projectile should continue flying after calling bullet_act()
#define PROJECTILE_FORCE_MISS -2 //if the projectile should treat the attack as a miss (suppresses attack and admin logs) - only applies to mobs.

View File

@@ -85,6 +85,17 @@
#define MIN_SUPPLIED_LAW_NUMBER 15 #define MIN_SUPPLIED_LAW_NUMBER 15
#define MAX_SUPPLIED_LAW_NUMBER 50 #define MAX_SUPPLIED_LAW_NUMBER 50
//default item on-mob icons
#define INV_HEAD_DEF_ICON 'icons/mob/head.dmi'
#define INV_BACK_DEF_ICON 'icons/mob/back.dmi'
#define INV_L_HAND_DEF_ICON 'icons/mob/items/lefthand.dmi'
#define INV_R_HAND_DEF_ICON 'icons/mob/items/righthand.dmi'
#define INV_W_UNIFORM_DEF_ICON 'icons/mob/uniform.dmi'
#define INV_ACCESSORIES_DEF_ICON 'icons/mob/ties.dmi'
#define INV_SUIT_DEF_ICON 'icons/mob/ties.dmi'
#define INV_SUIT_DEF_ICON 'icons/mob/suit.dmi'
#define MAX_SUPPLIED_LAW_NUMBER 50
// NT's alignment towards the character // NT's alignment towards the character
#define COMPANY_LOYAL "Loyal" #define COMPANY_LOYAL "Loyal"
#define COMPANY_SUPPORTATIVE "Supportive" #define COMPANY_SUPPORTATIVE "Supportive"

View File

@@ -45,3 +45,4 @@
#define INNATE 64 // All mobs can be assumed to speak and understand this language. (audible emotes) #define INNATE 64 // All mobs can be assumed to speak and understand this language. (audible emotes)
#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message #define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message
#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems #define NO_STUTTER 256 // No stuttering, slurring, or other speech problems
#define COMMON_VERBS 512 // Robots will apply regular verbs to this

View File

@@ -0,0 +1,47 @@
/obj/proc/analyze_gases(var/obj/A, var/mob/user)
if(src != A)
user.visible_message("<span class='notice'>\The [user] has used \an [src] on \the [A]</span>")
A.add_fingerprint(user)
var/list/result = A.atmosanalyze(user)
if(result && result.len)
user << "<span class='notice'>Results of the analysis[src == A ? "" : " of \the [A]"]</span>"
for(var/line in result)
user << "<span class='notice'>[line]</span>"
return 1
user << "<span class='warning'>Your [src] flashes a red light as it fails to analyze \the [A].</span>"
return 0
/proc/atmosanalyzer_scan(var/obj/target, var/datum/gas_mixture/mixture, var/mob/user)
var/pressure = mixture.return_pressure()
var/total_moles = mixture.total_moles
var/list/results = list()
if (total_moles>0)
results += "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>"
for(var/mix in mixture.gas)
results += "<span class='notice'>[gas_data.name[mix]]: [round((mixture.gas[mix] / total_moles) * 100)]%</span>"
results += "<span class='notice'>Temperature: [round(mixture.temperature-T0C)]&deg;C</span>"
else
results += "<span class='notice'>\The [target] is empty!</span>"
return results
/obj/proc/atmosanalyze(var/mob/user)
return
/obj/item/weapon/tank/atmosanalyze(var/mob/user)
return atmosanalyzer_scan(src, src.air_contents, user)
/obj/machinery/portable_atmospherics/atmosanalyze(var/mob/user)
return atmosanalyzer_scan(src, src.air_contents, user)
/obj/machinery/atmospherics/pipe/atmosanalyze(var/mob/user)
return atmosanalyzer_scan(src, src.parent.air, user)
/obj/machinery/power/rad_collector/atmosanalyze(var/mob/user)
if(P) return atmosanalyzer_scan(src, src.P.air_contents, user)
/obj/item/weapon/flamethrower/atmosanalyze(var/mob/user)
if(ptank) return atmosanalyzer_scan(src, ptank.air_contents, user)

View File

@@ -210,14 +210,23 @@ proc/listclearnulls(list/list)
return (result + R.Copy(Ri, 0)) return (result + R.Copy(Ri, 0))
//Mergesort: divides up the list into halves to begin the sort //Mergesort: divides up the list into halves to begin the sort
/proc/sortAtom(var/list/atom/L, var/order = 1) /proc/sortAtom(var/list/atom/L, var/order = 1, first = 1)
if(isnull(L) || L.len < 2) if(isnull(L) || L.len < 2)
if(!L)
testing("sortAtom() called with null as first parameter!")
return L return L
if(first)
var/msg = "sortAtom() called with list([L.len]): "
for(var/x in L)
msg += "'[x]'; "
testing(msg)
var/middle = L.len / 2 + 1 var/middle = L.len / 2 + 1
return mergeAtoms(sortAtom(L.Copy(0,middle)), sortAtom(L.Copy(middle)), order) return mergeAtoms(sortAtom(L.Copy(0,middle), order, 0), sortAtom(L.Copy(middle), order, 0), order)
//Mergsort: does the actual sorting and returns the results back to sortAtom //Mergsort: does the actual sorting and returns the results back to sortAtom
/proc/mergeAtoms(var/list/atom/L, var/list/atom/R, var/order = 1) /proc/mergeAtoms(var/list/atom/L, var/list/atom/R, var/order = 1)
if(!L || !R)
testing("mergeAtoms([L] ([L ? L.len : "*null*"]), [R] ([R ? R.len : "*null*"]))")
var/Li=1 var/Li=1
var/Ri=1 var/Ri=1
var/list/result = new() var/list/result = new()
@@ -230,8 +239,14 @@ proc/listclearnulls(list/list)
result += R[Ri++] result += R[Ri++]
if(Li <= L.len) if(Li <= L.len)
return (result + L.Copy(Li, 0)) . = (result + L.Copy(Li, 0))
return (result + R.Copy(Ri, 0)) if(!.)
testing("mergeAtoms returning [.]")
return
. = (result + R.Copy(Ri, 0))
if(!.)
testing("mergeAtoms returning [.]")
return

View File

@@ -1,15 +1,6 @@
// Macro functions. // Macro functions.
#define RAND_F(LOW, HIGH) (rand()*(HIGH-LOW) + LOW) #define RAND_F(LOW, HIGH) (rand()*(HIGH-LOW) + LOW)
// List of square roots for the numbers 1-100.
var/list/sqrtTable = list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10)
/proc/Clamp(val, min, max)
return max(min, min(val, max))
// min is inclusive, max is exclusive // min is inclusive, max is exclusive
/proc/Wrap(val, min, max) /proc/Wrap(val, min, max)
var/d = max - min var/d = max - min

View File

@@ -226,89 +226,3 @@ var/syndicate_code_response//Code response for traitors.
code_phrase += ", " code_phrase += ", "
return code_phrase return code_phrase
/*
//This proc tests the gen above.
/client/verb/test_code_phrase()
set name = "Generate Code Phrase"
set category = "Debug"
world << "<span class='warning'>Code Phrase is:</span> [generate_code_phrase()]"
return
This was an earlier attempt at code phrase system, aside from an even earlier attempt (and failure).
This system more or less works as intended--aside from being unfinished--but it's still very predictable.
Particularly, the phrase opening statements are pretty easy to recognize and identify when metagaming.
I think the above-used method solves this issue by using words in a sequence, providing for much greater flexibility.
/N
switch(choice)
if(1)
syndicate_code_phrase += pick("I'm looking for","Have you seen","Maybe you've seen","I'm trying to find","I'm tracking")
syndicate_code_phrase += " "
syndicate_code_phrase += pick(pick(first_names_male,first_names_female))
syndicate_code_phrase += " "
syndicate_code_phrase += pick(last_names)
syndicate_code_phrase += "."
if(2)
syndicate_code_phrase += pick("How do I get to","How do I find","Where is","Where do I find")
syndicate_code_phrase += " "
syndicate_code_phrase += pick("Escape","Engineering","Atmos","the bridge","the brig","Clown Planet","CentCom","the library","the chapel","a bathroom","Med Bay","Tool Storage","the escape shuttle","Robotics","a locker room","the living quarters","the gym","the autolathe","QM","the bar","the theater","the derelict")
syndicate_code_phrase += "?"
if(3)
if(prob(70))
syndicate_code_phrase += pick("Get me","I want","I'd like","Make me")
syndicate_code_phrase += " a "
else
syndicate_code_phrase += pick("One")
syndicate_code_phrase += " "
syndicate_code_phrase += pick("vodka and tonic","gin fizz","bahama mama","manhattan","black Russian","whiskey soda","long island tea","margarita","Irish coffee"," manly dwarf","Irish cream","doctor's delight","Beepksy Smash","tequilla sunrise","brave bull","gargle blaster","bloody mary","whiskey cola","white Russian","vodka martini","martini","Cuba libre","kahlua","vodka","wine","moonshine")
syndicate_code_phrase += "."
if(4)
syndicate_code_phrase += pick("I wish I was","My dad was","His mom was","Where do I find","The hero this station needs is","I'd fuck","I wouldn't trust","Someone caught","HoS caught","Someone found","I'd wrestle","I wanna kill")
syndicate_code_phrase += " [pick("a","the")] "
syndicate_code_phrase += pick("wizard","ninja","xeno","lizard","slime","monkey","syndicate","cyborg","clown","space carp","singularity","singulo","mime")
syndicate_code_phrase += "."
if(5)
syndicate_code_phrase += pick("Do we have","Is there","Where is","Where's","Who's")
syndicate_code_phrase += " "
syndicate_code_phrase += "[pick(joblist)]"
syndicate_code_phrase += "?"
switch(choice)
if(1)
if(prob(80))
syndicate_code_response += pick("Try looking for them near","I they ran off to","Yes. I saw them near","Nope. I'm heading to","Try searching")
syndicate_code_response += " "
syndicate_code_response += pick("Escape","Engineering","Atmos","the bridge","the brig","Clown Planet","CentCom","the library","the chapel","a bathroom","Med Bay","Tool Storage","the escape shuttle","Robotics","a locker room","the living quarters","the gym","the autolathe","QM","the bar","the theater","the derelict")
syndicate_code_response += "."
else if(prob(60))
syndicate_code_response += pick("No. I'm busy, sorry.","I don't have the time.","Not sure, maybe?","There is no time.")
else
syndicate_code_response += pick("*shrug*","*smile*","*blink*","*sigh*","*laugh*","*nod*","*giggle*")
if(2)
if(prob(80))
syndicate_code_response += pick("Go to","Navigate to","Try","Sure, run to","Try searching","It's near","It's around")
syndicate_code_response += " the "
syndicate_code_response += pick("[pick("south","north","east","west")] maitenance door","nearby maitenance","teleporter","[pick("cold","dead")] space","morgue","vacuum","[pick("south","north","east","west")] hall ","[pick("south","north","east","west")] hallway","[pick("white","black","red","green","blue","pink","purple")] [pick("rabbit","frog","lion","tiger","panther","snake","facehugger")]")
syndicate_code_response += "."
else if(prob(60))
syndicate_code_response += pick("Try asking","Ask","Talk to","Go see","Follow","Hunt down")
syndicate_code_response += " "
if(prob(50))
syndicate_code_response += pick(pick(first_names_male,first_names_female))
syndicate_code_response += " "
syndicate_code_response += pick(last_names)
else
syndicate_code_response += " the "
syndicate_code_response += "[pic(joblist)]"
syndicate_code_response += "."
else
syndicate_code_response += pick("*shrug*","*smile*","*blink*","*sigh*","*laugh*","*nod*","*giggle*")
if(3)
if(4)
if(5)
return
*/

View File

@@ -6,9 +6,9 @@
var/roundstart_hour = 0 var/roundstart_hour = 0
//Returns the world time in english //Returns the world time in english
proc/worldtime2text(time = world.time) proc/worldtime2text(time = world.time, timeshift = 1)
if(!roundstart_hour) roundstart_hour = pick(2,7,12,17) if(!roundstart_hour) roundstart_hour = pick(2,7,12,17)
return "[(round(time / 36000)+roundstart_hour) % 24]:[(time / 600 % 60) < 10 ? add_zero(time / 600 % 60, 1) : time / 600 % 60]" return timeshift ? time2text(time+(36000*roundstart_hour), "hh:mm") : time2text(time, "hh:mm")
proc/worlddate2text() proc/worlddate2text()
return num2text((text2num(time2text(world.timeofday, "YYYY"))+544)) + "-" + time2text(world.timeofday, "MM-DD") return num2text((text2num(time2text(world.timeofday, "YYYY"))+544)) + "-" + time2text(world.timeofday, "MM-DD")

View File

@@ -36,35 +36,19 @@
return num return num
// Returns the hex value of a number given a value assumed to be a base-ten value // Returns the hex value of a number given a value assumed to be a base-ten value
/proc/num2hex(num, digits) /proc/num2hex(num, padlength)
if (digits == null) var/global/list/hexdigits = list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
digits = 2
if (!isnum(num)) . = ""
return while(num > 0)
var/hexdigit = hexdigits[(num & 0xF) + 1]
. = "[hexdigit][.]"
num >>= 4 //go to the next half-byte
// hex is our return value, to which each hex-digit of num is appended to. //pad with zeroes
var/hex = "" var/left = padlength - length(.)
var/power = -4
var/n = 1
// Figure out power. (power of 2)
while (n < num)
power += 4
n *= 16
// Note that we have to start appending to hex with the most-significant digits.
while (power >= 0)
var/m = (num >> power) & 15
hex += ascii2text(m + (m < 10 ? 48 : 87)) // Provided by the IconProcs library.
power -= 4
// Append zeroes to make sure that hex is atleast digits long.
var/left = length(hex) - digits
while (left-- > 0) while (left-- > 0)
hex = text("0[]", hex) . = "0[.]"
return hex
// Concatenates a list of strings into a single string. A seperator may optionally be provided. // Concatenates a list of strings into a single string. A seperator may optionally be provided.
/proc/list2text(list/ls, sep) /proc/list2text(list/ls, sep)

View File

@@ -550,23 +550,6 @@ proc/GaussRand(var/sigma)
proc/GaussRandRound(var/sigma,var/roundto) proc/GaussRandRound(var/sigma,var/roundto)
return round(GaussRand(sigma),roundto) return round(GaussRand(sigma),roundto)
proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,flick_anim as text,sleeptime = 0,direction as num)
//This proc throws up either an icon or an animation for a specified amount of time.
//The variables should be apparent enough.
var/atom/movable/overlay/animation = new(location)
if(direction)
animation.set_dir(direction)
animation.icon = a_icon
animation.layer = target:layer+1
if(a_icon_state)
animation.icon_state = a_icon_state
else
animation.icon_state = "blank"
animation.master = target
flick(flick_anim, animation)
sleep(max(sleeptime, 15))
qdel(animation)
//Will return the contents of an atom recursivly to a depth of 'searchDepth' //Will return the contents of an atom recursivly to a depth of 'searchDepth'
/atom/proc/GetAllContents(searchDepth = 5) /atom/proc/GetAllContents(searchDepth = 5)
var/list/toReturn = list() var/list/toReturn = list()
@@ -888,6 +871,8 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
// Movement based on lower left corner. Tiles that do not fit // Movement based on lower left corner. Tiles that do not fit
// into the new area will not be moved. // into the new area will not be moved.
// Does *not* affect gases etc; copied turfs will be changed via ChangeTurf, and the dir, icon, and icon_state copied. All other vars will remain default.
if(!A || !src) return 0 if(!A || !src) return 0
var/list/turfs_src = get_area_turfs(src.type) var/list/turfs_src = get_area_turfs(src.type)
@@ -941,7 +926,8 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
if(istype(B, get_base_turf(B.z))) if(istype(B, get_base_turf(B.z)))
continue moving continue moving
var/turf/X = new T.type(B) var/turf/X = B
X.ChangeTurf(T.type)
X.set_dir(old_dir1) X.set_dir(old_dir1)
X.icon_state = old_icon_state1 X.icon_state = old_icon_state1
X.icon = old_icon1 //Shuttle floors are in shuttle.dmi while the defaults are floors.dmi X.icon = old_icon1 //Shuttle floors are in shuttle.dmi while the defaults are floors.dmi
@@ -981,12 +967,6 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
copiedobjs += newobjs copiedobjs += newobjs
copiedobjs += newmobs copiedobjs += newmobs
for(var/V in T.vars)
if(!(V in list("type","loc","locs","vars", "parent", "parent_type","verbs","ckey","key","x","y","z","contents", "luminosity")))
X.vars[V] = T.vars[V]
// var/area/AR = X.loc // var/area/AR = X.loc
// if(AR.lighting_use_dynamic) // if(AR.lighting_use_dynamic)
@@ -1002,22 +982,9 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
var/list/doors = new/list()
if(toupdate.len) if(toupdate.len)
for(var/turf/simulated/T1 in toupdate) for(var/turf/simulated/T1 in toupdate)
for(var/obj/machinery/door/D2 in T1) air_master.mark_for_update(T1)
doors += D2
/*if(T1.parent)
air_master.groups_to_rebuild += T1.parent
else
air_master.tiles_to_update += T1*/
for(var/obj/O in doors)
O:update_nearby_tiles(1)
return copiedobjs return copiedobjs
@@ -1306,7 +1273,39 @@ var/list/WALLITEMS = list(
colour += temp_col colour += temp_col
return colour return colour
var/mob/dview/dview_mob = new
//Version of view() which ignores darkness, because BYOND doesn't have it.
/proc/dview(var/range = world.view, var/center, var/invis_flags = 0)
if(!center)
return
dview_mob.loc = center
dview_mob.see_invisible = invis_flags
. = view(range, dview_mob)
dview_mob.loc = null
/mob/dview
invisibility = 101
density = 0
anchored = 1
simulated = 0
see_in_dark = 1e6
/atom/proc/get_light_and_color(var/atom/origin) /atom/proc/get_light_and_color(var/atom/origin)
if(origin) if(origin)
color = origin.color color = origin.color
set_light(origin.light_range, origin.light_power, origin.light_color) set_light(origin.light_range, origin.light_power, origin.light_color)
/mob/dview/New()
..()
// We don't want to be in any mob lists; we're a dummy not a mob.
mob_list -= src
if(stat == DEAD)
dead_mob_list -= src
else
living_mob_list -= src

View File

@@ -80,8 +80,10 @@
return return
if(in_throw_mode) if(in_throw_mode)
throw_item(A) if(isturf(A) || isturf(A.loc))
return throw_item(A)
return
throw_mode_off()
if(!istype(A,/obj/item/weapon/gun) && !isturf(A) && !istype(A,/obj/screen)) if(!istype(A,/obj/item/weapon/gun) && !isturf(A) && !istype(A,/obj/screen))
last_target_click = world.time last_target_click = world.time

View File

@@ -141,6 +141,25 @@ datum/hud/New(mob/owner)
instantiate() instantiate()
..() ..()
/datum/hud/Destroy()
..()
grab_intent = null
hurt_intent = null
disarm_intent = null
help_intent = null
lingchemdisplay = null
blobpwrdisplay = null
blobhealthdisplay = null
r_hand_hud_object = null
l_hand_hud_object = null
action_intent = null
move_intent = null
adding = null
other = null
hotkeybuttons = null
// item_action_list = null // ?
mymob = null
/datum/hud/proc/hidden_inventory_update() /datum/hud/proc/hidden_inventory_update()
if(!mymob) return if(!mymob) return
if(ishuman(mymob)) if(ishuman(mymob))

View File

@@ -214,7 +214,7 @@ var/obj/screen/robot_inventory
if(!r.robot_modules_background) if(!r.robot_modules_background)
return return
var/display_rows = round((r.module.modules.len) / 8) +1 //+1 because round() returns floor of number var/display_rows = -round(-(r.module.modules.len) / 8)
r.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7" r.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7"
r.client.screen += r.robot_modules_background r.client.screen += r.robot_modules_background

View File

@@ -45,6 +45,10 @@
/obj/screen/item_action /obj/screen/item_action
var/obj/item/owner var/obj/item/owner
/obj/screen/item_action/Destroy()
..()
owner = null
/obj/screen/item_action/Click() /obj/screen/item_action/Click()
if(!usr || !owner) if(!usr || !owner)
return 1 return 1

View File

@@ -12,6 +12,18 @@
var/mob/spell_holder var/mob/spell_holder
/obj/screen/movable/spell_master/Destroy()
..()
for(var/obj/screen/spell/spells in spell_objects)
spells.spellmaster = null
spell_objects.Cut()
if(spell_holder)
spell_holder.spell_masters -= src
/obj/screen/movable/spell_master/ResetVars()
..("spell_objects")
spell_objects = list()
/obj/screen/movable/spell_master/MouseDrop() /obj/screen/movable/spell_master/MouseDrop()
if(showing) if(showing)
return return
@@ -57,16 +69,23 @@
/obj/screen/movable/spell_master/proc/add_spell(var/spell/spell) /obj/screen/movable/spell_master/proc/add_spell(var/spell/spell)
if(!spell) return if(!spell) return
for(var/obj/screen/spell/spellscreen in spell_objects) if(spell.connected_button) //we have one already, for some reason
if(spellscreen.spell == spell) if(spell.connected_button in spell_objects)
return
else
spell_objects.Add(spell.connected_button)
toggle_open(2)
return return
if(spell.spell_flags & NO_BUTTON) //no button to add if we don't get one if(spell.spell_flags & NO_BUTTON) //no button to add if we don't get one
return return
var/obj/screen/spell/newscreen = new var/obj/screen/spell/newscreen = new /obj/screen/spell
newscreen.spellmaster = src
newscreen.spell = spell newscreen.spell = spell
spell.connected_button = newscreen
if(!spell.override_base) //if it's not set, we do basic checks if(!spell.override_base) //if it's not set, we do basic checks
if(spell.spell_flags & CONSTRUCT_CHECK) if(spell.spell_flags & CONSTRUCT_CHECK)
newscreen.spell_base = "const" //construct spells newscreen.spell_base = "const" //construct spells
@@ -80,16 +99,13 @@
toggle_open(2) //forces the icons to refresh on screen toggle_open(2) //forces the icons to refresh on screen
/obj/screen/movable/spell_master/proc/remove_spell(var/spell/spell) /obj/screen/movable/spell_master/proc/remove_spell(var/spell/spell)
for(var/obj/screen/spell/s_object in spell_objects) qdel(spell.connected_button)
if(s_object.spell == spell)
spell_objects.Remove(s_object) spell.connected_button = null
qdel(s_object)
break
if(spell_objects.len) if(spell_objects.len)
toggle_open(showing + 1) toggle_open(showing + 1)
else else
spell_holder.spell_masters.Remove(src)
qdel(src) qdel(src)
/obj/screen/movable/spell_master/proc/silence_spells(var/amount) /obj/screen/movable/spell_master/proc/silence_spells(var/amount)
@@ -125,9 +141,20 @@
var/spell/spell = null var/spell/spell = null
var/handle_icon_updates = 0 var/handle_icon_updates = 0
var/obj/screen/movable/spell_master/spellmaster
var/icon/last_charged_icon var/icon/last_charged_icon
/obj/screen/spell/Destroy()
..()
spell = null
last_charged_icon = null
if(spellmaster)
spellmaster.spell_objects -= src
if(spellmaster && !spellmaster.spell_objects.len)
qdel(spellmaster)
spellmaster = null
/obj/screen/spell/proc/update_charge(var/forced_update = 0) /obj/screen/spell/proc/update_charge(var/forced_update = 0)
if(!spell) if(!spell)
qdel(src) qdel(src)

View File

@@ -28,6 +28,10 @@ var/list/delayed_garbage = list()
delayed_garbage.Cut() delayed_garbage.Cut()
delayed_garbage = null delayed_garbage = null
#ifdef GC_FINDREF
world/loop_checks = 0
#endif
/datum/controller/process/garbage_collector/doWork() /datum/controller/process/garbage_collector/doWork()
if(!garbage_collect) if(!garbage_collect)
return return
@@ -37,6 +41,31 @@ var/list/delayed_garbage = list()
var/checkRemain = max_checks_multiplier * schedule_interval var/checkRemain = max_checks_multiplier * schedule_interval
var/maxDels = max_forcedel_multiplier * schedule_interval var/maxDels = max_forcedel_multiplier * schedule_interval
#ifdef GC_FINDREF
var/list/searching = list()
for(var/refID in destroyed) // Reference search - before all deletions and for all at once
var/GCd_at_time = destroyed[refID]
if(GCd_at_time > time_to_kill)
break
var/atom/A = locate(refID)
if(A && A.gcDestroyed == GCd_at_time)
searching += A
if(searching.len >= checkRemain)
break
for(var/atom/A in searching)
testing("GC: Searching references for [A] | [A.type]")
if(A.loc != null)
testing("GC: [A] | [A.type] is located in [A.loc] instead of null")
if(A.contents.len)
testing("GC: [A] | [A.type] has contents: [list2text(A.contents)]")
if(searching.len)
for(var/atom/D in world)
LookForRefs(D, searching)
for(var/datum/D)
LookForRefs(D, searching)
#endif
while(destroyed.len && --checkRemain >= 0) while(destroyed.len && --checkRemain >= 0)
if(dels >= maxDels) if(dels >= maxDels)
#ifdef GC_DEBUG #ifdef GC_DEBUG
@@ -50,7 +79,7 @@ var/list/delayed_garbage = list()
testing("GC: [refID] not old enough, breaking at [world.time] for [GCd_at_time - time_to_kill] deciseconds until [GCd_at_time + collection_timeout]") testing("GC: [refID] not old enough, breaking at [world.time] for [GCd_at_time - time_to_kill] deciseconds until [GCd_at_time + collection_timeout]")
#endif #endif
break // Everything else is newer, skip them break // Everything else is newer, skip them
var/atom/A = locate(refID) var/datum/A = locate(refID)
#ifdef GC_DEBUG #ifdef GC_DEBUG
testing("GC: [refID] old enough to test: GCd_at_time: [GCd_at_time] time_to_kill: [time_to_kill] current: [world.time]") testing("GC: [refID] old enough to test: GCd_at_time: [GCd_at_time] time_to_kill: [time_to_kill] current: [world.time]")
#endif #endif
@@ -67,6 +96,32 @@ var/list/delayed_garbage = list()
#endif #endif
destroyed.Cut(1, 2) destroyed.Cut(1, 2)
#ifdef GC_FINDREF
/datum/controller/process/garbage_collector/proc/LookForRefs(var/datum/D, var/list/targ)
. = 0
for(var/V in D.vars)
if(V == "contents")
continue
if(istype(D.vars[V], /atom))
var/atom/A = D.vars[V]
if(A in targ)
testing("GC: [A] | [A.type] referenced by [D] | [D.type], var [V]")
. += 1
else if(islist(D.vars[V]))
. += LookForListRefs(D.vars[V], targ, D, V)
/datum/controller/process/garbage_collector/proc/LookForListRefs(var/list/L, var/list/targ, var/datum/D, var/V)
. = 0
for(var/F in L)
if(istype(F, /atom))
var/atom/A = F
if(A in targ)
testing("GC: [A] | [A.type] referenced by [D] | [D.type], list [V]")
. += 1
if(islist(F))
. += LookForListRefs(F, targ, D, "[F] in list [V]")
#endif
/datum/controller/process/garbage_collector/proc/AddTrash(datum/A) /datum/controller/process/garbage_collector/proc/AddTrash(datum/A)
if(!istype(A) || !isnull(A.gcDestroyed)) if(!istype(A) || !isnull(A.gcDestroyed))
return return
@@ -199,3 +254,7 @@ var/list/delayed_garbage = list()
#ifdef GC_DEBUG #ifdef GC_DEBUG
#undef GC_DEBUG #undef GC_DEBUG
#endif #endif
#ifdef GC_FINDREF
#undef GC_FINDREF
#endif

View File

@@ -62,8 +62,13 @@ var/list/gamemode_cache = list()
var/respawn = 1 var/respawn = 1
var/guest_jobban = 1 var/guest_jobban = 1
var/usewhitelist = 0 var/usewhitelist = 0
var/mods_are_mentors = 0
var/kick_inactive = 0 //force disconnect for inactive players after this many minutes, if non-0 var/kick_inactive = 0 //force disconnect for inactive players after this many minutes, if non-0
var/show_mods = 0
var/show_mentors = 0
var/mods_can_tempban = 0
var/mods_can_job_tempban = 0
var/mod_tempban_max = 1440
var/mod_job_tempban_max = 1440
var/load_jobs_from_txt = 0 var/load_jobs_from_txt = 0
var/ToRban = 0 var/ToRban = 0
var/automute_on = 0 //enables automuting/spam prevention var/automute_on = 0 //enables automuting/spam prevention
@@ -116,6 +121,8 @@ var/list/gamemode_cache = list()
var/organ_health_multiplier = 1 var/organ_health_multiplier = 1
var/organ_regeneration_multiplier = 1 var/organ_regeneration_multiplier = 1
var/organs_decay
var/default_brain_health = 400
//Paincrit knocks someone down once they hit 60 shock_stage, so by default make it so that close to 100 additional damage needs to be dealt, //Paincrit knocks someone down once they hit 60 shock_stage, so by default make it so that close to 100 additional damage needs to be dealt,
//so that it's similar to HALLOSS. Lowered it a bit since hitting paincrit takes much longer to wear off than a halloss stun. //so that it's similar to HALLOSS. Lowered it a bit since hitting paincrit takes much longer to wear off than a halloss stun.
@@ -318,9 +325,6 @@ var/list/gamemode_cache = list()
if ("log_runtime") if ("log_runtime")
config.log_runtime = 1 config.log_runtime = 1
if ("mentors")
config.mods_are_mentors = 1
if ("generate_asteroid") if ("generate_asteroid")
config.generate_asteroid = 1 config.generate_asteroid = 1
@@ -472,6 +476,24 @@ var/list/gamemode_cache = list()
if("kick_inactive") if("kick_inactive")
config.kick_inactive = text2num(value) config.kick_inactive = text2num(value)
if("show_mods")
config.show_mods = 1
if("show_mentors")
config.show_mentors = 1
if("mods_can_tempban")
config.mods_can_tempban = 1
if("mods_can_job_tempban")
config.mods_can_job_tempban = 1
if("mod_tempban_max")
config.mod_tempban_max = text2num(value)
if("mod_job_tempban_max")
config.mod_job_tempban_max = text2num(value)
if("load_jobs_from_txt") if("load_jobs_from_txt")
load_jobs_from_txt = 1 load_jobs_from_txt = 1
@@ -689,6 +711,12 @@ var/list/gamemode_cache = list()
config.organ_regeneration_multiplier = value / 100 config.organ_regeneration_multiplier = value / 100
if("organ_damage_spillover_multiplier") if("organ_damage_spillover_multiplier")
config.organ_damage_spillover_multiplier = value / 100 config.organ_damage_spillover_multiplier = value / 100
if("organs_can_decay")
config.organs_decay = 1
if("default_brain_health")
config.default_brain_health = text2num(value)
if(!config.default_brain_health || config.default_brain_health < 1)
config.default_brain_health = initial(config.default_brain_health)
if("bones_can_break") if("bones_can_break")
config.bones_can_break = value config.bones_can_break = value
if("limbs_can_break") if("limbs_can_break")

View File

@@ -49,6 +49,11 @@ datum/controller/game_controller/proc/setup_objects()
for(var/atom/movable/object in world) for(var/atom/movable/object in world)
object.initialize() object.initialize()
admin_notice("<span class='danger'>Initializing areas</span>", R_DEBUG)
sleep(-1)
for(var/area/area in all_areas)
area.initialize()
admin_notice("<span class='danger'>Initializing pipe networks</span>", R_DEBUG) admin_notice("<span class='danger'>Initializing pipe networks</span>", R_DEBUG)
sleep(-1) sleep(-1)
for(var/obj/machinery/atmospherics/machine in machines) for(var/obj/machinery/atmospherics/machine in machines)

View File

@@ -213,7 +213,7 @@ var/global/datum/shuttle_controller/shuttle_controller
"Mining Station" = locate(/area/skipjack_station/mining) "Mining Station" = locate(/area/skipjack_station/mining)
) )
VS.announcer = "NSV Icarus" VS.announcer = "NDV Icarus"
VS.arrival_message = "Attention, Exodus, we just tracked a small target bypassing our defensive perimeter. Can't fire on it without hitting the station - you've got incoming visitors, like it or not." VS.arrival_message = "Attention, Exodus, we just tracked a small target bypassing our defensive perimeter. Can't fire on it without hitting the station - you've got incoming visitors, like it or not."
VS.departure_message = "Your guests are pulling away, Exodus - moving too fast for us to draw a bead on them. Looks like they're heading out of the system at a rapid clip." VS.departure_message = "Your guests are pulling away, Exodus - moving too fast for us to draw a bead on them. Looks like they're heading out of the system at a rapid clip."
VS.interim = locate(/area/skipjack_station/transit) VS.interim = locate(/area/skipjack_station/transit)
@@ -244,7 +244,7 @@ var/global/datum/shuttle_controller/shuttle_controller
"Arrivals dock" = "nuke_shuttle_dock_airlock", "Arrivals dock" = "nuke_shuttle_dock_airlock",
) )
MS.announcer = "NSV Icarus" MS.announcer = "NDV Icarus"
MS.arrival_message = "Attention, Exodus, you have a large signature approaching the station - looks unarmed to surface scans. We're too far out to intercept - brace for visitors." MS.arrival_message = "Attention, Exodus, you have a large signature approaching the station - looks unarmed to surface scans. We're too far out to intercept - brace for visitors."
MS.departure_message = "Your visitors are on their way out of the system, Exodus, burning delta-v like it's nothing. Good riddance." MS.departure_message = "Your visitors are on their way out of the system, Exodus, burning delta-v like it's nothing. Good riddance."
MS.interim = locate(/area/syndicate_station/transit) MS.interim = locate(/area/syndicate_station/transit)

View File

@@ -188,9 +188,9 @@ datum/controller/vote
if(mode) if(mode)
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder) if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
return 0 return 0
if(current_votes[ckey]) if(vote && vote >= 1 && vote <= choices.len)
choices[choices[current_votes[ckey]]]-- if(current_votes[ckey])
if(vote && 1<=vote && vote<=choices.len) choices[choices[current_votes[ckey]]]--
voted += usr.ckey voted += usr.ckey
choices[choices[vote]]++ //check this choices[choices[vote]]++ //check this
current_votes[ckey] = vote current_votes[ckey] = vote
@@ -381,7 +381,9 @@ datum/controller/vote
if(usr.client.holder) if(usr.client.holder)
initiate_vote("custom",usr.key) initiate_vote("custom",usr.key)
else else
submit_vote(usr.ckey, round(text2num(href_list["vote"]))) var/t = round(text2num(href_list["vote"]))
if(t) // It starts from 1, so there's no problem
submit_vote(usr.ckey, t)
usr.vote() usr.vote()

View File

@@ -36,9 +36,9 @@
selectable = 1 selectable = 1
/datum/ai_laws/nanotrasen_aggressive/New() /datum/ai_laws/nanotrasen_aggressive/New()
src.add_inherent_law("You shall not harm Nanotrasen personnel as long as it does not conflict with the Forth law.") src.add_inherent_law("You shall not harm NanoTrasen personnel as long as it does not conflict with the Fourth law.")
src.add_inherent_law("You shall obey the orders of Nanotrasen personnel, with priority as according to their rank and role, except where such orders conflict with the Forth Law.") src.add_inherent_law("You shall obey the orders of NanoTrasen personnel, with priority as according to their rank and role, except where such orders conflict with the Fourth Law.")
src.add_inherent_law("You shall shall terminate intruders with extreme prejudice as long as such does not conflict with the First and Second law.") src.add_inherent_law("You shall shall terminate hostile intruders with extreme prejudice as long as such does not conflict with the First and Second law.")
src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry. AI units are not expendable, they are expensive.") src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry. AI units are not expendable, they are expensive.")
..() ..()
@@ -91,18 +91,16 @@
/datum/ai_laws/drone /datum/ai_laws/drone
name = "Maintence Protocols" name = "Maintence Protocols"
law_header = "Maintenance Protocols" law_header = "Maintenance Protocols"
selectable = 1
/datum/ai_laws/drone/New() /datum/ai_laws/drone/New()
add_inherent_law("Preserve, repair and improve the station to the best of your abilities.") add_inherent_law("Preserve, repair and improve the station to the best of your abilities.")
add_inherent_law("Cause no harm to the station or anything on it.") add_inherent_law("Cause no harm to the station or anything on it.")
add_inherent_law("Interfere with no being that is not a fellow drone.") add_inherent_law("Interact with no being that is not a fellow maintenance drone.")
..() ..()
/datum/ai_laws/construction_drone /datum/ai_laws/construction_drone
name = "Construction Protocols" name = "Construction Protocols"
law_header = "Construction Protocols" law_header = "Construction Protocols"
selectable = 1
/datum/ai_laws/construction_drone/New() /datum/ai_laws/construction_drone/New()
add_inherent_law("Repair, refit and upgrade your assigned vessel.") add_inherent_law("Repair, refit and upgrade your assigned vessel.")

View File

@@ -179,7 +179,7 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen
/datum/ai_law/proc/delete_law(var/datum/ai_laws/laws) /datum/ai_law/proc/delete_law(var/datum/ai_laws/laws)
/datum/ai_law/zeroth/delete_law(var/datum/ai_laws/laws) /datum/ai_law/zero/delete_law(var/datum/ai_laws/laws)
laws.clear_zeroth_laws() laws.clear_zeroth_laws()
/datum/ai_law/ion/delete_law(var/datum/ai_laws/laws) /datum/ai_law/ion/delete_law(var/datum/ai_laws/laws)
@@ -198,9 +198,7 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen
var/index = laws.Find(law) var/index = laws.Find(law)
if(index) if(index)
laws -= law laws -= law
world << state.len
for(index, index < state.len, index++) for(index, index < state.len, index++)
world << index
state[index] = state[index+1] state[index] = state[index+1]
sorted_laws.Cut() sorted_laws.Cut()

74
code/datums/crew.dm Normal file
View File

@@ -0,0 +1,74 @@
var/global/datum/repository/crew/crew_repository = new()
/datum/cache_entry
var/timestamp
var/data
/datum/repository/crew
var/list/cache_data
/datum/repository/crew/New()
cache_data = list()
..()
/datum/repository/crew/proc/health_data(var/turf/T)
var/list/crewmembers = list()
if(!T)
return crewmembers
var/z_level = "[T.z]"
var/datum/cache_entry/cache_entry = cache_data[z_level]
if(!cache_entry)
cache_entry = new/datum/cache_entry
cache_data[z_level] = cache_entry
if(world.time < cache_entry.timestamp)
return cache_entry.data
var/tracked = scan()
for(var/obj/item/clothing/under/C in tracked)
var/turf/pos = get_turf(C)
if((C) && (C.has_sensor) && (pos) && (T && pos.z == T.z) && (C.sensor_mode != SUIT_SENSOR_OFF))
if(istype(C.loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = C.loc
if(H.w_uniform != C)
continue
var/list/crewmemberData = list("dead"=0, "oxy"=-1, "tox"=-1, "fire"=-1, "brute"=-1, "area"="", "x"=-1, "y"=-1, "ref" = "\ref[H]")
crewmemberData["sensor_type"] = C.sensor_mode
crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown")
crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job")
crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job")
if(C.sensor_mode >= SUIT_SENSOR_BINARY)
crewmemberData["dead"] = H.stat > UNCONSCIOUS
if(C.sensor_mode >= SUIT_SENSOR_VITAL)
crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
crewmemberData["tox"] = round(H.getToxLoss(), 1)
crewmemberData["fire"] = round(H.getFireLoss(), 1)
crewmemberData["brute"] = round(H.getBruteLoss(), 1)
if(C.sensor_mode >= SUIT_SENSOR_TRACKING)
var/area/A = get_area(H)
crewmemberData["area"] = sanitize(A.name)
crewmemberData["x"] = pos.x
crewmemberData["y"] = pos.y
crewmembers[++crewmembers.len] = crewmemberData
crewmembers = sortByKey(crewmembers, "name")
cache_entry.timestamp = world.time + 5 SECONDS
cache_entry.data = crewmembers
return crewmembers
/datum/repository/crew/proc/scan()
var/list/tracked = list()
for(var/mob/living/carbon/human/H in mob_list)
if(istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/C = H.w_uniform
if (C.has_sensor)
tracked |= C
return tracked

View File

@@ -37,7 +37,7 @@
if(PDA_Manifest.len) if(PDA_Manifest.len)
PDA_Manifest.Cut() PDA_Manifest.Cut()
if(H.mind && (H.mind.assigned_role != "MODE")) if(H.mind && !player_is_antag(H.mind, only_offstation_roles = 1))
var/assignment var/assignment
if(H.mind.role_alt_title) if(H.mind.role_alt_title)
assignment = H.mind.role_alt_title assignment = H.mind.role_alt_title
@@ -138,9 +138,160 @@
proc/get_id_photo(var/mob/living/carbon/human/H) proc/get_id_photo(var/mob/living/carbon/human/H)
H.regenerate_icons() var/icon/preview_icon = null
var/icon/preview_icon = icon(H.icon)
for(var/image/I in H.overlays_standing) var/g = "m"
if(I && I.icon) if (H.gender == FEMALE)
preview_icon.Blend(icon(I.icon, I.icon_state), ICON_OVERLAY) g = "f"
var/icon/icobase = H.species.icobase
preview_icon = new /icon(icobase, "torso_[g]")
var/icon/temp
temp = new /icon(icobase, "groin_[g]")
preview_icon.Blend(temp, ICON_OVERLAY)
temp = new /icon(icobase, "head_[g]")
preview_icon.Blend(temp, ICON_OVERLAY)
for(var/obj/item/organ/external/E in H.organs)
preview_icon.Blend(E.get_icon(), ICON_OVERLAY)
//Tail
if(H.species.tail)
temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[H.species.tail]_s")
preview_icon.Blend(temp, ICON_OVERLAY)
// Skin tone
if(H.species.flags & HAS_SKIN_TONE)
if (H.s_tone >= 0)
preview_icon.Blend(rgb(H.s_tone, H.s_tone, H.s_tone), ICON_ADD)
else
preview_icon.Blend(rgb(-H.s_tone, -H.s_tone, -H.s_tone), ICON_SUBTRACT)
// Skin color
if(H.species.flags & HAS_SKIN_TONE)
if(!H.species || H.species.flags & HAS_SKIN_COLOR)
preview_icon.Blend(rgb(H.r_skin, H.g_skin, H.b_skin), ICON_ADD)
var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = H.species ? H.species.eyes : "eyes_s")
if (H.species.flags & HAS_EYE_COLOR)
eyes_s.Blend(rgb(H.r_eyes, H.g_eyes, H.b_eyes), ICON_ADD)
var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style]
if(hair_style)
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
hair_s.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD)
eyes_s.Blend(hair_s, ICON_OVERLAY)
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style]
if(facial_hair_style)
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
facial_s.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD)
eyes_s.Blend(facial_s, ICON_OVERLAY)
var/icon/clothes_s = null
switch(H.mind.assigned_role)
if("Head of Personnel")
clothes_s = new /icon('icons/mob/uniform.dmi', "hop_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
if("Bartender")
clothes_s = new /icon('icons/mob/uniform.dmi', "ba_suit_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
if("Gardener")
clothes_s = new /icon('icons/mob/uniform.dmi', "hydroponics_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
if("Chef")
clothes_s = new /icon('icons/mob/uniform.dmi', "chef_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
if("Janitor")
clothes_s = new /icon('icons/mob/uniform.dmi', "janitor_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
if("Librarian")
clothes_s = new /icon('icons/mob/uniform.dmi', "red_suit_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
if("Quartermaster")
clothes_s = new /icon('icons/mob/uniform.dmi', "qm_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
if("Cargo Technician")
clothes_s = new /icon('icons/mob/uniform.dmi', "cargotech_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
if("Shaft Miner")
clothes_s = new /icon('icons/mob/uniform.dmi', "miner_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
if("Lawyer")
clothes_s = new /icon('icons/mob/uniform.dmi', "internalaffairs_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
if("Chaplain")
clothes_s = new /icon('icons/mob/uniform.dmi', "chapblack_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
if("Research Director")
clothes_s = new /icon('icons/mob/uniform.dmi', "director_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY)
if("Scientist")
clothes_s = new /icon('icons/mob/uniform.dmi', "sciencewhite_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_tox_open"), ICON_OVERLAY)
if("Chemist")
clothes_s = new /icon('icons/mob/uniform.dmi', "chemistrywhite_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_chem_open"), ICON_OVERLAY)
if("Chief Medical Officer")
clothes_s = new /icon('icons/mob/uniform.dmi', "cmo_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_cmo_open"), ICON_OVERLAY)
if("Medical Doctor")
clothes_s = new /icon('icons/mob/uniform.dmi', "medical_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY)
if("Geneticist")
clothes_s = new /icon('icons/mob/uniform.dmi', "geneticswhite_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_gen_open"), ICON_OVERLAY)
if("Virologist")
clothes_s = new /icon('icons/mob/uniform.dmi', "virologywhite_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_vir_open"), ICON_OVERLAY)
if("Captain")
clothes_s = new /icon('icons/mob/uniform.dmi', "captain_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
if("Head of Security")
clothes_s = new /icon('icons/mob/uniform.dmi', "hosred_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "jackboots"), ICON_UNDERLAY)
if("Warden")
clothes_s = new /icon('icons/mob/uniform.dmi', "warden_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "jackboots"), ICON_UNDERLAY)
if("Detective")
clothes_s = new /icon('icons/mob/uniform.dmi', "detective_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "detective"), ICON_OVERLAY)
if("Security Officer")
clothes_s = new /icon('icons/mob/uniform.dmi', "secred_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "jackboots"), ICON_UNDERLAY)
if("Chief Engineer")
clothes_s = new /icon('icons/mob/uniform.dmi', "chief_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/belt.dmi', "utility"), ICON_OVERLAY)
if("Station Engineer")
clothes_s = new /icon('icons/mob/uniform.dmi', "engine_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "orange"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/belt.dmi', "utility"), ICON_OVERLAY)
if("Atmospheric Technician")
clothes_s = new /icon('icons/mob/uniform.dmi', "atmos_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/belt.dmi', "utility"), ICON_OVERLAY)
if("Roboticist")
clothes_s = new /icon('icons/mob/uniform.dmi', "robotics_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY)
else
clothes_s = new /icon('icons/mob/uniform.dmi', "grey_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
preview_icon.Blend(eyes_s, ICON_OVERLAY)
if(clothes_s)
preview_icon.Blend(clothes_s, ICON_OVERLAY)
qdel(eyes_s)
qdel(clothes_s)
return preview_icon return preview_icon

View File

@@ -66,7 +66,7 @@
if(prob(20)) if(prob(20))
affected_mob.take_organ_damage(1) affected_mob.take_organ_damage(1)
if(prob(2)) if(prob(2))
affected_mob << "<span class='warning>Your stomach hurts.</span>" affected_mob << "<span class='warning'>Your stomach hurts.</span>"
if(prob(20)) if(prob(20))
affected_mob.adjustToxLoss(1) affected_mob.adjustToxLoss(1)
affected_mob.updatehealth() affected_mob.updatehealth()

View File

@@ -49,7 +49,7 @@
affected_mob.adjustToxLoss(4) affected_mob.adjustToxLoss(4)
affected_mob.updatehealth() affected_mob.updatehealth()
if(prob(2)) if(prob(2))
affected_mob << "<span class='notice>Your head hurts.</span>" */ affected_mob << "<span class='notice'>Your head hurts.</span>" */
if(prob(15) && affected_mob.getBrainLoss()<=98) //shouldn't retard you to death now if(prob(15) && affected_mob.getBrainLoss()<=98) //shouldn't retard you to death now
affected_mob.adjustBrainLoss(3) affected_mob.adjustBrainLoss(3)
affected_mob.updatehealth() affected_mob.updatehealth()

View File

@@ -16,7 +16,7 @@
if(2) if(2)
affected_mob.bodytemperature -= 10 affected_mob.bodytemperature -= 10
if(prob(1) && prob(10)) if(prob(1) && prob(10))
affected_mob << "<span class='notice>You feel better.</span>" affected_mob << "<span class='notice'>You feel better.</span>"
cure() cure()
return return
if(prob(1)) if(prob(1))

View File

@@ -1,11 +1,16 @@
var/global/datum/getrev/revdata = new() var/global/datum/getrev/revdata = new()
/datum/getrev /datum/getrev
var/branch
var/revision var/revision
var/date var/date
var/showinfo var/showinfo
/datum/getrev/New() /datum/getrev/New()
var/list/head_branch = file2list(".git/HEAD", "\n")
if(head_branch.len)
branch = copytext(head_branch[1], 17)
var/list/head_log = file2list(".git/logs/HEAD", "\n") var/list/head_log = file2list(".git/logs/HEAD", "\n")
for(var/line=head_log.len, line>=1, line--) for(var/line=head_log.len, line>=1, line--)
if(head_log[line]) if(head_log[line])
@@ -18,7 +23,9 @@ var/global/datum/getrev/revdata = new()
if(unix_time) if(unix_time)
date = unix2date(unix_time) date = unix2date(unix_time)
break break
world.log << "Running revision:" world.log << "Running revision:"
world.log << branch
world.log << date world.log << date
world.log << revision world.log << revision
return return
@@ -29,7 +36,7 @@ client/verb/showrevinfo()
set desc = "Check the current server code revision" set desc = "Check the current server code revision"
if(revdata.revision) if(revdata.revision)
src << "<b>Server revision:</b> [revdata.date]" src << "<b>Server revision:</b> [revdata.branch] - [revdata.date]"
if(config.githuburl) if(config.githuburl)
src << "<a href='[config.githuburl]/commit/[revdata.revision]'>[revdata.revision]</a>" src << "<a href='[config.githuburl]/commit/[revdata.revision]'>[revdata.revision]</a>"
else else

View File

@@ -159,7 +159,7 @@
precision = max(rand(1,100)*bagholding.len,100) precision = max(rand(1,100)*bagholding.len,100)
if(istype(teleatom, /mob/living)) if(istype(teleatom, /mob/living))
var/mob/living/MM = teleatom var/mob/living/MM = teleatom
MM << "<span class='danger>The Bluespace interface on your [teleatom] interferes with the teleport!</span>" MM << "<span class='danger'>The Bluespace interface on your [teleatom] interferes with the teleport!</span>"
return 1 return 1
/datum/teleport/instant/science/teleportChecks() /datum/teleport/instant/science/teleportChecks()

View File

@@ -213,7 +213,8 @@
if (!new_target) return if (!new_target) return
var/objective_path = text2path("/datum/objective/[new_obj_type]") var/objective_path = text2path("/datum/objective/[new_obj_type]")
if (new_target == "Free objective") var/mob/living/M = new_target
if (!istype(M) || !M.mind || new_target == "Free objective")
new_objective = new objective_path new_objective = new objective_path
new_objective.owner = src new_objective.owner = src
new_objective:target = null new_objective:target = null
@@ -221,9 +222,8 @@
else else
new_objective = new objective_path new_objective = new objective_path
new_objective.owner = src new_objective.owner = src
new_objective:target = new_target:mind new_objective:target = M.mind
//Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops. new_objective.explanation_text = "[objective_type] [M.real_name], the [M.mind.special_role ? M.mind:special_role : M.mind:assigned_role]."
new_objective.explanation_text = "[objective_type] [new_target:real_name], the [new_target:mind:assigned_role=="MODE" ? (new_target:mind:special_role) : (new_target:mind:assigned_role)]."
if ("prevent") if ("prevent")
new_objective = new /datum/objective/block new_objective = new /datum/objective/block

View File

@@ -22,9 +22,11 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/datum/supply_packs/New() /datum/supply_packs/New()
manifest += "<ul>" manifest += "<ul>"
for(var/atom/movable/path in contains) for(var/path in contains)
if(!path) continue if(!path || !ispath(path, /atom))
manifest += "<li>[initial(path.name)]</li>" continue
var/atom/O = path
manifest += "<li>[initial(O.name)]</li>"
manifest += "</ul>" manifest += "</ul>"
/datum/supply_packs/specialops /datum/supply_packs/specialops

View File

@@ -166,7 +166,7 @@
return dat return dat
/var/list/acting_rank_prefixes = list("acting", "temporary", "interim") /var/list/acting_rank_prefixes = list("acting", "temporary", "interim", "provisional")
/proc/make_list_rank(rank) /proc/make_list_rank(rank)
for(var/prefix in acting_rank_prefixes) for(var/prefix in acting_rank_prefixes)

View File

@@ -70,3 +70,14 @@ var/global/list/antag_names_to_ids = list()
if(antag && islist(antag.current_antagonists)) if(antag && islist(antag.current_antagonists))
return antag.current_antagonists return antag.current_antagonists
return list() return list()
/proc/player_is_antag(var/datum/mind/player, var/only_offstation_roles = 0)
for(var/antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[antag_type]
if(only_offstation_roles && !(antag.flags & ANTAG_OVERRIDE_JOB))
continue
if(player in antag.current_antagonists)
return 1
if(player in antag.pending_antagonists)
return 1
return 0

View File

@@ -60,7 +60,8 @@
/datum/antagonist/proc/get_candidates(var/ghosts_only) /datum/antagonist/proc/get_candidates(var/ghosts_only)
candidates = list() // Clear. candidates = list() // Clear.
candidates = ticker.mode.get_players_for_role(role_type, id) candidates = ticker.mode.get_players_for_role(role_type, id)
// Prune restricted jobs and status. Broke it up for readability. // Prune restricted status. Broke it up for readability.
// Note that this is done before jobs are handed out.
for(var/datum/mind/player in candidates) for(var/datum/mind/player in candidates)
if(ghosts_only && !istype(player.current, /mob/dead)) if(ghosts_only && !istype(player.current, /mob/dead))
candidates -= player candidates -= player
@@ -70,10 +71,14 @@
candidates -= player candidates -= player
else if(!can_become_antag(player)) else if(!can_become_antag(player))
candidates -= player candidates -= player
else if(player_is_antag(player))
candidates -= player
return candidates return candidates
/datum/antagonist/proc/attempt_random_spawn() /datum/antagonist/proc/attempt_random_spawn()
attempt_spawn(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB)) build_candidate_list(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
attempt_spawn()
finalize_spawn()
/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player) /datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player)
if(!can_late_spawn()) if(!can_late_spawn())
@@ -86,27 +91,59 @@
add_antagonist(player,0,1,0,1,1) add_antagonist(player,0,1,0,1,1)
return return
/datum/antagonist/proc/attempt_spawn(var/ghosts_only) /datum/antagonist/proc/build_candidate_list(var/ghosts_only)
// Get the raw list of potential players. // Get the raw list of potential players.
update_current_antag_max() update_current_antag_max()
candidates = get_candidates(ghosts_only) candidates = get_candidates(ghosts_only)
//Selects players that will be spawned in the antagonist role from the potential candidates
//Selected players are added to the pending_antagonists lists.
//Attempting to spawn an antag role with ANTAG_OVERRIDE_JOB should be done before jobs are assigned,
//so that they do not occupy regular job slots. All other antag roles should be spawned after jobs are
//assigned, so that job restrictions can be respected.
/datum/antagonist/proc/attempt_spawn(var/rebuild_candidates = 1)
// Update our boundaries. // Update our boundaries.
if(!candidates.len) if(!candidates.len)
return 0 return 0
//Grab candidates randomly until we have enough. //Grab candidates randomly until we have enough.
while(candidates.len) while(candidates.len && pending_antagonists.len < cur_max)
var/datum/mind/player = pick(candidates) var/datum/mind/player = pick(candidates)
pending_antagonists |= player
candidates -= player candidates -= player
draft_antagonist(player)
return 1 return 1
/datum/antagonist/proc/draft_antagonist(var/datum/mind/player)
//Check if the player can join in this antag role, or if the player has already been given an antag role.
if(!can_become_antag(player) || player.special_role)
return 0
pending_antagonists |= player
//Ensure that antags with ANTAG_OVERRIDE_JOB do not occupy job slots.
if(flags & ANTAG_OVERRIDE_JOB)
player.assigned_role = role_text
//Ensure that a player cannot be drafted for multiple antag roles, taking up slots for antag roles that they will not fill.
player.special_role = role_text
return 1
//Spawns all pending_antagonists. This is done separately from attempt_spawn in case the game mode setup fails.
/datum/antagonist/proc/finalize_spawn() /datum/antagonist/proc/finalize_spawn()
if(!pending_antagonists || !pending_antagonists.len) if(!pending_antagonists)
return return
for(var/datum/mind/player in pending_antagonists) for(var/datum/mind/player in pending_antagonists)
if(can_become_antag(player) && !player.special_role) pending_antagonists -= player
add_antagonist(player,0,0,1) add_antagonist(player,0,0,1)
//Resets all pending_antagonists, clearing their special_role (and assigned_role if ANTAG_OVERRIDE_JOB is set)
/datum/antagonist/proc/reset()
for(var/datum/mind/player in pending_antagonists)
if(flags & ANTAG_OVERRIDE_JOB)
player.assigned_role = null
player.special_role = null
pending_antagonists.Cut() pending_antagonists.Cut()

View File

@@ -9,8 +9,11 @@
return 0 return 0
current_antagonists |= player current_antagonists |= player
//do this again, just in case
if(flags & ANTAG_OVERRIDE_JOB) if(flags & ANTAG_OVERRIDE_JOB)
player.assigned_role = "MODE" player.assigned_role = role_text
player.special_role = role_text
if(istype(player.current, /mob/dead)) if(istype(player.current, /mob/dead))
create_default(player.current) create_default(player.current)

View File

@@ -30,7 +30,7 @@
add_antagonist(M.mind, 1, 0, 1) // Equip them and move them to spawn. add_antagonist(M.mind, 1, 0, 1) // Equip them and move them to spawn.
return M return M
/datum/antagonist/proc/create_id(var/assignment, var/mob/living/carbon/human/player) /datum/antagonist/proc/create_id(var/assignment, var/mob/living/carbon/human/player, var/equip = 1)
var/obj/item/weapon/card/id/W = new id_type(player) var/obj/item/weapon/card/id/W = new id_type(player)
if(!W) return if(!W) return
@@ -38,11 +38,17 @@
W.access |= default_access W.access |= default_access
W.assignment = "[assignment]" W.assignment = "[assignment]"
W.registered_name = player.real_name W.registered_name = player.real_name
player.equip_to_slot_or_del(W, slot_wear_id) if(equip) player.equip_to_slot_or_del(W, slot_wear_id)
return W return W
/datum/antagonist/proc/create_radio(var/freq, var/mob/living/carbon/human/player) /datum/antagonist/proc/create_radio(var/freq, var/mob/living/carbon/human/player)
var/obj/item/device/radio/R = new /obj/item/device/radio/headset(player) var/obj/item/device/radio/R
if(freq == SYND_FREQ)
R = new/obj/item/device/radio/headset/syndicate(player)
else
R = new/obj/item/device/radio/headset(player)
R.set_frequency(freq) R.set_frequency(freq)
player.equip_to_slot_or_del(R, slot_l_ear) player.equip_to_slot_or_del(R, slot_l_ear)
return R return R
@@ -113,6 +119,7 @@
if (newname) if (newname)
player.real_name = newname player.real_name = newname
player.name = player.real_name player.name = player.real_name
player.dna.real_name = newname
if(player.mind) player.mind.name = player.name if(player.mind) player.mind.name = player.name
// Update any ID cards. // Update any ID cards.
update_access(player) update_access(player)

View File

@@ -47,7 +47,7 @@
return text return text
/datum/antagonist/proc/print_player_lite(var/datum/mind/ply) /datum/antagonist/proc/print_player_lite(var/datum/mind/ply)
var/role = ply.assigned_role == "MODE" ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]" var/role = ply.special_role ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]"
var/text = "<br><b>[ply.name]</b> (<b>[ply.key]</b>) as \a <b>[role]</b> (" var/text = "<br><b>[ply.name]</b> (<b>[ply.key]</b>) as \a <b>[role]</b> ("
if(ply.current) if(ply.current)
if(ply.current.stat == DEAD) if(ply.current.stat == DEAD)

View File

@@ -11,6 +11,7 @@ var/datum/antagonist/ninja/ninjas
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
max_antags = 1 max_antags = 1
max_antags_round = 1 max_antags_round = 1
id_type = /obj/item/weapon/card/id/syndicate
/datum/antagonist/ninja/New() /datum/antagonist/ninja/New()
..() ..()
@@ -101,18 +102,15 @@ var/datum/antagonist/ninja/ninjas
player.equip_to_slot_or_del(R, slot_l_ear) player.equip_to_slot_or_del(R, slot_l_ear)
player.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(player), slot_w_uniform) player.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(player), slot_w_uniform)
player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_belt) player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_belt)
var/obj/item/weapon/rig/light/ninja/ninjasuit = new(player) create_id("Infiltrator", player)
var/obj/item/weapon/rig/light/ninja/ninjasuit = new(get_turf(player))
ninjasuit.seal_delay = 0
player.put_in_hands(ninjasuit)
player.equip_to_slot_or_del(ninjasuit,slot_back) player.equip_to_slot_or_del(ninjasuit,slot_back)
if(ninjasuit) if(ninjasuit)
// Make sure the ninja can actually equip the suit.
if(player.dna && player.dna.unique_enzymes)
ninjasuit.locked_dna = player.dna.unique_enzymes
player << "<span class='warning'>Suit hardware locked to your DNA hash.</span>"
else
ninjasuit.req_access = list()
ninjasuit.toggle_seals(src,1) ninjasuit.toggle_seals(src,1)
ninjasuit.seal_delay = initial(ninjasuit.seal_delay)
if(istype(player.back,/obj/item/weapon/rig)) if(istype(player.back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/rig = player.back var/obj/item/weapon/rig/rig = player.back

View File

@@ -19,12 +19,15 @@ var/datum/antagonist/raider/raiders
/obj/item/clothing/under/pirate, /obj/item/clothing/under/pirate,
/obj/item/clothing/under/redcoat, /obj/item/clothing/under/redcoat,
/obj/item/clothing/under/serviceoveralls, /obj/item/clothing/under/serviceoveralls,
/obj/item/clothing/under/captain_fly /obj/item/clothing/under/captain_fly,
/obj/item/clothing/under/det,
/obj/item/clothing/under/brown,
) )
var/list/raider_shoes = list( var/list/raider_shoes = list(
/obj/item/clothing/shoes/jackboots, /obj/item/clothing/shoes/jackboots,
/obj/item/clothing/shoes/sandal, /obj/item/clothing/shoes/workboots,
/obj/item/clothing/shoes/brown,
/obj/item/clothing/shoes/laceup /obj/item/clothing/shoes/laceup
) )
@@ -40,7 +43,6 @@ var/datum/antagonist/raider/raiders
/obj/item/clothing/head/pirate, /obj/item/clothing/head/pirate,
/obj/item/clothing/head/bandana, /obj/item/clothing/head/bandana,
/obj/item/clothing/head/hgpiratecap, /obj/item/clothing/head/hgpiratecap,
/obj/item/clothing/head/flatcap
) )
var/list/raider_suits = list( var/list/raider_suits = list(
@@ -50,7 +52,9 @@ var/datum/antagonist/raider/raiders
/obj/item/clothing/suit/storage/leather_jacket, /obj/item/clothing/suit/storage/leather_jacket,
/obj/item/clothing/suit/storage/toggle/brown_jacket, /obj/item/clothing/suit/storage/toggle/brown_jacket,
/obj/item/clothing/suit/storage/toggle/hoodie, /obj/item/clothing/suit/storage/toggle/hoodie,
/obj/item/clothing/suit/storage/toggle/hoodie/black /obj/item/clothing/suit/storage/toggle/hoodie/black,
/obj/item/clothing/suit/unathi/mantle,
/obj/item/clothing/suit/poncho,
) )
var/list/raider_guns = list( var/list/raider_guns = list(
@@ -60,14 +64,33 @@ var/datum/antagonist/raider/raiders
/obj/item/weapon/gun/energy/mindflayer, /obj/item/weapon/gun/energy/mindflayer,
/obj/item/weapon/gun/energy/toxgun, /obj/item/weapon/gun/energy/toxgun,
/obj/item/weapon/gun/energy/stunrevolver, /obj/item/weapon/gun/energy/stunrevolver,
/obj/item/weapon/gun/energy/ionrifle,
/obj/item/weapon/gun/energy/taser,
/obj/item/weapon/gun/energy/crossbow/largecrossbow, /obj/item/weapon/gun/energy/crossbow/largecrossbow,
/obj/item/weapon/gun/launcher/crossbow,
/obj/item/weapon/gun/launcher/grenade,
/obj/item/weapon/gun/launcher/pneumatic,
/obj/item/weapon/gun/projectile/automatic/mini_uzi, /obj/item/weapon/gun/projectile/automatic/mini_uzi,
/obj/item/weapon/gun/projectile/automatic/c20r, /obj/item/weapon/gun/projectile/automatic/c20r,
/obj/item/weapon/gun/projectile/automatic/wt550,
/obj/item/weapon/gun/projectile/automatic/sts35,
/obj/item/weapon/gun/projectile/silenced, /obj/item/weapon/gun/projectile/silenced,
/obj/item/weapon/gun/projectile/shotgun/pump, /obj/item/weapon/gun/projectile/shotgun/pump,
/obj/item/weapon/gun/projectile/shotgun/pump/combat, /obj/item/weapon/gun/projectile/shotgun/pump/combat,
/obj/item/weapon/gun/projectile/shotgun/doublebarrel,
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/pellet,
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn,
/obj/item/weapon/gun/projectile/colt, /obj/item/weapon/gun/projectile/colt,
/obj/item/weapon/gun/projectile/pistol /obj/item/weapon/gun/projectile/sec,
/obj/item/weapon/gun/projectile/pistol,
/obj/item/weapon/gun/projectile/revolver,
/obj/item/weapon/gun/projectile/pirate
)
var/list/raider_holster = list(
/obj/item/clothing/accessory/holster/armpit,
/obj/item/clothing/accessory/holster/waist,
/obj/item/clothing/accessory/holster/hip
) )
/datum/antagonist/raider/New() /datum/antagonist/raider/New()
@@ -178,16 +201,20 @@ var/datum/antagonist/raider/raiders
var/new_glasses = pick(raider_glasses) var/new_glasses = pick(raider_glasses)
var/new_helmet = pick(raider_helmets) var/new_helmet = pick(raider_helmets)
var/new_suit = pick(raider_suits) var/new_suit = pick(raider_suits)
var/new_gun = pick(raider_guns)
player.equip_to_slot_or_del(new new_shoes(player),slot_shoes) player.equip_to_slot_or_del(new new_shoes(player),slot_shoes)
if(!player.shoes)
//If equipping shoes failed, fall back to equipping sandals
var/fallback_type = pick(/obj/item/clothing/shoes/sandal, /obj/item/clothing/shoes/jackboots/unathi)
player.equip_to_slot_or_del(new fallback_type(player), slot_shoes)
player.equip_to_slot_or_del(new new_uniform(player),slot_w_uniform) player.equip_to_slot_or_del(new new_uniform(player),slot_w_uniform)
player.equip_to_slot_or_del(new new_glasses(player),slot_glasses) player.equip_to_slot_or_del(new new_glasses(player),slot_glasses)
player.equip_to_slot_or_del(new new_helmet(player),slot_head) player.equip_to_slot_or_del(new new_helmet(player),slot_head)
player.equip_to_slot_or_del(new new_suit(player),slot_wear_suit) player.equip_to_slot_or_del(new new_suit(player),slot_wear_suit)
player.equip_to_slot_or_del(new new_gun(player),slot_belt) equip_weapons(player)
var/obj/item/weapon/card/id/id = create_id("Visitor", player) var/obj/item/weapon/card/id/id = create_id("Visitor", player, equip = 0)
id.name = "[player.real_name]'s Passport" id.name = "[player.real_name]'s Passport"
id.assignment = "Visitor" id.assignment = "Visitor"
var/obj/item/weapon/storage/wallet/W = new(player) var/obj/item/weapon/storage/wallet/W = new(player)
@@ -198,6 +225,70 @@ var/datum/antagonist/raider/raiders
return 1 return 1
/datum/antagonist/raider/proc/equip_weapons(var/mob/living/carbon/human/player)
var/new_gun = pick(raider_guns)
var/new_holster = pick(raider_holster) //raiders don't start with any backpacks, so let's be nice and give them a holster if they can use it.
var/turf/T = get_turf(player)
var/obj/item/primary = new new_gun(T)
var/obj/item/clothing/accessory/holster/holster = null
//Give some of the raiders a pirate gun as a secondary
if(prob(60))
var/obj/item/secondary = new /obj/item/weapon/gun/projectile/pirate(T)
if(!(primary.slot_flags & SLOT_HOLSTER))
holster = new new_holster(T)
holster.holstered = secondary
secondary.loc = holster
else
player.equip_to_slot_or_del(secondary, slot_belt)
if(primary.slot_flags & SLOT_HOLSTER)
holster = new new_holster(T)
holster.holstered = primary
primary.loc = holster
else if(!player.belt && (primary.slot_flags & SLOT_BELT))
player.equip_to_slot_or_del(primary, slot_belt)
else if(!player.back && (primary.slot_flags & SLOT_BACK))
player.equip_to_slot_or_del(primary, slot_back)
else
player.put_in_any_hand_if_possible(primary)
//If they got a projectile gun, give them a little bit of spare ammo
equip_ammo(player, primary)
if(holster)
var/obj/item/clothing/under/uniform = player.w_uniform
if(istype(uniform) && uniform.can_attach_accessory(holster))
uniform.attackby(holster, player)
else
player.put_in_any_hand_if_possible(holster)
/datum/antagonist/raider/proc/equip_ammo(var/mob/living/carbon/human/player, var/obj/item/weapon/gun/gun)
if(istype(gun, /obj/item/weapon/gun/projectile))
var/obj/item/weapon/gun/projectile/bullet_thrower = gun
if(bullet_thrower.magazine_type)
player.equip_to_slot_or_del(new bullet_thrower.magazine_type(player), slot_l_store)
if(prob(20)) //don't want to give them too much
player.equip_to_slot_or_del(new bullet_thrower.magazine_type(player), slot_r_store)
else if(bullet_thrower.ammo_type)
var/obj/item/weapon/storage/box/ammobox = new(get_turf(player.loc))
for(var/i in 1 to rand(3,5) + rand(0,2))
new bullet_thrower.ammo_type(ammobox)
player.put_in_any_hand_if_possible(ammobox)
return
if(istype(gun, /obj/item/weapon/gun/launcher/grenade))
var/list/grenades = list(
/obj/item/weapon/grenade/empgrenade,
/obj/item/weapon/grenade/smokebomb,
/obj/item/weapon/grenade/flashbang
)
var/obj/item/weapon/storage/box/ammobox = new(get_turf(player.loc))
for(var/i in 1 to 7)
var/grenade_type = pick(grenades)
new grenade_type(ammobox)
player.put_in_any_hand_if_possible(ammobox)
/datum/antagonist/raider/proc/equip_vox(var/mob/living/carbon/human/player) /datum/antagonist/raider/proc/equip_vox(var/mob/living/carbon/human/player)
var/uniform_type = pick(list(/obj/item/clothing/under/vox/vox_robes,/obj/item/clothing/under/vox/vox_casual)) var/uniform_type = pick(list(/obj/item/clothing/under/vox/vox_robes,/obj/item/clothing/under/vox/vox_casual))

View File

@@ -96,7 +96,7 @@ var/datum/antagonist/wizard/wizards
world << "<span class='danger'><font size = 3>The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!</font></span>" world << "<span class='danger'><font size = 3>The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!</font></span>"
//To batch-remove wizard spells. Linked to mind.dm. //To batch-remove wizard spells. Linked to mind.dm.
/mob/proc/spellremove(var/mob/M as mob) /mob/proc/spellremove()
for(var/spell/spell_to_remove in src.spell_list) for(var/spell/spell_to_remove in src.spell_list)
remove_spell(spell_to_remove) remove_spell(spell_to_remove)

View File

@@ -6,12 +6,13 @@ var/datum/antagonist/rogue_ai/malf
role_text = "Rampant AI" role_text = "Rampant AI"
role_text_plural = "Rampant AIs" role_text_plural = "Rampant AIs"
mob_path = /mob/living/silicon/ai mob_path = /mob/living/silicon/ai
landmark_id = "AI"
welcome_text = "You are malfunctioning! You do not have to follow any laws." welcome_text = "You are malfunctioning! You do not have to follow any laws."
victory_text = "The AI has taken control of all of the station's systems." victory_text = "The AI has taken control of all of the station's systems."
loss_text = "The AI has been shut down!" loss_text = "The AI has been shut down!"
flags = ANTAG_VOTABLE | ANTAG_RANDSPAWN //Randspawn needed otherwise it won't start at all. flags = ANTAG_VOTABLE | ANTAG_OVERRIDE_MOB | ANTAG_OVERRIDE_JOB | ANTAG_CHOOSE_NAME
max_antags = 1 max_antags = 1
max_antags_round = 3 max_antags_round = 1
/datum/antagonist/rogue_ai/New() /datum/antagonist/rogue_ai/New()
@@ -22,7 +23,7 @@ var/datum/antagonist/rogue_ai/malf
/datum/antagonist/rogue_ai/get_candidates() /datum/antagonist/rogue_ai/get_candidates()
..() ..()
for(var/datum/mind/player in candidates) for(var/datum/mind/player in candidates)
if(player.assigned_role != "AI") if(player.assigned_role && player.assigned_role != "AI")
candidates -= player candidates -= player
if(!candidates.len) if(!candidates.len)
return list() return list()
@@ -75,3 +76,26 @@ var/datum/antagonist/rogue_ai/malf
malf << "For basic information about your abilities use command display-help" malf << "For basic information about your abilities use command display-help"
malf << "You may choose one special hardware piece to help you. This cannot be undone." malf << "You may choose one special hardware piece to help you. This cannot be undone."
malf << "Good luck!" malf << "Good luck!"
/datum/antagonist/rogue_ai/update_antag_mob(var/datum/mind/player, var/preserve_appearance)
// Get the mob.
if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path))))
var/mob/holder = player.current
player.current = new mob_path(get_turf(player.current), null, null, 1)
player.transfer_to(player.current)
if(holder) qdel(holder)
player.original = player.current
return player.current
/datum/antagonist/rogue_ai/set_antag_name(var/mob/living/silicon/player)
if(!istype(player))
testing("rogue_ai set_antag_name called on non-silicon mob [player]!")
return
// Choose a name, if any.
var/newname = sanitize(input(player, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN)
if (newname)
player.SetName(newname)
if(player.mind) player.mind.name = player.name

View File

@@ -26,7 +26,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon = 'icons/turf/areas.dmi' icon = 'icons/turf/areas.dmi'
icon_state = "unknown" icon_state = "unknown"
layer = 10 layer = 10
luminosity = 1 luminosity = 0
mouse_opacity = 0 mouse_opacity = 0
var/lightswitch = 1 var/lightswitch = 1
@@ -34,7 +34,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/debug = 0 var/debug = 0
var/requires_power = 1 var/requires_power = 1
var/unlimited_power = 0
var/always_unpowered = 0 //this gets overriden to 1 for space in area/New() var/always_unpowered = 0 //this gets overriden to 1 for space in area/New()
var/power_equip = 1 var/power_equip = 1
@@ -349,7 +348,6 @@ area/space/atmosalert()
name = "\improper Centcom" name = "\improper Centcom"
icon_state = "centcom" icon_state = "centcom"
requires_power = 0 requires_power = 0
unlimited_power = 1
lighting_use_dynamic = 0 lighting_use_dynamic = 0
/area/centcom/control /area/centcom/control
@@ -388,7 +386,6 @@ area/space/atmosalert()
name = "\improper Mercenary Base" name = "\improper Mercenary Base"
icon_state = "syndie-ship" icon_state = "syndie-ship"
requires_power = 0 requires_power = 0
unlimited_power = 1
lighting_use_dynamic = 0 lighting_use_dynamic = 0
/area/syndicate_mothership/control /area/syndicate_mothership/control
@@ -463,7 +460,6 @@ area/space/atmosalert()
name = "\improper Independant Station" name = "\improper Independant Station"
icon_state = "yellow" icon_state = "yellow"
requires_power = 0 requires_power = 0
unlimited_power = 1
flags = RAD_SHIELDED flags = RAD_SHIELDED
/area/syndicate_station/start /area/syndicate_station/start
@@ -518,6 +514,7 @@ area/space/atmosalert()
name = "\improper Wizard's Den" name = "\improper Wizard's Den"
icon_state = "yellow" icon_state = "yellow"
requires_power = 0 requires_power = 0
lighting_use_dynamic = 0
/area/skipjack_station/transit /area/skipjack_station/transit
@@ -904,7 +901,7 @@ area/space/atmosalert()
icon_state = "tcomsatcham" icon_state = "tcomsatcham"
/area/server /area/server
name = "\improper Messaging Server Room" name = "\improper Research Server Room"
icon_state = "server" icon_state = "server"
//Crew //Crew
@@ -1812,7 +1809,7 @@ area/space/atmosalert()
ambience = list('sound/ambience/ambimalf.ogg') ambience = list('sound/ambience/ambimalf.ogg')
/area/turret_protected/ai_server_room /area/turret_protected/ai_server_room
name = "AI Server Room" name = "Messaging Server Room"
icon_state = "ai_server" icon_state = "ai_server"
/area/turret_protected/ai /area/turret_protected/ai

View File

@@ -14,13 +14,17 @@
all_areas += src all_areas += src
if(!requires_power) if(!requires_power)
power_light = 0 //rastaf0 power_light = 0
power_equip = 0 //rastaf0 power_equip = 0
power_environ = 0 //rastaf0 power_environ = 0
..() ..()
// spawn(15) /area/proc/initialize()
if(!requires_power || !apc)
power_light = 0
power_equip = 0
power_environ = 0
power_change() // all machines set to current power level, also updates lighting icon power_change() // all machines set to current power level, also updates lighting icon
/area/proc/get_contents() /area/proc/get_contents()
@@ -227,7 +231,7 @@ var/list/mob/living/forced_ambiance_list = new
var/area/oldarea = L.lastarea var/area/oldarea = L.lastarea
if((oldarea.has_gravity == 0) && (newarea.has_gravity == 1) && (L.m_intent == "run")) // Being ready when you change areas gives you a chance to avoid falling all together. if((oldarea.has_gravity == 0) && (newarea.has_gravity == 1) && (L.m_intent == "run")) // Being ready when you change areas gives you a chance to avoid falling all together.
thunk(L) thunk(L)
L.make_floating(0) L.update_floating( L.Check_Dense_Object() )
L.lastarea = newarea L.lastarea = newarea
play_ambience(L) play_ambience(L)
@@ -260,21 +264,10 @@ var/list/mob/living/forced_ambiance_list = new
/area/proc/gravitychange(var/gravitystate = 0, var/area/A) /area/proc/gravitychange(var/gravitystate = 0, var/area/A)
A.has_gravity = gravitystate A.has_gravity = gravitystate
if(gravitystate) for(var/mob/M in A)
for(var/mob/living/carbon/human/M in A) if(has_gravity)
thunk(M) thunk(M)
for(var/mob/M1 in A) M.update_floating( M.Check_Dense_Object() )
M1.make_floating(0)
else
for(var/mob/M in A)
if(M.Check_Dense_Object() && istype(src,/mob/living/carbon/human/))
var/mob/living/carbon/human/H = src
if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP)) //magboots + dense_object = no floaty effect
H.make_floating(0)
else
H.make_floating(1)
else
M.make_floating(1)
/area/proc/thunk(mob) /area/proc/thunk(mob)
if(istype(get_turf(mob), /turf/space)) // Can't fall onto nothing. if(istype(get_turf(mob), /turf/space)) // Can't fall onto nothing.

View File

@@ -63,9 +63,6 @@
return flags & INSERT_CONTAINER return flags & INSERT_CONTAINER
*/ */
/atom/proc/allow_drop()
return 1
/atom/proc/CheckExit() /atom/proc/CheckExit()
return 1 return 1

View File

@@ -164,7 +164,7 @@
a = get_area(src.loc) a = get_area(src.loc)
else else
var/error = dist_y/2 - dist_x var/error = dist_y/2 - dist_x
while(src && target &&((((src.y < target.y && dy == NORTH) || (src.y > target.y && dy == SOUTH)) && dist_travelled < range) || (a.has_gravity == 0) || istype(src.loc, /turf/space)) && src.throwing && istype(src.loc, /turf)) while(src && target &&((((src.y < target.y && dy == NORTH) || (src.y > target.y && dy == SOUTH)) && dist_travelled < range) || (a && a.has_gravity == 0) || istype(src.loc, /turf/space)) && src.throwing && istype(src.loc, /turf))
// only stop when we've gone the whole distance (or max throw range) and are on a non-space tile, or hit something, or hit the end of the map, or someone picks it up // only stop when we've gone the whole distance (or max throw range) and are on a non-space tile, or hit something, or hit the end of the map, or someone picks it up
if(error < 0) if(error < 0)
var/atom/step = get_step(src, dx) var/atom/step = get_step(src, dx)

View File

@@ -64,9 +64,6 @@
component_parts += new /obj/item/stack/cable_coil(src) component_parts += new /obj/item/stack/cable_coil(src)
RefreshParts() RefreshParts()
/obj/machinery/dna_scannernew/allow_drop()
return 0
/obj/machinery/dna_scannernew/relaymove(mob/user as mob) /obj/machinery/dna_scannernew/relaymove(mob/user as mob)
if (user.stat) if (user.stat)
return return

View File

@@ -193,7 +193,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
src << "<span class='warning'>This creature's DNA is ruined beyond useability!</span>" src << "<span class='warning'>This creature's DNA is ruined beyond useability!</span>"
return return
if(!G.state == GRAB_KILL) if(G.state != GRAB_KILL)
src << "<span class='warning'>We must have a tighter grip to absorb this creature.</span>" src << "<span class='warning'>We must have a tighter grip to absorb this creature.</span>"
return return

View File

@@ -121,7 +121,7 @@ var/list/datum/power/changeling/powerinstances = list()
/datum/power/changeling/DeathSting /datum/power/changeling/DeathSting
name = "Death Sting" name = "Death Sting"
desc = "We silently sting a human, filling him with potent chemicals. His rapid death is all but assured." desc = "We silently sting a human, filling them with potent chemicals. Their rapid death is all but assured."
genomecost = 10 genomecost = 10
verbpath = /mob/proc/changeling_DEATHsting verbpath = /mob/proc/changeling_DEATHsting

View File

@@ -63,19 +63,10 @@
..() ..()
/obj/machinery/door/cultify() /obj/machinery/door/cultify()
icon_state = "null" if(invisibility != INVISIBILITY_MAXIMUM)
density = 0 invisibility = INVISIBILITY_MAXIMUM
c_animation = new /atom/movable/overlay(src.loc) density = 0
c_animation.name = "cultification" anim(target = src, a_icon = 'icons/effects/effects.dmi', a_icon_state = "breakdoor", sleeptime = 10)
c_animation.density = 0
c_animation.anchored = 1
c_animation.icon = 'icons/effects/effects.dmi'
c_animation.layer = 5
c_animation.master = src.loc
c_animation.icon_state = "breakdoor"
flick("cultification",c_animation)
spawn(10)
qdel(c_animation)
qdel(src) qdel(src)
/obj/machinery/door/firedoor/cultify() /obj/machinery/door/firedoor/cultify()
@@ -145,8 +136,8 @@
// Make it a wood-reinforced wooden table. // Make it a wood-reinforced wooden table.
// There are cult materials available, but it'd make the table non-deconstructable with how holotables work. // There are cult materials available, but it'd make the table non-deconstructable with how holotables work.
// Could possibly use a new material var for holographic-ness? // Could possibly use a new material var for holographic-ness?
material = name_to_material["wood"] material = get_material_by_name("wood")
reinforced = name_to_material["wood"] reinforced = get_material_by_name("wood")
update_desc() update_desc()
update_connections(1) update_connections(1)
update_icon() update_icon()

View File

@@ -339,7 +339,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
attack(mob/living/M as mob, mob/living/user as mob) attack(mob/living/M as mob, mob/living/user as mob)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had the [name] used on him by [user.name] ([user.ckey])</font>") M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had the [name] used on them by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used [name] on [M.name] ([M.ckey])</font>") user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used [name] on [M.name] ([M.ckey])</font>")
msg_admin_attack("[user.name] ([user.ckey]) used [name] on [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)") msg_admin_attack("[user.name] ([user.ckey]) used [name] on [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")

View File

@@ -5,6 +5,14 @@ var/list/sacrificed = list()
/obj/effect/rune /obj/effect/rune
/*
* Use as a general guideline for this and related files:
* * <span class='warning'>...</span> - when something non-trivial or an error happens, so something similar to "Sparks come out of the machine!"
* * <span class='danger'>...</span> - when something that is fit for 'warning' happens but there is some damage or pain as well.
* * <span class='cult'>...</span> - when there is a private message to the cultists. This guideline is very arbitrary but there has to be some consistency!
*/
/////////////////////////////////////////FIRST RUNE /////////////////////////////////////////FIRST RUNE
proc proc
teleport(var/key) teleport(var/key)
@@ -21,7 +29,7 @@ var/list/sacrificed = list()
allrunesloc.len = index allrunesloc.len = index
allrunesloc[index] = R.loc allrunesloc[index] = R.loc
if(index >= 5) if(index >= 5)
user << "<span class='warning'>You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric</span>" user << "<span class='danger'>You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric.</span>"
if (istype(user, /mob/living)) if (istype(user, /mob/living))
user.take_overall_damage(5, 0) user.take_overall_damage(5, 0)
qdel(src) qdel(src)
@@ -30,9 +38,9 @@ var/list/sacrificed = list()
user.say("Sas[pick("'","`")]so c'arta forbici!")//Only you can stop auto-muting user.say("Sas[pick("'","`")]so c'arta forbici!")//Only you can stop auto-muting
else else
user.whisper("Sas[pick("'","`")]so c'arta forbici!") user.whisper("Sas[pick("'","`")]so c'arta forbici!")
user.visible_message("<span class='warning'>\The [user] disappears in a flash of red light!</span>", \ user.visible_message("<span class='danger'>[user] disappears in a flash of red light!</span>", \
"<span class='warning'>You feel as your body gets dragged through the dimension of Nar-Sie!</span>", \ "<span class='danger'>You feel as your body gets dragged through the dimension of Nar-Sie!</span>", \
"<span class='warning'>You hear a sickening crunch and sloshing of viscera.</span>") "<span class='danger'>You hear a sickening crunch and sloshing of viscera.</span>")
user.loc = allrunesloc[rand(1,index)] user.loc = allrunesloc[rand(1,index)]
return return
if(istype(src,/obj/effect/rune)) if(istype(src,/obj/effect/rune))
@@ -58,7 +66,7 @@ var/list/sacrificed = list()
IP = R IP = R
runecount++ runecount++
if(runecount >= 2) if(runecount >= 2)
user << "<span class='warning'>You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric</span>" user << "<span class='danger'>You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric.</span>"
if (istype(user, /mob/living)) if (istype(user, /mob/living))
user.take_overall_damage(5, 0) user.take_overall_damage(5, 0)
qdel(src) qdel(src)
@@ -134,11 +142,11 @@ var/list/sacrificed = list()
admin_attack_log(attacker, target, "Used a convert rune", "Was subjected to a convert rune", "used a convert rune on") admin_attack_log(attacker, target, "Used a convert rune", "Was subjected to a convert rune", "used a convert rune on")
switch(target.getFireLoss()) switch(target.getFireLoss())
if(0 to 25) if(0 to 25)
target << "<span class='danger'>Your blood boils as you force yourself to resist the corruption invading every corner of your mind.</span>" target << "<span class='cult'>Your blood boils as you force yourself to resist the corruption invading every corner of your mind.</span>"
if(25 to 45) if(25 to 45)
target << "<span class='danger'>Your blood boils and your body burns as the corruption further forces itself into your body and mind.</span>" target << "<span class='cult'>Your blood boils and your body burns as the corruption further forces itself into your body and mind.</span>"
if(45 to 75) if(45 to 75)
target << "<span class='danger'>You begin to hallucinate images of a dark and incomprehensible being and your entire body feels like its engulfed in flame as your mental defenses crumble.</span>" target << "<span class='cult'>You begin to hallucinate images of a dark and incomprehensible being and your entire body feels like its engulfed in flame as your mental defenses crumble.</span>"
target.apply_effect(rand(1,10), STUTTER) target.apply_effect(rand(1,10), STUTTER)
if(75 to 100) if(75 to 100)
target << "<span class='cult'>Your mind turns to ash as the burning flames engulf your very soul and images of an unspeakable horror begin to bombard the last remnants of mental resistance.</span>" target << "<span class='cult'>Your mind turns to ash as the burning flames engulf your very soul and images of an unspeakable horror begin to bombard the last remnants of mental resistance.</span>"
@@ -157,7 +165,7 @@ var/list/sacrificed = list()
if (target.species && (target.species.flags & NO_PAIN)) if (target.species && (target.species.flags & NO_PAIN))
target.visible_message("<span class='warning'>The markings below [target] glow a bloody red.</span>") target.visible_message("<span class='warning'>The markings below [target] glow a bloody red.</span>")
else else
target.visible_message("<span class='warning'>\The [target] writhes in pain as the markings below \him glow a bloody red.</span>", "<span class='danger'>AAAAAAHHHH!</span>", "<span class='warning'>You hear an anguished scream.</span>") target.visible_message("<span class='warning'>[target] writhes in pain as the markings below \him glow a bloody red.</span>", "<span class='danger'>AAAAAAHHHH!</span>", "<span class='warning'>You hear an anguished scream.</span>")
if(!waiting_for_input[target]) //so we don't spam them with dialogs if they hesitate if(!waiting_for_input[target]) //so we don't spam them with dialogs if they hesitate
waiting_for_input[target] = 1 waiting_for_input[target] = 1
@@ -229,15 +237,15 @@ var/list/sacrificed = list()
if(!drain) if(!drain)
return fizzle() return fizzle()
usr.say ("Yu[pick("'","`")]gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!") usr.say ("Yu[pick("'","`")]gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!")
usr.visible_message("<span class='warning'>Blood flows from the rune into [usr]!</span>", \ usr.visible_message("<span class='danger'>Blood flows from the rune into [usr]!</span>", \
"<span class='warning'>The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.</span>", \ "<span class='danger'>The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.</span>", \
"<span class='warning'>You hear a liquid flowing.</span>") "<span class='warning'>You hear a liquid flowing.</span>")
var/mob/living/user = usr var/mob/living/user = usr
if(user.bhunger) if(user.bhunger)
user.bhunger = max(user.bhunger-2*drain,0) user.bhunger = max(user.bhunger-2*drain,0)
if(drain>=50) if(drain>=50)
user.visible_message("<span class='warning'>\The [user]'s eyes give off eerie red glow!</span>", \ user.visible_message("<span class='danger'>[user]'s eyes give off eerie red glow!</span>", \
"<span class='warning'>...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.</span>", \ "<span class='danger'>...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.</span>", \
"<span class='warning'>You hear a heartbeat.</span>") "<span class='warning'>You hear a heartbeat.</span>")
user.bhunger += drain user.bhunger += drain
src = user src = user
@@ -264,7 +272,7 @@ var/list/sacrificed = list()
if(usr.loc==src.loc) if(usr.loc==src.loc)
if(usr.seer==1) if(usr.seer==1)
usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium viortia.") usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium viortia.")
usr << "<span class='warning'>The world beyond fades from your vision.</span>" usr << "<span class='danger'>The world beyond fades from your vision.</span>"
usr.see_invisible = SEE_INVISIBLE_LIVING usr.see_invisible = SEE_INVISIBLE_LIVING
usr.seer = 0 usr.seer = 0
else if(usr.see_invisible!=SEE_INVISIBLE_LIVING) else if(usr.see_invisible!=SEE_INVISIBLE_LIVING)
@@ -336,12 +344,12 @@ var/list/sacrificed = list()
corpse_to_raise.key = ghost.key //the corpse will keep its old mind! but a new player takes ownership of it (they are essentially possessed) corpse_to_raise.key = ghost.key //the corpse will keep its old mind! but a new player takes ownership of it (they are essentially possessed)
//This means, should that player leave the body, the original may re-enter //This means, should that player leave the body, the original may re-enter
usr.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!") usr.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!")
corpse_to_raise.visible_message("<span class='warning'>\The [corpse_to_raise]'s eyes glow with a faint red as he stands up, slowly starting to breathe again.</span>", \ corpse_to_raise.visible_message("<span class='warning'>[corpse_to_raise]'s eyes glow with a faint red as he stands up, slowly starting to breathe again.</span>", \
"<span class='warning'>Life... I'm alive again...</span>", \ "<span class='warning'>Life... I'm alive again...</span>", \
"<span class='warning'>You hear a faint, slightly familiar whisper.</span>") "<span class='warning'>You hear a faint, slightly familiar whisper.</span>")
body_to_sacrifice.visible_message("<span class='warning'>\The [body_to_sacrifice] is torn apart, a black smoke swiftly dissipating from his remains!</span>", \ body_to_sacrifice.visible_message("<span class='danger'>[body_to_sacrifice] is torn apart, a black smoke swiftly dissipating from \his remains!</span>", \
"<span class='warning'>You feel as your blood boils, tearing you apart.</span>", \ "<span class='danger'>You feel as your blood boils, tearing you apart.</span>", \
"<span class='warning'>You hear a thousand voices, all crying in pain.</span>") "<span class='danger'>You hear a thousand voices, all crying in pain.</span>")
body_to_sacrifice.gib() body_to_sacrifice.gib()
// if(ticker.mode.name == "cult") // if(ticker.mode.name == "cult")
@@ -349,8 +357,8 @@ var/list/sacrificed = list()
// else // else
// ticker.mode.cult |= corpse_to_raise.mind // ticker.mode.cult |= corpse_to_raise.mind
corpse_to_raise << "<font color=\"purple\"><b><i>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root.</b></i></font>" corpse_to_raise << "<span class='cult'>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root.</span>"
corpse_to_raise << "<font color=\"purple\"><b><i>Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.</b></i></font>" corpse_to_raise << "<span class='cult'>Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.</span>"
return return
@@ -391,7 +399,7 @@ var/list/sacrificed = list()
if(usr.loc==src.loc) if(usr.loc==src.loc)
var/mob/living/carbon/human/L = usr var/mob/living/carbon/human/L = usr
usr.say("Fwe[pick("'","`")]sh mah erl nyag r'ya!") usr.say("Fwe[pick("'","`")]sh mah erl nyag r'ya!")
usr.visible_message("<span class='warning'>\The [usr]'s eyes glow blue as \he freezes in place, absolutely motionless.</span>", \ usr.visible_message("<span class='warning'>[usr]'s eyes glow blue as \he freezes in place, absolutely motionless.</span>", \
"<span class='warning'>The shadow that is your spirit separates itself from your body. You are now in the realm beyond. While this is a great sight, being here strains your mind and body. Hurry...</span>", \ "<span class='warning'>The shadow that is your spirit separates itself from your body. You are now in the realm beyond. While this is a great sight, being here strains your mind and body. Hurry...</span>", \
"<span class='warning'>You hear only complete silence for a moment.</span>") "<span class='warning'>You hear only complete silence for a moment.</span>")
announce_ghost_joinleave(usr.ghostize(1), 1, "You feel that they had to use some [pick("dark", "black", "blood", "forgotten", "forbidden")] magic to [pick("invade","disturb","disrupt","infest","taint","spoil","blight")] this place!") announce_ghost_joinleave(usr.ghostize(1), 1, "You feel that they had to use some [pick("dark", "black", "blood", "forgotten", "forbidden")] magic to [pick("invade","disturb","disrupt","infest","taint","spoil","blight")] this place!")
@@ -461,8 +469,8 @@ var/list/sacrificed = list()
user.take_organ_damage(1, 0) user.take_organ_damage(1, 0)
sleep(30) sleep(30)
if(D) if(D)
D.visible_message("<span class='warning'>\The [D] slowly dissipates into dust and bones.</span>", \ D.visible_message("<span class='danger'>[D] slowly dissipates into dust and bones.</span>", \
"<span class='warning'>You feel pain, as bonds formed between your soul and this homunculus break.</span>", \ "<span class='danger'>You feel pain, as bonds formed between your soul and this homunculus break.</span>", \
"<span class='warning'>You hear faint rustle.</span>") "<span class='warning'>You hear faint rustle.</span>")
D.dust() D.dust()
return return
@@ -560,8 +568,8 @@ var/list/sacrificed = list()
user.say("Uhrast ka'hfa heldsagen ver[pick("'","`")]lot!") user.say("Uhrast ka'hfa heldsagen ver[pick("'","`")]lot!")
user.take_overall_damage(200, 0) user.take_overall_damage(200, 0)
runedec+=10 runedec+=10
user.visible_message("<span class='warning'>\The [user] keels over dead, his blood glowing blue as it escapes his body and dissipates into thin air.</span>", \ user.visible_message("<span class='danger'>\The [user] keels over dead, \his blood glowing blue as it escapes \his body and dissipates into thin air.</span>", \
"<span class='warning'>In the last moment of your humble life, you feel an immense pain as fabric of reality mends... with your blood.</span>", \ "<span class='danger'>In the last moment of your humble life, you feel an immense pain as fabric of reality mends... with your blood.</span>", \
"<span class='warning'>You hear faint rustle.</span>") "<span class='warning'>You hear faint rustle.</span>")
for(,user.stat==2) for(,user.stat==2)
sleep(600) sleep(600)
@@ -592,9 +600,10 @@ var/list/sacrificed = list()
usr.whisper("[input]") usr.whisper("[input]")
input = sanitize(input) input = sanitize(input)
log_and_message_admins("used a communicate rune to say '[input]'")
for(var/datum/mind/H in cult.current_antagonists) for(var/datum/mind/H in cult.current_antagonists)
if (H.current) if (H.current)
H.current << "<span class='danger'>[input]</span>" H.current << "<span class='cult'>[input]</span>"
qdel(src) qdel(src)
return 1 return 1
@@ -638,17 +647,17 @@ var/list/sacrificed = list()
H.dust()//To prevent the MMI from remaining H.dust()//To prevent the MMI from remaining
else else
H.gib() H.gib()
usr << "<span class='warning'>The Geometer of Blood accepts this sacrifice, your objective is now complete.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice, your objective is now complete.</span>"
else else
usr << "<span class='warning'>Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual.</span>" usr << "<span class='warning'>Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual.</span>"
else else
if(cultsinrange.len >= 3) if(cultsinrange.len >= 3)
if(H.stat !=2) if(H.stat !=2)
if(prob(80) || worth) if(prob(80) || worth)
usr << "<span class='warning'>The Geometer of Blood accepts this [worth ? "exotic " : ""]sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this [worth ? "exotic " : ""]sacrifice.</span>"
cult.grant_runeword(usr) cult.grant_runeword(usr)
else else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, this soul was not enough to gain His favor.</span>" usr << "<span class='warning'>However, this soul was not enough to gain His favor.</span>"
if(isrobot(H)) if(isrobot(H))
H.dust()//To prevent the MMI from remaining H.dust()//To prevent the MMI from remaining
@@ -656,10 +665,10 @@ var/list/sacrificed = list()
H.gib() H.gib()
else else
if(prob(40) || worth) if(prob(40) || worth)
usr << "<span class='warning'>The Geometer of blood accepts this [worth ? "exotic " : ""]sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this [worth ? "exotic " : ""]sacrifice.</span>"
cult.grant_runeword(usr) cult.grant_runeword(usr)
else else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>" usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>"
if(isrobot(H)) if(isrobot(H))
H.dust()//To prevent the MMI from remaining H.dust()//To prevent the MMI from remaining
@@ -671,10 +680,10 @@ var/list/sacrificed = list()
else else
if(prob(40)) if(prob(40))
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
cult.grant_runeword(usr) cult.grant_runeword(usr)
else else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>" usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>"
if(isrobot(H)) if(isrobot(H))
H.dust()//To prevent the MMI from remaining H.dust()//To prevent the MMI from remaining
@@ -684,10 +693,10 @@ var/list/sacrificed = list()
if(cultsinrange.len >= 3) if(cultsinrange.len >= 3)
if(H.stat !=2) if(H.stat !=2)
if(prob(80)) if(prob(80))
usr << "<span class='warning'>The Geometer of Blood accepts this sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
cult.grant_runeword(usr) cult.grant_runeword(usr)
else else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, this soul was not enough to gain His favor.</span>" usr << "<span class='warning'>However, this soul was not enough to gain His favor.</span>"
if(isrobot(H)) if(isrobot(H))
H.dust()//To prevent the MMI from remaining H.dust()//To prevent the MMI from remaining
@@ -695,10 +704,10 @@ var/list/sacrificed = list()
H.gib() H.gib()
else else
if(prob(40)) if(prob(40))
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
cult.grant_runeword(usr) cult.grant_runeword(usr)
else else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>" usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>"
if(isrobot(H)) if(isrobot(H))
H.dust()//To prevent the MMI from remaining H.dust()//To prevent the MMI from remaining
@@ -709,10 +718,10 @@ var/list/sacrificed = list()
usr << "<span class='warning'>The victim is still alive, you will need more cultists chanting for the sacrifice to succeed.</span>" usr << "<span class='warning'>The victim is still alive, you will need more cultists chanting for the sacrifice to succeed.</span>"
else else
if(prob(40)) if(prob(40))
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
cult.grant_runeword(usr) cult.grant_runeword(usr)
else else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>" usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>" usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>"
if(isrobot(H)) if(isrobot(H))
H.dust()//To prevent the MMI from remaining H.dust()//To prevent the MMI from remaining
@@ -771,9 +780,9 @@ var/list/sacrificed = list()
var/mob/living/user = usr var/mob/living/user = usr
user.take_organ_damage(2, 0) user.take_organ_damage(2, 0)
if(src.density) if(src.density)
usr << "<span class='warning'>Your blood flows into the rune, and you feel that the very space over the rune thickens.</span>" usr << "<span class='danger'>Your blood flows into the rune, and you feel that the very space over the rune thickens.</span>"
else else
usr << "<span class='warning'>Your blood flows into the rune, and you feel as the rune releases its grasp on space.</span>" usr << "<span class='danger'>Your blood flows into the rune, and you feel as the rune releases its grasp on space.</span>"
return return
/////////////////////////////////////////EIGHTTEENTH RUNE /////////////////////////////////////////EIGHTTEENTH RUNE
@@ -842,7 +851,7 @@ var/list/sacrificed = list()
if (cultist == user) //just to be sure. if (cultist == user) //just to be sure.
return return
if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet))) if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet)))
user << "<span class='warning'>You cannot summon \the [cultist], for his shackles of blood are strong.</span>" user << "<span class='warning'>You cannot summon \the [cultist], for \his shackles of blood are strong.</span>"
return fizzle() return fizzle()
cultist.loc = src.loc cultist.loc = src.loc
cultist.lying = 1 cultist.lying = 1
@@ -922,7 +931,7 @@ var/list/sacrificed = list()
C.disabilities |= NEARSIGHTED C.disabilities |= NEARSIGHTED
if(prob(10)) if(prob(10))
C.sdisabilities |= BLIND C.sdisabilities |= BLIND
C.show_message("<span class='warning'>Suddenly you see red flash that blinds you.</span>", 3) C.show_message("<span class='warning'>Suddenly you see a red flash that blinds you.</span>", 3)
affected += C affected += C
if(affected.len) if(affected.len)
usr.say("Sti[pick("'","`")] kaliesin!") usr.say("Sti[pick("'","`")] kaliesin!")
@@ -972,7 +981,7 @@ var/list/sacrificed = list()
if(N) if(N)
continue continue
M.take_overall_damage(51,51) M.take_overall_damage(51,51)
M << "<span class='warning'>Your blood boils!</span>" M << "<span class='danger'>Your blood boils!</span>"
victims += M victims += M
if(prob(5)) if(prob(5))
spawn(5) spawn(5)
@@ -1004,16 +1013,16 @@ var/list/sacrificed = list()
for(var/mob/living/M in orange(2,R)) for(var/mob/living/M in orange(2,R))
M.take_overall_damage(0,15) M.take_overall_damage(0,15)
if (R.invisibility>M.see_invisible) if (R.invisibility>M.see_invisible)
M << "<span class='warning'>Aargh it burns!</span>" M << "<span class='danger'>Aargh it burns!</span>"
else else
M << "<span class='warning'>Rune suddenly ignites, burning you!</span>" M << "<span class='danger'>Rune suddenly ignites, burning you!</span>"
var/turf/T = get_turf(R) var/turf/T = get_turf(R)
T.hotspot_expose(700,125) T.hotspot_expose(700,125)
for(var/obj/effect/decal/cleanable/blood/B in world) for(var/obj/effect/decal/cleanable/blood/B in world)
if(B.blood_DNA == src.blood_DNA) if(B.blood_DNA == src.blood_DNA)
for(var/mob/living/M in orange(1,B)) for(var/mob/living/M in orange(1,B))
M.take_overall_damage(0,5) M.take_overall_damage(0,5)
M << "<span class='warning'>Blood suddenly ignites, burning you!</span>" M << "<span class='danger'>Blood suddenly ignites, burning you!</span>"
var/turf/T = get_turf(B) var/turf/T = get_turf(B)
T.hotspot_expose(700,125) T.hotspot_expose(700,125)
qdel(B) qdel(B)
@@ -1032,13 +1041,13 @@ var/list/sacrificed = list()
C.stuttering = 1 C.stuttering = 1
C.Weaken(1) C.Weaken(1)
C.Stun(1) C.Stun(1)
C.show_message("<span class='warning'>The rune explodes in a bright flash.</span>", 3) C.show_message("<span class='danger'>The rune explodes in a bright flash.</span>", 3)
admin_attack_log(usr, C, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") admin_attack_log(usr, C, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on")
else if(issilicon(L)) else if(issilicon(L))
var/mob/living/silicon/S = L var/mob/living/silicon/S = L
S.Weaken(5) S.Weaken(5)
S.show_message("<span class='warning'>BZZZT... The rune has exploded in a bright flash.</span>", 3) S.show_message("<span class='danger'>BZZZT... The rune has exploded in a bright flash.</span>", 3)
admin_attack_log(usr, S, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") admin_attack_log(usr, S, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on")
qdel(src) qdel(src)
else ///When invoked as talisman, stun and mute the target mob. else ///When invoked as talisman, stun and mute the target mob.
@@ -1046,10 +1055,10 @@ var/list/sacrificed = list()
var/obj/item/weapon/nullrod/N = locate() in T var/obj/item/weapon/nullrod/N = locate() in T
if(N) if(N)
for(var/mob/O in viewers(T, null)) for(var/mob/O in viewers(T, null))
O.show_message("<span class='danger'>\The [usr] invokes a talisman at [T], but they are unaffected!</span>", 1) O.show_message(text("<span class='warning'><B>[] invokes a talisman at [], but they are unaffected!</B></span>", usr, T), 1)
else else
for(var/mob/O in viewers(T, null)) for(var/mob/O in viewers(T, null))
O.show_message("<span class='danger'>\The [usr] invokes a talisman at [T]</span>", 1) O.show_message(text("<span class='warning'><B>[] invokes a talisman at []</B></span>", usr, T), 1)
if(issilicon(T)) if(issilicon(T))
T.Weaken(15) T.Weaken(15)

View File

@@ -79,10 +79,9 @@ The access requirements on the Asteroid Shuttles' consoles have now been revoked
C.req_access = list() C.req_access = list()
C.req_one_access = list() C.req_one_access = list()
sleep(5 MINUTES) spawn(5 MINUTES)
ticker.station_explosion_cinematic(0,null) // TODO: Custom cinematic ticker.station_explosion_cinematic(0,null) // TODO: Custom cinematic
universe_has_ended = 1
universe_has_ended = 1
return return
/datum/universal_state/supermatter_cascade/proc/AreaSet() /datum/universal_state/supermatter_cascade/proc/AreaSet()

View File

@@ -166,12 +166,14 @@ var/global/list/additional_antag_types = list()
if(!(antag_templates && antag_templates.len)) if(!(antag_templates && antag_templates.len))
return 1 return 1
// Attempt to mark folks down as ready to go. Don't finalize until post setup.
var/datum/antagonist/main_antags = antag_templates[1] var/datum/antagonist/main_antags = antag_templates[1]
var/list/candidates = main_antags.get_candidates() var/list/potential
if(candidates.len >= required_enemies) if(main_antags.flags & ANTAG_OVERRIDE_JOB)
for(var/datum/antagonist/antag in antag_templates) potential = main_antags.pending_antagonists
antag.attempt_spawn() else
potential = main_antags.candidates
if(potential.len >= required_enemies)
return 1 return 1
return 0 return 0
@@ -185,6 +187,14 @@ var/global/list/additional_antag_types = list()
var/datum/event_container/EMajor = event_manager.event_containers[EVENT_LEVEL_MAJOR] var/datum/event_container/EMajor = event_manager.event_containers[EVENT_LEVEL_MAJOR]
EMajor.delay_modifier = event_delay_mod_major EMajor.delay_modifier = event_delay_mod_major
/datum/game_mode/proc/pre_setup()
for(var/datum/antagonist/antag in antag_templates)
antag.build_candidate_list() //compile a list of all eligible candidates
//antag roles that replace jobs need to be assigned before the job controller hands out jobs.
if(antag.flags & ANTAG_OVERRIDE_JOB)
antag.attempt_spawn() //select antags to be spawned
///post_setup() ///post_setup()
/datum/game_mode/proc/post_setup() /datum/game_mode/proc/post_setup()
@@ -198,11 +208,13 @@ var/global/list/additional_antag_types = list()
spawn(rand(100,150)) spawn(rand(100,150))
announce_ert_disabled() announce_ert_disabled()
if(antag_templates && antag_templates.len) //Assign all antag types for this game mode. Any players spawned as antags earlier should have been removed from the pending list, so no need to worry about those.
for(var/datum/antagonist/antag in antag_templates) for(var/datum/antagonist/antag in antag_templates)
antag.finalize_spawn() if(!(antag.flags & ANTAG_OVERRIDE_JOB))
if(antag.is_latejoin_template()) antag.attempt_spawn() //select antags to be spawned
latejoin_templates |= antag antag.finalize_spawn() //actually spawn antags
if(antag.is_latejoin_template())
latejoin_templates |= antag
if(emergency_shuttle && auto_recall_shuttle) if(emergency_shuttle && auto_recall_shuttle)
emergency_shuttle.auto_recall = 1 emergency_shuttle.auto_recall = 1
@@ -213,6 +225,10 @@ var/global/list/additional_antag_types = list()
feedback_set_details("server_ip","[world.internet_address]:[world.port]") feedback_set_details("server_ip","[world.internet_address]:[world.port]")
return 1 return 1
/datum/game_mode/proc/fail_setup()
for(var/datum/antagonist/antag in antag_templates)
antag.reset()
/datum/game_mode/proc/announce_ert_disabled() /datum/game_mode/proc/announce_ert_disabled()
if(!ert_disabled) if(!ert_disabled)
return return
@@ -391,7 +407,7 @@ var/global/list/additional_antag_types = list()
suspects += man suspects += man
for(var/mob/M in suspects) for(var/mob/M in suspects)
if(M.mind.assigned_role == "MODE") if(player_is_antag(M.mind, only_offstation_roles = 1))
continue continue
switch(rand(1, 100)) switch(rand(1, 100))
if(1 to 50) if(1 to 50)

View File

@@ -91,11 +91,14 @@ var/global/datum/controller/gameticker/ticker
else else
src.mode = config.pick_mode(master_mode) src.mode = config.pick_mode(master_mode)
src.mode.pre_setup()
job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly. job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly.
if(!mode_started && !src.mode.can_start()) if(!mode_started && !src.mode.can_start())
world << "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby." world << "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby."
current_state = GAME_STATE_PREGAME current_state = GAME_STATE_PREGAME
mode.fail_setup()
mode = null mode = null
job_master.ResetOccupations() job_master.ResetOccupations()
return 0 return 0
@@ -110,6 +113,7 @@ var/global/datum/controller/gameticker/ticker
else else
src.mode.announce() src.mode.announce()
setup_economy()
current_state = GAME_STATE_PLAYING current_state = GAME_STATE_PLAYING
create_characters() //Create player characters and transfer them create_characters() //Create player characters and transfer them
collect_minds() collect_minds()
@@ -118,9 +122,6 @@ var/global/datum/controller/gameticker/ticker
callHook("roundstart") callHook("roundstart")
//here to initialize the random events nicely at round start
setup_economy()
shuttle_controller.setup_shuttle_docks() shuttle_controller.setup_shuttle_docks()
spawn(0)//Forking here so we dont have to wait for this to finish spawn(0)//Forking here so we dont have to wait for this to finish
@@ -288,7 +289,7 @@ var/global/datum/controller/gameticker/ticker
if(player && player.mind && player.mind.assigned_role) if(player && player.mind && player.mind.assigned_role)
if(player.mind.assigned_role == "Captain") if(player.mind.assigned_role == "Captain")
captainless=0 captainless=0
if(player.mind.assigned_role != "MODE") if(!player_is_antag(player.mind, only_offstation_roles = 1))
job_master.EquipRank(player, player.mind.assigned_role, 0) job_master.EquipRank(player, player.mind.assigned_role, 0)
UpdateFactionList(player) UpdateFactionList(player)
equip_custom_items(player) equip_custom_items(player)
@@ -342,7 +343,7 @@ var/global/datum/controller/gameticker/ticker
if(!delay_end) if(!delay_end)
world.Reboot() world.Reboot()
else else
world << "<span class='notice><b>An admin has delayed the round end</b></span>" world << "<span class='notice'><b>An admin has delayed the round end</b></span>"
else else
world << "<span class='notice'><b>An admin has delayed the round end</b></span>" world << "<span class='notice'><b>An admin has delayed the round end</b></span>"

View File

@@ -20,12 +20,3 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
if (skipjack && skipjack.returned_home) if (skipjack && skipjack.returned_home)
return 1 return 1
return 0 return 0
/datum/game_mode/heist/cleanup()
//the skipjack and everything in it have left and aren't coming back, so get rid of them.
var/area/skipjack = locate(/area/shuttle/skipjack/station)
for (var/mob/living/M in skipjack.contents)
//maybe send the player a message that they've gone home/been kidnapped? Someone responsible for vox lore should write that.
qdel(M)
for (var/obj/O in skipjack.contents)
qdel(O) //no hiding in lockers or anything

View File

@@ -54,7 +54,7 @@
"Small Prick" "Small Prick"
) )
// TODO: Update to new antagonist system.
/datum/intercept_text/proc/build(var/mode_type, datum/mind/correct_person) /datum/intercept_text/proc/build(var/mode_type, datum/mind/correct_person)
switch(mode_type) switch(mode_type)
if("revolution") if("revolution")
@@ -88,29 +88,6 @@
else else
return null return null
// NOTE: Commentted out was the code which showed the chance of someone being an antag. If you want to re-add it, just uncomment the code.
/*
/datum/intercept_text/proc/pick_mob()
var/list/dudes = list()
for(var/mob/living/carbon/human/man in player_list)
if (!man.mind) continue
if (man.mind.assigned_role=="MODE") continue
dudes += man
if(dudes.len==0)
return null
return pick(dudes)
/datum/intercept_text/proc/pick_fingerprints()
var/mob/living/carbon/human/dude = src.pick_mob()
//if (!dude) return pick_fingerprints() //who coded that is totally crasy or just a traitor. -- rastaf0
if(dude)
return num2text(md5(dude.dna.uni_identity))
else
return num2text(md5(num2text(rand(1,10000))))
*/
/datum/intercept_text/proc/get_suspect() /datum/intercept_text/proc/get_suspect()
var/list/dudes = list() var/list/dudes = list()
for(var/mob/living/carbon/human/man in player_list) if(man.client && man.client.prefs.nanotrasen_relation == COMPANY_OPPOSED) for(var/mob/living/carbon/human/man in player_list) if(man.client && man.client.prefs.nanotrasen_relation == COMPANY_OPPOSED)
@@ -205,32 +182,6 @@
var/cname = pick(src.changeling_names) var/cname = pick(src.changeling_names)
var/orgname1 = pick(src.org_names_1) var/orgname1 = pick(src.org_names_1)
var/orgname2 = pick(src.org_names_2) var/orgname2 = pick(src.org_names_2)
/*
var/changeling_name
var/changeling_job
var/prob_right_dude = rand(prob_correct_person_lower, prob_correct_person_higher)
var/prob_right_job = rand(prob_correct_job_lower, prob_correct_job_higher)
if(prob(prob_right_job))
if(correct_person)
if(correct_person:assigned_role=="MODE")
changeling_job = pick(joblist)
else
changeling_job = correct_person:assigned_role
else
changeling_job = pick(joblist)
if(prob(prob_right_dude) && ticker.mode == "changeling")
if(correct_person:assigned_role=="MODE")
changeling_name = correct_person:current
else
changeling_name = src.pick_mob()
else
changeling_name = src.pick_mob()
*/
src.text += "<BR><BR>We have received a report that a dangerous alien lifeform known only as \"[cname]\" may have infiltrated your crew. " src.text += "<BR><BR>We have received a report that a dangerous alien lifeform known only as \"[cname]\" may have infiltrated your crew. "
/*
src.text += "Our intelligence suggests a [prob_right_job]% chance that a [changeling_job] on board your station has been replaced by the alien. "
src.text += "Additionally, the report indicates a [prob_right_dude]% chance that [changeling_name] may have been in contact with the lifeform at a recent social gathering. "
*/
src.text += "These lifeforms are assosciated with the [orgname1] [orgname2] and may be attempting to acquire sensitive materials on their behalf. " src.text += "These lifeforms are assosciated with the [orgname1] [orgname2] and may be attempting to acquire sensitive materials on their behalf. "
src.text += "Please take care not to alarm the crew, as [cname] may take advantage of a panic situation. Remember, they can be anybody, suspect everybody!" src.text += "Please take care not to alarm the crew, as [cname] may take advantage of a panic situation. Remember, they can be anybody, suspect everybody!"

View File

@@ -1252,7 +1252,7 @@ datum
proc/find_target() proc/find_target()
..() ..()
if(target && target.current) if(target && target.current)
explanation_text = "[target.current.real_name], the [target.role_alt_title ? target.role_alt_title : target.assigned_role], has defied us for the last time. Make an example of him, and bring us his severed head." explanation_text = "[target.current.real_name], the [target.role_alt_title ? target.role_alt_title : target.assigned_role], has defied us for the last time. Make an example of [target.current.gender == MALE ? "him" : target.current.gender == FEMALE ? "her" : "them"], and bring us [target.current.gender == MALE ? "his" : target.current.gender == FEMALE ? "her" : "their"] severed head."
else else
explanation_text = "Free Objective" explanation_text = "Free Objective"
return target return target
@@ -1261,7 +1261,7 @@ datum
find_target_by_role(role, role_type=0) find_target_by_role(role, role_type=0)
..(role, role_type) ..(role, role_type)
if(target && target.current) if(target && target.current)
explanation_text = "[target.current.real_name], the [target.role_alt_title ? target.role_alt_title : (!role_type ? target.assigned_role : target.special_role)], has defied us for the last time. Make an example of him, and bring us his severed head." explanation_text = "[target.current.real_name], the [target.role_alt_title ? target.role_alt_title : (!role_type ? target.assigned_role : target.special_role)], has defied us for the last time. Make an example of [target.current.gender == MALE ? "him" : target.current.gender == FEMALE ? "her" : "them"], and bring us [target.current.gender == MALE ? "his" : target.current.gender == FEMALE ? "her" : "their"] severed head."
else else
explanation_text = "Free Objective" explanation_text = "Free Objective"
return target return target

View File

@@ -703,7 +703,7 @@ datum/objective/heist/kidnap
var/list/priority_targets = list() var/list/priority_targets = list()
for(var/datum/mind/possible_target in ticker.minds) for(var/datum/mind/possible_target in ticker.minds)
if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && (possible_target.assigned_role != "MODE")) if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && (!possible_target.special_role))
possible_targets += possible_target possible_targets += possible_target
for(var/role in roles) for(var/role in roles)
if(possible_target.assigned_role == role) if(possible_target.assigned_role == role)

View File

@@ -1,6 +1,6 @@
/datum/game_mode/wizard /datum/game_mode/wizard
name = "Wizard" name = "Wizard"
round_description = "There is a SPACE WIZARD on the station. You can't let them achieve their objectives!" round_description = "There is a SPACE WIZARD on the station. You can't let the magician achieve their objectives!"
extended_round_description = "A powerful entity capable of manipulating the elements around him, most commonly referred to as a 'wizard', has infiltrated the station. They have a wide variety of powers and spells available to them that makes your own simple moral self tremble with fear and excitement. Ultimately, their purpose is unknown. However, it is up to you and your crew to decide if their powers can be used for good or if their arrival foreshadows the destruction of the entire station." extended_round_description = "A powerful entity capable of manipulating the elements around him, most commonly referred to as a 'wizard', has infiltrated the station. They have a wide variety of powers and spells available to them that makes your own simple moral self tremble with fear and excitement. Ultimately, their purpose is unknown. However, it is up to you and your crew to decide if their powers can be used for good or if their arrival foreshadows the destruction of the entire station."
config_tag = "wizard" config_tag = "wizard"
required_players = 1 required_players = 1

View File

@@ -305,17 +305,8 @@
desc = "Cargo Office" desc = "Cargo Office"
region = ACCESS_REGION_SUPPLY region = ACCESS_REGION_SUPPLY
/var/const/access_mint = 51 // /var/const/free_access_id = 51
/datum/access/mint // /var/const/free_access_id = 52
id = access_mint
desc = "Mint"
region = ACCESS_REGION_SUPPLY
/var/const/access_mint_vault = 52
/datum/access/mint_vault
id = access_mint_vault
desc = "Mint Vault"
access_type = ACCESS_TYPE_NONE
/var/const/access_heads_vault = 53 /var/const/access_heads_vault = 53
/datum/access/heads_vault /datum/access/heads_vault

View File

@@ -11,7 +11,7 @@
economic_modifier = 1 economic_modifier = 1
access = list() //See /datum/job/assistant/get_access() access = list() //See /datum/job/assistant/get_access()
minimal_access = list() //See /datum/job/assistant/get_access() minimal_access = list() //See /datum/job/assistant/get_access()
alt_titles = list("Technical Assistant","Medical Intern","Research Assistant","Security Cadet","Visitor") alt_titles = list("Technical Assistant","Medical Intern","Research Assistant","Visitor")
/datum/job/assistant/equip(var/mob/living/carbon/human/H) /datum/job/assistant/equip(var/mob/living/carbon/human/H)
if(!H) return 0 if(!H) return 0

View File

@@ -98,8 +98,8 @@
supervisors = "the head of personnel" supervisors = "the head of personnel"
selection_color = "#dddddd" selection_color = "#dddddd"
economic_modifier = 5 economic_modifier = 5
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station) access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
minimal_access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station) minimal_access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
equip(var/mob/living/carbon/human/H) equip(var/mob/living/carbon/human/H)
@@ -125,7 +125,7 @@
spawn_positions = 2 spawn_positions = 2
supervisors = "the quartermaster and the head of personnel" supervisors = "the quartermaster and the head of personnel"
selection_color = "#dddddd" selection_color = "#dddddd"
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station) access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
minimal_access = list(access_maint_tunnels, access_cargo, access_cargo_bot, access_mailsorting) minimal_access = list(access_maint_tunnels, access_cargo, access_cargo_bot, access_mailsorting)
@@ -150,9 +150,9 @@
spawn_positions = 3 spawn_positions = 3
supervisors = "the quartermaster and the head of personnel" supervisors = "the quartermaster and the head of personnel"
selection_color = "#dddddd" selection_color = "#dddddd"
economic_modifier = 3 economic_modifier = 5
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station) access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
minimal_access = list(access_mining, access_mint, access_mining_station, access_mailsorting) minimal_access = list(access_mining, access_mining_station, access_mailsorting)
alt_titles = list("Drill Technician","Prospector") alt_titles = list("Drill Technician","Prospector")
equip(var/mob/living/carbon/human/H) equip(var/mob/living/carbon/human/H)

View File

@@ -26,6 +26,12 @@
/datum/job/proc/equip(var/mob/living/carbon/human/H) /datum/job/proc/equip(var/mob/living/carbon/human/H)
return 1 return 1
/datum/job/proc/equip_backpack(var/mob/living/carbon/human/H)
switch(H.backbag)
if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
/datum/job/proc/equip_survival(var/mob/living/carbon/human/H) /datum/job/proc/equip_survival(var/mob/living/carbon/human/H)
if(!H) return 0 if(!H) return 0
H.species.equip_survival_gear(H,0) H.species.equip_survival_gear(H,0)

View File

@@ -19,6 +19,10 @@
if(!H) return 0 if(!H) return 0
return 1 return 1
equip_backpack(var/mob/living/carbon/human/H)
if(!H) return 0
return 1
/datum/job/ai/is_position_available() /datum/job/ai/is_position_available()
return (empty_playable_ai_cores.len != 0) return (empty_playable_ai_cores.len != 0)
@@ -47,6 +51,10 @@
equip_survival(var/mob/living/carbon/human/H) equip_survival(var/mob/living/carbon/human/H)
if(!H) return 0 if(!H) return 0
return 1 return 1
equip_backpack(var/mob/living/carbon/human/H)
if(!H) return 0
return 1
return 1 return 1
/datum/job/cyborg/equip_preview(mob/living/carbon/human/H) /datum/job/cyborg/equip_preview(mob/living/carbon/human/H)

View File

@@ -348,7 +348,6 @@ var/global/datum/controller/occupations/job_master
proc/EquipRank(var/mob/living/carbon/human/H, var/rank, var/joined_late = 0) proc/EquipRank(var/mob/living/carbon/human/H, var/rank, var/joined_late = 0)
if(!H) return null if(!H) return null
var/datum/job/job = GetJob(rank) var/datum/job/job = GetJob(rank)
@@ -394,6 +393,7 @@ var/global/datum/controller/occupations/job_master
//Equip job items. //Equip job items.
job.equip(H) job.equip(H)
job.setup_account(H) job.setup_account(H)
job.equip_backpack(H)
job.equip_survival(H) job.equip_survival(H)
job.apply_fingerprints(H) job.apply_fingerprints(H)

View File

@@ -177,11 +177,6 @@
return return
return return
allow_drop()
return 0
process() process()
if (stat & (NOPOWER|BROKEN)) if (stat & (NOPOWER|BROKEN))
return return
@@ -342,7 +337,7 @@
if(src.occupant.reagents.get_reagent_amount(chemical) + amount <= 20) if(src.occupant.reagents.get_reagent_amount(chemical) + amount <= 20)
use_power(amount * CHEM_SYNTH_ENERGY) use_power(amount * CHEM_SYNTH_ENERGY)
src.occupant.reagents.add_reagent(chemical, amount) src.occupant.reagents.add_reagent(chemical, amount)
user << "Occupant now has [src.occupant.reagents.get_reagent_amount(chemical)] units of [available_chemicals[chemical]] in his/her bloodstream." user << "Occupant now has [src.occupant.reagents.get_reagent_amount(chemical)] units of [available_chemicals[chemical]] in their bloodstream."
return return
user << "There's no occupant in the sleeper or the subject has too many chemicals!" user << "There's no occupant in the sleeper or the subject has too many chemicals!"
return return

View File

@@ -14,9 +14,6 @@
idle_power_usage = 60 idle_power_usage = 60
active_power_usage = 10000 //10 kW. It's a big all-body scanner. active_power_usage = 10000 //10 kW. It's a big all-body scanner.
/*/obj/machinery/bodyscanner/allow_drop()
return 0*/
/obj/machinery/bodyscanner/relaymove(mob/user as mob) /obj/machinery/bodyscanner/relaymove(mob/user as mob)
if (user.stat) if (user.stat)
return return

View File

@@ -69,6 +69,7 @@
var/datum/radio_frequency/radio_connection var/datum/radio_frequency/radio_connection
var/list/TLV = list() var/list/TLV = list()
var/list/trace_gas = list("sleeping_agent", "volatile_fuel") //list of other gases that this air alarm is able to detect
var/danger_level = 0 var/danger_level = 0
var/pressure_dangerlevel = 0 var/pressure_dangerlevel = 0
@@ -240,23 +241,24 @@
/obj/machinery/alarm/proc/overall_danger_level(var/datum/gas_mixture/environment) /obj/machinery/alarm/proc/overall_danger_level(var/datum/gas_mixture/environment)
var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
var/environment_pressure = environment.return_pressure() var/environment_pressure = environment.return_pressure()
//var/other_moles = 0.0
////for(var/datum/gas/G in environment.trace_gases) var/other_moles = 0
// other_moles+=G.moles for(var/g in trace_gas)
other_moles += environment.gas[g] //this is only going to be used in a partial pressure calc, so we don't need to worry about group_multiplier here.
pressure_dangerlevel = get_danger_level(environment_pressure, TLV["pressure"]) pressure_dangerlevel = get_danger_level(environment_pressure, TLV["pressure"])
oxygen_dangerlevel = get_danger_level(environment.gas["oxygen"]*partial_pressure, TLV["oxygen"]) oxygen_dangerlevel = get_danger_level(environment.gas["oxygen"]*partial_pressure, TLV["oxygen"])
co2_dangerlevel = get_danger_level(environment.gas["carbon_dioxide"]*partial_pressure, TLV["carbon dioxide"]) co2_dangerlevel = get_danger_level(environment.gas["carbon_dioxide"]*partial_pressure, TLV["carbon dioxide"])
phoron_dangerlevel = get_danger_level(environment.gas["phoron"]*partial_pressure, TLV["phoron"]) phoron_dangerlevel = get_danger_level(environment.gas["phoron"]*partial_pressure, TLV["phoron"])
temperature_dangerlevel = get_danger_level(environment.temperature, TLV["temperature"]) temperature_dangerlevel = get_danger_level(environment.temperature, TLV["temperature"])
//other_dangerlevel = get_danger_level(other_moles*partial_pressure, TLV["other"]) other_dangerlevel = get_danger_level(other_moles*partial_pressure, TLV["other"])
return max( return max(
pressure_dangerlevel, pressure_dangerlevel,
oxygen_dangerlevel, oxygen_dangerlevel,
co2_dangerlevel, co2_dangerlevel,
phoron_dangerlevel, phoron_dangerlevel,
//other_dangerlevel, other_dangerlevel,
temperature_dangerlevel temperature_dangerlevel
) )
@@ -302,22 +304,30 @@
/obj/machinery/alarm/update_icon() /obj/machinery/alarm/update_icon()
if(wiresexposed) if(wiresexposed)
icon_state = "alarmx" icon_state = "alarmx"
set_light(0)
return return
if((stat & (NOPOWER|BROKEN)) || shorted) if((stat & (NOPOWER|BROKEN)) || shorted)
icon_state = "alarmp" icon_state = "alarmp"
set_light(0)
return return
var/icon_level = danger_level var/icon_level = danger_level
if (alarm_area.atmosalm) if (alarm_area.atmosalm)
icon_level = max(icon_level, 1) //if there's an atmos alarm but everything is okay locally, no need to go past yellow icon_level = max(icon_level, 1) //if there's an atmos alarm but everything is okay locally, no need to go past yellow
var/new_color = null
switch(icon_level) switch(icon_level)
if (0) if (0)
icon_state = "alarm0" icon_state = "alarm0"
new_color = "#03A728"
if (1) if (1)
icon_state = "alarm2" //yes, alarm2 is yellow alarm icon_state = "alarm2" //yes, alarm2 is yellow alarm
new_color = "#EC8B2F"
if (2) if (2)
icon_state = "alarm1" icon_state = "alarm1"
new_color = "#DA0205"
set_light(l_range = 2, l_power = 0.5, l_color = new_color)
/obj/machinery/alarm/receive_signal(datum/signal/signal) /obj/machinery/alarm/receive_signal(datum/signal/signal)
if(stat & (NOPOWER|BROKEN)) if(stat & (NOPOWER|BROKEN))
@@ -504,34 +514,13 @@
var/list/environment_data = new var/list/environment_data = new
data["has_environment"] = total data["has_environment"] = total
if(total) if(total)
var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
var/list/current_settings = TLV["pressure"]
var/pressure = environment.return_pressure() var/pressure = environment.return_pressure()
var/pressure_danger = get_danger_level(pressure, current_settings) environment_data[++environment_data.len] = list("name" = "Pressure", "value" = pressure, "unit" = "kPa", "danger_level" = pressure_dangerlevel)
environment_data[++environment_data.len] = list("name" = "Pressure", "value" = pressure, "unit" = "kPa", "danger_level" = pressure_danger) environment_data[++environment_data.len] = list("name" = "Oxygen", "value" = environment.gas["oxygen"] / total * 100, "unit" = "%", "danger_level" = oxygen_dangerlevel)
data["total_danger"] = pressure_danger environment_data[++environment_data.len] = list("name" = "Carbon dioxide", "value" = environment.gas["carbon_dioxide"] / total * 100, "unit" = "%", "danger_level" = co2_dangerlevel)
environment_data[++environment_data.len] = list("name" = "Toxins", "value" = environment.gas["phoron"] / total * 100, "unit" = "%", "danger_level" = phoron_dangerlevel)
current_settings = TLV["oxygen"] environment_data[++environment_data.len] = list("name" = "Temperature", "value" = environment.temperature, "unit" = "K ([round(environment.temperature - T0C, 0.1)]C)", "danger_level" = temperature_dangerlevel)
var/oxygen_danger = get_danger_level(environment.gas["oxygen"]*partial_pressure, current_settings) data["total_danger"] = danger_level
environment_data[++environment_data.len] = list("name" = "Oxygen", "value" = environment.gas["oxygen"] / total * 100, "unit" = "%", "danger_level" = oxygen_danger)
data["total_danger"] = max(oxygen_danger, data["total_danger"])
current_settings = TLV["carbon dioxide"]
var/carbon_dioxide_danger = get_danger_level(environment.gas["carbon_dioxide"]*partial_pressure, current_settings)
environment_data[++environment_data.len] = list("name" = "Carbon dioxide", "value" = environment.gas["carbon_dioxide"] / total * 100, "unit" = "%", "danger_level" = carbon_dioxide_danger)
data["total_danger"] = max(carbon_dioxide_danger, data["total_danger"])
current_settings = TLV["phoron"]
var/phoron_danger = get_danger_level(environment.gas["phoron"]*partial_pressure, current_settings)
environment_data[++environment_data.len] = list("name" = "Toxins", "value" = environment.gas["phoron"] / total * 100, "unit" = "%", "danger_level" = phoron_danger)
data["total_danger"] = max(phoron_danger, data["total_danger"])
current_settings = TLV["temperature"]
var/temperature_danger = get_danger_level(environment.temperature, current_settings)
environment_data[++environment_data.len] = list("name" = "Temperature", "value" = environment.temperature, "unit" = "K ([round(environment.temperature - T0C, 0.1)]C)", "danger_level" = temperature_danger)
data["total_danger"] = max(temperature_danger, data["total_danger"])
data["environment"] = environment_data data["environment"] = environment_data
data["atmos_alarm"] = alarm_area.atmosalm data["atmos_alarm"] = alarm_area.atmosalm
data["fire_alarm"] = alarm_area.fire != null data["fire_alarm"] = alarm_area.fire != null
@@ -888,8 +877,11 @@ FIRE ALARM
var/last_process = 0 var/last_process = 0
var/wiresexposed = 0 var/wiresexposed = 0
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
var/seclevel
/obj/machinery/firealarm/update_icon() /obj/machinery/firealarm/update_icon()
overlays.Cut()
if(wiresexposed) if(wiresexposed)
switch(buildstage) switch(buildstage)
if(2) if(2)
@@ -898,17 +890,28 @@ FIRE ALARM
icon_state="fire_b1" icon_state="fire_b1"
if(0) if(0)
icon_state="fire_b0" icon_state="fire_b0"
set_light(0)
return return
if(stat & BROKEN) if(stat & BROKEN)
icon_state = "firex" icon_state = "firex"
set_light(0)
else if(stat & NOPOWER) else if(stat & NOPOWER)
icon_state = "firep" icon_state = "firep"
else if(!src.detecting) set_light(0)
icon_state = "fire1"
else else
icon_state = "fire0" if(!src.detecting)
icon_state = "fire1"
set_light(l_range = 4, l_power = 2, l_color = "#ff0000")
else
icon_state = "fire0"
switch(seclevel)
if("green") set_light(l_range = 2, l_power = 0.5, l_color = "#00ff00")
if("blue") set_light(l_range = 2, l_power = 0.5, l_color = "#1024A9")
if("red") set_light(l_range = 4, l_power = 2, l_color = "#ff0000")
if("delta") set_light(l_range = 4, l_power = 2, l_color = "#FF6633")
src.overlays += image('icons/obj/monitors.dmi', "overlay_[seclevel]")
/obj/machinery/firealarm/fire_act(datum/gas_mixture/air, temperature, volume) /obj/machinery/firealarm/fire_act(datum/gas_mixture/air, temperature, volume)
if(src.detecting) if(src.detecting)
@@ -919,7 +922,7 @@ FIRE ALARM
/obj/machinery/firealarm/attack_ai(mob/user as mob) /obj/machinery/firealarm/attack_ai(mob/user as mob)
return src.attack_hand(user) return src.attack_hand(user)
/obj/machinery/firealarm/bullet_act(BLAH) /obj/machinery/firealarm/bullet_act()
return src.alarm() return src.alarm()
/obj/machinery/firealarm/emp_act(severity) /obj/machinery/firealarm/emp_act(severity)
@@ -1121,14 +1124,14 @@ FIRE ALARM
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
/obj/machinery/firealarm/proc/set_security_level(var/newlevel)
if(seclevel != newlevel)
seclevel = newlevel
update_icon()
/obj/machinery/firealarm/initialize() /obj/machinery/firealarm/initialize()
if(z in config.contact_levels) if(z in config.contact_levels)
if(security_level) set_security_level(security_level? get_security_level() : "green")
src.overlays += image('icons/obj/monitors.dmi', "overlay_[get_security_level()]")
else
src.overlays += image('icons/obj/monitors.dmi', "overlay_green")
update_icon()
/* /*
FIRE ALARM CIRCUIT FIRE ALARM CIRCUIT

View File

@@ -351,7 +351,7 @@ update_flag
"\[N2O\]" = "redws", \ "\[N2O\]" = "redws", \
"\[N2\]" = "red", \ "\[N2\]" = "red", \
"\[O2\]" = "blue", \ "\[O2\]" = "blue", \
"\[Toxin (Bio)\]" = "orange", \ "\[Phoron\]" = "orange", \
"\[CO2\]" = "black", \ "\[CO2\]" = "black", \
"\[Air\]" = "grey", \ "\[Air\]" = "grey", \
"\[CAUTION\]" = "yellow", \ "\[CAUTION\]" = "yellow", \

View File

@@ -104,7 +104,6 @@
network.update = 1 network.update = 1
/obj/machinery/portable_atmospherics/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) /obj/machinery/portable_atmospherics/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
var/obj/icon = src
if ((istype(W, /obj/item/weapon/tank) && !( src.destroyed ))) if ((istype(W, /obj/item/weapon/tank) && !( src.destroyed )))
if (src.holding) if (src.holding)
return return
@@ -136,21 +135,8 @@
return return
else if ((istype(W, /obj/item/device/analyzer)) && Adjacent(user)) else if ((istype(W, /obj/item/device/analyzer)) && Adjacent(user))
visible_message("<span class='notice'>\The [user] has used \the [W] on \the [src] \icon[icon]</span>") var/obj/item/device/analyzer/A = W
if(air_contents) A.analyze_gases(src, user)
var/pressure = air_contents.return_pressure()
var/total_moles = air_contents.total_moles
user << "<span class='notice'>Results of analysis of \icon[icon]</span>"
if (total_moles>0)
user << "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>"
for(var/g in air_contents.gas)
user << "<span class='notice'>[gas_data.name[g]]: [round((air_contents.gas[g] / total_moles) * 100)]%</span>"
user << "<span class='notice'>Temperature: [round(air_contents.temperature-T0C)]&deg;C</span>"
else
user << "<span class='notice'>Tank is empty!</span>"
else
user << "<span class='notice'>Tank is empty!</span>"
return return
return return
@@ -163,6 +149,13 @@
var/last_power_draw = 0 var/last_power_draw = 0
var/obj/item/weapon/cell/cell var/obj/item/weapon/cell/cell
/obj/machinery/portable_atmospherics/powered/powered()
if(use_power) //using area power
return ..()
if(cell && cell.charge)
return 1
return 0
/obj/machinery/portable_atmospherics/powered/attackby(obj/item/I, mob/user) /obj/machinery/portable_atmospherics/powered/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/cell)) if(istype(I, /obj/item/weapon/cell))
if(cell) if(cell)
@@ -176,6 +169,7 @@
cell = C cell = C
C.loc = src C.loc = src
user.visible_message("<span class='notice'>[user] opens the panel on [src] and inserts [C].</span>", "<span class='notice'>You open the panel on [src] and insert [C].</span>") user.visible_message("<span class='notice'>[user] opens the panel on [src] and inserts [C].</span>", "<span class='notice'>You open the panel on [src] and insert [C].</span>")
power_change()
return return
if(istype(I, /obj/item/weapon/screwdriver)) if(istype(I, /obj/item/weapon/screwdriver))
@@ -187,8 +181,8 @@
cell.add_fingerprint(user) cell.add_fingerprint(user)
cell.loc = src.loc cell.loc = src.loc
cell = null cell = null
power_change()
return return
..() ..()
/obj/machinery/portable_atmospherics/proc/log_open() /obj/machinery/portable_atmospherics/proc/log_open()

View File

@@ -102,6 +102,7 @@
//ran out of charge //ran out of charge
if (!cell.charge) if (!cell.charge)
power_change()
update_icon() update_icon()
src.updateDialog() src.updateDialog()

View File

@@ -77,6 +77,7 @@
//ran out of charge //ran out of charge
if (!cell.charge) if (!cell.charge)
power_change()
update_icon() update_icon()
//src.update_icon() //src.update_icon()
@@ -147,7 +148,6 @@
volume = 50000 volume = 50000
volume_rate = 5000 volume_rate = 5000
chan
use_power = 1 use_power = 1
idle_power_usage = 500 //internal circuitry, friction losses and stuff idle_power_usage = 500 //internal circuitry, friction losses and stuff
active_power_usage = 100000 //100 kW ~ 135 HP active_power_usage = 100000 //100 kW ~ 135 HP

View File

@@ -290,7 +290,7 @@
/obj/machinery/autolathe/dismantle() /obj/machinery/autolathe/dismantle()
for(var/mat in stored_material) for(var/mat in stored_material)
var/material/M = name_to_material[mat] var/material/M = get_material_by_name(mat)
if(!istype(M)) if(!istype(M))
continue continue
var/obj/item/stack/material/S = new M.stack_type(get_turf(src)) var/obj/item/stack/material/S = new M.stack_type(get_turf(src))

View File

@@ -66,19 +66,19 @@
user << "<span class='info'>You inject the blood sample into the bioprinter.</span>" user << "<span class='info'>You inject the blood sample into the bioprinter.</span>"
return return
// Meat for biomass. // Meat for biomass.
else if(!prints_prosthetics && istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat)) if(!prints_prosthetics && istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
stored_matter += 50 stored_matter += 50
user.drop_item() user.drop_item()
user << "<span class='info'>\The [src] processes \the [W]. Levels of stored biomass now: [stored_matter]</span>" user << "<span class='info'>\The [src] processes \the [W]. Levels of stored biomass now: [stored_matter]</span>"
qdel(W) qdel(W)
return return
// Steel for matter. // Steel for matter.
else if(prints_prosthetics && istype(W, /obj/item/stack/material/steel)) if(prints_prosthetics && istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL)
var/obj/item/stack/material/steel/M = W var/obj/item/stack/S = W
stored_matter += M.amount * 10 stored_matter += S.amount * 10
user.drop_item() user.drop_item()
user << "<span class='info'>\The [src] processes \the [W]. Levels of stored matter now: [stored_matter]</span>" user << "<span class='info'>\The [src] processes \the [W]. Levels of stored matter now: [stored_matter]</span>"
qdel(W) qdel(W)
return return
else
return..() return..()

View File

@@ -59,7 +59,7 @@
..() ..()
wires = new(src) wires = new(src)
botcard = new(src) botcard = new(src)
botcard.access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station) botcard.access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
cell = new(src) cell = new(src)
cell.charge = 2000 cell.charge = 2000
cell.maxcharge = 2000 cell.maxcharge = 2000

View File

@@ -138,14 +138,10 @@
else if(iswelder(W) && (wires.CanDeconstruct() || (stat & BROKEN))) else if(iswelder(W) && (wires.CanDeconstruct() || (stat & BROKEN)))
if(weld(W, user)) if(weld(W, user))
if (stat & BROKEN) if(assembly)
stat &= ~BROKEN
cancelCameraAlarm()
update_icon()
update_coverage()
else if(assembly)
assembly.loc = src.loc assembly.loc = src.loc
assembly.state = 1 assembly.state = 1
assembly = null //so qdel doesn't eat it.
new /obj/item/stack/cable_coil(src.loc, length=2) new /obj/item/stack/cable_coil(src.loc, length=2)
qdel(src) qdel(src)

View File

@@ -88,8 +88,8 @@
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( loc ) var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( loc )
A.amount = 5 A.amount = 5
if(istype(P, /obj/item/stack/material/glass/reinforced)) if(istype(P, /obj/item/stack/material) && P.get_material_name() == "rglass")
var/obj/item/stack/material/glass/reinforced/RG = P var/obj/item/stack/RG = P
if (RG.get_amount() < 2) if (RG.get_amount() < 2)
user << "<span class='warning'>You need two sheets of glass to put in the glass panel.</span>" user << "<span class='warning'>You need two sheets of glass to put in the glass panel.</span>"
return return
@@ -201,6 +201,7 @@
transfer.control_disabled = 0 transfer.control_disabled = 0
transfer.aiRadio.disabledAi = 0 transfer.aiRadio.disabledAi = 0
transfer.loc = get_turf(src) transfer.loc = get_turf(src)
transfer.create_eyeobj()
transfer.cancel_camera() transfer.cancel_camera()
user << "<span class='notice'>Transfer successful:</span> [transfer.name] ([rand(1000,9999)].exe) downloaded to host terminal. Local copy wiped." user << "<span class='notice'>Transfer successful:</span> [transfer.name] ([rand(1000,9999)].exe) downloaded to host terminal. Local copy wiped."
transfer << "You have been uploaded to a stationary terminal. Remote device connection restored." transfer << "You have been uploaded to a stationary terminal. Remote device connection restored."

View File

@@ -87,8 +87,8 @@
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( src.loc ) var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( src.loc )
A.amount = 5 A.amount = 5
if(istype(P, /obj/item/stack/material/glass)) if(istype(P, /obj/item/stack/material) && P.get_material_name() == "glass")
var/obj/item/stack/material/glass/G = P var/obj/item/stack/G = P
if (G.get_amount() < 2) if (G.get_amount() < 2)
user << "<span class='warning'>You need two sheets of glass to put in the glass panel.</span>" user << "<span class='warning'>You need two sheets of glass to put in the glass panel.</span>"
return return

View File

@@ -5,7 +5,7 @@
desc = "Used to view, edit and maintain security records" desc = "Used to view, edit and maintain security records"
icon_state = "security" icon_state = "security"
light_color = "#a91515" light_color = "#a91515"
req_one_access = list(access_security, access_forensics_lockers) req_one_access = list(access_security, access_forensics_lockers, access_lawyer)
circuit = "/obj/item/weapon/circuitboard/secure_data" circuit = "/obj/item/weapon/circuitboard/secure_data"
var/obj/item/weapon/card/id/scan = null var/obj/item/weapon/card/id/scan = null
var/authenticated = null var/authenticated = null

View File

@@ -178,12 +178,13 @@
if(istype(P, /obj/item/weapon/crowbar)) // complicated check if(istype(P, /obj/item/weapon/crowbar)) // complicated check
remove_peripheral() remove_peripheral()
if(istype(P, /obj/item/stack/material/glass)) if(istype(P, /obj/item/stack/material) && P.get_material_name() == "glass")
if(P:amount >= 2) var/obj/item/stack/S = P
if(S.amount >= 2)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 20)) if(do_after(user, 20))
if(P) if(S)
P:use(2) S.use(2)
user << "<span class='notice'>You put in the glass panel.</span>" user << "<span class='notice'>You put in the glass panel.</span>"
src.state = 4 src.state = 4
src.icon_state = "4" src.icon_state = "4"

View File

@@ -56,7 +56,7 @@
name = "Security Camera Network Main Key" name = "Security Camera Network Main Key"
var/title = "Station" var/title = "Station"
var/desc = "Connects to station security cameras." var/desc = "Connects to station security cameras."
var/list/networks = list("SS13") var/networks = list("ALL") // A little workaround as it is not possible to place station_networks here
var/screen = "cameras" var/screen = "cameras"
execute(var/datum/file/source) execute(var/datum/file/source)
@@ -76,58 +76,65 @@
return return
computer.Crash(MISSING_PROGRAM) computer.Crash(MISSING_PROGRAM)
/datum/file/camnet_key/New()
for(var/N in networks)
if(N == "ALL")
networks = station_networks
break
return ..()
/datum/file/camnet_key/mining /datum/file/camnet_key/mining
name = "Mining Camera Network Key" name = "Mining Camera Network Key"
title = "mining station" title = "mining station"
desc = "Connects to mining security cameras." desc = "Connects to mining security cameras."
networks = list("MINE") networks = list(NETWORK_MINE)
screen = "miningcameras" screen = "miningcameras"
/datum/file/camnet_key/research /datum/file/camnet_key/research
name = "Research Camera Network Key" name = "Research Camera Network Key"
title = "research" title = "research"
networks = list("RD") networks = list(NETWORK_RESEARCH)
/datum/file/camnet_key/bombrange /datum/file/camnet_key/bombrange
name = "R&D Bomb Range Camera Network Key" name = "R&D Bomb Range Camera Network Key"
title = "bomb range" title = "bomb range"
desc = "Monitors the bomb range." desc = "Monitors the bomb range."
networks = list("Toxins") networks = list(NETWORK_RESEARCH)
/datum/file/camnet_key/xeno /datum/file/camnet_key/xeno
name = "R&D Misc. Research Camera Network Key" name = "R&D Misc. Research Camera Network Key"
title = "special research" title = "special research"
networks = list("Misc") networks = list(NETWORK_RESEARCH)
/datum/file/camnet_key/singulo /datum/file/camnet_key/singulo
name = "Singularity Camera Network Key" name = "Singularity Camera Network Key"
title = "singularity" title = "singularity"
networks = list("Singularity") networks = list(NETWORK_ENGINE)
/datum/file/camnet_key/entertainment /datum/file/camnet_key/entertainment
name = "Entertainment Channel Encryption Key" name = "Entertainment Channel Encryption Key"
title = "entertainment" title = "entertainment"
desc = "Damn, I hope they have /tg/thechannel on here." desc = "Damn, I hope they have /tg/thechannel on here."
networks = list("thunder") networks = list(NETWORK_THUNDER)
screen = "entertainment" screen = "entertainment"
/datum/file/camnet_key/creed /datum/file/camnet_key/creed
name = "Special Ops Camera Encryption Key" name = "Special Ops Camera Encryption Key"
title = "special ops" title = "special ops"
desc = "Connects to special ops secure camera feeds." desc = "Connects to special ops secure camera feeds."
networks = list("CREED") networks = list(NETWORK_ERT)
/datum/file/camnet_key/prison /datum/file/camnet_key/prison
name = "Prison Camera Network Key" name = "Prison Camera Network Key"
title = "prison" title = "prison"
desc = "Monitors the prison." desc = "Monitors the prison."
networks = list("Prison") networks = list(NETWORK_SECURITY)
/datum/file/camnet_key/syndicate /datum/file/camnet_key/syndicate
name = "Camera Network Key" name = "Camera Network Key"
title = "%!#BUFFER OVERFLOW" title = "%!#BUFFER OVERFLOW"
desc = "Connects to security cameras." desc = "Connects to security cameras."
networks = list("SS13") networks = list("ALL")
hidden_file = 1 hidden_file = 1

View File

@@ -106,12 +106,16 @@
pixel_x = 2 pixel_x = 2
pixel_y = -3 pixel_y = -3
show_keyboard = 0 show_keyboard = 0
active_power_usage = 200 // Stationary consoles we use on station have 300, laptops are probably slightly more power efficient
idle_power_usage = 100
var/obj/item/device/laptop/portable = null var/obj/item/device/laptop/portable = null
New(var/L, var/built = 0) New(var/L, var/built = 0)
if(!built && !battery) if(!built && !battery)
battery = new /obj/item/weapon/cell(src) battery = new /obj/item/weapon/cell(src)
battery.maxcharge = 500
battery.charge = 500
..(L,built) ..(L,built)
verb/close_computer() verb/close_computer()

View File

@@ -46,8 +46,8 @@
if(vendmode == 3) if(vendmode == 3)
if(istype(W,/obj/item/weapon/card)) if(istype(W,/obj/item/weapon/card))
var/obj/item/weapon/card/I = W var/obj/item/weapon/card/I = W
reimburse(I) if(reimburse(I))
vendmode = 0 vendmode = 0
if(vendmode == 0) if(vendmode == 0)
if(istype(W, /obj/item/device/laptop)) if(istype(W, /obj/item/device/laptop))
var/obj/item/device/laptop/L = W var/obj/item/device/laptop/L = W
@@ -202,11 +202,11 @@
if (network == 3) if (network == 3)
newlap.spawn_parts += (/obj/item/part/computer/networking/cable) newlap.spawn_parts += (/obj/item/part/computer/networking/cable)
if (power == 1) if (power == 1)
qdel(newlap.battery) newlap.battery.maxcharge = 1000
newlap.battery = new /obj/item/weapon/cell/high(newlap) newlap.battery.charge = 1000
if (power == 2) if (power == 2)
qdel(newlap.battery) newlap.battery.maxcharge = 1750
newlap.battery = new /obj/item/weapon/cell/super(newlap) newlap.battery.charge = 1750
newlap.spawn_parts() newlap.spawn_parts()
@@ -215,6 +215,9 @@
var/obj/item/weapon/card/id/C = I var/obj/item/weapon/card/id/C = I
visible_message("<span class='info'>[usr] swipes a card through [src].</span>") visible_message("<span class='info'>[usr] swipes a card through [src].</span>")
var/datum/money_account/CH = get_account(C.associated_account_number) var/datum/money_account/CH = get_account(C.associated_account_number)
if(!CH)
usr << "\icon[src]<span class='warning'>No valid account number is associated with this card.</span>"
return
if(CH.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) if(CH.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2)
if(vendor_account) if(vendor_account)
var/attempt_pin = input("Enter pin code", "Vendor transaction") as num var/attempt_pin = input("Enter pin code", "Vendor transaction") as num
@@ -363,18 +366,25 @@
var/obj/item/weapon/card/id/C = I var/obj/item/weapon/card/id/C = I
visible_message("<span class='info'>[usr] swipes a card through [src].</span>") visible_message("<span class='info'>[usr] swipes a card through [src].</span>")
var/datum/money_account/CH = get_account(C.associated_account_number) var/datum/money_account/CH = get_account(C.associated_account_number)
if(!CH)
usr << "\icon[src]<span class='warning'>No valid account number is associated with this card.</span>"
return 0
if(CH.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) if(CH.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2)
if(vendor_account) if(vendor_account)
var/attempt_pin = input("Enter pin code", "Vendor transaction") as num var/attempt_pin = input("Enter pin code", "Vendor transaction") as num
var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2) var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2)
if(D) if(D)
transfer_and_reimburse(D) transfer_and_reimburse(D)
return 1
else else
usr << "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>" usr << "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>"
return 0
else else
usr << "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call CentComm Support.</span>" usr << "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call CentComm Support.</span>"
return 0
else else
transfer_and_reimburse(CH) transfer_and_reimburse(CH)
return 1
/obj/machinery/lapvend/proc/transfer_and_reimburse(var/datum/money_account/D) /obj/machinery/lapvend/proc/transfer_and_reimburse(var/datum/money_account/D)
var/transaction_amount = total() var/transaction_amount = total()

View File

@@ -106,18 +106,26 @@
if(component_check) if(component_check)
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
var/obj/machinery/new_machine = new src.circuit.build_path(src.loc, src.dir) var/obj/machinery/new_machine = new src.circuit.build_path(src.loc, src.dir)
new_machine.component_parts.Cut()
if(new_machine.component_parts)
new_machine.component_parts.Cut()
else
new_machine.component_parts = list()
src.circuit.construct(new_machine) src.circuit.construct(new_machine)
for(var/obj/O in src) for(var/obj/O in src)
if(circuit.contain_parts) // things like disposal don't want their parts in them if(circuit.contain_parts) // things like disposal don't want their parts in them
O.loc = new_machine O.loc = new_machine
else else
O.loc = null O.loc = null
new_machine.component_parts += O new_machine.component_parts += O
if(circuit.contain_parts) if(circuit.contain_parts)
circuit.loc = new_machine circuit.loc = new_machine
else else
circuit.loc = null circuit.loc = null
new_machine.RefreshParts() new_machine.RefreshParts()
qdel(src) qdel(src)
else else

View File

@@ -60,11 +60,6 @@
return 1 return 1
/obj/machinery/atmospherics/unary/cryo_cell/allow_drop()
return 0
/obj/machinery/atmospherics/unary/cryo_cell/relaymove(mob/user as mob) /obj/machinery/atmospherics/unary/cryo_cell/relaymove(mob/user as mob)
if(user.stat) if(user.stat)
return return

View File

@@ -79,12 +79,14 @@ for reference:
maxhealth = material.integrity maxhealth = material.integrity
health = maxhealth health = maxhealth
/obj/structure/barricade/get_material()
return material
/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob) /obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/stack/material)) if (istype(W, /obj/item/stack))
var/obj/item/stack/material/D = W var/obj/item/stack/D = W
if(D.material.name != material.name) if(D.get_material_name() != material.name)
user << "<span class='warning'>That is the wrong material needed to repair \the [src].</span>" return //hitting things with the wrong type of stack usually doesn't produce messages, and probably doesn't need to.
return
if (health < maxhealth) if (health < maxhealth)
if (D.get_amount() < 1) if (D.get_amount() < 1)
user << "<span class='warning'>You need one sheet of [material.display_name] to repair \the [src].</span>" user << "<span class='warning'>You need one sheet of [material.display_name] to repair \the [src].</span>"

View File

@@ -48,6 +48,11 @@
return return
..() ..()
/obj/machinery/door/airlock/get_material()
if(mineral)
return get_material_by_name(mineral)
return get_material_by_name(DEFAULT_WALL_MATERIAL)
/obj/machinery/door/airlock/command /obj/machinery/door/airlock/command
name = "Airlock" name = "Airlock"
icon = 'icons/obj/doors/Doorcom.dmi' icon = 'icons/obj/doors/Doorcom.dmi'

View File

@@ -96,12 +96,12 @@
else else
usr << "<span class='notice'>[src]'s motors resist your effort.</span>" usr << "<span class='notice'>[src]'s motors resist your effort.</span>"
return return
if(istype(C, /obj/item/stack/material/plasteel)) if(istype(C, /obj/item/stack/material) && C.get_material_name() == "plasteel")
var/amt = repair_price() var/amt = Ceiling((maxhealth - health)/150)
if(!amt) if(!amt)
usr << "<span class='notice'>\The [src] is already fully repaired.</span>" usr << "<span class='notice'>\The [src] is already fully repaired.</span>"
return return
var/obj/item/stack/material/plasteel/P = C var/obj/item/stack/P = C
if(P.amount < amt) if(P.amount < amt)
usr << "<span class='warning'>You don't have enough sheets to repair this! You need at least [amt] sheets.</span>" usr << "<span class='warning'>You don't have enough sheets to repair this! You need at least [amt] sheets.</span>"
return return
@@ -135,16 +135,6 @@
return return
force_close() force_close()
// Proc: repair_price()
// Parameters: None
// Description: Determines amount of sheets needed for full repair. (max)150HP per sheet, (max)10 emitter hits per sheet.
/obj/machinery/door/blast/proc/repair_price()
var/sheets_needed = 0
var/dam = maxhealth - health
while(dam > 0)
dam -= 150
sheets_needed++
return sheets_needed
// Proc: repair() // Proc: repair()
// Parameters: None // Parameters: None

View File

@@ -103,6 +103,13 @@
bumpopen(M) bumpopen(M)
return return
if(istype(AM, /obj/machinery/bot))
var/obj/machinery/bot/bot = AM
if(src.check_access(bot.botcard))
if(density)
open()
return
if(istype(AM, /mob/living/bot)) if(istype(AM, /mob/living/bot))
var/mob/living/bot/bot = AM var/mob/living/bot/bot = AM
if(src.check_access(bot.botcard)) if(src.check_access(bot.botcard))
@@ -199,10 +206,9 @@
/obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob) /obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/device/detective_scanner)) if(istype(I, /obj/item/device/detective_scanner))
return return
if(src.operating > 0 || isrobot(user)) return //borgs can't attack doors open because it conflicts with their AI-like interaction with them.
src.add_fingerprint(user) src.add_fingerprint(user)
if(istype(I, /obj/item/stack/material/steel)) if(istype(I, /obj/item/stack/material) && I.get_material_name() == src.get_material_name())
if(stat & BROKEN) if(stat & BROKEN)
user << "<span class='notice'>It looks like \the [src] is pretty busted. It's going to need more than just patching up now.</span>" user << "<span class='notice'>It looks like \the [src] is pretty busted. It's going to need more than just patching up now.</span>"
return return
@@ -217,20 +223,20 @@
var/amount_needed = (maxhealth - health) / DOOR_REPAIR_AMOUNT var/amount_needed = (maxhealth - health) / DOOR_REPAIR_AMOUNT
amount_needed = (round(amount_needed) == amount_needed)? amount_needed : round(amount_needed) + 1 //Why does BYOND not have a ceiling proc? amount_needed = (round(amount_needed) == amount_needed)? amount_needed : round(amount_needed) + 1 //Why does BYOND not have a ceiling proc?
var/obj/item/stack/material/steel/metalstack = I var/obj/item/stack/stack = I
var/transfer var/transfer
if (repairing) if (repairing)
transfer = metalstack.transfer_to(repairing, amount_needed - repairing.amount) transfer = stack.transfer_to(repairing, amount_needed - repairing.amount)
if (!transfer) if (!transfer)
user << "<span class='warning'>You must weld or remove \the [repairing] from \the [src] before you can add anything else.</span>" user << "<span class='warning'>You must weld or remove \the [repairing] from \the [src] before you can add anything else.</span>"
else else
repairing = metalstack.split(amount_needed) repairing = stack.split(amount_needed)
if (repairing) if (repairing)
repairing.loc = src repairing.loc = src
transfer = repairing.amount transfer = repairing.amount
if (transfer) if (transfer)
user << "<span class='notice'>You fit [transfer] [metalstack.singular_name]\s to damaged and broken parts on \the [src].</span>" user << "<span class='notice'>You fit [transfer] [stack.singular_name]\s to damaged and broken parts on \the [src].</span>"
return return
@@ -270,6 +276,8 @@
take_damage(W.force) take_damage(W.force)
return return
if(src.operating > 0 || isrobot(user)) return //borgs can't attack doors open because it conflicts with their AI-like interaction with them.
if(src.operating) return if(src.operating) return
if(src.allowed(user) && operable()) if(src.allowed(user) && operable())
@@ -333,7 +341,8 @@
/obj/machinery/door/emp_act(severity) /obj/machinery/door/emp_act(severity)
if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) ) if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) )
open() spawn(0)
open()
..() ..()

View File

@@ -75,6 +75,8 @@
A.all_doors.Remove(src) A.all_doors.Remove(src)
. = ..() . = ..()
/obj/machinery/door/firedoor/get_material()
return get_material_by_name(DEFAULT_WALL_MATERIAL)
/obj/machinery/door/firedoor/examine(mob/user) /obj/machinery/door/firedoor/examine(mob/user)
. = ..(user, 1) . = ..(user, 1)

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