mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
Merge remote-tracking branch 'upstream/dev' into follow
Conflicts: .travis.yml
This commit is contained in:
@@ -5,6 +5,7 @@ sudo: false
|
||||
env:
|
||||
BYOND_MAJOR="508"
|
||||
BYOND_MINOR="1287"
|
||||
MACRO_COUNT=1234
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@@ -32,7 +33,7 @@ script:
|
||||
- (! grep 'step_[xy]' maps/**/*.dmm)
|
||||
- (! find nano/templates/ -type f -exec md5sum {} + | sort | uniq -D -w 32 | grep nano)
|
||||
- (! 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 1249 or less)"; [ $num -le 1249 ])
|
||||
- (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 - <<< "88490b460c26947f5ec1ab1bb9fa9f17 *html/changelogs/example.yml"
|
||||
- python tools/TagMatcher/tag-matcher.py ../..
|
||||
|
||||
@@ -24,12 +24,14 @@
|
||||
#include "code\__defines\dna.dm"
|
||||
#include "code\__defines\gamemode.dm"
|
||||
#include "code\__defines\items_clothing.dm"
|
||||
#include "code\__defines\lighting.dm"
|
||||
#include "code\__defines\machinery.dm"
|
||||
#include "code\__defines\math_physics.dm"
|
||||
#include "code\__defines\misc.dm"
|
||||
#include "code\__defines\mobs.dm"
|
||||
#include "code\__defines\research.dm"
|
||||
#include "code\__defines\species_languages.dm"
|
||||
#include "code\_helpers\atmospherics.dm"
|
||||
#include "code\_helpers\datum_pool.dm"
|
||||
#include "code\_helpers\files.dm"
|
||||
#include "code\_helpers\game.dm"
|
||||
@@ -144,6 +146,7 @@
|
||||
#include "code\datums\ai_laws.dm"
|
||||
#include "code\datums\browser.dm"
|
||||
#include "code\datums\computerfiles.dm"
|
||||
#include "code\datums\crew.dm"
|
||||
#include "code\datums\datacore.dm"
|
||||
#include "code\datums\datumvars.dm"
|
||||
#include "code\datums\disease.dm"
|
||||
@@ -772,6 +775,7 @@
|
||||
#include "code\game\objects\structures\watercloset.dm"
|
||||
#include "code\game\objects\structures\windoor_assembly.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\crates.dm"
|
||||
#include "code\game\objects\structures\crates_lockers\largecrate.dm"
|
||||
@@ -1277,6 +1281,7 @@
|
||||
#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\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\examine.dm"
|
||||
#include "code\modules\mob\living\silicon\pai\life.dm"
|
||||
@@ -1308,6 +1313,7 @@
|
||||
#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_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\corpse.dm"
|
||||
#include "code\modules\mob\living\simple_animal\parrot.dm"
|
||||
@@ -1505,6 +1511,7 @@
|
||||
#include "code\modules\random_map\noise\tundra.dm"
|
||||
#include "code\modules\reagents\Chemistry-Colours.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-Metabolism.dm"
|
||||
#include "code\modules\reagents\Chemistry-Readme.dm"
|
||||
@@ -1673,16 +1680,15 @@
|
||||
#include "code\modules\spells\aoe_turf\conjure\forcewall.dm"
|
||||
#include "code\modules\spells\general\area_teleport.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\flesh_to_stone.dm"
|
||||
#include "code\modules\spells\targeted\genetic.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\shift.dm"
|
||||
#include "code\modules\spells\targeted\subjugate.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\fireball.dm"
|
||||
#include "code\modules\spells\targeted\projectile\magic_missile.dm"
|
||||
|
||||
@@ -1120,20 +1120,8 @@
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/device/analyzer) && in_range(user, src))
|
||||
for (var/mob/O in viewers(user, null))
|
||||
O << "<span class='notice'>\The [user] has used \the [W] on \the [src] \icon[src]</span>"
|
||||
|
||||
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)]°C</span>"
|
||||
else
|
||||
user << "<span class='notice'>Tank is empty!</span>"
|
||||
var/obj/item/device/analyzer/A = W
|
||||
A.analyze_gases(src, user)
|
||||
|
||||
/obj/machinery/atmospherics/pipe/tank/air
|
||||
name = "Pressure Tank (Air)"
|
||||
|
||||
@@ -241,7 +241,7 @@ mob/living/carbon/human/airflow_hit(atom/A)
|
||||
zone/proc/movables()
|
||||
. = list()
|
||||
for(var/turf/T in contents)
|
||||
for(var/atom/A in T)
|
||||
if(istype(A, /obj/effect) || istype(A, /mob/aiEye))
|
||||
for(var/atom/movable/A in T)
|
||||
if(!A.simulated || A.anchored || istype(A, /obj/effect) || istype(A, /mob/aiEye))
|
||||
continue
|
||||
. += A
|
||||
|
||||
@@ -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(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
|
||||
|
||||
|
||||
|
||||
6
code/__defines/lighting.dm
Normal file
6
code/__defines/lighting.dm
Normal 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
|
||||
@@ -12,7 +12,7 @@
|
||||
#define INVISIBILITY_EYE 61
|
||||
|
||||
#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_TWO 45
|
||||
#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_CLOSED_LAYER 3.1 //Above most items if closed
|
||||
#define LIGHTING_LAYER 11
|
||||
#define OBFUSCATION_LAYER 14 //Where images covering the view for eyes are put
|
||||
#define SCREEN_LAYER 17 //Mob HUD/effects layer
|
||||
#define OBFUSCATION_LAYER 21 //Where images covering the view for eyes are put
|
||||
#define SCREEN_LAYER 22 //Mob HUD/effects layer
|
||||
|
||||
// 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.
|
||||
@@ -154,3 +154,7 @@
|
||||
#define BOMBCAP_HEAVY_RADIUS (max_explosion_range/2)
|
||||
#define BOMBCAP_LIGHT_RADIUS max_explosion_range
|
||||
#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.
|
||||
|
||||
@@ -83,4 +83,14 @@
|
||||
|
||||
|
||||
#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'
|
||||
|
||||
@@ -44,4 +44,5 @@
|
||||
#define NONGLOBAL 32 // Do not add to general languages list.
|
||||
#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_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
|
||||
|
||||
47
code/_helpers/atmospherics.dm
Normal file
47
code/_helpers/atmospherics.dm
Normal 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)]°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)
|
||||
@@ -210,14 +210,23 @@ proc/listclearnulls(list/list)
|
||||
return (result + R.Copy(Ri, 0))
|
||||
|
||||
//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(!L)
|
||||
testing("sortAtom() called with null as first parameter!")
|
||||
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
|
||||
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
|
||||
/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/Ri=1
|
||||
var/list/result = new()
|
||||
@@ -230,8 +239,14 @@ proc/listclearnulls(list/list)
|
||||
result += R[Ri++]
|
||||
|
||||
if(Li <= L.len)
|
||||
return (result + L.Copy(Li, 0))
|
||||
return (result + R.Copy(Ri, 0))
|
||||
. = (result + L.Copy(Li, 0))
|
||||
if(!.)
|
||||
testing("mergeAtoms returning [.]")
|
||||
return
|
||||
. = (result + R.Copy(Ri, 0))
|
||||
if(!.)
|
||||
testing("mergeAtoms returning [.]")
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
var/roundstart_hour = 0
|
||||
//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)
|
||||
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()
|
||||
return num2text((text2num(time2text(world.timeofday, "YYYY"))+544)) + "-" + time2text(world.timeofday, "MM-DD")
|
||||
|
||||
|
||||
proc/time_stamp()
|
||||
return time2text(world.timeofday, "hh:mm:ss")
|
||||
|
||||
|
||||
@@ -871,6 +871,8 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
|
||||
// Movement based on lower left corner. Tiles that do not fit
|
||||
// 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
|
||||
|
||||
var/list/turfs_src = get_area_turfs(src.type)
|
||||
@@ -924,7 +926,8 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
|
||||
if(istype(B, get_base_turf(B.z)))
|
||||
continue moving
|
||||
|
||||
var/turf/X = new T.type(B)
|
||||
var/turf/X = B
|
||||
X.ChangeTurf(T.type)
|
||||
X.set_dir(old_dir1)
|
||||
X.icon_state = old_icon_state1
|
||||
X.icon = old_icon1 //Shuttle floors are in shuttle.dmi while the defaults are floors.dmi
|
||||
@@ -964,12 +967,6 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
|
||||
copiedobjs += newobjs
|
||||
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
|
||||
|
||||
// if(AR.lighting_use_dynamic)
|
||||
@@ -985,22 +982,9 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
|
||||
|
||||
|
||||
|
||||
var/list/doors = new/list()
|
||||
|
||||
if(toupdate.len)
|
||||
for(var/turf/simulated/T1 in toupdate)
|
||||
for(var/obj/machinery/door/D2 in 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)
|
||||
|
||||
|
||||
|
||||
air_master.mark_for_update(T1)
|
||||
|
||||
return copiedobjs
|
||||
|
||||
@@ -1289,29 +1273,39 @@ var/list/WALLITEMS = list(
|
||||
colour += temp_col
|
||||
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
|
||||
|
||||
var/global/mob/dview/DV
|
||||
if(!DV)
|
||||
DV = new
|
||||
dview_mob.loc = center
|
||||
|
||||
DV.loc = center
|
||||
dview_mob.see_invisible = invis_flags
|
||||
|
||||
DV.see_in_dark = range
|
||||
DV.see_invisible = invis_flags
|
||||
|
||||
. = view(range, DV)
|
||||
DV.loc = null
|
||||
. = 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)
|
||||
if(origin)
|
||||
color = origin.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
|
||||
|
||||
@@ -141,6 +141,25 @@ datum/hud/New(mob/owner)
|
||||
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()
|
||||
if(!mymob) return
|
||||
if(ishuman(mymob))
|
||||
|
||||
@@ -45,6 +45,10 @@
|
||||
/obj/screen/item_action
|
||||
var/obj/item/owner
|
||||
|
||||
/obj/screen/item_action/Destroy()
|
||||
..()
|
||||
owner = null
|
||||
|
||||
/obj/screen/item_action/Click()
|
||||
if(!usr || !owner)
|
||||
return 1
|
||||
|
||||
@@ -12,6 +12,18 @@
|
||||
|
||||
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()
|
||||
if(showing)
|
||||
return
|
||||
@@ -57,16 +69,23 @@
|
||||
/obj/screen/movable/spell_master/proc/add_spell(var/spell/spell)
|
||||
if(!spell) return
|
||||
|
||||
for(var/obj/screen/spell/spellscreen in spell_objects)
|
||||
if(spellscreen.spell == spell)
|
||||
if(spell.connected_button) //we have one already, for some reason
|
||||
if(spell.connected_button in spell_objects)
|
||||
return
|
||||
else
|
||||
spell_objects.Add(spell.connected_button)
|
||||
toggle_open(2)
|
||||
return
|
||||
|
||||
if(spell.spell_flags & NO_BUTTON) //no button to add if we don't get one
|
||||
return
|
||||
|
||||
var/obj/screen/spell/newscreen = new
|
||||
|
||||
var/obj/screen/spell/newscreen = new /obj/screen/spell
|
||||
newscreen.spellmaster = src
|
||||
newscreen.spell = spell
|
||||
|
||||
spell.connected_button = newscreen
|
||||
|
||||
if(!spell.override_base) //if it's not set, we do basic checks
|
||||
if(spell.spell_flags & CONSTRUCT_CHECK)
|
||||
newscreen.spell_base = "const" //construct spells
|
||||
@@ -80,16 +99,13 @@
|
||||
toggle_open(2) //forces the icons to refresh on screen
|
||||
|
||||
/obj/screen/movable/spell_master/proc/remove_spell(var/spell/spell)
|
||||
for(var/obj/screen/spell/s_object in spell_objects)
|
||||
if(s_object.spell == spell)
|
||||
spell_objects.Remove(s_object)
|
||||
qdel(s_object)
|
||||
break
|
||||
qdel(spell.connected_button)
|
||||
|
||||
spell.connected_button = null
|
||||
|
||||
if(spell_objects.len)
|
||||
toggle_open(showing + 1)
|
||||
else
|
||||
spell_holder.spell_masters.Remove(src)
|
||||
qdel(src)
|
||||
|
||||
/obj/screen/movable/spell_master/proc/silence_spells(var/amount)
|
||||
@@ -125,9 +141,20 @@
|
||||
|
||||
var/spell/spell = null
|
||||
var/handle_icon_updates = 0
|
||||
var/obj/screen/movable/spell_master/spellmaster
|
||||
|
||||
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)
|
||||
if(!spell)
|
||||
qdel(src)
|
||||
|
||||
@@ -28,6 +28,10 @@ var/list/delayed_garbage = list()
|
||||
delayed_garbage.Cut()
|
||||
delayed_garbage = null
|
||||
|
||||
#ifdef GC_FINDREF
|
||||
world/loop_checks = 0
|
||||
#endif
|
||||
|
||||
/datum/controller/process/garbage_collector/doWork()
|
||||
if(!garbage_collect)
|
||||
return
|
||||
@@ -37,6 +41,31 @@ var/list/delayed_garbage = list()
|
||||
var/checkRemain = max_checks_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)
|
||||
if(dels >= maxDels)
|
||||
#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]")
|
||||
#endif
|
||||
break // Everything else is newer, skip them
|
||||
var/atom/A = locate(refID)
|
||||
var/datum/A = locate(refID)
|
||||
#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]")
|
||||
#endif
|
||||
@@ -67,6 +96,32 @@ var/list/delayed_garbage = list()
|
||||
#endif
|
||||
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)
|
||||
if(!istype(A) || !isnull(A.gcDestroyed))
|
||||
return
|
||||
@@ -199,3 +254,7 @@ var/list/delayed_garbage = list()
|
||||
#ifdef GC_DEBUG
|
||||
#undef GC_DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef GC_FINDREF
|
||||
#undef GC_FINDREF
|
||||
#endif
|
||||
|
||||
@@ -121,6 +121,8 @@ var/list/gamemode_cache = list()
|
||||
|
||||
var/organ_health_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,
|
||||
//so that it's similar to HALLOSS. Lowered it a bit since hitting paincrit takes much longer to wear off than a halloss stun.
|
||||
@@ -709,6 +711,12 @@ var/list/gamemode_cache = list()
|
||||
config.organ_regeneration_multiplier = value / 100
|
||||
if("organ_damage_spillover_multiplier")
|
||||
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")
|
||||
config.bones_can_break = value
|
||||
if("limbs_can_break")
|
||||
|
||||
@@ -49,6 +49,11 @@ datum/controller/game_controller/proc/setup_objects()
|
||||
for(var/atom/movable/object in world)
|
||||
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)
|
||||
sleep(-1)
|
||||
for(var/obj/machinery/atmospherics/machine in machines)
|
||||
|
||||
@@ -188,9 +188,9 @@ datum/controller/vote
|
||||
if(mode)
|
||||
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
|
||||
return 0
|
||||
if(current_votes[ckey])
|
||||
choices[choices[current_votes[ckey]]]--
|
||||
if(vote && 1<=vote && vote<=choices.len)
|
||||
if(vote && vote >= 1 && vote <= choices.len)
|
||||
if(current_votes[ckey])
|
||||
choices[choices[current_votes[ckey]]]--
|
||||
voted += usr.ckey
|
||||
choices[choices[vote]]++ //check this
|
||||
current_votes[ckey] = vote
|
||||
|
||||
@@ -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/zeroth/delete_law(var/datum/ai_laws/laws)
|
||||
/datum/ai_law/zero/delete_law(var/datum/ai_laws/laws)
|
||||
laws.clear_zeroth_laws()
|
||||
|
||||
/datum/ai_law/ion/delete_law(var/datum/ai_laws/laws)
|
||||
|
||||
74
code/datums/crew.dm
Normal file
74
code/datums/crew.dm
Normal 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
|
||||
@@ -138,9 +138,160 @@
|
||||
|
||||
|
||||
proc/get_id_photo(var/mob/living/carbon/human/H)
|
||||
H.regenerate_icons()
|
||||
var/icon/preview_icon = icon(H.icon)
|
||||
for(var/image/I in H.overlays_standing)
|
||||
if(I && I.icon)
|
||||
preview_icon.Blend(icon(I.icon, I.icon_state), ICON_OVERLAY)
|
||||
var/icon/preview_icon = null
|
||||
|
||||
var/g = "m"
|
||||
if (H.gender == FEMALE)
|
||||
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
|
||||
|
||||
@@ -60,7 +60,8 @@
|
||||
/datum/antagonist/proc/get_candidates(var/ghosts_only)
|
||||
candidates = list() // Clear.
|
||||
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)
|
||||
if(ghosts_only && !istype(player.current, /mob/dead))
|
||||
candidates -= player
|
||||
@@ -75,7 +76,9 @@
|
||||
return candidates
|
||||
|
||||
/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)
|
||||
if(!can_late_spawn())
|
||||
@@ -88,27 +91,59 @@
|
||||
add_antagonist(player,0,1,0,1,1)
|
||||
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.
|
||||
update_current_antag_max()
|
||||
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.
|
||||
if(!candidates.len)
|
||||
return 0
|
||||
|
||||
//Grab candidates randomly until we have enough.
|
||||
while(candidates.len)
|
||||
while(candidates.len && pending_antagonists.len < cur_max)
|
||||
var/datum/mind/player = pick(candidates)
|
||||
pending_antagonists |= player
|
||||
candidates -= player
|
||||
draft_antagonist(player)
|
||||
|
||||
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()
|
||||
if(!pending_antagonists || !pending_antagonists.len)
|
||||
if(!pending_antagonists)
|
||||
return
|
||||
|
||||
for(var/datum/mind/player in pending_antagonists)
|
||||
if(can_become_antag(player) && !player.special_role)
|
||||
add_antagonist(player,0,0,1)
|
||||
pending_antagonists.Cut()
|
||||
pending_antagonists -= player
|
||||
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()
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
return 0
|
||||
|
||||
current_antagonists |= player
|
||||
|
||||
//do this again, just in case
|
||||
if(flags & ANTAG_OVERRIDE_JOB)
|
||||
player.assigned_role = role_text
|
||||
player.special_role = role_text
|
||||
|
||||
@@ -42,7 +42,13 @@
|
||||
return W
|
||||
|
||||
/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)
|
||||
player.equip_to_slot_or_del(R, slot_l_ear)
|
||||
return R
|
||||
@@ -113,6 +119,7 @@
|
||||
if (newname)
|
||||
player.real_name = newname
|
||||
player.name = player.real_name
|
||||
player.dna.real_name = newname
|
||||
if(player.mind) player.mind.name = player.name
|
||||
// Update any ID cards.
|
||||
update_access(player)
|
||||
|
||||
@@ -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>"
|
||||
|
||||
//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)
|
||||
remove_spell(spell_to_remove)
|
||||
|
||||
|
||||
@@ -6,12 +6,13 @@ var/datum/antagonist/rogue_ai/malf
|
||||
role_text = "Rampant AI"
|
||||
role_text_plural = "Rampant AIs"
|
||||
mob_path = /mob/living/silicon/ai
|
||||
landmark_id = "AI"
|
||||
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."
|
||||
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_round = 3
|
||||
max_antags_round = 1
|
||||
|
||||
|
||||
/datum/antagonist/rogue_ai/New()
|
||||
@@ -22,7 +23,7 @@ var/datum/antagonist/rogue_ai/malf
|
||||
/datum/antagonist/rogue_ai/get_candidates()
|
||||
..()
|
||||
for(var/datum/mind/player in candidates)
|
||||
if(player.assigned_role != "AI")
|
||||
if(player.assigned_role && player.assigned_role != "AI")
|
||||
candidates -= player
|
||||
if(!candidates.len)
|
||||
return list()
|
||||
@@ -75,3 +76,26 @@ var/datum/antagonist/rogue_ai/malf
|
||||
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 << "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
|
||||
|
||||
|
||||
@@ -901,7 +901,7 @@ area/space/atmosalert()
|
||||
icon_state = "tcomsatcham"
|
||||
|
||||
/area/server
|
||||
name = "\improper Messaging Server Room"
|
||||
name = "\improper Research Server Room"
|
||||
icon_state = "server"
|
||||
|
||||
//Crew
|
||||
@@ -1809,7 +1809,7 @@ area/space/atmosalert()
|
||||
ambience = list('sound/ambience/ambimalf.ogg')
|
||||
|
||||
/area/turret_protected/ai_server_room
|
||||
name = "AI Server Room"
|
||||
name = "Messaging Server Room"
|
||||
icon_state = "ai_server"
|
||||
|
||||
/area/turret_protected/ai
|
||||
|
||||
@@ -14,13 +14,17 @@
|
||||
all_areas += src
|
||||
|
||||
if(!requires_power)
|
||||
power_light = 0 //rastaf0
|
||||
power_equip = 0 //rastaf0
|
||||
power_environ = 0 //rastaf0
|
||||
power_light = 0
|
||||
power_equip = 0
|
||||
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
|
||||
|
||||
/area/proc/get_contents()
|
||||
@@ -227,7 +231,7 @@ var/list/mob/living/forced_ambiance_list = new
|
||||
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.
|
||||
thunk(L)
|
||||
L.make_floating(0)
|
||||
L.update_floating( L.Check_Dense_Object() )
|
||||
|
||||
L.lastarea = newarea
|
||||
play_ambience(L)
|
||||
@@ -260,21 +264,10 @@ var/list/mob/living/forced_ambiance_list = new
|
||||
/area/proc/gravitychange(var/gravitystate = 0, var/area/A)
|
||||
A.has_gravity = gravitystate
|
||||
|
||||
if(gravitystate)
|
||||
for(var/mob/living/carbon/human/M in A)
|
||||
for(var/mob/M in A)
|
||||
if(has_gravity)
|
||||
thunk(M)
|
||||
for(var/mob/M1 in A)
|
||||
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)
|
||||
M.update_floating( M.Check_Dense_Object() )
|
||||
|
||||
/area/proc/thunk(mob)
|
||||
if(istype(get_turf(mob), /turf/space)) // Can't fall onto nothing.
|
||||
|
||||
@@ -63,9 +63,6 @@
|
||||
return flags & INSERT_CONTAINER
|
||||
*/
|
||||
|
||||
/atom/proc/allow_drop()
|
||||
return 1
|
||||
|
||||
/atom/proc/CheckExit()
|
||||
return 1
|
||||
|
||||
@@ -487,4 +484,4 @@ its easier to just keep the beam vertical.
|
||||
O.show_message( message, 2, deaf_message, 1)
|
||||
else if(ismob(I))
|
||||
var/mob/M = I
|
||||
M.show_message( message, 2, deaf_message, 1)
|
||||
M.show_message( message, 2, deaf_message, 1)
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
a = get_area(src.loc)
|
||||
else
|
||||
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
|
||||
if(error < 0)
|
||||
var/atom/step = get_step(src, dx)
|
||||
|
||||
@@ -64,9 +64,6 @@
|
||||
component_parts += new /obj/item/stack/cable_coil(src)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/dna_scannernew/allow_drop()
|
||||
return 0
|
||||
|
||||
/obj/machinery/dna_scannernew/relaymove(mob/user as mob)
|
||||
if (user.stat)
|
||||
return
|
||||
|
||||
@@ -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>"
|
||||
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>"
|
||||
return
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ var/list/datum/power/changeling/powerinstances = list()
|
||||
|
||||
/datum/power/changeling/DeathSting
|
||||
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
|
||||
verbpath = /mob/proc/changeling_DEATHsting
|
||||
|
||||
|
||||
@@ -136,8 +136,8 @@
|
||||
// Make it a wood-reinforced wooden table.
|
||||
// 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?
|
||||
material = name_to_material["wood"]
|
||||
reinforced = name_to_material["wood"]
|
||||
material = get_material_by_name("wood")
|
||||
reinforced = get_material_by_name("wood")
|
||||
update_desc()
|
||||
update_connections(1)
|
||||
update_icon()
|
||||
|
||||
@@ -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)
|
||||
|
||||
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>")
|
||||
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>)")
|
||||
|
||||
|
||||
@@ -5,6 +5,14 @@ var/list/sacrificed = list()
|
||||
|
||||
/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
|
||||
proc
|
||||
teleport(var/key)
|
||||
@@ -21,7 +29,7 @@ var/list/sacrificed = list()
|
||||
allrunesloc.len = index
|
||||
allrunesloc[index] = R.loc
|
||||
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))
|
||||
user.take_overall_damage(5, 0)
|
||||
qdel(src)
|
||||
@@ -30,9 +38,9 @@ var/list/sacrificed = list()
|
||||
user.say("Sas[pick("'","`")]so c'arta forbici!")//Only you can stop auto-muting
|
||||
else
|
||||
user.whisper("Sas[pick("'","`")]so c'arta forbici!")
|
||||
user.visible_message("<span class='warning'>\The [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='warning'>You hear a sickening crunch and sloshing of viscera.</span>")
|
||||
user.visible_message("<span class='danger'>[user] disappears in a flash of red light!</span>", \
|
||||
"<span class='danger'>You feel as your body gets dragged through the dimension of Nar-Sie!</span>", \
|
||||
"<span class='danger'>You hear a sickening crunch and sloshing of viscera.</span>")
|
||||
user.loc = allrunesloc[rand(1,index)]
|
||||
return
|
||||
if(istype(src,/obj/effect/rune))
|
||||
@@ -58,7 +66,7 @@ var/list/sacrificed = list()
|
||||
IP = R
|
||||
runecount++
|
||||
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))
|
||||
user.take_overall_damage(5, 0)
|
||||
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")
|
||||
switch(target.getFireLoss())
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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>"
|
||||
@@ -157,7 +165,7 @@ var/list/sacrificed = list()
|
||||
if (target.species && (target.species.flags & NO_PAIN))
|
||||
target.visible_message("<span class='warning'>The markings below [target] glow a bloody red.</span>")
|
||||
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
|
||||
waiting_for_input[target] = 1
|
||||
@@ -229,15 +237,15 @@ var/list/sacrificed = list()
|
||||
if(!drain)
|
||||
return fizzle()
|
||||
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>", \
|
||||
"<span class='warning'>The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.</span>", \
|
||||
usr.visible_message("<span class='danger'>Blood flows from the rune into [usr]!</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>")
|
||||
var/mob/living/user = usr
|
||||
if(user.bhunger)
|
||||
user.bhunger = max(user.bhunger-2*drain,0)
|
||||
if(drain>=50)
|
||||
user.visible_message("<span class='warning'>\The [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>", \
|
||||
user.visible_message("<span class='danger'>[user]'s eyes give off eerie red glow!</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>")
|
||||
user.bhunger += drain
|
||||
src = user
|
||||
@@ -264,7 +272,7 @@ var/list/sacrificed = list()
|
||||
if(usr.loc==src.loc)
|
||||
if(usr.seer==1)
|
||||
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.seer = 0
|
||||
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)
|
||||
//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!")
|
||||
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'>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>", \
|
||||
"<span class='warning'>You feel as your blood boils, tearing you apart.</span>", \
|
||||
"<span class='warning'>You hear a thousand voices, all crying in pain.</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='danger'>You feel as your blood boils, tearing you apart.</span>", \
|
||||
"<span class='danger'>You hear a thousand voices, all crying in pain.</span>")
|
||||
body_to_sacrifice.gib()
|
||||
|
||||
// if(ticker.mode.name == "cult")
|
||||
@@ -349,8 +357,8 @@ var/list/sacrificed = list()
|
||||
// else
|
||||
// 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 << "<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'>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 << "<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
|
||||
|
||||
|
||||
@@ -391,7 +399,7 @@ var/list/sacrificed = list()
|
||||
if(usr.loc==src.loc)
|
||||
var/mob/living/carbon/human/L = usr
|
||||
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'>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!")
|
||||
@@ -461,8 +469,8 @@ var/list/sacrificed = list()
|
||||
user.take_organ_damage(1, 0)
|
||||
sleep(30)
|
||||
if(D)
|
||||
D.visible_message("<span class='warning'>\The [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>", \
|
||||
D.visible_message("<span class='danger'>[D] slowly dissipates into dust and bones.</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>")
|
||||
D.dust()
|
||||
return
|
||||
@@ -560,8 +568,8 @@ var/list/sacrificed = list()
|
||||
user.say("Uhrast ka'hfa heldsagen ver[pick("'","`")]lot!")
|
||||
user.take_overall_damage(200, 0)
|
||||
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>", \
|
||||
"<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>", \
|
||||
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='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>")
|
||||
for(,user.stat==2)
|
||||
sleep(600)
|
||||
@@ -592,9 +600,10 @@ var/list/sacrificed = list()
|
||||
usr.whisper("[input]")
|
||||
|
||||
input = sanitize(input)
|
||||
log_and_message_admins("used a communicate rune to say '[input]'")
|
||||
for(var/datum/mind/H in cult.current_antagonists)
|
||||
if (H.current)
|
||||
H.current << "<span class='danger'>[input]</span>"
|
||||
H.current << "<span class='cult'>[input]</span>"
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
@@ -638,17 +647,17 @@ var/list/sacrificed = list()
|
||||
H.dust()//To prevent the MMI from remaining
|
||||
else
|
||||
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
|
||||
usr << "<span class='warning'>Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual.</span>"
|
||||
else
|
||||
if(cultsinrange.len >= 3)
|
||||
if(H.stat !=2)
|
||||
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)
|
||||
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>"
|
||||
if(isrobot(H))
|
||||
H.dust()//To prevent the MMI from remaining
|
||||
@@ -656,10 +665,10 @@ var/list/sacrificed = list()
|
||||
H.gib()
|
||||
else
|
||||
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)
|
||||
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>"
|
||||
if(isrobot(H))
|
||||
H.dust()//To prevent the MMI from remaining
|
||||
@@ -671,10 +680,10 @@ var/list/sacrificed = list()
|
||||
else
|
||||
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)
|
||||
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>"
|
||||
if(isrobot(H))
|
||||
H.dust()//To prevent the MMI from remaining
|
||||
@@ -684,10 +693,10 @@ var/list/sacrificed = list()
|
||||
if(cultsinrange.len >= 3)
|
||||
if(H.stat !=2)
|
||||
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)
|
||||
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>"
|
||||
if(isrobot(H))
|
||||
H.dust()//To prevent the MMI from remaining
|
||||
@@ -695,10 +704,10 @@ var/list/sacrificed = list()
|
||||
H.gib()
|
||||
else
|
||||
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)
|
||||
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>"
|
||||
if(isrobot(H))
|
||||
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>"
|
||||
else
|
||||
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)
|
||||
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>"
|
||||
if(isrobot(H))
|
||||
H.dust()//To prevent the MMI from remaining
|
||||
@@ -771,9 +780,9 @@ var/list/sacrificed = list()
|
||||
var/mob/living/user = usr
|
||||
user.take_organ_damage(2, 0)
|
||||
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
|
||||
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
|
||||
|
||||
/////////////////////////////////////////EIGHTTEENTH RUNE
|
||||
@@ -842,7 +851,7 @@ var/list/sacrificed = list()
|
||||
if (cultist == user) //just to be sure.
|
||||
return
|
||||
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()
|
||||
cultist.loc = src.loc
|
||||
cultist.lying = 1
|
||||
@@ -922,7 +931,7 @@ var/list/sacrificed = list()
|
||||
C.disabilities |= NEARSIGHTED
|
||||
if(prob(10))
|
||||
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
|
||||
if(affected.len)
|
||||
usr.say("Sti[pick("'","`")] kaliesin!")
|
||||
@@ -972,7 +981,7 @@ var/list/sacrificed = list()
|
||||
if(N)
|
||||
continue
|
||||
M.take_overall_damage(51,51)
|
||||
M << "<span class='warning'>Your blood boils!</span>"
|
||||
M << "<span class='danger'>Your blood boils!</span>"
|
||||
victims += M
|
||||
if(prob(5))
|
||||
spawn(5)
|
||||
@@ -1004,16 +1013,16 @@ var/list/sacrificed = list()
|
||||
for(var/mob/living/M in orange(2,R))
|
||||
M.take_overall_damage(0,15)
|
||||
if (R.invisibility>M.see_invisible)
|
||||
M << "<span class='warning'>Aargh it burns!</span>"
|
||||
M << "<span class='danger'>Aargh it burns!</span>"
|
||||
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)
|
||||
T.hotspot_expose(700,125)
|
||||
for(var/obj/effect/decal/cleanable/blood/B in world)
|
||||
if(B.blood_DNA == src.blood_DNA)
|
||||
for(var/mob/living/M in orange(1,B))
|
||||
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)
|
||||
T.hotspot_expose(700,125)
|
||||
qdel(B)
|
||||
@@ -1032,13 +1041,13 @@ var/list/sacrificed = list()
|
||||
C.stuttering = 1
|
||||
C.Weaken(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")
|
||||
|
||||
else if(issilicon(L))
|
||||
var/mob/living/silicon/S = L
|
||||
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")
|
||||
qdel(src)
|
||||
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
|
||||
if(N)
|
||||
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
|
||||
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))
|
||||
T.Weaken(15)
|
||||
|
||||
@@ -326,7 +326,7 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
|
||||
|
||||
//AI laws
|
||||
for(var/mob/living/silicon/ai/M in living_mob_list)
|
||||
if(M.stat != 2 && M.has_power)
|
||||
if(M.stat != 2 && M.see_in_dark != 0)
|
||||
var/who2 = pick("ALIENS", "BEARS", "CLOWNS", "XENOS", "PETES", "BOMBS", "FETISHES", "WIZARDS", "SYNDICATE AGENTS", "CENTCOM OFFICERS", "SPACE PIRATES", "TRAITORS", "MONKEYS", "BEES", "CARP", "CRABS", "EELS", "BANDITS", "LIGHTS")
|
||||
var/what2 = pick("BOLTERS", "STAVES", "DICE", "SINGULARITIES", "TOOLBOXES", "NETTLES", "AIRLOCKS", "CLOTHES", "WEAPONS", "MEDKITS", "BOMBS", "CANISTERS", "CHAIRS", "BBQ GRILLS", "ID CARDS", "CAPTAINS")
|
||||
var/what2pref = pick("SOFT", "WARM", "WET", "COLD", "ICY", "SEXY", "UGLY", "CUBAN")
|
||||
|
||||
@@ -166,12 +166,14 @@ var/global/list/additional_antag_types = list()
|
||||
if(!(antag_templates && antag_templates.len))
|
||||
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/list/candidates = main_antags.get_candidates()
|
||||
if(candidates.len >= required_enemies)
|
||||
for(var/datum/antagonist/antag in antag_templates)
|
||||
antag.attempt_spawn()
|
||||
var/list/potential
|
||||
if(main_antags.flags & ANTAG_OVERRIDE_JOB)
|
||||
potential = main_antags.pending_antagonists
|
||||
else
|
||||
potential = main_antags.candidates
|
||||
|
||||
if(potential.len >= required_enemies)
|
||||
return 1
|
||||
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]
|
||||
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()
|
||||
/datum/game_mode/proc/post_setup()
|
||||
|
||||
@@ -198,11 +208,13 @@ var/global/list/additional_antag_types = list()
|
||||
spawn(rand(100,150))
|
||||
announce_ert_disabled()
|
||||
|
||||
if(antag_templates && antag_templates.len)
|
||||
for(var/datum/antagonist/antag in antag_templates)
|
||||
antag.finalize_spawn()
|
||||
if(antag.is_latejoin_template())
|
||||
latejoin_templates |= antag
|
||||
//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)
|
||||
if(!(antag.flags & ANTAG_OVERRIDE_JOB))
|
||||
antag.attempt_spawn() //select antags to be spawned
|
||||
antag.finalize_spawn() //actually spawn antags
|
||||
if(antag.is_latejoin_template())
|
||||
latejoin_templates |= antag
|
||||
|
||||
if(emergency_shuttle && auto_recall_shuttle)
|
||||
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]")
|
||||
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()
|
||||
if(!ert_disabled)
|
||||
return
|
||||
|
||||
@@ -91,11 +91,14 @@ var/global/datum/controller/gameticker/ticker
|
||||
else
|
||||
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.
|
||||
|
||||
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."
|
||||
current_state = GAME_STATE_PREGAME
|
||||
mode.fail_setup()
|
||||
mode = null
|
||||
job_master.ResetOccupations()
|
||||
return 0
|
||||
@@ -110,6 +113,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
else
|
||||
src.mode.announce()
|
||||
|
||||
setup_economy()
|
||||
current_state = GAME_STATE_PLAYING
|
||||
create_characters() //Create player characters and transfer them
|
||||
collect_minds()
|
||||
@@ -118,9 +122,6 @@ var/global/datum/controller/gameticker/ticker
|
||||
|
||||
callHook("roundstart")
|
||||
|
||||
//here to initialize the random events nicely at round start
|
||||
setup_economy()
|
||||
|
||||
shuttle_controller.setup_shuttle_docks()
|
||||
|
||||
spawn(0)//Forking here so we dont have to wait for this to finish
|
||||
|
||||
@@ -20,12 +20,3 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
|
||||
if (skipjack && skipjack.returned_home)
|
||||
return 1
|
||||
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
|
||||
@@ -1252,7 +1252,7 @@ datum
|
||||
proc/find_target()
|
||||
..()
|
||||
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
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
@@ -1261,7 +1261,7 @@ datum
|
||||
find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
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
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
@@ -1488,4 +1488,4 @@ datum/objective/silence
|
||||
#undef LENIENT
|
||||
#undef NORMAL
|
||||
#undef HARD
|
||||
#undef IMPOSSIBLE
|
||||
#undef IMPOSSIBLE
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/game_mode/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."
|
||||
config_tag = "wizard"
|
||||
required_players = 1
|
||||
|
||||
@@ -305,17 +305,8 @@
|
||||
desc = "Cargo Office"
|
||||
region = ACCESS_REGION_SUPPLY
|
||||
|
||||
/var/const/access_mint = 51
|
||||
/datum/access/mint
|
||||
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/free_access_id = 51
|
||||
// /var/const/free_access_id = 52
|
||||
|
||||
/var/const/access_heads_vault = 53
|
||||
/datum/access/heads_vault
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
selection_color = "#dddddd"
|
||||
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)
|
||||
if(!H) return 0
|
||||
|
||||
@@ -97,8 +97,8 @@
|
||||
spawn_positions = 1
|
||||
supervisors = "the head of personnel"
|
||||
selection_color = "#dddddd"
|
||||
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_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_mining, access_mining_station)
|
||||
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
@@ -124,7 +124,7 @@
|
||||
spawn_positions = 2
|
||||
supervisors = "the quartermaster and the head of personnel"
|
||||
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)
|
||||
|
||||
|
||||
@@ -149,8 +149,8 @@
|
||||
spawn_positions = 3
|
||||
supervisors = "the quartermaster and the head of personnel"
|
||||
selection_color = "#dddddd"
|
||||
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_mining, access_mint, access_mining_station, access_mailsorting)
|
||||
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_mining_station, access_mailsorting)
|
||||
alt_titles = list("Drill Technician","Prospector")
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
|
||||
@@ -177,11 +177,6 @@
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
allow_drop()
|
||||
return 0
|
||||
|
||||
|
||||
process()
|
||||
if (stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
@@ -342,7 +337,7 @@
|
||||
if(src.occupant.reagents.get_reagent_amount(chemical) + amount <= 20)
|
||||
use_power(amount * CHEM_SYNTH_ENERGY)
|
||||
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
|
||||
user << "There's no occupant in the sleeper or the subject has too many chemicals!"
|
||||
return
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
idle_power_usage = 60
|
||||
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)
|
||||
if (user.stat)
|
||||
return
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
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/pressure_dangerlevel = 0
|
||||
@@ -240,23 +241,24 @@
|
||||
/obj/machinery/alarm/proc/overall_danger_level(var/datum/gas_mixture/environment)
|
||||
var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
|
||||
var/environment_pressure = environment.return_pressure()
|
||||
//var/other_moles = 0.0
|
||||
////for(var/datum/gas/G in environment.trace_gases)
|
||||
// other_moles+=G.moles
|
||||
|
||||
var/other_moles = 0
|
||||
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"])
|
||||
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"])
|
||||
phoron_dangerlevel = get_danger_level(environment.gas["phoron"]*partial_pressure, TLV["phoron"])
|
||||
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(
|
||||
pressure_dangerlevel,
|
||||
oxygen_dangerlevel,
|
||||
co2_dangerlevel,
|
||||
phoron_dangerlevel,
|
||||
//other_dangerlevel,
|
||||
other_dangerlevel,
|
||||
temperature_dangerlevel
|
||||
)
|
||||
|
||||
@@ -302,22 +304,30 @@
|
||||
/obj/machinery/alarm/update_icon()
|
||||
if(wiresexposed)
|
||||
icon_state = "alarmx"
|
||||
set_light(0)
|
||||
return
|
||||
if((stat & (NOPOWER|BROKEN)) || shorted)
|
||||
icon_state = "alarmp"
|
||||
set_light(0)
|
||||
return
|
||||
|
||||
var/icon_level = danger_level
|
||||
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
|
||||
|
||||
var/new_color = null
|
||||
switch(icon_level)
|
||||
if (0)
|
||||
icon_state = "alarm0"
|
||||
new_color = "#03A728"
|
||||
if (1)
|
||||
icon_state = "alarm2" //yes, alarm2 is yellow alarm
|
||||
new_color = "#EC8B2F"
|
||||
if (2)
|
||||
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)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
@@ -504,34 +514,13 @@
|
||||
var/list/environment_data = new
|
||||
data["has_environment"] = 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_danger = get_danger_level(pressure, current_settings)
|
||||
environment_data[++environment_data.len] = list("name" = "Pressure", "value" = pressure, "unit" = "kPa", "danger_level" = pressure_danger)
|
||||
data["total_danger"] = pressure_danger
|
||||
|
||||
current_settings = TLV["oxygen"]
|
||||
var/oxygen_danger = get_danger_level(environment.gas["oxygen"]*partial_pressure, current_settings)
|
||||
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"])
|
||||
|
||||
environment_data[++environment_data.len] = list("name" = "Pressure", "value" = pressure, "unit" = "kPa", "danger_level" = pressure_dangerlevel)
|
||||
environment_data[++environment_data.len] = list("name" = "Oxygen", "value" = environment.gas["oxygen"] / total * 100, "unit" = "%", "danger_level" = oxygen_dangerlevel)
|
||||
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)
|
||||
environment_data[++environment_data.len] = list("name" = "Temperature", "value" = environment.temperature, "unit" = "K ([round(environment.temperature - T0C, 0.1)]C)", "danger_level" = temperature_dangerlevel)
|
||||
data["total_danger"] = danger_level
|
||||
data["environment"] = environment_data
|
||||
data["atmos_alarm"] = alarm_area.atmosalm
|
||||
data["fire_alarm"] = alarm_area.fire != null
|
||||
@@ -888,8 +877,11 @@ FIRE ALARM
|
||||
var/last_process = 0
|
||||
var/wiresexposed = 0
|
||||
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
|
||||
var/seclevel
|
||||
|
||||
/obj/machinery/firealarm/update_icon()
|
||||
overlays.Cut()
|
||||
|
||||
if(wiresexposed)
|
||||
switch(buildstage)
|
||||
if(2)
|
||||
@@ -898,17 +890,28 @@ FIRE ALARM
|
||||
icon_state="fire_b1"
|
||||
if(0)
|
||||
icon_state="fire_b0"
|
||||
|
||||
set_light(0)
|
||||
return
|
||||
|
||||
if(stat & BROKEN)
|
||||
icon_state = "firex"
|
||||
set_light(0)
|
||||
else if(stat & NOPOWER)
|
||||
icon_state = "firep"
|
||||
else if(!src.detecting)
|
||||
icon_state = "fire1"
|
||||
set_light(0)
|
||||
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)
|
||||
if(src.detecting)
|
||||
@@ -919,7 +922,7 @@ FIRE ALARM
|
||||
/obj/machinery/firealarm/attack_ai(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/firealarm/bullet_act(BLAH)
|
||||
/obj/machinery/firealarm/bullet_act()
|
||||
return src.alarm()
|
||||
|
||||
/obj/machinery/firealarm/emp_act(severity)
|
||||
@@ -1121,14 +1124,14 @@ FIRE ALARM
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
|
||||
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()
|
||||
if(z in config.contact_levels)
|
||||
if(security_level)
|
||||
src.overlays += image('icons/obj/monitors.dmi', "overlay_[get_security_level()]")
|
||||
else
|
||||
src.overlays += image('icons/obj/monitors.dmi', "overlay_green")
|
||||
|
||||
update_icon()
|
||||
set_security_level(security_level? get_security_level() : "green")
|
||||
|
||||
/*
|
||||
FIRE ALARM CIRCUIT
|
||||
|
||||
@@ -104,7 +104,6 @@
|
||||
network.update = 1
|
||||
|
||||
/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 (src.holding)
|
||||
return
|
||||
@@ -136,21 +135,8 @@
|
||||
return
|
||||
|
||||
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>")
|
||||
if(air_contents)
|
||||
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)]°C</span>"
|
||||
else
|
||||
user << "<span class='notice'>Tank is empty!</span>"
|
||||
else
|
||||
user << "<span class='notice'>Tank is empty!</span>"
|
||||
var/obj/item/device/analyzer/A = W
|
||||
A.analyze_gases(src, user)
|
||||
return
|
||||
|
||||
return
|
||||
@@ -163,6 +149,13 @@
|
||||
var/last_power_draw = 0
|
||||
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)
|
||||
if(istype(I, /obj/item/weapon/cell))
|
||||
if(cell)
|
||||
@@ -176,6 +169,7 @@
|
||||
cell = C
|
||||
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>")
|
||||
power_change()
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
@@ -187,8 +181,8 @@
|
||||
cell.add_fingerprint(user)
|
||||
cell.loc = src.loc
|
||||
cell = null
|
||||
power_change()
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/portable_atmospherics/proc/log_open()
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
|
||||
//ran out of charge
|
||||
if (!cell.charge)
|
||||
power_change()
|
||||
update_icon()
|
||||
|
||||
src.updateDialog()
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
|
||||
//ran out of charge
|
||||
if (!cell.charge)
|
||||
power_change()
|
||||
update_icon()
|
||||
|
||||
//src.update_icon()
|
||||
@@ -147,7 +148,6 @@
|
||||
volume = 50000
|
||||
volume_rate = 5000
|
||||
|
||||
chan
|
||||
use_power = 1
|
||||
idle_power_usage = 500 //internal circuitry, friction losses and stuff
|
||||
active_power_usage = 100000 //100 kW ~ 135 HP
|
||||
|
||||
@@ -290,7 +290,7 @@
|
||||
/obj/machinery/autolathe/dismantle()
|
||||
|
||||
for(var/mat in stored_material)
|
||||
var/material/M = name_to_material[mat]
|
||||
var/material/M = get_material_by_name(mat)
|
||||
if(!istype(M))
|
||||
continue
|
||||
var/obj/item/stack/material/S = new M.stack_type(get_turf(src))
|
||||
|
||||
@@ -66,19 +66,19 @@
|
||||
user << "<span class='info'>You inject the blood sample into the bioprinter.</span>"
|
||||
return
|
||||
// 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
|
||||
user.drop_item()
|
||||
user << "<span class='info'>\The [src] processes \the [W]. Levels of stored biomass now: [stored_matter]</span>"
|
||||
qdel(W)
|
||||
return
|
||||
// Steel for matter.
|
||||
else if(prints_prosthetics && istype(W, /obj/item/stack/material/steel))
|
||||
var/obj/item/stack/material/steel/M = W
|
||||
stored_matter += M.amount * 10
|
||||
if(prints_prosthetics && istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL)
|
||||
var/obj/item/stack/S = W
|
||||
stored_matter += S.amount * 10
|
||||
user.drop_item()
|
||||
user << "<span class='info'>\The [src] processes \the [W]. Levels of stored matter now: [stored_matter]</span>"
|
||||
qdel(W)
|
||||
return
|
||||
else
|
||||
return..()
|
||||
|
||||
return..()
|
||||
@@ -59,7 +59,7 @@
|
||||
..()
|
||||
wires = 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.charge = 2000
|
||||
cell.maxcharge = 2000
|
||||
|
||||
@@ -88,8 +88,8 @@
|
||||
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( loc )
|
||||
A.amount = 5
|
||||
|
||||
if(istype(P, /obj/item/stack/material/glass/reinforced))
|
||||
var/obj/item/stack/material/glass/reinforced/RG = P
|
||||
if(istype(P, /obj/item/stack/material) && P.get_material_name() == "rglass")
|
||||
var/obj/item/stack/RG = P
|
||||
if (RG.get_amount() < 2)
|
||||
user << "<span class='warning'>You need two sheets of glass to put in the glass panel.</span>"
|
||||
return
|
||||
@@ -201,6 +201,7 @@
|
||||
transfer.control_disabled = 0
|
||||
transfer.aiRadio.disabledAi = 0
|
||||
transfer.loc = get_turf(src)
|
||||
transfer.create_eyeobj()
|
||||
transfer.cancel_camera()
|
||||
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."
|
||||
|
||||
@@ -87,8 +87,8 @@
|
||||
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( src.loc )
|
||||
A.amount = 5
|
||||
|
||||
if(istype(P, /obj/item/stack/material/glass))
|
||||
var/obj/item/stack/material/glass/G = P
|
||||
if(istype(P, /obj/item/stack/material) && P.get_material_name() == "glass")
|
||||
var/obj/item/stack/G = P
|
||||
if (G.get_amount() < 2)
|
||||
user << "<span class='warning'>You need two sheets of glass to put in the glass panel.</span>"
|
||||
return
|
||||
|
||||
@@ -178,12 +178,13 @@
|
||||
if(istype(P, /obj/item/weapon/crowbar)) // complicated check
|
||||
remove_peripheral()
|
||||
|
||||
if(istype(P, /obj/item/stack/material/glass))
|
||||
if(P:amount >= 2)
|
||||
if(istype(P, /obj/item/stack/material) && P.get_material_name() == "glass")
|
||||
var/obj/item/stack/S = P
|
||||
if(S.amount >= 2)
|
||||
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
if(P)
|
||||
P:use(2)
|
||||
if(S)
|
||||
S.use(2)
|
||||
user << "<span class='notice'>You put in the glass panel.</span>"
|
||||
src.state = 4
|
||||
src.icon_state = "4"
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
name = "Security Camera Network Main Key"
|
||||
var/title = "Station"
|
||||
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"
|
||||
|
||||
execute(var/datum/file/source)
|
||||
@@ -76,58 +76,65 @@
|
||||
return
|
||||
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
|
||||
name = "Mining Camera Network Key"
|
||||
title = "mining station"
|
||||
desc = "Connects to mining security cameras."
|
||||
networks = list("MINE")
|
||||
networks = list(NETWORK_MINE)
|
||||
screen = "miningcameras"
|
||||
|
||||
/datum/file/camnet_key/research
|
||||
name = "Research Camera Network Key"
|
||||
title = "research"
|
||||
networks = list("RD")
|
||||
networks = list(NETWORK_RESEARCH)
|
||||
|
||||
/datum/file/camnet_key/bombrange
|
||||
name = "R&D Bomb Range Camera Network Key"
|
||||
title = "bomb range"
|
||||
desc = "Monitors the bomb range."
|
||||
networks = list("Toxins")
|
||||
networks = list(NETWORK_RESEARCH)
|
||||
|
||||
/datum/file/camnet_key/xeno
|
||||
name = "R&D Misc. Research Camera Network Key"
|
||||
title = "special research"
|
||||
networks = list("Misc")
|
||||
networks = list(NETWORK_RESEARCH)
|
||||
|
||||
/datum/file/camnet_key/singulo
|
||||
name = "Singularity Camera Network Key"
|
||||
title = "singularity"
|
||||
networks = list("Singularity")
|
||||
networks = list(NETWORK_ENGINE)
|
||||
|
||||
/datum/file/camnet_key/entertainment
|
||||
name = "Entertainment Channel Encryption Key"
|
||||
title = "entertainment"
|
||||
desc = "Damn, I hope they have /tg/thechannel on here."
|
||||
networks = list("thunder")
|
||||
networks = list(NETWORK_THUNDER)
|
||||
screen = "entertainment"
|
||||
|
||||
/datum/file/camnet_key/creed
|
||||
name = "Special Ops Camera Encryption Key"
|
||||
title = "special ops"
|
||||
desc = "Connects to special ops secure camera feeds."
|
||||
networks = list("CREED")
|
||||
networks = list(NETWORK_ERT)
|
||||
|
||||
/datum/file/camnet_key/prison
|
||||
name = "Prison Camera Network Key"
|
||||
title = "prison"
|
||||
desc = "Monitors the prison."
|
||||
networks = list("Prison")
|
||||
networks = list(NETWORK_SECURITY)
|
||||
|
||||
/datum/file/camnet_key/syndicate
|
||||
name = "Camera Network Key"
|
||||
title = "%!#BUFFER OVERFLOW"
|
||||
desc = "Connects to security cameras."
|
||||
networks = list("SS13")
|
||||
networks = list("ALL")
|
||||
hidden_file = 1
|
||||
|
||||
|
||||
|
||||
@@ -106,12 +106,16 @@
|
||||
pixel_x = 2
|
||||
pixel_y = -3
|
||||
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
|
||||
|
||||
New(var/L, var/built = 0)
|
||||
if(!built && !battery)
|
||||
battery = new /obj/item/weapon/cell(src)
|
||||
battery.maxcharge = 500
|
||||
battery.charge = 500
|
||||
..(L,built)
|
||||
|
||||
verb/close_computer()
|
||||
|
||||
@@ -202,11 +202,11 @@
|
||||
if (network == 3)
|
||||
newlap.spawn_parts += (/obj/item/part/computer/networking/cable)
|
||||
if (power == 1)
|
||||
qdel(newlap.battery)
|
||||
newlap.battery = new /obj/item/weapon/cell/high(newlap)
|
||||
newlap.battery.maxcharge = 1000
|
||||
newlap.battery.charge = 1000
|
||||
if (power == 2)
|
||||
qdel(newlap.battery)
|
||||
newlap.battery = new /obj/item/weapon/cell/super(newlap)
|
||||
newlap.battery.maxcharge = 1750
|
||||
newlap.battery.charge = 1750
|
||||
|
||||
newlap.spawn_parts()
|
||||
|
||||
|
||||
@@ -60,11 +60,6 @@
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/cryo_cell/allow_drop()
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/cryo_cell/relaymove(mob/user as mob)
|
||||
if(user.stat)
|
||||
return
|
||||
|
||||
@@ -79,12 +79,14 @@ for reference:
|
||||
maxhealth = material.integrity
|
||||
health = maxhealth
|
||||
|
||||
/obj/structure/barricade/get_material()
|
||||
return material
|
||||
|
||||
/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (istype(W, /obj/item/stack/material))
|
||||
var/obj/item/stack/material/D = W
|
||||
if(D.material.name != material.name)
|
||||
user << "<span class='warning'>That is the wrong material needed to repair \the [src].</span>"
|
||||
return
|
||||
if (istype(W, /obj/item/stack))
|
||||
var/obj/item/stack/D = W
|
||||
if(D.get_material_name() != material.name)
|
||||
return //hitting things with the wrong type of stack usually doesn't produce messages, and probably doesn't need to.
|
||||
if (health < maxhealth)
|
||||
if (D.get_amount() < 1)
|
||||
user << "<span class='warning'>You need one sheet of [material.display_name] to repair \the [src].</span>"
|
||||
|
||||
@@ -48,6 +48,11 @@
|
||||
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
|
||||
name = "Airlock"
|
||||
icon = 'icons/obj/doors/Doorcom.dmi'
|
||||
|
||||
@@ -96,12 +96,12 @@
|
||||
else
|
||||
usr << "<span class='notice'>[src]'s motors resist your effort.</span>"
|
||||
return
|
||||
if(istype(C, /obj/item/stack/material/plasteel))
|
||||
var/amt = repair_price()
|
||||
if(istype(C, /obj/item/stack/material) && C.get_material_name() == "plasteel")
|
||||
var/amt = Ceiling((maxhealth - health)/150)
|
||||
if(!amt)
|
||||
usr << "<span class='notice'>\The [src] is already fully repaired.</span>"
|
||||
return
|
||||
var/obj/item/stack/material/plasteel/P = C
|
||||
var/obj/item/stack/P = C
|
||||
if(P.amount < amt)
|
||||
usr << "<span class='warning'>You don't have enough sheets to repair this! You need at least [amt] sheets.</span>"
|
||||
return
|
||||
@@ -135,16 +135,6 @@
|
||||
return
|
||||
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()
|
||||
// Parameters: None
|
||||
@@ -154,7 +144,7 @@
|
||||
if(stat & BROKEN)
|
||||
stat &= ~BROKEN
|
||||
|
||||
|
||||
|
||||
/obj/machinery/door/blast/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group) return 1
|
||||
return ..()
|
||||
|
||||
@@ -103,6 +103,13 @@
|
||||
bumpopen(M)
|
||||
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))
|
||||
var/mob/living/bot/bot = AM
|
||||
if(src.check_access(bot.botcard))
|
||||
@@ -199,10 +206,9 @@
|
||||
/obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(istype(I, /obj/item/device/detective_scanner))
|
||||
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)
|
||||
|
||||
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)
|
||||
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
|
||||
@@ -217,20 +223,20 @@
|
||||
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?
|
||||
|
||||
var/obj/item/stack/material/steel/metalstack = I
|
||||
var/obj/item/stack/stack = I
|
||||
var/transfer
|
||||
if (repairing)
|
||||
transfer = metalstack.transfer_to(repairing, amount_needed - repairing.amount)
|
||||
transfer = stack.transfer_to(repairing, amount_needed - repairing.amount)
|
||||
if (!transfer)
|
||||
user << "<span class='warning'>You must weld or remove \the [repairing] from \the [src] before you can add anything else.</span>"
|
||||
else
|
||||
repairing = metalstack.split(amount_needed)
|
||||
repairing = stack.split(amount_needed)
|
||||
if (repairing)
|
||||
repairing.loc = src
|
||||
transfer = repairing.amount
|
||||
|
||||
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
|
||||
|
||||
@@ -270,6 +276,8 @@
|
||||
take_damage(W.force)
|
||||
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.allowed(user) && operable())
|
||||
@@ -333,7 +341,8 @@
|
||||
|
||||
/obj/machinery/door/emp_act(severity)
|
||||
if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) )
|
||||
open()
|
||||
spawn(0)
|
||||
open()
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -75,6 +75,8 @@
|
||||
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)
|
||||
. = ..(user, 1)
|
||||
|
||||
@@ -176,7 +176,7 @@ Class Procs:
|
||||
qdel(src)
|
||||
|
||||
//sets the use_power var and then forces an area power update
|
||||
/obj/machinery/proc/update_use_power(var/new_use_power, var/force_update = 0)
|
||||
/obj/machinery/proc/update_use_power(var/new_use_power)
|
||||
use_power = new_use_power
|
||||
|
||||
/obj/machinery/proc/auto_use_power()
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
user.visible_message("<span class='notice'>[user] has [!a_dis?"de":""]activated auto-dismantling.</span>", "<span class='notice'>You [!a_dis?"de":""]activate auto-dismantling.</span>")
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/stack/material/steel))
|
||||
if(istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL)
|
||||
|
||||
var/result = load_metal(W)
|
||||
if(isnull(result))
|
||||
@@ -86,7 +86,7 @@
|
||||
on=0
|
||||
return
|
||||
|
||||
/obj/machinery/pipelayer/proc/load_metal(var/obj/item/stack/material/steel/MM)
|
||||
/obj/machinery/pipelayer/proc/load_metal(var/obj/item/stack/MM)
|
||||
if(istype(MM) && MM.get_amount())
|
||||
var/cur_amount = metal
|
||||
var/to_load = max(max_metal - round(cur_amount),0)
|
||||
|
||||
@@ -399,15 +399,16 @@ var/list/turret_icons
|
||||
emagged = 1
|
||||
|
||||
enabled=0
|
||||
sleep(rand(60,600))
|
||||
if(!enabled)
|
||||
enabled=1
|
||||
spawn(rand(60,600))
|
||||
if(!enabled)
|
||||
enabled=1
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/porta_turret/ex_act(severity)
|
||||
switch (severity)
|
||||
if (1)
|
||||
del(src)
|
||||
qdel(src)
|
||||
if (2)
|
||||
if (prob(25))
|
||||
@@ -624,6 +625,14 @@ var/list/turret_icons
|
||||
// Emagged turrets again use twice as much power due to higher firing rates
|
||||
use_power(reqpower * (2 * (emagged || lethal)) * (2 * emagged))
|
||||
|
||||
//Turrets aim for the center of mass by default.
|
||||
//If the target is grabbing someone then the turret smartly aims for extremities
|
||||
var/obj/item/weapon/grab/G = locate() in target
|
||||
if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people.
|
||||
A.def_zone = pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
else
|
||||
A.def_zone = pick("chest", "groin")
|
||||
|
||||
//Shooting Code:
|
||||
A.current = T
|
||||
A.starting = T
|
||||
@@ -696,8 +705,8 @@ var/list/turret_icons
|
||||
return
|
||||
|
||||
if(1)
|
||||
if(istype(I, /obj/item/stack/material/steel))
|
||||
var/obj/item/stack/material/steel/M = I
|
||||
if(istype(I, /obj/item/stack/material) && I.get_material_name() == DEFAULT_WALL_MATERIAL)
|
||||
var/obj/item/stack/M = I
|
||||
if(M.use(2))
|
||||
user << "<span class='notice'>You add some metal armor to the interior frame.</span>"
|
||||
build_step = 2
|
||||
@@ -788,8 +797,8 @@ var/list/turret_icons
|
||||
//attack_hand() removes the prox sensor
|
||||
|
||||
if(6)
|
||||
if(istype(I, /obj/item/stack/material/steel))
|
||||
var/obj/item/stack/material/steel/M = I
|
||||
if(istype(I, /obj/item/stack/material) && I.get_material_name() == DEFAULT_WALL_MATERIAL)
|
||||
var/obj/item/stack/M = I
|
||||
if(M.use(2))
|
||||
user << "<span class='notice'>You add some metal armor to the exterior frame.</span>"
|
||||
build_step = 7
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
/obj/machinery/recharge_station
|
||||
name = "cyborg recharging station"
|
||||
desc = "A heavy duty rapid charging system, designed to quickly recharge cyborg power reserves."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "borgcharger0"
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 50
|
||||
active_power_usage = 50
|
||||
var/mob/occupant = null
|
||||
var/obj/item/weapon/cell/cell = null
|
||||
//var/max_internal_charge = 15000 // Two charged borgs in a row with default cell
|
||||
//var/current_internal_charge = 15000 // Starts charged, to prevent power surges on round start
|
||||
var/charging_cap_active = 1000 // Active Cap - When cyborg is inside
|
||||
var/charging_cap_passive = 250 // Passive Cap - Recharging internal capacitor when no cyborg is inside
|
||||
var/icon_update_tick = 0 // Used to update icon only once every 10 ticks
|
||||
var/charge_rate = 250 // How much charge is restored per tick
|
||||
var/weld_rate = 0 // How much brute damage is repaired per tick
|
||||
var/wire_rate = 0 // How much burn damage is repaired per tick
|
||||
var/icon_update_tick = 0 // Used to rebuild the overlay only once every 10 ticks
|
||||
var/charging = 0
|
||||
|
||||
var/charging_power // W. Power rating used for charging the cyborg. 120 kW if un-upgraded
|
||||
var/restore_power_active // W. Power drawn from APC when an occupant is charging. 40 kW if un-upgraded
|
||||
var/restore_power_passive // W. Power drawn from APC when idle. 7 kW if un-upgraded
|
||||
var/weld_rate = 0 // How much brute damage is repaired per tick
|
||||
var/wire_rate = 0 // How much burn damage is repaired per tick
|
||||
|
||||
var/weld_power_use = 2300 // power used per point of brute damage repaired. 2.3 kW ~ about the same power usage of a handheld arc welder
|
||||
var/wire_power_use = 500 // power used per point of burn damage repaired.
|
||||
|
||||
/obj/machinery/recharge_station/New()
|
||||
..()
|
||||
@@ -30,51 +33,76 @@
|
||||
component_parts += new /obj/item/weapon/cell/high(src)
|
||||
component_parts += new /obj/item/stack/cable_coil(src, 5)
|
||||
|
||||
build_icon()
|
||||
RefreshParts()
|
||||
|
||||
update_icon()
|
||||
|
||||
RefreshParts()
|
||||
/obj/machinery/recharge_station/proc/has_cell_power()
|
||||
return cell && cell.percent() > 0
|
||||
|
||||
/obj/machinery/recharge_station/process()
|
||||
if(stat & (BROKEN))
|
||||
return
|
||||
|
||||
if((stat & (NOPOWER)) && (!cell || cell.percent() <= 0)) // No Power.
|
||||
return
|
||||
|
||||
var/chargemode = 0
|
||||
if(occupant)
|
||||
process_occupant()
|
||||
chargemode = 1
|
||||
// Power Stuff
|
||||
|
||||
if(!cell) // Shouldn't be possible, but sanity check
|
||||
return
|
||||
|
||||
if(stat & NOPOWER)
|
||||
cell.use(50 * CELLRATE) // Internal Circuitry, 50W load. No power - Runs from internal cell
|
||||
return // No external power = No charging
|
||||
if((stat & NOPOWER) && !has_cell_power()) // No power and cell is dead.
|
||||
if(icon_update_tick)
|
||||
icon_update_tick = 0 //just rebuild the overlay once more only
|
||||
update_icon()
|
||||
return
|
||||
|
||||
// Calculating amount of power to draw
|
||||
var/charge_diff = (chargemode ? charging_cap_active : charging_cap_passive) + 50 // 50W for circuitry
|
||||
//First, draw from the internal power cell to recharge/repair/etc the occupant
|
||||
if(occupant)
|
||||
process_occupant()
|
||||
|
||||
charge_diff = cell.give(charge_diff)
|
||||
//Then, if external power is available, recharge the internal cell
|
||||
var/recharge_amount = 0
|
||||
if(!(stat & NOPOWER))
|
||||
// Calculating amount of power to draw
|
||||
recharge_amount = (occupant ? restore_power_active : restore_power_passive) * CELLRATE
|
||||
|
||||
if(idle_power_usage != charge_diff) // Force update, but only when our power usage changed this tick.
|
||||
idle_power_usage = charge_diff
|
||||
update_use_power(1, 1)
|
||||
recharge_amount = cell.give(recharge_amount)
|
||||
use_power(recharge_amount / CELLRATE)
|
||||
|
||||
if(icon_update_tick >= 10)
|
||||
update_icon()
|
||||
icon_update_tick = 0
|
||||
else
|
||||
icon_update_tick++
|
||||
|
||||
if(occupant || recharge_amount)
|
||||
update_icon()
|
||||
|
||||
//since the recharge station can still be on even with NOPOWER. Instead it draws from the internal cell.
|
||||
/obj/machinery/recharge_station/auto_use_power()
|
||||
if(!(stat & NOPOWER))
|
||||
return ..()
|
||||
|
||||
if(!has_cell_power())
|
||||
return 0
|
||||
if(src.use_power == 1)
|
||||
cell.use(idle_power_usage * CELLRATE)
|
||||
else if(src.use_power >= 2)
|
||||
cell.use(active_power_usage * CELLRATE)
|
||||
return 1
|
||||
|
||||
//Processes the occupant, drawing from the internal power cell if needed.
|
||||
/obj/machinery/recharge_station/proc/process_occupant()
|
||||
if(istype(occupant, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = occupant
|
||||
|
||||
/obj/machinery/recharge_station/allow_drop()
|
||||
return 0
|
||||
if(R.module)
|
||||
R.module.respawn_consumable(R, charging_power * CELLRATE / 250) //consumables are magical, apparently
|
||||
if(R.cell && !R.cell.fully_charged())
|
||||
var/diff = min(R.cell.maxcharge - R.cell.charge, charging_power * CELLRATE) // Capped by charging_power / tick
|
||||
var/charge_used = cell.use(diff)
|
||||
R.cell.give(charge_used)
|
||||
|
||||
//Lastly, attempt to repair the cyborg if enabled
|
||||
if(weld_rate && R.getBruteLoss() && cell.checked_use(weld_power_use * weld_rate * CELLRATE))
|
||||
R.adjustBruteLoss(-weld_rate)
|
||||
if(wire_rate && R.getFireLoss() && cell.checked_use(wire_power_use * wire_rate * CELLRATE))
|
||||
R.adjustFireLoss(-wire_rate)
|
||||
|
||||
/obj/machinery/recharge_station/examine(mob/user)
|
||||
..(user)
|
||||
@@ -92,9 +120,6 @@
|
||||
return
|
||||
|
||||
/obj/machinery/recharge_station/emp_act(severity)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
..(severity)
|
||||
return
|
||||
if(occupant)
|
||||
occupant.emp_act(severity)
|
||||
go_out()
|
||||
@@ -125,13 +150,20 @@
|
||||
man_rating += P.rating
|
||||
cell = locate(/obj/item/weapon/cell) in component_parts
|
||||
|
||||
charge_rate = 125 * cap_rating
|
||||
charging_cap_passive = charge_rate
|
||||
charging_power = 40000 + 40000 * cap_rating
|
||||
restore_power_active = 10000 + 15000 * cap_rating
|
||||
restore_power_passive = 5000 + 1000 * cap_rating
|
||||
weld_rate = max(0, man_rating - 3)
|
||||
wire_rate = max(0, man_rating - 5)
|
||||
|
||||
/obj/machinery/recharge_station/update_icon()
|
||||
..()
|
||||
desc = initial(desc)
|
||||
desc += " Uses a dedicated internal power cell to deliver [charging_power]W when in use."
|
||||
if(weld_rate)
|
||||
desc += "<br>It is capable of repairing structural damage."
|
||||
if(wire_rate)
|
||||
desc += "<br>It is capable of repairing burn damage."
|
||||
|
||||
/obj/machinery/recharge_station/proc/build_overlays()
|
||||
overlays.Cut()
|
||||
switch(round(chargepercentage()))
|
||||
if(1 to 20)
|
||||
@@ -147,53 +179,33 @@
|
||||
if(99 to 110)
|
||||
overlays += image('icons/obj/objects.dmi', "statn_c100")
|
||||
|
||||
/obj/machinery/recharge_station/Bumped(var/mob/AM)
|
||||
move_inside(AM)
|
||||
/obj/machinery/recharge_station/update_icon()
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "borgcharger0"
|
||||
return
|
||||
|
||||
/obj/machinery/recharge_station/proc/build_icon()
|
||||
if(NOPOWER|BROKEN)
|
||||
if(occupant)
|
||||
icon_state = "borgcharger1"
|
||||
if(occupant)
|
||||
if((stat & NOPOWER) && !has_cell_power())
|
||||
icon_state = "borgcharger2"
|
||||
else
|
||||
icon_state = "borgcharger0"
|
||||
icon_state = "borgcharger1"
|
||||
else
|
||||
icon_state = "borgcharger0"
|
||||
|
||||
/obj/machinery/recharge_station/proc/process_occupant()
|
||||
if(occupant)
|
||||
if(istype(occupant, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = occupant
|
||||
if(R.module)
|
||||
R.module.respawn_consumable(R, charge_rate / 250)
|
||||
if(!R.cell)
|
||||
return
|
||||
if(!R.cell.fully_charged())
|
||||
var/diff = min(R.cell.maxcharge - R.cell.charge, charge_rate) // Capped at charge_rate charge / tick
|
||||
if (cell.charge >= diff)
|
||||
cell.use(diff)
|
||||
R.cell.give(diff)
|
||||
if(weld_rate && R.getBruteLoss())
|
||||
R.adjustBruteLoss(-1)
|
||||
if(wire_rate && R.getFireLoss())
|
||||
R.adjustFireLoss(-1)
|
||||
else if(istype(occupant, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = occupant
|
||||
if(!isnull(H.internal_organs_by_name["cell"]) && H.nutrition < 450)
|
||||
H.nutrition = min(H.nutrition+10, 450)
|
||||
update_use_power(1)
|
||||
if(icon_update_tick == 0)
|
||||
build_overlays()
|
||||
|
||||
/obj/machinery/recharge_station/Bumped(var/mob/AM)
|
||||
move_inside(AM)
|
||||
|
||||
/obj/machinery/recharge_station/proc/go_out()
|
||||
if(!(occupant))
|
||||
return
|
||||
//for(var/obj/O in src)
|
||||
// O.loc = loc
|
||||
if(occupant.client)
|
||||
occupant.client.eye = occupant.client.mob
|
||||
occupant.client.perspective = MOB_PERSPECTIVE
|
||||
occupant.loc = loc
|
||||
occupant.reset_view()
|
||||
occupant = null
|
||||
build_icon()
|
||||
update_use_power(1)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/recharge_station/verb/move_eject()
|
||||
@@ -205,49 +217,26 @@
|
||||
add_fingerprint(usr)
|
||||
return
|
||||
|
||||
/obj/machinery/recharge_station/verb/move_inside(var/mob/user = usr)
|
||||
/obj/machinery/recharge_station/verb/move_inside()
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(!user)
|
||||
if(usr.stat == DEAD)
|
||||
return
|
||||
if(occupant)
|
||||
usr << "<span class='notice'>\The [src] is already occupied!</span>"
|
||||
return
|
||||
|
||||
var/can_accept_user
|
||||
if(istype(user, /mob/living/silicon/robot))
|
||||
|
||||
var/mob/living/silicon/robot/R = user
|
||||
|
||||
if(R.stat == 2)
|
||||
//Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO
|
||||
return
|
||||
if(occupant)
|
||||
R << "<span class='notice'>The cell is already occupied!</span>"
|
||||
return
|
||||
if(!R.cell)
|
||||
R << "<span class='notice'>Without a powercell, you can't be recharged.</span>"
|
||||
//Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO
|
||||
return
|
||||
can_accept_user = 1
|
||||
|
||||
else if(istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!isnull(H.internal_organs_by_name["cell"]))
|
||||
can_accept_user = 1
|
||||
|
||||
if(!can_accept_user)
|
||||
user << "<span class='notice'>Only non-organics may enter the recharger!</span>"
|
||||
var/mob/living/silicon/robot/R = usr
|
||||
if(!istype(R))
|
||||
usr << "<span class='notice'>Only synthetics may enter the recharger!</span>"
|
||||
return
|
||||
if(!R.cell)
|
||||
usr << "<span class='notice'>Without a powercell, you can't be recharged.</span>"
|
||||
return
|
||||
|
||||
|
||||
user.stop_pulling()
|
||||
if(user.client)
|
||||
user.client.perspective = EYE_PERSPECTIVE
|
||||
user.client.eye = src
|
||||
user.loc = src
|
||||
occupant = user
|
||||
/*for(var/obj/O in src)
|
||||
O.loc = loc*/
|
||||
add_fingerprint(user)
|
||||
build_icon()
|
||||
update_use_power(1)
|
||||
return
|
||||
usr.reset_view(src)
|
||||
usr.loc = src
|
||||
occupant = usr
|
||||
add_fingerprint(usr)
|
||||
update_icon()
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
active_power_usage = 10000
|
||||
|
||||
/obj/machinery/robotic_fabricator/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if (istype(O, /obj/item/stack/material/steel))
|
||||
var/obj/item/stack/material/steel/M = O
|
||||
if (istype(O, /obj/item/stack/material) && O.get_material_name() == DEFAULT_WALL_MATERIAL)
|
||||
var/obj/item/stack/M = O
|
||||
if (src.metal_amount < 150000.0)
|
||||
var/count = 0
|
||||
src.overlays += "fab-load-metal"
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
user << "The charge meter reads [cell ? round(cell.percent(),1) : 0]%"
|
||||
return
|
||||
|
||||
/obj/machinery/space_heater/powered()
|
||||
if(cell && cell.charge)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/space_heater/emp_act(severity)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
..(severity)
|
||||
@@ -56,6 +61,7 @@
|
||||
C.add_fingerprint(usr)
|
||||
|
||||
user.visible_message("<span class='notice'>[user] inserts a power cell into [src].</span>", "<span class='notice'>You insert the power cell into [src].</span>")
|
||||
power_change()
|
||||
else
|
||||
user << "The hatch must be open to insert a power cell."
|
||||
return
|
||||
@@ -125,6 +131,7 @@
|
||||
usr.put_in_hands(cell)
|
||||
cell.add_fingerprint(usr)
|
||||
cell = null
|
||||
power_change()
|
||||
|
||||
|
||||
if("cellinstall")
|
||||
@@ -135,7 +142,7 @@
|
||||
cell = C
|
||||
C.loc = src
|
||||
C.add_fingerprint(usr)
|
||||
|
||||
power_change()
|
||||
usr.visible_message("<span class='notice'>[usr] inserts \the [C] into \the [src].</span>", "<span class='notice'>You insert \the [C] into \the [src].</span>")
|
||||
|
||||
updateDialog()
|
||||
@@ -176,4 +183,5 @@
|
||||
env.merge(removed)
|
||||
else
|
||||
on = 0
|
||||
power_change()
|
||||
update_icon()
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
/obj/machinery/syndicate_beacon/proc/selfdestruct()
|
||||
selfdestructing = 1
|
||||
spawn() explosion(src.loc, rand(3,8), rand(1,3), 1, 10)
|
||||
spawn() explosion(src.loc, 1, rand(1,3), rand(3,8), 10)
|
||||
|
||||
////////////////////////////////////////
|
||||
//Singularity beacon
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
id = "Hub"
|
||||
network = "tcommsat"
|
||||
autolinkers = list("hub", "relay", "c_relay", "s_relay", "m_relay", "r_relay", "science", "medical",
|
||||
"supply", "service", "common", "command", "engineering", "security",
|
||||
"receiverA", "receiverB", "broadcasterA", "broadcasterB")
|
||||
"supply", "service", "common", "command", "engineering", "security", "unused",
|
||||
"receiverA", "broadcasterA")
|
||||
|
||||
/obj/machinery/telecomms/hub/preset_cent
|
||||
id = "CentComm Hub"
|
||||
@@ -52,22 +52,11 @@
|
||||
|
||||
//Receivers
|
||||
|
||||
//--PRESET LEFT--//
|
||||
|
||||
/obj/machinery/telecomms/receiver/preset_left
|
||||
/obj/machinery/telecomms/receiver/preset_right
|
||||
id = "Receiver A"
|
||||
network = "tcommsat"
|
||||
autolinkers = list("receiverA") // link to relay
|
||||
freq_listening = list(SCI_FREQ, MED_FREQ, SUP_FREQ, SRV_FREQ) // science, medical, supply, service
|
||||
|
||||
|
||||
//--PRESET RIGHT--//
|
||||
|
||||
/obj/machinery/telecomms/receiver/preset_right
|
||||
id = "Receiver B"
|
||||
network = "tcommsat"
|
||||
autolinkers = list("receiverB") // link to relay
|
||||
freq_listening = list(COMM_FREQ, ENG_FREQ, SEC_FREQ) //command, engineering, security
|
||||
freq_listening = list(SCI_FREQ, MED_FREQ, SUP_FREQ, SRV_FREQ, COMM_FREQ, ENG_FREQ, SEC_FREQ)
|
||||
|
||||
//Common and other radio frequencies for people to freely use
|
||||
New()
|
||||
@@ -95,7 +84,14 @@
|
||||
id = "Bus 2"
|
||||
network = "tcommsat"
|
||||
freq_listening = list(SUP_FREQ, SRV_FREQ)
|
||||
autolinkers = list("processor2", "supply", "service")
|
||||
autolinkers = list("processor2", "supply", "service", "unused")
|
||||
|
||||
/obj/machinery/telecomms/bus/preset_two/New()
|
||||
for(var/i = 1441, i < 1489, i += 2)
|
||||
if(i == AI_FREQ || i == PUB_FREQ)
|
||||
continue
|
||||
freq_listening |= i
|
||||
..()
|
||||
|
||||
/obj/machinery/telecomms/bus/preset_three
|
||||
id = "Bus 3"
|
||||
@@ -106,14 +102,9 @@
|
||||
/obj/machinery/telecomms/bus/preset_four
|
||||
id = "Bus 4"
|
||||
network = "tcommsat"
|
||||
freq_listening = list(ENG_FREQ)
|
||||
freq_listening = list(ENG_FREQ, AI_FREQ, PUB_FREQ)
|
||||
autolinkers = list("processor4", "engineering", "common")
|
||||
|
||||
/obj/machinery/telecomms/bus/preset_four/New()
|
||||
for(var/i = 1441, i < 1489, i += 2)
|
||||
freq_listening |= i
|
||||
..()
|
||||
|
||||
/obj/machinery/telecomms/bus/preset_cent
|
||||
id = "CentComm Bus"
|
||||
network = "tcommsat"
|
||||
@@ -169,7 +160,7 @@
|
||||
id = "Supply Server"
|
||||
freq_listening = list(SUP_FREQ)
|
||||
autolinkers = list("supply")
|
||||
|
||||
|
||||
/obj/machinery/telecomms/server/presets/service
|
||||
id = "Service Server"
|
||||
freq_listening = list(SRV_FREQ)
|
||||
@@ -177,13 +168,19 @@
|
||||
|
||||
/obj/machinery/telecomms/server/presets/common
|
||||
id = "Common Server"
|
||||
freq_listening = list()
|
||||
freq_listening = list(PUB_FREQ, AI_FREQ) // AI Private and Common
|
||||
autolinkers = list("common")
|
||||
|
||||
//Common and other radio frequencies for people to freely use
|
||||
// 1441 to 1489
|
||||
/obj/machinery/telecomms/server/presets/common/New()
|
||||
// "Unused" channels, AKA all others.
|
||||
/obj/machinery/telecomms/server/presets/unused
|
||||
id = "Unused Server"
|
||||
freq_listening = list()
|
||||
autolinkers = list("unused")
|
||||
|
||||
/obj/machinery/telecomms/server/presets/unused/New()
|
||||
for(var/i = 1441, i < 1489, i += 2)
|
||||
if(i == AI_FREQ || i == PUB_FREQ)
|
||||
continue
|
||||
freq_listening |= i
|
||||
..()
|
||||
|
||||
@@ -213,18 +210,11 @@
|
||||
|
||||
//--PRESET LEFT--//
|
||||
|
||||
/obj/machinery/telecomms/broadcaster/preset_left
|
||||
/obj/machinery/telecomms/broadcaster/preset_right
|
||||
id = "Broadcaster A"
|
||||
network = "tcommsat"
|
||||
autolinkers = list("broadcasterA")
|
||||
|
||||
//--PRESET RIGHT--//
|
||||
|
||||
/obj/machinery/telecomms/broadcaster/preset_right
|
||||
id = "Broadcaster B"
|
||||
network = "tcommsat"
|
||||
autolinkers = list("broadcasterB")
|
||||
|
||||
/obj/machinery/telecomms/broadcaster/preset_cent
|
||||
id = "CentComm Broadcaster"
|
||||
network = "tcommsat"
|
||||
|
||||
@@ -218,9 +218,9 @@
|
||||
enabled=0
|
||||
updateTurrets()
|
||||
|
||||
sleep(rand(60,600))
|
||||
if(!enabled)
|
||||
enabled=1
|
||||
updateTurrets()
|
||||
spawn(rand(60,600))
|
||||
if(!enabled)
|
||||
enabled=1
|
||||
updateTurrets()
|
||||
|
||||
..()
|
||||
|
||||
@@ -266,6 +266,15 @@
|
||||
else
|
||||
A = new /obj/item/projectile/energy/electrode( loc )
|
||||
use_power(200)
|
||||
|
||||
//Turrets aim for the center of mass by default.
|
||||
//If the target is grabbing someone then the turret smartly aims for extremities
|
||||
var/obj/item/weapon/grab/G = locate() in target
|
||||
if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people.
|
||||
A.def_zone = pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
else
|
||||
A.def_zone = pick("chest", "groin")
|
||||
|
||||
A.current = T
|
||||
A.starting = T
|
||||
A.yo = U.y - T.y
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
if (!(XRAY in user.mutations))
|
||||
user.mutations.Add(XRAY)
|
||||
user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
|
||||
user.see_in_dark = 8
|
||||
user.see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
|
||||
if (!(COLD_RESISTANCE in user.mutations))
|
||||
@@ -66,4 +67,4 @@
|
||||
show_objectives(user.mind)
|
||||
user << "You have a very bad feeling about this."
|
||||
|
||||
return
|
||||
return
|
||||
@@ -22,12 +22,6 @@
|
||||
|
||||
Destroy()
|
||||
qdel(pr_mech_sleeper)
|
||||
..()
|
||||
|
||||
allow_drop()
|
||||
return 0
|
||||
|
||||
destroy()
|
||||
for(var/atom/movable/AM in src)
|
||||
AM.forceMove(get_turf(src))
|
||||
return ..()
|
||||
|
||||
@@ -1078,9 +1078,6 @@
|
||||
var/door_locked = 1
|
||||
salvageable = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/passenger/allow_drop()
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/passenger/destroy()
|
||||
for(var/atom/movable/AM in src)
|
||||
AM.forceMove(get_turf(src))
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/obj/effect/expl_particles/New()
|
||||
..()
|
||||
spawn (15)
|
||||
src.loc = null
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/effect/expl_particles/Move()
|
||||
@@ -49,7 +49,7 @@
|
||||
/obj/effect/explosion/New()
|
||||
..()
|
||||
spawn (10)
|
||||
src.loc = null
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/datum/effect/system/explosion
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
// Uncomment this define to check for possible lengthy processing of emp_act()s.
|
||||
// If emp_act() takes more than defined deciseconds (1/10 seconds) an admin message and log is created.
|
||||
// I do not recommend having this uncommented on main server, it probably causes a bit more lag, espicially with larger EMPs.
|
||||
|
||||
// #define EMPDEBUG 10
|
||||
|
||||
proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
|
||||
if(!epicenter) return
|
||||
|
||||
@@ -24,6 +30,9 @@ proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
|
||||
M << 'sound/effects/EMPulse.ogg'
|
||||
|
||||
for(var/atom/T in range(light_range, epicenter))
|
||||
#ifdef EMPDEBUG
|
||||
var/time = world.timeofday
|
||||
#endif
|
||||
var/distance = get_dist(epicenter, T)
|
||||
if(distance < 0)
|
||||
distance = 0
|
||||
@@ -36,4 +45,8 @@ proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
|
||||
T.emp_act(2)
|
||||
else if(distance <= light_range)
|
||||
T.emp_act(2)
|
||||
#ifdef EMPDEBUG
|
||||
if((world.timeofday - time) >= EMPDEBUG)
|
||||
log_and_message_admins("EMPDEBUG: [T.name] - [T.type] - took [world.timeofday - time]ds to process emp_act()!")
|
||||
#endif
|
||||
return 1
|
||||
@@ -68,7 +68,7 @@
|
||||
/obj/item/weapon/pen/crayon/afterattack(atom/target, mob/user as mob, proximity)
|
||||
if(!proximity) return
|
||||
if(istype(target,/turf/simulated/floor))
|
||||
var/drawtype = input("Choose what you'd like to draw.", "Crayon scribbles") in list("graffiti","rune","letter")
|
||||
var/drawtype = input("Choose what you'd like to draw.", "Crayon scribbles") in list("graffiti","rune","letter","arrow")
|
||||
switch(drawtype)
|
||||
if("letter")
|
||||
drawtype = input("Choose the letter.", "Crayon scribbles") in list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
|
||||
@@ -77,6 +77,9 @@
|
||||
user << "You start drawing graffiti on the [target.name]."
|
||||
if("rune")
|
||||
user << "You start drawing a rune on the [target.name]."
|
||||
if("arrow")
|
||||
drawtype = input("Choose the arrow.", "Crayon scribbles") in list("left", "right", "up", "down")
|
||||
user << "You start drawing an arrow on the [target.name]."
|
||||
if(instant || do_after(user, 50))
|
||||
new /obj/effect/decal/cleanable/crayon(target,colour,shadeColour,drawtype)
|
||||
user << "You finish drawing."
|
||||
|
||||
@@ -1284,40 +1284,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
user << "<span class='notice'>No significant chemical agents found in [A].</span>"
|
||||
|
||||
if(5)
|
||||
if((istype(A, /obj/item/weapon/tank)) || (istype(A, /obj/machinery/portable_atmospherics)))
|
||||
var/obj/icon = A
|
||||
for (var/mob/O in viewers(user, null))
|
||||
O << "<span class='warning'>\The [user] has used [src] on \icon[icon] [A].</span>"
|
||||
var/pressure = A:air_contents.return_pressure()
|
||||
|
||||
var/total_moles = A: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 A:air_contents.gas)
|
||||
user << "<span class='notice'>[gas_data.name[g]]: [round((A:air_contents.gas[g] / total_moles) * 100)]%</span>"
|
||||
user << "<span class='notice'>Temperature: [round(A:air_contents.temperature-T0C)]°C</span>"
|
||||
else
|
||||
user << "<span class='notice'>Tank is empty!</span>"
|
||||
|
||||
if (istype(A, /obj/machinery/atmospherics/pipe/tank))
|
||||
var/obj/icon = A
|
||||
for (var/mob/O in viewers(user, null))
|
||||
O << "<span class='warning'>\The [user] has used [src] on \icon[icon] [A]</span>"
|
||||
|
||||
var/obj/machinery/atmospherics/pipe/tank/T = A
|
||||
var/pressure = T.parent.air.return_pressure()
|
||||
var/total_moles = T.parent.air.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 T.parent.air.gas)
|
||||
user << "<span class='notice'>[gas_data.name[g]]: [round((T.parent.air.gas[g] / total_moles) * 100)]%</span>"
|
||||
user << "<span class='notice'>Temperature: [round(T.parent.air.temperature-T0C)]°C</span>"
|
||||
else
|
||||
user << "<span class='notice'>Tank is empty!</span>"
|
||||
analyze_gases(A, user)
|
||||
|
||||
if (!scanmode && istype(A, /obj/item/weapon/paper) && owner)
|
||||
// JMO 20140705: Makes scanned document show up properly in the notes. Not pretty for formatted documents,
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
|
||||
ai.loc = src
|
||||
ai.cancel_camera()
|
||||
ai.destroy_eyeobj(src)
|
||||
ai.control_disabled = 1
|
||||
ai.aiRestorePowerRoutine = 0
|
||||
carded_ai = ai
|
||||
|
||||
@@ -67,8 +67,8 @@
|
||||
user << "It has [uses] lights remaining."
|
||||
|
||||
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/stack/material/glass))
|
||||
var/obj/item/stack/material/glass/G = W
|
||||
if(istype(W, /obj/item/stack/material) && W.get_material_name() == "glass")
|
||||
var/obj/item/stack/G = W
|
||||
if(uses >= max_uses)
|
||||
user << "<span class='warning'>[src.name] is full.</span>"
|
||||
return
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
*/
|
||||
/obj/item/device/radio/headset/headset_cargo
|
||||
name = "supply radio headset"
|
||||
desc = "A headset used by the QM and his slaves."
|
||||
desc = "A headset used by the QM and their slaves."
|
||||
icon_state = "cargo_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/device/encryptionkey/headset_cargo
|
||||
|
||||
@@ -156,6 +156,9 @@
|
||||
else
|
||||
channels[chan_name] |= FREQ_LISTENING
|
||||
|
||||
if(href_list["nowindow"]) // here for pAIs, maybe others will want it, idk
|
||||
return
|
||||
|
||||
interact(usr)
|
||||
|
||||
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel) //BS12 EDIT
|
||||
@@ -575,7 +578,6 @@
|
||||
if(keyslot.syndie)
|
||||
src.syndie = 1
|
||||
|
||||
|
||||
for (var/ch_name in src.channels)
|
||||
if(!radio_controller)
|
||||
sleep(30) // Waiting for the radio_controller to be created.
|
||||
|
||||
@@ -256,6 +256,13 @@ REAGENT SCANNER
|
||||
|
||||
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINERING = 1)
|
||||
|
||||
/obj/item/device/analyzer/atmosanalyze(var/mob/user)
|
||||
var/air = user.return_air()
|
||||
if (!air)
|
||||
return
|
||||
|
||||
return atmosanalyzer_scan(src, air, user)
|
||||
|
||||
/obj/item/device/analyzer/attack_self(mob/user as mob)
|
||||
|
||||
if (user.stat)
|
||||
@@ -264,27 +271,7 @@ REAGENT SCANNER
|
||||
usr << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
||||
return
|
||||
|
||||
var/turf/location = user.loc
|
||||
if (!( istype(location, /turf) ))
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/total_moles = environment.total_moles
|
||||
|
||||
user.show_message("<span class='notice'><b>Results:</b></span>", 1)
|
||||
if(abs(pressure - ONE_ATMOSPHERE) < 10)
|
||||
user.show_message("<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>", 1)
|
||||
else
|
||||
user.show_message("<span class='warning'>Pressure: [round(pressure,0.1)] kPa</span>", 1)
|
||||
if(total_moles)
|
||||
for(var/g in environment.gas)
|
||||
user.show_message("<span class='notice'>[gas_data.name[g]]: [round((environment.gas[g] / total_moles)*100)]%</span>", 1)
|
||||
|
||||
user.show_message("<span class='notice'>Temperature: [round(environment.temperature-T0C)]°C</span>", 1)
|
||||
|
||||
src.add_fingerprint(user)
|
||||
analyze_gases(src, user)
|
||||
return
|
||||
|
||||
/obj/item/device/mass_spectrometer
|
||||
|
||||
@@ -127,8 +127,8 @@
|
||||
|
||||
/obj/item/robot_parts/robot_suit/attackby(obj/item/W as obj, mob/user as mob)
|
||||
..()
|
||||
if(istype(W, /obj/item/stack/material/steel) && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
|
||||
var/obj/item/stack/material/steel/M = W
|
||||
if(istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
|
||||
var/obj/item/stack/material/M = W
|
||||
if (M.use(1))
|
||||
var/obj/item/weapon/secbot_assembly/ed209_assembly/B = new /obj/item/weapon/secbot_assembly/ed209_assembly
|
||||
B.loc = get_turf(src)
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
return
|
||||
|
||||
return -1 // the bullet/projectile goes through the target! Ie, you missed
|
||||
return PROJECTILE_CONTINUE // the bullet/projectile goes through the target!
|
||||
|
||||
|
||||
// Small memory holder entity for transparent bullet holes
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
user.drop_from_inventory(src)
|
||||
qdel(src)
|
||||
|
||||
if(istype(O,/obj/item/stack/material/steel))
|
||||
var/obj/item/stack/material/steel/M = O
|
||||
if(istype(O,/obj/item/stack/material) && O.get_material_name() == DEFAULT_WALL_MATERIAL)
|
||||
var/obj/item/stack/M = O
|
||||
if (M.use(1))
|
||||
use(1)
|
||||
new/obj/item/stack/tile/light(get_turf(user))
|
||||
|
||||
@@ -40,7 +40,7 @@ AI MODULES
|
||||
|
||||
if (comp.current.stat == 2 || comp.current.control_disabled == 1)
|
||||
usr << "Upload failed. No signal is being detected from the AI."
|
||||
else if (!comp.current.has_power)
|
||||
else if (comp.current.see_in_dark == 0)
|
||||
usr << "Upload failed. Only a faint signal is being detected from the AI, and it is not responding to our requests. It may be low on power."
|
||||
else
|
||||
src.transmitInstructions(comp.current, usr)
|
||||
@@ -83,7 +83,7 @@ AI MODULES
|
||||
laws.sync(target, 0)
|
||||
addAdditionalLaws(target, sender)
|
||||
|
||||
target << "[sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: "
|
||||
target << "\The [sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: "
|
||||
target.show_laws()
|
||||
|
||||
/obj/item/weapon/aiModule/proc/log_law_changes(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
@@ -140,13 +140,7 @@ AI MODULES
|
||||
if(!targetName)
|
||||
usr << "No name detected on module, please enter one."
|
||||
return 0
|
||||
..()
|
||||
|
||||
/obj/item/weapon/aiModule/oneHuman/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = "Only [targetName] is a crew member."
|
||||
target << "[sender.real_name] attempted to modify your zeroth law." // And lets them know that someone tried. --NeoFite
|
||||
target << "It would be in your best interest to play along with [sender.real_name] that [law]"
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/aiModule/oneHuman/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
var/law = "Only [targetName] is an crew member."
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
else if(istype(target,/turf))
|
||||
user << "<span class='notice'>You scrub \the [target.name] clean.</span>"
|
||||
var/turf/T = target
|
||||
T.clean()
|
||||
T.clean(src)
|
||||
else
|
||||
user << "<span class='notice'>You clean \the [target.name].</span>"
|
||||
target.clean_blood()
|
||||
|
||||
@@ -112,20 +112,9 @@
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/device/analyzer) && ptank)
|
||||
var/obj/item/weapon/icon = src
|
||||
user.visible_message("<span class='notice'>[user] has used the analyzer on \icon[icon]</span>")
|
||||
var/pressure = ptank.air_contents.return_pressure()
|
||||
var/total_moles = ptank.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 ptank.air_contents.gas)
|
||||
user << "<span class='notice'>[gas_data.name[g]]: [round((ptank.air_contents.gas[g] / total_moles) * 100)]%</span>"
|
||||
user << "<span class='notice'>Temperature: [round(ptank.air_contents.temperature-T0C)]°C</span>"
|
||||
else
|
||||
user << "<span class='notice'>Tank is empty!</span>"
|
||||
if(istype(W, /obj/item/device/analyzer))
|
||||
var/obj/item/device/analyzer/A = W
|
||||
A.analyze_gases(src, user)
|
||||
return
|
||||
..()
|
||||
return
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
user << "<span class='warning'>\The [src] is full.</span>"
|
||||
else
|
||||
spawn(5)
|
||||
I.reagents.trans_to_mob(src.imp, 5)
|
||||
I.reagents.trans_to_obj(src.imp, 5)
|
||||
user << "<span class='notice'>You inject 5 units of the solution. The syringe now contains [I.reagents.total_volume] units.</span>"
|
||||
else if (istype(I, /obj/item/weapon/implanter))
|
||||
var/obj/item/weapon/implanter/M = I
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
if(!isnull(matter[material_type]))
|
||||
matter[material_type] *= force_divisor // May require a new var instead.
|
||||
|
||||
/obj/item/weapon/material/get_material()
|
||||
return material
|
||||
|
||||
/obj/item/weapon/material/proc/update_force()
|
||||
if(edge || sharp)
|
||||
force = material.get_edge_damage()
|
||||
|
||||
@@ -89,4 +89,4 @@
|
||||
..(loc, "steel")
|
||||
|
||||
/obj/item/weapon/material/shard/phoron/New(loc)
|
||||
..(loc, "phoron glass")
|
||||
..(loc, "phglass")
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
/obj/item/weapon/melee/energy/attack_self(mob/living/user as mob)
|
||||
if (active)
|
||||
if ((CLUMSY in user.mutations) && prob(50))
|
||||
user.visible_message("<span class='danger'>[user] accidentally cuts \himself with \the [src].</span>",\
|
||||
user.visible_message("<span class='danger'>\The [user] accidentally cuts \himself with \the [src].</span>",\
|
||||
"<span class='danger'>You accidentally cut yourself with \the [src].</span>")
|
||||
user.take_organ_damage(5,5)
|
||||
deactivate(user)
|
||||
@@ -50,9 +50,10 @@
|
||||
return
|
||||
|
||||
/obj/item/weapon/melee/energy/suicide_act(mob/user)
|
||||
var/tempgender = "[user.gender == MALE ? "he's" : user.gender == FEMALE ? "she's" : "they are"]"
|
||||
if (active)
|
||||
viewers(user) << pick("<span class='danger'>\The [user] is slitting \his stomach open with \the [src]! It looks like \he's trying to commit seppuku.</span>", \
|
||||
"<span class='danger'>\The [user] is falling on \the [src]! It looks like \he's trying to commit suicide.</span>")
|
||||
viewers(user) << pick("<span class='danger'>\The [user] is slitting \his stomach open with \the [src]! It looks like [tempgender] trying to commit seppuku.</span>", \
|
||||
"<span class='danger'>\The [user] is falling on \the [src]! It looks like [tempgender] trying to commit suicide.</span>")
|
||||
return (BRUTELOSS|FIRELOSS)
|
||||
|
||||
/*
|
||||
@@ -90,7 +91,7 @@
|
||||
user << "<span class='notice'>\The [src] is de-energised. It's just a regular axe now.</span>"
|
||||
|
||||
/obj/item/weapon/melee/energy/axe/suicide_act(mob/user)
|
||||
viewers(user) << "<span class='warning'>\The [user] swings \the [src] towards /his head! It looks like \he's trying to commit suicide.</span>"
|
||||
viewers(user) << "<span class='warning'>\The [user] swings \the [src] towards \his head! It looks like \he's trying to commit suicide.</span>"
|
||||
return (BRUTELOSS|FIRELOSS)
|
||||
|
||||
/*
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user